Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
tool for visualizing multi level tags
To run: VisTags <inp_file> <outfile> -O <read_opts> -t <tags> -l <levels> -d <dim>
In this example, it is shown how to create some simple tags for those tags that come from climate data, multiple levels. you can read directly nc data, or *.h5m file that will have the tag with multi levels output will be a vtk file with dense tags of form tag_name_<level> the tag name might contain a time index too, like T0 or U0 <tag> is a list of tags, separated by commas, no spaces <levels> is a list of levels, separated by commas, no spaces dimension of entities with the tags will be specified with -d (default 2)
an example of use
VisTags gcrm_r3.nc out.vtk -O VARIABLE=u -t u0,u1 -l 0,1,2 -d 2 (we knew that it had variable u in the file, that it had 256 levels, that there are 2 time steps, etc)
or VisTags gcrm_r3.nc out.vtk -t u0 -l 0,1,2 -d 2 (it will read all variables, but we need to know that u0 will be created as a tag)
the out.vtk file will contain u0_0, u0_1, as simple dense double tags
/** @example VisTags.cpp \n * \brief tool for visualizing multi level tags \n * <b>To run</b>: VisTags <inp_file> <outfile> -O <read_opts> -t <tags> -l <levels> -d <dim> \n * * In this example, it is shown how to create some simple tags for those tags that come from * climate data, multiple levels. * you can read directly nc data, or *.h5m file that will have the tag with multi levels * output will be a vtk file with dense tags of form tag_name_<level> * the tag name might contain a time index too, like T0 or U0 * <tag> is a list of tags, separated by commas, no spaces * <levels> is a list of levels, separated by commas, no spaces * dimension of entities with the tags will be specified with -d (default 2) * * an example of use * * VisTags gcrm_r3.nc out.vtk -O VARIABLE=u -t u0,u1 -l 0,1,2 -d 2 * (we knew that it had variable u in the file, that it had 256 levels, that there are 2 time * steps, etc) * * or * VisTags gcrm_r3.nc out.vtk -t u0 -l 0,1,2 -d 2 * (it will read all variables, but we need to know that u0 will be created as a tag) * * the out.vtk file will contain u0_0, u0_1, as simple dense double tags */ #include <iostream> #include <vector> #include <sstream> #include <string> // Include header for MOAB instance and tag conventions #include "moab/Core.hpp" #include "MBTagConventions.hpp" #include "moab/FileOptions.hpp" #ifdef MOAB_HAVE_MPI #include "moab/ParallelComm.hpp" #endif using namespace moab; using namespace std; int main( int argc, char** argv ) { #ifdef MOAB_HAVE_NETCDF #ifdef MOAB_HAVE_MPI MPI_Init( &argc, &argv ); #endif ErrorCode rval; string file_input, file_output; string read_opts, tags; // Tags to write, separated by commas; it is the name of the tag if( argc < 2 ) { file_input = string( MESH_DIR ) + string( "/io/gcrm_r3.nc" ); file_output = "VisTagsOut.vtk"; } else { file_input = argv[1]; file_output = argv[2]; } read_opts = ""; tags = ""; // Instantiate Interface* mb = new( std::nothrow ) Core; if( NULL == mb ) return 1; int dimension = 2; // In MOAB, it may have index after reading (T0, T1, etc) char* levels = NULL; // Levels, separated by commas, no spaces (like 0, 1, 19) if( argc > 3 ) { int index = 3; while( index < argc ) { if( !strcmp( argv[index], "-O" ) ) // This is for reading options, optional read_opts = argv[++index]; if( !strcmp( argv[index], "-t" ) ) tags = argv[++index]; if( !strcmp( argv[index], "-l" ) ) levels = argv[++index]; if( !strcmp( argv[index], "-d" ) ) dimension = atoi( argv[++index] ); index++; } } ostringstream opts; opts << ";;TAGS=" << tags << ";LEVELS=" << levels << "\0"; FileOptions fo( opts.str().c_str() ); vector< string > tagsNames; vector< int > levelsArray; fo.get_strs_option( "TAGS", tagsNames ); fo.get_ints_option( "LEVELS", levelsArray ); // Load the input file with the specified options rval = mb->load_file( file_input.c_str(), 0, read_opts.c_str() );MB_CHK_SET_ERR( rval, "not loading file" ); Range ents; rval = mb->get_entities_by_dimension( 0, dimension, ents );MB_CHK_SET_ERR( rval, "not getting ents" ); // Now create double tags for entities of dimension for( size_t i = 0; i < tagsNames.size(); i++ ) { string tagName = tagsNames[i]; Tag tagh; rval = mb->tag_get_handle( tagName.c_str(), tagh ); if( MB_SUCCESS != rval ) { cout << "not getting tag " << tagName.c_str() << "\n"; continue; } int len = 0; rval = mb->tag_get_length( tagh, len ); if( MB_SUCCESS != rval ) { cout << "not getting tag len " << tagName.c_str() << "\n"; continue; } DataType type; rval = mb->tag_get_data_type( tagh, type ); if( MB_SUCCESS != rval ) { cout << "not getting tag type " << tagName.c_str() << "\n"; continue; } int count; void* dataptr; // Assume double tags, for simplicity rval = mb->tag_iterate( tagh, ents.begin(), ents.end(), count, dataptr ); if( MB_SUCCESS != rval || count != (int)ents.size() ) { cout << "not getting tag iterate right " << tagName.c_str() << "\n"; continue; } // Now create a new tag, with a new name, concatenated, and copy data there , for each level for( size_t j = 0; j < levelsArray.size(); j++ ) { int level = levelsArray[j]; if( level >= len ) { cout << "level too big at " << level << "\n"; continue; } ostringstream newTagName; newTagName << tagName << "_" << level; Tag newTagh; rval = mb->tag_get_handle( newTagName.str().c_str(), 1, type, newTagh, MB_TAG_DENSE | MB_TAG_CREAT ); if( MB_SUCCESS != rval ) { cout << "not getting new tag " << newTagName.str() << "\n"; continue; } void* newDataPtr; rval = mb->tag_iterate( newTagh, ents.begin(), ents.end(), count, newDataPtr ); if( MB_SUCCESS != rval || count != (int)ents.size() ) { cout << "not getting new tag iterate " << newTagName.str() << "\n"; continue; } if( MB_TYPE_DOUBLE == type ) { double* ptrD = (double*)newDataPtr; double* oldData = (double*)dataptr; for( int k = 0; k < count; k++, ptrD++ ) *ptrD = oldData[level + count * k]; } } // for (size_t j = 0; j < levelsArray.size(); j++) mb->tag_delete( tagh ); // No need for the tag anymore, write it to the new file } // for (size_t i = 0; i < tagsNames.size(); i++) rval = mb->write_file( file_output.c_str() );MB_CHK_SET_ERR( rval, "Can't write file " << file_output ); cout << "Successfully wrote file " << file_output << "\n"; delete mb; #ifdef MOAB_HAVE_MPI MPI_Finalize(); #endif #else std::cout << " configure with netcdf for this example to work\n"; #endif return 0; }