source: XIOS/trunk/src/io/inetcdf4.cpp @ 811

Last change on this file since 811 was 811, checked in by ymipsl, 8 years ago

Bug fix when time dimension is not the unlimited dimension

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: 25.5 KB
RevLine 
[219]1#include "inetcdf4.hpp"
[599]2#include "netCdfInterface.hpp"
[782]3#include "netCdf_cf_constant.hpp"
[219]4
5#include <boost/algorithm/string.hpp>
6
[335]7namespace xios
[219]8{
[802]9  CINetCDF4::CINetCDF4(const StdString& filename, const MPI_Comm* comm /*= NULL*/, bool multifile /*= true*/, const StdString& timeCounterName /*= "time_counter"*/)
[599]10  {
[736]11    // Don't use parallel mode if there is only one process
12    if (comm)
[599]13    {
[736]14      int commSize = 0;
15      MPI_Comm_size(*comm, &commSize);
16      if (commSize <= 1)
17        comm = NULL;
[599]18    }
[736]19    mpi = comm && !multifile;
20
21    // The file format will be detected automatically by NetCDF, it is safe to always set NC_MPIIO
22    // even if Parallel NetCDF ends up being used.
23    if (mpi)
24      CNetCdfInterface::openPar(filename, NC_NOWRITE | NC_MPIIO, *comm, MPI_INFO_NULL, this->ncidp);
25    else
26      CNetCdfInterface::open(filename, NC_NOWRITE, this->ncidp);
[802]27
28    this->timeCounterName = timeCounterName;
[811]29    if (!CNetCdfInterface::isDimExisted(this->ncidp, this->timeCounterName)) this->timeCounterName=this->getUnlimitedDimensionName() ;
30   
[599]31  }
[219]32
[599]33  CINetCDF4::~CINetCDF4(void)
34  { /* Nothing to do */ }
[219]35
[599]36  //---------------------------------------------------------------
[219]37
[599]38  void CINetCDF4::close(void)
39  {
[686]40    CNetCdfInterface::close(this->ncidp);
[599]41  }
[219]42
[599]43  //---------------------------------------------------------------
[219]44
[599]45  int CINetCDF4::getGroup(const CVarPath* const path)
46  {
47    int retvalue = this->ncidp;
48    if (path == NULL) return retvalue;
49    CVarPath::const_iterator it = path->begin(), end = path->end();
[219]50
[599]51    for (; it != end; it++)
52    {
53      const StdString& groupid = *it;
[686]54      CNetCdfInterface::inqNcId(retvalue, groupid, retvalue);
[599]55    }
[219]56
[599]57    return retvalue;
58  }
[219]59
[599]60  int CINetCDF4::getVariable(const StdString& varname,
61                             const CVarPath* const path)
62  {
63    int varid = 0;
64    int grpid = this->getGroup(path);
[686]65    CNetCdfInterface::inqVarId(grpid, varname, varid);
[599]66    return varid;
67  }
[219]68
[599]69  int CINetCDF4::getDimension(const StdString& dimname,
70                              const CVarPath* const path)
71  {
72    int dimid = 0;
73    int grpid = this->getGroup(path);
[686]74    CNetCdfInterface::inqDimId(grpid, dimname, dimid);
[599]75    return dimid;
76  }
[219]77
[599]78  std::pair<nc_type, StdSize> CINetCDF4::getAttribute(const StdString& attname,
79                                                      const StdString* const var,
80                                                      const CVarPath* const path)
81  {
82    std::pair<nc_type, StdSize> retvalue;
83    int grpid = this->getGroup(path);
84    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
[686]85    CNetCdfInterface::inqAtt(grpid, varid, attname, retvalue.first, retvalue.second);
[599]86    return retvalue;
87  }
[219]88
[599]89  int CINetCDF4::getUnlimitedDimension(const CVarPath* const path)
90  {
91    int dimid = 0;
92    int grpid = this->getGroup(path);
[686]93    CNetCdfInterface::inqUnLimDim(grpid, dimid);
[599]94    return dimid;
95  }
[219]96
[599]97  StdString CINetCDF4::getUnlimitedDimensionName(const CVarPath* const path)
98  {
99    int grpid = this->getGroup(path);
100    int dimid = this->getUnlimitedDimension(path);
[219]101
[686]102    StdString dimname;
103    if (dimid != -1)
104      CNetCdfInterface::inqDimName(grpid, dimid, dimname);
[599]105    return dimname;
106  }
[219]107
[599]108  //---------------------------------------------------------------
[686]109
[599]110  StdSize CINetCDF4::getNbVertex(const StdString& name,
111                                 const CVarPath* const path)
112  {
[219]113
[599]114    if (this->isRectilinear(name, path) ||
115       this->isCurvilinear(name, path))
116    {
117      if (this->is3Dim(name, path)) return 8;
118      else return 4;
119    }
120    if (this->isUnstructured(name, path))
121    {
122      StdString bound = this->getBoundsId
123            (this->getCoordinatesIdList(name, path).back(), path);
124      StdString dim = this->getDimensionsList(&bound, path).back();
[686]125      return this->getDimensions(&bound, path)[dim];
[599]126    }
127    return size_t(-1);
128  }
[219]129
[599]130  //---------------------------------------------------------------
[219]131
[599]132  std::list<StdString> CINetCDF4::getGroups(const CVarPath* const path)
133  {
134    int nbgroup = 0, *groupid = NULL;
135    int grpid = this->getGroup(path);
136    std::list<StdString> retvalue;
[219]137
[686]138    CNetCdfInterface::inqGrpIds(grpid, nbgroup, NULL);
[599]139    groupid = new int[nbgroup]();
[686]140    CNetCdfInterface::inqGrpIds(grpid, nbgroup, groupid);
[219]141
[599]142    for (int i = 0; i < nbgroup; i++)
143    {
[686]144      StdString fullGrpName;
145      CNetCdfInterface::inqGrpFullName(groupid[i], fullGrpName);
146      retvalue.push_back(fullGrpName);
[599]147    }
[219]148
[599]149    delete [] groupid;
150    return retvalue;
151  }
[219]152
[599]153  std::list<StdString> CINetCDF4::getVariables(const CVarPath* const path)
154  {
155    int nbvar = 0, *varid = NULL;
156    int grpid = this->getGroup(path);
157    std::list<StdString> retvalue;
[219]158
[686]159    CNetCdfInterface::inqVarIds(grpid, nbvar, NULL);
[599]160    varid = new int[nbvar]();
[686]161    CNetCdfInterface::inqVarIds(grpid, nbvar, varid);
[219]162
[599]163    for (int i = 0; i < nbvar; i++)
164    {
[686]165      StdString varName;
166      CNetCdfInterface::inqVarName(grpid, varid[i], varName);
167      retvalue.push_back(varName);
[599]168    }
169
170    delete [] varid;
171    return retvalue;
172  }
173
174  StdSize CINetCDF4::getNbOfTimestep(const CVarPath* const path)
175  {
[686]176    return this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)];
[599]177  }
178
179  std::set<StdString> CINetCDF4::getBoundVariables(const CVarPath* const path)
180  {
181    std::set<StdString> retvalue;
182    std::list<StdString> variables = this->getVariables(path);
183    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
184    for (; it != end; it++)
185    {
186      const StdString& var = *it;
187      if (this->hasBounds(var, path))
188        retvalue.insert(retvalue.end(), this->getBoundsId(var, path));
189    }
190    return retvalue;
191  }
192
193  std::set<StdString> CINetCDF4::getCoordVariables(const CVarPath* const path)
194  {
195    std::set<StdString> retvalue;
196    std::list<StdString> variables = this->getVariables(path);
197    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
198    for (; it != end; it++)
199    {
200      const StdString& var = *it;
201      std::list<StdString> coords = this->getCoordinatesIdList(var, path);
202      std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
203      for (; it != end; it++)
[219]204      {
[599]205        const StdString& coord = *it;
206        if (this->hasVariable(coord, path))
207          retvalue.insert(retvalue.end(), coord);
[219]208      }
[599]209    }
210    return retvalue;
211  }
[219]212
[599]213  std::list<StdString> CINetCDF4::getDimensionsList(const StdString* const var, const CVarPath* const path)
214  {
215    int nbdim = 0, *dimid = NULL;
216    int grpid = this->getGroup(path);
217    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
218    std::list<StdString> retvalue;
[219]219
[599]220    if (var != NULL)
221    {
[686]222      CNetCdfInterface::inqVarNDims(grpid, varid, nbdim);
[599]223      dimid = new int[nbdim]();
[686]224      CNetCdfInterface::inqVarDimId(grpid, varid, dimid);
[599]225    }
226    else
227    {
[686]228      CNetCdfInterface::inqDimIds(grpid, nbdim, NULL, 1);
[599]229      dimid = new int[nbdim]();
[686]230      CNetCdfInterface::inqDimIds(grpid, nbdim, dimid, 1);
[599]231    }
[219]232
[599]233    for (int i = 0; i < nbdim; i++)
234    {
[686]235      std::string dimname;
236      CNetCdfInterface::inqDimName(grpid, dimid[i], dimname);
[599]237      retvalue.push_back(dimname);
238    }
239    delete [] dimid;
[219]240
[599]241    return retvalue;
242  }
[219]243
[599]244  std::map<StdString, StdSize> CINetCDF4::getDimensions(const StdString* const var, const CVarPath* const path)
245  {
246    int nbdim = 0, *dimid = NULL;
247    int grpid = this->getGroup(path);
248    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
249    std::map<StdString, StdSize> retvalue;
[219]250
[599]251    if (var != NULL)
252    {
[686]253      CNetCdfInterface::inqVarNDims(grpid, varid, nbdim);
[599]254      dimid = new int[nbdim]();
[686]255      CNetCdfInterface::inqVarDimId(grpid, varid, dimid);
[599]256    }
257    else
258    {
[686]259      CNetCdfInterface::inqDimIds(grpid, nbdim, NULL, 1);
[599]260      dimid = new int[nbdim]();
[686]261      CNetCdfInterface::inqDimIds(grpid, nbdim, dimid, 1);
[599]262    }
[219]263
[599]264    for (int i = 0; i < nbdim; i++)
265    {
[686]266      std::string dimname;
267      CNetCdfInterface::inqDimName(grpid, dimid[i], dimname);
268      StdSize size = 0;
269      CNetCdfInterface::inqDimLen(grpid, dimid[i], size);
[219]270
[599]271      retvalue.insert(retvalue.end(), std::make_pair(dimname, size));
272    }
273    delete [] dimid;
[219]274
[599]275    return retvalue;
276  }
[219]277
[686]278  std::list<StdString> CINetCDF4::getAttributes(const StdString* const var, const CVarPath* const path)
[599]279  {
280    int nbatt = 0;
281    std::list<StdString> retvalue;
282    int grpid = this->getGroup(path);
283    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
[219]284
[599]285    if (var != NULL)
[686]286      CNetCdfInterface::inqVarNAtts(grpid, varid, nbatt);
[599]287    else
[686]288      CNetCdfInterface::inqNAtts(grpid, nbatt);
[219]289
[599]290    for (int i = 0; i < nbatt; i++)
291    {
[686]292      StdString attname;
293      CNetCdfInterface::inqAttName(grpid, varid, i, attname);
[599]294      retvalue.push_back(attname);
295    }
296    return retvalue;
297  }
[219]298
[599]299  int CINetCDF4::getAttributeId(const StdString& name,
300                                const StdString* const var,
301                                const CVarPath* const path)
302  {
303    int retvalue = 0;
304    std::list<StdString> atts = this->getAttributes(var, path);
305    std::list<StdString>::const_iterator it = atts.begin(), end = atts.end();
306    for (; it != end; it++)
307    {
308      const StdString& attname = *it;
[782]309      if (attname.compare(0, name.size(), name) == 0)
[599]310        return retvalue;
311      retvalue++;
312    }
313    return -1;
314  }
[219]315
[599]316  //---------------------------------------------------------------
[219]317
[599]318  bool CINetCDF4::hasMissingValue(const StdString& name,
319                                  const CVarPath* const path)
320  {
[686]321    return (this->hasAttribute("missing_value", &name, path) || this->hasAttribute("_FillValue", &name, path));
[599]322  }
[219]323
[599]324  bool CINetCDF4::hasAttribute(const StdString& name,
325                               const StdString* const var ,
326                               const CVarPath* const path)
327  {
328    std::list<StdString> atts = this->getAttributes(var, path);
329    std::list<StdString>::const_iterator it = atts.begin(), end = atts.end();
330    for (; it != end; it++)
331    {
332      const StdString& attname = *it;
[782]333      if (attname.compare(0, name.size(), name) == 0) return true;
[599]334    }
335    return false;
336  }
[219]337
[599]338  bool CINetCDF4::hasVariable(const StdString& name,
339                              const CVarPath* const path)
340  {
341    std::list<StdString> variables = this->getVariables(path);
342    std::list<StdString>::const_iterator it = variables.begin(), end = variables.end();
343    for (; it != end; it++)
344    {
345      const StdString& varname = *it;
[782]346      if (varname.compare(0, name.size(), name) == 0) return true;
[599]347    }
348    return false;
349  }
[219]350
[599]351  bool CINetCDF4::hasCoordinates(const StdString& name,
352                                 const CVarPath* const path)
353  {
[782]354    return this->hasAttribute(CCFKeywords::XIOS_CF_coordinates, &name, path);
[599]355  }
[219]356
[599]357  bool CINetCDF4::hasBounds(const StdString& name,
358                            const CVarPath* const path)
359  {
[782]360    return this->hasAttribute(CCFKeywords::XIOS_CF_bounds, &name, path);
[599]361  }
[219]362
[599]363  bool CINetCDF4::hasTemporalDim(const CVarPath* const path)
364  {
[802]365    std::list<StdString> dims = this->getDimensionsList(NULL, path);
366    return (std::find(dims.begin(), dims.end(), timeCounterName) != dims.end());
[599]367  }
[219]368
[599]369  //---------------------------------------------------------------
[219]370
[686]371  template <class T>
372  std::vector<T> CINetCDF4::getAttributeValue(const StdString& name,
373                                              const StdString* const var,
374                                              const CVarPath* const path)
375  {
376    int grpid = this->getGroup(path);
377    int varid = (var != NULL) ? this->getVariable(*var, path) : NC_GLOBAL;
378    std::pair<nc_type , StdSize> attinfos = this->getAttribute(name, var, path);
379    std::vector<T> retvalue(attinfos.second);
380    nc_type type = CNetCdfInterface::getNcType<T>();
381    if (attinfos.first != type)
382      ERROR("CINetCDF4::getAttributeValue<T>(name, var, path)",
383            << "[ name : " << name
384            << ", type requested :" << attinfos.first
385            << ", type stored : " << type << "]"
386            << " Invalid type !");
387    CNetCdfInterface::getAttType(grpid, varid, name.c_str(), &retvalue[0]);
388    return retvalue;
[599]389  }
[219]390
[686]391  template std::vector<double> CINetCDF4::getAttributeValue(const StdString& name,
392                                                            const StdString* const var,
393                                                            const CVarPath* const path);
394  template std::vector<float> CINetCDF4::getAttributeValue(const StdString& name,
395                                                           const StdString* const var,
396                                                           const CVarPath* const path);
397  template std::vector<int> CINetCDF4::getAttributeValue(const StdString& name,
398                                                         const StdString* const var,
399                                                         const CVarPath* const path);
400  template std::vector<char> CINetCDF4::getAttributeValue(const StdString& name,
401                                                          const StdString* const var,
402                                                          const CVarPath* const path);
[219]403
[599]404  StdString CINetCDF4::getAttributeValue(const StdString& name,
405                                         const StdString* const var,
406                                         const CVarPath* const path)
407  {
[686]408    std::vector<char> data = this->getAttributeValue<char>(name, var, path);
[219]409
[686]410    return StdString(data.begin(), data.end());
[599]411  }
[219]412
[686]413  template <class T>
414  T CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path)
[599]415  {
416    if (this->hasAttribute("missing_value", &name, path))
[686]417      return this->getAttributeValue<T>("missing_value", &name, path)[0];
[599]418    if (this->hasAttribute("_FillValue", &name, path))
[686]419      return this->getAttributeValue<T>("_FillValue", &name, path)[0];
[599]420    return 0;
421  }
[219]422
[686]423  template double CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path);
424  template float CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path);
425  template int CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path);
426  template char CINetCDF4::getMissingValue(const StdString& name, const CVarPath* const path);
[219]427
[599]428  //---------------------------------------------------------------
[219]429
[599]430  std::list<StdString> CINetCDF4::getCoordinatesIdList(const StdString& name, const CVarPath* const path)
431  {
432    std::list<StdString> retvalue;
433    StdString value = this->getCoordinatesId(name, path);
[219]434
[599]435    boost::split(retvalue, value, boost::is_any_of(" "));
[219]436
[599]437    std::list<StdString>::iterator it = retvalue.begin(), end = retvalue.end();
438    for (; it != end; it++)
439    {
440      StdString& coord = *it;
441      coord.assign(coord.data());
442    }
443    return retvalue;
444  }
[219]445
[599]446  StdString CINetCDF4::getCoordinatesId(const StdString& name, const CVarPath* const path)
447  {
448    StdString retvalue;
[782]449    if (this->hasAttribute(CCFKeywords::XIOS_CF_coordinates, &name, path))
[599]450    {
[782]451      return this->getAttributeValue(CCFKeywords::XIOS_CF_coordinates, &name, path);
[599]452    }
453    else
454    {
455      std::list<StdString> dims = this->getDimensionsList(&name, path);
456      std::list<StdString>::const_iterator it = dims.begin(), end = dims.end();
457      for (; it != end; it++)
[219]458      {
[599]459        const StdString& value = *it;
460        retvalue.append(value).push_back(' ');
[219]461      }
[599]462      retvalue.erase(retvalue.end() - 1) ;
463    }
[219]464
[599]465    return retvalue;
466  }
467
468  StdString CINetCDF4::getBoundsId(const StdString& name,
469                                   const CVarPath* const path)
470  {
471    StdString retvalue;
[782]472    if (this->hasAttribute(CCFKeywords::XIOS_CF_bounds, &name, path))
473      retvalue = this->getAttributeValue(CCFKeywords::XIOS_CF_bounds, &name, path);
[599]474    return retvalue;
475  }
476
477  //---------------------------------------------------------------
478
479  bool CINetCDF4::isBound(const StdString& name,
480                          const CVarPath* const path)
481  {
482    std::set<StdString> bounds = this->getBoundVariables(path);
483    return (bounds.find(name) != bounds.end());
484  }
485
486  bool CINetCDF4::isCoordinate(const StdString& name,
487                               const CVarPath* const path)
488  {
489    std::set<StdString> coords = this->getCoordVariables(path);
490    return (coords.find(name) != coords.end());
491  }
492
493  bool CINetCDF4::isRectilinear(const StdString& name, const CVarPath* const path)
494  {
495    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
496    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
497    for (; it != end; it++)
498    {
499      const StdString& coord = *it;
500      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path))
[219]501      {
[599]502        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
503        if ((dimvar.size() == 1) && (dimvar.find(coord) != dimvar.end()))
504          continue;
505        else
506          return false;
[219]507      }
[599]508    }
509    return true;
510  }
[219]511
[599]512  bool CINetCDF4::isCurvilinear(const StdString& name, const CVarPath* const path)
513  {
514    if (this->isRectilinear(name, path) || !this->hasCoordinates(name, path))
515      return false;
516
[782]517    bool isCurVi = true;
518    unsigned int nbLonLat = 0;
[599]519    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
520    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
521    for (; it != end; it++)
522    {
523      const StdString& coord = *it;
[782]524      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path))
[219]525      {
[599]526        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
[782]527        if (2 == dimvar.size()) ++nbLonLat;
[219]528      }
[599]529    }
[782]530    if (2 != nbLonLat) isCurVi = false;
531
532    return isCurVi;
[599]533  }
[219]534
[599]535  bool CINetCDF4::isUnstructured(const StdString& name, const CVarPath* const path)
536  {
537    if (this->isRectilinear(name, path) ||
538        this->isCurvilinear(name, path) ||
539        !this->hasCoordinates(name, path))
540       return false;
[219]541
[599]542    StdString dimname = this->getDimensionsList(&name, path).back();
[219]543
[599]544    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
545    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
546    for (; it != end; it++)
547    {
548      const StdString& coord = *it;
[782]549      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path))
[219]550      {
[599]551        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
552        if ((dimvar.size() == 1) &&
553            (dimvar.find(dimname) != dimvar.end()))
554          continue;
555        else
556          return false;
557      }
558    }
[219]559
[599]560    return true;
561  }
[219]562
[599]563  bool CINetCDF4::isUnknown(const StdString& name, const CVarPath* const path)
564  {
565    return !(this->isRectilinear(name, path) || this->isCurvilinear(name, path) || this->isUnstructured(name, path));
566  }
[219]567
[599]568  bool CINetCDF4::isTemporal(const StdString& name, const CVarPath* const path)
569  {
[802]570    std::list<StdString> dims = this->getDimensionsList(&name, path);
571    return (std::find(dims.begin(), dims.end(), timeCounterName) != dims.end());
[599]572  }
[219]573
[599]574  bool CINetCDF4::is3Dim(const StdString& name, const CVarPath* const path)
575  {
576    int i = 0;
577    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
578    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
579    for (; it != end; it++)
580    {
581      const StdString& coord = *it;
582      if (this->hasVariable(coord, path))
[219]583      {
[599]584        if (this->isTemporal(coord, path))
585          continue;
586        i++;
[219]587      }
[599]588      else
[219]589      {
[782]590        StdString unlimitedDimName = this->getUnlimitedDimensionName();
591        if (coord.compare(0, unlimitedDimName.size(), unlimitedDimName) == 0)
[599]592          continue;
593        i++;
[219]594      }
[599]595    }
596    return (i == 3);
597  }
[219]598
[599]599  bool CINetCDF4::isCellGrid(const StdString& name, const CVarPath* const path)
600  {
601    if (this->isCoordinate(name, path))
602    {
[686]603      return this->hasBounds(name, path);
[599]604    }
605    else
606    {
607      std::list<StdString> coords = this->getCoordinatesIdList(name, path);
608      std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
609      for (; it != end; it++)
[219]610      {
[599]611        const StdString& coord = *it;
612        if (this->hasVariable(coord, path))
613        {
614          if (this->isTemporal(coord, path))
615            continue;
616          if (this->isCellGrid(coord, path))
617            continue;
618          return false;
619        }
620        else
621        {
[782]622          StdString unlimitedDimName = this->getUnlimitedDimensionName();
623          if (coord.compare(0, unlimitedDimName.size(), unlimitedDimName) == 0)
[599]624            continue;
625          return false;
626        }
[219]627      }
[599]628    }
[219]629
[599]630    return true;
631  }
[219]632
[599]633  //---------------------------------------------------------------
[219]634
[599]635  std::list<StdString> CINetCDF4::getDataVariables(bool _is3D,       bool _isRecti,
636                                                   bool _isCurvi,    bool _isUnstr,
637                                                   bool _isCellData, bool _isTemporal,
638                                                   const CVarPath* const path)
639  {
640    std::list<StdString> retvalue;
641    std::list<StdString> allvars  = this->getVariables(path);
642    std::set<StdString> allcoords = this->getCoordVariables(path);
[219]643
[599]644    std::list<StdString>::const_iterator it = allvars.begin(), end = allvars.end();
645    for (; it != end; it++)
646    {
647      const StdString& var = *it;
648      if (this->isCoordinate(var, path)) continue;
[219]649
[599]650      if (!_isRecti && this->isRectilinear(var, path))  continue;
651      if (!_isCurvi && this->isCurvilinear(var, path))  continue;
652      if (!_isUnstr && this->isUnstructured(var, path)) continue;
[219]653
[599]654      if (!_isTemporal && this->isTemporal(var, path)) continue;
655      if (!_is3D       && this->is3Dim(var, path))     continue;
656      if (!_isCellData && this->isCellGrid(var, path)) continue;
[219]657
[599]658      if (this->isUnknown(var, path)) continue;
[219]659
[599]660      retvalue.push_back(var);
661    }
662    return retvalue;
663  }
[219]664
[599]665  //---------------------------------------------------------------
[219]666
[599]667  void CINetCDF4::getDataInfo(const StdString& var, const CVarPath* const path, StdSize record,
668                              std::vector<StdSize>& sstart, std::vector<StdSize>& scount, StdSize& array_size,
669                              const std::vector<StdSize>* start /*= NULL*/, const std::vector<StdSize>* count /*= NULL*/)
670  {
671    std::list<StdString> dimlist = this->getDimensionsList(&var, path);
672    std::map<StdString, StdSize> dimmap = this->getDimensions(&var, path);
673    std::list<StdString>::iterator it = dimlist.begin();
674    if (this->isTemporal(var, path))
675    {
676      if (record != UNLIMITED_DIM)
677        sstart.push_back(record);
678      else
679        sstart.push_back(0);
680      scount.push_back(1);
681      it++;
682    }
683    for (int i = 0; it != dimlist.end(); it++, i++)
684    {
685      if (start && count)
[219]686      {
[599]687        sstart.push_back((*start)[i]);
688        scount.push_back((*count)[i]);
689        array_size *= (*count)[i];
[219]690      }
[599]691      else
[219]692      {
[599]693        sstart.push_back(0);
694        scount.push_back(dimmap[*it]);
695        array_size *= dimmap[*it];
[219]696      }
[599]697    }
698  }
[219]699
[686]700  template <class T>
701  void CINetCDF4::getData(CArray<T, 1>& data, const StdString& var,
[599]702                          const CVarPath* const path, StdSize record)
703  {
704    std::vector<StdSize> start, count;
705    int grpid = this->getGroup(path);
706    int varid = this->getVariable(var, path);
707    StdSize array_size = 1;
708    this->getDataInfo(var, path, record, start, count, array_size);
709    data.resize(array_size);
[686]710    CNetCdfInterface::getVaraType(grpid, varid, &start[0], &count[0], data.dataFirst());
[599]711  }
[219]712
[599]713  template <>
[686]714  void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var,
715                          const CVarPath* const path, StdSize record);
716  template <>
[599]717  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var,
[686]718                          const CVarPath* const path, StdSize record);
[599]719  template <>
720  void CINetCDF4::getData(CArray<float, 1>& data, const StdString& var,
[686]721                          const CVarPath* const path, StdSize record);
[219]722
[599]723  //---------------------------------------------------------------
724
725  StdString CINetCDF4::getLonCoordName(const StdString& varname,
726                                       const CVarPath* const path)
727  {
[782]728    std::list<StdString>::const_iterator itbList, itList, iteList;
[599]729    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
[782]730    itbList = clist.begin(); iteList = clist.end();
731    for (itList = itbList; itList != iteList; ++itList)
732    {
733      if (this->hasAttribute(CCFKeywords::XIOS_CF_units, &(*itList), path))
734      {
735        StdString unit = this->getAttributeValue(CCFKeywords::XIOS_CF_units, &(*itList), path);
736        if (CCFConvention::XIOS_CF_Longitude_units.end() != CCFConvention::XIOS_CF_Longitude_units.find(unit))
737          return *itList;
738      }
739    }
[599]740  }
741
742  StdString CINetCDF4::getLatCoordName(const StdString& varname,
743                                       const CVarPath* const path)
744  {
[782]745    std::list<StdString>::const_iterator itbList, itList, iteList;
[599]746    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
[782]747    itbList = clist.begin(); iteList = clist.end();
748    for (itList = itbList; itList != iteList; ++itList)
749    {
750      if (this->hasAttribute(CCFKeywords::XIOS_CF_units, &(*itList), path))
751      {
752        StdString unit = this->getAttributeValue(CCFKeywords::XIOS_CF_units, &(*itList), path);
753        if (CCFConvention::XIOS_CF_Latitude_units.end() != CCFConvention::XIOS_CF_Latitude_units.find(unit))
754          return *itList;
755      }
756    }
[599]757  }
758
759  StdString CINetCDF4::getVertCoordName(const StdString& varname,
760                                        const CVarPath* const path)
761  {
762    if (!this->is3Dim(varname, path)) return "";
763    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
764    if (this->hasCoordinates(varname, path))
[686]765      return *(++(++clist.begin()));
[599]766    else
[686]767      return *(++(++clist.rbegin()));
[599]768  }
[335]769} // namespace xios
Note: See TracBrowser for help on using the repository browser.