Branch data Line data Source code
1 : : #include "ReadNC.hpp"
2 : : #include "NCHelper.hpp"
3 : :
4 : : #include "moab/ReadUtilIface.hpp"
5 : : #include "MBTagConventions.hpp"
6 : : #include "moab/FileOptions.hpp"
7 : :
8 : : namespace moab
9 : : {
10 : :
11 : 1 : ReaderIface* ReadNC::factory( Interface* iface )
12 : : {
13 [ + - ]: 1 : return new ReadNC( iface );
14 : : }
15 : :
16 : 1 : ReadNC::ReadNC( Interface* impl )
17 : : : mbImpl( impl ), fileId( -1 ), mGlobalIdTag( 0 ), mpFileIdTag( NULL ), dbgOut( stderr ), isParallel( false ),
18 : : partMethod( ScdParData::ALLJORKORI ), scdi( NULL ),
19 : : #ifdef MOAB_HAVE_MPI
20 : : myPcomm( NULL ),
21 : : #endif
22 : : noMesh( false ), noVars( false ), spectralMesh( false ), noMixedElements( false ), noEdges( false ),
23 [ + - ][ + - ]: 1 : gatherSetRank( -1 ), tStepBase( -1 ), trivialPartitionShift( 0 ), myHelper( NULL )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
24 : : {
25 [ - + ]: 1 : assert( impl != NULL );
26 [ + - ]: 1 : impl->query_interface( readMeshIface );
27 : 1 : }
28 : :
29 : 3 : ReadNC::~ReadNC()
30 : : {
31 : 1 : mbImpl->release_interface( readMeshIface );
32 [ - + ][ # # ]: 1 : if( myHelper != NULL ) delete myHelper;
33 [ - + ]: 2 : }
34 : :
35 : 1 : ErrorCode ReadNC::load_file( const char* file_name, const EntityHandle* file_set, const FileOptions& opts,
36 : : const ReaderIface::SubsetList* /*subset_list*/, const Tag* file_id_tag )
37 : : {
38 : : // See if opts has variable(s) specified
39 [ + - ]: 1 : std::vector< std::string > var_names;
40 [ + - ]: 2 : std::vector< int > tstep_nums;
41 [ + - ]: 2 : std::vector< double > tstep_vals;
42 : :
43 : : // Get and cache predefined tag handles
44 [ + - ]: 1 : mGlobalIdTag = mbImpl->globalId_tag();
45 : : // Store the pointer to the tag; if not null, set when global id tag
46 : : // is set too, with the same data, duplicated
47 : 1 : mpFileIdTag = file_id_tag;
48 : :
49 [ + - ][ - + ]: 1 : ErrorCode rval = parse_options( opts, var_names, tstep_nums, tstep_vals );MB_CHK_SET_ERR( rval, "Trouble parsing option string" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
50 : :
51 : : // Open the file
52 [ + - ]: 1 : dbgOut.tprintf( 1, "Opening file %s\n", file_name );
53 [ + - ][ + - ]: 1 : fileName = std::string( file_name );
54 : : int success;
55 : :
56 : : #ifdef MOAB_HAVE_PNETCDF
57 : : if( isParallel )
58 : : success = NCFUNC( open )( myPcomm->proc_config().proc_comm(), file_name, 0, MPI_INFO_NULL, &fileId );
59 : : else
60 : : success = NCFUNC( open )( MPI_COMM_SELF, file_name, 0, MPI_INFO_NULL, &fileId );
61 : : #else
62 [ + - ]: 1 : success = NCFUNC( open )( file_name, 0, &fileId );
63 : : #endif
64 [ + - ][ + - ]: 1 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble opening file " << file_name );
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ]
65 : :
66 : : // Read the header (num dimensions, dimensions, num variables, global attribs)
67 [ # # ][ # # ]: 0 : rval = read_header();MB_CHK_SET_ERR( rval, "Trouble reading file header" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
68 : :
69 : : // Make sure there's a file set to put things in
70 : : EntityHandle tmp_set;
71 [ # # ][ # # ]: 0 : if( noMesh && !file_set ) { MB_SET_ERR( MB_FAILURE, "NOMESH option requires non-NULL file set on input" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
72 [ # # ][ # # ]: 0 : else if( !file_set || ( file_set && *file_set == 0 ) )
[ # # ]
73 : : {
74 [ # # ][ # # ]: 0 : rval = mbImpl->create_meshset( MESHSET_SET, tmp_set );MB_CHK_SET_ERR( rval, "Trouble creating file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
75 : : }
76 : : else
77 : 0 : tmp_set = *file_set;
78 : :
79 : : // Get the scd interface
80 : 0 : scdi = NULL;
81 [ # # ]: 0 : rval = mbImpl->query_interface( scdi );
82 [ # # ]: 0 : if( NULL == scdi ) return MB_FAILURE;
83 : :
84 [ # # ][ # # ]: 0 : if( NULL != myHelper ) delete myHelper;
85 : :
86 : : // Get appropriate NC helper instance based on information read from the header
87 [ # # ]: 0 : myHelper = NCHelper::get_nc_helper( this, fileId, opts, tmp_set );
88 [ # # ][ # # ]: 0 : if( NULL == myHelper ) { MB_SET_ERR( MB_FAILURE, "Failed to get NCHelper class instance" ); }
[ # # ][ # # ]
[ # # ][ # # ]
89 : :
90 : : // Initialize mesh values
91 [ # # ][ # # ]: 0 : rval = myHelper->init_mesh_vals();MB_CHK_SET_ERR( rval, "Trouble initializing mesh values" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
92 : :
93 : : // Check existing mesh from last read
94 [ # # ][ # # ]: 0 : if( noMesh && !noVars )
95 : : {
96 [ # # ][ # # ]: 0 : rval = myHelper->check_existing_mesh();MB_CHK_SET_ERR( rval, "Trouble checking mesh from last read" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
97 : : }
98 : :
99 : : // Create some conventional tags, e.g. __NUM_DIMS
100 : : // For multiple reads to a specified file set, we assume a single file, or a series of
101 : : // files with separated timesteps. Keep a flag on the file set to prevent conventional
102 : : // tags from being created again on a second read
103 : 0 : Tag convTagsCreated = 0;
104 : 0 : int def_val = 0;
105 : : rval = mbImpl->tag_get_handle( "__CONV_TAGS_CREATED", 1, MB_TYPE_INTEGER, convTagsCreated,
106 [ # # ][ # # ]: 0 : MB_TAG_SPARSE | MB_TAG_CREAT, &def_val );MB_CHK_SET_ERR( rval, "Trouble getting _CONV_TAGS_CREATED tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
107 : 0 : int create_conv_tags_flag = 0;
108 [ # # ]: 0 : rval = mbImpl->tag_get_data( convTagsCreated, &tmp_set, 1, &create_conv_tags_flag );
109 : : // The first read to the file set
110 [ # # ]: 0 : if( 0 == create_conv_tags_flag )
111 : : {
112 : : // Read dimensions (coordinate variables) by default to create tags like __<var_name>_DIMS
113 : : // This is done only once (assume that all files read to the file set have the same
114 : : // dimensions)
115 [ # # ][ # # ]: 0 : rval = myHelper->read_variables( dimNames, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading dimensions" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
116 : :
117 [ # # ][ # # ]: 0 : rval = myHelper->create_conventional_tags( tstep_nums );MB_CHK_SET_ERR( rval, "Trouble creating NC conventional tags" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
118 : :
119 : 0 : create_conv_tags_flag = 1;
120 [ # # ][ # # ]: 0 : rval = mbImpl->tag_set_data( convTagsCreated, &tmp_set, 1, &create_conv_tags_flag );MB_CHK_SET_ERR( rval, "Trouble setting data to _CONV_TAGS_CREATED tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
121 : : }
122 : : // Another read to the file set
123 : : else
124 : : {
125 [ # # ]: 0 : if( tStepBase > -1 )
126 : : {
127 : : // If timesteps spread across files, merge time values read
128 : : // from current file to existing time tag
129 [ # # ][ # # ]: 0 : rval = myHelper->update_time_tag_vals();MB_CHK_SET_ERR( rval, "Trouble updating time tag values" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
130 : : }
131 : : }
132 : :
133 : : // Create mesh vertex/edge/face sequences
134 [ # # ]: 0 : Range faces;
135 [ # # ]: 0 : if( !noMesh )
136 : : {
137 [ # # ][ # # ]: 0 : rval = myHelper->create_mesh( faces );MB_CHK_SET_ERR( rval, "Trouble creating mesh" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
138 : : }
139 : :
140 : : // Read specified variables onto grid
141 [ # # ]: 0 : if( !noVars )
142 : : {
143 [ # # ]: 0 : if( var_names.empty() )
144 : : {
145 : : // If VARIABLE option is missing, read all variables
146 [ # # ][ # # ]: 0 : rval = myHelper->read_variables( var_names, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading all variables" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
147 : : }
148 : : else
149 : : {
150 : : // Exclude dimensions that are read to the file set by default
151 [ # # ]: 0 : std::vector< std::string > non_dim_var_names;
152 [ # # ]: 0 : for( unsigned int i = 0; i < var_names.size(); i++ )
153 : : {
154 [ # # ][ # # ]: 0 : if( std::find( dimNames.begin(), dimNames.end(), var_names[i] ) == dimNames.end() )
[ # # ][ # # ]
155 [ # # ][ # # ]: 0 : non_dim_var_names.push_back( var_names[i] );
156 : : }
157 : :
158 [ # # ]: 0 : if( !non_dim_var_names.empty() )
159 : : {
160 [ # # ][ # # ]: 0 : rval = myHelper->read_variables( non_dim_var_names, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading specified variables" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
161 : 0 : }
162 : : }
163 : : }
164 : :
165 : : #ifdef MOAB_HAVE_MPI
166 : : // Create partition set, and populate with elements
167 [ # # ]: 0 : if( isParallel )
168 : : {
169 : : EntityHandle partn_set;
170 [ # # ][ # # ]: 0 : rval = mbImpl->create_meshset( MESHSET_SET, partn_set );MB_CHK_SET_ERR( rval, "Trouble creating partition set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
171 : :
172 [ # # ][ # # ]: 0 : rval = mbImpl->add_entities( partn_set, faces );MB_CHK_SET_ERR( rval, "Couldn't add new faces to partition set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
173 : :
174 [ # # ]: 0 : Range verts;
175 [ # # ][ # # ]: 0 : rval = mbImpl->get_connectivity( faces, verts );MB_CHK_SET_ERR( rval, "Couldn't get verts of faces" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
176 : :
177 [ # # ][ # # ]: 0 : rval = mbImpl->add_entities( partn_set, verts );MB_CHK_SET_ERR( rval, "Couldn't add new verts to partition set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
178 : :
179 [ # # ][ # # ]: 0 : myPcomm->partition_sets().insert( partn_set );
180 : :
181 : : // Write partition tag name on partition set
182 [ # # ]: 0 : Tag part_tag = myPcomm->partition_tag();
183 [ # # ][ # # ]: 0 : int dum_rank = myPcomm->proc_config().proc_rank();
184 [ # # ][ # # ]: 0 : rval = mbImpl->tag_set_data( part_tag, &partn_set, 1, &dum_rank );MB_CHK_SET_ERR( rval, "Trouble writing partition tag name on partition set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
185 : : }
186 : : #endif
187 : :
188 [ # # ]: 0 : mbImpl->release_interface( scdi );
189 : 0 : scdi = NULL;
190 : :
191 : : // Close the file
192 [ # # ]: 0 : success = NCFUNC( close )( fileId );
193 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble closing file" );
[ # # ][ # # ]
[ # # ][ # # ]
194 : :
195 : 1 : return MB_SUCCESS;
196 : : }
197 : :
198 : 1 : ErrorCode ReadNC::parse_options( const FileOptions& opts, std::vector< std::string >& var_names,
199 : : std::vector< int >& tstep_nums, std::vector< double >& tstep_vals )
200 : : {
201 : : int tmpval;
202 [ + - ][ - + ]: 1 : if( MB_SUCCESS == opts.get_int_option( "DEBUG_IO", 1, tmpval ) )
203 : : {
204 [ # # ]: 0 : dbgOut.set_verbosity( tmpval );
205 [ # # ][ # # ]: 0 : dbgOut.set_prefix( "NC " );
206 : : }
207 : :
208 [ + - ]: 1 : ErrorCode rval = opts.get_strs_option( "VARIABLE", var_names );
209 [ - + ]: 1 : if( MB_TYPE_OUT_OF_RANGE == rval )
210 : 0 : noVars = true;
211 : : else
212 : 1 : noVars = false;
213 : :
214 [ + - ]: 1 : opts.get_ints_option( "TIMESTEP", tstep_nums );
215 [ + - ]: 1 : opts.get_reals_option( "TIMEVAL", tstep_vals );
216 : :
217 [ + - ]: 1 : rval = opts.get_null_option( "NOMESH" );
218 [ - + ]: 1 : if( MB_SUCCESS == rval ) noMesh = true;
219 : :
220 [ + - ]: 1 : rval = opts.get_null_option( "SPECTRAL_MESH" );
221 [ - + ]: 1 : if( MB_SUCCESS == rval ) spectralMesh = true;
222 : :
223 [ + - ]: 1 : rval = opts.get_null_option( "NO_MIXED_ELEMENTS" );
224 [ - + ]: 1 : if( MB_SUCCESS == rval ) noMixedElements = true;
225 : :
226 [ + - ]: 1 : rval = opts.get_null_option( "NO_EDGES" );
227 [ - + ]: 1 : if( MB_SUCCESS == rval ) noEdges = true;
228 : :
229 [ + - ][ - + ]: 1 : if( 2 <= dbgOut.get_verbosity() )
230 : : {
231 [ # # ]: 0 : if( !var_names.empty() )
232 : : {
233 [ # # ]: 0 : std::cerr << "Variables requested: ";
234 [ # # ]: 0 : for( unsigned int i = 0; i < var_names.size(); i++ )
235 [ # # ][ # # ]: 0 : std::cerr << var_names[i];
236 [ # # ]: 0 : std::cerr << std::endl;
237 : : }
238 : :
239 [ # # ]: 0 : if( !tstep_nums.empty() )
240 : : {
241 [ # # ]: 0 : std::cerr << "Timesteps requested: ";
242 [ # # ]: 0 : for( unsigned int i = 0; i < tstep_nums.size(); i++ )
243 [ # # ][ # # ]: 0 : std::cerr << tstep_nums[i];
244 [ # # ]: 0 : std::cerr << std::endl;
245 : : }
246 : :
247 [ # # ]: 0 : if( !tstep_vals.empty() )
248 : : {
249 [ # # ]: 0 : std::cerr << "Time vals requested: ";
250 [ # # ]: 0 : for( unsigned int i = 0; i < tstep_vals.size(); i++ )
251 [ # # ][ # # ]: 0 : std::cerr << tstep_vals[i];
252 [ # # ]: 0 : std::cerr << std::endl;
253 : : }
254 : : }
255 : :
256 [ + - ]: 1 : rval = opts.get_int_option( "GATHER_SET", 0, gatherSetRank );
257 [ - + ][ # # ]: 1 : if( MB_TYPE_OUT_OF_RANGE == rval ) { MB_SET_ERR( rval, "Invalid value for GATHER_SET option" ); }
[ # # ][ # # ]
[ # # ][ # # ]
258 : :
259 [ + - ]: 1 : rval = opts.get_int_option( "TIMESTEPBASE", 0, tStepBase );
260 [ - + ][ # # ]: 1 : if( MB_TYPE_OUT_OF_RANGE == rval ) { MB_SET_ERR( rval, "Invalid value for TIMESTEPBASE option" ); }
[ # # ][ # # ]
[ # # ][ # # ]
261 : :
262 [ + - ]: 1 : rval = opts.get_int_option( "TRIVIAL_PARTITION_SHIFT", 1, trivialPartitionShift );
263 [ - + ][ # # ]: 1 : if( MB_TYPE_OUT_OF_RANGE == rval ) { MB_SET_ERR( rval, "Invalid value for TRIVIAL_PARTITION_SHIFT option" ); }
[ # # ][ # # ]
[ # # ][ # # ]
264 : :
265 : : #ifdef MOAB_HAVE_MPI
266 [ + - ]: 1 : isParallel = ( opts.match_option( "PARALLEL", "READ_PART" ) != MB_ENTITY_NOT_FOUND );
267 : :
268 [ + - ]: 1 : if( !isParallel )
269 : : // Return success here, since rval still has _NOT_FOUND from not finding option
270 : : // in this case, myPcomm will be NULL, so it can never be used; always check for isParallel
271 : : // before any use for myPcomm
272 : 1 : return MB_SUCCESS;
273 : :
274 : 0 : int pcomm_no = 0;
275 [ # # ]: 0 : rval = opts.get_int_option( "PARALLEL_COMM", pcomm_no );
276 [ # # ][ # # ]: 0 : if( MB_TYPE_OUT_OF_RANGE == rval ) { MB_SET_ERR( rval, "Invalid value for PARALLEL_COMM option" ); }
[ # # ][ # # ]
[ # # ][ # # ]
277 [ # # ]: 0 : myPcomm = ParallelComm::get_pcomm( mbImpl, pcomm_no );
278 [ # # ][ # # ]: 0 : if( 0 == myPcomm ) { myPcomm = new ParallelComm( mbImpl, MPI_COMM_WORLD ); }
[ # # ]
279 [ # # ][ # # ]: 0 : const int rank = myPcomm->proc_config().proc_rank();
280 [ # # ]: 0 : dbgOut.set_rank( rank );
281 : :
282 : : int dum;
283 [ # # ]: 0 : rval = opts.match_option( "PARTITION_METHOD", ScdParData::PartitionMethodNames, dum );
284 [ # # ][ # # ]: 0 : if( MB_FAILURE == rval ) { MB_SET_ERR( rval, "Unknown partition method specified" ); }
[ # # ][ # # ]
[ # # ][ # # ]
285 [ # # ]: 0 : else if( MB_ENTITY_NOT_FOUND == rval )
286 : 0 : partMethod = ScdParData::ALLJORKORI;
287 : : else
288 : 0 : partMethod = dum;
289 : : #endif
290 : :
291 : 1 : return MB_SUCCESS;
292 : : }
293 : :
294 : 0 : ErrorCode ReadNC::read_header()
295 : : {
296 [ # # ]: 0 : dbgOut.tprint( 1, "Reading header...\n" );
297 : :
298 : : // Get the global attributes
299 : : int numgatts;
300 : : int success;
301 [ # # ]: 0 : success = NCFUNC( inq_natts )( fileId, &numgatts );
302 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Couldn't get number of global attributes" );
[ # # ][ # # ]
[ # # ][ # # ]
303 : :
304 : : // Read attributes into globalAtts
305 [ # # ][ # # ]: 0 : ErrorCode result = get_attributes( NC_GLOBAL, numgatts, globalAtts );MB_CHK_SET_ERR( result, "Trouble getting global attributes" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
306 [ # # ]: 0 : dbgOut.tprintf( 1, "Read %u attributes\n", (unsigned int)globalAtts.size() );
307 : :
308 : : // Read in dimensions into dimNames and dimLens
309 [ # # ][ # # ]: 0 : result = get_dimensions( fileId, dimNames, dimLens );MB_CHK_SET_ERR( result, "Trouble getting dimensions" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
310 [ # # ]: 0 : dbgOut.tprintf( 1, "Read %u dimensions\n", (unsigned int)dimNames.size() );
311 : :
312 : : // Read in variables into varInfo
313 [ # # ][ # # ]: 0 : result = get_variables();MB_CHK_SET_ERR( result, "Trouble getting variables" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
314 [ # # ]: 0 : dbgOut.tprintf( 1, "Read %u variables\n", (unsigned int)varInfo.size() );
315 : :
316 : 0 : return MB_SUCCESS;
317 : : }
318 : :
319 : 0 : ErrorCode ReadNC::get_attributes( int var_id, int num_atts, std::map< std::string, AttData >& atts, const char* prefix )
320 : : {
321 : : char dum_name[120];
322 : :
323 [ # # ]: 0 : for( int i = 0; i < num_atts; i++ )
324 : : {
325 : : // Get the name
326 [ # # ]: 0 : int success = NCFUNC( inq_attname )( fileId, var_id, i, dum_name );
327 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting attribute name" );
[ # # ][ # # ]
[ # # ][ # # ]
328 : :
329 [ # # ][ # # ]: 0 : AttData& data = atts[std::string( dum_name )];
330 [ # # ][ # # ]: 0 : data.attName = std::string( dum_name );
331 [ # # ]: 0 : success = NCFUNC( inq_att )( fileId, var_id, dum_name, &data.attDataType, &data.attLen );
332 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting info for attribute " << data.attName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
333 : 0 : data.attVarId = var_id;
334 : :
335 : : dbgOut.tprintf( 2, "%sAttribute %s: length=%u, varId=%d, type=%d\n", ( prefix ? prefix : "" ),
336 [ # # ][ # # ]: 0 : data.attName.c_str(), (unsigned int)data.attLen, data.attVarId, data.attDataType );
337 : : }
338 : :
339 : 0 : return MB_SUCCESS;
340 : : }
341 : :
342 : 0 : ErrorCode ReadNC::get_dimensions( int file_id, std::vector< std::string >& dim_names, std::vector< int >& dim_lens )
343 : : {
344 : : // Get the number of dimensions
345 : : int num_dims;
346 [ # # ]: 0 : int success = NCFUNC( inq_ndims )( file_id, &num_dims );
347 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting number of dimensions" );
[ # # ][ # # ]
[ # # ][ # # ]
348 : :
349 [ # # ]: 0 : if( num_dims > NC_MAX_DIMS )
350 : : {
351 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
352 : : "ReadNC: File contains " << num_dims << " dims but NetCDF library supports only " << NC_MAX_DIMS );
353 : : }
354 : :
355 : : char dim_name[NC_MAX_NAME + 1];
356 : : NCDF_SIZE dim_len;
357 [ # # ]: 0 : dim_names.resize( num_dims );
358 [ # # ]: 0 : dim_lens.resize( num_dims );
359 : :
360 [ # # ]: 0 : for( int i = 0; i < num_dims; i++ )
361 : : {
362 [ # # ]: 0 : success = NCFUNC( inq_dim )( file_id, i, dim_name, &dim_len );
363 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting dimension info" );
[ # # ][ # # ]
[ # # ][ # # ]
364 : :
365 [ # # ][ # # ]: 0 : dim_names[i] = std::string( dim_name );
[ # # ]
366 [ # # ]: 0 : dim_lens[i] = dim_len;
367 : :
368 [ # # ]: 0 : dbgOut.tprintf( 2, "Dimension %s, length=%u\n", dim_name, (unsigned int)dim_len );
369 : : }
370 : :
371 : 0 : return MB_SUCCESS;
372 : : }
373 : :
374 : 0 : ErrorCode ReadNC::get_variables()
375 : : {
376 : : // First cache the number of time steps
377 [ # # ]: 0 : std::vector< std::string >::iterator vit = std::find( dimNames.begin(), dimNames.end(), "time" );
378 [ # # ][ # # ]: 0 : if( vit == dimNames.end() ) vit = std::find( dimNames.begin(), dimNames.end(), "t" );
[ # # ]
379 : :
380 : 0 : int ntimes = 0;
381 [ # # ][ # # ]: 0 : if( vit != dimNames.end() ) ntimes = dimLens[vit - dimNames.begin()];
[ # # ][ # # ]
382 [ # # ]: 0 : if( !ntimes ) ntimes = 1;
383 : :
384 : : // Get the number of variables
385 : : int num_vars;
386 [ # # ]: 0 : int success = NCFUNC( inq_nvars )( fileId, &num_vars );
387 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting number of variables" );
[ # # ][ # # ]
[ # # ][ # # ]
388 : :
389 [ # # ]: 0 : if( num_vars > NC_MAX_VARS )
390 : : {
391 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
392 : : "ReadNC: File contains " << num_vars << " vars but NetCDF library supports only " << NC_MAX_VARS );
393 : : }
394 : :
395 : : char var_name[NC_MAX_NAME + 1];
396 : : int var_ndims;
397 : :
398 [ # # ]: 0 : for( int i = 0; i < num_vars; i++ )
399 : : {
400 : : // Get the name first, so we can allocate a map iterate for this var
401 [ # # ]: 0 : success = NCFUNC( inq_varname )( fileId, i, var_name );
402 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting variable name" );
[ # # ][ # # ]
[ # # ][ # # ]
403 [ # # ][ # # ]: 0 : VarData& data = varInfo[std::string( var_name )];
404 [ # # ][ # # ]: 0 : data.varName = std::string( var_name );
405 : 0 : data.varId = i;
406 [ # # ]: 0 : data.varTags.resize( ntimes, 0 );
407 : :
408 : : // Get the data type
409 [ # # ]: 0 : success = NCFUNC( inq_vartype )( fileId, i, &data.varDataType );
410 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting data type for variable " << data.varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
411 : :
412 : : // Get the number of dimensions, then the dimensions
413 [ # # ]: 0 : success = NCFUNC( inq_varndims )( fileId, i, &var_ndims );
414 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting number of dims for variable " << data.varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
415 [ # # ]: 0 : data.varDims.resize( var_ndims );
416 : :
417 [ # # ][ # # ]: 0 : success = NCFUNC( inq_vardimid )( fileId, i, &data.varDims[0] );
418 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting dimensions for variable " << data.varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
419 : :
420 : : // Finally, get the number of attributes, then the attributes
421 [ # # ]: 0 : success = NCFUNC( inq_varnatts )( fileId, i, &data.numAtts );
422 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Trouble getting number of dims for variable " << data.varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
423 : :
424 : : // Print debug info here so attribute info comes afterwards
425 : : dbgOut.tprintf( 2, "Variable %s: Id=%d, numAtts=%d, datatype=%d, num_dims=%u\n", data.varName.c_str(),
426 [ # # ]: 0 : data.varId, data.numAtts, data.varDataType, (unsigned int)data.varDims.size() );
427 : :
428 [ # # ][ # # ]: 0 : ErrorCode rval = get_attributes( i, data.numAtts, data.varAtts, " " );MB_CHK_SET_ERR( rval, "Trouble getting attributes for variable " << data.varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
429 : : }
430 : :
431 : 0 : return MB_SUCCESS;
432 : : }
433 : :
434 : 0 : ErrorCode ReadNC::read_tag_values( const char*, const char*, const FileOptions&, std::vector< int >&,
435 : : const SubsetList* )
436 : : {
437 : 0 : return MB_FAILURE;
438 : : }
439 : :
440 [ + - ][ + - ]: 228 : } // namespace moab
|