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

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

Suite nouvelle interface fortran

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