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

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

branch_openmp merged with trunk r1544

  • 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: 27.7 KB
Line 
1#include "inetcdf4.hpp"
2#include "netCdfInterface.hpp"
3#include "netCdf_cf_constant.hpp"
4#include "ep_mpi.hpp"
5#include <boost/algorithm/string.hpp>
6
7namespace xios
8{
9  CINetCDF4::CINetCDF4(const StdString& filename, const ep_lib::MPI_Comm* comm /*= NULL*/, bool multifile /*= true*/,
10                       bool readMetaDataPar /*= false*/, const StdString& timeCounterName /*= "time_counter"*/)
11  {
12    // Don't use parallel mode if there is only one process
13    if (comm)
14    {
15      int commSize = 0;
16      ep_lib::MPI_Comm_size(*comm, &commSize);
17      if (commSize <= 1)
18        comm = NULL;
19    }
20    mpi = comm && !multifile && readMetaDataPar;
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, to_mpi_comm((*comm)->mpi_comm), to_mpi_info(MPI_INFO_NULL), 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->hasVariable(*var, path)) ? 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->hasVariable(*var, path)) ? this->getVariable(*var, path) : NC_GLOBAL;
220    std::list<StdString> retvalue;
221
222    if (var != NULL && this->hasVariable(*var, path))
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->hasVariable(*var, path)) ? this->getVariable(*var, path) : NC_GLOBAL;
251    std::map<StdString, StdSize> retvalue;
252
253    if (var != NULL && this->hasVariable(*var, path))
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->hasVariable(*var, path)) ? this->getVariable(*var, path) : NC_GLOBAL;
286
287    if (var != NULL && this->hasVariable(*var, path))
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->hasVariable(*var, path)) ? 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> varCoords = this->getCoordinatesIdList(name, path);
498    std::list<StdString> varDims = this->getDimensionsList(&name, path);
499    std::list<StdString>::const_iterator it = varCoords.begin(), end = varCoords.end();
500    std::set<StdString> varDims1D;
501
502    // Firstly, loop over coordinate list
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> coordDims = this->getDimensions(&coord, path);
509        for (std::map<StdString, StdSize>::const_iterator itTmp = coordDims.begin(); itTmp != coordDims.end(); itTmp++)
510        {
511          varDims.remove(itTmp->first);
512        }
513        if (this->isLonOrLat(coord, path) && coordDims.size() == 1)
514        {
515          varDims1D.insert(coordDims.begin()->first);
516          continue;
517        }
518      }
519    }
520    // Secondly, loop over remaining dimensions
521    for (it= varDims.begin(); it != varDims.end(); it++)
522    {
523      const StdString& coord = *it;
524      std::map<StdString, StdSize> coordDims = this->getDimensions(&coord, path);
525      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path) )
526      {
527        if (this->isLonOrLat(coord, path) && coordDims.size() == 1)
528        {
529          varDims1D.insert(coordDims.begin()->first);
530          continue;
531        }
532      }
533    }
534
535    return (varDims1D.size() == 2);
536  }
537
538  bool CINetCDF4::isCurvilinear(const StdString& name, const CVarPath* const path)
539  {
540    if (this->isRectilinear(name, path) || !this->hasCoordinates(name, path))
541      return false;
542
543    bool isCurVi = true;
544    unsigned int nbLonLat = 0;
545    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
546    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
547    for (; it != end; it++)
548    {
549      const StdString& coord = *it;
550      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path) && this->isLonOrLat(coord, path))
551      {
552        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
553        if (2 == dimvar.size()) ++nbLonLat;
554      }
555    }
556    if (2 != nbLonLat) isCurVi = false;
557
558    return isCurVi;
559  }
560
561  bool CINetCDF4::isUnstructured(const StdString& name, const CVarPath* const path)
562  {
563    if (this->isRectilinear(name, path) ||
564        this->isCurvilinear(name, path) ||
565        !this->hasCoordinates(name, path))
566       return false;
567    else return true ;
568   
569// check this part above   
570    StdString dimname = this->getDimensionsList(&name, path).back();
571
572    std::list<StdString> coords = this->getCoordinatesIdList(name, path);
573    std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
574    for (; it != end; it++)
575    {
576      const StdString& coord = *it;
577      if (this->hasVariable(coord, path) && !this->isTemporal(coord, path) && this->isLonOrLat(coord, path))
578      {
579        std::map<StdString, StdSize> dimvar = this->getDimensions(&coord, path);
580        if ((dimvar.size() == 1) &&
581            (dimvar.find(dimname) != dimvar.end()))
582          continue;
583        else
584          return false;
585      }
586    }
587
588    return true;
589  }
590
591  bool CINetCDF4::isUnknown(const StdString& name, const CVarPath* const path)
592  {
593    return !(this->isRectilinear(name, path) || this->isCurvilinear(name, path) || this->isUnstructured(name, path));
594  }
595
596  bool CINetCDF4::isTemporal(const StdString& name, const CVarPath* const path)
597  {
598    std::list<StdString> dims = this->getDimensionsList(&name, path);
599    return (std::find(dims.begin(), dims.end(), timeCounterName) != dims.end());
600  }
601
602  bool CINetCDF4::is3Dim(const StdString& name, const CVarPath* const path)
603  {
604    int i = 0;
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        i++;
615      }
616      else
617      {
618        StdString unlimitedDimName = this->getUnlimitedDimensionName();
619        if (coord.compare(0, unlimitedDimName.size(), unlimitedDimName) == 0)
620          continue;
621        i++;
622      }
623    }
624    return (i == 3);
625  }
626
627  bool CINetCDF4::isCellGrid(const StdString& name, const CVarPath* const path)
628  {
629    if (this->isCoordinate(name, path))
630    {
631      return this->hasBounds(name, path);
632    }
633    else
634    {
635      std::list<StdString> coords = this->getCoordinatesIdList(name, path);
636      std::list<StdString>::const_iterator it = coords.begin(), end = coords.end();
637      for (; it != end; it++)
638      {
639        const StdString& coord = *it;
640        if (this->hasVariable(coord, path))
641        {
642          if (this->isTemporal(coord, path))
643            continue;
644          if (this->isCellGrid(coord, path))
645            continue;
646          return false;
647        }
648        else
649        {
650          StdString unlimitedDimName = this->getUnlimitedDimensionName();
651          if (coord.compare(0, unlimitedDimName.size(), unlimitedDimName) == 0)
652            continue;
653          return false;
654        }
655      }
656    }
657
658    return true;
659  }
660
661  //---------------------------------------------------------------
662
663  std::list<StdString> CINetCDF4::getDataVariables(bool _is3D,       bool _isRecti,
664                                                   bool _isCurvi,    bool _isUnstr,
665                                                   bool _isCellData, bool _isTemporal,
666                                                   const CVarPath* const path)
667  {
668    std::list<StdString> retvalue;
669    std::list<StdString> allvars  = this->getVariables(path);
670    std::set<StdString> allcoords = this->getCoordVariables(path);
671
672    std::list<StdString>::const_iterator it = allvars.begin(), end = allvars.end();
673    for (; it != end; it++)
674    {
675      const StdString& var = *it;
676      if (this->isCoordinate(var, path)) continue;
677
678      if (!_isRecti && this->isRectilinear(var, path))  continue;
679      if (!_isCurvi && this->isCurvilinear(var, path))  continue;
680      if (!_isUnstr && this->isUnstructured(var, path)) continue;
681
682      if (!_isTemporal && this->isTemporal(var, path)) continue;
683      if (!_is3D       && this->is3Dim(var, path))     continue;
684      if (!_isCellData && this->isCellGrid(var, path)) continue;
685
686      if (this->isUnknown(var, path)) continue;
687
688      retvalue.push_back(var);
689    }
690    return retvalue;
691  }
692
693  //---------------------------------------------------------------
694
695  void CINetCDF4::getDataInfo(const StdString& var, const CVarPath* const path, StdSize record,
696                              std::vector<StdSize>& sstart, std::vector<StdSize>& scount, StdSize& array_size,
697                              const std::vector<StdSize>* start /*= NULL*/, const std::vector<StdSize>* count /*= NULL*/)
698  {
699    std::list<StdString> dimlist = this->getDimensionsList(&var, path);
700    std::map<StdString, StdSize> dimmap = this->getDimensions(&var, path);
701    std::list<StdString>::iterator it = dimlist.begin();
702    if (this->isTemporal(var, path))
703    {
704      if (record != UNLIMITED_DIM)
705        sstart.push_back(record);
706      else
707        sstart.push_back(0);
708      scount.push_back(1);
709      it++;
710    }
711    for (int i = 0; it != dimlist.end(); it++, i++)
712    {
713      if (start && count)
714      {
715        sstart.push_back((*start)[i]);
716        scount.push_back((*count)[i]);
717        array_size *= (*count)[i];
718      }
719      else
720      {
721        sstart.push_back(0);
722        scount.push_back(dimmap[*it]);
723        array_size *= dimmap[*it];
724      }
725    }
726  }
727
728  template <class T>
729  void CINetCDF4::getData(CArray<T, 1>& data, const StdString& var,
730                          const CVarPath* const path, StdSize record)
731  {
732    std::vector<StdSize> start, count;
733    int grpid = this->getGroup(path);
734    int varid = this->getVariable(var, path);
735    StdSize array_size = 1;
736    this->getDataInfo(var, path, record, start, count, array_size);
737    data.resize(array_size);
738    CNetCdfInterface::getVaraType(grpid, varid, &start[0], &count[0], data.dataFirst());
739  }
740
741  template <>
742  void CINetCDF4::getData(CArray<int, 1>& data, const StdString& var,
743                          const CVarPath* const path, StdSize record);
744  template <>
745  void CINetCDF4::getData(CArray<double, 1>& data, const StdString& var,
746                          const CVarPath* const path, StdSize record);
747  template <>
748  void CINetCDF4::getData(CArray<float, 1>& data, const StdString& var,
749                          const CVarPath* const path, StdSize record);
750
751  //---------------------------------------------------------------
752
753  StdString CINetCDF4::getLonCoordName(const StdString& varname,
754                                       const CVarPath* const path)
755  {
756    StdString lonName;
757    std::list<StdString>::const_iterator itbList, itList, iteList;
758    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
759    itbList = clist.begin(); iteList = clist.end();
760    for (itList = itbList; itList != iteList; ++itList)
761    {
762      if (this->hasAttribute(CCFKeywords::XIOS_CF_units, &(*itList), path))
763      {
764        StdString unit = this->getAttributeValue(CCFKeywords::XIOS_CF_units, &(*itList), path);
765        if (CCFConvention::XIOS_CF_Longitude_units.end() != CCFConvention::XIOS_CF_Longitude_units.find(unit))
766        {
767          lonName = *itList;
768          return lonName;
769        }
770      }
771    }
772    return lonName;
773  }
774
775  StdString CINetCDF4::getLatCoordName(const StdString& varname,
776                                       const CVarPath* const path)
777  {
778    StdString latName;
779    std::list<StdString>::const_iterator itbList, itList, iteList;
780    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
781    itbList = clist.begin(); iteList = clist.end();
782    for (itList = itbList; itList != iteList; ++itList)
783    {
784      if (this->hasAttribute(CCFKeywords::XIOS_CF_units, &(*itList), path))
785      {
786        StdString unit = this->getAttributeValue(CCFKeywords::XIOS_CF_units, &(*itList), path);
787        if (CCFConvention::XIOS_CF_Latitude_units.end() != CCFConvention::XIOS_CF_Latitude_units.find(unit))
788        {
789          latName = *itList;
790          return latName;
791        }
792      }
793    }
794    return latName;
795  }
796
797  StdString CINetCDF4::getVertCoordName(const StdString& varname,
798                                        const CVarPath* const path)
799  {
800    if (!this->is3Dim(varname, path)) return "";
801    std::list<StdString> clist = this->getCoordinatesIdList(varname, path);
802    if (this->hasCoordinates(varname, path))
803      return *(++(++clist.begin()));
804    else
805      return *(++(++clist.rbegin()));
806  }
807
808  bool CINetCDF4::isLonOrLat(const StdString& varname, const CVarPath* const path)
809  {
810    if (this->hasAttribute(CCFKeywords::XIOS_CF_units, &varname, path))
811    {
812      StdString unit = this->getAttributeValue(CCFKeywords::XIOS_CF_units, &varname, path);
813      return      (CCFConvention::XIOS_CF_Latitude_units.end() != CCFConvention::XIOS_CF_Latitude_units.find(unit)
814                || CCFConvention::XIOS_CF_Longitude_units.end() != CCFConvention::XIOS_CF_Longitude_units.find(unit));
815    }
816    else return false ;
817  }
818
819} // namespace xios
Note: See TracBrowser for help on using the repository browser.