source: XMLIO_V2/dev/dev_rv/src/xmlio/output/onetcdf4.cpp @ 265

Last change on this file since 265 was 265, checked in by hozdoba, 13 years ago

Corrections après tests sur titane

File size: 14.2 KB
Line 
1#include "onetcdf4.hpp"
2
3namespace xmlioserver
4{
5   namespace io
6   {
7      /// ////////////////////// Définitions ////////////////////// ///
8
9      CONetCDF4::CONetCDF4
10         (const StdString & filename, bool exist, const MPI_Comm * comm)
11            : path()
12      {
13         this->wmpi = (comm != NULL);
14         this->initialize(filename, exist, comm);
15      }
16     
17      //---------------------------------------------------------------
18     
19      CONetCDF4::CONetCDF4
20         (const StdString & filename, bool exist, const comm::MPIComm * comm, bool)
21         : path()
22      {
23         this->wmpi = (comm != NULL);
24         MPI_Comm * null_comm = NULL;
25         if (comm == NULL)
26            this->initialize(filename, exist, null_comm);
27         else
28         {
29            MPI_Comm comm_c = MPI_Comm_f2c(*comm);
30            this->initialize(filename, exist, &comm_c);
31         }
32      }
33     
34      //---------------------------------------------------------------
35     
36      CONetCDF4::~CONetCDF4(void)
37      {
38         CheckError(nc_close(this->ncidp));
39      }
40
41      ///--------------------------------------------------------------
42
43      void CONetCDF4::initialize
44         (const StdString & filename, bool exist, const MPI_Comm * comm)
45      {
46         if (!exist)
47         {
48            if (comm != NULL)
49            {
50               CheckError(nc_create_par
51                  (filename.c_str(), NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, &this->ncidp));
52            }
53            else CheckError(nc_create(filename.c_str(), NC_NETCDF4, &this->ncidp));
54         }
55         else
56         {
57            if (comm != NULL)
58               CheckError(nc_open_par
59                  (filename.c_str(), NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, &this->ncidp));
60            else  CheckError(nc_open(filename.c_str(), NC_NETCDF4, &this->ncidp));
61         }
62      }
63     
64      //---------------------------------------------------------------
65     
66      void CONetCDF4::definition_start(void)
67      { 
68         CheckError(nc_redef(this->ncidp));
69      }
70     
71      //---------------------------------------------------------------
72     
73      void CONetCDF4::definition_end(void)
74      { 
75         CheckError(nc_enddef(this->ncidp));
76      }
77     
78      //---------------------------------------------------------------
79     
80      void CONetCDF4::CheckError(int status)
81      {
82         if (status != NC_NOERR)
83         {
84            StdString errormsg (nc_strerror(status)); // fuite mémoire ici ?
85            ERROR("CONetCDF4::CheckError(int status)",
86                  << "[ status = " << status << " ] " << errormsg);
87         }
88      }
89
90      //---------------------------------------------------------------
91     
92      int CONetCDF4::getCurrentGroup(void)
93      {
94         return (this->getGroup(this->getCurrentPath()));
95      }
96     
97      //---------------------------------------------------------------
98     
99      int CONetCDF4::getGroup(const CONetCDF4Path & path)
100      {
101         int retvalue = this->ncidp;
102         
103         CONetCDF4Path::const_iterator
104            it  = path.begin(), end = path.end();
105
106         for (;it != end; it++)
107         {
108            const StdString & groupid = *it;
109            CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue));
110         }
111         return (retvalue);
112      }
113     
114      //---------------------------------------------------------------
115     
116      int CONetCDF4::getVariable(const StdString & varname)
117      {
118         int varid = 0;
119         int grpid = this->getCurrentGroup();
120         CheckError(nc_inq_varid (grpid, varname.c_str(), &varid));
121         return (varid);
122      }
123     
124      //---------------------------------------------------------------
125     
126      int CONetCDF4::getDimension(const StdString & dimname)
127      {
128         int dimid = 0;
129         int grpid = this->getCurrentGroup();
130         CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid));
131         return (dimid);
132      }
133     
134      //---------------------------------------------------------------
135     
136      int CONetCDF4::getUnlimitedDimension(void)
137      {
138         int dimid = 0;
139         int grpid = this->getCurrentGroup();
140         CheckError(nc_inq_unlimdim (grpid, &dimid));
141         return (dimid);
142      }
143     
144      StdString CONetCDF4::getUnlimitedDimensionName(void)
145      {
146         char full_name_in[NC_MAX_NAME +1];
147         int grpid = this->getGroup(path);
148         int dimid = this->getUnlimitedDimension();
149                             
150         if (dimid == -1) return (std::string());
151            CheckError(nc_inq_dimname(grpid, dimid, full_name_in));
152                                         
153         StdString dimname(full_name_in);
154         return (dimname);
155      }
156     
157      //---------------------------------------------------------------
158     
159      std::vector<StdSize> CONetCDF4::getDimensions(const StdString & varname)
160      {
161         StdSize size = 0;
162         std::vector<StdSize> retvalue;
163         int grpid = this->getCurrentGroup();
164         int varid = this->getVariable(varname);
165         int nbdim = 0, *dimid = NULL;
166
167         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
168         dimid = new int[nbdim]();
169         CheckError(nc_inq_vardimid(grpid, varid, dimid));
170
171         for (int i = 0; i < nbdim; i++)
172         {
173            CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
174            if (size == NC_UNLIMITED)
175                size = UNLIMITED_DIM;
176            retvalue.push_back(size);
177         }
178
179         return (retvalue);
180      }
181
182      std::vector<std::string> CONetCDF4::getDimensionsIdList (const std::string * _varname)
183      {
184         char full_name_in[NC_MAX_NAME +1];
185         int nbdim = 0, *dimid = NULL;
186         int grpid = this->getCurrentGroup();
187         int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL;
188         std::vector<std::string> retvalue;
189                                   
190         if (_varname != NULL)
191         {
192            CheckError(nc_inq_varndims(grpid, varid, &nbdim));
193            dimid = new int[nbdim]();
194            CheckError(nc_inq_vardimid(grpid, varid, dimid));
195         }
196         else
197         {
198            CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1));
199            dimid = new int[nbdim]();
200            CheckError(nc_inq_dimids(grpid, NULL, dimid, 1));
201         }
202                                       
203         for (int i = 0; i < nbdim; i++)
204         {
205            CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in));
206            std::string dimname(full_name_in);
207            retvalue.push_back(dimname);
208         }
209         delete [] dimid;
210                                                                                                                                                     
211         return (retvalue);
212      }
213
214
215      //---------------------------------------------------------------
216
217      const CONetCDF4::CONetCDF4Path & CONetCDF4::getCurrentPath(void) const
218      { return (this->path); }
219
220      void CONetCDF4::setCurrentPath(const CONetCDF4Path & path)
221      { this->path = path; }
222
223      //---------------------------------------------------------------
224
225      int CONetCDF4::addGroup(const StdString & name)
226      {
227         int retvalue = 0;
228         int grpid = this->getCurrentGroup();
229         CheckError(nc_def_grp(grpid, const_cast<char*>(name.c_str()), &retvalue));
230         return (retvalue);
231      }
232     
233      //---------------------------------------------------------------
234     
235      int CONetCDF4::addDimension(const StdString& name, const StdSize size)
236      {
237         int retvalue = 0;
238         int grpid = this->getCurrentGroup();
239         if (size != UNLIMITED_DIM)
240            CheckError(nc_def_dim (grpid, name.c_str(), size, &retvalue));
241         else
242            CheckError(nc_def_dim (grpid, name.c_str(), NC_UNLIMITED, &retvalue));
243         return (retvalue);
244      }
245     
246      //---------------------------------------------------------------
247     
248      int CONetCDF4::addVariable(const StdString & name, nc_type type,
249                                  const std::vector<StdString> & dim)
250      {
251         int retvalue = 0;
252         std::vector<int> dimids;
253         int grpid = this->getCurrentGroup();
254         
255         std::vector<StdString>::const_iterator
256            it  = dim.begin(), end = dim.end();
257
258         for (;it != end; it++)
259         {
260            const StdString & dimid = *it;
261            dimids.push_back(this->getDimension(dimid));
262         }
263         CheckError(nc_def_var (grpid, name.c_str(), type, dimids.size(), &(dimids[0]), &retvalue));
264         return (retvalue);
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//         for (StdSize u = 0; u < sstart.size(); u++)
355//            std::cout << "(" << sstart[u] << "," << scount[u]  << ")" ;
356//         std::cout << std::endl;
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, double * data)
365      {
366         CheckError(nc_put_vara_double(grpid, varid, &(sstart[0]), &(scount[0]), data));
367      }
368     
369      //---------------------------------------------------------------
370     
371      template <>
372         void CONetCDF4::writeData_(int grpid, int varid,
373                                    const std::vector<StdSize> & sstart,
374                                    const std::vector<StdSize> & scount, int * data)
375      {
376          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data));
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      }
388
389      //---------------------------------------------------------------
390
391      void CONetCDF4::writeData(const ARRAY(int, 2) data, const StdString & name)
392      {
393         int grpid = this->getCurrentGroup();
394         int varid = this->getVariable(name);
395         StdSize array_size = 1;
396         std::vector<StdSize> sstart, scount;
397
398         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
399         this->writeData_(grpid, varid, sstart, scount, data->data());
400      }
401
402      //---------------------------------------------------------------
403     
404      bool CONetCDF4::varExist(const StdString & varname)
405      {
406         int varid = 0;
407         int grpid = this->getCurrentGroup();
408         return (nc_inq_varid (grpid, varname.c_str(), &varid) == NC_NOERR);
409      }
410
411      ///--------------------------------------------------------------
412   } // namespace io
413} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.