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

Last change on this file since 802 was 802, checked in by rlacroix, 8 years ago

Add a new file attribute time_counter_name.

Users can now modify the name of the time counter dimension and axis name.

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