source: XIOS/dev/branch_openmp/src/io/inetcdf4.cpp @ 1463

Last change on this file since 1463 was 1463, checked in by yushan, 6 years ago

test_remap modified to follow trunk. memory free issue in mapper.cpp solved by changing tags. Yet need to know why.

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