source: XMLIO_V2/dev/dev_rv/src4/xmlio/netcdf/onetcdf4.cpp @ 249

Last change on this file since 249 was 249, checked in by hozdoba, 13 years ago

Ajout d'une partie d'Interface fortran pour la version 4
Ajout des sorties netcdf4 pour la version 4

File size: 11.3 KB
Line 
1/* ************************************************************************** *
2 *      Copyright © IPSL/LSCE, XMLIOServer, Avril 2010 - Octobre 2011         *
3 * ************************************************************************** */
4 
5// XMLIOServer headers
6#include "onetcdf4.hpp"
7#include "onetcdf4_impl.hpp"
8
9// /////////////////////////////// Définitions ////////////////////////////// //
10
11namespace xmlioserver {
12namespace io {
13
14   // ------------------------------ Constructeurs -----------------------------
15   
16   CONetCDF4::CONetCDF4(const std::string & filename, bool exist,
17                        const MPI_Comm * _comm_server)
18   {
19      if (_comm_server != NULL) this->comm_server = *_comm_server;
20      if (this->comm_server)
21      { 
22         if (exist)
23            CheckError(nc_open_par(filename.c_str(), NC_NETCDF4|NC_MPIIO,
24                        this->comm_server.get(), MPI_INFO_NULL, &this->ncidp));
25         else
26            CheckError(nc_create_par(filename.c_str(), NC_NETCDF4|NC_MPIIO,
27                        this->comm_server.get(), MPI_INFO_NULL, &this->ncidp));
28      }
29      else
30      { 
31         if (exist)
32            CheckError(nc_open(filename.c_str(), NC_NETCDF4, &this->ncidp));
33         else
34            CheckError(nc_create(filename.c_str(), NC_NETCDF4, &this->ncidp));
35      }
36   }
37
38   // ------------------------------- Destructeur ------------------------------
39   
40   CONetCDF4::~CONetCDF4(void)
41   {
42       CheckError(nc_close(this->ncidp));
43   }
44   
45   // --------------------- Vérification des erreurs NetCDF --------------------
46   
47   void CONetCDF4::CheckError(int _status) throw (CException)
48   {
49      if (_status != NC_NOERR)
50      {
51         std::string errormsg (nc_strerror(_status)); // fuite mémoire ici ?
52         XIOS_ERROR("CONetCDF4::CheckError(int status)",
53              << "[ status = " << _status << " ] " << errormsg);
54      }
55   }
56   
57   // ------------------------- Début/Fin de définition ------------------------
58   
59   void CONetCDF4::definition_start(void)
60   { 
61      CheckError(nc_redef(this->ncidp));
62   }
63     
64   void CONetCDF4::definition_end(void)
65   { 
66      CheckError(nc_enddef(this->ncidp));
67   }
68   
69   // ------------------------------- Accesseurs -------------------------------
70   
71   const CONetCDF4::CNetCDF4Path & CONetCDF4::getCurrentPath(void) const
72   { 
73       return (this->path); 
74   }
75   
76   std::string CONetCDF4::getUnlimitedDimensionName(void)
77   {
78      char full_name_in[NC_MAX_NAME +1];
79      int grpid = this->getGroup(path);
80      int dimid = this->getUnlimitedDimension();
81     
82      if (dimid == -1) return (std::string());
83      CheckError(nc_inq_dimname(grpid, dimid, full_name_in));
84
85      std::string dimname(full_name_in);
86      return (dimname);
87   }
88 
89   std::vector<std::string> CONetCDF4::getDimensionsIdList (const std::string * _varname)
90   {
91      char full_name_in[NC_MAX_NAME +1];
92      int nbdim = 0, *dimid = NULL;
93      int grpid = this->getCurrentGroup();
94      int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
95      std::vector<std::string> retvalue;
96
97      if (_varname != NULL)
98      {
99         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
100         dimid = new int[nbdim]();
101         CheckError(nc_inq_vardimid(grpid, varid, dimid));
102      }
103      else
104      {
105         CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
106         dimid = new int[nbdim]();
107         CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
108      }
109
110      for (int i = 0; i < nbdim; i++)
111      {
112         CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
113         std::string dimname(full_name_in);
114         retvalue.push_back(dimname);
115      }
116      delete [] dimid;
117
118      return (retvalue);
119   }
120
121   // ------------------------------- Mutateurs --------------------------------
122
123   void CONetCDF4::setCurrentPath(const CONetCDF4::CNetCDF4Path & path)
124   { 
125       this->path = path; 
126   }
127   
128   int CONetCDF4::addDimension(const std::string & _name, std::size_t _size)
129   {
130      int retvalue = 0;
131      int grpid = this->getCurrentGroup();
132      if (_size != UNLIMITED_DIM)
133         CheckError(nc_def_dim (grpid, _name.c_str(), _size, &retvalue));
134      else
135         CheckError(nc_def_dim (grpid, _name.c_str(), NC_UNLIMITED, &retvalue));
136      return (retvalue);
137   }
138   
139   int CONetCDF4::addVariable (const std::string & _name, nc_type _type,
140                               const std::vector<std::string> & _dims)
141   {
142      int retvalue = 0;
143      std::vector<int> dimids;
144      int grpid = this->getCurrentGroup();
145         
146      std::vector<std::string>::const_iterator
147         it  = _dims.begin(), end = _dims.end();
148
149      for (;it != end; it++)
150      {
151         const std::string & dimid = *it;
152         dimids.push_back(this->getDimension(dimid));
153      }
154      CheckError(nc_def_var(grpid, _name.c_str(), _type, dimids.size(), &(dimids[0]), &retvalue));
155      return (retvalue);
156   }
157   
158   int CONetCDF4::addGroup(const std::string & _name)
159   {
160      int retvalue = 0;
161      int grpid = this->getCurrentGroup();
162      CheckError(nc_def_grp(grpid, const_cast<char*>(_name.c_str()), &retvalue));
163      return (retvalue);
164   }
165   
166   // --------------------------- Accesseurs protégés --------------------------
167   
168   int CONetCDF4::getCurrentGroup(void)
169   {
170      return (this->getGroup(this->getCurrentPath()));
171   }
172   
173   int CONetCDF4::getGroup(const CNetCDF4Path & path)
174   {
175      int retvalue = this->ncidp;
176     
177      CNetCDF4Path::const_iterator
178         it  = path.begin(), end = path.end();
179
180      for (;it != end; it++)
181      {
182         const std::string & groupid = *it;
183         CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue));
184      }
185      return (retvalue);
186   }
187   
188   int CONetCDF4::getVariable(const std::string & varname)
189   {
190      int varid = 0;
191      int grpid = this->getCurrentGroup();
192      CheckError(nc_inq_varid (grpid, varname.c_str(), &varid));
193      return (varid);
194   }
195   
196   int CONetCDF4::getDimension(const std::string & dimname)
197   {
198      int dimid = 0;
199      int grpid = this->getCurrentGroup();
200      CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid));
201      return (dimid);
202   }
203   
204   int CONetCDF4::getUnlimitedDimension(void)
205   {
206      int dimid = 0;
207      int grpid = this->getCurrentGroup();
208      CheckError(nc_inq_unlimdim (grpid, &dimid));
209      return (dimid);
210   }
211   
212   std::vector<std::size_t> CONetCDF4::getDimensions(const std::string & varname)
213   {
214      std::size_t size = 0;
215      std::vector<std::size_t> retvalue;
216      int grpid = this->getCurrentGroup();
217      int varid = this->getVariable(varname);
218      int nbdim = 0, *dimid = NULL;
219
220      CheckError(nc_inq_varndims(grpid, varid, &nbdim));
221      dimid = new int[nbdim]();
222      CheckError(nc_inq_vardimid(grpid, varid, dimid));
223
224      for (int i = 0; i < nbdim; i++)
225      {
226         CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
227         if (size == NC_UNLIMITED)
228             size = UNLIMITED_DIM;
229         retvalue.push_back(size);
230      }
231
232      return (retvalue);
233   }
234   
235   bool CONetCDF4::varExist(const std::string & _varname)
236   {
237      int varid = 0;
238      int grpid = this->getCurrentGroup();
239      return (nc_inq_varid (grpid, _varname.c_str(), &varid) == NC_NOERR);
240   }
241   
242// ----------------- Obtention des informations d'écriture ------------------
243   
244   void CONetCDF4::getWriteDataInfos(const std::string & _varname,
245                                     std::size_t   _record, 
246                                     std::size_t & _array_size,
247                                     std::vector<std::size_t> & _sstart,
248                                     std::vector<std::size_t> & _scount,
249                                     const std::vector<std::size_t> * _start,
250                                     const std::vector<std::size_t> * _count)
251   {
252      std::vector<std::size_t> sizes  = this->getDimensions(_varname);
253      std::vector<std::string> iddims = this->getDimensionsIdList (&_varname);   
254      std::vector<std::size_t>::const_iterator
255         it  = sizes.begin(), end = sizes.end();
256      int i = 0;
257     
258      if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0)
259      {
260         _sstart.push_back(_record);
261         _scount.push_back(1); 
262         if ((_start == NULL) &&
263             (_count == NULL)) i++;
264         it++;
265      }
266
267      for (;it != end; it++)
268      {     
269         if ((_start != NULL) && (_count != NULL))
270         {
271            _sstart.push_back((*_start)[i]);
272            _scount.push_back((*_count)[i]);
273            _array_size *= (*_count)[i];
274            i++;
275         }
276         else
277         {
278            _sstart.push_back(0);
279            _scount.push_back(sizes[i]);
280            _array_size *= sizes[i];
281            i++;
282         }
283      }
284   }
285   
286   // ------------------------- Ecriture des données --------------------------
287     
288   template <>
289      void CONetCDF4::writeData_(int _grpid, int _varid,
290                                const std::vector<std::size_t> & _sstart,
291                                const std::vector<std::size_t> & _scount,
292                                const float * _data)
293   {
294      CheckError(nc_put_vara_float(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
295   }
296   
297   template <>
298      void CONetCDF4::writeData_(int _grpid, int _varid,
299                                const std::vector<std::size_t> & _sstart,
300                                const std::vector<std::size_t> & _scount,
301                                const int * _data)
302   {
303      CheckError(nc_put_vara_int(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
304   }
305   
306   template <>
307      void CONetCDF4::writeData_(int _grpid, int _varid,
308                                const std::vector<std::size_t> & _sstart,
309                                const std::vector<std::size_t> & _scount,
310                                const double * _data)
311   {
312      CheckError(nc_put_vara_double(_grpid, _varid, &(_sstart[0]), &(_scount[0]), _data));       
313   }
314
315   // ------------------------- Ecriture des attributs --------------------------
316
317   template <>
318      void CONetCDF4::writeAttribute_
319         (const std::string & _attname, const double * _value, std::size_t _size, int _grpid, int _varid)
320   {       
321        CheckError(nc_put_att_double(_grpid, _varid, _attname.c_str(), NC_DOUBLE, _size, _value));
322   }
323   
324   template <>
325      void CONetCDF4::writeAttribute_
326         (const std::string & _attname, const float * _value, std::size_t _size, int _grpid, int _varid)
327   {
328       CheckError(nc_put_att_float(_grpid, _varid, _attname.c_str(), NC_FLOAT, _size, _value));
329   }
330   
331   template <>
332      void CONetCDF4::writeAttribute_
333         (const std::string & _attname, const int * _value, std::size_t _size, int _grpid, int _varid)
334   {
335       CheckError(nc_put_att_int(_grpid, _varid, _attname.c_str(), NC_INT, _size, _value));
336   }
337   
338   template <>
339      void CONetCDF4::writeAttribute_
340         (const std::string & _attname, const char * _value, std::size_t _size, int _grpid, int _varid)
341   {
342       CheckError(nc_put_att_text(_grpid, _varid, _attname.c_str(), _size, _value));
343   }
344   
345   void CONetCDF4::writeAttribute
346      (const std::string & _attname, const std::string & _value, const std::string * _varname)
347   {
348      std::vector<char> chart;
349      chart.assign (_value.begin(), _value.end());
350      this->writeAttribute(_attname, chart, _varname);
351   }
352   
353} // namespace io
354} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.