moab
|
00001 #include "ReadGCRM.hpp" 00002 00003 #include <algorithm> 00004 #include <assert.h> 00005 #include <stdio.h> 00006 #include <string.h> 00007 #include <cmath> 00008 #include <cstdlib> 00009 #include <iostream> 00010 #include <sstream> 00011 #include <map> 00012 #include <dirent.h> 00013 00014 #include "moab/Core.hpp" 00015 #include "moab/ReaderIface.hpp" 00016 #include "moab/ReadUtilIface.hpp" 00017 #include "MBTagConventions.hpp" 00018 #include "moab/FileOptions.hpp" 00019 00020 #define ERRORR(rval, str) \ 00021 if (MB_SUCCESS != rval) {readMeshIface->report_error("%s", str); return rval;} 00022 00023 #define ERRORS(err, str) \ 00024 if (err) {readMeshIface->report_error("%s", str); return MB_FAILURE;} 00025 00026 namespace moab 00027 { 00028 00029 ReaderIface* ReadGCRM::factory(Interface* iface) { 00030 return new ReadGCRM(iface); 00031 } 00032 00033 ReadGCRM::ReadGCRM(Interface* impl) : 00034 CPU_WORD_SIZE(-1), IO_WORD_SIZE(-1), mbImpl(impl), fileId(-1), tMin(-1), tMax(-1), tDim(-1), 00035 numUnLim(-1), mCurrentMeshHandle(0), startVertex(0), startElem(0), mGlobalIdTag(0), max_line_length(-1), 00036 max_str_length(-1), vertexOffset(0), dbgOut(stderr), partMethod(-1), isParallel(false) 00037 00038 #ifdef USE_MPI 00039 , myPcomm(NULL) 00040 #endif 00041 { 00042 assert(impl != NULL); 00043 impl->query_interface(readMeshIface); 00044 } 00045 00046 ReadGCRM::~ReadGCRM() 00047 { 00048 if (readMeshIface) { 00049 mbImpl->release_interface(readMeshIface); 00050 readMeshIface = 0; 00051 } 00052 } 00053 00054 void ReadGCRM::reset() { 00055 CPU_WORD_SIZE = -1; 00056 IO_WORD_SIZE = -1; 00057 fileId = -1; 00058 tMin = tMax = -1; 00059 numUnLim = -1; 00060 mCurrentMeshHandle = 0; 00061 startVertex = startElem = 0; 00062 mGlobalIdTag = 0; 00063 max_line_length = -1; 00064 max_str_length = -1; 00065 vertexOffset = 0; 00066 dbgOut = stderr; 00067 mCurrentMeshHandle = 0; 00068 vertexOffset = 0; 00069 00070 #ifdef USE_MPI 00071 myPcomm = NULL; 00072 #endif 00073 } 00074 00075 ErrorCode ReadGCRM::load_file( const char* /* file_name */, 00076 const EntityHandle* /* file_set*/, 00077 const FileOptions& /* opts */, 00078 const SubsetList* /* subset_list */, 00079 const Tag* /*file_id_tag*/) 00080 { 00081 // guarantee failure for now 00082 return MB_FAILURE; 00083 00084 /* VSM: Temporarily commenting out all the relevant code until the above guaranteed failure is fixed */ 00085 /* 00086 if (subset_list) { 00087 // see src/moab/ReaderIface.hpp, definition of SubsetList struct; this basically specifies 00088 // an integer tag and tag values for sets to read on this proc, or a part number and total # parts 00089 // for reading a trivial partition of entities 00090 } 00091 00092 // save filename to member variable so we don't need to pass as an argument 00093 // to called functions 00094 fileName = file_name; 00095 00096 // process options; see src/FileOptions.hpp for API for FileOptions class, and doc/metadata_info.doc for 00097 // a description of various options used by some of the readers in MOAB 00098 ErrorCode result = process_options(opts); 00099 if (MB_SUCCESS != result) { 00100 readMeshIface->report_error( "%s: problem reading options\n", fileName); 00101 return result; 00102 } 00103 00104 // Open file; filePtr is member of ReadGCRM, change to whatever mechanism is used to identify file 00105 FILE* filePtr = fopen( fileName, "r" ); 00106 if (!filePtr) 00107 { 00108 readMeshIface->report_error( "%s: fopen returned error.\n", fileName); 00109 return MB_FILE_DOES_NOT_EXIST; 00110 } 00111 00112 // read number of verts, elements, sets 00113 long num_verts = 0, num_elems = 0, num_sets = 0; 00114 00115 // read_ents keeps a running set of entities read from this file, including vertices, elements, and sets; 00116 // these will get added to file_set (if input) at the end of the read 00117 Range read_ents; 00118 00119 // start_vertex is passed back so we know how to convert indices from the file into vertex handles; most 00120 // of the time this is done by adding start_vertex to the (0-based) index; if the index is 1-based, you also 00121 // need to subtract one; see read_elements for details 00122 EntityHandle start_vertex; 00123 result = read_vertices(num_verts, start_vertex, read_ents); 00124 if (MB_SUCCESS != result) return result; 00125 00126 // create/read elements; this template assumes that all elements are the same type, so can be read in a single 00127 // call to read_elements, and kept track of with a single start_elem handle. If there are more entity types, 00128 // might have to keep these start handles in an array/vector. start_elem is only really needed if you're reading 00129 // sets later, and need to convert some file-based index to an entity handle 00130 EntityHandle start_elem; 00131 result = read_elements(num_elems, start_vertex, start_elem, read_ents); 00132 if (MB_SUCCESS != result) return result; 00133 00134 // read/create entity sets; typically these sets have some tag identifying what they're for, see doc/metadata_info.doc 00135 // for examples of different kinds of sets and how they're marked 00136 result = create_sets(num_sets, start_vertex, num_verts, start_elem, num_elems, read_ents); 00137 if (MB_SUCCESS != result) return result; 00138 00139 // finally, add all read_ents into the file set, if one was input 00140 if (file_set && *file_set) { 00141 result = mbImpl->add_entities(*file_set, read_ents); 00142 if (MB_SUCCESS != result) return result; 00143 } 00144 00145 return result; 00146 */ 00147 } 00148 00149 ErrorCode ReadGCRM::read_vertices(int num_verts, EntityHandle &start_vertex, Range &read_ents) 00150 { 00151 // allocate nodes; these are allocated in one shot, get contiguous handles starting with start_handle, 00152 // and the reader is passed back double*'s pointing to MOAB's native storage for vertex coordinates 00153 // for those verts 00154 std::vector<double*> coord_arrays; 00155 ErrorCode result = readMeshIface->get_node_coords( 3, num_verts, 1, start_vertex, coord_arrays ); 00156 if (MB_SUCCESS != result) { 00157 readMeshIface->report_error("%s: Trouble reading vertices\n", fileName); 00158 return result; 00159 } 00160 00161 // fill in vertex coordinate arrays 00162 double *x = coord_arrays[0], 00163 *y = coord_arrays[1], 00164 *z = coord_arrays[2]; 00165 for(long i = 0; i < num_verts; ++i) { 00166 // empty statement to avoid compiler warning 00167 if (x || y || z) {} 00168 // read x/y/z 00169 } 00170 00171 if (num_verts) read_ents.insert(start_vertex, start_vertex + num_verts - 1); 00172 00173 return result; 00174 } 00175 00177 ErrorCode ReadGCRM::read_elements(int num_elems, EntityHandle start_vertex, 00178 EntityHandle &start_elem, Range &read_ents) 00179 { 00180 // get the entity type being read 00181 EntityType ent_type = MBHEX; 00182 00183 // get the number of vertices per entity 00184 int verts_per_elem = 8; 00185 00186 // Create the element sequence; passes back a pointer to the internal storage for connectivity and the 00187 // starting entity handle 00188 EntityHandle* conn_array; 00189 ErrorCode result = readMeshIface->get_element_connect( num_elems, verts_per_elem, ent_type, 00190 1, start_elem, conn_array ); 00191 if (MB_SUCCESS != result) { 00192 readMeshIface->report_error("%s: Trouble reading elements\n", fileName); 00193 return result; 00194 } 00195 00196 // read connectivity into conn_array directly 00197 for (long i = 0; i < num_elems; i++) { 00198 // read connectivity 00199 } 00200 00201 // convert file-based connectivity indices to vertex handles in-place; be careful, if indices are smaller than handles, 00202 // need to do from the end of the list so we don't overwrite data 00203 // 00204 // here, we assume indices are smaller than handles, just for demonstration; create an integer-type pointer to connectivity 00205 // initialized to same start of connectivity array 00206 int *ind_array = reinterpret_cast<int*>(conn_array); 00207 // OFFSET is value of first vertex index in file; most files are 1-based, but some might be 0-based 00208 int OFFSET = 1; 00209 for (long i = num_elems*verts_per_elem-1; i >= 0; i--) { 00210 conn_array[i] = ind_array[i] + start_vertex + OFFSET; 00211 00212 // this assert assumes last handle in read_ents is highest vertex handle in this file 00213 assert(conn_array[i] >= start_vertex && conn_array[i] <= *read_ents.rbegin()); 00214 } 00215 00216 // notify MOAB of the new elements 00217 result = readMeshIface->update_adjacencies(start_elem, num_elems, verts_per_elem, conn_array); 00218 if (MB_SUCCESS != result) return result; 00219 00220 // add elements to read_ents 00221 if (num_elems) read_ents.insert(start_elem, start_elem+num_elems-1); 00222 00223 return MB_SUCCESS; 00224 } 00225 00227 ErrorCode ReadGCRM::create_sets(int num_sets, EntityHandle /*start_vertex*/, int /*num_verts*/, 00228 EntityHandle /*start_elem*/, int /*num_elems*/, Range &read_ents) 00229 { 00230 ErrorCode result = MB_SUCCESS; 00231 EntityHandle this_set; 00232 00233 for (int i = 0; i < num_sets; i++) { 00234 // create set 00235 result = mbImpl->create_meshset(MESHSET_SET, this_set); 00236 if (MB_SUCCESS != result) { 00237 readMeshIface->report_error("%s: Trouble creating set.\n", fileName); 00238 return result; 00239 } 00240 00241 Range set_ents; 00242 // read/compute what's in this set; REMEMBER TO CONVERT THESE TO MOAB HANDLES 00243 00244 // add them to the set 00245 result = mbImpl->add_entities(this_set, set_ents); 00246 if (MB_SUCCESS != result) { 00247 readMeshIface->report_error("%s: Trouble putting entities in set.\n", fileName); 00248 return result; 00249 } 00250 00251 // add the new set to read_ents 00252 read_ents.insert(this_set); 00253 } 00254 00255 return MB_SUCCESS; 00256 } 00257 00258 ErrorCode ReadGCRM::process_options(const FileOptions &opts) 00259 { 00260 // mark all options seen, to avoid compile warning on unused variable 00261 opts.mark_all_seen(); 00262 return MB_SUCCESS; 00263 } 00264 00265 ErrorCode ReadGCRM::read_header() { 00266 CPU_WORD_SIZE = sizeof(double); 00267 IO_WORD_SIZE = sizeof(double); 00268 00269 dbgOut.tprint(1, "Reading header...\n"); 00270 00271 // get the global attributes 00272 int numgatts; 00273 int success; 00274 success = NCFUNC(inq_natts )(fileId, &numgatts); 00275 ERRORS(success, "Couldn't get number of global attributes."); 00276 00277 // read attributes into globalAtts 00278 ErrorCode result = get_attributes(NC_GLOBAL, numgatts, globalAtts); 00279 ERRORR(result, "Getting attributes."); 00280 dbgOut.tprintf(1, "Read %u attributes\n", (unsigned int) globalAtts.size()); 00281 00282 // read in dimensions into dimVals 00283 result = get_dimensions(fileId, dimNames, dimVals); 00284 ERRORR(result, "Getting dimensions."); 00285 dbgOut.tprintf(1, "Read %u dimensions\n", (unsigned int) dimVals.size()); 00286 00287 // read in variables into varInfo 00288 result = get_variables(); 00289 ERRORR(result, "Getting variables."); 00290 dbgOut.tprintf(1, "Read %u variables\n", (unsigned int) varInfo.size()); 00291 00292 return MB_SUCCESS; 00293 } 00294 00295 ErrorCode ReadGCRM::get_attributes(int var_id, int num_atts, std::map<std::string, AttData> &atts, const char *prefix) { 00296 00297 char dum_name[120]; 00298 00299 for (int i = 0; i < num_atts; i++) { 00300 // get the name 00301 int success = NCFUNC(inq_attname)(fileId, var_id, i, dum_name); 00302 ERRORS(success, "Trouble getting attribute name."); 00303 00304 AttData &data = atts[std::string(dum_name)]; 00305 data.attName = std::string(dum_name); 00306 success = NCFUNC(inq_att)(fileId, var_id, dum_name, &data.attDataType, &data.attLen); 00307 ERRORS(success, "Trouble getting attribute info."); 00308 data.attVarId = var_id; 00309 00310 dbgOut.tprintf(2, "%sAttribute %s: length=%u, varId=%d, type=%d\n", (prefix ? prefix : ""), data.attName.c_str(), 00311 (unsigned int) data.attLen, data.attVarId, data.attDataType); 00312 } 00313 00314 return MB_SUCCESS; 00315 } 00316 00317 ErrorCode ReadGCRM::get_dimensions(int file_id, std::vector<std::string> &dim_names, std::vector<int> &dim_vals) { 00318 // get the number of dimensions 00319 int num_dims; 00320 int success = NCFUNC(inq_ndims)(file_id, &num_dims); 00321 ERRORS(success, "Trouble getting number of dimensions."); 00322 00323 if (num_dims > NC_MAX_DIMS) { 00324 readMeshIface->report_error("ReadGCRM: File contains %d dims but NetCDF library supports only %d\n", num_dims, (int) NC_MAX_DIMS); 00325 return MB_FAILURE; 00326 } 00327 00328 char dim_name[NC_MAX_NAME + 1]; 00329 NCDF_SIZE dum_len; 00330 dim_names.resize(num_dims); 00331 dim_vals.resize(num_dims); 00332 00333 for (int i = 0; i < num_dims; i++) { 00334 success = NCFUNC(inq_dim)(file_id, i, dim_name, &dum_len); 00335 ERRORS(success, "Trouble getting dimension info."); 00336 00337 dim_vals[i] = dum_len; 00338 dim_names[i] = std::string(dim_name); 00339 00340 dbgOut.tprintf(2, "Dimension %s, length=%u\n", dim_name, (unsigned int) dum_len); 00341 } 00342 00343 return MB_SUCCESS; 00344 } 00345 00346 ErrorCode ReadGCRM::get_variables() { 00347 // first cache the number of time steps 00348 std::vector<std::string>::iterator vit = std::find(dimNames.begin(), dimNames.end(), "time"); 00349 if (vit == dimNames.end()) 00350 vit = std::find(dimNames.begin(), dimNames.end(), "t"); 00351 00352 int ntimes = 0; 00353 if (vit != dimNames.end()) 00354 ntimes = dimVals[vit - dimNames.begin()]; 00355 if (!ntimes) 00356 ntimes = 1; 00357 00358 // get the number of variables 00359 int num_vars; 00360 int success = NCFUNC(inq_nvars)(fileId, &num_vars); 00361 ERRORS(success, "Trouble getting number of variables."); 00362 00363 if (num_vars > NC_MAX_VARS) { 00364 readMeshIface->report_error("ReadGCRM: File contains %d vars but NetCDF library supports only %d\n", num_vars, (int) NC_MAX_VARS); 00365 return MB_FAILURE; 00366 } 00367 00368 char var_name[NC_MAX_NAME + 1]; 00369 int var_ndims; 00370 00371 for (int i = 0; i < num_vars; i++) { 00372 // get the name first, so we can allocate a map iterate for this var 00373 success = NCFUNC(inq_varname )(fileId, i, var_name); 00374 ERRORS(success, "Trouble getting var name."); 00375 VarData &data = varInfo[std::string(var_name)]; 00376 data.varName = std::string(var_name); 00377 data.varId = i; 00378 data.varTags.resize(ntimes, 0); 00379 00380 // get the data type 00381 success = NCFUNC(inq_vartype)(fileId, i, &data.varDataType); 00382 ERRORS(success, "Trouble getting variable data type."); 00383 00384 // get the number of dimensions, then the dimensions 00385 success = NCFUNC(inq_varndims)(fileId, i, &var_ndims); 00386 ERRORS(success, "Trouble getting number of dims of a variable."); 00387 data.varDims.resize(var_ndims); 00388 00389 success = NCFUNC(inq_vardimid)(fileId, i, &data.varDims[0]); 00390 ERRORS(success, "Trouble getting variable dimensions."); 00391 00392 // finally, get the number of attributes, then the attributes 00393 success = NCFUNC(inq_varnatts)(fileId, i, &data.numAtts); 00394 ERRORS(success, "Trouble getting number of dims of a variable."); 00395 00396 // print debug info here so attribute info comes afterwards 00397 dbgOut.tprintf(2, "Variable %s: Id=%d, numAtts=%d, datatype=%d, num_dims=%u\n", data.varName.c_str(), data.varId, data.numAtts, 00398 data.varDataType, (unsigned int) data.varDims.size()); 00399 00400 ErrorCode rval = get_attributes(i, data.numAtts, data.varAtts, " "); 00401 ERRORR(rval, "Trouble getting attributes for a variable."); 00402 00403 } 00404 00405 return MB_SUCCESS; 00406 } 00407 00408 ErrorCode ReadGCRM::read_tag_values(const char*, const char*, const FileOptions&, std::vector<int>&, const SubsetList*) { 00409 return MB_FAILURE; 00410 } 00411 00412 ErrorCode ReadGCRM::create_tags(ScdInterface *scdi, EntityHandle file_set, const std::vector<int>& tstep_nums) { 00413 ErrorCode rval; 00414 std::string tag_name; 00415 00416 // <__NUM_DIMS> 00417 Tag numDimsTag = 0; 00418 tag_name = "__NUM_DIMS"; 00419 int numDims = dimNames.size(); 00420 rval = mbImpl->tag_get_handle(tag_name.c_str(), 1, MB_TYPE_INTEGER, numDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT); 00421 ERRORR(rval, "Trouble creating __NUM_DIMS tag."); 00422 rval = mbImpl->tag_set_data(numDimsTag, &file_set, 1, &numDims); 00423 ERRORR(rval, "Trouble setting data for __NUM_DIMS tag."); 00424 if (MB_SUCCESS == rval) 00425 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00426 00427 // <__NUM_VARS> 00428 Tag numVarsTag = 0; 00429 tag_name = "__NUM_VARS"; 00430 int numVars = varInfo.size(); 00431 rval = mbImpl->tag_get_handle(tag_name.c_str(), 1, MB_TYPE_INTEGER, numVarsTag, MB_TAG_SPARSE | MB_TAG_CREAT); 00432 ERRORR(rval, "Trouble creating __NUM_VARS tag."); 00433 rval = mbImpl->tag_set_data(numVarsTag, &file_set, 1, &numVars); 00434 ERRORR(rval, "Trouble setting data for __NUM_VARS tag."); 00435 if (MB_SUCCESS == rval) 00436 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00437 00438 // <__DIM_NAMES> 00439 Tag dimNamesTag = 0; 00440 tag_name = "__DIM_NAMES"; 00441 std::string dimnames; 00442 unsigned int dimNamesSz = dimNames.size(); 00443 for (unsigned int i = 0; i != dimNamesSz; ++i) { 00444 dimnames.append(dimNames[i]); 00445 dimnames.push_back('\0'); 00446 } 00447 int dimnamesSz = dimnames.size(); 00448 rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, dimNamesTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN); 00449 ERRORR(rval, "Trouble creating __DIM_NAMES tag."); 00450 const void* ptr = dimnames.c_str(); 00451 rval = mbImpl->tag_set_by_ptr(dimNamesTag, &file_set, 1, &ptr, &dimnamesSz); 00452 ERRORR(rval, "Trouble setting data for __DIM_NAMES tag."); 00453 if (MB_SUCCESS == rval) 00454 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00455 00456 // <__VAR_NAMES> 00457 Tag varNamesTag = 0; 00458 tag_name = "__VAR_NAMES"; 00459 std::string varnames; 00460 std::map<std::string, VarData>::iterator mapIter; 00461 for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) { 00462 varnames.append(mapIter->first); 00463 varnames.push_back('\0'); 00464 } 00465 int varnamesSz = varnames.size(); 00466 rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN); 00467 ERRORR(rval, "Trouble creating __VAR_NAMES tag."); 00468 ptr = varnames.c_str(); 00469 rval = mbImpl->tag_set_by_ptr(varNamesTag, &file_set, 1, &ptr, &varnamesSz); 00470 ERRORR(rval, "Trouble setting data for __VAR_NAMES tag."); 00471 if (MB_SUCCESS == rval) 00472 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00473 00474 // __<dim_name>_LOC_MINMAX 00475 for (unsigned int i = 0; i != dimNamesSz; ++i) { 00476 if (dimNames[i] == "time") { 00477 std::stringstream ss_tag_name; 00478 ss_tag_name << "__" << dimNames[i] << "_LOC_MINMAX"; 00479 tag_name = ss_tag_name.str(); 00480 Tag tagh = 0; 00481 std::vector<int> val(2, 0); 00482 val[0] = tMin; 00483 val[1] = tMax; 00484 rval = mbImpl->tag_get_handle(tag_name.c_str(), 2, MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT); 00485 ERRORR(rval, "Trouble creating __<dim_name>_LOC_MINMAX tag."); 00486 rval = mbImpl->tag_set_data(tagh, &file_set, 1, &val[0]); 00487 ERRORR(rval, "Trouble setting data for __<dim_name>_LOC_MINMAX tag."); 00488 if (MB_SUCCESS == rval) 00489 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00490 } 00491 } 00492 00493 // __<dim_name>_LOC_VALS 00494 for (unsigned int i = 0; i != dimNamesSz; ++i) { 00495 if (dimNames[i] != "time") 00496 continue; 00497 std::vector<int> val; 00498 if (!tstep_nums.empty()) 00499 val = tstep_nums; 00500 else { 00501 val.resize(tVals.size()); 00502 for (unsigned int j = 0; j != tVals.size(); ++j) 00503 val[j] = j; 00504 } 00505 Tag tagh = 0; 00506 std::stringstream ss_tag_name; 00507 ss_tag_name << "__" << dimNames[i] << "_LOC_VALS"; 00508 tag_name = ss_tag_name.str(); 00509 rval = mbImpl->tag_get_handle(tag_name.c_str(), val.size(), MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT); 00510 ERRORR(rval, "Trouble creating __<dim_name>_LOC_VALS tag."); 00511 rval = mbImpl->tag_set_data(tagh, &file_set, 1, &val[0]); 00512 ERRORR(rval, "Trouble setting data for __<dim_name>_LOC_VALS tag."); 00513 if (MB_SUCCESS == rval) 00514 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00515 } 00516 00517 // __<var_name>_DIMS 00518 for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) { 00519 Tag varNamesDimsTag = 0; 00520 std::stringstream ss_tag_name; 00521 ss_tag_name << "__" << mapIter->first << "_DIMS"; 00522 tag_name = ss_tag_name.str(); 00523 unsigned int varDimSz = varInfo[mapIter->first].varDims.size(); 00524 if (varDimSz == 0) 00525 continue; 00526 varInfo[mapIter->first].varTags.resize(varDimSz, 0); 00527 for (unsigned int i = 0; i != varDimSz; ++i) { 00528 Tag tmptag = 0; 00529 std::string tmptagname = dimNames[varInfo[mapIter->first].varDims[i]]; 00530 mbImpl->tag_get_handle(tmptagname.c_str(), 0, MB_TYPE_OPAQUE, tmptag, MB_TAG_ANY); 00531 varInfo[mapIter->first].varTags[i] = tmptag; 00532 } 00533 rval = mbImpl->tag_get_handle(tag_name.c_str(), varDimSz, MB_TYPE_HANDLE, varNamesDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT); 00534 ERRORR(rval, "Trouble creating __<var_name>_DIMS tag."); 00535 rval = mbImpl->tag_set_data(varNamesDimsTag, &file_set, 1, &(varInfo[mapIter->first].varTags[0])); 00536 ERRORR(rval, "Trouble setting data for __<var_name>_DIMS tag."); 00537 if (MB_SUCCESS == rval) 00538 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00539 } 00540 00541 // <PARTITION_METHOD> 00542 Tag part_tag = scdi->part_method_tag(); 00543 if (!part_tag) 00544 ERRORR(MB_FAILURE, "Trouble getting partition method tag."); 00545 rval = mbImpl->tag_set_data(part_tag, &file_set, 1, &partMethod); 00546 ERRORR(rval, "Trouble setting data for PARTITION_METHOD tag."); 00547 if (MB_SUCCESS == rval) 00548 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00549 00550 // <__GLOBAL_ATTRIBS> 00551 tag_name = "__GLOBAL_ATTRIBS"; 00552 Tag globalAttTag = 0; 00553 rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, globalAttTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN); 00554 ERRORR(rval, "Trouble creating __GLOBAL_ATTRIBS tag."); 00555 std::string gattVal; 00556 std::vector<int> gattLen; 00557 rval = create_attrib_string(globalAtts, gattVal, gattLen); 00558 ERRORR(rval, "Trouble creating attribute strings."); 00559 const void* gattptr = gattVal.c_str(); 00560 int globalAttSz = gattVal.size(); 00561 rval = mbImpl->tag_set_by_ptr(globalAttTag, &file_set, 1, &gattptr, &globalAttSz); 00562 ERRORR(rval, "Trouble setting data for __GLOBAL_ATTRIBS tag."); 00563 if (MB_SUCCESS == rval) 00564 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00565 00566 // <__GLOBAL_ATTRIBS_LEN> 00567 tag_name = "__GLOBAL_ATTRIBS_LEN"; 00568 Tag globalAttLenTag = 0; 00569 if (gattLen.size() == 0) 00570 gattLen.push_back(0); 00571 rval = mbImpl->tag_get_handle(tag_name.c_str(), gattLen.size(), MB_TYPE_INTEGER, globalAttLenTag, MB_TAG_SPARSE | MB_TAG_CREAT); 00572 ERRORR(rval, "Trouble creating __GLOBAL_ATTRIBS_LEN tag."); 00573 rval = mbImpl->tag_set_data(globalAttLenTag, &file_set, 1, &gattLen[0]); 00574 ERRORR(rval, "Trouble setting data for __GLOBAL_ATTRIBS_LEN tag."); 00575 if (MB_SUCCESS == rval) 00576 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00577 00578 // __<var_name>_ATTRIBS and __<var_name>_ATTRIBS_LEN 00579 for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) { 00580 std::stringstream ssTagName; 00581 ssTagName << "__" << mapIter->first << "_ATTRIBS"; 00582 tag_name = ssTagName.str(); 00583 Tag varAttTag = 0; 00584 rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, varAttTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN); 00585 ERRORR(rval, "Trouble creating __<var_name>_ATTRIBS tag."); 00586 std::string varAttVal; 00587 std::vector<int> varAttLen; 00588 rval = create_attrib_string(mapIter->second.varAtts, varAttVal, varAttLen); 00589 ERRORR(rval, "Trouble creating attribute strings."); 00590 const void* varAttPtr = varAttVal.c_str(); 00591 int varAttSz = varAttVal.size(); 00592 rval = mbImpl->tag_set_by_ptr(varAttTag, &file_set, 1, &varAttPtr, &varAttSz); 00593 ERRORR(rval, "Trouble setting data for __<var_name>_ATTRIBS tag."); 00594 if (MB_SUCCESS == rval) 00595 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00596 if (varAttLen.size() == 0) 00597 varAttLen.push_back(0); 00598 ssTagName << "_LEN"; 00599 tag_name = ssTagName.str(); 00600 Tag varAttLenTag = 0; 00601 rval = mbImpl->tag_get_handle(tag_name.c_str(), varAttLen.size(), MB_TYPE_INTEGER, varAttLenTag, MB_TAG_SPARSE | MB_TAG_CREAT); 00602 ERRORR(rval, "Trouble creating __<var_name>_ATTRIBS_LEN tag."); 00603 rval = mbImpl->tag_set_data(varAttLenTag, &file_set, 1, &varAttLen[0]); 00604 ERRORR(rval, "Trouble setting data for __<var_name>_ATTRIBS_LEN tag."); 00605 if (MB_SUCCESS == rval) 00606 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00607 } 00608 00609 // <__VAR_NAMES_LOCATIONS> 00610 tag_name = "__VAR_NAMES_LOCATIONS"; 00611 Tag varNamesLocsTag = 0; 00612 std::vector<int> varNamesLocs(varInfo.size()); 00613 rval = mbImpl->tag_get_handle(tag_name.c_str(), varNamesLocs.size(), MB_TYPE_INTEGER, varNamesLocsTag, MB_TAG_CREAT 00614 | MB_TAG_SPARSE); 00615 ERRORR(rval, "Trouble creating __VAR_NAMES_LOCATIONS tag."); 00616 for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) { 00617 varNamesLocs[std::distance(varInfo.begin(), mapIter)] = mapIter->second.entLoc; 00618 } 00619 rval = mbImpl->tag_set_data(varNamesLocsTag, &file_set, 1, &varNamesLocs[0]); 00620 ERRORR(rval, "Trouble setting data for __VAR_NAMES_LOCATIONS tag."); 00621 if (MB_SUCCESS == rval) 00622 dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str()); 00623 00624 return MB_SUCCESS; 00625 } 00626 00627 ErrorCode ReadGCRM::create_attrib_string(const std::map<std::string, AttData>& attMap, std::string& attVal, std::vector<int>& attLen) { 00628 int success; 00629 std::stringstream ssAtt; 00630 unsigned int sz = 0; 00631 std::map<std::string, AttData>::const_iterator attIt = attMap.begin(); 00632 for (; attIt != attMap.end(); ++attIt) { 00633 ssAtt << attIt->second.attName; 00634 ssAtt << '\0'; 00635 void* attData = NULL; 00636 switch (attIt->second.attDataType) { 00637 case NC_BYTE: 00638 case NC_CHAR: 00639 sz = attIt->second.attLen; 00640 attData = (char *) malloc(sz); 00641 success = NCFUNC(get_att_text)(fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (char*) attData); 00642 ERRORS(success, "Failed to read attribute char data.") 00643 ; 00644 ssAtt << "char;"; 00645 break; 00646 case NC_DOUBLE: 00647 sz = attIt->second.attLen * sizeof(double); 00648 attData = (double *) malloc(sz); 00649 success = NCFUNC(get_att_double)(fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (double*) attData); 00650 ERRORS(success, "Failed to read attribute double data.") 00651 ; 00652 ssAtt << "double;"; 00653 break; 00654 case NC_FLOAT: 00655 sz = attIt->second.attLen * sizeof(float); 00656 attData = (float *) malloc(sz); 00657 success = NCFUNC(get_att_float)(fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (float*) attData); 00658 ERRORS(success, "Failed to read attribute float data.") 00659 ; 00660 ssAtt << "float;"; 00661 break; 00662 case NC_INT: 00663 sz = attIt->second.attLen * sizeof(int); 00664 attData = (int *) malloc(sz); 00665 success = NCFUNC(get_att_int)(fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (int*) attData); 00666 ERRORS(success, "Failed to read attribute int data.") 00667 ; 00668 ssAtt << "int;"; 00669 break; 00670 case NC_SHORT: 00671 sz = attIt->second.attLen * sizeof(short); 00672 attData = (short *) malloc(sz); 00673 success = NCFUNC(get_att_short)(fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (short*) attData); 00674 ERRORS(success, "Failed to read attribute short data.") 00675 ; 00676 ssAtt << "short;"; 00677 break; 00678 default: 00679 success = 1; 00680 } 00681 char* tmpc = (char *) attData; 00682 for (unsigned int counter = 0; counter != sz; ++counter) 00683 ssAtt << tmpc[counter]; 00684 free(attData); 00685 ssAtt << ';'; 00686 attLen.push_back(ssAtt.str().size() - 1); 00687 } 00688 attVal = ssAtt.str(); 00689 00690 return MB_SUCCESS; 00691 } 00692 00693 } // namespace moab