LCOV - code coverage report
Current view: top level - src/io - NCHelper.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 1 703 0.1 %
Date: 2020-12-16 07:07:30 Functions: 2 20 10.0 %
Branches: 2 2958 0.1 %

           Branch data     Line data    Source code
       1                 :            : #include "NCHelper.hpp"
       2                 :            : #include "NCHelperEuler.hpp"
       3                 :            : #include "NCHelperFV.hpp"
       4                 :            : #include "NCHelperDomain.hpp"
       5                 :            : #include "NCHelperHOMME.hpp"
       6                 :            : #include "NCHelperMPAS.hpp"
       7                 :            : #include "NCHelperGCRM.hpp"
       8                 :            : 
       9                 :            : #include <sstream>
      10                 :            : 
      11                 :            : #include "MBTagConventions.hpp"
      12                 :            : 
      13                 :            : #ifdef WIN32
      14                 :            : #ifdef size_t
      15                 :            : #undef size_t
      16                 :            : #endif
      17                 :            : #endif
      18                 :            : 
      19                 :            : namespace moab
      20                 :            : {
      21                 :            : 
      22                 :          0 : NCHelper* NCHelper::get_nc_helper( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet )
      23                 :            : {
      24                 :            :     // Check if CF convention is being followed
      25                 :          0 :     bool is_CF = false;
      26                 :            : 
      27                 :          0 :     std::map< std::string, ReadNC::AttData >& globalAtts     = readNC->globalAtts;
      28 [ #  # ][ #  # ]:          0 :     std::map< std::string, ReadNC::AttData >::iterator attIt = globalAtts.find( "conventions" );
      29 [ #  # ][ #  # ]:          0 :     if( attIt == globalAtts.end() ) attIt = globalAtts.find( "Conventions" );
         [ #  # ][ #  # ]
      30                 :            : 
      31 [ #  # ][ #  # ]:          0 :     if( attIt != globalAtts.end() )
      32                 :            :     {
      33         [ #  # ]:          0 :         unsigned int sz = attIt->second.attLen;
      34         [ #  # ]:          0 :         std::string att_data;
      35         [ #  # ]:          0 :         att_data.resize( sz + 1 );
      36         [ #  # ]:          0 :         att_data[sz] = '\000';
      37                 :            :         int success =
      38 [ #  # ][ #  # ]:          0 :             NCFUNC( get_att_text )( fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &att_data[0] );
         [ #  # ][ #  # ]
      39 [ #  # ][ #  # ]:          0 :         if( 0 == success && att_data.find( "CF" ) != std::string::npos ) is_CF = true;
         [ #  # ][ #  # ]
      40                 :            :     }
      41                 :            : 
      42         [ #  # ]:          0 :     if( is_CF )
      43                 :            :     {
      44 [ #  # ][ #  # ]:          0 :         if( NCHelperEuler::can_read_file( readNC, fileId ) )
      45 [ #  # ][ #  # ]:          0 :             return new( std::nothrow ) NCHelperEuler( readNC, fileId, opts, fileSet );
      46 [ #  # ][ #  # ]:          0 :         else if( NCHelperFV::can_read_file( readNC, fileId ) )
      47 [ #  # ][ #  # ]:          0 :             return new( std::nothrow ) NCHelperFV( readNC, fileId, opts, fileSet );
      48 [ #  # ][ #  # ]:          0 :         else if( NCHelperHOMME::can_read_file( readNC, fileId ) )
      49 [ #  # ][ #  # ]:          0 :             return new( std::nothrow ) NCHelperHOMME( readNC, fileId, opts, fileSet );
      50 [ #  # ][ #  # ]:          0 :         else if( NCHelperDomain::can_read_file( readNC, fileId ) )
      51 [ #  # ][ #  # ]:          0 :             return new( std::nothrow ) NCHelperDomain( readNC, fileId, opts, fileSet );
      52                 :            :     }
      53                 :            :     else
      54                 :            :     {
      55 [ #  # ][ #  # ]:          0 :         if( NCHelperMPAS::can_read_file( readNC ) )
      56 [ #  # ][ #  # ]:          0 :             return new( std::nothrow ) NCHelperMPAS( readNC, fileId, opts, fileSet );
      57                 :            :         // For a HOMME connectivity file, there might be no CF convention
      58 [ #  # ][ #  # ]:          0 :         else if( NCHelperHOMME::can_read_file( readNC, fileId ) )
      59 [ #  # ][ #  # ]:          0 :             return new( std::nothrow ) NCHelperHOMME( readNC, fileId, opts, fileSet );
      60                 :            :         // gcrm reader
      61 [ #  # ][ #  # ]:          0 :         else if( NCHelperGCRM::can_read_file( readNC ) )
      62 [ #  # ][ #  # ]:          0 :             return new( std::nothrow ) NCHelperGCRM( readNC, fileId, opts, fileSet );
      63                 :            :     }
      64                 :            : 
      65                 :            :     // Unknown NetCDF grid (will fill this in later for POP, CICE and CLM)
      66                 :          0 :     return NULL;
      67                 :            : }
      68                 :            : 
      69                 :          0 : ErrorCode NCHelper::create_conventional_tags( const std::vector< int >& tstep_nums )
      70                 :            : {
      71                 :          0 :     Interface*& mbImpl                                   = _readNC->mbImpl;
      72                 :          0 :     std::vector< std::string >& dimNames                 = _readNC->dimNames;
      73                 :          0 :     std::vector< int >& dimLens                          = _readNC->dimLens;
      74                 :          0 :     std::map< std::string, ReadNC::AttData >& globalAtts = _readNC->globalAtts;
      75                 :          0 :     std::map< std::string, ReadNC::VarData >& varInfo    = _readNC->varInfo;
      76                 :          0 :     DebugOutput& dbgOut                                  = _readNC->dbgOut;
      77                 :          0 :     int& partMethod                                      = _readNC->partMethod;
      78                 :          0 :     ScdInterface* scdi                                   = _readNC->scdi;
      79                 :            : 
      80                 :            :     ErrorCode rval;
      81         [ #  # ]:          0 :     std::string tag_name;
      82                 :            : 
      83                 :            :     // <__NUM_DIMS>
      84                 :          0 :     Tag numDimsTag = 0;
      85         [ #  # ]:          0 :     tag_name       = "__NUM_DIMS";
      86                 :          0 :     int numDims    = dimNames.size();
      87 [ #  # ][ #  # ]:          0 :     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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      88 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_set_data( numDimsTag, &_fileSet, 1, &numDims );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      89         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
      90                 :            : 
      91                 :            :     // <__NUM_VARS>
      92                 :          0 :     Tag numVarsTag = 0;
      93         [ #  # ]:          0 :     tag_name       = "__NUM_VARS";
      94                 :          0 :     int numVars    = varInfo.size();
      95 [ #  # ][ #  # ]:          0 :     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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      96 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_set_data( numVarsTag, &_fileSet, 1, &numVars );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      97         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
      98                 :            : 
      99                 :            :     // <__DIM_NAMES>
     100                 :          0 :     Tag dimNamesTag = 0;
     101         [ #  # ]:          0 :     tag_name        = "__DIM_NAMES";
     102         [ #  # ]:          0 :     std::string dimnames;
     103                 :          0 :     unsigned int dimNamesSz = dimNames.size();
     104         [ #  # ]:          0 :     for( unsigned int i = 0; i != dimNamesSz; i++ )
     105                 :            :     {
     106 [ #  # ][ #  # ]:          0 :         dimnames.append( dimNames[i] );
     107         [ #  # ]:          0 :         dimnames.push_back( '\0' );
     108                 :            :     }
     109                 :          0 :     int dimnamesSz = dimnames.size();
     110                 :            :     rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, dimNamesTag,
     111 [ #  # ][ #  # ]:          0 :                                    MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     112                 :          0 :     const void* ptr = dimnames.c_str();
     113 [ #  # ][ #  # ]:          0 :     rval            = mbImpl->tag_set_by_ptr( dimNamesTag, &_fileSet, 1, &ptr, &dimnamesSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     114         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     115                 :            : 
     116                 :            :     // <__DIM_LENS>
     117                 :          0 :     Tag dimLensTag = 0;
     118         [ #  # ]:          0 :     tag_name       = "__DIM_LENS";
     119                 :          0 :     int dimLensSz  = dimLens.size();
     120                 :            :     rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, dimLensTag,
     121 [ #  # ][ #  # ]:          0 :                                    MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     122         [ #  # ]:          0 :     ptr  = &( dimLens[0] );
     123 [ #  # ][ #  # ]:          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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     124         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     125                 :            : 
     126                 :            :     // <__VAR_NAMES>
     127                 :          0 :     Tag varNamesTag = 0;
     128         [ #  # ]:          0 :     tag_name        = "__VAR_NAMES";
     129         [ #  # ]:          0 :     std::string varnames;
     130         [ #  # ]:          0 :     std::map< std::string, ReadNC::VarData >::iterator mapIter;
     131 [ #  # ][ #  # ]:          0 :     for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
                 [ #  # ]
     132                 :            :     {
     133 [ #  # ][ #  # ]:          0 :         varnames.append( mapIter->first );
     134         [ #  # ]:          0 :         varnames.push_back( '\0' );
     135                 :            :     }
     136                 :          0 :     int varnamesSz = varnames.size();
     137                 :            :     rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag,
     138 [ #  # ][ #  # ]:          0 :                                    MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     139                 :          0 :     ptr  = varnames.c_str();
     140 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_set_by_ptr( varNamesTag, &_fileSet, 1, &ptr, &varnamesSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     141         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     142                 :            : 
     143                 :            :     // __<dim_name>_LOC_MINMAX (for time)
     144         [ #  # ]:          0 :     for( unsigned int i = 0; i != dimNamesSz; i++ )
     145                 :            :     {
     146 [ #  # ][ #  # ]:          0 :         if( dimNames[i] == "time" || dimNames[i] == "Time" || dimNames[i] == "t" )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     147                 :            :         {
     148                 :            :             // some files might have Time dimension as 0, it will not appear in any
     149                 :            :             // variables, so skip it
     150         [ #  # ]:          0 :             if( nTimeSteps == 0 ) continue;
     151 [ #  # ][ #  # ]:          0 :             std::stringstream ss_tag_name;
     152 [ #  # ][ #  # ]:          0 :             ss_tag_name << "__" << dimNames[i] << "_LOC_MINMAX";
         [ #  # ][ #  # ]
     153 [ #  # ][ #  # ]:          0 :             tag_name = ss_tag_name.str();
     154                 :          0 :             Tag tagh = 0;
     155 [ #  # ][ #  # ]:          0 :             std::vector< int > val( 2, 0 );
     156         [ #  # ]:          0 :             val[0] = 0;
     157         [ #  # ]:          0 :             val[1] = nTimeSteps - 1;
     158 [ #  # ][ #  # ]:          0 :             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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     159 [ #  # ][ #  # ]:          0 :             rval = mbImpl->tag_set_data( tagh, &_fileSet, 1, &val[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     160 [ #  # ][ #  # ]:          0 :             dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     161                 :            :         }
     162                 :            :     }
     163                 :            : 
     164                 :            :     // __<dim_name>_LOC_VALS (for time)
     165         [ #  # ]:          0 :     for( unsigned int i = 0; i != dimNamesSz; i++ )
     166                 :            :     {
     167 [ #  # ][ #  # ]:          0 :         if( dimNames[i] == "time" || dimNames[i] == "Time" || dimNames[i] == "t" )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     168                 :            :         {
     169         [ #  # ]:          0 :             std::vector< int > val;
     170         [ #  # ]:          0 :             if( !tstep_nums.empty() )
     171         [ #  # ]:          0 :                 val = tstep_nums;
     172                 :            :             else
     173                 :            :             {
     174                 :            :                 // some files might have Time dimension as 0, it will not appear in any
     175                 :            :                 // variables, so skip it
     176         [ #  # ]:          0 :                 if( tVals.empty() ) continue;
     177         [ #  # ]:          0 :                 val.resize( tVals.size() );
     178         [ #  # ]:          0 :                 for( unsigned int j = 0; j != tVals.size(); j++ )
     179         [ #  # ]:          0 :                     val[j] = j;
     180                 :            :             }
     181                 :          0 :             Tag tagh = 0;
     182 [ #  # ][ #  # ]:          0 :             std::stringstream ss_tag_name;
              [ #  #  # ]
     183 [ #  # ][ #  # ]:          0 :             ss_tag_name << "__" << dimNames[i] << "_LOC_VALS";
         [ #  # ][ #  # ]
     184 [ #  # ][ #  # ]:          0 :             tag_name = ss_tag_name.str();
     185                 :          0 :             rval     = mbImpl->tag_get_handle( tag_name.c_str(), val.size(), MB_TYPE_INTEGER, tagh,
     186 [ #  # ][ #  # ]:          0 :                                            MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     187 [ #  # ][ #  # ]:          0 :             rval = mbImpl->tag_set_data( tagh, &_fileSet, 1, &val[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     188 [ #  # ][ #  # ]:          0 :             dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     189                 :            :         }
     190                 :            :     }
     191                 :            : 
     192                 :            :     // __<var_name>_DIMS
     193 [ #  # ][ #  # ]:          0 :     for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
                 [ #  # ]
     194                 :            :     {
     195                 :          0 :         Tag varNamesDimsTag = 0;
     196 [ #  # ][ #  # ]:          0 :         std::stringstream ss_tag_name;
     197 [ #  # ][ #  # ]:          0 :         ss_tag_name << "__" << mapIter->first << "_DIMS";
         [ #  # ][ #  # ]
     198 [ #  # ][ #  # ]:          0 :         tag_name              = ss_tag_name.str();
     199 [ #  # ][ #  # ]:          0 :         unsigned int varDimSz = varInfo[mapIter->first].varDims.size();
     200         [ #  # ]:          0 :         if( varDimSz == 0 ) continue;
     201         [ #  # ]:          0 :         std::vector< Tag > varDimTags( varDimSz );
              [ #  #  # ]
     202         [ #  # ]:          0 :         for( unsigned int i = 0; i != varDimSz; i++ )
     203                 :            :         {
     204                 :          0 :             Tag tmptag             = 0;
     205 [ #  # ][ #  # ]:          0 :             std::string tmptagname = dimNames[varInfo[mapIter->first].varDims[i]];
         [ #  # ][ #  # ]
                 [ #  # ]
     206 [ #  # ][ #  # ]:          0 :             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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     207 [ #  # ][ #  # ]:          0 :             varDimTags[i] = tmptag;
     208                 :          0 :         }
     209                 :            :         // rval = mbImpl->tag_get_handle(tag_name.c_str(), varDimSz, MB_TYPE_HANDLE,
     210                 :            :         // varNamesDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT); We should not use MB_TYPE_HANDLE for Tag
     211                 :            :         // here. Tag is a pointer, which is 4 bytes on 32 bit machines and 8 bytes on 64 bit
     212                 :            :         // machines. Normally, entity handle is 8 bytes on 64 bit machines, but it can also be
     213                 :            :         // configured to 4 bytes.
     214                 :            :         rval = mbImpl->tag_get_handle( tag_name.c_str(), varDimSz * sizeof( Tag ), MB_TYPE_OPAQUE, varNamesDimsTag,
     215 [ #  # ][ #  # ]:          0 :                                        MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     216 [ #  # ][ #  # ]:          0 :         rval = mbImpl->tag_set_data( varNamesDimsTag, &_fileSet, 1, &( varDimTags[0] ) );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     217 [ #  # ][ #  # ]:          0 :         dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     218                 :          0 :     }
     219                 :            : 
     220                 :            :     // <PARTITION_METHOD>
     221         [ #  # ]:          0 :     Tag part_tag = scdi->part_method_tag();
     222 [ #  # ][ #  # ]:          0 :     if( !part_tag ) MB_SET_ERR( MB_FAILURE, "Trouble getting PARTITION_METHOD tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     223 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_set_data( part_tag, &_fileSet, 1, &partMethod );MB_CHK_SET_ERR( rval, "Trouble setting data to PARTITION_METHOD tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     224         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     225                 :            : 
     226                 :            :     // <__GLOBAL_ATTRIBS>
     227         [ #  # ]:          0 :     tag_name         = "__GLOBAL_ATTRIBS";
     228                 :          0 :     Tag globalAttTag = 0;
     229                 :            :     rval             = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, globalAttTag,
     230 [ #  # ][ #  # ]:          0 :                                    MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     231         [ #  # ]:          0 :     std::string gattVal;
     232         [ #  # ]:          0 :     std::vector< int > gattLen;
     233 [ #  # ][ #  # ]:          0 :     rval = create_attrib_string( globalAtts, gattVal, gattLen );MB_CHK_SET_ERR( rval, "Trouble creating global attribute string" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     234                 :          0 :     const void* gattptr = gattVal.c_str();
     235                 :          0 :     int globalAttSz     = gattVal.size();
     236 [ #  # ][ #  # ]:          0 :     rval                = mbImpl->tag_set_by_ptr( globalAttTag, &_fileSet, 1, &gattptr, &globalAttSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     237         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     238                 :            : 
     239                 :            :     // <__GLOBAL_ATTRIBS_LEN>
     240         [ #  # ]:          0 :     tag_name            = "__GLOBAL_ATTRIBS_LEN";
     241                 :          0 :     Tag globalAttLenTag = 0;
     242 [ #  # ][ #  # ]:          0 :     if( gattLen.size() == 0 ) gattLen.push_back( 0 );
     243                 :          0 :     rval = mbImpl->tag_get_handle( tag_name.c_str(), gattLen.size(), MB_TYPE_INTEGER, globalAttLenTag,
     244 [ #  # ][ #  # ]:          0 :                                    MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     245 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_set_data( globalAttLenTag, &_fileSet, 1, &gattLen[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     246         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     247                 :            : 
     248                 :            :     // __<var_name>_ATTRIBS and __<var_name>_ATTRIBS_LEN
     249 [ #  # ][ #  # ]:          0 :     for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
                 [ #  # ]
     250                 :            :     {
     251 [ #  # ][ #  # ]:          0 :         std::stringstream ssTagName;
     252 [ #  # ][ #  # ]:          0 :         ssTagName << "__" << mapIter->first << "_ATTRIBS";
         [ #  # ][ #  # ]
     253 [ #  # ][ #  # ]:          0 :         tag_name      = ssTagName.str();
     254                 :          0 :         Tag varAttTag = 0;
     255                 :            :         rval          = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varAttTag,
     256 [ #  # ][ #  # ]:          0 :                                        MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     257                 :            : 
     258 [ #  # ][ #  # ]:          0 :         std::string varAttVal;
     259 [ #  # ][ #  # ]:          0 :         std::vector< int > varAttLen;
     260 [ #  # ][ #  # ]:          0 :         if( mapIter->second.numAtts < 1 )
     261                 :            :         {
     262 [ #  # ][ #  # ]:          0 :             if( dummyVarNames.find( mapIter->first ) != dummyVarNames.end() )
         [ #  # ][ #  # ]
     263                 :            :             {
     264                 :            :                 // This variable is a dummy coordinate variable
     265         [ #  # ]:          0 :                 varAttVal = "DUMMY_VAR";
     266                 :            :             }
     267                 :            :             else
     268                 :            :             {
     269                 :            :                 // This variable has no attributes
     270         [ #  # ]:          0 :                 varAttVal = "NO_ATTRIBS";
     271                 :            :             }
     272                 :            :         }
     273                 :            :         else
     274                 :            :         {
     275 [ #  # ][ #  # ]:          0 :             rval = create_attrib_string( mapIter->second.varAtts, varAttVal, varAttLen );MB_CHK_SET_ERR( rval, "Trouble creating attribute string for variable " << mapIter->first );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     276                 :            :         }
     277                 :          0 :         const void* varAttPtr = varAttVal.c_str();
     278                 :          0 :         int varAttSz          = varAttVal.size();
     279         [ #  # ]:          0 :         if( 0 == varAttSz ) varAttSz = 1;
     280 [ #  # ][ #  # ]:          0 :         rval = mbImpl->tag_set_by_ptr( varAttTag, &_fileSet, 1, &varAttPtr, &varAttSz );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     281         [ #  # ]:          0 :         dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     282                 :            : 
     283         [ #  # ]:          0 :         ssTagName << "_LEN";
     284 [ #  # ][ #  # ]:          0 :         tag_name         = ssTagName.str();
     285                 :          0 :         Tag varAttLenTag = 0;
     286 [ #  # ][ #  # ]:          0 :         if( 0 == varAttLen.size() ) varAttLen.push_back( 0 );
     287                 :          0 :         rval = mbImpl->tag_get_handle( tag_name.c_str(), varAttLen.size(), MB_TYPE_INTEGER, varAttLenTag,
     288 [ #  # ][ #  # ]:          0 :                                        MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     289 [ #  # ][ #  # ]:          0 :         rval = mbImpl->tag_set_data( varAttLenTag, &_fileSet, 1, &varAttLen[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     290 [ #  # ][ #  # ]:          0 :         dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     291                 :          0 :     }
     292                 :            : 
     293                 :            :     // <__VAR_NAMES_LOCATIONS>
     294         [ #  # ]:          0 :     tag_name            = "__VAR_NAMES_LOCATIONS";
     295                 :          0 :     Tag varNamesLocsTag = 0;
     296         [ #  # ]:          0 :     std::vector< int > varNamesLocs( varInfo.size() );
     297                 :          0 :     rval = mbImpl->tag_get_handle( tag_name.c_str(), varNamesLocs.size(), MB_TYPE_INTEGER, varNamesLocsTag,
     298 [ #  # ][ #  # ]:          0 :                                    MB_TAG_CREAT | MB_TAG_SPARSE );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     299 [ #  # ][ #  # ]:          0 :     for( mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter )
                 [ #  # ]
     300                 :            :     {
     301 [ #  # ][ #  # ]:          0 :         varNamesLocs[std::distance( varInfo.begin(), mapIter )] = mapIter->second.entLoc;
                 [ #  # ]
     302                 :            :     }
     303 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_set_data( varNamesLocsTag, &_fileSet, 1, &varNamesLocs[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     304         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     305                 :            : 
     306                 :            :     // <__MESH_TYPE>
     307                 :          0 :     Tag meshTypeTag          = 0;
     308         [ #  # ]:          0 :     tag_name                 = "__MESH_TYPE";
     309         [ #  # ]:          0 :     std::string meshTypeName = get_mesh_type_name();
     310                 :            : 
     311                 :            :     rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, meshTypeTag,
     312 [ #  # ][ #  # ]:          0 :                                    MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     313                 :          0 :     ptr      = meshTypeName.c_str();
     314                 :          0 :     int leng = meshTypeName.size();
     315 [ #  # ][ #  # ]:          0 :     rval     = mbImpl->tag_set_by_ptr( meshTypeTag, &_fileSet, 1, &ptr, &leng );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     316         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Conventional tag %s created\n", tag_name.c_str() );
     317                 :            : 
     318                 :          0 :     return MB_SUCCESS;
     319                 :            : }
     320                 :            : 
     321                 :          0 : ErrorCode NCHelper::update_time_tag_vals()
     322                 :            : {
     323                 :          0 :     Interface*& mbImpl                   = _readNC->mbImpl;
     324                 :          0 :     std::vector< std::string >& dimNames = _readNC->dimNames;
     325                 :            : 
     326                 :            :     ErrorCode rval;
     327                 :            : 
     328                 :            :     // The time tag might be a dummy one (e.g. 'Time' for MPAS)
     329 [ #  # ][ #  # ]:          0 :     std::string time_tag_name = dimNames[tDim];
     330 [ #  # ][ #  # ]:          0 :     if( dummyVarNames.find( time_tag_name ) != dummyVarNames.end() ) return MB_SUCCESS;
                 [ #  # ]
     331                 :            : 
     332                 :          0 :     Tag time_tag      = 0;
     333                 :          0 :     const void* data  = NULL;
     334                 :          0 :     int time_tag_size = 0;
     335 [ #  # ][ #  # ]:          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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     336 [ #  # ][ #  # ]:          0 :     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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     337                 :          0 :     const double* time_tag_vals = static_cast< const double* >( data );
     338                 :            : 
     339                 :            :     // Merge tVals (read from current file) to existing time tag
     340                 :            :     // Assume that time_tag_vals and tVals are both sorted
     341         [ #  # ]:          0 :     std::vector< double > merged_time_vals;
     342         [ #  # ]:          0 :     merged_time_vals.reserve( time_tag_size + nTimeSteps );
     343                 :          0 :     int i = 0;
     344                 :          0 :     int j = 0;
     345                 :            : 
     346                 :            :     // Merge time values from time_tag_vals and tVals
     347 [ #  # ][ #  # ]:          0 :     while( i < time_tag_size && j < nTimeSteps )
     348                 :            :     {
     349 [ #  # ][ #  # ]:          0 :         if( time_tag_vals[i] < tVals[j] )
     350         [ #  # ]:          0 :             merged_time_vals.push_back( time_tag_vals[i++] );
     351                 :            :         else
     352 [ #  # ][ #  # ]:          0 :             merged_time_vals.push_back( tVals[j++] );
     353                 :            :     }
     354                 :            : 
     355                 :            :     // Append remaining time values of time_tag_vals (if any)
     356         [ #  # ]:          0 :     while( i < time_tag_size )
     357         [ #  # ]:          0 :         merged_time_vals.push_back( time_tag_vals[i++] );
     358                 :            : 
     359                 :            :     // Append remaining time values of tVals (if any)
     360         [ #  # ]:          0 :     while( j < nTimeSteps )
     361 [ #  # ][ #  # ]:          0 :         merged_time_vals.push_back( tVals[j++] );
     362                 :            : 
     363         [ #  # ]:          0 :     data          = &merged_time_vals[0];
     364                 :          0 :     time_tag_size = merged_time_vals.size();
     365 [ #  # ][ #  # ]:          0 :     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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     366                 :            : 
     367                 :          0 :     return MB_SUCCESS;
     368                 :            : }
     369                 :            : 
     370                 :          0 : ErrorCode NCHelper::read_variables_setup( std::vector< std::string >& var_names, std::vector< int >& tstep_nums,
     371                 :            :                                           std::vector< ReadNC::VarData >& vdatas,
     372                 :            :                                           std::vector< ReadNC::VarData >& vsetdatas )
     373                 :            : {
     374                 :          0 :     std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
     375                 :          0 :     std::vector< std::string >& dimNames              = _readNC->dimNames;
     376                 :            : 
     377         [ #  # ]:          0 :     std::map< std::string, ReadNC::VarData >::iterator mit;
     378                 :            : 
     379                 :            :     // If empty read them all (except ignored variables)
     380         [ #  # ]:          0 :     if( var_names.empty() )
     381                 :            :     {
     382 [ #  # ][ #  # ]:          0 :         for( mit = varInfo.begin(); mit != varInfo.end(); ++mit )
                 [ #  # ]
     383                 :            :         {
     384 [ #  # ][ #  # ]:          0 :             ReadNC::VarData vd = ( *mit ).second;
     385                 :            : 
     386                 :            :             // If read all variables at once, skip ignored ones
     387 [ #  # ][ #  # ]:          0 :             if( ignoredVarNames.find( vd.varName ) != ignoredVarNames.end() ) continue;
                 [ #  # ]
     388                 :            : 
     389                 :            :             // Coordinate variables (include dummy ones) were read to the file set by default
     390 [ #  # ][ #  # ]:          0 :             if( std::find( dimNames.begin(), dimNames.end(), vd.varName ) != dimNames.end() ) continue;
                 [ #  # ]
     391                 :            : 
     392         [ #  # ]:          0 :             if( vd.entLoc == ReadNC::ENTLOCSET )
     393         [ #  # ]:          0 :                 vsetdatas.push_back( vd );
     394                 :            :             else
     395 [ #  # ][ #  # ]:          0 :                 vdatas.push_back( vd );
     396                 :          0 :         }
     397                 :            :     }
     398                 :            :     else
     399                 :            :     {
     400                 :            :         // Read specified variables (might include ignored ones)
     401         [ #  # ]:          0 :         for( unsigned int i = 0; i < var_names.size(); i++ )
     402                 :            :         {
     403 [ #  # ][ #  # ]:          0 :             mit = varInfo.find( var_names[i] );
     404 [ #  # ][ #  # ]:          0 :             if( mit != varInfo.end() )
     405                 :            :             {
     406 [ #  # ][ #  # ]:          0 :                 ReadNC::VarData vd = ( *mit ).second;
     407                 :            : 
     408                 :            :                 // Upon creation of dummy coordinate variables, tag values have already been set
     409 [ #  # ][ #  # ]:          0 :                 if( dummyVarNames.find( vd.varName ) != dummyVarNames.end() ) continue;
                 [ #  # ]
     410                 :            : 
     411         [ #  # ]:          0 :                 if( vd.entLoc == ReadNC::ENTLOCSET )
     412         [ #  # ]:          0 :                     vsetdatas.push_back( vd );
     413                 :            :                 else
     414 [ #  # ][ #  # ]:          0 :                     vdatas.push_back( vd );
     415                 :            :             }
     416                 :            :             else
     417                 :            :             {
     418 [ #  # ][ #  # ]:          0 :                 MB_SET_ERR( MB_FAILURE, "Couldn't find specified variable " << var_names[i] );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     419                 :            :             }
     420                 :            :         }
     421                 :            :     }
     422                 :            : 
     423 [ #  # ][ #  # ]:          0 :     if( tstep_nums.empty() && nTimeSteps > 0 )
                 [ #  # ]
     424                 :            :     {
     425                 :            :         // No timesteps input, get them all
     426         [ #  # ]:          0 :         for( int i = 0; i < nTimeSteps; i++ )
     427         [ #  # ]:          0 :             tstep_nums.push_back( i );
     428                 :            :     }
     429                 :            : 
     430         [ #  # ]:          0 :     if( !tstep_nums.empty() )
     431                 :            :     {
     432         [ #  # ]:          0 :         for( unsigned int i = 0; i < vdatas.size(); i++ )
     433                 :            :         {
     434 [ #  # ][ #  # ]:          0 :             vdatas[i].varTags.resize( tstep_nums.size(), 0 );
     435 [ #  # ][ #  # ]:          0 :             vdatas[i].varDatas.resize( tstep_nums.size() );
     436                 :            :             // NC reader assumes that non-set variables always have timesteps
     437 [ #  # ][ #  # ]:          0 :             assert( std::find( vdatas[i].varDims.begin(), vdatas[i].varDims.end(), tDim ) != vdatas[i].varDims.end() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     438         [ #  # ]:          0 :             vdatas[i].has_tsteps = true;
     439                 :            :         }
     440                 :            : 
     441         [ #  # ]:          0 :         for( unsigned int i = 0; i < vsetdatas.size(); i++ )
     442                 :            :         {
     443 [ #  # ][ #  # ]:          0 :             if( ( std::find( vsetdatas[i].varDims.begin(), vsetdatas[i].varDims.end(), tDim ) !=
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  #  
                   #  # ]
     444 [ #  # ][ #  # ]:          0 :                   vsetdatas[i].varDims.end() ) &&
                 [ #  # ]
     445 [ #  # ][ #  # ]:          0 :                 ( vsetdatas[i].varName != dimNames[tDim] ) )
                 [ #  # ]
     446                 :            :             {
     447                 :            :                 // Set variables with timesteps: e.g. xtime(Time) or xtime(Time, StrLen)
     448 [ #  # ][ #  # ]:          0 :                 vsetdatas[i].varTags.resize( tstep_nums.size(), 0 );
     449 [ #  # ][ #  # ]:          0 :                 vsetdatas[i].varDatas.resize( tstep_nums.size() );
     450         [ #  # ]:          0 :                 vsetdatas[i].has_tsteps = true;
     451                 :            :             }
     452                 :            :             else
     453                 :            :             {
     454                 :            :                 // Set variables without timesteps: no time dimension, or time itself
     455 [ #  # ][ #  # ]:          0 :                 vsetdatas[i].varTags.resize( 1, 0 );
     456 [ #  # ][ #  # ]:          0 :                 vsetdatas[i].varDatas.resize( 1 );
     457         [ #  # ]:          0 :                 vsetdatas[i].has_tsteps = false;
     458                 :            :             }
     459                 :            :         }
     460                 :            :     }
     461                 :            : 
     462                 :          0 :     return MB_SUCCESS;
     463                 :            : }
     464                 :            : 
     465                 :          0 : ErrorCode NCHelper::read_variables_to_set( std::vector< ReadNC::VarData >& vdatas, std::vector< int >& tstep_nums )
     466                 :            : {
     467                 :          0 :     Interface*& mbImpl  = _readNC->mbImpl;
     468                 :          0 :     DebugOutput& dbgOut = _readNC->dbgOut;
     469                 :            : 
     470 [ #  # ][ #  # ]:          0 :     ErrorCode rval = read_variables_to_set_allocate( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble allocating space to read set variables" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     471                 :            : 
     472                 :            :     // Finally, read into that space
     473                 :            :     int success;
     474         [ #  # ]:          0 :     for( unsigned int i = 0; i < vdatas.size(); i++ )
     475                 :            :     {
     476                 :            :         // Note, for set variables without timesteps, loop one time and then break
     477         [ #  # ]:          0 :         for( unsigned int t = 0; t < tstep_nums.size(); t++ )
     478                 :            :         {
     479 [ #  # ][ #  # ]:          0 :             void* data = vdatas[i].varDatas[t];
     480                 :            : 
     481                 :            :             // Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen)
     482 [ #  # ][ #  # ]:          0 :             if( vdatas[i].has_tsteps )
     483                 :            :             {
     484                 :            :                 // Set readStart for each timestep along time dimension
     485 [ #  # ][ #  # ]:          0 :                 vdatas[i].readStarts[0] = tstep_nums[t];
                 [ #  # ]
     486                 :            :             }
     487                 :            : 
     488         [ #  # ]:          0 :             switch( vdatas[i].varDataType )
           [ #  #  #  # ]
     489                 :            :             {
     490                 :            :                 case NC_BYTE:
     491                 :            :                 case NC_CHAR:
     492 [ #  # ][ #  # ]:          0 :                     success = NCFUNCAG( _vara_text )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                 [ #  # ]
     493 [ #  # ][ #  # ]:          0 :                                                       &vdatas[i].readCounts[0], (char*)data );
                 [ #  # ]
     494         [ #  # ]:          0 :                     if( success )
     495 [ #  # ][ #  # ]:          0 :                         MB_SET_ERR( MB_FAILURE, "Failed to read byte/char data for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     496                 :          0 :                     break;
     497                 :            :                 case NC_SHORT:
     498                 :            :                 case NC_INT:
     499 [ #  # ][ #  # ]:          0 :                     success = NCFUNCAG( _vara_int )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                 [ #  # ]
     500 [ #  # ][ #  # ]:          0 :                                                      &vdatas[i].readCounts[0], (int*)data );
                 [ #  # ]
     501         [ #  # ]:          0 :                     if( success )
     502 [ #  # ][ #  # ]:          0 :                         MB_SET_ERR( MB_FAILURE, "Failed to read short/int data for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     503                 :          0 :                     break;
     504                 :            :                 case NC_FLOAT:
     505                 :            :                 case NC_DOUBLE:
     506 [ #  # ][ #  # ]:          0 :                     success = NCFUNCAG( _vara_double )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                 [ #  # ]
     507 [ #  # ][ #  # ]:          0 :                                                         &vdatas[i].readCounts[0], (double*)data );
                 [ #  # ]
     508         [ #  # ]:          0 :                     if( success )
     509 [ #  # ][ #  # ]:          0 :                         MB_SET_ERR( MB_FAILURE, "Failed to read float/double data for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     510                 :          0 :                     break;
     511                 :            :                 default:
     512 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     513                 :            :             }
     514                 :            : 
     515         [ #  # ]:          0 :             dbgOut.tprintf( 2, "Setting data for variable %s, time step %d\n", vdatas[i].varName.c_str(),
     516 [ #  # ][ #  # ]:          0 :                             tstep_nums[t] );
     517 [ #  # ][ #  # ]:          0 :             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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     518                 :            : 
     519                 :            :             // Memory pointed by pointer data can be deleted, as tag_set_by_ptr() has already copied
     520                 :            :             // the tag values
     521         [ #  # ]:          0 :             switch( vdatas[i].varDataType )
           [ #  #  #  # ]
     522                 :            :             {
     523                 :            :                 case NC_BYTE:
     524                 :            :                 case NC_CHAR:
     525         [ #  # ]:          0 :                     delete[]( char* ) data;
     526                 :          0 :                     break;
     527                 :            :                 case NC_SHORT:
     528                 :            :                 case NC_INT:
     529         [ #  # ]:          0 :                     delete[]( int* ) data;
     530                 :          0 :                     break;
     531                 :            :                 case NC_FLOAT:
     532                 :            :                 case NC_DOUBLE:
     533         [ #  # ]:          0 :                     delete[]( double* ) data;
     534                 :          0 :                     break;
     535                 :            :                 default:
     536                 :          0 :                     break;
     537                 :            :             }
     538 [ #  # ][ #  # ]:          0 :             vdatas[i].varDatas[t] = NULL;
     539                 :            : 
     540                 :            :             // Loop continues only for set variables with timesteps, e.g. xtime(Time) or xtime(Time,
     541                 :            :             // StrLen)
     542 [ #  # ][ #  # ]:          0 :             if( !vdatas[i].has_tsteps ) break;
     543                 :            :         }
     544                 :            :     }
     545                 :            : 
     546                 :            :     // Debug output, if requested
     547         [ #  # ]:          0 :     if( 1 == dbgOut.get_verbosity() )
     548                 :            :     {
     549 [ #  # ][ #  # ]:          0 :         dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() );
     550         [ #  # ]:          0 :         for( unsigned int i = 1; i < vdatas.size(); i++ )
     551                 :          0 :             dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() );
     552                 :          0 :         dbgOut.tprintf( 1, "\n" );
     553                 :            :     }
     554                 :            : 
     555                 :          0 :     return rval;
     556                 :            : }
     557                 :            : 
     558                 :          0 : ErrorCode NCHelper::read_coordinate( const char* var_name, int lmin, int lmax, std::vector< double >& cvals )
     559                 :            : {
     560                 :          0 :     std::map< std::string, ReadNC::VarData >& varInfo       = _readNC->varInfo;
     561 [ #  # ][ #  # ]:          0 :     std::map< std::string, ReadNC::VarData >::iterator vmit = varInfo.find( var_name );
     562 [ #  # ][ #  # ]:          0 :     if( varInfo.end() == vmit ) MB_SET_ERR( MB_FAILURE, "Couldn't find variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     563                 :            : 
     564 [ #  # ][ #  # ]:          0 :     assert( lmin >= 0 && lmax >= lmin );
     565                 :          0 :     NCDF_SIZE tstart     = lmin;
     566                 :          0 :     NCDF_SIZE tcount     = lmax - lmin + 1;
     567                 :          0 :     NCDF_DIFF dum_stride = 1;
     568                 :            :     int success;
     569                 :            : 
     570                 :            :     // Check size
     571 [ #  # ][ #  # ]:          0 :     if( (std::size_t)tcount != cvals.size() ) cvals.resize( tcount );
     572                 :            : 
     573                 :            :     // Check to make sure it's a float or double
     574 [ #  # ][ #  # ]:          0 :     switch( ( *vmit ).second.varDataType )
     575                 :            :     {
     576                 :            :         case NC_FLOAT:
     577                 :            :         case NC_DOUBLE:
     578                 :            :             // Read float as double
     579                 :            :             success =
     580 [ #  # ][ #  # ]:          0 :                 NCFUNCAG( _vars_double )( _fileId, ( *vmit ).second.varId, &tstart, &tcount, &dum_stride, &cvals[0] );
                 [ #  # ]
     581 [ #  # ][ #  # ]:          0 :             if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read float/double data for variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     582                 :          0 :             break;
     583                 :            :         default:
     584 [ #  # ][ #  # ]:          0 :             MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     585                 :            :     }
     586                 :            : 
     587                 :          0 :     return MB_SUCCESS;
     588                 :            : }
     589                 :            : 
     590                 :          0 : ErrorCode NCHelper::get_tag_to_set( ReadNC::VarData& var_data, int tstep_num, Tag& tagh )
     591                 :            : {
     592                 :          0 :     Interface*& mbImpl  = _readNC->mbImpl;
     593                 :          0 :     DebugOutput& dbgOut = _readNC->dbgOut;
     594                 :          0 :     int& tStepBase      = _readNC->tStepBase;
     595                 :            : 
     596         [ #  # ]:          0 :     if( tStepBase > 0 ) tstep_num += tStepBase;
     597                 :            : 
     598         [ #  # ]:          0 :     std::ostringstream tag_name;
     599         [ #  # ]:          0 :     if( var_data.has_tsteps )
     600 [ #  # ][ #  # ]:          0 :         tag_name << var_data.varName << tstep_num;
     601                 :            :     else
     602         [ #  # ]:          0 :         tag_name << var_data.varName;
     603                 :            : 
     604                 :          0 :     ErrorCode rval = MB_SUCCESS;
     605                 :          0 :     tagh           = 0;
     606   [ #  #  #  # ]:          0 :     switch( var_data.varDataType )
     607                 :            :     {
     608                 :            :         case NC_BYTE:
     609                 :            :         case NC_CHAR:
     610                 :            :             rval = mbImpl->tag_get_handle( tag_name.str().c_str(), 0, MB_TYPE_OPAQUE, tagh,
     611 [ #  # ][ #  # ]:          0 :                                            MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     612                 :          0 :             break;
     613                 :            :         case NC_SHORT:
     614                 :            :         case NC_INT:
     615                 :            :             rval = mbImpl->tag_get_handle( tag_name.str().c_str(), 0, MB_TYPE_INTEGER, tagh,
     616 [ #  # ][ #  # ]:          0 :                                            MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     617                 :          0 :             break;
     618                 :            :         case NC_FLOAT:
     619                 :            :         case NC_DOUBLE:
     620                 :            :             rval = mbImpl->tag_get_handle( tag_name.str().c_str(), 0, MB_TYPE_DOUBLE, tagh,
     621 [ #  # ][ #  # ]:          0 :                                            MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     622                 :          0 :             break;
     623                 :            :         default:
     624 [ #  # ][ #  # ]:          0 :             MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << var_data.varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     625                 :            :     }
     626                 :            : 
     627 [ #  # ][ #  # ]:          0 :     dbgOut.tprintf( 2, "Tag %s created\n", tag_name.str().c_str() );
     628                 :            : 
     629                 :          0 :     return rval;
     630                 :            : }
     631                 :            : 
     632                 :          0 : ErrorCode NCHelper::get_tag_to_nonset( ReadNC::VarData& var_data, int tstep_num, Tag& tagh, int num_lev )
     633                 :            : {
     634                 :          0 :     Interface*& mbImpl  = _readNC->mbImpl;
     635                 :          0 :     DebugOutput& dbgOut = _readNC->dbgOut;
     636                 :          0 :     int& tStepBase      = _readNC->tStepBase;
     637                 :            : 
     638         [ #  # ]:          0 :     if( tStepBase > 0 ) tstep_num += tStepBase;
     639                 :            : 
     640         [ #  # ]:          0 :     std::ostringstream tag_name;
     641 [ #  # ][ #  # ]:          0 :     tag_name << var_data.varName << tstep_num;
     642                 :            : 
     643                 :          0 :     ErrorCode rval = MB_SUCCESS;
     644                 :          0 :     tagh           = 0;
     645   [ #  #  #  # ]:          0 :     switch( var_data.varDataType )
     646                 :            :     {
     647                 :            :         case NC_BYTE:
     648                 :            :         case NC_CHAR:
     649                 :            :             rval = mbImpl->tag_get_handle( tag_name.str().c_str(), num_lev, MB_TYPE_OPAQUE, tagh,
     650 [ #  # ][ #  # ]:          0 :                                            MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     651                 :          0 :             break;
     652                 :            :         case NC_SHORT:
     653                 :            :         case NC_INT:
     654                 :            :             rval = mbImpl->tag_get_handle( tag_name.str().c_str(), num_lev, MB_TYPE_INTEGER, tagh,
     655 [ #  # ][ #  # ]:          0 :                                            MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     656                 :          0 :             break;
     657                 :            :         case NC_FLOAT:
     658                 :            :         case NC_DOUBLE:
     659                 :            :             rval = mbImpl->tag_get_handle( tag_name.str().c_str(), num_lev, MB_TYPE_DOUBLE, tagh,
     660 [ #  # ][ #  # ]:          0 :                                            MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating tag " << tag_name.str() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     661                 :          0 :             break;
     662                 :            :         default:
     663 [ #  # ][ #  # ]:          0 :             MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << var_data.varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     664                 :            :     }
     665                 :            : 
     666 [ #  # ][ #  # ]:          0 :     dbgOut.tprintf( 2, "Tag %s created\n", tag_name.str().c_str() );
     667                 :            : 
     668                 :          0 :     return rval;
     669                 :            : }
     670                 :            : 
     671                 :          0 : ErrorCode NCHelper::create_attrib_string( const std::map< std::string, ReadNC::AttData >& attMap, std::string& attVal,
     672                 :            :                                           std::vector< int >& attLen )
     673                 :            : {
     674                 :            :     int success;
     675 [ #  # ][ #  # ]:          0 :     std::stringstream ssAtt;
     676                 :          0 :     unsigned int sz                                                = 0;
     677                 :          0 :     std::map< std::string, ReadNC::AttData >::const_iterator attIt = attMap.begin();
     678 [ #  # ][ #  # ]:          0 :     for( ; attIt != attMap.end(); ++attIt )
                 [ #  # ]
     679                 :            :     {
     680 [ #  # ][ #  # ]:          0 :         ssAtt << attIt->second.attName;
     681         [ #  # ]:          0 :         ssAtt << '\0';
     682                 :          0 :         void* attData = NULL;
     683 [ #  # ][ #  #  :          0 :         switch( attIt->second.attDataType )
             #  #  #  # ]
     684                 :            :         {
     685                 :            :             case NC_BYTE:
     686                 :            :             case NC_CHAR:
     687         [ #  # ]:          0 :                 sz      = attIt->second.attLen;
     688                 :          0 :                 attData = (char*)malloc( sz );
     689   [ #  #  #  # ]:          0 :                 success = NCFUNC( get_att_text )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
     690         [ #  # ]:          0 :                                                   (char*)attData );
     691         [ #  # ]:          0 :                 if( success )
     692 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Failed to read byte/char data for attribute " << attIt->second.attName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     693         [ #  # ]:          0 :                 ssAtt << "char;";
     694                 :          0 :                 break;
     695                 :            :             case NC_SHORT:
     696         [ #  # ]:          0 :                 sz      = attIt->second.attLen * sizeof( short );
     697                 :          0 :                 attData = (short*)malloc( sz );
     698   [ #  #  #  # ]:          0 :                 success = NCFUNC( get_att_short )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
     699         [ #  # ]:          0 :                                                    (short*)attData );
     700         [ #  # ]:          0 :                 if( success )
     701 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Failed to read short data for attribute " << attIt->second.attName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     702         [ #  # ]:          0 :                 ssAtt << "short;";
     703                 :          0 :                 break;
     704                 :            :             case NC_INT:
     705         [ #  # ]:          0 :                 sz      = attIt->second.attLen * sizeof( int );
     706                 :          0 :                 attData = (int*)malloc( sz );
     707   [ #  #  #  # ]:          0 :                 success = NCFUNC( get_att_int )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
     708         [ #  # ]:          0 :                                                  (int*)attData );
     709         [ #  # ]:          0 :                 if( success )
     710 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Failed to read int data for attribute " << attIt->second.attName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     711         [ #  # ]:          0 :                 ssAtt << "int;";
     712                 :          0 :                 break;
     713                 :            :             case NC_FLOAT:
     714         [ #  # ]:          0 :                 sz      = attIt->second.attLen * sizeof( float );
     715                 :          0 :                 attData = (float*)malloc( sz );
     716   [ #  #  #  # ]:          0 :                 success = NCFUNC( get_att_float )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
     717         [ #  # ]:          0 :                                                    (float*)attData );
     718         [ #  # ]:          0 :                 if( success )
     719 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Failed to read float data for attribute " << attIt->second.attName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     720         [ #  # ]:          0 :                 ssAtt << "float;";
     721                 :          0 :                 break;
     722                 :            :             case NC_DOUBLE:
     723         [ #  # ]:          0 :                 sz      = attIt->second.attLen * sizeof( double );
     724                 :          0 :                 attData = (double*)malloc( sz );
     725   [ #  #  #  # ]:          0 :                 success = NCFUNC( get_att_double )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
     726         [ #  # ]:          0 :                                                     (double*)attData );
     727         [ #  # ]:          0 :                 if( success )
     728 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Failed to read double data for attribute " << attIt->second.attName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     729         [ #  # ]:          0 :                 ssAtt << "double;";
     730                 :          0 :                 break;
     731                 :            :             default:
     732 [ #  # ][ #  # ]:          0 :                 MB_SET_ERR( MB_FAILURE, "Unexpected data type for attribute " << attIt->second.attName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     733                 :            :         }
     734                 :          0 :         char* tmpc = (char*)attData;
     735         [ #  # ]:          0 :         for( unsigned int counter = 0; counter != sz; ++counter )
     736         [ #  # ]:          0 :             ssAtt << tmpc[counter];
     737                 :          0 :         free( attData );
     738         [ #  # ]:          0 :         ssAtt << ';';
     739 [ #  # ][ #  # ]:          0 :         attLen.push_back( ssAtt.str().size() - 1 );
     740                 :            :     }
     741 [ #  # ][ #  # ]:          0 :     attVal = ssAtt.str();
     742                 :            : 
     743                 :          0 :     return MB_SUCCESS;
     744                 :            : }
     745                 :            : 
     746                 :          0 : ErrorCode NCHelper::create_dummy_variables()
     747                 :            : {
     748                 :          0 :     Interface*& mbImpl                                = _readNC->mbImpl;
     749                 :          0 :     std::vector< std::string >& dimNames              = _readNC->dimNames;
     750                 :          0 :     std::vector< int >& dimLens                       = _readNC->dimLens;
     751                 :          0 :     std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
     752                 :          0 :     DebugOutput& dbgOut                               = _readNC->dbgOut;
     753                 :            : 
     754                 :            :     // Hack: look at all dimensions, and see if we have one that does not appear in the list of
     755                 :            :     // varInfo names Right now, candidates are from unstructured meshes, such as ncol (HOMME) and
     756                 :            :     // nCells (MPAS) For each of them, create a dummy coordinate variable with a sparse tag to store
     757                 :            :     // the dimension length
     758         [ #  # ]:          0 :     for( unsigned int i = 0; i < dimNames.size(); i++ )
     759                 :            :     {
     760                 :            :         // If there is a variable with this dimension name, skip
     761 [ #  # ][ #  # ]:          0 :         if( varInfo.find( dimNames[i] ) != varInfo.end() ) continue;
         [ #  # ][ #  # ]
     762                 :            : 
     763                 :            :         // Create a dummy coordinate variable
     764                 :          0 :         int sizeTotalVar = varInfo.size();
     765 [ #  # ][ #  # ]:          0 :         std::string var_name( dimNames[i] );
     766         [ #  # ]:          0 :         ReadNC::VarData& data = varInfo[var_name];
     767         [ #  # ]:          0 :         data.varName          = var_name;
     768                 :          0 :         data.varId            = sizeTotalVar;
     769         [ #  # ]:          0 :         data.varTags.resize( 1, 0 );
     770                 :          0 :         data.varDataType = NC_INT;
     771         [ #  # ]:          0 :         data.varDims.resize( 1 );
     772         [ #  # ]:          0 :         data.varDims[0] = (int)i;
     773                 :          0 :         data.numAtts    = 0;
     774                 :          0 :         data.entLoc     = ReadNC::ENTLOCSET;
     775         [ #  # ]:          0 :         dummyVarNames.insert( var_name );
     776         [ #  # ]:          0 :         dbgOut.tprintf( 2, "Dummy coordinate variable created for dimension %s\n", var_name.c_str() );
     777                 :            : 
     778                 :            :         // Create a corresponding sparse tag
     779                 :            :         Tag tagh;
     780                 :            :         ErrorCode rval = mbImpl->tag_get_handle( var_name.c_str(), 0, MB_TYPE_INTEGER, tagh,
     781 [ #  # ][ #  # ]:          0 :                                                  MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble creating tag for dummy coordinate variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     782                 :            : 
     783                 :            :         // Tag value is the dimension length
     784         [ #  # ]:          0 :         const void* ptr = &dimLens[i];
     785                 :            :         // Tag size is 1
     786                 :          0 :         int size = 1;
     787 [ #  # ][ #  # ]:          0 :         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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     788                 :            : 
     789 [ #  # ][ #  # ]:          0 :         dbgOut.tprintf( 2, "Sparse tag created for dimension %s\n", var_name.c_str() );
     790                 :          0 :     }
     791                 :            : 
     792                 :          0 :     return MB_SUCCESS;
     793                 :            : }
     794                 :            : 
     795                 :          0 : ErrorCode NCHelper::read_variables_to_set_allocate( std::vector< ReadNC::VarData >& vdatas,
     796                 :            :                                                     std::vector< int >& tstep_nums )
     797                 :            : {
     798                 :          0 :     std::vector< int >& dimLens = _readNC->dimLens;
     799                 :          0 :     DebugOutput& dbgOut         = _readNC->dbgOut;
     800                 :            : 
     801                 :          0 :     ErrorCode rval = MB_SUCCESS;
     802                 :            : 
     803         [ #  # ]:          0 :     for( unsigned int i = 0; i < vdatas.size(); i++ )
     804                 :            :     {
     805                 :            :         // Set up readStarts and readCounts
     806         [ #  # ]:          0 :         if( vdatas[i].has_tsteps )
     807                 :            :         {
     808                 :            :             // First: time
     809 [ #  # ][ #  # ]:          0 :             vdatas[i].readStarts.push_back( 0 );  // This value is timestep dependent, will be set later
     810 [ #  # ][ #  # ]:          0 :             vdatas[i].readCounts.push_back( 1 );
     811                 :            : 
     812                 :            :             // Next: other dimensions
     813         [ #  # ]:          0 :             for( unsigned int idx = 1; idx != vdatas[i].varDims.size(); idx++ )
     814                 :            :             {
     815 [ #  # ][ #  # ]:          0 :                 vdatas[i].readStarts.push_back( 0 );
     816 [ #  # ][ #  # ]:          0 :                 vdatas[i].readCounts.push_back( dimLens[vdatas[i].varDims[idx]] );
     817                 :            :             }
     818                 :            :         }
     819                 :            :         else
     820                 :            :         {
     821         [ #  # ]:          0 :             if( vdatas[i].varDims.empty() )
     822                 :            :             {
     823                 :            :                 // Scalar variable
     824 [ #  # ][ #  # ]:          0 :                 vdatas[i].readStarts.push_back( 0 );
     825 [ #  # ][ #  # ]:          0 :                 vdatas[i].readCounts.push_back( 1 );
     826                 :            :             }
     827                 :            :             else
     828                 :            :             {
     829         [ #  # ]:          0 :                 for( unsigned int idx = 0; idx != vdatas[i].varDims.size(); idx++ )
     830                 :            :                 {
     831 [ #  # ][ #  # ]:          0 :                     vdatas[i].readStarts.push_back( 0 );
     832 [ #  # ][ #  # ]:          0 :                     vdatas[i].readCounts.push_back( dimLens[vdatas[i].varDims[idx]] );
     833                 :            :                 }
     834                 :            :             }
     835                 :            :         }
     836                 :            : 
     837                 :            :         // Get variable size
     838                 :          0 :         vdatas[i].sz = 1;
     839         [ #  # ]:          0 :         for( std::size_t idx = 0; idx != vdatas[i].readCounts.size(); idx++ )
     840                 :          0 :             vdatas[i].sz *= vdatas[i].readCounts[idx];
     841                 :            : 
     842                 :            :         // Note, for set variables without timesteps, loop one time and then break
     843         [ #  # ]:          0 :         for( unsigned int t = 0; t < tstep_nums.size(); t++ )
     844                 :            :         {
     845                 :          0 :             dbgOut.tprintf( 2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t] );
     846                 :            : 
     847         [ #  # ]:          0 :             if( tstep_nums[t] >= dimLens[tDim] )
     848 [ #  # ][ #  # ]:          0 :             { MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t] ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     849                 :            : 
     850                 :            :             // Get the tag to read into
     851         [ #  # ]:          0 :             if( !vdatas[i].varTags[t] )
     852                 :            :             {
     853 [ #  # ][ #  # ]:          0 :                 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 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     854                 :            :             }
     855                 :            : 
     856   [ #  #  #  # ]:          0 :             switch( vdatas[i].varDataType )
     857                 :            :             {
     858                 :            :                 case NC_BYTE:
     859                 :            :                 case NC_CHAR:
     860                 :          0 :                     vdatas[i].varDatas[t] = new char[vdatas[i].sz];
     861                 :          0 :                     break;
     862                 :            :                 case NC_SHORT:
     863                 :            :                 case NC_INT:
     864         [ #  # ]:          0 :                     vdatas[i].varDatas[t] = new int[vdatas[i].sz];
     865                 :          0 :                     break;
     866                 :            :                 case NC_FLOAT:
     867                 :            :                 case NC_DOUBLE:
     868         [ #  # ]:          0 :                     vdatas[i].varDatas[t] = new double[vdatas[i].sz];
     869                 :          0 :                     break;
     870                 :            :                 default:
     871 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     872                 :            :             }
     873                 :            : 
     874                 :            :             // Loop continues only for set variables with timesteps, e.g. xtime(Time) or xtime(Time,
     875                 :            :             // StrLen)
     876         [ #  # ]:          0 :             if( !vdatas[i].has_tsteps ) break;
     877                 :            :         }
     878                 :            :     }
     879                 :            : 
     880                 :          0 :     return rval;
     881                 :            : }
     882                 :            : 
     883                 :          0 : ErrorCode ScdNCHelper::check_existing_mesh()
     884                 :            : {
     885                 :          0 :     Interface*& mbImpl = _readNC->mbImpl;
     886                 :            : 
     887                 :            :     // Get the number of vertices
     888                 :            :     int num_verts;
     889 [ #  # ][ #  # ]:          0 :     ErrorCode rval = mbImpl->get_number_entities_by_dimension( _fileSet, 0, num_verts );MB_CHK_SET_ERR( rval, "Trouble getting number of vertices" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     890                 :            : 
     891                 :            :     /*
     892                 :            :     // Check against parameters
     893                 :            :     // When ghosting is used, this check might fail (to be updated later)
     894                 :            :     if (num_verts > 0) {
     895                 :            :       int expected_verts = (lDims[3] - lDims[0] + 1) * (lDims[4] - lDims[1] + 1) * (-1 == lDims[2] ?
     896                 :            :     1 : lDims[5] - lDims[2] + 1); if (num_verts != expected_verts) { MB_SET_ERR(MB_FAILURE, "Number
     897                 :            :     of vertices doesn't match");
     898                 :            :       }
     899                 :            :     }
     900                 :            :     */
     901                 :            : 
     902                 :            :     // Check the number of elements too
     903                 :            :     int num_elems;
     904 [ #  # ][ #  # ]:          0 :     rval = mbImpl->get_number_entities_by_dimension( _fileSet, ( -1 == lCDims[2] ? 2 : 3 ), num_elems );MB_CHK_SET_ERR( rval, "Trouble getting number of elements" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     905                 :            : 
     906                 :            :     /*
     907                 :            :     // Check against parameters
     908                 :            :     // When ghosting is used, this check might fail (to be updated later)
     909                 :            :     if (num_elems > 0) {
     910                 :            :       int expected_elems = (lCDims[3] - lCDims[0] + 1) * (lCDims[4] - lCDims[1] + 1) * (-1 ==
     911                 :            :     lCDims[2] ? 1 : (lCDims[5] - lCDims[2] + 1)); if (num_elems != expected_elems) {
     912                 :            :         MB_SET_ERR(MB_FAILURE, "Number of elements doesn't match");
     913                 :            :       }
     914                 :            :     }
     915                 :            :     */
     916                 :            : 
     917                 :          0 :     return MB_SUCCESS;
     918                 :            : }
     919                 :            : 
     920                 :          0 : ErrorCode ScdNCHelper::create_mesh( Range& faces )
     921                 :            : {
     922                 :          0 :     Interface*& mbImpl      = _readNC->mbImpl;
     923                 :          0 :     Tag& mGlobalIdTag       = _readNC->mGlobalIdTag;
     924                 :          0 :     const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
     925                 :          0 :     DebugOutput& dbgOut     = _readNC->dbgOut;
     926                 :          0 :     ScdInterface* scdi      = _readNC->scdi;
     927                 :          0 :     ScdParData& parData     = _readNC->parData;
     928                 :            : 
     929         [ #  # ]:          0 :     Range tmp_range;
     930                 :            :     ScdBox* scd_box;
     931                 :            : 
     932                 :            :     ErrorCode rval =
     933                 :            :         scdi->construct_box( HomCoord( lDims[0], lDims[1], lDims[2], 1 ), HomCoord( lDims[3], lDims[4], lDims[5], 1 ),
     934 [ #  # ][ #  # ]:          0 :                              NULL, 0, scd_box, locallyPeriodic, &parData, true );MB_CHK_SET_ERR( rval, "Trouble creating scd vertex sequence" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     935                 :            : 
     936                 :            :     // Add verts to tmp_range first, so we can duplicate global ids in vertex ids
     937 [ #  # ][ #  # ]:          0 :     tmp_range.insert( scd_box->start_vertex(), scd_box->start_vertex() + scd_box->num_vertices() - 1 );
         [ #  # ][ #  # ]
     938                 :            : 
     939         [ #  # ]:          0 :     if( mpFileIdTag )
     940                 :            :     {
     941                 :            :         int count;
     942                 :            :         void* data;
     943 [ #  # ][ #  # ]:          0 :         rval = mbImpl->tag_iterate( *mpFileIdTag, tmp_range.begin(), tmp_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate file ID tag on local vertices" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     944 [ #  # ][ #  # ]:          0 :         assert( count == scd_box->num_vertices() );
     945                 :          0 :         int* fid_data = (int*)data;
     946 [ #  # ][ #  # ]:          0 :         rval          = mbImpl->tag_iterate( mGlobalIdTag, tmp_range.begin(), tmp_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global ID tag on local vertices" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     947 [ #  # ][ #  # ]:          0 :         assert( count == scd_box->num_vertices() );
     948                 :          0 :         int* gid_data = (int*)data;
     949         [ #  # ]:          0 :         for( int i = 0; i < count; i++ )
     950                 :          0 :             fid_data[i] = gid_data[i];
     951                 :            :     }
     952                 :            : 
     953                 :            :     // Then add box set and elements to the range, then to the file set
     954 [ #  # ][ #  # ]:          0 :     tmp_range.insert( scd_box->start_element(), scd_box->start_element() + scd_box->num_elements() - 1 );
         [ #  # ][ #  # ]
     955 [ #  # ][ #  # ]:          0 :     tmp_range.insert( scd_box->box_set() );
     956 [ #  # ][ #  # ]:          0 :     rval = mbImpl->add_entities( _fileSet, tmp_range );MB_CHK_SET_ERR( rval, "Couldn't add new vertices to current file set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     957                 :            : 
     958 [ #  # ][ #  # ]:          0 :     dbgOut.tprintf( 1, "scdbox %d quads, %d vertices\n", scd_box->num_elements(), scd_box->num_vertices() );
                 [ #  # ]
     959                 :            : 
     960                 :            :     // Set the vertex coordinates
     961                 :            :     double *xc, *yc, *zc;
     962 [ #  # ][ #  # ]:          0 :     rval = scd_box->get_coordinate_arrays( xc, yc, zc );MB_CHK_SET_ERR( rval, "Couldn't get vertex coordinate arrays" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     963                 :            : 
     964                 :            :     int i, j, k, il, jl, kl;
     965                 :          0 :     int dil = lDims[3] - lDims[0] + 1;
     966                 :          0 :     int djl = lDims[4] - lDims[1] + 1;
     967 [ #  # ][ #  # ]:          0 :     assert( dil == (int)ilVals.size() && djl == (int)jlVals.size() &&
                 [ #  # ]
     968         [ #  # ]:          0 :             ( -1 == lDims[2] || lDims[5] - lDims[2] + 1 == (int)levVals.size() ) );
     969                 :            : 
     970         [ #  # ]:          0 :     for( kl = lDims[2]; kl <= lDims[5]; kl++ )
     971                 :            :     {
     972                 :          0 :         k = kl - lDims[2];
     973         [ #  # ]:          0 :         for( jl = lDims[1]; jl <= lDims[4]; jl++ )
     974                 :            :         {
     975                 :          0 :             j = jl - lDims[1];
     976         [ #  # ]:          0 :             for( il = lDims[0]; il <= lDims[3]; il++ )
     977                 :            :             {
     978                 :          0 :                 i                = il - lDims[0];
     979                 :          0 :                 unsigned int pos = i + j * dil + k * dil * djl;
     980         [ #  # ]:          0 :                 xc[pos]          = ilVals[i];
     981         [ #  # ]:          0 :                 yc[pos]          = jlVals[j];
     982 [ #  # ][ #  # ]:          0 :                 zc[pos]          = ( -1 == lDims[2] ? 0.0 : levVals[k] );
     983                 :            :             }
     984                 :            :         }
     985                 :            :     }
     986                 :            : 
     987                 :            : #ifndef NDEBUG
     988                 :            :     int num_verts =
     989         [ #  # ]:          0 :         ( lDims[3] - lDims[0] + 1 ) * ( lDims[4] - lDims[1] + 1 ) * ( -1 == lDims[2] ? 1 : lDims[5] - lDims[2] + 1 );
     990         [ #  # ]:          0 :     std::vector< int > gids( num_verts );
     991 [ #  # ][ #  # ]:          0 :     Range verts( scd_box->start_vertex(), scd_box->start_vertex() + scd_box->num_vertices() - 1 );
         [ #  # ][ #  # ]
     992 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_data( mGlobalIdTag, verts, &gids[0] );MB_CHK_SET_ERR( rval, "Trouble getting local gid values of vertices" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     993 [ #  # ][ #  # ]:          0 :     int vmin = *( std::min_element( gids.begin(), gids.end() ) ),
     994 [ #  # ][ #  # ]:          0 :         vmax = *( std::max_element( gids.begin(), gids.end() ) );
     995         [ #  # ]:          0 :     dbgOut.tprintf( 1, "Vertex gids %d-%d\n", vmin, vmax );
     996                 :            : #endif
     997                 :            : 
     998                 :            :     // Add elements to the range passed in
     999 [ #  # ][ #  # ]:          0 :     faces.insert( scd_box->start_element(), scd_box->start_element() + scd_box->num_elements() - 1 );
         [ #  # ][ #  # ]
    1000                 :            : 
    1001 [ #  # ][ #  # ]:          0 :     if( 2 <= dbgOut.get_verbosity() )
    1002                 :            :     {
    1003 [ #  # ][ #  # ]:          0 :         assert( scd_box->boundary_complete() );
    1004         [ #  # ]:          0 :         EntityHandle dum_ent = scd_box->start_element();
    1005 [ #  # ][ #  # ]:          0 :         rval                 = mbImpl->list_entities( &dum_ent, 1 );MB_CHK_SET_ERR( rval, "Trouble listing first hex" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1006                 :            : 
    1007         [ #  # ]:          0 :         std::vector< EntityHandle > connect;
    1008 [ #  # ][ #  # ]:          0 :         rval = mbImpl->get_connectivity( &dum_ent, 1, connect );MB_CHK_SET_ERR( rval, "Trouble getting connectivity" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1009                 :            : 
    1010 [ #  # ][ #  # ]:          0 :         rval = mbImpl->list_entities( &connect[0], connect.size() );MB_CHK_SET_ERR( rval, "Trouble listing element connectivity" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1011                 :            :     }
    1012                 :            : 
    1013         [ #  # ]:          0 :     Range edges;
    1014         [ #  # ]:          0 :     mbImpl->get_adjacencies( faces, 1, true, edges, Interface::UNION );
    1015                 :            : 
    1016                 :            :     // Create COORDS tag for quads
    1017 [ #  # ][ #  # ]:          0 :     rval = create_quad_coordinate_tag();MB_CHK_SET_ERR( rval, "Trouble creating COORDS tag for quads" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1018                 :            : 
    1019                 :          0 :     return MB_SUCCESS;
    1020                 :            : }
    1021                 :            : 
    1022                 :          0 : ErrorCode ScdNCHelper::read_variables( std::vector< std::string >& var_names, std::vector< int >& tstep_nums )
    1023                 :            : {
    1024         [ #  # ]:          0 :     std::vector< ReadNC::VarData > vdatas;
    1025         [ #  # ]:          0 :     std::vector< ReadNC::VarData > vsetdatas;
    1026                 :            : 
    1027 [ #  # ][ #  # ]:          0 :     ErrorCode rval = read_variables_setup( var_names, tstep_nums, vdatas, vsetdatas );MB_CHK_SET_ERR( rval, "Trouble setting up to read variables" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1028                 :            : 
    1029         [ #  # ]:          0 :     if( !vsetdatas.empty() )
    1030                 :            :     {
    1031 [ #  # ][ #  # ]:          0 :         rval = read_variables_to_set( vsetdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading variables to set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1032                 :            :     }
    1033                 :            : 
    1034         [ #  # ]:          0 :     if( !vdatas.empty() )
    1035                 :            :     {
    1036 [ #  # ][ #  # ]:          0 :         rval = read_scd_variables_to_nonset( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading variables to verts/edges/faces" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1037                 :            :     }
    1038                 :            : 
    1039                 :          0 :     return MB_SUCCESS;
    1040                 :            : }
    1041                 :            : 
    1042                 :          0 : ErrorCode ScdNCHelper::read_scd_variables_to_nonset_allocate( std::vector< ReadNC::VarData >& vdatas,
    1043                 :            :                                                               std::vector< int >& tstep_nums )
    1044                 :            : {
    1045                 :          0 :     Interface*& mbImpl          = _readNC->mbImpl;
    1046                 :          0 :     std::vector< int >& dimLens = _readNC->dimLens;
    1047                 :          0 :     DebugOutput& dbgOut         = _readNC->dbgOut;
    1048                 :            : 
    1049                 :          0 :     Range* range = NULL;
    1050                 :            : 
    1051                 :            :     // Get vertices
    1052         [ #  # ]:          0 :     Range verts;
    1053 [ #  # ][ #  # ]:          0 :     ErrorCode rval = mbImpl->get_entities_by_dimension( _fileSet, 0, verts );MB_CHK_SET_ERR( rval, "Trouble getting vertices in current file set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1054 [ #  # ][ #  # ]:          0 :     assert( "Should only have a single vertex subrange, since they were read in one shot" && verts.psize() == 1 );
    1055                 :            : 
    1056         [ #  # ]:          0 :     Range edges;
    1057 [ #  # ][ #  # ]:          0 :     rval = mbImpl->get_entities_by_dimension( _fileSet, 1, edges );MB_CHK_SET_ERR( rval, "Trouble getting edges in current file set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1058                 :            : 
    1059                 :            :     // Get faces
    1060         [ #  # ]:          0 :     Range faces;
    1061 [ #  # ][ #  # ]:          0 :     rval = mbImpl->get_entities_by_dimension( _fileSet, 2, faces );MB_CHK_SET_ERR( rval, "Trouble getting faces in current file set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1062 [ #  # ][ #  # ]:          0 :     assert( "Should only have a single face subrange, since they were read in one shot" && faces.psize() == 1 );
    1063                 :            : 
    1064                 :            : #ifdef MOAB_HAVE_MPI
    1065         [ #  # ]:          0 :     moab::Range faces_owned;
    1066                 :          0 :     bool& isParallel = _readNC->isParallel;
    1067         [ #  # ]:          0 :     if( isParallel )
    1068                 :            :     {
    1069                 :          0 :         ParallelComm*& myPcomm = _readNC->myPcomm;
    1070 [ #  # ][ #  # ]:          0 :         rval                   = myPcomm->filter_pstatus( faces, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &faces_owned );MB_CHK_SET_ERR( rval, "Trouble getting owned faces in current file set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1071                 :            :     }
    1072                 :            :     else
    1073         [ #  # ]:          0 :         faces_owned = faces;  // Not running in parallel, but still with MPI
    1074                 :            : #endif
    1075                 :            : 
    1076         [ #  # ]:          0 :     for( unsigned int i = 0; i < vdatas.size(); i++ )
    1077                 :            :     {
    1078                 :            :         // Support non-set variables with 4 dimensions like (time, lev, lat, lon)
    1079 [ #  # ][ #  # ]:          0 :         assert( 4 == vdatas[i].varDims.size() );
    1080                 :            : 
    1081                 :            :         // For a non-set variable, time should be the first dimension
    1082 [ #  # ][ #  # ]:          0 :         assert( tDim == vdatas[i].varDims[0] );
                 [ #  # ]
    1083                 :            : 
    1084                 :            :         // Set up readStarts and readCounts
    1085 [ #  # ][ #  # ]:          0 :         vdatas[i].readStarts.resize( 4 );
    1086 [ #  # ][ #  # ]:          0 :         vdatas[i].readCounts.resize( 4 );
    1087                 :            : 
    1088                 :            :         // First: time
    1089 [ #  # ][ #  # ]:          0 :         vdatas[i].readStarts[0] = 0;  // This value is timestep dependent, will be set later
    1090 [ #  # ][ #  # ]:          0 :         vdatas[i].readCounts[0] = 1;
    1091                 :            : 
    1092                 :            :         // Next: lev
    1093 [ #  # ][ #  # ]:          0 :         vdatas[i].readStarts[1] = 0;
    1094 [ #  # ][ #  # ]:          0 :         vdatas[i].readCounts[1] = vdatas[i].numLev;
                 [ #  # ]
    1095                 :            : 
    1096                 :            :         // Finally: lat (or slat) and lon (or slon)
    1097         [ #  # ]:          0 :         switch( vdatas[i].entLoc )
           [ #  #  #  # ]
    1098                 :            :         {
    1099                 :            :             case ReadNC::ENTLOCVERT:
    1100                 :            :                 // Vertices
    1101 [ #  # ][ #  # ]:          0 :                 vdatas[i].readStarts[2] = lDims[1];
    1102 [ #  # ][ #  # ]:          0 :                 vdatas[i].readCounts[2] = lDims[4] - lDims[1] + 1;
    1103 [ #  # ][ #  # ]:          0 :                 vdatas[i].readStarts[3] = lDims[0];
    1104 [ #  # ][ #  # ]:          0 :                 vdatas[i].readCounts[3] = lDims[3] - lDims[0] + 1;
    1105                 :          0 :                 range                   = &verts;
    1106                 :          0 :                 break;
    1107                 :            :             case ReadNC::ENTLOCNSEDGE:
    1108                 :            :             case ReadNC::ENTLOCEWEDGE:
    1109                 :            :             case ReadNC::ENTLOCEDGE:
    1110                 :            :                 // Not implemented yet, set a global error
    1111 [ #  # ][ #  # ]:          0 :                 MB_SET_GLB_ERR( MB_NOT_IMPLEMENTED, "Reading edge data is not implemented yet" );
         [ #  # ][ #  # ]
                 [ #  # ]
    1112                 :            :             case ReadNC::ENTLOCFACE:
    1113                 :            :                 // Faces
    1114 [ #  # ][ #  # ]:          0 :                 vdatas[i].readStarts[2] = lCDims[1];
    1115 [ #  # ][ #  # ]:          0 :                 vdatas[i].readCounts[2] = lCDims[4] - lCDims[1] + 1;
    1116 [ #  # ][ #  # ]:          0 :                 vdatas[i].readStarts[3] = lCDims[0];
    1117 [ #  # ][ #  # ]:          0 :                 vdatas[i].readCounts[3] = lCDims[3] - lCDims[0] + 1;
    1118                 :            : #ifdef MOAB_HAVE_MPI
    1119                 :          0 :                 range = &faces_owned;
    1120                 :            : #else
    1121                 :            :                 range = &faces;
    1122                 :            : #endif
    1123                 :          0 :                 break;
    1124                 :            :             default:
    1125 [ #  # ][ #  # ]:          0 :                 MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1126                 :            :         }
    1127                 :            : 
    1128         [ #  # ]:          0 :         for( unsigned int t = 0; t < tstep_nums.size(); t++ )
    1129                 :            :         {
    1130 [ #  # ][ #  # ]:          0 :             dbgOut.tprintf( 2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t] );
                 [ #  # ]
    1131                 :            : 
    1132 [ #  # ][ #  # ]:          0 :             if( tstep_nums[t] >= dimLens[tDim] )
                 [ #  # ]
    1133 [ #  # ][ #  # ]:          0 :             { MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t] ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1134                 :            : 
    1135                 :            :             // Get the tag to read into
    1136 [ #  # ][ #  # ]:          0 :             if( !vdatas[i].varTags[t] )
                 [ #  # ]
    1137                 :            :             {
    1138 [ #  # ][ #  # ]:          0 :                 rval = get_tag_to_nonset( vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev );MB_CHK_SET_ERR( rval, "Trouble getting tag to non-set variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1139                 :            :             }
    1140                 :            : 
    1141                 :            :             // Get ptr to tag space
    1142                 :            :             void* data;
    1143                 :            :             int count;
    1144 [ #  # ][ #  # ]:          0 :             rval = mbImpl->tag_iterate( vdatas[i].varTags[t], range->begin(), range->end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate tag for non-set variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1145 [ #  # ][ #  # ]:          0 :             assert( (unsigned)count == range->size() );
    1146 [ #  # ][ #  # ]:          0 :             vdatas[i].varDatas[t] = data;
    1147                 :            :         }
    1148                 :            : 
    1149                 :            :         // Get variable size
    1150         [ #  # ]:          0 :         vdatas[i].sz = 1;
    1151 [ #  # ][ #  # ]:          0 :         for( std::size_t idx = 0; idx != vdatas[i].readCounts.size(); idx++ )
    1152 [ #  # ][ #  # ]:          0 :             vdatas[i].sz *= vdatas[i].readCounts[idx];
                 [ #  # ]
    1153                 :            :     }
    1154                 :            : 
    1155                 :          0 :     return rval;
    1156                 :            : }
    1157                 :            : 
    1158                 :          0 : ErrorCode ScdNCHelper::read_scd_variables_to_nonset( std::vector< ReadNC::VarData >& vdatas,
    1159                 :            :                                                      std::vector< int >& tstep_nums )
    1160                 :            : {
    1161                 :          0 :     DebugOutput& dbgOut = _readNC->dbgOut;
    1162                 :            : 
    1163 [ #  # ][ #  # ]:          0 :     ErrorCode rval = read_scd_variables_to_nonset_allocate( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble allocating space to read non-set variables" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1164                 :            : 
    1165                 :            :     // Finally, read into that space
    1166                 :            :     int success;
    1167         [ #  # ]:          0 :     for( unsigned int i = 0; i < vdatas.size(); i++ )
    1168                 :            :     {
    1169                 :          0 :         std::size_t sz = vdatas[i].sz;
    1170                 :            : 
    1171                 :            :         // A typical supported variable: float T(time, lev, lat, lon)
    1172                 :            :         // For tag values, need transpose (lev, lat, lon) to (lat, lon, lev)
    1173                 :          0 :         size_t ni = vdatas[i].readCounts[3];  // lon or slon
    1174                 :          0 :         size_t nj = vdatas[i].readCounts[2];  // lat or slat
    1175                 :          0 :         size_t nk = vdatas[i].readCounts[1];  // lev
    1176                 :            : 
    1177         [ #  # ]:          0 :         for( unsigned int t = 0; t < tstep_nums.size(); t++ )
    1178                 :            :         {
    1179                 :            :             // Tag data for this timestep
    1180                 :          0 :             void* data = vdatas[i].varDatas[t];
    1181                 :            : 
    1182                 :            :             // Set readStart for each timestep along time dimension
    1183                 :          0 :             vdatas[i].readStarts[0] = tstep_nums[t];
    1184                 :            : 
    1185   [ #  #  #  # ]:          0 :             switch( vdatas[i].varDataType )
    1186                 :            :             {
    1187                 :            :                 case NC_BYTE:
    1188                 :            :                 case NC_CHAR: {
    1189         [ #  # ]:          0 :                     std::vector< char > tmpchardata( sz );
    1190 [ #  # ][ #  # ]:          0 :                     success = NCFUNCAG( _vara_text )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                 [ #  # ]
    1191 [ #  # ][ #  # ]:          0 :                                                       &vdatas[i].readCounts[0], &tmpchardata[0] );
         [ #  # ][ #  # ]
    1192         [ #  # ]:          0 :                     if( success )
    1193 [ #  # ][ #  # ]:          0 :                         MB_SET_ERR( MB_FAILURE, "Failed to read byte/char data for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1194 [ #  # ][ #  # ]:          0 :                     if( vdatas[i].numLev > 1 )
    1195                 :            :                         // Transpose (lev, lat, lon) to (lat, lon, lev)
    1196 [ #  # ][ #  # ]:          0 :                         kji_to_jik( ni, nj, nk, data, &tmpchardata[0] );
    1197                 :            :                     else
    1198                 :            :                     {
    1199         [ #  # ]:          0 :                         for( std::size_t idx = 0; idx != tmpchardata.size(); idx++ )
    1200         [ #  # ]:          0 :                             ( (char*)data )[idx] = tmpchardata[idx];
    1201                 :            :                     }
    1202         [ #  # ]:          0 :                     break;
    1203                 :            :                 }
    1204                 :            :                 case NC_SHORT:
    1205                 :            :                 case NC_INT: {
    1206         [ #  # ]:          0 :                     std::vector< int > tmpintdata( sz );
    1207 [ #  # ][ #  # ]:          0 :                     success = NCFUNCAG( _vara_int )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                 [ #  # ]
    1208 [ #  # ][ #  # ]:          0 :                                                      &vdatas[i].readCounts[0], &tmpintdata[0] );
         [ #  # ][ #  # ]
    1209         [ #  # ]:          0 :                     if( success )
    1210 [ #  # ][ #  # ]:          0 :                         MB_SET_ERR( MB_FAILURE, "Failed to read short/int data for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1211 [ #  # ][ #  # ]:          0 :                     if( vdatas[i].numLev > 1 )
    1212                 :            :                         // Transpose (lev, lat, lon) to (lat, lon, lev)
    1213 [ #  # ][ #  # ]:          0 :                         kji_to_jik( ni, nj, nk, data, &tmpintdata[0] );
    1214                 :            :                     else
    1215                 :            :                     {
    1216         [ #  # ]:          0 :                         for( std::size_t idx = 0; idx != tmpintdata.size(); idx++ )
    1217         [ #  # ]:          0 :                             ( (int*)data )[idx] = tmpintdata[idx];
    1218                 :            :                     }
    1219         [ #  # ]:          0 :                     break;
    1220                 :            :                 }
    1221                 :            :                 case NC_FLOAT:
    1222                 :            :                 case NC_DOUBLE: {
    1223         [ #  # ]:          0 :                     std::vector< double > tmpdoubledata( sz );
    1224 [ #  # ][ #  # ]:          0 :                     success = NCFUNCAG( _vara_double )( _fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
                 [ #  # ]
    1225 [ #  # ][ #  # ]:          0 :                                                         &vdatas[i].readCounts[0], &tmpdoubledata[0] );
         [ #  # ][ #  # ]
    1226         [ #  # ]:          0 :                     if( success )
    1227 [ #  # ][ #  # ]:          0 :                         MB_SET_ERR( MB_FAILURE, "Failed to read float/double data for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1228 [ #  # ][ #  # ]:          0 :                     if( vdatas[i].numLev > 1 )
    1229                 :            :                         // Transpose (lev, lat, lon) to (lat, lon, lev)
    1230 [ #  # ][ #  # ]:          0 :                         kji_to_jik( ni, nj, nk, data, &tmpdoubledata[0] );
    1231                 :            :                     else
    1232                 :            :                     {
    1233         [ #  # ]:          0 :                         for( std::size_t idx = 0; idx != tmpdoubledata.size(); idx++ )
    1234         [ #  # ]:          0 :                             ( (double*)data )[idx] = tmpdoubledata[idx];
    1235                 :            :                     }
    1236         [ #  # ]:          0 :                     break;
    1237                 :            :                 }
    1238                 :            :                 default:
    1239 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1240                 :            :             }
    1241                 :            :         }
    1242                 :            :     }
    1243                 :            : 
    1244                 :            :     // Debug output, if requested
    1245         [ #  # ]:          0 :     if( 1 == dbgOut.get_verbosity() )
    1246                 :            :     {
    1247 [ #  # ][ #  # ]:          0 :         dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() );
    1248         [ #  # ]:          0 :         for( unsigned int i = 1; i < vdatas.size(); i++ )
    1249                 :          0 :             dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() );
    1250                 :          0 :         dbgOut.tprintf( 1, "\n" );
    1251                 :            :     }
    1252                 :            : 
    1253                 :          0 :     return rval;
    1254                 :            : }
    1255                 :            : 
    1256                 :          0 : ErrorCode ScdNCHelper::create_quad_coordinate_tag()
    1257                 :            : {
    1258                 :          0 :     Interface*& mbImpl = _readNC->mbImpl;
    1259                 :            : 
    1260         [ #  # ]:          0 :     Range ents;
    1261 [ #  # ][ #  # ]:          0 :     ErrorCode rval = mbImpl->get_entities_by_type( _fileSet, moab::MBQUAD, ents );MB_CHK_SET_ERR( rval, "Trouble getting quads" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1262                 :            : 
    1263                 :          0 :     std::size_t numOwnedEnts = 0;
    1264                 :            : #ifdef MOAB_HAVE_MPI
    1265         [ #  # ]:          0 :     Range ents_owned;
    1266                 :          0 :     bool& isParallel = _readNC->isParallel;
    1267         [ #  # ]:          0 :     if( isParallel )
    1268                 :            :     {
    1269                 :          0 :         ParallelComm*& myPcomm = _readNC->myPcomm;
    1270 [ #  # ][ #  # ]:          0 :         rval                   = myPcomm->filter_pstatus( ents, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &ents_owned );MB_CHK_SET_ERR( rval, "Trouble getting owned quads" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1271         [ #  # ]:          0 :         numOwnedEnts = ents_owned.size();
    1272                 :            :     }
    1273                 :            :     else
    1274                 :            :     {
    1275         [ #  # ]:          0 :         numOwnedEnts = ents.size();
    1276         [ #  # ]:          0 :         ents_owned   = ents;
    1277                 :            :     }
    1278                 :            : #else
    1279                 :            :     numOwnedEnts = ents.size();
    1280                 :            : #endif
    1281                 :            : 
    1282         [ #  # ]:          0 :     if( numOwnedEnts == 0 ) return MB_SUCCESS;
    1283                 :            : 
    1284         [ #  # ]:          0 :     assert( numOwnedEnts == ilCVals.size() * jlCVals.size() );
    1285         [ #  # ]:          0 :     std::vector< double > coords( numOwnedEnts * 3 );
    1286                 :          0 :     std::size_t pos = 0;
    1287         [ #  # ]:          0 :     for( std::size_t j = 0; j != jlCVals.size(); ++j )
    1288                 :            :     {
    1289         [ #  # ]:          0 :         for( std::size_t i = 0; i != ilCVals.size(); ++i )
    1290                 :            :         {
    1291                 :          0 :             pos             = j * ilCVals.size() * 3 + i * 3;
    1292 [ #  # ][ #  # ]:          0 :             coords[pos]     = ilCVals[i];
    1293 [ #  # ][ #  # ]:          0 :             coords[pos + 1] = jlCVals[j];
    1294         [ #  # ]:          0 :             coords[pos + 2] = 0.0;
    1295                 :            :         }
    1296                 :            :     }
    1297         [ #  # ]:          0 :     std::string tag_name = "COORDS";
    1298                 :          0 :     Tag tagh             = 0;
    1299 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_handle( tag_name.c_str(), 3, MB_TYPE_DOUBLE, tagh, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating COORDS tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1300                 :            : 
    1301                 :            :     void* data;
    1302                 :            :     int count;
    1303                 :            : #ifdef MOAB_HAVE_MPI
    1304 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_iterate( tagh, ents_owned.begin(), ents_owned.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate COORDS tag on quads" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1305                 :            : #else
    1306                 :            :     rval = mbImpl->tag_iterate( tagh, ents.begin(), ents.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate COORDS tag on quads" );
    1307                 :            : #endif
    1308         [ #  # ]:          0 :     assert( count == (int)numOwnedEnts );
    1309                 :          0 :     double* quad_data = (double*)data;
    1310         [ #  # ]:          0 :     std::copy( coords.begin(), coords.end(), quad_data );
    1311                 :            : 
    1312                 :          0 :     return MB_SUCCESS;
    1313                 :            : }
    1314                 :            : 
    1315                 :          0 : ErrorCode UcdNCHelper::read_variables( std::vector< std::string >& var_names, std::vector< int >& tstep_nums )
    1316                 :            : {
    1317         [ #  # ]:          0 :     std::vector< ReadNC::VarData > vdatas;
    1318         [ #  # ]:          0 :     std::vector< ReadNC::VarData > vsetdatas;
    1319                 :            : 
    1320 [ #  # ][ #  # ]:          0 :     ErrorCode rval = read_variables_setup( var_names, tstep_nums, vdatas, vsetdatas );MB_CHK_SET_ERR( rval, "Trouble setting up to read variables" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1321                 :            : 
    1322         [ #  # ]:          0 :     if( !vsetdatas.empty() )
    1323                 :            :     {
    1324 [ #  # ][ #  # ]:          0 :         rval = read_variables_to_set( vsetdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading variables to set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1325                 :            :     }
    1326                 :            : 
    1327         [ #  # ]:          0 :     if( !vdatas.empty() )
    1328                 :            :     {
    1329                 :            : #ifdef MOAB_HAVE_PNETCDF
    1330                 :            :         // With pnetcdf support, we will use async read
    1331                 :            :         rval = read_ucd_variables_to_nonset_async( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading variables to verts/edges/faces" );
    1332                 :            : #else
    1333                 :            :         // Without pnetcdf support, we will use old read
    1334 [ #  # ][ #  # ]:          0 :         rval = read_ucd_variables_to_nonset( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble reading variables to verts/edges/faces" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1335                 :            : #endif
    1336                 :            :     }
    1337                 :            : 
    1338                 :          0 :     return MB_SUCCESS;
    1339                 :            : }
    1340                 :            : 
    1341 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11