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

Last change on this file since 286 was 286, checked in by ymipsl, 13 years ago

reprise en main de la version de H. Ozdoba. Correction de différentes erreurs de conception et bug.
Version NEMO operationnel en client/server, interoperabilita avec OASIS, reconstition de fichiers via netcdf4/HDF5

YM

File size: 14.5 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         std::cout<<"--> Var "<<name.c_str()<<std::endl ;
258         CheckError(nc_def_var (grpid, name.c_str(), type, dimids.size(), &(dimids[0]), &retvalue));
259         return (retvalue);
260      }
261
262      //---------------------------------------------------------------
263
264      template <>
265         void CONetCDF4::addAttribute
266            (const StdString & name, const StdString & value, const StdString * varname )
267      {
268         int grpid = this->getCurrentGroup();
269         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
270         CheckError(nc_put_att(grpid, varid, name.c_str(), NC_CHAR, value.size()+1, value.c_str()));
271         //CheckError(nc_put_att_string(grpid, varid, name.c_str(), 1, &str));
272      }
273     
274      //---------------------------------------------------------------
275     
276      template <>
277         void CONetCDF4::addAttribute
278            (const StdString & name, const double & value, const StdString * varname )
279      {
280         int grpid = this->getCurrentGroup();
281         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
282         CheckError(nc_put_att_double(grpid, varid, name.c_str(), NC_DOUBLE,1, &value));
283      }
284     
285      //---------------------------------------------------------------
286     
287      template <>
288         void CONetCDF4::addAttribute
289            (const StdString & name, const float & value, const StdString * varname )
290      {
291         int grpid = this->getCurrentGroup();
292         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
293         CheckError(nc_put_att_float(grpid, varid, name.c_str(), NC_FLOAT, 1, &value));
294      }
295     
296      //---------------------------------------------------------------
297     
298      template <>
299         void CONetCDF4::addAttribute
300            (const StdString & name, const int & value, const StdString * varname )
301      {
302         int grpid = this->getCurrentGroup();
303         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
304         CheckError(nc_put_att_int(grpid, varid, name.c_str(), NC_INT,1, &value));
305      }
306
307      //---------------------------------------------------------------
308
309      void CONetCDF4::getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size,
310                                        std::vector<StdSize> & sstart,
311                                        std::vector<StdSize> & scount,
312                                        const std::vector<StdSize> * start,
313                                        const std::vector<StdSize> * count)
314      {   
315         std::vector<std::size_t> sizes  = this->getDimensions(name);
316         std::vector<std::string> iddims = this->getDimensionsIdList (&name);   
317         std::vector<std::size_t>::const_iterator
318            it  = sizes.begin(), end = sizes.end();
319         int i = 0;
320     
321         if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0)
322         {
323            sstart.push_back(record);
324            scount.push_back(1); 
325            if ((start == NULL) &&
326                (count == NULL)) i++;
327            it++;
328         }
329
330         for (;it != end; it++)
331         {     
332            if ((start != NULL) && (count != NULL))
333            {
334               sstart.push_back((*start)[i]);
335               scount.push_back((*count)[i]);
336               array_size *= (*count)[i];
337               i++;
338            }
339            else
340            {
341               sstart.push_back(0);
342               scount.push_back(sizes[i]);
343               array_size *= sizes[i];
344               i++;
345            }
346         }
347         
348//         if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0)
349//         {
350//            if (array_size==0) scount[0]=0 ;
351//         }         
352//         for (StdSize u = 0; u < sstart.size(); u++)
353//            std::cout << "(" << sstart[u] << "," << scount[u]  << ")" ;
354//         std::cout << std::endl;
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, double * data)
363      {
364         CheckError(nc_put_vara_double(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, int * data)
374      {
375          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data));
376//          sync() ;
377      }
378     
379      //---------------------------------------------------------------
380     
381      template <>
382         void CONetCDF4::writeData_(int grpid, int varid,
383                                    const std::vector<StdSize> & sstart,
384                                    const std::vector<StdSize> & scount, float * data)
385      {
386          CheckError(nc_put_vara_float(grpid, varid, &(sstart[0]), &(scount[0]), data));
387//          sync() ;
388      }
389
390      //---------------------------------------------------------------
391
392      void CONetCDF4::writeData(const ARRAY(int, 2) data, const StdString & name)
393      {
394         int grpid = this->getCurrentGroup();
395         int varid = this->getVariable(name);
396         StdSize array_size = 1;
397         std::vector<StdSize> sstart, scount;
398
399         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
400         this->writeData_(grpid, varid, sstart, scount, data->data());
401      }
402
403      //---------------------------------------------------------------
404     
405      bool CONetCDF4::varExist(const StdString & varname)
406      {
407         int varid = 0;
408         int grpid = this->getCurrentGroup();
409         return (nc_inq_varid (grpid, varname.c_str(), &varid) == NC_NOERR);
410      }
411
412      void CONetCDF4::sync(void)
413      {
414       
415         comm::CMPIManager::Barrier(comm::CMPIManager::GetCommServer());
416         CheckError(nc_sync(this->ncidp)) ;
417      } 
418      ///--------------------------------------------------------------
419   } // namespace io
420} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.