LCOV - code coverage report
Current view: top level - src/io - WriteNC.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 1 261 0.4 %
Date: 2020-12-16 07:07:30 Functions: 2 9 22.2 %
Branches: 2 986 0.2 %

           Branch data     Line data    Source code
       1                 :            : #include "WriteNC.hpp"
       2                 :            : #include "moab/CN.hpp"
       3                 :            : #include "MBTagConventions.hpp"
       4                 :            : #include "MBParallelConventions.h"
       5                 :            : #include "moab/Interface.hpp"
       6                 :            : #include "moab/Range.hpp"
       7                 :            : #include "moab/WriteUtilIface.hpp"
       8                 :            : #include "moab/FileOptions.hpp"
       9                 :            : #include "NCWriteHelper.hpp"
      10                 :            : 
      11                 :            : #include <fstream>
      12                 :            : #include <map>
      13                 :            : #include <set>
      14                 :            : 
      15                 :            : #include <iostream>
      16                 :            : #include <sstream>
      17                 :            : 
      18                 :            : #ifdef WIN32
      19                 :            : #ifdef size_t
      20                 :            : #undef size_t
      21                 :            : #endif
      22                 :            : #endif
      23                 :            : 
      24                 :            : namespace moab
      25                 :            : {
      26                 :            : 
      27                 :          0 : WriterIface* WriteNC::factory( Interface* iface )
      28                 :            : {
      29         [ #  # ]:          0 :     return new WriteNC( iface );
      30                 :            : }
      31                 :            : 
      32                 :          0 : WriteNC::WriteNC( Interface* impl )
      33                 :            :     : mbImpl( impl ), dbgOut( stderr ),
      34                 :            : #ifdef MOAB_HAVE_MPI
      35                 :            :       myPcomm( NULL ),
      36                 :            : #endif
      37 [ #  # ][ #  # ]:          0 :       noMesh( false ), noVars( false ), append( false ), mGlobalIdTag( 0 ), isParallel( false ), myHelper( NULL )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      38                 :            : {
      39         [ #  # ]:          0 :     assert( impl != NULL );
      40         [ #  # ]:          0 :     impl->query_interface( mWriteIface );
      41                 :          0 : }
      42                 :            : 
      43                 :          0 : WriteNC::~WriteNC()
      44                 :            : {
      45                 :          0 :     mbImpl->release_interface( mWriteIface );
      46 [ #  # ][ #  # ]:          0 :     if( myHelper != NULL ) delete myHelper;
      47         [ #  # ]:          0 : }
      48                 :            : 
      49                 :            : //! Writes out a file
      50                 :          0 : ErrorCode WriteNC::write_file( const char* file_name, const bool overwrite, const FileOptions& options,
      51                 :            :                                const EntityHandle* file_set, const int num_set, const std::vector< std::string >&,
      52                 :            :                                const Tag*, int, int )
      53                 :            : {
      54                 :            :     ErrorCode rval;
      55                 :            :     // See if opts has variable(s) specified
      56         [ #  # ]:          0 :     std::vector< std::string > var_names;
      57         [ #  # ]:          0 :     std::vector< std::string > desired_names;
      58         [ #  # ]:          0 :     std::vector< int > tstep_nums;
      59         [ #  # ]:          0 :     std::vector< double > tstep_vals;
      60                 :            : 
      61                 :            :     // Get and cache predefined tag handles
      62         [ #  # ]:          0 :     mGlobalIdTag = mbImpl->globalId_tag();
      63                 :            : 
      64                 :            :     // num set has to be 1, we will write only one set, the original file set used to load
      65 [ #  # ][ #  # ]:          0 :     if( num_set != 1 ) MB_SET_ERR( MB_FAILURE, "We should write only one set (the file set used to read data into)" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      66                 :            : 
      67 [ #  # ][ #  # ]:          0 :     rval = parse_options( options, var_names, desired_names, tstep_nums, tstep_vals );MB_CHK_SET_ERR( rval, "Trouble parsing option string" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
      68                 :            : 
      69                 :            :     // Important to create some data that will be used to write the file; dimensions, variables, etc
      70                 :            :     // new variables still need to have some way of defining their dimensions
      71                 :            :     // maybe it will be passed as write options
      72 [ #  # ][ #  # ]:          0 :     rval = process_conventional_tags( *file_set );MB_CHK_SET_ERR( rval, "Trouble processing conventional tags" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
      73                 :            : 
      74                 :            :     // Create or append the file
      75         [ #  # ]:          0 :     if( append )
      76         [ #  # ]:          0 :         dbgOut.tprintf( 1, "opening file %s for appending \n", file_name );
      77                 :            :     else
      78         [ #  # ]:          0 :         dbgOut.tprintf( 1, "creating file %s\n", file_name );
      79                 :          0 :     fileName = file_name;
      80                 :            :     int success;
      81                 :            : 
      82         [ #  # ]:          0 :     if( append )
      83                 :            :     {
      84                 :          0 :         int omode = NC_WRITE;
      85                 :            : #ifdef MOAB_HAVE_PNETCDF
      86                 :            :         if( isParallel )
      87                 :            :             success = NCFUNC( open )( myPcomm->proc_config().proc_comm(), file_name, omode, MPI_INFO_NULL, &fileId );
      88                 :            :         else
      89                 :            :             success = NCFUNC( open )( MPI_COMM_SELF, file_name, omode, MPI_INFO_NULL, &fileId );
      90                 :            : #else
      91                 :            :         // This is a regular netcdf file, open in write mode
      92         [ #  # ]:          0 :         success = NCFUNC( open )( file_name, omode, &fileId );
      93                 :            : #endif
      94 [ #  # ][ #  # ]:          0 :         if( success ) MB_SET_ERR( MB_FAILURE, "Trouble opening file " << file_name << " for appending" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      95                 :            :     }
      96                 :            :     else
      97                 :            :     {  // Case when the file is new, will be overwritten, most likely
      98         [ #  # ]:          0 :         int cmode = overwrite ? NC_CLOBBER : NC_NOCLOBBER;
      99                 :            : #ifdef MOAB_HAVE_PNETCDF
     100                 :            :         if( isParallel )
     101                 :            :             success = NCFUNC( create )( myPcomm->proc_config().proc_comm(), file_name, cmode, MPI_INFO_NULL, &fileId );
     102                 :            :         else
     103                 :            :             success = NCFUNC( create )( MPI_COMM_SELF, file_name, cmode, MPI_INFO_NULL, &fileId );
     104                 :            : #else
     105                 :            :         // This is a regular netcdf file
     106         [ #  # ]:          0 :         success = NCFUNC( create )( file_name, cmode, &fileId );
     107                 :            : #endif
     108 [ #  # ][ #  # ]:          0 :         if( success ) MB_SET_ERR( MB_FAILURE, "Trouble creating file " << file_name << " for writing" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     109                 :            :     }
     110                 :            : 
     111 [ #  # ][ #  # ]:          0 :     if( NULL != myHelper ) delete myHelper;
     112                 :            : 
     113                 :            :     // Get appropriate helper instance for WriteNC class based on some info in the file set
     114         [ #  # ]:          0 :     myHelper = NCWriteHelper::get_nc_helper( this, fileId, options, *file_set );
     115 [ #  # ][ #  # ]:          0 :     if( NULL == myHelper ) { MB_SET_ERR( MB_FAILURE, "Failed to get NCWriteHelper class instance" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     116                 :            : 
     117 [ #  # ][ #  # ]:          0 :     rval = myHelper->collect_mesh_info();MB_CHK_SET_ERR( rval, "Trouble collecting mesh information" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     118                 :            : 
     119 [ #  # ][ #  # ]:          0 :     rval = myHelper->collect_variable_data( var_names, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble collecting variable data" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     120                 :            : 
     121 [ #  # ][ #  # ]:          0 :     rval = myHelper->init_file( var_names, desired_names, append );MB_CHK_SET_ERR( rval, "Trouble initializing file" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     122                 :            : 
     123 [ #  # ][ #  # ]:          0 :     rval = myHelper->write_values( var_names, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble writing values to file" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     124                 :            : 
     125         [ #  # ]:          0 :     success = NCFUNC( close )( fileId );
     126 [ #  # ][ #  # ]:          0 :     if( success ) MB_SET_ERR( MB_FAILURE, "Trouble closing file" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     127                 :            : 
     128                 :          0 :     return MB_SUCCESS;
     129                 :            : }
     130                 :            : 
     131                 :          0 : ErrorCode WriteNC::parse_options( const FileOptions& opts, std::vector< std::string >& var_names,
     132                 :            :                                   std::vector< std::string >& desired_names, std::vector< int >& tstep_nums,
     133                 :            :                                   std::vector< double >& tstep_vals )
     134                 :            : {
     135                 :            :     int tmpval;
     136 [ #  # ][ #  # ]:          0 :     if( MB_SUCCESS == opts.get_int_option( "DEBUG_IO", 1, tmpval ) )
     137                 :            :     {
     138         [ #  # ]:          0 :         dbgOut.set_verbosity( tmpval );
     139 [ #  # ][ #  # ]:          0 :         dbgOut.set_prefix( "NCWrite" );
     140                 :            :     }
     141                 :            : 
     142         [ #  # ]:          0 :     ErrorCode rval = opts.get_strs_option( "VARIABLE", var_names );
     143         [ #  # ]:          0 :     if( MB_TYPE_OUT_OF_RANGE == rval )
     144                 :          0 :         noVars = true;
     145                 :            :     else
     146                 :          0 :         noVars = false;
     147                 :            : 
     148         [ #  # ]:          0 :     rval = opts.get_strs_option( "RENAME", desired_names );
     149         [ #  # ]:          0 :     if( MB_ENTITY_NOT_FOUND == rval )
     150                 :            :     {
     151         [ #  # ]:          0 :         if( !noVars )
     152                 :            :         {
     153         [ #  # ]:          0 :             desired_names.resize( var_names.size() );
     154         [ #  # ]:          0 :             std::copy( var_names.begin(), var_names.end(), desired_names.begin() );
     155                 :            :         }
     156                 :            :     }
     157                 :            :     // Either way
     158         [ #  # ]:          0 :     assert( desired_names.size() == var_names.size() );
     159                 :            : 
     160         [ #  # ]:          0 :     opts.get_ints_option( "TIMESTEP", tstep_nums );
     161         [ #  # ]:          0 :     opts.get_reals_option( "TIMEVAL", tstep_vals );
     162         [ #  # ]:          0 :     rval = opts.get_null_option( "NOMESH" );
     163         [ #  # ]:          0 :     if( MB_SUCCESS == rval ) noMesh = true;
     164                 :            : 
     165         [ #  # ]:          0 :     rval = opts.get_null_option( "APPEND" );
     166         [ #  # ]:          0 :     if( MB_SUCCESS == rval ) append = true;
     167                 :            : 
     168 [ #  # ][ #  # ]:          0 :     if( 2 <= dbgOut.get_verbosity() )
     169                 :            :     {
     170         [ #  # ]:          0 :         if( !var_names.empty() )
     171                 :            :         {
     172         [ #  # ]:          0 :             std::cerr << "Variables requested: ";
     173         [ #  # ]:          0 :             for( unsigned int i = 0; i < var_names.size(); i++ )
     174 [ #  # ][ #  # ]:          0 :                 std::cerr << var_names[i];
     175         [ #  # ]:          0 :             std::cerr << std::endl;
     176                 :            :         }
     177         [ #  # ]:          0 :         if( !tstep_nums.empty() )
     178                 :            :         {
     179         [ #  # ]:          0 :             std::cerr << "Timesteps requested: ";
     180         [ #  # ]:          0 :             for( unsigned int i = 0; i < tstep_nums.size(); i++ )
     181 [ #  # ][ #  # ]:          0 :                 std::cerr << tstep_nums[i];
     182         [ #  # ]:          0 :             std::cerr << std::endl;
     183                 :            :         }
     184         [ #  # ]:          0 :         if( !tstep_vals.empty() )
     185                 :            :         {
     186         [ #  # ]:          0 :             std::cerr << "Time vals requested: ";
     187         [ #  # ]:          0 :             for( unsigned int i = 0; i < tstep_vals.size(); i++ )
     188 [ #  # ][ #  # ]:          0 :                 std::cerr << tstep_vals[i];
     189         [ #  # ]:          0 :             std::cerr << std::endl;
     190                 :            :         }
     191                 :            :     }
     192                 :            : 
     193                 :            : // FIXME: copied from ReadNC, may need revise
     194                 :            : #ifdef MOAB_HAVE_MPI
     195         [ #  # ]:          0 :     isParallel = ( opts.match_option( "PARALLEL", "WRITE_PART" ) != MB_ENTITY_NOT_FOUND );
     196                 :            : 
     197         [ #  # ]:          0 :     if( !isParallel )
     198                 :            :         // Return success here, since rval still has _NOT_FOUND from not finding option
     199                 :            :         // in this case, myPcomm will be NULL, so it can never be used; always check for isParallel
     200                 :            :         // before any use for myPcomm
     201                 :          0 :         return MB_SUCCESS;
     202                 :            : 
     203                 :          0 :     int pcomm_no = 0;
     204         [ #  # ]:          0 :     rval         = opts.get_int_option( "PARALLEL_COMM", pcomm_no );
     205 [ #  # ][ #  # ]:          0 :     if( MB_TYPE_OUT_OF_RANGE == rval ) { MB_SET_ERR( rval, "Invalid value for PARALLEL_COMM option" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     206                 :            : 
     207         [ #  # ]:          0 :     myPcomm = ParallelComm::get_pcomm( mbImpl, pcomm_no );
     208 [ #  # ][ #  # ]:          0 :     if( 0 == myPcomm ) { myPcomm = new ParallelComm( mbImpl, MPI_COMM_WORLD ); }
                 [ #  # ]
     209                 :            : 
     210                 :            : #ifndef MOAB_HAVE_PNETCDF
     211 [ #  # ][ #  # ]:          0 :     const int procs = myPcomm->proc_config().proc_size();
     212         [ #  # ]:          0 :     if( procs > 1 )
     213 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Attempt to launch NC writer in parallel without pnetcdf support" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     214                 :            : #endif
     215                 :            : 
     216 [ #  # ][ #  # ]:          0 :     const int rank = myPcomm->proc_config().proc_rank();
     217         [ #  # ]:          0 :     dbgOut.set_rank( rank );
     218                 :            : #endif
     219                 :            : 
     220                 :          0 :     return MB_SUCCESS;
     221                 :            : }
     222                 :            : 
     223                 :            : // This is the inverse process to create conventional tags
     224                 :            : // Will look at <pargal_source>/src/core/fileinfo.cpp, init dim, vars, atts
     225                 :          0 : ErrorCode WriteNC::process_conventional_tags( EntityHandle fileSet )
     226                 :            : {
     227                 :            :     ErrorCode rval;
     228                 :            : 
     229                 :            :     // Start copy
     230                 :          0 :     Tag dimNamesTag      = 0;
     231         [ #  # ]:          0 :     std::string tag_name = "__DIM_NAMES";
     232                 :          0 :     const void* data     = NULL;
     233                 :          0 :     int dimNamesSz       = 0;
     234 [ #  # ][ #  # ]:          0 :     rval                 = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, dimNamesTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     235 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_by_ptr( dimNamesTag, &fileSet, 1, &data, &dimNamesSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     236                 :          0 :     const char* p = static_cast< const char* >( data );
     237         [ #  # ]:          0 :     dbgOut.tprintf( 1, "__DIM_NAMES tag has string length %d\n", dimNamesSz );
     238                 :            : 
     239                 :          0 :     std::size_t start = 0;
     240                 :            : 
     241                 :          0 :     Tag dimLensTag = 0;
     242         [ #  # ]:          0 :     tag_name       = "__DIM_LENS";
     243                 :          0 :     data           = NULL;
     244                 :          0 :     int dimLensSz  = 0;
     245 [ #  # ][ #  # ]:          0 :     rval           = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, dimLensTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     246 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_by_ptr( dimLensTag, &fileSet, 1, &data, &dimLensSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     247                 :          0 :     const int* int_p = static_cast< const int* >( data );
     248         [ #  # ]:          0 :     dbgOut.tprintf( 1, "__DIM_LENS tag has %d values\n", dimLensSz );
     249                 :            : 
     250                 :          0 :     int idxDim = 0;
     251                 :            :     // Dim names are separated by '\0' in the string of __DIM_NAMES tag
     252         [ #  # ]:          0 :     for( std::size_t i = 0; i != static_cast< std::size_t >( dimNamesSz ); i++ )
     253                 :            :     {
     254         [ #  # ]:          0 :         if( p[i] == '\0' )
     255                 :            :         {
     256         [ #  # ]:          0 :             std::string dim_name( &p[start], i - start );
     257                 :          0 :             int len = int_p[idxDim];
     258         [ #  # ]:          0 :             dimNames.push_back( dim_name );
     259         [ #  # ]:          0 :             dimLens.push_back( len );
     260         [ #  # ]:          0 :             dbgOut.tprintf( 2, "Dimension %s has length %d\n", dim_name.c_str(), len );
     261                 :            :             // FIXME: Need info from moab to set unlimited dimension
     262                 :            :             // Currently assume each file has the same number of time dimensions
     263                 :            :             /*if ((dim_name == "time") || (dim_name == "Time"))
     264                 :            :               insert(dim_name, *(new pcdim(dim_name, len * m_file_names.size(), true)));
     265                 :            :             else
     266                 :            :               insert(dim_name, *(new pcdim(dim_name, len)));*/
     267                 :          0 :             start = i + 1;
     268                 :          0 :             idxDim++;
     269                 :            :         }
     270                 :            :     }
     271                 :            : 
     272                 :          0 :     Tag meshTypeTag = 0;
     273         [ #  # ]:          0 :     tag_name        = "__MESH_TYPE";
     274                 :          0 :     data            = NULL;
     275                 :          0 :     int meshTypeSz  = 0;
     276 [ #  # ][ #  # ]:          0 :     rval            = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, meshTypeTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     277 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_by_ptr( meshTypeTag, &fileSet, 1, &data, &meshTypeSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     278                 :          0 :     p         = static_cast< const char* >( data );
     279 [ #  # ][ #  # ]:          0 :     grid_type = std::string( &p[0], meshTypeSz );
     280         [ #  # ]:          0 :     dbgOut.tprintf( 2, "Mesh type: %s\n", grid_type.c_str() );
     281                 :            : 
     282                 :            :     // Read <__VAR_NAMES_LOCATIONS> tag
     283                 :          0 :     Tag varNamesLocsTag = 0;
     284         [ #  # ]:          0 :     tag_name            = "__VAR_NAMES_LOCATIONS";
     285                 :          0 :     data                = NULL;
     286                 :          0 :     int varNamesLocsSz  = 0;
     287 [ #  # ][ #  # ]:          0 :     rval                = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, varNamesLocsTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     288 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_by_ptr( varNamesLocsTag, &fileSet, 1, &data, &varNamesLocsSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     289                 :          0 :     int_p = static_cast< const int* >( data );
     290         [ #  # ]:          0 :     std::vector< int > varNamesLocs( varNamesLocsSz );
     291         [ #  # ]:          0 :     std::copy( int_p, int_p + varNamesLocsSz, varNamesLocs.begin() );
     292                 :            : 
     293                 :          0 :     Tag varNamesTag = 0;
     294         [ #  # ]:          0 :     tag_name        = "__VAR_NAMES";
     295 [ #  # ][ #  # ]:          0 :     rval            = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     296                 :          0 :     data           = NULL;
     297                 :          0 :     int varNamesSz = 0;
     298 [ #  # ][ #  # ]:          0 :     rval           = mbImpl->tag_get_by_ptr( varNamesTag, &fileSet, 1, &data, &varNamesSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     299         [ #  # ]:          0 :     dbgOut.tprintf( 2, "__VAR_NAMES tag has string length %d\n", varNamesSz );
     300                 :          0 :     p = static_cast< const char* >( data );
     301                 :            : 
     302                 :          0 :     start      = 0;
     303                 :          0 :     int idxVar = 0;
     304                 :            :     int sz;
     305                 :            :     // Var names are separated by '\0' in the string of __VAR_NAMES tag
     306         [ #  # ]:          0 :     for( std::size_t i = 0; i != static_cast< std::size_t >( varNamesSz ); i++ )
     307                 :            :     {
     308         [ #  # ]:          0 :         if( p[i] == '\0' )
     309                 :            :         {
     310         [ #  # ]:          0 :             std::string var_name( &p[start], i - start );
     311                 :            : 
     312         [ #  # ]:          0 :             dbgOut.tprintf( 2, "var name: %s index %d \n", var_name.c_str(), idxVar );
     313                 :            :             // Process var name:
     314                 :            :             // This will create/initiate map; we will populate variableDataStruct with info about
     315                 :            :             // dims, tags, etc reference & is important; otherwise variableDataStruct will go out of
     316                 :            :             // scope, and deleted :(
     317         [ #  # ]:          0 :             VarData& variableDataStruct = varInfo[var_name];
     318         [ #  # ]:          0 :             variableDataStruct.varName  = var_name;
     319         [ #  # ]:          0 :             variableDataStruct.entLoc   = varNamesLocs[idxVar];
     320                 :            : 
     321         [ #  # ]:          0 :             dbgOut.tprintf( 2, "at var name %s varInfo size %d \n", var_name.c_str(), (int)varInfo.size() );
     322                 :            : 
     323                 :          0 :             sz                    = 0;
     324                 :          0 :             Tag dims_tag          = 0;
     325 [ #  # ][ #  # ]:          0 :             std::string dim_names = "__" + var_name + "_DIMS";
              [ #  #  # ]
     326         [ #  # ]:          0 :             rval = mbImpl->tag_get_handle( dim_names.c_str(), 0, MB_TYPE_OPAQUE, dims_tag, MB_TAG_ANY );
     327         [ #  # ]:          0 :             if( MB_SUCCESS != rval )
     328                 :            :             {
     329         [ #  # ]:          0 :                 if( MB_TAG_NOT_FOUND == rval )
     330                 :            :                 {
     331         [ #  # ]:          0 :                     dbgOut.tprintf( 2, "tag : %s not found, continue \n", dim_names.c_str() );
     332                 :          0 :                     start = i + 1;
     333                 :          0 :                     idxVar++;
     334                 :          0 :                     continue;
     335                 :            :                 }
     336 [ #  # ][ #  # ]:          0 :                 MB_SET_ERR( rval, "Trouble getting conventional tag " << dim_names );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     337                 :            :             }
     338 [ #  # ][ #  # ]:          0 :             rval = mbImpl->tag_get_length( dims_tag, sz );MB_CHK_SET_ERR( rval, "Trouble getting size of dimensions for variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     339                 :          0 :             sz /= sizeof( Tag );  // The type is MB_TYPE_OPAQUE, but it is a list of tags, so we
     340                 :            :                                   // need to divide by the size of Tag
     341                 :            :             // sz is used for number of dimension tags in this list
     342         [ #  # ]:          0 :             dbgOut.tprintf( 2, "var name: %s has %d dimensions \n", var_name.c_str(), sz );
     343                 :            : 
     344         [ #  # ]:          0 :             variableDataStruct.varDims.resize( sz );
     345                 :          0 :             const void* ptr = NULL;
     346         [ #  # ]:          0 :             rval            = mbImpl->tag_get_by_ptr( dims_tag, &fileSet, 1, &ptr );
     347                 :            : 
     348                 :          0 :             const Tag* ptags = static_cast< const moab::Tag* >( ptr );
     349         [ #  # ]:          0 :             for( std::size_t j = 0; j != static_cast< std::size_t >( sz ); j++ )
     350                 :            :             {
     351         [ #  # ]:          0 :                 std::string dim_name;
     352 [ #  # ][ #  # ]:          0 :                 rval = mbImpl->tag_get_name( ptags[j], dim_name );MB_CHK_SET_ERR( rval, "Trouble getting dimension of variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     353         [ #  # ]:          0 :                 dbgOut.tprintf( 2, "var name: %s has %s as dimension \n", var_name.c_str(), dim_name.c_str() );
     354         [ #  # ]:          0 :                 std::vector< std::string >::iterator vit = std::find( dimNames.begin(), dimNames.end(), dim_name );
     355 [ #  # ][ #  # ]:          0 :                 if( vit == dimNames.end() )
     356 [ #  # ][ #  # ]:          0 :                     MB_SET_ERR( MB_FAILURE, "Dimension " << dim_name << " not found for variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     357 [ #  # ][ #  # ]:          0 :                 variableDataStruct.varDims[j] = (int)( vit - dimNames.begin() );  // Will be used for writing
                 [ #  # ]
     358                 :            :                 // This will have to change to actual file dimension, for writing
     359                 :          0 :             }
     360                 :            : 
     361                 :            :             // Attributes for this variable
     362 [ #  # ][ #  # ]:          0 :             std::stringstream ssTagName;
              [ #  #  # ]
     363 [ #  # ][ #  # ]:          0 :             ssTagName << "__" << var_name << "_ATTRIBS";
                 [ #  # ]
     364 [ #  # ][ #  # ]:          0 :             tag_name      = ssTagName.str();
     365                 :          0 :             Tag varAttTag = 0;
     366                 :            :             rval =
     367 [ #  # ][ #  # ]:          0 :                 mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, varAttTag, MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     368                 :          0 :             const void* varAttPtr = NULL;
     369                 :          0 :             int varAttSz          = 0;
     370 [ #  # ][ #  # ]:          0 :             rval                  = mbImpl->tag_get_by_ptr( varAttTag, &fileSet, 1, &varAttPtr, &varAttSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     371 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag retrieved for variable %s\n", tag_name.c_str() );
     372                 :            : 
     373 [ #  # ][ #  # ]:          0 :             std::string attribString( (char*)varAttPtr, (char*)varAttPtr + varAttSz );
     374 [ #  # ][ #  # ]:          0 :             if( attribString == "NO_ATTRIBS" )
     375                 :            :             {
     376                 :            :                 // This variable has no attributes
     377                 :          0 :                 variableDataStruct.numAtts = 0;
     378                 :            :             }
     379 [ #  # ][ #  # ]:          0 :             else if( attribString == "DUMMY_VAR" )
     380                 :            :             {
     381                 :            :                 // This variable is a dummy coordinate variable
     382                 :          0 :                 variableDataStruct.numAtts = 0;
     383         [ #  # ]:          0 :                 dummyVarNames.insert( variableDataStruct.varName );
     384                 :            :             }
     385                 :            :             else
     386                 :            :             {
     387         [ #  # ]:          0 :                 ssTagName << "_LEN";
     388 [ #  # ][ #  # ]:          0 :                 tag_name         = ssTagName.str();
     389                 :          0 :                 Tag varAttLenTag = 0;
     390 [ #  # ][ #  # ]:          0 :                 rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, varAttLenTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     391                 :          0 :                 int varAttLenSz = 0;
     392 [ #  # ][ #  # ]:          0 :                 rval            = mbImpl->tag_get_length( varAttLenTag, varAttLenSz );MB_CHK_SET_ERR( rval, "Trouble getting length of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     393         [ #  # ]:          0 :                 std::vector< int > varAttLen( varAttLenSz );
     394 [ #  # ][ #  # ]:          0 :                 rval = mbImpl->tag_get_data( varAttLenTag, &fileSet, 1, &varAttLen[0] );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     395                 :            : 
     396 [ #  # ][ #  # ]:          0 :                 rval = process_concatenated_attribute( varAttPtr, varAttSz, varAttLen, variableDataStruct.varAtts );MB_CHK_SET_ERR( rval, "Trouble processing attributes of variable " << var_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     397                 :            : 
     398 [ #  # ][ #  # ]:          0 :                 if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag metadata for variable %s\n", tag_name.c_str() );
                 [ #  # ]
     399                 :            :             }
     400                 :            :             // End attribute
     401                 :            : 
     402                 :          0 :             start = i + 1;
     403         [ #  # ]:          0 :             idxVar++;
     404                 :            :         }  // if (p[i] == '\0')
     405                 :            :     }
     406                 :            : 
     407                 :            :     // Global attributes
     408         [ #  # ]:          0 :     tag_name         = "__GLOBAL_ATTRIBS";
     409                 :          0 :     Tag globalAttTag = 0;
     410 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_OPAQUE, globalAttTag, MB_TAG_SPARSE | MB_TAG_VARLEN );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     411         [ #  # ]:          0 :     std::vector< int > gattLen;
     412                 :            : 
     413                 :          0 :     const void* gattptr = NULL;
     414                 :          0 :     int globalAttSz     = 0;
     415 [ #  # ][ #  # ]:          0 :     rval                = mbImpl->tag_get_by_ptr( globalAttTag, &fileSet, 1, &gattptr, &globalAttSz );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     416                 :            : 
     417 [ #  # ][ #  # ]:          0 :     if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag value retrieved for %s size %d\n", tag_name.c_str(), globalAttSz );
     418                 :            : 
     419                 :            :     // <__GLOBAL_ATTRIBS_LEN>
     420         [ #  # ]:          0 :     tag_name            = "__GLOBAL_ATTRIBS_LEN";
     421                 :          0 :     Tag globalAttLenTag = 0;
     422                 :            : 
     423 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_handle( tag_name.c_str(), 0, MB_TYPE_INTEGER, globalAttLenTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     424                 :          0 :     int sizeGAtt = 0;
     425 [ #  # ][ #  # ]:          0 :     rval         = mbImpl->tag_get_length( globalAttLenTag, sizeGAtt );MB_CHK_SET_ERR( rval, "Trouble getting length of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     426         [ #  # ]:          0 :     gattLen.resize( sizeGAtt );
     427 [ #  # ][ #  # ]:          0 :     rval = mbImpl->tag_get_data( globalAttLenTag, &fileSet, 1, &gattLen[0] );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag " << tag_name );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     428 [ #  # ][ #  # ]:          0 :     if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Tag retrieved for variable %s\n", tag_name.c_str() );
     429                 :            : 
     430 [ #  # ][ #  # ]:          0 :     rval = process_concatenated_attribute( gattptr, globalAttSz, gattLen, globalAtts );MB_CHK_SET_ERR( rval, "Trouble processing global attributes" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     431                 :            : 
     432                 :          0 :     return MB_SUCCESS;
     433                 :            : }
     434                 :            : 
     435                 :            : // Reverse process from create_attrib_string
     436                 :          0 : ErrorCode WriteNC::process_concatenated_attribute( const void* attPtr, int attSz, std::vector< int >& attLen,
     437                 :            :                                                    std::map< std::string, AttData >& attributes )
     438                 :            : {
     439                 :          0 :     std::size_t start       = 0;
     440                 :          0 :     std::size_t att_counter = 0;
     441         [ #  # ]:          0 :     std::string concatString( (char*)attPtr, (char*)attPtr + attSz );
     442                 :            : 
     443         [ #  # ]:          0 :     for( std::size_t i = 0; i != (size_t)attSz; i++ )
     444                 :            :     {
     445 [ #  # ][ #  # ]:          0 :         if( concatString[i] == '\0' )
     446                 :            :         {
     447 [ #  # ][ #  # ]:          0 :             std::string att_name( &concatString[start], i - start );
     448                 :          0 :             start = i + 1;
     449 [ #  # ][ #  # ]:          0 :             while( concatString[i] != ';' )
     450                 :          0 :                 ++i;
     451 [ #  # ][ #  # ]:          0 :             std::string data_type( &concatString[start], i - start );
                 [ #  # ]
     452                 :          0 :             ++i;
     453                 :          0 :             start = i;
     454         [ #  # ]:          0 :             i     = attLen[att_counter];
     455 [ #  # ][ #  # ]:          0 :             if( concatString[i] != ';' ) MB_SET_ERR( MB_FAILURE, "Error parsing attributes" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     456                 :            : 
     457 [ #  # ][ #  # ]:          0 :             std::string data_val( &concatString[start], i - start );
                 [ #  # ]
     458                 :          0 :             start = i + 1;
     459                 :            : 
     460         [ #  # ]:          0 :             AttData& attrib = attributes[att_name];
     461         [ #  # ]:          0 :             attrib.attValue = data_val;
     462                 :          0 :             attrib.attLen   = data_val.size();
     463                 :            : 
     464 [ #  # ][ #  # ]:          0 :             if( data_type == "char" )
     465                 :          0 :                 attrib.attDataType = NC_CHAR;
     466 [ #  # ][ #  # ]:          0 :             else if( data_type == "double" )
     467                 :          0 :                 attrib.attDataType = NC_DOUBLE;
     468 [ #  # ][ #  # ]:          0 :             else if( data_type == "float" )
     469                 :          0 :                 attrib.attDataType = NC_FLOAT;
     470 [ #  # ][ #  # ]:          0 :             else if( data_type == "int" )
     471                 :          0 :                 attrib.attDataType = NC_INT;
     472 [ #  # ][ #  # ]:          0 :             else if( data_type == "short" )
     473                 :          0 :                 attrib.attDataType = NC_SHORT;
     474                 :            : 
     475                 :          0 :             ++att_counter;
     476         [ #  # ]:          0 :             dbgOut.tprintf( 2, "       Process attribute %s with value %s \n", att_name.c_str(), data_val.c_str() );
     477                 :            :         }
     478                 :            :     }
     479                 :            : 
     480                 :          0 :     return MB_SUCCESS;
     481                 :            : }
     482                 :            : 
     483 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11