1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #include "pl-zmw.h"
28 #include <sysalloc.h>
29 
zmw_init(zmw_tab * tab)30 void zmw_init( zmw_tab *tab )
31 {
32     init_array_file( &tab->HoleNumber );
33     init_array_file( &tab->HoleStatus );
34     init_array_file( &tab->HoleXY );
35     init_array_file( &tab->NumEvent );
36     init_array_file( &tab->NumPasses );
37 }
38 
39 
zmw_close(zmw_tab * tab)40 void zmw_close( zmw_tab *tab )
41 {
42     free_array_file( &tab->HoleNumber );
43     free_array_file( &tab->HoleStatus );
44     free_array_file( &tab->HoleXY );
45     free_array_file( &tab->NumEvent );
46     free_array_file( &tab->NumPasses );
47 }
48 
49 
zmw_open(const KDirectory * hdf5_dir,zmw_tab * tab,const bool num_passes,const char * path,bool supress_err_msg)50 rc_t zmw_open( const KDirectory *hdf5_dir, zmw_tab *tab,
51                const bool num_passes, const char * path, bool supress_err_msg )
52 {
53     rc_t rc;
54 
55     zmw_init( tab );
56     rc = open_element( hdf5_dir, &tab->HoleNumber, path, "ZMW/HoleNumber",
57                        HOLE_NUMBER_BITSIZE, HOLE_NUMBER_COLS, true, false, supress_err_msg );
58     if ( rc == 0 )
59         rc = open_element( hdf5_dir, &tab->HoleStatus, path, "ZMW/HoleStatus",
60                            HOLE_STATUS_BITSIZE, HOLE_STATUS_COLS, true, false, supress_err_msg );
61     if ( rc == 0 )
62         rc = open_element( hdf5_dir, &tab->HoleXY, path, "ZMW/HoleXY",
63                            HOLE_XY_BITSIZE, HOLE_XY_COLS, true, false, supress_err_msg );
64     if ( rc == 0 )
65         rc = open_element( hdf5_dir, &tab->NumEvent, path, "ZMW/NumEvent",
66                            NUMEVENT_BITSIZE, NUMEVENT_COLS, true, false, supress_err_msg );
67     if ( rc == 0 && num_passes )
68         rc = open_element( hdf5_dir, &tab->NumPasses, path, "Passes/NumPasses",
69                            NUMPASSES_BITSIZE, NUMPASSES_COLS, true, false, supress_err_msg );
70 
71     if ( rc != 0 )
72         zmw_close( tab ); /* releases only initialized elements */
73     return rc;
74 }
75 
76 
zmw_total(zmw_tab * tab)77 uint64_t zmw_total( zmw_tab *tab )
78 {
79     rc_t rc = 0;
80     uint64_t res = 0, pos = 0;
81     uint64_t num_entries = tab->NumEvent.extents[0];
82 
83     while( pos < num_entries && rc == 0 )
84     {
85         uint64_t n_read, to_read = ZMW_BLOCK_SIZE;
86         uint32_t d[ ZMW_BLOCK_SIZE ];
87 
88         if ( ( pos + to_read ) >= num_entries )
89             to_read = ( num_entries - pos );
90         rc = array_file_read_dim1( &tab->NumEvent, pos, d, to_read, &n_read );
91         if ( rc == 0 )
92         {
93             uint32_t i;
94             pos+=n_read;
95             for ( i = 0; i < n_read; ++i )
96                 res += d[ i ];
97         }
98     }
99     return res;
100 }
101 
102 
zmw_read_block(zmw_tab * tab,zmw_block * block,const uint64_t total_spots,const uint64_t pos,const bool with_num_passes)103 rc_t zmw_read_block( zmw_tab *tab, zmw_block * block,
104                      const uint64_t total_spots,
105                      const uint64_t pos,
106                      const bool with_num_passes )
107 {
108     rc_t rc;
109     uint64_t to_read = ZMW_BLOCK_SIZE;
110     uint64_t read_NumEvent, read_HoleNumber, read_HoleStatus,
111              read_HoleXY, read_NumPasses;
112 
113     block->n_read = 0;
114     if ( ( pos + to_read ) >= total_spots )
115         to_read = ( total_spots - pos );
116     rc = array_file_read_dim1( &tab->NumEvent, pos, &block->NumEvent[0],
117                                 to_read, &read_NumEvent );
118     if ( rc == 0 )
119         rc = array_file_read_dim1( &tab->HoleNumber, pos, &block->HoleNumber[0],
120                                     to_read, &read_HoleNumber );
121     if ( rc == 0 )
122         rc = array_file_read_dim1( &tab->HoleStatus, pos, &block->HoleStatus[0],
123                                     to_read, &read_HoleStatus );
124     if ( rc == 0 )
125         rc = array_file_read_dim2( &tab->HoleXY, pos, &block->HoleXY[0],
126                                    to_read, 2, &read_HoleXY );
127     if ( rc == 0 && with_num_passes )
128         rc = array_file_read_dim1( &tab->NumPasses, pos, &block->NumPasses[0],
129                                     to_read, &read_NumPasses );
130     if ( rc == 0 )
131     {
132         if ( ( read_NumEvent != read_HoleNumber ) ||
133              ( read_NumEvent != read_HoleStatus ) ||
134              ( read_NumEvent != read_HoleXY ) )
135         {
136             rc = RC( rcExe, rcNoTarg, rcAllocating, rcParam, rcInvalid );
137             LOGERR( klogErr, rc, "Diff in NumEvents/HoleNumber/HoleStatus/HoleXY" );
138         }
139         else
140         {
141             if ( with_num_passes && read_NumEvent != read_NumPasses )
142             {
143                 rc = RC( rcExe, rcNoTarg, rcAllocating, rcParam, rcInvalid );
144                 LOGERR( klogErr, rc, "Diff in NumEvents/NumPasses" );
145             }
146             else
147                 block->n_read = read_NumEvent;
148         }
149     }
150     return rc;
151 }
152 
153 
zmw_block_row(zmw_block * block,zmw_row * row,const uint32_t idx)154 void zmw_block_row( zmw_block * block, zmw_row * row,
155                     const uint32_t idx )
156 {
157     row->NumEvent    = block->NumEvent[ idx ];
158     row->HoleNumber  = block->HoleNumber[ idx ];
159     row->HoleStatus  = block->HoleStatus[ idx ];
160     row->HoleXY[ 0 ] = block->HoleXY[ idx * 2 ];
161     row->HoleXY[ 1 ] = block->HoleXY[ idx * 2 + 1 ];
162     row->NumPasses   = block->NumPasses[ idx ];
163 }
164 
165 
166 
zmw_for_each(zmw_tab * tab,const KLoadProgressbar ** xml_progress,VCursor * cursor,bool with_progress,const uint32_t * col_idx,region_type_mapping * mapping,const bool with_num_passes,zmw_on_row on_row,void * data)167 rc_t zmw_for_each( zmw_tab *tab, const KLoadProgressbar ** xml_progress, VCursor * cursor,
168                    bool with_progress, const uint32_t *col_idx, region_type_mapping *mapping,
169                    const bool with_num_passes, zmw_on_row on_row, void * data )
170 {
171     zmw_block block;
172     zmw_row row;
173     pl_progress *progress;
174     uint64_t pos = 0;
175     uint64_t total_rows = tab->NumEvent.extents[0];
176 
177     rc_t rc = progress_chunk( xml_progress, total_rows );
178     if ( with_progress )
179         pl_progress_make( &progress, total_rows );
180     row.spot_nr = 0;
181     row.offset = 0;
182     while( pos < total_rows && rc == 0 )
183     {
184         rc = zmw_read_block( tab, &block, total_rows, pos, with_num_passes );
185         if ( rc == 0 )
186         {
187             uint32_t i;
188             for ( i = 0; i < block.n_read && rc == 0; ++i )
189             {
190                 rc = Quitting();
191                 if ( rc == 0 )
192                 {
193                     zmw_block_row( &block, &row, i );
194                     rc = on_row( cursor, col_idx, mapping, &row, data );
195                     if ( rc == 0 )
196                     {
197                         rc = progress_step( *xml_progress );
198                         if ( with_progress )
199                             pl_progress_increment( progress, 1 );
200                     }
201                     row.offset += block.NumEvent[ i ];
202                     row.spot_nr ++;
203                 }
204                 else
205                     LOGERR( klogErr, rc, "...loading ZMW-table interrupted" );
206             }
207             pos += block.n_read;
208         }
209     }
210 
211     if ( with_progress )
212         pl_progress_destroy( progress );
213 
214     if ( rc == 0 )
215     {
216         rc = VCursorCommit( cursor );
217         if ( rc != 0 )
218             LOGERR( klogErr, rc, "cannot commit vdb-cursor on ZMW-table" );
219     }
220     return rc;
221 }
222