New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
onetcdf4.cpp in vendors/XIOS/current/src/output – NEMO

source: vendors/XIOS/current/src/output/onetcdf4.cpp @ 3472

Last change on this file since 3472 was 3472, checked in by rblod, 12 years ago

Load XIOS_SRC into vendors/XIOS/current.

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