source: XIOS/trunk/src/output/onetcdf4.cpp @ 334

Last change on this file since 334 was 314, checked in by ymipsl, 12 years ago

Removing obsolete files and some cleaning...

YM

File size: 14.0 KB
Line 
1#include "onetcdf4.hpp"
2#include "group_template_impl.hpp"
3
4namespace xmlioserver
5{
6   namespace io
7   {
8      /// ////////////////////// Définitions ////////////////////// ///
9
10      CONetCDF4::CONetCDF4
11         (const StdString & filename, bool exist, const MPI_Comm * comm, bool multifile)
12            : path()
13      {
14         this->wmpi = (comm != NULL) && !multifile;
15         this->initialize(filename, exist, comm,multifile);
16      }
17     
18      //---------------------------------------------------------------
19     
20     
21
22      CONetCDF4::~CONetCDF4(void)
23      {
24//         CheckError(nc_close(this->ncidp));
25      }
26
27      ///--------------------------------------------------------------
28
29      void CONetCDF4::initialize
30         (const StdString & filename, bool exist, const MPI_Comm * comm, bool multifile)
31      {
32         if (!exist)
33         {
34            if (comm != NULL)
35            {
36               if (!multifile) CheckError(nc_create_par(filename.c_str(), NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, &this->ncidp));
37               else CheckError(nc_create(filename.c_str(), NC_NETCDF4, &this->ncidp));
38            }
39            else CheckError(nc_create(filename.c_str(), NC_NETCDF4, &this->ncidp));
40         }
41         else
42         {
43            if (comm != NULL)
44            {
45               if (!multifile) CheckError(nc_open_par(filename.c_str(), NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, &this->ncidp));
46               else CheckError(nc_open(filename.c_str(), NC_NETCDF4, &this->ncidp));
47            }
48            else  CheckError(nc_open(filename.c_str(), NC_NETCDF4, &this->ncidp));
49         }
50      }
51     
52      void CONetCDF4::close()
53      {
54        CheckError(nc_close(this->ncidp));
55      }
56     
57      //---------------------------------------------------------------
58     
59      void CONetCDF4::definition_start(void)
60      { 
61         CheckError(nc_redef(this->ncidp));
62      }
63     
64      //---------------------------------------------------------------
65     
66      void CONetCDF4::definition_end(void)
67      { 
68         CheckError(nc_enddef(this->ncidp));
69      }
70     
71      //---------------------------------------------------------------
72     
73      void CONetCDF4::CheckError(int status)
74      {
75         if (status != NC_NOERR)
76         {
77            StdString errormsg (nc_strerror(status)); // fuite mémoire ici ?
78            ERROR("CONetCDF4::CheckError(int status)",
79                  << "[ status = " << status << " ] " << errormsg);
80         }
81      }
82
83      //---------------------------------------------------------------
84     
85      int CONetCDF4::getCurrentGroup(void)
86      {
87         return (this->getGroup(this->getCurrentPath()));
88      }
89     
90      //---------------------------------------------------------------
91     
92      int CONetCDF4::getGroup(const CONetCDF4Path & path)
93      {
94         int retvalue = this->ncidp;
95         
96         CONetCDF4Path::const_iterator
97            it  = path.begin(), end = path.end();
98
99         for (;it != end; it++)
100         {
101            const StdString & groupid = *it;
102            CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue));
103         }
104         return (retvalue);
105      }
106     
107      //---------------------------------------------------------------
108     
109      int CONetCDF4::getVariable(const StdString & varname)
110      {
111         int varid = 0;
112         int grpid = this->getCurrentGroup();
113         CheckError(nc_inq_varid (grpid, varname.c_str(), &varid));
114         return (varid);
115      }
116     
117      //---------------------------------------------------------------
118     
119      int CONetCDF4::getDimension(const StdString & dimname)
120      {
121         int dimid = 0;
122         int grpid = this->getCurrentGroup();
123         CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid));
124         return (dimid);
125      }
126     
127      //---------------------------------------------------------------
128     
129      int CONetCDF4::getUnlimitedDimension(void)
130      {
131         int dimid = 0;
132         int grpid = this->getCurrentGroup();
133         CheckError(nc_inq_unlimdim (grpid, &dimid));
134         return (dimid);
135      }
136     
137      StdString CONetCDF4::getUnlimitedDimensionName(void)
138      {
139         char full_name_in[NC_MAX_NAME +1];
140         int grpid = this->getGroup(path);
141         int dimid = this->getUnlimitedDimension();
142                             
143         if (dimid == -1) return (std::string());
144            CheckError(nc_inq_dimname(grpid, dimid, full_name_in));
145                                         
146         StdString dimname(full_name_in);
147         return (dimname);
148      }
149     
150      //---------------------------------------------------------------
151     
152      std::vector<StdSize> CONetCDF4::getDimensions(const StdString & varname)
153      {
154         StdSize size = 0;
155         std::vector<StdSize> retvalue;
156         int grpid = this->getCurrentGroup();
157         int varid = this->getVariable(varname);
158         int nbdim = 0, *dimid = NULL;
159
160         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
161         dimid = new int[nbdim]();
162         CheckError(nc_inq_vardimid(grpid, varid, dimid));
163
164         for (int i = 0; i < nbdim; i++)
165         {
166            CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
167            if (size == NC_UNLIMITED)
168                size = UNLIMITED_DIM;
169            retvalue.push_back(size);
170         }
171
172         return (retvalue);
173      }
174
175      std::vector<std::string> CONetCDF4::getDimensionsIdList (const std::string * _varname)
176      {
177         char full_name_in[NC_MAX_NAME +1];
178         int nbdim = 0, *dimid = NULL;
179         int grpid = this->getCurrentGroup();
180         int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
181         std::vector<std::string> retvalue;
182                                   
183         if (_varname != NULL)
184         {
185            CheckError(nc_inq_varndims(grpid, varid, &nbdim));
186            dimid = new int[nbdim]();
187            CheckError(nc_inq_vardimid(grpid, varid, dimid));
188         }
189         else
190         {
191            CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
192            dimid = new int[nbdim]();
193            CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
194         }
195                                       
196         for (int i = 0; i < nbdim; i++)
197         {
198            CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
199            std::string dimname(full_name_in);
200            retvalue.push_back(dimname);
201         }
202         delete [] dimid;
203                                                                                                                                                     
204         return (retvalue);
205      }
206
207
208      //---------------------------------------------------------------
209
210      const CONetCDF4::CONetCDF4Path & CONetCDF4::getCurrentPath(void) const
211      { return (this->path); }
212
213      void CONetCDF4::setCurrentPath(const CONetCDF4Path & path)
214      { this->path = path; }
215
216      //---------------------------------------------------------------
217
218      int CONetCDF4::addGroup(const StdString & name)
219      {
220         int retvalue = 0;
221         int grpid = this->getCurrentGroup();
222         CheckError(nc_def_grp(grpid, const_cast<char*>(name.c_str()), &retvalue));
223         return (retvalue);
224      }
225     
226      //---------------------------------------------------------------
227     
228      int CONetCDF4::addDimension(const StdString& name, const StdSize size)
229      {
230         int retvalue = 0;
231         int grpid = this->getCurrentGroup();
232         if (size != UNLIMITED_DIM)
233            CheckError(nc_def_dim (grpid, name.c_str(), size, &retvalue));
234         else
235            CheckError(nc_def_dim (grpid, name.c_str(), NC_UNLIMITED, &retvalue));
236         return (retvalue);
237      }
238     
239      //---------------------------------------------------------------
240     
241      int CONetCDF4::addVariable(const StdString & name, nc_type type,
242                                  const std::vector<StdString> & dim)
243      {
244         int retvalue = 0;
245         std::vector<int> dimids;
246         int grpid = this->getCurrentGroup();
247         
248         std::vector<StdString>::const_iterator
249            it  = dim.begin(), end = dim.end();
250
251         for (;it != end; it++)
252         {
253            const StdString & dimid = *it;
254            dimids.push_back(this->getDimension(dimid));
255         }
256         CheckError(nc_def_var (grpid, name.c_str(), type, dimids.size(), &(dimids[0]), &retvalue));
257         return (retvalue);
258      }
259
260      //---------------------------------------------------------------
261
262      template <>
263         void CONetCDF4::addAttribute
264            (const StdString & name, const StdString & value, const StdString * varname )
265      {
266         int grpid = this->getCurrentGroup();
267         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
268         CheckError(nc_put_att(grpid, varid, name.c_str(), NC_CHAR, value.size()+1, value.c_str()));
269         //CheckError(nc_put_att_string(grpid, varid, name.c_str(), 1, &str));
270      }
271     
272      //---------------------------------------------------------------
273     
274      template <>
275         void CONetCDF4::addAttribute
276            (const StdString & name, const double & value, const StdString * varname )
277      {
278         int grpid = this->getCurrentGroup();
279         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
280         CheckError(nc_put_att_double(grpid, varid, name.c_str(), NC_DOUBLE,1, &value));
281      }
282     
283      //---------------------------------------------------------------
284     
285      template <>
286         void CONetCDF4::addAttribute
287            (const StdString & name, const float & value, const StdString * varname )
288      {
289         int grpid = this->getCurrentGroup();
290         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
291         CheckError(nc_put_att_float(grpid, varid, name.c_str(), NC_FLOAT, 1, &value));
292      }
293     
294      //---------------------------------------------------------------
295     
296      template <>
297         void CONetCDF4::addAttribute
298            (const StdString & name, const int & value, const StdString * varname )
299      {
300         int grpid = this->getCurrentGroup();
301         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
302         CheckError(nc_put_att_int(grpid, varid, name.c_str(), NC_INT,1, &value));
303      }
304
305      //---------------------------------------------------------------
306
307      void CONetCDF4::getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size,
308                                        std::vector<StdSize> & sstart,
309                                        std::vector<StdSize> & scount,
310                                        const std::vector<StdSize> * start,
311                                        const std::vector<StdSize> * count)
312      {   
313         std::vector<std::size_t> sizes  = this->getDimensions(name);
314         std::vector<std::string> iddims = this->getDimensionsIdList (&name);   
315         std::vector<std::size_t>::const_iterator
316            it  = sizes.begin(), end = sizes.end();
317         int i = 0;
318     
319         if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0)
320         {
321            sstart.push_back(record);
322            scount.push_back(1); 
323            if ((start == NULL) &&
324                (count == NULL)) i++;
325            it++;
326         }
327
328         for (;it != end; it++)
329         {     
330            if ((start != NULL) && (count != NULL))
331            {
332               sstart.push_back((*start)[i]);
333               scount.push_back((*count)[i]);
334               array_size *= (*count)[i];
335               i++;
336            }
337            else
338            {
339               sstart.push_back(0);
340               scount.push_back(sizes[i]);
341               array_size *= sizes[i];
342               i++;
343            }
344         }
345         
346      }
347
348      //---------------------------------------------------------------
349
350      template <>
351         void CONetCDF4::writeData_(int grpid, int varid,
352                                    const std::vector<StdSize> & sstart,
353                                    const std::vector<StdSize> & scount, double * data)
354      {
355         CheckError(nc_put_vara_double(grpid, varid, &(sstart[0]), &(scount[0]), data));
356//         sync() ;
357      }
358     
359      //---------------------------------------------------------------
360     
361      template <>
362         void CONetCDF4::writeData_(int grpid, int varid,
363                                    const std::vector<StdSize> & sstart,
364                                    const std::vector<StdSize> & scount, int * data)
365      {
366          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data));
367//          sync() ;
368      }
369     
370      //---------------------------------------------------------------
371     
372      template <>
373         void CONetCDF4::writeData_(int grpid, int varid,
374                                    const std::vector<StdSize> & sstart,
375                                    const std::vector<StdSize> & scount, float * data)
376      {
377          CheckError(nc_put_vara_float(grpid, varid, &(sstart[0]), &(scount[0]), data));
378//          sync() ;
379      }
380
381      //---------------------------------------------------------------
382
383      void CONetCDF4::writeData(const ARRAY(int, 2) data, const StdString & name)
384      {
385         int grpid = this->getCurrentGroup();
386         int varid = this->getVariable(name);
387         StdSize array_size = 1;
388         std::vector<StdSize> sstart, scount;
389
390         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
391         this->writeData_(grpid, varid, sstart, scount, data->data());
392      }
393
394      //---------------------------------------------------------------
395     
396      bool CONetCDF4::varExist(const StdString & varname)
397      {
398         int varid = 0;
399         int grpid = this->getCurrentGroup();
400         return (nc_inq_varid (grpid, varname.c_str(), &varid) == NC_NOERR);
401      }
402
403      void CONetCDF4::sync(void)
404      {
405         CheckError(nc_sync(this->ncidp)) ;
406      } 
407      ///--------------------------------------------------------------
408   } // namespace io
409} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.