Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
moab::NCHelper Class Reference

Helper class to isolate reading of several different nc file formats. More...

#include <NCHelper.hpp>

+ Inheritance diagram for moab::NCHelper:
+ Collaboration diagram for moab::NCHelper:

Classes

class  Node3D

Public Member Functions

 NCHelper (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
virtual ~NCHelper ()
virtual ErrorCode init_mesh_vals ()=0
 Interfaces to be implemented in child classes.
virtual ErrorCode check_existing_mesh ()=0
virtual ErrorCode create_mesh (Range &faces)=0
virtual ErrorCode read_variables (std::vector< std::string > &var_names, std::vector< int > &tstep_nums)=0
virtual std::string get_mesh_type_name ()=0
ErrorCode create_conventional_tags (const std::vector< int > &tstep_nums)
 Create NC conventional tags.
ErrorCode update_time_tag_vals ()
 Update time tag values if timesteps spread across files.

Static Public Member Functions

static NCHelperget_nc_helper (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 Get appropriate helper instance for ReadNC class.

Protected Member Functions

ErrorCode read_variables_setup (std::vector< std::string > &var_names, std::vector< int > &tstep_nums, std::vector< ReadNC::VarData > &vdatas, std::vector< ReadNC::VarData > &vsetdatas)
 Separate set and non-set variables (common to scd mesh and ucd mesh)
ErrorCode read_variables_to_set (std::vector< ReadNC::VarData > &vdatas, std::vector< int > &tstep_nums)
 Read set variables (common to scd mesh and ucd mesh)
ErrorCode read_coordinate (const char *var_name, int lmin, int lmax, std::vector< double > &cvals)
ErrorCode get_tag_to_set (ReadNC::VarData &var_data, int tstep_num, Tag &tagh)
ErrorCode get_tag_to_nonset (ReadNC::VarData &var_data, int tstep_num, Tag &tagh, int num_lev)
ErrorCode create_attrib_string (const std::map< std::string, ReadNC::AttData > &attMap, std::string &attString, std::vector< int > &attLen)
 Create a character string attString of attMap. with '\0' terminating each attribute name, ';' separating the data type and value, and ';' separating one name/data type/value from the next'. attLen stores the end position for each name/data type/ value.
ErrorCode create_dummy_variables ()
 For a dimension that does not have a corresponding coordinate variable (e.g. ncol for HOMME), create a dummy variable with a sparse tag to store the dimension length.

Protected Attributes

ReadNC_readNC
 Allow NCHelper to directly access members of ReadNC.
int _fileId
 Cache some information from ReadNC.
const FileOptions_opts
EntityHandle _fileSet
int nTimeSteps
 Dimensions of time and level.
int nLevels
std::vector< double > tVals
 Values for time and level.
std::vector< double > levVals
int tDim
 Dimension numbers for time and level.
int levDim
std::set< std::string > ignoredVarNames
 Ignored variables.
std::set< std::string > dummyVarNames
 Dummy variables.

Private Member Functions

ErrorCode read_variables_to_set_allocate (std::vector< ReadNC::VarData > &vdatas, std::vector< int > &tstep_nums)
 Used by read_variables_to_set()

Detailed Description

Helper class to isolate reading of several different nc file formats.

Definition at line 24 of file NCHelper.hpp.


Constructor & Destructor Documentation

moab::NCHelper::NCHelper ( ReadNC readNC,
int  fileId,
const FileOptions opts,
EntityHandle  fileSet 
) [inline]

Definition at line 27 of file NCHelper.hpp.

        : _readNC( readNC ), _fileId( fileId ), _opts( opts ), _fileSet( fileSet ), nTimeSteps( 0 ), nLevels( 1 ),
          tDim( -1 ), levDim( -1 )
    {
    }
virtual moab::NCHelper::~NCHelper ( ) [inline, virtual]

Definition at line 32 of file NCHelper.hpp.

{}

Member Function Documentation

ErrorCode moab::NCHelper::create_attrib_string ( const std::map< std::string, ReadNC::AttData > &  attMap,
std::string &  attString,
std::vector< int > &  attLen 
) [protected]

Create a character string attString of attMap. with '\0' terminating each attribute name, ';' separating the data type and value, and ';' separating one name/data type/value from the next'. attLen stores the end position for each name/data type/ value.

Definition at line 676 of file NCHelper.cpp.

References _fileId, MB_SET_ERR, MB_SUCCESS, and NCFUNC.

Referenced by create_conventional_tags().

{
    int success;
    std::stringstream ssAtt;
    unsigned int sz                                                = 0;
    std::map< std::string, ReadNC::AttData >::const_iterator attIt = attMap.begin();
    for( ; attIt != attMap.end(); ++attIt )
    {
        ssAtt << attIt->second.attName;
        ssAtt << '\0';
        void* attData = NULL;
        switch( attIt->second.attDataType )
        {
            case NC_BYTE:
            case NC_CHAR:
                sz      = attIt->second.attLen;
                attData = (char*)malloc( sz );
                success = NCFUNC( get_att_text )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
                                                  (char*)attData );
                if( success )
                    MB_SET_ERR( MB_FAILURE, "Failed to read byte/char data for attribute " << attIt->second.attName );
                ssAtt << "char;";
                break;
            case NC_SHORT:
                sz      = attIt->second.attLen * sizeof( short );
                attData = (short*)malloc( sz );
                success = NCFUNC( get_att_short )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
                                                   (short*)attData );
                if( success )
                    MB_SET_ERR( MB_FAILURE, "Failed to read short data for attribute " << attIt->second.attName );
                ssAtt << "short;";
                break;
            case NC_INT:
                sz      = attIt->second.attLen * sizeof( int );
                attData = (int*)malloc( sz );
                success = NCFUNC( get_att_int )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
                                                 (int*)attData );
                if( success )
                    MB_SET_ERR( MB_FAILURE, "Failed to read int data for attribute " << attIt->second.attName );
                ssAtt << "int;";
                break;
            case NC_FLOAT:
                sz      = attIt->second.attLen * sizeof( float );
                attData = (float*)malloc( sz );
                success = NCFUNC( get_att_float )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
                                                   (float*)attData );
                if( success )
                    MB_SET_ERR( MB_FAILURE, "Failed to read float data for attribute " << attIt->second.attName );
                ssAtt << "float;";
                break;
            case NC_DOUBLE:
                sz      = attIt->second.attLen * sizeof( double );
                attData = (double*)malloc( sz );
                success = NCFUNC( get_att_double )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
                                                    (double*)attData );
                if( success )
                    MB_SET_ERR( MB_FAILURE, "Failed to read double data for attribute " << attIt->second.attName );
                ssAtt << "double;";
                break;
            default:
                MB_SET_ERR( MB_FAILURE, "Unexpected data type for attribute " << attIt->second.attName );
        }
        char* tmpc = (char*)attData;
        for( unsigned int counter = 0; counter != sz; ++counter )
            ssAtt << tmpc[counter];
        free( attData );
        ssAtt << ';';
        attLen.push_back( ssAtt.str().size() - 1 );
    }
    attVal = ssAtt.str();

    return MB_SUCCESS;
}
ErrorCode moab::NCHelper::create_conventional_tags ( const std::vector< int > &  tstep_nums)

Create NC conventional tags.

Definition at line 73 of file NCHelper.cpp.

References _fileSet, _readNC, create_attrib_string(), moab::ReadNC::dbgOut, moab::ReadNC::dimLens, moab::ReadNC::dimNames, dummyVarNames, ErrorCode, get_mesh_type_name(), moab::ReadNC::globalAtts, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_ANY, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TAG_VARLEN, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, moab::ReadNC::mbImpl, nTimeSteps, moab::ScdInterface::part_method_tag(), moab::ReadNC::partMethod, moab::ReadNC::scdi, moab::Interface::tag_get_handle(), moab::Interface::tag_set_by_ptr(), moab::Interface::tag_set_data(), moab::DebugOutput::tprintf(), tVals, and moab::ReadNC::varInfo.

Referenced by moab::ReadNC::load_file().

{
    Interface*& mbImpl                                   = _readNC->mbImpl;
    std::vector< std::string >& dimNames                 = _readNC->dimNames;
    std::vector< int >& dimLens                          = _readNC->dimLens;
    std::map< std::string, ReadNC::AttData >& globalAtts = _readNC->globalAtts;
    std::map< std::string, ReadNC::VarData >& varInfo    = _readNC->varInfo;
    DebugOutput& dbgOut                                  = _readNC->dbgOut;
    int& partMethod                                      = _readNC->partMethod;
    ScdInterface* scdi                                   = _readNC->scdi;

    ErrorCode rval;
    std::string tag_name;

    // <__NUM_DIMS>
    Tag numDimsTag = 0;
    tag_name       = "__NUM_DIMS";
    int numDims    = dimNames.size();
    rval = mbImpl->tag_get_handle( tag_name.c_str(), 1, MB_TYPE_INTEGER, numDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    rval = mbImpl->tag_set_data( numDimsTag, &_fileSet, 1, &numDims );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // <__NUM_VARS>
    Tag numVarsTag = 0;
    tag_name       = "__NUM_VARS";
    int numVars    = varInfo.size();
    rval = mbImpl->tag_get_handle( tag_name.c_str(), 1, MB_TYPE_INTEGER, numVarsTag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    rval = mbImpl->tag_set_data( numVarsTag, &_fileSet, 1, &numVars );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // <__DIM_NAMES>
    Tag dimNamesTag = 0;
    tag_name        = "__DIM_NAMES";
    std::string dimnames;
    unsigned int dimNamesSz = dimNames.size();
    for( unsigned int i = 0; i != dimNamesSz; i++ )
    {
        dimnames.append( dimNames[i] );
        dimnames.push_back( '\0' );
    }
    int dimnamesSz = dimnames.size();
    rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, dimNamesTag,
                                             MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    const void* ptr = dimnames.c_str();
    rval            = mbImpl->tag_set_by_ptr( dimNamesTag, &_fileSet, 1, &ptr, &dimnamesSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // <__DIM_LENS>
    Tag dimLensTag = 0;
    tag_name       = "__DIM_LENS";
    int dimLensSz  = dimLens.size();
    rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, dimLensTag,
                                             MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    ptr  = &( dimLens[0] );
    rval = mbImpl->tag_set_by_ptr( dimLensTag, &_fileSet, 1, &ptr, &dimLensSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // <__VAR_NAMES>
    Tag varNamesTag = 0;
    tag_name        = "__VAR_NAMES";
    std::string varnames;
    std::map< std::string, ReadNC::VarData >::iterator mapIter;
    for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
    {
        varnames.append( mapIter->first );
        varnames.push_back( '\0' );
    }
    int varnamesSz = varnames.size();
    rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag,
                                             MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    ptr  = varnames.c_str();
    rval = mbImpl->tag_set_by_ptr( varNamesTag, &_fileSet, 1, &ptr, &varnamesSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // __<dim_name>_LOC_MINMAX (for time)
    for( unsigned int i = 0; i != dimNamesSz; i++ )
    {
        if( dimNames[i] == "time" || dimNames[i] == "Time" || dimNames[i] == "t" )
        {
            // some files might have Time dimension as 0, it will not appear in any
            // variables, so skip it
            if( nTimeSteps == 0 ) continue;
            std::stringstream ss_tag_name;
            ss_tag_name << "__" << dimNames[i] << "_LOC_MINMAX";
            tag_name = ss_tag_name.str();
            Tag tagh = 0;
            std::vector< int > val( 2, 0 );
            val[0] = 0;
            val[1] = nTimeSteps - 1;
            rval   = mbImpl->tag_get_handle( tag_name.c_str(), 2, MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
            rval = mbImpl->tag_set_data( tagh, &_fileSet, 1, &val[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
            dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
        }
    }

    // __<dim_name>_LOC_VALS (for time)
    for( unsigned int i = 0; i != dimNamesSz; i++ )
    {
        if( dimNames[i] == "time" || dimNames[i] == "Time" || dimNames[i] == "t" )
        {
            std::vector< int > val;
            if( !tstep_nums.empty() )
                val = tstep_nums;
            else
            {
                // some files might have Time dimension as 0, it will not appear in any
                // variables, so skip it
                if( tVals.empty() ) continue;
                val.resize( tVals.size() );
                for( unsigned int j = 0; j != tVals.size(); j++ )
                    val[j] = j;
            }
            Tag tagh = 0;
            std::stringstream ss_tag_name;
            ss_tag_name << "__" << dimNames[i] << "_LOC_VALS";
            tag_name = ss_tag_name.str();
            rval     = mbImpl->tag_get_handle( tag_name.c_str(), val.size(), MB_TYPE_INTEGER, tagh,
                                               MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
            rval = mbImpl->tag_set_data( tagh, &_fileSet, 1, &val[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
            dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
        }
    }

    // __<var_name>_DIMS
    for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
    {
        Tag varNamesDimsTag = 0;
        std::stringstream ss_tag_name;
        ss_tag_name << "__" << mapIter->first << "_DIMS";
        tag_name              = ss_tag_name.str();
        unsigned int varDimSz = varInfo[mapIter->first].varDims.size();
        if( varDimSz == 0 ) continue;
        std::vector< Tag > varDimTags( varDimSz );
        for( unsigned int i = 0; i != varDimSz; i++ )
        {
            Tag tmptag             = 0;
            std::string tmptagname = dimNames[varInfo[mapIter->first].varDims[i]];
            rval = mbImpl->tag_get_handle( tmptagname.c_str(), 0, MB_TYPE_OPAQUE, tmptag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting tag " << tmptagname );
            varDimTags[i] = tmptag;
        }
        // rval = mbImpl->tag_get_handle(tag_name.c_str(), varDimSz, MB_TYPE_HANDLE,
        // varNamesDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT); We should not use MB_TYPE_HANDLE for Tag
        // here. Tag is a pointer, which is 4 bytes on 32 bit machines and 8 bytes on 64 bit
        // machines. Normally, entity handle is 8 bytes on 64 bit machines, but it can also be
        // configured to 4 bytes.
        rval = mbImpl->tag_get_handle( tag_name.c_str(), varDimSz * sizeof( Tag ), MB_TYPE_OPAQUE, varNamesDimsTag,
                                       MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
        rval = mbImpl->tag_set_data( varNamesDimsTag, &_fileSet, 1, &( varDimTags[0] ) );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
        dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
    }

    // <PARTITION_METHOD>
    Tag part_tag = scdi->part_method_tag();
    if( !part_tag ) MB_SET_ERR( MB_FAILURE, "Trouble getting PARTITION_METHOD tag" );
    rval = mbImpl->tag_set_data( part_tag, &_fileSet, 1, &partMethod );MB_CHK_SET_ERR( rval, "Trouble setting data to PARTITION_METHOD tag" );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // <__GLOBAL_ATTRIBS>
    tag_name         = "__GLOBAL_ATTRIBS";
    Tag globalAttTag = 0;
    rval             = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, globalAttTag,
                                               MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    std::string gattVal;
    std::vector< int > gattLen;
    rval = create_attrib_string( globalAtts, gattVal, gattLen );MB_CHK_SET_ERR( rval, "Trouble creating global attribute string" );
    const void* gattptr = gattVal.c_str();
    int globalAttSz     = gattVal.size();
    rval                = mbImpl->tag_set_by_ptr( globalAttTag, &_fileSet, 1, &gattptr, &globalAttSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // <__GLOBAL_ATTRIBS_LEN>
    tag_name            = "__GLOBAL_ATTRIBS_LEN";
    Tag globalAttLenTag = 0;
    if( gattLen.size() == 0 ) gattLen.push_back( 0 );
    rval = mbImpl->tag_get_handle( tag_name.c_str(), gattLen.size(), MB_TYPE_INTEGER, globalAttLenTag,
                                   MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    rval = mbImpl->tag_set_data( globalAttLenTag, &_fileSet, 1, &gattLen[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // __<var_name>_ATTRIBS and __<var_name>_ATTRIBS_LEN
    for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
    {
        std::stringstream ssTagName;
        ssTagName << "__" << mapIter->first << "_ATTRIBS";
        tag_name      = ssTagName.str();
        Tag varAttTag = 0;
        rval          = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varAttTag,
                                                MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );

        std::string varAttVal;
        std::vector< int > varAttLen;
        if( mapIter->second.numAtts < 1 )
        {
            if( dummyVarNames.find( mapIter->first ) != dummyVarNames.end() )
            {
                // This variable is a dummy coordinate variable
                varAttVal = "DUMMY_VAR";
            }
            else
            {
                // This variable has no attributes
                varAttVal = "NO_ATTRIBS";
            }
        }
        else
        {
            rval = create_attrib_string( mapIter->second.varAtts, varAttVal, varAttLen );MB_CHK_SET_ERR( rval, "Trouble creating attribute string for variable " << mapIter->first );
        }
        const void* varAttPtr = varAttVal.c_str();
        int varAttSz          = varAttVal.size();
        if( 0 == varAttSz ) varAttSz = 1;
        rval = mbImpl->tag_set_by_ptr( varAttTag, &_fileSet, 1, &varAttPtr, &varAttSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
        dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

        ssTagName << "_LEN";
        tag_name         = ssTagName.str();
        Tag varAttLenTag = 0;
        if( 0 == varAttLen.size() ) varAttLen.push_back( 0 );
        rval = mbImpl->tag_get_handle( tag_name.c_str(), varAttLen.size(), MB_TYPE_INTEGER, varAttLenTag,
                                       MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
        rval = mbImpl->tag_set_data( varAttLenTag, &_fileSet, 1, &varAttLen[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
        dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
    }

    // <__VAR_NAMES_LOCATIONS>
    tag_name            = "__VAR_NAMES_LOCATIONS";
    Tag varNamesLocsTag = 0;
    std::vector< int > varNamesLocs( varInfo.size() );
    rval = mbImpl->tag_get_handle( tag_name.c_str(), varNamesLocs.size(), MB_TYPE_INTEGER, varNamesLocsTag,
                                   MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
    {
        varNamesLocs[std::distance( varInfo.begin(), mapIter )] = mapIter->second.entLoc;
    }
    rval = mbImpl->tag_set_data( varNamesLocsTag, &_fileSet, 1, &varNamesLocs[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    // <__MESH_TYPE>
    Tag meshTypeTag          = 0;
    tag_name                 = "__MESH_TYPE";
    std::string meshTypeName = get_mesh_type_name();

    rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, meshTypeTag,
                                   MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
    ptr      = meshTypeName.c_str();
    int leng = meshTypeName.size();
    rval     = mbImpl->tag_set_by_ptr( meshTypeTag, &_fileSet, 1, &ptr, &leng );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
    dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );

    return MB_SUCCESS;
}

For a dimension that does not have a corresponding coordinate variable (e.g. ncol for HOMME), create a dummy variable with a sparse tag to store the dimension length.

Definition at line 752 of file NCHelper.cpp.

References _fileSet, _readNC, moab::ReadNC::dbgOut, moab::ReadNC::dimLens, moab::ReadNC::dimNames, dummyVarNames, moab::ReadNC::VarData::entLoc, moab::ReadNC::ENTLOCSET, ErrorCode, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TAG_VARLEN, MB_TYPE_INTEGER, moab::ReadNC::mbImpl, moab::ReadNC::VarData::numAtts, size, moab::Interface::tag_get_handle(), moab::Interface::tag_set_by_ptr(), moab::DebugOutput::tprintf(), moab::ReadNC::VarData::varDataType, moab::ReadNC::VarData::varDims, moab::ReadNC::VarData::varId, moab::ReadNC::varInfo, moab::ReadNC::VarData::varName, and moab::ReadNC::VarData::varTags.

Referenced by moab::NCHelperHOMME::init_mesh_vals(), moab::NCHelperFV::init_mesh_vals(), and moab::NCHelperEuler::init_mesh_vals().

{
    Interface*& mbImpl                                = _readNC->mbImpl;
    std::vector< std::string >& dimNames              = _readNC->dimNames;
    std::vector< int >& dimLens                       = _readNC->dimLens;
    std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
    DebugOutput& dbgOut                               = _readNC->dbgOut;

    // Hack: look at all dimensions, and see if we have one that does not appear in the list of
    // varInfo names Right now, candidates are from unstructured meshes, such as ncol (HOMME) and
    // nCells (MPAS) For each of them, create a dummy coordinate variable with a sparse tag to store
    // the dimension length
    for( unsigned int i = 0; i < dimNames.size(); i++ )
    {
        // If there is a variable with this dimension name, skip
        if( varInfo.find( dimNames[i] ) != varInfo.end() ) continue;

        // Create a dummy coordinate variable
        int sizeTotalVar = varInfo.size();
        std::string var_name( dimNames[i] );
        ReadNC::VarData& data = varInfo[var_name];
        data.varName          = var_name;
        data.varId            = sizeTotalVar;
        data.varTags.resize( 1, 0 );
        data.varDataType = NC_INT;
        data.varDims.resize( 1 );
        data.varDims[0] = (int)i;
        data.numAtts    = 0;
        data.entLoc     = ReadNC::ENTLOCSET;
        dummyVarNames.insert( var_name );
        dbgOut.tprintf( 2, "Dummy coordinate variable created for dimension %s\n", var_name.c_str() );

        // Create a corresponding sparse tag
        Tag tagh;
        ErrorCode rval = mbImpl->tag_get_handle( var_name.c_str(), 0, MB_TYPE_INTEGER, tagh,
                                                 MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag for dummy coordinate variable " << var_name );

        // Tag value is the dimension length
        const void* ptr = &dimLens[i];
        // Tag size is 1
        int size = 1;
        rval     = mbImpl->tag_set_by_ptr( tagh, &_fileSet, 1, &ptr, &size );MB_CHK_SET_ERR( rval, "Trouble setting tag data for dummy coordinate variable " << var_name );

        dbgOut.tprintf( 2, "Sparse tag created for dimension %s\n", var_name.c_str() );
    }

    return MB_SUCCESS;
}
NCHelper * moab::NCHelper::get_nc_helper ( ReadNC readNC,
int  fileId,
const FileOptions opts,
EntityHandle  fileSet 
) [static]

Get appropriate helper instance for ReadNC class.

Definition at line 23 of file NCHelper.cpp.

References moab::NCHelperHOMME::can_read_file(), moab::NCHelperDomain::can_read_file(), moab::NCHelperGCRM::can_read_file(), moab::NCHelperScrip::can_read_file(), moab::NCHelperMPAS::can_read_file(), moab::NCHelperFV::can_read_file(), moab::NCHelperEuler::can_read_file(), moab::ReadNC::globalAtts, and NCFUNC.

Referenced by moab::ReadNC::load_file().

{
    // Check if CF convention is being followed
    bool is_CF = false;

    std::map< std::string, ReadNC::AttData >& globalAtts     = readNC->globalAtts;
    std::map< std::string, ReadNC::AttData >::iterator attIt = globalAtts.find( "conventions" );
    if( attIt == globalAtts.end() ) attIt = globalAtts.find( "Conventions" );

    if( attIt != globalAtts.end() )
    {
        unsigned int sz = attIt->second.attLen;
        std::string att_data;
        att_data.resize( sz + 1 );
        att_data[sz] = '\000';
        int success =
            NCFUNC( get_att_text )( fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &att_data[0] );
        if( 0 == success && att_data.find( "CF" ) != std::string::npos ) is_CF = true;
    }

    if( is_CF )
    {
        if( NCHelperEuler::can_read_file( readNC, fileId ) )
            return new( std::nothrow ) NCHelperEuler( readNC, fileId, opts, fileSet );
        else if( NCHelperFV::can_read_file( readNC, fileId ) )
            return new( std::nothrow ) NCHelperFV( readNC, fileId, opts, fileSet );
        else if( NCHelperHOMME::can_read_file( readNC, fileId ) )
            return new( std::nothrow ) NCHelperHOMME( readNC, fileId, opts, fileSet );
        else if( NCHelperDomain::can_read_file( readNC, fileId ) )
            return new( std::nothrow ) NCHelperDomain( readNC, fileId, opts, fileSet );
    }
    else
    {
        if( NCHelperMPAS::can_read_file( readNC ) )
            return new( std::nothrow ) NCHelperMPAS( readNC, fileId, opts, fileSet );
        // For a HOMME connectivity file, there might be no CF convention
        else if( NCHelperHOMME::can_read_file( readNC, fileId ) )
            return new( std::nothrow ) NCHelperHOMME( readNC, fileId, opts, fileSet );
        // gcrm reader
        else if( NCHelperGCRM::can_read_file( readNC ) )
            return new( std::nothrow ) NCHelperGCRM( readNC, fileId, opts, fileSet );
    }
    // SCRIP can be CF or non CF, if it comes from MPAS :)
    if( NCHelperScrip::can_read_file( readNC, fileId ) )
        return new( std::nothrow ) NCHelperScrip( readNC, fileId, opts, fileSet );

    // Unknown NetCDF grid (will fill this in later for POP, CICE and CLM)
    return NULL;
}
ErrorCode moab::NCHelper::get_tag_to_nonset ( ReadNC::VarData var_data,
int  tstep_num,
Tag tagh,
int  num_lev 
) [protected]

Definition at line 637 of file NCHelper.cpp.

References _readNC, moab::ReadNC::dbgOut, ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, moab::ReadNC::mbImpl, moab::Interface::tag_get_handle(), moab::DebugOutput::tprintf(), moab::ReadNC::tStepBase, moab::ReadNC::VarData::varDataType, and moab::ReadNC::VarData::varName.

Referenced by moab::ScdNCHelper::read_scd_variables_to_nonset_allocate(), and moab::NCHelperHOMME::read_ucd_variables_to_nonset_allocate().

{
    Interface*& mbImpl  = _readNC->mbImpl;
    DebugOutput& dbgOut = _readNC->dbgOut;
    int& tStepBase      = _readNC->tStepBase;

    if( tStepBase > 0 ) tstep_num += tStepBase;

    std::ostringstream tag_name;
    tag_name << var_data.varName << tstep_num;

    ErrorCode rval = MB_SUCCESS;
    tagh           = 0;
    switch( var_data.varDataType )
    {
        case NC_BYTE:
        case NC_CHAR:
            rval = mbImpl->tag_get_handle( tag_name.str().c_str(), num_lev, MB_TYPE_OPAQUE, tagh,
                                           MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
            break;
        case NC_SHORT:
        case NC_INT:
            rval = mbImpl->tag_get_handle( tag_name.str().c_str(), num_lev, MB_TYPE_INTEGER, tagh,
                                           MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
            break;
        case NC_FLOAT:
        case NC_DOUBLE:
            rval = mbImpl->tag_get_handle( tag_name.str().c_str(), num_lev, MB_TYPE_DOUBLE, tagh,
                                           MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
            break;
        default:
            MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << var_data.varName );
    }

    dbgOut.tprintf( 2, "Tag %s created\n", tag_name.str().c_str() );

    return rval;
}
ErrorCode moab::NCHelper::get_tag_to_set ( ReadNC::VarData var_data,
int  tstep_num,
Tag tagh 
) [protected]

Definition at line 595 of file NCHelper.cpp.

References _readNC, moab::ReadNC::dbgOut, ErrorCode, moab::ReadNC::VarData::has_tsteps, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TAG_VARLEN, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, moab::ReadNC::mbImpl, moab::Interface::tag_get_handle(), moab::DebugOutput::tprintf(), moab::ReadNC::tStepBase, moab::ReadNC::VarData::varDataType, and moab::ReadNC::VarData::varName.

Referenced by read_variables_to_set_allocate().

{
    Interface*& mbImpl  = _readNC->mbImpl;
    DebugOutput& dbgOut = _readNC->dbgOut;
    int& tStepBase      = _readNC->tStepBase;

    if( tStepBase > 0 ) tstep_num += tStepBase;

    std::ostringstream tag_name;
    if( var_data.has_tsteps )
        tag_name << var_data.varName << tstep_num;
    else
        tag_name << var_data.varName;

    ErrorCode rval = MB_SUCCESS;
    tagh           = 0;
    switch( var_data.varDataType )
    {
        case NC_BYTE:
        case NC_CHAR:
            rval = mbImpl->tag_get_handle( tag_name.str().c_str(), 0, MB_TYPE_OPAQUE, tagh,
                                           MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
            break;
        case NC_SHORT:
        case NC_INT:
            rval = mbImpl->tag_get_handle( tag_name.str().c_str(), 0, MB_TYPE_INTEGER, tagh,
                                           MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
            break;
        case NC_FLOAT:
        case NC_DOUBLE:
            rval = mbImpl->tag_get_handle( tag_name.str().c_str(), 0, MB_TYPE_DOUBLE, tagh,
                                           MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
            break;
        default:
            MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << var_data.varName );
    }

    dbgOut.tprintf( 2, "Tag %s created\n", tag_name.str().c_str() );

    return rval;
}
ErrorCode moab::NCHelper::read_coordinate ( const char *  var_name,
int  lmin,
int  lmax,
std::vector< double > &  cvals 
) [protected]

Definition at line 563 of file NCHelper.cpp.

References _fileId, _readNC, MB_SET_ERR, MB_SUCCESS, NCDF_DIFF, NCDF_SIZE, NCFUNCAG, and moab::ReadNC::varInfo.

Referenced by moab::NCHelperHOMME::init_mesh_vals(), moab::NCHelperMPAS::init_mesh_vals(), moab::NCHelperFV::init_mesh_vals(), moab::NCHelperGCRM::init_mesh_vals(), and moab::NCHelperEuler::init_mesh_vals().

{
    std::map< std::string, ReadNC::VarData >& varInfo       = _readNC->varInfo;
    std::map< std::string, ReadNC::VarData >::iterator vmit = varInfo.find( var_name );
    if( varInfo.end() == vmit ) MB_SET_ERR( MB_FAILURE, "Couldn't find variable " << var_name );

    assert( lmin >= 0 && lmax >= lmin );
    NCDF_SIZE tstart     = lmin;
    NCDF_SIZE tcount     = lmax - lmin + 1;
    NCDF_DIFF dum_stride = 1;
    int success;

    // Check size
    if( (std::size_t)tcount != cvals.size() ) cvals.resize( tcount );

    // Check to make sure it's a float or double
    switch( ( *vmit ).second.varDataType )
    {
        case NC_FLOAT:
        case NC_DOUBLE:
            // Read float as double
            success =
                NCFUNCAG( _vars_double )( _fileId, ( *vmit ).second.varId, &tstart, &tcount, &dum_stride, &cvals[0] );
            if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read float/double data for variable " << var_name );
            break;
        default:
            MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << var_name );
    }

    return MB_SUCCESS;
}
virtual ErrorCode moab::NCHelper::read_variables ( std::vector< std::string > &  var_names,
std::vector< int > &  tstep_nums 
) [pure virtual]

Implemented in moab::UcdNCHelper, and moab::ScdNCHelper.

Referenced by moab::ReadNC::load_file().

ErrorCode moab::NCHelper::read_variables_setup ( std::vector< std::string > &  var_names,
std::vector< int > &  tstep_nums,
std::vector< ReadNC::VarData > &  vdatas,
std::vector< ReadNC::VarData > &  vsetdatas 
) [protected]

Separate set and non-set variables (common to scd mesh and ucd mesh)

Definition at line 374 of file NCHelper.cpp.

References _readNC, moab::ReadNC::dimNames, dummyVarNames, moab::ReadNC::VarData::entLoc, moab::ReadNC::ENTLOCSET, ignoredVarNames, MB_SET_ERR, MB_SUCCESS, nTimeSteps, tDim, moab::ReadNC::varInfo, and moab::ReadNC::VarData::varName.

Referenced by moab::ScdNCHelper::read_variables(), and moab::UcdNCHelper::read_variables().

{
    std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
    std::vector< std::string >& dimNames              = _readNC->dimNames;

    std::map< std::string, ReadNC::VarData >::iterator mit;

    // If empty read them all (except ignored variables)
    if( var_names.empty() )
    {
        for( mit = varInfo.begin(); mit != varInfo.end(); ++mit )
        {
            ReadNC::VarData vd = ( *mit ).second;

            // If read all variables at once, skip ignored ones
            if( ignoredVarNames.find( vd.varName ) != ignoredVarNames.end() ) continue;

            // Coordinate variables (include dummy ones) were read to the file set by default
            if( std::find( dimNames.begin(), dimNames.end(), vd.varName ) != dimNames.end() ) continue;

            if( vd.entLoc == ReadNC::ENTLOCSET )
                vsetdatas.push_back( vd );
            else
                vdatas.push_back( vd );
        }
    }
    else
    {
        // Read specified variables (might include ignored ones)
        for( unsigned int i = 0; i < var_names.size(); i++ )
        {
            mit = varInfo.find( var_names[i] );
            if( mit != varInfo.end() )
            {
                ReadNC::VarData vd = ( *mit ).second;

                // Upon creation of dummy coordinate variables, tag values have already been set
                if( dummyVarNames.find( vd.varName ) != dummyVarNames.end() ) continue;

                if( vd.entLoc == ReadNC::ENTLOCSET )
                    vsetdatas.push_back( vd );
                else
                    vdatas.push_back( vd );
            }
            else
            {
                MB_SET_ERR( MB_FAILURE, "Couldn't find specified variable " << var_names[i] );
            }
        }
    }

    if( tstep_nums.empty() && nTimeSteps > 0 )
    {
        // No timesteps input, get them all
        for( int i = 0; i < nTimeSteps; i++ )
            tstep_nums.push_back( i );
    }

    if( !tstep_nums.empty() )
    {
        for( unsigned int i = 0; i < vdatas.size(); i++ )
        {
            vdatas[i].varTags.resize( tstep_nums.size(), 0 );
            vdatas[i].varDatas.resize( tstep_nums.size() );
            // NC reader assumes that non-set variables always have timesteps
            assert( std::find( vdatas[i].varDims.begin(), vdatas[i].varDims.end(), tDim ) != vdatas[i].varDims.end() );
            vdatas[i].has_tsteps = true;
        }

        for( unsigned int i = 0; i < vsetdatas.size(); i++ )
        {
            if( ( std::find( vsetdatas[i].varDims.begin(), vsetdatas[i].varDims.end(), tDim ) !=
                  vsetdatas[i].varDims.end() ) &&
                ( vsetdatas[i].varName != dimNames[tDim] ) )
            {
                // Set variables with timesteps: e.g. xtime(Time) or xtime(Time, StrLen)
                vsetdatas[i].varTags.resize( tstep_nums.size(), 0 );
                vsetdatas[i].varDatas.resize( tstep_nums.size() );
                vsetdatas[i].has_tsteps = true;
            }
            else
            {
                // Set variables without timesteps: no time dimension, or time itself
                vsetdatas[i].varTags.resize( 1, 0 );
                vsetdatas[i].varDatas.resize( 1 );
                vsetdatas[i].has_tsteps = false;
            }
        }
    }

    return MB_SUCCESS;
}
ErrorCode moab::NCHelper::read_variables_to_set ( std::vector< ReadNC::VarData > &  vdatas,
std::vector< int > &  tstep_nums 
) [protected]

Read set variables (common to scd mesh and ucd mesh)

Definition at line 470 of file NCHelper.cpp.

References _fileId, _fileSet, _readNC, moab::ReadNC::dbgOut, ErrorCode, moab::DebugOutput::get_verbosity(), MB_CHK_SET_ERR, MB_SET_ERR, moab::ReadNC::mbImpl, NCFUNCAG, moab::DebugOutput::printf(), read_variables_to_set_allocate(), t, moab::Interface::tag_set_by_ptr(), and moab::DebugOutput::tprintf().

Referenced by moab::ScdNCHelper::read_variables(), and moab::UcdNCHelper::read_variables().

{
    Interface*& mbImpl  = _readNC->mbImpl;
    DebugOutput& dbgOut = _readNC->dbgOut;

    ErrorCode rval = read_variables_to_set_allocate( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble allocating space to read set variables" );

    // Finally, read into that space
    int success;
    for( unsigned int i = 0; i < vdatas.size(); i++ )
    {
        // Note, for set variables without timesteps, loop one time and then break
        for( unsigned int t = 0; t < tstep_nums.size(); t++ )
        {
            void* data = vdatas[i].varDatas[t];

            // Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen)
            if( vdatas[i].has_tsteps )
            {
                // Set readStart for each timestep along time dimension
                vdatas[i].readStarts[0] = tstep_nums[t];
            }

            switch( vdatas[i].varDataType )
            {
                case NC_BYTE:
                case NC_CHAR:
                    success = NCFUNCAG( _vara_text )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                                                      &vdatas[i].readCounts[0], (char*)data );
                    if( success )
                        MB_SET_ERR( MB_FAILURE, "Failed to read byte/char data for variable " << vdatas[i].varName );
                    break;
                case NC_SHORT:
                case NC_INT:
                    success = NCFUNCAG( _vara_int )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                                                     &vdatas[i].readCounts[0], (int*)data );
                    if( success )
                        MB_SET_ERR( MB_FAILURE, "Failed to read short/int data for variable " << vdatas[i].varName );
                    break;
                case NC_FLOAT:
                case NC_DOUBLE:
                    success = NCFUNCAG( _vara_double )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                                                        &vdatas[i].readCounts[0], (double*)data );
                    if( success )
                        MB_SET_ERR( MB_FAILURE, "Failed to read float/double data for variable " << vdatas[i].varName );
                    break;
                default:
                    MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
            }

            dbgOut.tprintf( 2, "Setting data for variable %s, time step %d\n", vdatas[i].varName.c_str(),
                            tstep_nums[t] );
            rval = mbImpl->tag_set_by_ptr( vdatas[i].varTags[t], &_fileSet, 1, &data, &vdatas[i].sz );MB_CHK_SET_ERR( rval, "Trouble setting tag data for variable " << vdatas[i].varName );

            // Memory pointed by pointer data can be deleted, as tag_set_by_ptr() has already copied
            // the tag values
            switch( vdatas[i].varDataType )
            {
                case NC_BYTE:
                case NC_CHAR:
                    delete[]( char* ) data;
                    break;
                case NC_SHORT:
                case NC_INT:
                    delete[]( int* ) data;
                    break;
                case NC_FLOAT:
                case NC_DOUBLE:
                    delete[]( double* ) data;
                    break;
                default:
                    break;
            }
            vdatas[i].varDatas[t] = NULL;

            // Loop continues only for set variables with timesteps, e.g. xtime(Time) or xtime(Time,
            // StrLen)
            if( !vdatas[i].has_tsteps ) break;
        }
    }

    // Debug output, if requested
    if( 1 == dbgOut.get_verbosity() )
    {
        dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() );
        for( unsigned int i = 1; i < vdatas.size(); i++ )
            dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() );
        dbgOut.tprintf( 1, "\n" );
    }

    return rval;
}
ErrorCode moab::NCHelper::read_variables_to_set_allocate ( std::vector< ReadNC::VarData > &  vdatas,
std::vector< int > &  tstep_nums 
) [private]

Used by read_variables_to_set()

Definition at line 801 of file NCHelper.cpp.

References _readNC, moab::ReadNC::dbgOut, moab::ReadNC::dimLens, ErrorCode, get_tag_to_set(), MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SET_ERR, MB_SUCCESS, t, tDim, and moab::DebugOutput::tprintf().

Referenced by read_variables_to_set().

{
    std::vector< int >& dimLens = _readNC->dimLens;
    DebugOutput& dbgOut         = _readNC->dbgOut;

    ErrorCode rval = MB_SUCCESS;

    for( unsigned int i = 0; i < vdatas.size(); i++ )
    {
        // Set up readStarts and readCounts
        if( vdatas[i].has_tsteps )
        {
            // First: time
            vdatas[i].readStarts.push_back( 0 );  // This value is timestep dependent, will be set later
            vdatas[i].readCounts.push_back( 1 );

            // Next: other dimensions
            for( unsigned int idx = 1; idx != vdatas[i].varDims.size(); idx++ )
            {
                vdatas[i].readStarts.push_back( 0 );
                vdatas[i].readCounts.push_back( dimLens[vdatas[i].varDims[idx]] );
            }
        }
        else
        {
            if( vdatas[i].varDims.empty() )
            {
                // Scalar variable
                vdatas[i].readStarts.push_back( 0 );
                vdatas[i].readCounts.push_back( 1 );
            }
            else
            {
                for( unsigned int idx = 0; idx != vdatas[i].varDims.size(); idx++ )
                {
                    vdatas[i].readStarts.push_back( 0 );
                    vdatas[i].readCounts.push_back( dimLens[vdatas[i].varDims[idx]] );
                }
            }
        }

        // Get variable size
        vdatas[i].sz = 1;
        for( std::size_t idx = 0; idx != vdatas[i].readCounts.size(); idx++ )
            vdatas[i].sz *= vdatas[i].readCounts[idx];

        // Note, for set variables without timesteps, loop one time and then break
        for( unsigned int t = 0; t < tstep_nums.size(); t++ )
        {
            dbgOut.tprintf( 2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t] );

            if( tstep_nums[t] >= dimLens[tDim] )
            {
                MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t] );
            }

            // Get the tag to read into
            if( !vdatas[i].varTags[t] )
            {
                rval = get_tag_to_set( vdatas[i], tstep_nums[t], vdatas[i].varTags[t] );MB_CHK_SET_ERR( rval, "Trouble getting tag to set variable " << vdatas[i].varName );
            }

            switch( vdatas[i].varDataType )
            {
                case NC_BYTE:
                case NC_CHAR:
                    vdatas[i].varDatas[t] = new char[vdatas[i].sz];
                    break;
                case NC_SHORT:
                case NC_INT:
                    vdatas[i].varDatas[t] = new int[vdatas[i].sz];
                    break;
                case NC_FLOAT:
                case NC_DOUBLE:
                    vdatas[i].varDatas[t] = new double[vdatas[i].sz];
                    break;
                default:
                    MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
            }

            // Loop continues only for set variables with timesteps, e.g. xtime(Time) or xtime(Time,
            // StrLen)
            if( !vdatas[i].has_tsteps ) break;
        }
    }

    return rval;
}

Update time tag values if timesteps spread across files.

Definition at line 325 of file NCHelper.cpp.

References _fileSet, _readNC, moab::ReadNC::dimNames, dummyVarNames, ErrorCode, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_VARLEN, MB_TYPE_DOUBLE, moab::ReadNC::mbImpl, nTimeSteps, moab::Interface::tag_get_by_ptr(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_by_ptr(), tDim, and tVals.

Referenced by moab::ReadNC::load_file().

{
    Interface*& mbImpl                   = _readNC->mbImpl;
    std::vector< std::string >& dimNames = _readNC->dimNames;

    ErrorCode rval;

    // The time tag might be a dummy one (e.g. 'Time' for MPAS)
    std::string time_tag_name = dimNames[tDim];
    if( dummyVarNames.find( time_tag_name ) != dummyVarNames.end() ) return MB_SUCCESS;

    Tag time_tag      = 0;
    const void* data  = NULL;
    int time_tag_size = 0;
    rval              = mbImpl->tag_get_handle( time_tag_name.c_str(), 0, MB_TYPE_DOUBLE, time_tag, MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble getting tag " << time_tag_name );
    rval = mbImpl->tag_get_by_ptr( time_tag, &_fileSet, 1, &data, &time_tag_size );MB_CHK_SET_ERR( rval, "Trouble getting data of tag " << time_tag_name );
    const double* time_tag_vals = static_cast< const double* >( data );

    // Merge tVals (read from current file) to existing time tag
    // Assume that time_tag_vals and tVals are both sorted
    std::vector< double > merged_time_vals;
    merged_time_vals.reserve( time_tag_size + nTimeSteps );
    int i = 0;
    int j = 0;

    // Merge time values from time_tag_vals and tVals
    while( i < time_tag_size && j < nTimeSteps )
    {
        if( time_tag_vals[i] < tVals[j] )
            merged_time_vals.push_back( time_tag_vals[i++] );
        else
            merged_time_vals.push_back( tVals[j++] );
    }

    // Append remaining time values of time_tag_vals (if any)
    while( i < time_tag_size )
        merged_time_vals.push_back( time_tag_vals[i++] );

    // Append remaining time values of tVals (if any)
    while( j < nTimeSteps )
        merged_time_vals.push_back( tVals[j++] );

    data          = &merged_time_vals[0];
    time_tag_size = merged_time_vals.size();
    rval          = mbImpl->tag_set_by_ptr( time_tag, &_fileSet, 1, &data, &time_tag_size );MB_CHK_SET_ERR( rval, "Trouble setting data to tag " << time_tag_name );

    return MB_SUCCESS;
}

Member Data Documentation

std::set< std::string > moab::NCHelper::dummyVarNames [protected]

Dummy variables.

Definition at line 120 of file NCHelper.hpp.

Referenced by create_conventional_tags(), create_dummy_variables(), read_variables_setup(), and update_time_tag_vals().

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines