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

Last change on this file since 1287 was 1287, checked in by yushan, 7 years ago

EP updated

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