#include <NCWriteHelper.hpp>
Public Member Functions | |
NCWriteHelper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet) | |
virtual | ~NCWriteHelper () |
virtual ErrorCode | collect_mesh_info ()=0 |
Collect necessary info about local mesh (implemented in child classes) More... | |
virtual ErrorCode | collect_variable_data (std::vector< std::string > &var_names, std::vector< int > &tstep_nums) |
Collect data for specified variables (partially implemented in child classes) More... | |
ErrorCode | init_file (std::vector< std::string > &var_names, std::vector< std::string > &desired_names, bool _append) |
Initialize file: this is where all defines are done The VarData dimension ids are filled up after define. More... | |
ErrorCode | write_values (std::vector< std::string > &var_names, std::vector< int > &tstep_nums) |
Take the info from VarData and write first non-set variables, then set variables. More... | |
Static Public Member Functions | |
static NCWriteHelper * | get_nc_helper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet) |
Get appropriate helper instance for WriteNC class based on some info in the file set. More... | |
Protected Member Functions | |
virtual ErrorCode | write_nonset_variables (std::vector< WriteNC::VarData > &vdatas, std::vector< int > &tstep_nums)=0 |
Protected Attributes | |
WriteNC * | _writeNC |
Allow NCWriteHelper to directly access members of WriteNC. More... | |
int | _fileId |
Cache some information from WriteNC. More... | |
const FileOptions & | _opts |
EntityHandle | _fileSet |
int | nTimeSteps |
Dimensions of time and level. More... | |
int | nLevels |
int | tDim |
Dimension numbers for time and level. More... | |
int | levDim |
Range | localCellsOwned |
Local owned cells, edges and vertices. More... | |
Range | localEdgesOwned |
Range | localVertsOwned |
std::vector< double > | timeStepVals |
Time values of output timesteps. More... | |
Private Member Functions | |
ErrorCode | write_set_variables (std::vector< WriteNC::VarData > &vsetdatas, std::vector< int > &tstep_nums) |
Definition at line 22 of file NCWriteHelper.hpp.
|
inline |
Definition at line 25 of file NCWriteHelper.hpp.
26 : _writeNC( writeNC ), _fileId( fileId ), _opts( opts ), _fileSet( fileSet ), nTimeSteps( 0 ), nLevels( 1 ), 27 tDim( -1 ), levDim( -1 ) 28 { 29 }
|
inlinevirtual |
Definition at line 30 of file NCWriteHelper.hpp.
30 {};
|
pure virtual |
Collect necessary info about local mesh (implemented in child classes)
Implemented in moab::NCWriteMPAS, moab::NCWriteHOMME, moab::ScdNCWriteHelper, and moab::NCWriteGCRM.
Referenced by moab::WriteNC::write_file().
|
virtual |
Collect data for specified variables (partially implemented in child classes)
Reimplemented in moab::NCWriteMPAS, moab::NCWriteHOMME, moab::ScdNCWriteHelper, and moab::NCWriteGCRM.
Definition at line 51 of file NCWriteHelper.cpp.
52 {
53 Interface*& mbImpl = _writeNC->mbImpl;
54 std::vector< std::string >& dimNames = _writeNC->dimNames;
55 std::vector< int >& dimLens = _writeNC->dimLens;
56 std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates;
57 std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames;
58 std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo;
59 DebugOutput& dbgOut = _writeNC->dbgOut;
60
61 ErrorCode rval;
62
63 usedCoordinates.clear();
64
65 if( tstep_nums.empty() && nTimeSteps > 0 )
66 {
67 // No timesteps input, get them all
68 for( int i = 0; i < nTimeSteps; i++ )
69 tstep_nums.push_back( i );
70 }
71
72 for( size_t i = 0; i < var_names.size(); i++ )
73 {
74 std::string varname = var_names[i];
75 std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( varname );
76 if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find variable " << varname );
77
78 WriteNC::VarData& currentVarData = vit->second;
79
80 dbgOut.tprintf( 2, " for variable %s varDims.size %d \n", varname.c_str(),
81 (int)currentVarData.varDims.size() );
82 for( size_t j = 0; j < currentVarData.varDims.size(); j++ )
83 {
84 std::string dimName = dimNames[currentVarData.varDims[j]];
85 vit = varInfo.find( dimName );
86 if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << dimName );
87
88 usedCoordinates.insert( dimName ); // Collect those used, we will need to write them to the file
89 dbgOut.tprintf( 2, " for variable %s need dimension %s with length %d\n", varname.c_str(),
90 dimName.c_str(), dimLens[currentVarData.varDims[j]] );
91 }
92
93 // Process coordinate variables later
94 if( usedCoordinates.find( varname ) != usedCoordinates.end() ) continue;
95
96 // Default has_tsteps is false
97 if( std::find( currentVarData.varDims.begin(), currentVarData.varDims.end(), tDim ) !=
98 currentVarData.varDims.end() )
99 currentVarData.has_tsteps = true;
100
101 // Default numLev is 0
102 if( ( std::find( currentVarData.varDims.begin(), currentVarData.varDims.end(), levDim ) !=
103 currentVarData.varDims.end() ) )
104 currentVarData.numLev = nLevels;
105
106 // Process set variables
107 if( WriteNC::ENTLOCSET == currentVarData.entLoc )
108 {
109 if( currentVarData.has_tsteps )
110 {
111 // Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen)
112 // TBD
113 MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing set variables with timesteps is not implemented yet" );
114 }
115 else
116 {
117 // Get the tag with varname
118 Tag tag = 0;
119 rval = mbImpl->tag_get_handle( varname.c_str(), tag );MB_CHK_SET_ERR( rval, "Can't find tag " << varname );
120 currentVarData.varTags.push_back( tag ); // Really, only one for these
121 const void* data;
122 int size;
123 rval = mbImpl->tag_get_by_ptr( tag, &_fileSet, 1, &data, &size );MB_CHK_SET_ERR( rval, "Can't get data of tag " << varname );
124
125 // Find the type of tag, and use it
126 DataType type;
127 rval = mbImpl->tag_get_data_type( tag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << varname );
128
129 currentVarData.varDataType = NC_DOUBLE;
130 if( MB_TYPE_INTEGER == type ) currentVarData.varDataType = NC_INT;
131
132 assert( 0 == currentVarData.memoryHogs.size() ); // Nothing so far
133 currentVarData.memoryHogs.push_back( (void*)data );
134
135 if( currentVarData.varDims.empty() )
136 {
137 // Scalar variable
138 currentVarData.writeStarts.push_back( 0 );
139 currentVarData.writeCounts.push_back( 1 );
140 }
141 else
142 {
143 for( size_t j = 0; j < currentVarData.varDims.size(); j++ )
144 {
145 currentVarData.writeStarts.push_back( 0 );
146 currentVarData.writeCounts.push_back( dimLens[currentVarData.varDims[j]] );
147 }
148 }
149
150 // Get variable size
151 currentVarData.sz = 1;
152 for( std::size_t idx = 0; idx != currentVarData.writeCounts.size(); idx++ )
153 currentVarData.sz *= currentVarData.writeCounts[idx];
154 }
155 } // if (WriteNC::ENTLOCSET == currentVarData.entLoc)
156 // Process non-set variables
157 else
158 {
159 Tag indexedTag = 0;
160
161 if( currentVarData.has_tsteps )
162 {
163 for( unsigned int t = 0; t < tstep_nums.size(); t++ )
164 {
165 std::stringstream ssTagNameWithIndex;
166 ssTagNameWithIndex << varname << tstep_nums[t];
167 rval = mbImpl->tag_get_handle( ssTagNameWithIndex.str().c_str(), indexedTag );MB_CHK_SET_ERR( rval, "Can't find tag " << ssTagNameWithIndex.str() );
168 dbgOut.tprintf( 2, " found indexed tag %d with name %s\n", tstep_nums[t],
169 ssTagNameWithIndex.str().c_str() );
170 currentVarData.varTags.push_back( indexedTag );
171 }
172 }
173 else
174 {
175 // This should be a user-created non-set variable without timesteps
176 // Treat it like having one, 0th, timestep
177 std::stringstream ssTagNameWithIndex;
178 ssTagNameWithIndex << varname << 0;
179 rval = mbImpl->tag_get_handle( ssTagNameWithIndex.str().c_str(), indexedTag );MB_CHK_SET_ERR( rval, "Can't find tag " << ssTagNameWithIndex.str() << " for a user-created variable" );
180 dbgOut.tprintf( 2, " found indexed tag 0 with name %s\n", ssTagNameWithIndex.str().c_str() );
181 currentVarData.varTags.push_back( indexedTag );
182 }
183
184 // The type of the tag is fixed though
185 DataType type;
186 rval = mbImpl->tag_get_data_type( indexedTag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << varname );
187
188 currentVarData.varDataType = NC_DOUBLE;
189 if( MB_TYPE_INTEGER == type ) currentVarData.varDataType = NC_INT;
190 }
191 } // for (size_t i = 0; i < var_names.size(); i++)
192
193 // Process coordinate variables here
194 // Check that for used coordinates we have found the tags
195 for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt )
196 {
197 const std::string& coordName = *setIt;
198
199 std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName );
200 if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName );
201
202 WriteNC::VarData& varCoordData = vit->second;
203 Tag coordTag = 0;
204 rval = mbImpl->tag_get_handle( coordName.c_str(), coordTag );MB_CHK_SET_ERR( rval, "Can't find tag " << coordName );
205 varCoordData.varTags.push_back( coordTag ); // Really, only one for these
206
207 const void* data;
208 int sizeCoordinate;
209 rval = mbImpl->tag_get_by_ptr( coordTag, &_fileSet, 1, &data, &sizeCoordinate );MB_CHK_SET_ERR( rval, "Can't get coordinate values of " << coordName );
210 dbgOut.tprintf( 2, " found coordinate tag with name %s and length %d\n", coordName.c_str(), sizeCoordinate );
211
212 // Find the type of tag, and use it
213 DataType type;
214 rval = mbImpl->tag_get_data_type( coordTag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << coordName );
215 varCoordData.varDataType = NC_DOUBLE;
216 if( MB_TYPE_INTEGER == type ) varCoordData.varDataType = NC_INT;
217
218 // Get dimension length (the only dimension of this coordinate variable, with the same name)
219 assert( 1 == varCoordData.varDims.size() );
220 int coordDimLen = dimLens[varCoordData.varDims[0]];
221
222 if( dummyVarNames.find( coordName ) != dummyVarNames.end() )
223 {
224 // For a dummy coordinate variable, the tag size is always 1
225 // The number of coordinates should be set to dimension length, instead of 1
226 assert( 1 == sizeCoordinate );
227 sizeCoordinate = coordDimLen;
228
229 // No variable data to write
230 data = NULL;
231 }
232 else
233 {
234 // The number of coordinates should be exactly the same as dimension length
235 // However, if timesteps spread across files and time tag has been updated,
236 // sizeCoordinate will be larger
237 if( varCoordData.varDims[0] != tDim ) assert( sizeCoordinate == coordDimLen );
238 }
239
240 // For time, the actual output size and values are determined by tstep_nums
241 if( varCoordData.varDims[0] == tDim )
242 {
243 // Does not apply to dummy time tag (e.g. 'Time' tag of MPAS), when timesteps
244 // spread across files
245 if( NULL != data ) assert( tstep_nums.size() > 0 && tstep_nums.size() <= (size_t)sizeCoordinate );
246
247 sizeCoordinate = tstep_nums.size();
248
249 if( NULL != data )
250 {
251 assert( NC_DOUBLE == varCoordData.varDataType );
252 timeStepVals.resize( sizeCoordinate );
253 for( unsigned int t = 0; t < tstep_nums.size(); t++ )
254 timeStepVals[t] = ( (double*)data )[tstep_nums[t]];
255
256 data = &timeStepVals[0];
257 }
258 }
259
260 // This is the length
261 varCoordData.sz = sizeCoordinate;
262 varCoordData.writeStarts.resize( 1 );
263 varCoordData.writeStarts[0] = 0;
264 varCoordData.writeCounts.resize( 1 );
265 varCoordData.writeCounts[0] = sizeCoordinate;
266
267 assert( 0 == varCoordData.memoryHogs.size() ); // Nothing so far
268 varCoordData.memoryHogs.push_back( (void*)data );
269 } // for (std::set<std::string>::iterator setIt ...
270
271 return MB_SUCCESS;
272 }
References _fileSet, _writeNC, moab::WriteNC::dbgOut, moab::WriteNC::dimLens, moab::WriteNC::dimNames, moab::WriteNC::dummyVarNames, moab::WriteNC::VarData::entLoc, moab::WriteNC::ENTLOCSET, ErrorCode, moab::WriteNC::VarData::has_tsteps, levDim, MB_CHK_SET_ERR, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, moab::WriteNC::mbImpl, moab::WriteNC::VarData::memoryHogs, nLevels, nTimeSteps, moab::WriteNC::VarData::numLev, size, moab::WriteNC::VarData::sz, moab::Interface::tag_get_by_ptr(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_handle(), tDim, timeStepVals, moab::DebugOutput::tprintf(), moab::WriteNC::usedCoordinates, moab::WriteNC::VarData::varDataType, moab::WriteNC::VarData::varDims, moab::WriteNC::varInfo, moab::WriteNC::VarData::varTags, moab::WriteNC::VarData::writeCounts, and moab::WriteNC::VarData::writeStarts.
Referenced by moab::NCWriteGCRM::collect_variable_data(), moab::ScdNCWriteHelper::collect_variable_data(), moab::NCWriteHOMME::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), and moab::WriteNC::write_file().
|
static |
Get appropriate helper instance for WriteNC class based on some info in the file set.
Get appropriate helper instance for WriteNC class; based on some info in the file set.
Definition at line 30 of file NCWriteHelper.cpp.
34 {
35 std::string& grid_type = writeNC->grid_type;
36 if( grid_type == "CAM_EUL" )
37 return new( std::nothrow ) NCWriteEuler( writeNC, fileId, opts, fileSet );
38 else if( grid_type == "CAM_FV" )
39 return new( std::nothrow ) NCWriteFV( writeNC, fileId, opts, fileSet );
40 else if( grid_type == "CAM_SE" )
41 return new( std::nothrow ) NCWriteHOMME( writeNC, fileId, opts, fileSet );
42 else if( grid_type == "MPAS" )
43 return new( std::nothrow ) NCWriteMPAS( writeNC, fileId, opts, fileSet );
44 else if( grid_type == "GCRM" )
45 return new( std::nothrow ) NCWriteGCRM( writeNC, fileId, opts, fileSet );
46
47 // Unknown NetCDF grid
48 return NULL;
49 }
References moab::WriteNC::grid_type.
Referenced by moab::WriteNC::write_file().
ErrorCode moab::NCWriteHelper::init_file | ( | std::vector< std::string > & | var_names, |
std::vector< std::string > & | desired_names, | ||
bool | _append | ||
) |
Initialize file: this is where all defines are done The VarData dimension ids are filled up after define.
Definition at line 274 of file NCWriteHelper.cpp.
277 {
278 std::vector< std::string >& dimNames = _writeNC->dimNames;
279 std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates;
280 std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames;
281 std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo;
282 std::map< std::string, WriteNC::AttData >& globalAtts = _writeNC->globalAtts;
283 DebugOutput& dbgOut = _writeNC->dbgOut;
284
285 int tDim_in_dimNames = tDim;
286 int levDim_in_dimNames = levDim;
287
288 // If append mode, make sure we are in define mode; a simple open will not allow creation of new
289 // variables
290 if( append )
291 {
292 int errcode = NCFUNC( redef )( _fileId );
293 if( errcode != NC_NOERR ) MB_SET_ERR( MB_FAILURE, "Can't open file in redefine mode" );
294 }
295
296 // First initialize all coordinates, then fill VarData for actual variables (and dimensions)
297 // Check that for used coordinates we have found the tags
298 for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt )
299 {
300 const std::string& coordName = *setIt;
301
302 std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName );
303 if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName );
304
305 WriteNC::VarData& varCoordData = vit->second;
306 varCoordData.varDims.resize( 1 );
307
308 // If not append, create it for sure
309 // If append, we might already have it, including the tag / variable with the same name
310 /*
311 * int ncmpi_inq_dimid(int ncid, const char *name, int *idp);
312 */
313 if( append )
314 {
315 int dimId;
316 if( NCFUNC( inq_dimid )( _fileId, coordName.c_str(), &dimId ) == NC_NOERR )
317 { // If not found, create it later
318 varCoordData.varDims[0] = dimId;
319 dbgOut.tprintf( 2, " file already has coordName %s dim id is %d \n", coordName.c_str(),
320 (int)varCoordData.varDims[0] );
321
322 // Update tDim and levDim to actual dimension id
323 if( coordName == dimNames[tDim_in_dimNames] )
324 tDim = varCoordData.varDims[0];
325 else if( coordName == dimNames[levDim_in_dimNames] )
326 levDim = varCoordData.varDims[0];
327
328 // Skip dummy coordinate variables (e.g. ncol)
329 if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue;
330
331 // Check that the coordinate is a variable too
332 // Inquire for a variable with the same name
333 int varId;
334 if( NCFUNC( inq_varid )( _fileId, coordName.c_str(), &varId ) != NC_NOERR )
335 MB_SET_ERR( MB_FAILURE, "We do not have a variable with the same name " << coordName );
336 // We should also check that this variable has one dimension, and it is dimId
337 varCoordData.varId = varId;
338 dbgOut.tprintf( 2, " file already has coordinate %s and varId is %d \n", coordName.c_str(), varId );
339
340 continue; // Maybe more checks are needed here
341 }
342 }
343
344 /* int nc_def_dim (int ncid, const char *name, size_t len, int *dimidp);
345 * example: status = nc_def_dim(fileId, "lat", 18L, &latid);
346 */
347
348 // Actually define a dimension
349 if( NCFUNC( def_dim )( _fileId, coordName.c_str(), (size_t)varCoordData.sz, &varCoordData.varDims[0] ) !=
350 NC_NOERR )
351 MB_SET_ERR( MB_FAILURE, "Failed to generate dimension " << coordName );
352 dbgOut.tprintf( 2, " for coordName %s dim id is %d \n", coordName.c_str(), (int)varCoordData.varDims[0] );
353
354 // Update tDim and levDim to actual dimension id
355 if( coordName == dimNames[tDim_in_dimNames] )
356 tDim = varCoordData.varDims[0];
357 else if( coordName == dimNames[levDim_in_dimNames] )
358 levDim = varCoordData.varDims[0];
359
360 // Create a variable with the same name, and its only dimension the one we just defined
361 /*
362 * int nc_def_var (int ncid, const char *name, nc_type xtype,
363 int ndims, const int dimids[], int *varidp);
364 example:
365 http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar.html#nc_005fdef_005fvar
366 */
367
368 // Skip dummy coordinate variables (e.g. ncol)
369 if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue;
370
371 // Define a coordinate variable
372 if( NCFUNC( def_var )( _fileId, coordName.c_str(), varCoordData.varDataType, 1, &( varCoordData.varDims[0] ),
373 &varCoordData.varId ) != NC_NOERR )
374 MB_SET_ERR( MB_FAILURE, "Failed to create coordinate variable " << coordName );
375
376 dbgOut.tprintf( 2, " for coordName %s variable id is %d \n", coordName.c_str(), varCoordData.varId );
377 }
378
379 // Now look at requested variables, and update from the index in dimNames to the actual
380 // dimension id
381 for( size_t i = 0; i < var_names.size(); i++ )
382 {
383 std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( var_names[i] );
384 if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find requested variable " << var_names[i] );
385
386 // Skip coordinate variables
387 if( usedCoordinates.find( var_names[i] ) != usedCoordinates.end() ) continue;
388
389 WriteNC::VarData& variableData = vit->second;
390
391 // The index is for dimNames; we need to find out the actual dimension id (from above)
392 int numDims = (int)variableData.varDims.size();
393 for( int j = 0; j < numDims; j++ )
394 {
395 std::string dimName = dimNames[variableData.varDims[j]];
396 std::map< std::string, WriteNC::VarData >::iterator vit2 = varInfo.find( dimName );
397 if( vit2 == varInfo.end() )
398 MB_SET_ERR( MB_FAILURE, "Can't find requested coordinate variable " << dimName );
399
400 WriteNC::VarData& coordData = vit2->second;
401 // Index in dimNames to actual dimension id
402 variableData.varDims[j] = coordData.varDims[0]; // This one, being a coordinate, is the only one
403 dbgOut.tprintf( 2, " dimension with index %d name %s has ID %d \n", j, dimName.c_str(),
404 variableData.varDims[j] );
405 }
406
407 // Define the variable now:
408 int errCode =
409 NCFUNC( def_var )( _fileId, desired_names[i].c_str(), variableData.varDataType,
410 (int)variableData.varDims.size(), &( variableData.varDims[0] ), &variableData.varId );
411 if( errCode != NC_NOERR ) MB_SET_ERR( MB_FAILURE, "Failed to create requested variable " << desired_names[i] );
412
413 dbgOut.tprintf( 2, " for variable %s with desired name %s variable id is %d \n", var_names[i].c_str(),
414 desired_names[i].c_str(), variableData.varId );
415 // Now define the variable, with all dimensions
416 }
417
418 // Define global attributes (exactly copied from the original file for the time being)
419 // Should we modify some of them (e.g. revision_Id) later?
420 std::map< std::string, WriteNC::AttData >::iterator attIt;
421 for( attIt = globalAtts.begin(); attIt != globalAtts.end(); ++attIt )
422 {
423 const std::string& attName = attIt->first;
424 WriteNC::AttData& attData = attIt->second;
425 NCDF_SIZE& attLen = attData.attLen;
426 nc_type& attDataType = attData.attDataType;
427 const std::string& attValue = attData.attValue;
428
429 switch( attDataType )
430 {
431 case NC_BYTE:
432 case NC_CHAR:
433 if( NC_NOERR !=
434 NCFUNC( put_att_text )( _fileId, NC_GLOBAL, attName.c_str(), attLen, attValue.c_str() ) )
435 MB_SET_ERR( MB_FAILURE, "Failed to define text type attribute" );
436 break;
437 case NC_DOUBLE:
438 if( NC_NOERR != NCFUNC( put_att_double )( _fileId, NC_GLOBAL, attName.c_str(), NC_DOUBLE, 1,
439 (double*)attValue.c_str() ) )
440 MB_SET_ERR( MB_FAILURE, "Failed to define double type attribute" );
441 break;
442 case NC_FLOAT:
443 if( NC_NOERR != NCFUNC( put_att_float )( _fileId, NC_GLOBAL, attName.c_str(), NC_FLOAT, 1,
444 (float*)attValue.c_str() ) )
445 MB_SET_ERR( MB_FAILURE, "Failed to define float type attribute" );
446 break;
447 case NC_INT:
448 if( NC_NOERR !=
449 NCFUNC( put_att_int )( _fileId, NC_GLOBAL, attName.c_str(), NC_INT, 1, (int*)attValue.c_str() ) )
450 MB_SET_ERR( MB_FAILURE, "Failed to define int type attribute" );
451 break;
452 case NC_SHORT:
453 if( NC_NOERR != NCFUNC( put_att_short )( _fileId, NC_GLOBAL, attName.c_str(), NC_SHORT, 1,
454 (short*)attValue.c_str() ) )
455 MB_SET_ERR( MB_FAILURE, "Failed to define short type attribute" );
456 break;
457 default:
458 MB_SET_ERR( MB_FAILURE, "Unknown attribute data type" );
459 }
460 }
461
462 // Take it out of define mode
463 if( NC_NOERR != NCFUNC( enddef )( _fileId ) ) MB_SET_ERR( MB_FAILURE, "Failed to close define mode" );
464
465 return MB_SUCCESS;
466 }
References _fileId, _writeNC, moab::WriteNC::AttData::attDataType, moab::WriteNC::AttData::attLen, moab::WriteNC::AttData::attValue, moab::WriteNC::dbgOut, moab::WriteNC::dimNames, moab::WriteNC::dummyVarNames, moab::WriteNC::globalAtts, levDim, MB_SET_ERR, MB_SUCCESS, NCDF_SIZE, NCFUNC, moab::WriteNC::VarData::sz, tDim, moab::DebugOutput::tprintf(), moab::WriteNC::usedCoordinates, moab::WriteNC::VarData::varDataType, moab::WriteNC::VarData::varDims, moab::WriteNC::VarData::varId, and moab::WriteNC::varInfo.
Referenced by moab::WriteNC::write_file().
|
protectedpure virtual |
Implemented in moab::NCWriteMPAS, moab::NCWriteHOMME, moab::ScdNCWriteHelper, and moab::NCWriteGCRM.
Referenced by write_values().
|
private |
Definition at line 525 of file NCWriteHelper.cpp.
527 {
528 int success;
529
530 // CAUTION: if the NetCDF ID is from a previous call to ncmpi_create rather than ncmpi_open,
531 // all processors need to call ncmpi_begin_indep_data(). If only the root processor does so,
532 // ncmpi_begin_indep_data() call will be blocked forever :(
533 #ifdef MOAB_HAVE_PNETCDF
534 // Enter independent I/O mode
535 success = NCFUNC( begin_indep_data )( _fileId );
536 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
537 #endif
538
539 int rank = 0;
540 #ifdef MOAB_HAVE_MPI
541 bool& isParallel = _writeNC->isParallel;
542 if( isParallel )
543 {
544 ParallelComm*& myPcomm = _writeNC->myPcomm;
545 rank = myPcomm->proc_config().proc_rank();
546 }
547 #endif
548 if( 0 == rank )
549 {
550 for( unsigned int i = 0; i < vsetdatas.size(); i++ )
551 {
552 WriteNC::VarData& variableData = vsetdatas[i];
553
554 // Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen)
555 if( variableData.has_tsteps )
556 {
557 MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing set variables with timesteps is not implemented yet" );
558 }
559
560 switch( variableData.varDataType )
561 {
562 case NC_DOUBLE:
563 // Independent I/O mode put
564 success = NCFUNCP( _vara_double )( _fileId, variableData.varId, &variableData.writeStarts[0],
565 &variableData.writeCounts[0],
566 (double*)( variableData.memoryHogs[0] ) );
567 if( success )
568 MB_SET_ERR( MB_FAILURE, "Failed to write double data for variable " << variableData.varName );
569 break;
570 case NC_INT:
571 // Independent I/O mode put
572 success =
573 NCFUNCP( _vara_int )( _fileId, variableData.varId, &variableData.writeStarts[0],
574 &variableData.writeCounts[0], (int*)( variableData.memoryHogs[0] ) );
575 if( success )
576 MB_SET_ERR( MB_FAILURE, "Failed to write int data for variable " << variableData.varName );
577 break;
578 default:
579 MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing non-double or non-int data is not implemented yet" );
580 }
581 }
582 }
583
584 #ifdef MOAB_HAVE_PNETCDF
585 // End independent I/O mode
586 success = NCFUNC( end_indep_data )( _fileId );
587 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
588 #endif
589
590 return MB_SUCCESS;
591 }
References _fileId, _writeNC, moab::WriteNC::VarData::has_tsteps, moab::WriteNC::isParallel, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_SUCCESS, moab::WriteNC::VarData::memoryHogs, NCFUNC, NCFUNCP, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::WriteNC::VarData::varDataType, moab::WriteNC::VarData::varId, moab::WriteNC::VarData::varName, moab::WriteNC::VarData::writeCounts, and moab::WriteNC::VarData::writeStarts.
Referenced by write_values().
ErrorCode moab::NCWriteHelper::write_values | ( | std::vector< std::string > & | var_names, |
std::vector< int > & | tstep_nums | ||
) |
Take the info from VarData and write first non-set variables, then set variables.
Definition at line 468 of file NCWriteHelper.cpp.
469 {
470 std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates;
471 std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames;
472 std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo;
473
474 std::vector< WriteNC::VarData > vdatas;
475 std::vector< WriteNC::VarData > vsetdatas;
476
477 // For set variables, include coordinates used by requested var_names
478 for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt )
479 {
480 const std::string& coordName = *setIt;
481
482 // Skip dummy coordinate variables (if any)
483 if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue;
484
485 std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName );
486 if( vit == varInfo.end() )
487 {
488 MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName );
489 }
490
491 vsetdatas.push_back( vit->second );
492 }
493
494 // Collect non-set and set variables from requested var_names
495 for( unsigned int i = 0; i < var_names.size(); i++ )
496 {
497 std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( var_names[i] );
498 if( vit == varInfo.end() )
499 {
500 MB_SET_ERR( MB_FAILURE, "Can't find requested variable " << var_names[i] );
501 }
502
503 WriteNC::VarData& variableData = vit->second;
504 if( WriteNC::ENTLOCSET == variableData.entLoc )
505 {
506 // Used coordinates has all ready been included
507 if( usedCoordinates.find( var_names[i] ) != usedCoordinates.end() ) continue;
508
509 vsetdatas.push_back( variableData );
510 }
511 else
512 vdatas.push_back( variableData );
513 }
514
515 // Assume that the data ranges do not overlap across processors
516 // While overlapped writing might still work, we should better not take that risk
517 write_nonset_variables( vdatas, tstep_nums );
518
519 // Use independent I/O mode put, since this write is only for the root processor
520 write_set_variables( vsetdatas, tstep_nums );
521
522 return MB_SUCCESS;
523 }
References _writeNC, moab::WriteNC::dummyVarNames, moab::WriteNC::VarData::entLoc, moab::WriteNC::ENTLOCSET, MB_SET_ERR, MB_SUCCESS, moab::WriteNC::usedCoordinates, moab::WriteNC::varInfo, write_nonset_variables(), and write_set_variables().
Referenced by moab::WriteNC::write_file().
|
protected |
Cache some information from WriteNC.
Definition at line 63 of file NCWriteHelper.hpp.
Referenced by init_file(), moab::NCWriteGCRM::write_nonset_variables(), moab::ScdNCWriteHelper::write_nonset_variables(), moab::NCWriteHOMME::write_nonset_variables(), moab::NCWriteMPAS::write_nonset_variables(), and write_set_variables().
|
protected |
Definition at line 65 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), and collect_variable_data().
|
protected |
Definition at line 64 of file NCWriteHelper.hpp.
|
protected |
Allow NCWriteHelper to directly access members of WriteNC.
Definition at line 60 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteGCRM::collect_variable_data(), collect_variable_data(), moab::ScdNCWriteHelper::collect_variable_data(), moab::NCWriteHOMME::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), init_file(), moab::NCWriteGCRM::write_nonset_variables(), moab::ScdNCWriteHelper::write_nonset_variables(), moab::NCWriteHOMME::write_nonset_variables(), moab::NCWriteMPAS::write_nonset_variables(), write_set_variables(), and write_values().
|
protected |
Definition at line 71 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteGCRM::collect_variable_data(), collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), and init_file().
|
protected |
Local owned cells, edges and vertices.
Definition at line 74 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteGCRM::write_nonset_variables(), moab::ScdNCWriteHelper::write_nonset_variables(), and moab::NCWriteMPAS::write_nonset_variables().
|
protected |
Definition at line 74 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteGCRM::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), moab::NCWriteGCRM::write_nonset_variables(), and moab::NCWriteMPAS::write_nonset_variables().
|
protected |
Definition at line 74 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteGCRM::write_nonset_variables(), moab::NCWriteHOMME::write_nonset_variables(), and moab::NCWriteMPAS::write_nonset_variables().
|
protected |
Definition at line 68 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), and collect_variable_data().
|
protected |
Dimensions of time and level.
Definition at line 68 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), and collect_variable_data().
|
protected |
Dimension numbers for time and level.
Definition at line 71 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteGCRM::collect_variable_data(), collect_variable_data(), moab::ScdNCWriteHelper::collect_variable_data(), moab::NCWriteHOMME::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), init_file(), moab::NCWriteGCRM::write_nonset_variables(), moab::ScdNCWriteHelper::write_nonset_variables(), moab::NCWriteHOMME::write_nonset_variables(), and moab::NCWriteMPAS::write_nonset_variables().
|
protected |
Time values of output timesteps.
Definition at line 77 of file NCWriteHelper.hpp.
Referenced by collect_variable_data().