source: XMLIO_V2/dev/common/src/output/onetcdf4.cpp @ 300

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

nouvelle version de developpement de xios

  • nouvelle interface fortran
  • recodage complet de la couche de communication
  • et bien d'autres choses...

YM

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