source: XIOS/dev/branch_yushan_merged/src/io/inetcdf4.cpp @ 1134

Last change on this file since 1134 was 1134, checked in by yushan, 4 years ago

branch merged with trunk r1130

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