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

Last change on this file since 229 was 229, 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::size_t>::const_iterator
129         it  = sizes.begin(), end = sizes.end();
130      int i = 0;
131
132      for (;it != end; it++)
133      {
134         std::size_t  s = *it;
135         if ((_start != NULL) && (_count != NULL))
136         {
137            if (s == UNLIMITED_DIM)
138            {
139               _sstart.push_back(_record);
140               _scount.push_back(1);
141            }
142            else
143            {
144               _sstart.push_back((*_start)[i]);
145               _scount.push_back((*_count)[i]);
146               _array_size *= (*_count)[i];
147               i++;
148            }
149         }
150         else
151         {
152            if (s == UNLIMITED_DIM)
153            {
154               _sstart.push_back(_record);
155               _scount.push_back(1);
156            }
157            else
158            {
159               _sstart.push_back(0);
160               _scount.push_back(sizes[i]);
161               _array_size *= sizes[i];
162            }
163            i++;
164         }
165      }
166   }
167   
168   void CINetCDF4::readAttribute
169      (const std::string & _attname, std::string & _value, const std::string * _varname)
170   {
171        std::vector<char> chart;
172        this->readAttribute(_attname,chart , _varname);
173        _value.assign(&(chart[0]), chart.size());
174   }
175
176   std::vector<std::string> CINetCDF4::getAttributes(const std::string * const _varname)
177   {
178      int nbatt = 0;
179      char full_name_in[NC_MAX_NAME +1];
180      std::vector<std::string> retvalue;
181      int grpid = this->getCurrentGroup();
182      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
183
184      if (_varname != NULL)
185         CheckError(nc_inq_varnatts (grpid, varid, &nbatt));
186      else
187         CheckError(nc_inq_natts(grpid, &nbatt));
188
189      for (int i = 0; i < nbatt; i++)
190      {
191         CheckError(nc_inq_attname(grpid, varid, i, full_name_in));
192         std::string attname(full_name_in);
193         retvalue.push_back(attname);
194      }
195      return (retvalue);
196   }
197   
198   
199   std::map<std::string, std::size_t> CINetCDF4::getDimensions(const std::string * const _varname)
200   {
201      std::size_t size = 0;
202      char full_name_in[NC_MAX_NAME +1];
203      int nbdim = 0, *dimid = NULL;
204      int grpid = this->getCurrentGroup();
205      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
206      std::map<std::string, std::size_t> retvalue;
207
208      if (_varname != NULL)
209      {
210         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
211         dimid = new int[nbdim]();
212         CheckError(nc_inq_vardimid(grpid, varid, dimid));
213      }
214      else
215      {
216         CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
217         dimid = new int[nbdim]();
218         CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
219      }
220
221      for (int i = 0; i < nbdim; i++)
222      {
223         CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
224         CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
225
226         std::string dimname(full_name_in);
227         retvalue.insert(retvalue.end(), std::make_pair(dimname, size));
228      }
229      delete [] dimid;
230
231      return (retvalue);
232   }
233   
234   std::vector<std::string> CINetCDF4::getGroups(void)
235   {
236      std::size_t strlen = 0;
237      char full_name_in[NC_MAX_NAME +1];
238      int nbgroup = 0, *groupid = NULL;
239      int grpid = this->getCurrentGroup();
240      std::vector<std::string> retvalue;
241
242      CheckError(nc_inq_grps(grpid, &nbgroup, NULL));
243      groupid = new int[nbgroup]();
244      CheckError(nc_inq_grps(grpid, NULL, groupid));
245
246      for (int i = 0; i < nbgroup; i++)
247      {
248         CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in));
249         std::string groupname(full_name_in, strlen);
250         retvalue.push_back(groupname);
251      }
252
253      delete [] groupid;
254      return (retvalue);
255   }
256   
257   std::vector<std::string> CINetCDF4::getVariables(void)
258   {
259      char full_name_in[NC_MAX_NAME +1];
260      int nbvar = 0, *varid = NULL;
261      int grpid = this->getCurrentGroup();
262      std::vector<std::string> retvalue;
263
264      CheckError(nc_inq_varids(grpid, &nbvar, NULL));
265      varid = new int[nbvar]();
266      CheckError(nc_inq_varids(grpid, NULL, varid));
267
268      for (int i = 0; i < nbvar; i++)
269      {
270         CheckError(nc_inq_varname(grpid, varid[i], full_name_in));
271         std::string varname(full_name_in);
272         retvalue.push_back(varname);
273      }
274
275      delete [] varid;
276      return (retvalue);
277   }
278   
279   std::size_t CINetCDF4::getNbOfTimestep(void)
280   {
281       return (this->getDimensions(NULL)[this->getUnlimitedDimensionName()]);
282   }
283           
284   std::string CINetCDF4::getUnlimitedDimensionName(void)
285   {
286      char full_name_in[NC_MAX_NAME +1];
287      int grpid = this->getGroup(path);
288      int dimid = this->getUnlimitedDimension();
289      CheckError(nc_inq_dimname(grpid, dimid, full_name_in));
290
291      std::string dimname(full_name_in);
292      return (dimname);
293   }
294 
295   std::vector<std::string> CINetCDF4::getDimensionsIdList (const std::string * _varname)
296   {
297      char full_name_in[NC_MAX_NAME +1];
298      int nbdim = 0, *dimid = NULL;
299      int grpid = this->getCurrentGroup();
300      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
301      std::vector<std::string> retvalue;
302
303      if (_varname != NULL)
304      {
305         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
306         dimid = new int[nbdim]();
307         CheckError(nc_inq_vardimid(grpid, varid, dimid));
308      }
309      else
310      {
311         CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
312         dimid = new int[nbdim]();
313         CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
314      }
315
316      for (int i = 0; i < nbdim; i++)
317      {
318         CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
319         std::string dimname(full_name_in);
320         retvalue.push_back(dimname);
321      }
322      delete [] dimid;
323
324      return (retvalue);
325   }
326   
327   template <>
328      void CINetCDF4::readData_(int _grpid, int _varid,
329                                const std::vector<std::size_t> & _sstart,
330                                const std::vector<std::size_t> & _scount,
331                                float * _data)
332   {
333      CheckError(nc_get_vara_float(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
334   }
335   
336   template <>
337      void CINetCDF4::readData_(int _grpid, int _varid,
338                                const std::vector<std::size_t> & _sstart,
339                                const std::vector<std::size_t> & _scount,
340                                int * _data)
341   {
342      CheckError(nc_get_vara_int(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
343   }
344   
345   template <>
346      void CINetCDF4::readData_(int _grpid, int _varid,
347                                const std::vector<std::size_t> & _sstart,
348                                const std::vector<std::size_t> & _scount,
349                                double * _data)
350   {
351      CheckError(nc_get_vara_double(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
352   }
353   
354   template <>
355      void CINetCDF4::readAttribute_
356         (const std::string & _attname, double * _value, int _grpid, int _varid)
357   {       
358        CheckError(nc_get_att_double(_grpid, _varid, _attname.c_str(), _value));
359   }
360   
361   template <>
362      void CINetCDF4::readAttribute_
363         (const std::string & _attname, float * _value, int _grpid, int _varid)
364   {
365       CheckError(nc_get_att_float(_grpid, _varid, _attname.c_str(), _value));
366   }
367   
368   template <>
369      void CINetCDF4::readAttribute_
370         (const std::string & _attname, int * _value, int _grpid, int _varid)
371   {
372       CheckError(nc_get_att_int(_grpid, _varid, _attname.c_str(), _value));
373   }
374   
375   template <>
376      void CINetCDF4::readAttribute_
377         (const std::string & _attname, char * _value, int _grpid, int _varid)
378   {
379       CheckError(nc_get_att_text(_grpid, _varid, _attname.c_str(), _value));
380   }
381   
382   bool CINetCDF4::varExist(const std::string & _varname)
383   {
384      int varid = 0;
385      int grpid = this->getCurrentGroup();
386      return (nc_inq_varid (grpid, _varname.c_str(), &varid) == NC_NOERR);
387   }
388   
389} // namespace io
390} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.