source: XMLIO_V2/dev/dev_rv/src4/xmlio/netcdf/inetcdf4.cpp @ 241

Last change on this file since 241 was 241, checked in by hozdoba, 11 years ago
File size: 11.7 KB
Line 
1/* ************************************************************************** *
2 *      Copyright © IPSL/LSCE, XMLIOServer, Avril 2010 - Octobre 2011         *
3 * ************************************************************************** */
4
5/**
6 * \file    inetcdf4.hpp
7 * \brief   Lecture des fichiers de données au format netCDF-4 (implémentation).
8 * \author  Hervé Ozdoba
9 * \version 0.4
10 * \date    15 Juin 2011
11 */
12
13// XMLIOServer headers
14#include "inetcdf4.hpp"
15#include "inetcdf4_impl.hpp"
16
17// /////////////////////////////// Définitions ////////////////////////////// //
18
19namespace xmlioserver {
20namespace io {
21   
22   CINetCDF4::CINetCDF4(const std::string & filename)
23   {
24      CheckError(nc_open(filename.c_str(), NC_NOWRITE, &this->ncidp));
25   }
26
27   CINetCDF4::~CINetCDF4(void)
28   {
29       CheckError(nc_close(this->ncidp));
30   }
31   
32   void CINetCDF4::CheckError(int _status) throw (CException)
33   {
34      if (_status != NC_NOERR)
35      {
36         std::string errormsg (nc_strerror(_status)); // fuite mémoire ici ?
37         XIOS_ERROR("CONetCDF4::CheckError(int status)",
38              << "[ status = " << _status << " ] " << errormsg);
39      }
40   }
41   
42   int CINetCDF4::getCurrentGroup(void)
43   {
44      return (this->getGroup(this->getCurrentPath()));
45   }
46   
47   int CINetCDF4::getGroup(const CNetCDF4Path & path)
48   {
49      int retvalue = this->ncidp;
50     
51      CNetCDF4Path::const_iterator
52         it  = path.begin(), end = path.end();
53
54      for (;it != end; it++)
55      {
56         const std::string & groupid = *it;
57         CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue));
58      }
59      return (retvalue);
60   }
61   
62   int CINetCDF4::getVariable(const std::string & varname)
63   {
64      int varid = 0;
65      int grpid = this->getCurrentGroup();
66      CheckError(nc_inq_varid (grpid, varname.c_str(), &varid));
67      return (varid);
68   }
69   
70   int CINetCDF4::getDimension(const std::string & dimname)
71   {
72      int dimid = 0;
73      int grpid = this->getCurrentGroup();
74      CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid));
75      return (dimid);
76   }
77   
78   int CINetCDF4::getUnlimitedDimension(void)
79   {
80      int dimid = 0;
81      int grpid = this->getCurrentGroup();
82      CheckError(nc_inq_unlimdim (grpid, &dimid));
83      return (dimid);
84   }
85   
86   std::vector<std::size_t> CINetCDF4::getDimensions(const std::string & varname)
87   {
88      std::size_t size = 0;
89      std::vector<std::size_t> retvalue;
90      int grpid = this->getCurrentGroup();
91      int varid = this->getVariable(varname);
92      int nbdim = 0, *dimid = NULL;
93
94      CheckError(nc_inq_varndims(grpid, varid, &nbdim));
95      dimid = new int[nbdim]();
96      CheckError(nc_inq_vardimid(grpid, varid, dimid));
97
98      for (int i = 0; i < nbdim; i++)
99      {
100         CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
101         if (size == NC_UNLIMITED)
102             size = UNLIMITED_DIM;
103         retvalue.push_back(size);
104      }
105
106      return (retvalue);
107   }
108   
109   const CINetCDF4::CNetCDF4Path & CINetCDF4::getCurrentPath(void) const
110   { 
111       return (this->path); 
112   }
113
114   void CINetCDF4::setCurrentPath(const CNetCDF4Path & path)
115   { 
116       this->path = path; 
117   }
118   
119   void CINetCDF4::getReadDataInfos(const std::string & _varname,
120                                    std::size_t   _record, 
121                                    std::size_t & _array_size,
122                                    std::vector<std::size_t> & _sstart,
123                                    std::vector<std::size_t> & _scount,
124                                    const std::vector<std::size_t> * _start,
125                                    const std::vector<std::size_t> * _count)
126   {
127      std::vector<std::size_t> sizes  = this->getDimensions(_varname);
128      std::vector<std::string> iddims = this->getDimensionsIdList (&_varname);   
129      std::vector<std::size_t>::const_iterator
130         it  = sizes.begin(), end = sizes.end();
131      int i = 0;
132     
133      if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0)
134      {
135         _sstart.push_back(_record);
136         _scount.push_back(1); 
137         if ((_start == NULL) &&
138             (_count == NULL)) i++;
139         it++;
140      }
141
142      for (;it != end; it++)
143      {     
144         if ((_start != NULL) && (_count != NULL))
145         {
146            _sstart.push_back((*_start)[i]);
147            _scount.push_back((*_count)[i]);
148            _array_size *= (*_count)[i];
149            i++;
150         }
151         else
152         {
153            _sstart.push_back(0);
154            _scount.push_back(sizes[i]);
155            _array_size *= sizes[i];
156            i++;
157         }
158      }
159   }
160   
161   void CINetCDF4::readAttribute
162      (const std::string & _attname, std::string & _value, const std::string * _varname)
163   {
164        std::vector<char> chart;
165        this->readAttribute(_attname,chart , _varname);
166        _value.assign(&(chart[0]), chart.size());
167   }
168
169   std::vector<std::string> CINetCDF4::getAttributes(const std::string * const _varname)
170   {
171      int nbatt = 0;
172      char full_name_in[NC_MAX_NAME +1];
173      std::vector<std::string> retvalue;
174      int grpid = this->getCurrentGroup();
175      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
176
177      if (_varname != NULL)
178         CheckError(nc_inq_varnatts (grpid, varid, &nbatt));
179      else
180         CheckError(nc_inq_natts(grpid, &nbatt));
181
182      for (int i = 0; i < nbatt; i++)
183      {
184         CheckError(nc_inq_attname(grpid, varid, i, full_name_in));
185         std::string attname(full_name_in);
186         retvalue.push_back(attname);
187      }
188      return (retvalue);
189   }
190   
191   
192   std::map<std::string, std::size_t> CINetCDF4::getDimensions(const std::string * const _varname)
193   {
194      std::size_t size = 0;
195      char full_name_in[NC_MAX_NAME +1];
196      int nbdim = 0, *dimid = NULL;
197      int grpid = this->getCurrentGroup();
198      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
199      std::map<std::string, std::size_t> retvalue;
200
201      if (_varname != NULL)
202      {
203         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
204         dimid = new int[nbdim]();
205         CheckError(nc_inq_vardimid(grpid, varid, dimid));
206      }
207      else
208      {
209         CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
210         dimid = new int[nbdim]();
211         CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
212      }
213
214      for (int i = 0; i < nbdim; i++)
215      {
216         CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
217         CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
218
219         std::string dimname(full_name_in);
220         retvalue.insert(retvalue.end(), std::make_pair(dimname, size));
221      }
222      delete [] dimid;
223
224      return (retvalue);
225   }
226   
227   std::vector<std::string> CINetCDF4::getGroups(void)
228   {
229      std::size_t strlen = 0;
230      char full_name_in[NC_MAX_NAME +1];
231      int nbgroup = 0, *groupid = NULL;
232      int grpid = this->getCurrentGroup();
233      std::vector<std::string> retvalue;
234
235      CheckError(nc_inq_grps(grpid, &nbgroup, NULL));
236      groupid = new int[nbgroup]();
237      CheckError(nc_inq_grps(grpid, NULL, groupid));
238
239      for (int i = 0; i < nbgroup; i++)
240      {
241         CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in));
242         std::string groupname(full_name_in, strlen);
243         retvalue.push_back(groupname);
244      }
245
246      delete [] groupid;
247      return (retvalue);
248   }
249   
250   std::vector<std::string> CINetCDF4::getVariables(void)
251   {
252      char full_name_in[NC_MAX_NAME +1];
253      int nbvar = 0, *varid = NULL;
254      int grpid = this->getCurrentGroup();
255      std::vector<std::string> retvalue;
256
257      CheckError(nc_inq_varids(grpid, &nbvar, NULL));
258      varid = new int[nbvar]();
259      CheckError(nc_inq_varids(grpid, NULL, varid));
260
261      for (int i = 0; i < nbvar; i++)
262      {
263         CheckError(nc_inq_varname(grpid, varid[i], full_name_in));
264         std::string varname(full_name_in);
265         retvalue.push_back(varname);
266      }
267
268      delete [] varid;
269      return (retvalue);
270   }
271   
272   std::size_t CINetCDF4::getNbOfTimestep(void)
273   {
274      int dimid = this->getUnlimitedDimension();
275      if (dimid == -1) return (1);
276      return (this->getDimensions(NULL)[this->getUnlimitedDimensionName()]);
277   }
278           
279   std::string CINetCDF4::getUnlimitedDimensionName(void)
280   {
281      char full_name_in[NC_MAX_NAME +1];
282      int grpid = this->getGroup(path);
283      int dimid = this->getUnlimitedDimension();
284     
285      if (dimid == -1) return (std::string());
286      CheckError(nc_inq_dimname(grpid, dimid, full_name_in));
287
288      std::string dimname(full_name_in);
289      return (dimname);
290   }
291 
292   std::vector<std::string> CINetCDF4::getDimensionsIdList (const std::string * _varname)
293   {
294      char full_name_in[NC_MAX_NAME +1];
295      int nbdim = 0, *dimid = NULL;
296      int grpid = this->getCurrentGroup();
297      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
298      std::vector<std::string> retvalue;
299
300      if (_varname != NULL)
301      {
302         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
303         dimid = new int[nbdim]();
304         CheckError(nc_inq_vardimid(grpid, varid, dimid));
305      }
306      else
307      {
308         CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
309         dimid = new int[nbdim]();
310         CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
311      }
312
313      for (int i = 0; i < nbdim; i++)
314      {
315         CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
316         std::string dimname(full_name_in);
317         retvalue.push_back(dimname);
318      }
319      delete [] dimid;
320
321      return (retvalue);
322   }
323   
324   template <>
325      void CINetCDF4::readData_(int _grpid, int _varid,
326                                const std::vector<std::size_t> & _sstart,
327                                const std::vector<std::size_t> & _scount,
328                                float * _data)
329   {
330      CheckError(nc_get_vara_float(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
331   }
332   
333   template <>
334      void CINetCDF4::readData_(int _grpid, int _varid,
335                                const std::vector<std::size_t> & _sstart,
336                                const std::vector<std::size_t> & _scount,
337                                int * _data)
338   {
339      CheckError(nc_get_vara_int(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
340   }
341   
342   template <>
343      void CINetCDF4::readData_(int _grpid, int _varid,
344                                const std::vector<std::size_t> & _sstart,
345                                const std::vector<std::size_t> & _scount,
346                                double * _data)
347   {
348      CheckError(nc_get_vara_double(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
349   }
350   
351   template <>
352      void CINetCDF4::readAttribute_
353         (const std::string & _attname, double * _value, int _grpid, int _varid)
354   {       
355        CheckError(nc_get_att_double(_grpid, _varid, _attname.c_str(), _value));
356   }
357   
358   template <>
359      void CINetCDF4::readAttribute_
360         (const std::string & _attname, float * _value, int _grpid, int _varid)
361   {
362       CheckError(nc_get_att_float(_grpid, _varid, _attname.c_str(), _value));
363   }
364   
365   template <>
366      void CINetCDF4::readAttribute_
367         (const std::string & _attname, int * _value, int _grpid, int _varid)
368   {
369       CheckError(nc_get_att_int(_grpid, _varid, _attname.c_str(), _value));
370   }
371   
372   template <>
373      void CINetCDF4::readAttribute_
374         (const std::string & _attname, char * _value, int _grpid, int _varid)
375   {
376       CheckError(nc_get_att_text(_grpid, _varid, _attname.c_str(), _value));
377   }
378   
379   bool CINetCDF4::varExist(const std::string & _varname)
380   {
381      int varid = 0;
382      int grpid = this->getCurrentGroup();
383      return (nc_inq_varid (grpid, _varname.c_str(), &varid) == NC_NOERR);
384   }
385   
386} // namespace io
387} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.