moab
ReadGCRM.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines