source: XIOS/dev/branch_yushan_merged/src/io/onetcdf4.cpp @ 1134

Last change on this file since 1134 was 1134, checked in by yushan, 7 years ago

branch merged with trunk r1130

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 21.6 KB
RevLine 
[528]1#include <fstream>
2
[219]3#include "onetcdf4.hpp"
[352]4#include "group_template.hpp"
[379]5#include "netcdf.hpp"
[498]6#include "netCdfInterface.hpp"
7#include "netCdfException.hpp"
[219]8
[335]9namespace xios
[219]10{
11      /// ////////////////////// Définitions ////////////////////// ///
12
[1134]13      CONetCDF4::CONetCDF4(const StdString& filename, bool append, bool useClassicFormat, bool useCFConvention, 
14                           const ep_lib::MPI_Comm* comm, bool multifile, const StdString& timeCounterName)
[686]15        : path()
16        , wmpi(false)
17        , useClassicFormat(useClassicFormat)
[878]18        , useCFConvention(useCFConvention)
[219]19      {
[878]20         this->initialize(filename, append, useClassicFormat, useCFConvention, comm, multifile, timeCounterName);
[219]21      }
[498]22
[219]23      //---------------------------------------------------------------
[286]24
[219]25      CONetCDF4::~CONetCDF4(void)
26      {
27      }
28
29      ///--------------------------------------------------------------
30
[878]31      void CONetCDF4::initialize(const StdString& filename, bool append, bool useClassicFormat, bool useCFConvention, 
[1134]32                                 const ep_lib::MPI_Comm* comm, bool multifile, const StdString& timeCounterName)
[219]33      {
[517]34         this->useClassicFormat = useClassicFormat;
[878]35         this->useCFConvention = useCFConvention;
[517]36
37         int mode = useClassicFormat ? 0 : NC_NETCDF4;
[605]38
39         // Don't use parallel mode if there is only one process
40         if (comm)
41         {
42            int commSize = 0;
43            MPI_Comm_size(*comm, &commSize);
44            if (commSize <= 1)
45               comm = NULL;
46         }
47         wmpi = comm && !multifile;
48
49         if (wmpi)
[517]50            mode |= useClassicFormat ? NC_PNETCDF : NC_MPIIO;
51
[528]52         // If the file does not exist, we always create it
53         if (!append || !std::ifstream(filename.c_str()))
[219]54         {
[605]55            if (wmpi)
[1134]56               CNetCdfInterface::createPar(filename, mode, static_cast<MPI_Comm>(comm->mpi_comm), MPI_INFO_NULL_STD, this->ncidp);           
[605]57            else
58               CNetCdfInterface::create(filename, mode, this->ncidp);
[528]59
60            this->appendMode = false;
[219]61         }
62         else
63         {
[528]64            mode |= NC_WRITE;
[605]65            if (wmpi)
[1134]66               CNetCdfInterface::openPar(filename, mode, static_cast<MPI_Comm>(comm->mpi_comm), MPI_INFO_NULL_STD, this->ncidp);
[605]67            else
68               CNetCdfInterface::open(filename, mode, this->ncidp);
[528]69
70            this->appendMode = true;
[219]71         }
[517]72
73         // If the classic NetCDF format is used, we enable the "no-fill mode" globally.
74         // This is done per variable for the NetCDF4 format.
75         if (useClassicFormat)
[606]76            CNetCdfInterface::setFill(this->ncidp, false);
[802]77
78         this->timeCounterName = timeCounterName;
[219]79      }
[498]80
[286]81      void CONetCDF4::close()
82      {
[686]83        CNetCdfInterface::close(this->ncidp);
[286]84      }
[498]85
[219]86      //---------------------------------------------------------------
[498]87
[219]88      void CONetCDF4::definition_start(void)
[498]89      {
[686]90         CNetCdfInterface::reDef(this->ncidp);
[219]91      }
[498]92
[219]93      //---------------------------------------------------------------
[498]94
[219]95      void CONetCDF4::definition_end(void)
96      {
[686]97         CNetCdfInterface::endDef(this->ncidp);
[219]98      }
99
100      //---------------------------------------------------------------
[498]101
[219]102      int CONetCDF4::getCurrentGroup(void)
103      {
[686]104         return this->getGroup(this->getCurrentPath());
[219]105      }
[498]106
[219]107      //---------------------------------------------------------------
[498]108
[686]109      int CONetCDF4::getGroup(const CONetCDF4Path& path)
[219]110      {
111         int retvalue = this->ncidp;
[498]112
[686]113         CONetCDF4Path::const_iterator it = path.begin(), end = path.end();
[219]114
[686]115         for (; it != end; it++)
[219]116         {
[686]117            const StdString& groupid = *it;
118            CNetCdfInterface::inqNcId(retvalue, groupid, retvalue);
[219]119         }
[686]120         return retvalue;
[219]121      }
[498]122
[219]123      //---------------------------------------------------------------
[498]124
[686]125      int CONetCDF4::getVariable(const StdString& varname)
[219]126      {
127         int varid = 0;
128         int grpid = this->getCurrentGroup();
[686]129         CNetCdfInterface::inqVarId(grpid, varname, varid);
130         return varid;
[219]131      }
[498]132
[219]133      //---------------------------------------------------------------
[498]134
[686]135      int CONetCDF4::getDimension(const StdString& dimname)
[219]136      {
137         int dimid = 0;
138         int grpid = this->getCurrentGroup();
[686]139         CNetCdfInterface::inqDimId(grpid, dimname, dimid);
140         return dimid;
[219]141      }
[498]142
[219]143      //---------------------------------------------------------------
[498]144
[219]145      int CONetCDF4::getUnlimitedDimension(void)
146      {
147         int dimid = 0;
148         int grpid = this->getCurrentGroup();
[686]149         CNetCdfInterface::inqUnLimDim(grpid, dimid);
150         return dimid;
[219]151      }
[498]152
[266]153      StdString CONetCDF4::getUnlimitedDimensionName(void)
154      {
155         int grpid = this->getGroup(path);
156         int dimid = this->getUnlimitedDimension();
[498]157
158         StdString dimname;
[686]159         if (dimid != -1)
160           CNetCdfInterface::inqDimName(grpid, dimid, dimname);
161         return dimname;
[266]162      }
[498]163
[219]164      //---------------------------------------------------------------
[498]165
[686]166      std::vector<StdSize> CONetCDF4::getDimensions(const StdString& varname)
[219]167      {
168         StdSize size = 0;
169         std::vector<StdSize> retvalue;
170         int grpid = this->getCurrentGroup();
171         int varid = this->getVariable(varname);
172         int nbdim = 0, *dimid = NULL;
173
[686]174         CNetCdfInterface::inqVarNDims(grpid, varid, nbdim);
[219]175         dimid = new int[nbdim]();
[686]176         CNetCdfInterface::inqVarDimId(grpid, varid, dimid);
[219]177
178         for (int i = 0; i < nbdim; i++)
179         {
[686]180            CNetCdfInterface::inqDimLen(grpid, dimid[i], size);
[219]181            if (size == NC_UNLIMITED)
182                size = UNLIMITED_DIM;
183            retvalue.push_back(size);
184         }
[401]185         delete [] dimid;
[686]186         return retvalue;
[219]187      }
188
[686]189      std::vector<std::string> CONetCDF4::getDimensionsIdList(const std::string* _varname)
[266]190      {
[498]191         int nDimNull = 0;
[266]192         int nbdim = 0, *dimid = NULL;
193         int grpid = this->getCurrentGroup();
194         int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
195         std::vector<std::string> retvalue;
[498]196
[266]197         if (_varname != NULL)
198         {
[686]199            CNetCdfInterface::inqVarNDims(grpid, varid, nbdim);
[266]200            dimid = new int[nbdim]();
[686]201            CNetCdfInterface::inqVarDimId(grpid, varid, dimid);
[266]202         }
203         else
204         {
[686]205            CNetCdfInterface::inqDimIds(grpid, nbdim, NULL, 1);
[266]206            dimid = new int[nbdim]();
[686]207            CNetCdfInterface::inqDimIds(grpid, nDimNull, dimid, 1);
[266]208         }
[498]209
[266]210         for (int i = 0; i < nbdim; i++)
211         {
[498]212            std::string dimname;
[686]213            CNetCdfInterface::inqDimName(grpid, dimid[i], dimname);
[266]214            retvalue.push_back(dimname);
215         }
216         delete [] dimid;
[498]217
[686]218         return retvalue;
[266]219      }
220
[219]221      //---------------------------------------------------------------
222
[707]223      void CONetCDF4::getTimeAxisBounds(CArray<double,2>& timeAxisBounds, const StdString& name, bool collective)
224      {
225        int grpid = this->getCurrentGroup();
226        int varid = this->getVariable(name);
227
228        std::vector<StdSize> start(2), count(2);
229        start[0] = 0;
230        // Find out how many temporal records have been written already to the file we are opening
231        int ncUnlimitedDimId;
232        CNetCdfInterface::inqUnLimDim(this->ncidp, ncUnlimitedDimId);
233        CNetCdfInterface::inqDimLen(this->ncidp, ncUnlimitedDimId, count[0]);
234        start[1] = 0;
235        count[1] = 2;
236
237        timeAxisBounds.resize(count[1], count[0]);
238
239        if (this->wmpi && collective)
240          CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE);
241        if (this->wmpi && !collective)
242          CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT);
243
244        CNetCdfInterface::getVaraType(grpid, varid, &start[0], &count[0], timeAxisBounds.dataFirst());
245      }
246
[1097]247      void CONetCDF4::getTimeAxisBounds(CArray<double,2>& timeAxisBounds, const StdString& name, bool collective, size_t record)
248      {
249        int grpid = this->getCurrentGroup();
250        int varid = this->getVariable(name);
[707]251
[1097]252        std::vector<StdSize> start(2), count(2);
253        start[0] = record;
254        count[0] = 1 ;
255        start[1] = 0;
256        count[1] = 2;
257
258        timeAxisBounds.resize(2, 1);
259
260        if (this->wmpi && collective)
261          CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE);
262        if (this->wmpi && !collective)
263          CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT);
264
265        CNetCdfInterface::getVaraType(grpid, varid, &start[0], &count[0], timeAxisBounds.dataFirst());
266      }
267
268
269
[686]270      const CONetCDF4::CONetCDF4Path& CONetCDF4::getCurrentPath(void) const
271      { return this->path; }
[219]272
[686]273      void CONetCDF4::setCurrentPath(const CONetCDF4Path& path)
[219]274      { this->path = path; }
275
276      //---------------------------------------------------------------
277
[686]278      int CONetCDF4::addGroup(const StdString& name)
[219]279      {
280         int retvalue = 0;
281         int grpid = this->getCurrentGroup();
[686]282         CNetCdfInterface::defGrp(grpid, name, retvalue);
283         return retvalue;
[219]284      }
[498]285
[219]286      //---------------------------------------------------------------
[498]287
[219]288      int CONetCDF4::addDimension(const StdString& name, const StdSize size)
289      {
290         int retvalue = 0;
291         int grpid = this->getCurrentGroup();
292         if (size != UNLIMITED_DIM)
[686]293            CNetCdfInterface::defDim(grpid, name, size, retvalue);
[219]294         else
[686]295            CNetCdfInterface::defDim(grpid, name, NC_UNLIMITED, retvalue);
296         return retvalue;
[219]297      }
[498]298
[219]299      //---------------------------------------------------------------
[498]300
[686]301      int CONetCDF4::addVariable(const StdString& name, nc_type type,
302                                 const std::vector<StdString>& dim)
[219]303      {
[350]304         int varid = 0;
[219]305         std::vector<int> dimids;
[606]306         std::vector<StdSize> dimsizes;
[857]307         int dimSize = dim.size();
[878]308         
[606]309         StdSize size;
310         StdSize totalSize;
311         StdSize maxSize = 1024 * 1024 * 256; // == 2GB/8 if output double
[498]312
[219]313         int grpid = this->getCurrentGroup();
[498]314
[606]315         std::vector<StdString>::const_iterator it = dim.begin(), end = dim.end();
[219]316
[878]317         for (int idx = 0; it != end; it++, ++idx)
[219]318         {
[686]319            const StdString& dimid = *it;
[219]320            dimids.push_back(this->getDimension(dimid));
[606]321            CNetCdfInterface::inqDimLen(grpid, this->getDimension(dimid), size);
322            if (size == NC_UNLIMITED) size = 1;
323            dimsizes.push_back(size);
[219]324         }
[453]325
[606]326         CNetCdfInterface::defVar(grpid, name, type, dimids.size(), &dimids[0], varid);
[498]327
[517]328         // The classic NetCDF format does not support chunking nor fill parameters
329         if (!useClassicFormat)
[453]330         {
[517]331            // set chunksize : size of one record
332            // but must not be > 2GB (netcdf or HDF5 problem)
333            totalSize = 1;
334            for (vector<StdSize>::reverse_iterator it = dimsizes.rbegin(); it != dimsizes.rend(); ++it)
335            {
336              totalSize *= *it;
337              if (totalSize >= maxSize) *it = 1;
338            }
[857]339            int storageType = (0 == dimSize) ? NC_CONTIGUOUS : NC_CHUNKED;
340            CNetCdfInterface::defVarChunking(grpid, varid, storageType, &dimsizes[0]);
[517]341            CNetCdfInterface::defVarFill(grpid, varid, true, NULL);
[453]342         }
343
[606]344         return varid;
[219]345      }
346
347      //---------------------------------------------------------------
348
[606]349      void CONetCDF4::setCompressionLevel(const StdString& varname, int compressionLevel)
350      {
[607]351         if (compressionLevel < 0 || compressionLevel > 9)
352           ERROR("void CONetCDF4::setCompressionLevel(const StdString& varname, int compressionLevel)",
353                 "Invalid compression level for variable \"" << varname << "\", the value should range between 0 and 9.");
354         if (compressionLevel && wmpi)
355           ERROR("void CONetCDF4::setCompressionLevel(const StdString& varname, int compressionLevel)",
356                 "Impossible to use compression for variable \"" << varname << "\" when using parallel mode.");
357
[606]358         int grpid = this->getCurrentGroup();
359         int varid = this->getVariable(varname);
360         CNetCdfInterface::defVarDeflate(grpid, varid, compressionLevel);
361      }
362
363      //---------------------------------------------------------------
364
[219]365      template <>
[686]366      void CONetCDF4::addAttribute(const StdString& name, const StdString& value, const StdString* varname)
[219]367      {
368         int grpid = this->getCurrentGroup();
369         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]370         CNetCdfInterface::putAttType(grpid, varid, name, value.size(), value.c_str());
[219]371      }
[498]372
[219]373      //---------------------------------------------------------------
[498]374
[219]375      template <>
[686]376      void CONetCDF4::addAttribute(const StdString& name, const double& value, const StdString* varname)
[219]377      {
378         int grpid = this->getCurrentGroup();
379         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]380         CNetCdfInterface::putAttType(grpid, varid, name, 1, &value);
[219]381      }
[391]382
[686]383      template <>
384      void CONetCDF4::addAttribute(const StdString& name, const CArray<double,1>& value, const StdString* varname)
[391]385      {
386         int grpid = this->getCurrentGroup();
387         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]388         CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst());
[498]389      }
[219]390      //---------------------------------------------------------------
[498]391
[219]392      template <>
[686]393      void CONetCDF4::addAttribute(const StdString& name, const float& value, const StdString* varname)
[219]394      {
395         int grpid = this->getCurrentGroup();
396         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]397         CNetCdfInterface::putAttType(grpid, varid, name, 1, &value);
[219]398      }
[391]399
[686]400      template <>
401      void CONetCDF4::addAttribute(const StdString& name, const CArray<float,1>& value, const StdString* varname)
[391]402      {
403         int grpid = this->getCurrentGroup();
404         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]405         CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst());
[498]406      }
407
[219]408      //---------------------------------------------------------------
[498]409
[219]410      template <>
[686]411      void CONetCDF4::addAttribute(const StdString& name, const int& value, const StdString* varname)
[219]412      {
413         int grpid = this->getCurrentGroup();
414         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]415         CNetCdfInterface::putAttType(grpid, varid, name, 1, &value);
[219]416      }
417
[686]418      template <>
419      void CONetCDF4::addAttribute(const StdString& name, const CArray<int,1>& value, const StdString* varname)
[391]420      {
421         int grpid = this->getCurrentGroup();
422         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]423         CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst());
[498]424      }
425
[472]426      template <>
[686]427      void CONetCDF4::addAttribute(const StdString& name, const short int& value, const StdString* varname)
[472]428      {
429         int grpid = this->getCurrentGroup();
430         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]431         CNetCdfInterface::putAttType(grpid, varid, name, 1, &value);
[472]432      }
[219]433
[686]434      template <>
435      void CONetCDF4::addAttribute(const StdString& name, const CArray<short int,1>& value, const StdString* varname)
[472]436      {
437         int grpid = this->getCurrentGroup();
438         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]439         CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst());
[498]440      }
441
[472]442      template <>
[686]443      void CONetCDF4::addAttribute(const StdString& name, const long int& value, const StdString* varname)
[472]444      {
445         int grpid = this->getCurrentGroup();
446         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]447         CNetCdfInterface::putAttType(grpid, varid, name, 1, &value);
[472]448      }
449
[686]450      template <>
451      void CONetCDF4::addAttribute(const StdString& name, const CArray<long int,1>& value, const StdString* varname)
[472]452      {
453         int grpid = this->getCurrentGroup();
454         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[686]455         CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst());
[498]456      }
457
[686]458      //---------------------------------------------------------------
[498]459
[686]460      void CONetCDF4::getWriteDataInfos(const StdString& name, StdSize record, StdSize& array_size,
461                                        std::vector<StdSize>& sstart,
462                                        std::vector<StdSize>& scount,
463                                        const std::vector<StdSize>* start,
464                                        const std::vector<StdSize>* count)
[498]465      {
[266]466         std::vector<std::size_t> sizes  = this->getDimensions(name);
[857]467         if (sizes.size()==0) 
[266]468         {
[857]469            array_size=1 ;
470            sstart.push_back(0);
[606]471            scount.push_back(1);
[266]472         }
[857]473         else
474         {
475           std::vector<std::string> iddims = this->getDimensionsIdList (&name);
476           std::vector<std::size_t>::const_iterator
477           it  = sizes.begin(), end = sizes.end();
478           int i = 0;
[219]479
[857]480           if (iddims.begin()->compare(timeCounterName) == 0)
481           {
482             sstart.push_back(record);
483             scount.push_back(1);
484              if ((start == NULL) &&
485                  (count == NULL)) i++;
486              it++;
487           }
488
489           for (;it != end; it++)
490           {
491              if ((start != NULL) && (count != NULL))
492              {
493                 sstart.push_back((*start)[i]);
494                 scount.push_back((*count)[i]);
495                 array_size *= (*count)[i];
496                 i++;
497              }
498              else
499              {
500                 sstart.push_back(0);
501                 scount.push_back(sizes[i]);
502                 array_size *= sizes[i];
503                 i++;
504              }
505           }
506
[219]507         }
508      }
[498]509
[857]510
[219]511      template <>
[686]512      void CONetCDF4::writeData_(int grpid, int varid,
513                                 const std::vector<StdSize>& sstart,
514                                 const std::vector<StdSize>& scount, const double* data)
[219]515      {
[686]516         CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data);
[219]517      }
[498]518
[219]519      //---------------------------------------------------------------
[498]520
[219]521      template <>
[686]522      void CONetCDF4::writeData_(int grpid, int varid,
523                                 const std::vector<StdSize>& sstart,
[1050]524                                 const std::vector<StdSize>& scount, char* data)
525      {
526          CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data);
527      }
528     
529      template <>
530
531      void CONetCDF4::writeData_(int grpid, int varid,
532                                 const std::vector<StdSize>& sstart,
[686]533                                 const std::vector<StdSize>& scount, const int* data)
[219]534      {
[1134]535         CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data);
[219]536      }
[1134]537
[219]538      //---------------------------------------------------------------
[498]539
[219]540      template <>
[686]541      void CONetCDF4::writeData_(int grpid, int varid,
542                                 const std::vector<StdSize>& sstart,
543                                 const std::vector<StdSize>& scount, const float* data)
[219]544      {
[1134]545         CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data);
[219]546      }
547
548      //---------------------------------------------------------------
549
[686]550      void CONetCDF4::writeData(const CArray<int, 2>& data, const StdString& name)
[219]551      {
552         int grpid = this->getCurrentGroup();
553         int varid = this->getVariable(name);
554         StdSize array_size = 1;
555         std::vector<StdSize> sstart, scount;
556
557         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
[369]558         this->writeData_(grpid, varid, sstart, scount, data.dataFirst());
[219]559      }
560
[686]561      void CONetCDF4::writeTimeAxisData(const CArray<double, 1>& data, const StdString& name,
[413]562                                        bool collective, StdSize record, bool isRoot)
563      {
564         int grpid = this->getCurrentGroup();
565         int varid = this->getVariable(name);
[498]566
[686]567         map<int,size_t>::iterator it=timeAxis.find(varid);
568         if (it == timeAxis.end()) timeAxis[varid] = record;
[498]569         else
[413]570         {
[686]571           if (it->second >= record) return;
572           else it->second =record;
[413]573         }
[498]574
[413]575         StdSize array_size = 1;
576         std::vector<StdSize> sstart, scount;
[498]577
[413]578         if (this->wmpi && collective)
[686]579            CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE);
[413]580         if (this->wmpi && !collective)
[686]581            CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT);
[498]582
[413]583         this->getWriteDataInfos(name, record, array_size,  sstart, scount, NULL, NULL);
[686]584         if (using_netcdf_internal)
585         {
586           if (!isRoot)
587           {
588             sstart[0] = sstart[0] + 1;
589             scount[0] = 0;
590           }
591         }
[413]592         this->writeData_(grpid, varid, sstart, scount, data.dataFirst());
593       }
594
[219]595      //---------------------------------------------------------------
[498]596
[686]597      bool CONetCDF4::varExist(const StdString& varname)
[219]598      {
599         int grpid = this->getCurrentGroup();
[686]600         return CNetCdfInterface::isVarExisted(grpid, varname);
[219]601      }
602
[878]603      bool CONetCDF4::dimExist(const StdString& dimname)
604      {
605         int grpid = this->getCurrentGroup();
606         return CNetCdfInterface::isDimExisted(grpid, dimname);
607      }
608
[286]609      void CONetCDF4::sync(void)
610      {
[686]611         CNetCdfInterface::sync(this->ncidp);
[498]612      }
[219]613      ///--------------------------------------------------------------
[337]614 } // namespace xios
Note: See TracBrowser for help on using the repository browser.