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

Last change on this file since 736 was 736, checked in by rlacroix, 9 years ago

Fix the opening of NetCDF-4 input files in parallel.

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