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

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

save dev. TO DO : test with xios

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