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

Last change on this file since 783 was 783, checked in by mhnguyen, 8 years ago

Adding attribute reading of unstructured grid

+) Fix a minor bug relating to unstructured grid detection
+) Add attribute reading for unstructured domain

Test
+) On Curie
+) test_remap passes

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