source: XIOS/trunk/src/output/onetcdf4.cpp @ 501

Last change on this file since 501 was 501, checked in by ymipsl, 10 years ago

Add licence copyright to all file ond directory src using the command :
svn propset -R copyright -F header_licence src

XIOS is now officialy under CeCILL licence

YM

  • 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: 17.8 KB
RevLine 
[219]1#include "onetcdf4.hpp"
[352]2#include "group_template.hpp"
[382]3#include "mpi.hpp"
[379]4#include "netcdf.hpp"
[498]5#include "netCdfInterface.hpp"
6#include "netCdfException.hpp"
[219]7
[335]8namespace xios
[219]9{
10      /// ////////////////////// Définitions ////////////////////// ///
11
12      CONetCDF4::CONetCDF4
[286]13         (const StdString & filename, bool exist, const MPI_Comm * comm, bool multifile)
[219]14            : path()
15      {
[286]16         this->wmpi = (comm != NULL) && !multifile;
17         this->initialize(filename, exist, comm,multifile);
[219]18      }
[498]19
[219]20      //---------------------------------------------------------------
[286]21
[498]22
[219]23      CONetCDF4::~CONetCDF4(void)
24      {
[286]25//         CheckError(nc_close(this->ncidp));
[219]26      }
27
28      ///--------------------------------------------------------------
29
30      void CONetCDF4::initialize
[286]31         (const StdString & filename, bool exist, const MPI_Comm * comm, bool multifile)
[219]32      {
33         if (!exist)
34         {
35            if (comm != NULL)
36            {
[498]37               if (!multifile) (CNetCdfInterface::createPar(filename, NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, (this->ncidp)));
38               else (CNetCdfInterface::create(filename, NC_NETCDF4, this->ncidp));
[219]39            }
[498]40            else (CNetCdfInterface::create(filename, NC_NETCDF4, this->ncidp));
[219]41         }
42         else
43         {
44            if (comm != NULL)
[286]45            {
[498]46               if (!multifile) (CNetCdfInterface::openPar(filename, NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, this->ncidp));
47               else (CNetCdfInterface::open(filename, NC_NETCDF4, this->ncidp));
[286]48            }
[498]49            else  (CNetCdfInterface::open(filename, NC_NETCDF4, this->ncidp));
[219]50         }
51      }
[498]52
[286]53      void CONetCDF4::close()
54      {
[498]55        (CNetCdfInterface::close(this->ncidp));
[286]56      }
[498]57
[219]58      //---------------------------------------------------------------
[498]59
[219]60      void CONetCDF4::definition_start(void)
[498]61      {
62         (CNetCdfInterface::reDef(this->ncidp));
[219]63      }
[498]64
[219]65      //---------------------------------------------------------------
[498]66
[219]67      void CONetCDF4::definition_end(void)
68      {
[498]69         (CNetCdfInterface::endDef(this->ncidp));
[219]70      }
71
72      //---------------------------------------------------------------
[498]73
74// Don't need it anymore?
75//      void CONetCDF4::CheckError(int status)
76//      {
77//         if (status != NC_NOERR)
78//         {
79//            StdString errormsg (nc_strerror(status)); // fuite mémoire ici ?
80//            ERROR("CONetCDF4::CheckError(int status)",
81//                  << "[ status = " << status << " ] " << errormsg);
82//         }
83//      }
84
85      //---------------------------------------------------------------
86
[219]87      int CONetCDF4::getCurrentGroup(void)
88      {
89         return (this->getGroup(this->getCurrentPath()));
90      }
[498]91
[219]92      //---------------------------------------------------------------
[498]93
[219]94      int CONetCDF4::getGroup(const CONetCDF4Path & path)
95      {
96         int retvalue = this->ncidp;
[498]97
[219]98         CONetCDF4Path::const_iterator
99            it  = path.begin(), end = path.end();
100
101         for (;it != end; it++)
102         {
103            const StdString & groupid = *it;
[498]104            (CNetCdfInterface::inqNcId(retvalue, groupid, retvalue));
[219]105         }
106         return (retvalue);
107      }
[498]108
[219]109      //---------------------------------------------------------------
[498]110
[219]111      int CONetCDF4::getVariable(const StdString & varname)
112      {
113         int varid = 0;
114         int grpid = this->getCurrentGroup();
[498]115         (CNetCdfInterface::inqVarId(grpid, varname, varid));
[219]116         return (varid);
117      }
[498]118
[219]119      //---------------------------------------------------------------
[498]120
[219]121      int CONetCDF4::getDimension(const StdString & dimname)
122      {
123         int dimid = 0;
124         int grpid = this->getCurrentGroup();
[498]125         (CNetCdfInterface::inqDimId(grpid, dimname, dimid));
[219]126         return (dimid);
127      }
[498]128
[219]129      //---------------------------------------------------------------
[498]130
[219]131      int CONetCDF4::getUnlimitedDimension(void)
132      {
133         int dimid = 0;
134         int grpid = this->getCurrentGroup();
[498]135         (CNetCdfInterface::inqUnLimDim(grpid, dimid));
[219]136         return (dimid);
137      }
[498]138
[266]139      StdString CONetCDF4::getUnlimitedDimensionName(void)
140      {
141         int grpid = this->getGroup(path);
142         int dimid = this->getUnlimitedDimension();
[498]143
[266]144         if (dimid == -1) return (std::string());
[498]145         StdString dimname;
146         (CNetCdfInterface::inqDimName(grpid, dimid, dimname));
147
[266]148         return (dimname);
149      }
[498]150
[219]151      //---------------------------------------------------------------
[498]152
[219]153      std::vector<StdSize> CONetCDF4::getDimensions(const StdString & varname)
154      {
155         StdSize size = 0;
156         std::vector<StdSize> retvalue;
157         int grpid = this->getCurrentGroup();
158         int varid = this->getVariable(varname);
159         int nbdim = 0, *dimid = NULL;
160
[498]161         (CNetCdfInterface::inqVarNDims(grpid, varid, nbdim));
[219]162         dimid = new int[nbdim]();
[498]163         (CNetCdfInterface::inqVarDimId(grpid, varid, dimid));
[219]164
165         for (int i = 0; i < nbdim; i++)
166         {
[498]167            (CNetCdfInterface::inqDimLen(grpid, dimid[i], size));
[219]168            if (size == NC_UNLIMITED)
169                size = UNLIMITED_DIM;
170            retvalue.push_back(size);
171         }
[401]172         delete [] dimid;
[219]173         return (retvalue);
174      }
175
[266]176      std::vector<std::string> CONetCDF4::getDimensionsIdList (const std::string * _varname)
177      {
[498]178         int nDimNull = 0;
[266]179         int nbdim = 0, *dimid = NULL;
180         int grpid = this->getCurrentGroup();
181         int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
182         std::vector<std::string> retvalue;
[498]183
[266]184         if (_varname != NULL)
185         {
[498]186            (CNetCdfInterface::inqVarNDims(grpid, varid, nbdim));
[266]187            dimid = new int[nbdim]();
[498]188            (CNetCdfInterface::inqVarDimId(grpid, varid, dimid));
[266]189         }
190         else
191         {
[498]192            (CNetCdfInterface::inqDimIds(grpid, nbdim, NULL, 1));
[266]193            dimid = new int[nbdim]();
[498]194            (CNetCdfInterface::inqDimIds(grpid, nDimNull, dimid, 1));
[266]195         }
[498]196
[266]197         for (int i = 0; i < nbdim; i++)
198         {
[498]199            std::string dimname;
200            (CNetCdfInterface::inqDimName(grpid, dimid[i], dimname));
[266]201            retvalue.push_back(dimname);
202         }
203         delete [] dimid;
[498]204
[266]205         return (retvalue);
206      }
207
208
[219]209      //---------------------------------------------------------------
210
211      const CONetCDF4::CONetCDF4Path & CONetCDF4::getCurrentPath(void) const
212      { return (this->path); }
213
214      void CONetCDF4::setCurrentPath(const CONetCDF4Path & path)
215      { this->path = path; }
216
217      //---------------------------------------------------------------
218
219      int CONetCDF4::addGroup(const StdString & name)
220      {
221         int retvalue = 0;
222         int grpid = this->getCurrentGroup();
[498]223         (CNetCdfInterface::defGrp(grpid, name, retvalue));
[219]224         return (retvalue);
225      }
[498]226
[219]227      //---------------------------------------------------------------
[498]228
[219]229      int CONetCDF4::addDimension(const StdString& name, const StdSize size)
230      {
231         int retvalue = 0;
232         int grpid = this->getCurrentGroup();
233         if (size != UNLIMITED_DIM)
[498]234            (CNetCdfInterface::defDim(grpid, name, size, retvalue));
[219]235         else
[498]236            (CNetCdfInterface::defDim(grpid, name, NC_UNLIMITED, retvalue));
[219]237         return (retvalue);
238      }
[498]239
[219]240      //---------------------------------------------------------------
[498]241
[219]242      int CONetCDF4::addVariable(const StdString & name, nc_type type,
243                                  const std::vector<StdString> & dim)
244      {
[350]245         int varid = 0;
[219]246         std::vector<int> dimids;
[350]247         std::vector<StdSize> dimsizes ;
248         StdSize size ;
[453]249         StdSize totalSize ;
250         StdSize maxSize=1024*1024*256 ; // == 2GB/8 if output double
[498]251
[219]252         int grpid = this->getCurrentGroup();
[498]253
[219]254         std::vector<StdString>::const_iterator
255            it  = dim.begin(), end = dim.end();
256
257         for (;it != end; it++)
258         {
259            const StdString & dimid = *it;
260            dimids.push_back(this->getDimension(dimid));
[498]261            (CNetCdfInterface::inqDimLen(grpid, this->getDimension(dimid), size));
[350]262            if (size==NC_UNLIMITED) size=1 ;
263            dimsizes.push_back(size) ;
[219]264         }
[453]265
[498]266         (CNetCdfInterface::defVar(grpid, name, type, dimids.size(), &(dimids[0]), varid));
267
[453]268// set chunksize : size of one record
269// but must not be > 2GB (netcdf or HDF5 problem)
270         totalSize=1 ;
271         for(vector<StdSize>::reverse_iterator it=dimsizes.rbegin(); it!=dimsizes.rend();++it)
272         {
273           totalSize*= *it ;
274           if (totalSize>=maxSize) *it=1 ;
275         }
276
[498]277         (CNetCdfInterface::defVarChunking(grpid, varid, NC_CHUNKED, &(dimsizes[0])));
278         (CNetCdfInterface::defVarFill(grpid, varid, true, NULL));
[350]279         return (varid);
[219]280      }
281
282      //---------------------------------------------------------------
283
284      template <>
285         void CONetCDF4::addAttribute
286            (const StdString & name, const StdString & value, const StdString * varname )
287      {
288         int grpid = this->getCurrentGroup();
289         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]290         (CNetCdfInterface::putAtt(grpid, varid, name, NC_CHAR, value.size(), value.c_str()));
[219]291         //CheckError(nc_put_att_string(grpid, varid, name.c_str(), 1, &str));
292      }
[498]293
[219]294      //---------------------------------------------------------------
[498]295
[219]296      template <>
297         void CONetCDF4::addAttribute
298            (const StdString & name, const double & value, const StdString * varname )
299      {
300         int grpid = this->getCurrentGroup();
301         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]302         (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value));
[219]303      }
[391]304
305       template <>
306         void CONetCDF4::addAttribute
307            (const StdString & name, const CArray<double,1>& value, const StdString * varname )
308      {
309         int grpid = this->getCurrentGroup();
310         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]311         (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst()));
312      }
[219]313      //---------------------------------------------------------------
[498]314
[219]315      template <>
316         void CONetCDF4::addAttribute
317            (const StdString & name, const float & value, const StdString * varname )
318      {
319         int grpid = this->getCurrentGroup();
320         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]321         (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value));
[219]322      }
[391]323
324       template <>
325         void CONetCDF4::addAttribute
326            (const StdString & name, const CArray<float,1>& value, const StdString * varname )
327      {
328         int grpid = this->getCurrentGroup();
329         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]330         (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst()));
331      }
332
[219]333      //---------------------------------------------------------------
[498]334
[219]335      template <>
336         void CONetCDF4::addAttribute
337            (const StdString & name, const int & value, const StdString * varname )
338      {
339         int grpid = this->getCurrentGroup();
340         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]341         (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value));
[219]342      }
343
[391]344       template <>
345         void CONetCDF4::addAttribute
346            (const StdString & name, const CArray<int,1>& value, const StdString * varname )
347      {
348         int grpid = this->getCurrentGroup();
349         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]350         (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst()));
351      }
352
[472]353      template <>
354         void CONetCDF4::addAttribute
355            (const StdString & name, const short int & value, const StdString * varname )
356      {
357         int grpid = this->getCurrentGroup();
358         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]359         (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value));
[472]360      }
[219]361
[472]362       template <>
363         void CONetCDF4::addAttribute
364            (const StdString & name, const CArray<short int,1>& value, const StdString * varname )
365      {
366         int grpid = this->getCurrentGroup();
367         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]368         (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst()));
369      }
370
371
372
[472]373      template <>
374         void CONetCDF4::addAttribute
375            (const StdString & name, const long int & value, const StdString * varname )
376      {
377         int grpid = this->getCurrentGroup();
378         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]379         (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value));
[472]380      }
381
382       template <>
383         void CONetCDF4::addAttribute
384            (const StdString & name, const CArray<long int,1>& value, const StdString * varname )
385      {
386         int grpid = this->getCurrentGroup();
387         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
[498]388         (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst()));
389      }
390
391
392
[472]393                //---------------------------------------------------------------
394
[219]395      void CONetCDF4::getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size,
396                                        std::vector<StdSize> & sstart,
397                                        std::vector<StdSize> & scount,
398                                        const std::vector<StdSize> * start,
399                                        const std::vector<StdSize> * count)
[498]400      {
[266]401         std::vector<std::size_t> sizes  = this->getDimensions(name);
[498]402         std::vector<std::string> iddims = this->getDimensionsIdList (&name);
[266]403         std::vector<std::size_t>::const_iterator
[219]404            it  = sizes.begin(), end = sizes.end();
405         int i = 0;
[438]406
[266]407         if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0)
408         {
409            sstart.push_back(record);
410            scount.push_back(1); 
411            if ((start == NULL) &&
412                (count == NULL)) i++;
413            it++;
414         }
[219]415
416         for (;it != end; it++)
[498]417         { 
[219]418            if ((start != NULL) && (count != NULL))
419            {
[266]420               sstart.push_back((*start)[i]);
421               scount.push_back((*count)[i]);
422               array_size *= (*count)[i];
423               i++;
[219]424            }
425            else
426            {
[266]427               sstart.push_back(0);
428               scount.push_back(sizes[i]);
429               array_size *= sizes[i];
[219]430               i++;
431            }
432         }
[498]433
[219]434      }
[498]435
436
437
[219]438      template <>
439         void CONetCDF4::writeData_(int grpid, int varid,
440                                    const std::vector<StdSize> & sstart,
[369]441                                    const std::vector<StdSize> & scount, const double * data)
[219]442      {
[498]443         (CNetCdfInterface::putVaraType(grpid, varid, &(sstart[0]), &(scount[0]), data));
[286]444//         sync() ;
[219]445      }
[498]446
[219]447      //---------------------------------------------------------------
[498]448
[219]449      template <>
450         void CONetCDF4::writeData_(int grpid, int varid,
451                                    const std::vector<StdSize> & sstart,
[369]452                                    const std::vector<StdSize> & scount, const int * data)
[219]453      {
[498]454          (CNetCdfInterface::putVaraType(grpid, varid, &(sstart[0]), &(scount[0]), data));
[286]455//          sync() ;
[219]456      }
[498]457
[219]458      //---------------------------------------------------------------
[498]459
[219]460      template <>
461         void CONetCDF4::writeData_(int grpid, int varid,
462                                    const std::vector<StdSize> & sstart,
[369]463                                    const std::vector<StdSize> & scount, const float * data)
[219]464      {
[498]465          (CNetCdfInterface::putVaraType(grpid, varid, &(sstart[0]), &(scount[0]), data));
[286]466//          sync() ;
[219]467      }
468
469      //---------------------------------------------------------------
470
[369]471      void CONetCDF4::writeData(const CArray<int, 2>& data, const StdString & name)
[219]472      {
473         int grpid = this->getCurrentGroup();
474         int varid = this->getVariable(name);
475         StdSize array_size = 1;
476         std::vector<StdSize> sstart, scount;
477
478         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
[369]479         this->writeData_(grpid, varid, sstart, scount, data.dataFirst());
[219]480      }
481
[413]482      void CONetCDF4::writeTimeAxisData(const CArray<double, 1>& data, const StdString & name,
483                                        bool collective, StdSize record, bool isRoot)
484      {
485         int grpid = this->getCurrentGroup();
486         int varid = this->getVariable(name);
[498]487
[413]488         map<int,size_t>::iterator it=timeAxis.find(varid) ;
489         if (it==timeAxis.end()) timeAxis[varid]=record ;
[498]490         else
[413]491         {
492           if (it->second >= record) return ;
493           else it->second =record ;
494         }
[498]495
[413]496         StdSize array_size = 1;
497         std::vector<StdSize> sstart, scount;
[498]498
[413]499         if (this->wmpi && collective)
[498]500         (CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE));
[413]501         if (this->wmpi && !collective)
[498]502         (CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT));
503
[413]504         this->getWriteDataInfos(name, record, array_size,  sstart, scount, NULL, NULL);
505         if (using_netcdf_internal)  if (!isRoot) { sstart[0]=sstart[0]+1 ; scount[0]=0 ;}
506         this->writeData_(grpid, varid, sstart, scount, data.dataFirst());
507       }
508
[219]509      //---------------------------------------------------------------
[498]510
[219]511      bool CONetCDF4::varExist(const StdString & varname)
512      {
513         int grpid = this->getCurrentGroup();
[498]514         return (CNetCdfInterface::isVarExisted(grpid, varname));
[219]515      }
516
[286]517      void CONetCDF4::sync(void)
518      {
[498]519         (CNetCdfInterface::sync(this->ncidp)) ;
520      }
[219]521      ///--------------------------------------------------------------
[337]522 } // namespace xios
Note: See TracBrowser for help on using the repository browser.