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

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