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 @ 3408

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

importing initial XIOS vendor drop

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.0 KB
Line 
1#include "onetcdf4.hpp"
2#include "group_template_impl.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 retvalue = 0;
243         std::vector<int> dimids;
244         int grpid = this->getCurrentGroup();
245         
246         std::vector<StdString>::const_iterator
247            it  = dim.begin(), end = dim.end();
248
249         for (;it != end; it++)
250         {
251            const StdString & dimid = *it;
252            dimids.push_back(this->getDimension(dimid));
253         }
254         CheckError(nc_def_var (grpid, name.c_str(), type, dimids.size(), &(dimids[0]), &retvalue));
255         return (retvalue);
256      }
257
258      //---------------------------------------------------------------
259
260      template <>
261         void CONetCDF4::addAttribute
262            (const StdString & name, const StdString & value, const StdString * varname )
263      {
264         int grpid = this->getCurrentGroup();
265         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
266         CheckError(nc_put_att(grpid, varid, name.c_str(), NC_CHAR, value.size()+1, value.c_str()));
267         //CheckError(nc_put_att_string(grpid, varid, name.c_str(), 1, &str));
268      }
269     
270      //---------------------------------------------------------------
271     
272      template <>
273         void CONetCDF4::addAttribute
274            (const StdString & name, const double & value, const StdString * varname )
275      {
276         int grpid = this->getCurrentGroup();
277         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
278         CheckError(nc_put_att_double(grpid, varid, name.c_str(), NC_DOUBLE,1, &value));
279      }
280     
281      //---------------------------------------------------------------
282     
283      template <>
284         void CONetCDF4::addAttribute
285            (const StdString & name, const float & value, const StdString * varname )
286      {
287         int grpid = this->getCurrentGroup();
288         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
289         CheckError(nc_put_att_float(grpid, varid, name.c_str(), NC_FLOAT, 1, &value));
290      }
291     
292      //---------------------------------------------------------------
293     
294      template <>
295         void CONetCDF4::addAttribute
296            (const StdString & name, const int & value, const StdString * varname )
297      {
298         int grpid = this->getCurrentGroup();
299         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
300         CheckError(nc_put_att_int(grpid, varid, name.c_str(), NC_INT,1, &value));
301      }
302
303      //---------------------------------------------------------------
304
305      void CONetCDF4::getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size,
306                                        std::vector<StdSize> & sstart,
307                                        std::vector<StdSize> & scount,
308                                        const std::vector<StdSize> * start,
309                                        const std::vector<StdSize> * count)
310      {   
311         std::vector<std::size_t> sizes  = this->getDimensions(name);
312         std::vector<std::string> iddims = this->getDimensionsIdList (&name);   
313         std::vector<std::size_t>::const_iterator
314            it  = sizes.begin(), end = sizes.end();
315         int i = 0;
316     
317         if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0)
318         {
319            sstart.push_back(record);
320            scount.push_back(1); 
321            if ((start == NULL) &&
322                (count == NULL)) i++;
323            it++;
324         }
325
326         for (;it != end; it++)
327         {     
328            if ((start != NULL) && (count != NULL))
329            {
330               sstart.push_back((*start)[i]);
331               scount.push_back((*count)[i]);
332               array_size *= (*count)[i];
333               i++;
334            }
335            else
336            {
337               sstart.push_back(0);
338               scount.push_back(sizes[i]);
339               array_size *= sizes[i];
340               i++;
341            }
342         }
343         
344      }
345
346      //---------------------------------------------------------------
347
348      template <>
349         void CONetCDF4::writeData_(int grpid, int varid,
350                                    const std::vector<StdSize> & sstart,
351                                    const std::vector<StdSize> & scount, double * data)
352      {
353         CheckError(nc_put_vara_double(grpid, varid, &(sstart[0]), &(scount[0]), data));
354//         sync() ;
355      }
356     
357      //---------------------------------------------------------------
358     
359      template <>
360         void CONetCDF4::writeData_(int grpid, int varid,
361                                    const std::vector<StdSize> & sstart,
362                                    const std::vector<StdSize> & scount, int * data)
363      {
364          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data));
365//          sync() ;
366      }
367     
368      //---------------------------------------------------------------
369     
370      template <>
371         void CONetCDF4::writeData_(int grpid, int varid,
372                                    const std::vector<StdSize> & sstart,
373                                    const std::vector<StdSize> & scount, float * data)
374      {
375          CheckError(nc_put_vara_float(grpid, varid, &(sstart[0]), &(scount[0]), data));
376//          sync() ;
377      }
378
379      //---------------------------------------------------------------
380
381      void CONetCDF4::writeData(const ARRAY(int, 2) data, const StdString & name)
382      {
383         int grpid = this->getCurrentGroup();
384         int varid = this->getVariable(name);
385         StdSize array_size = 1;
386         std::vector<StdSize> sstart, scount;
387
388         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
389         this->writeData_(grpid, varid, sstart, scount, data->data());
390      }
391
392      //---------------------------------------------------------------
393     
394      bool CONetCDF4::varExist(const StdString & varname)
395      {
396         int varid = 0;
397         int grpid = this->getCurrentGroup();
398         return (nc_inq_varid (grpid, varname.c_str(), &varid) == NC_NOERR);
399      }
400
401      void CONetCDF4::sync(void)
402      {
403         CheckError(nc_sync(this->ncidp)) ;
404      } 
405      ///--------------------------------------------------------------
406 } // namespace xios
Note: See TracBrowser for help on using the repository browser.