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

Last change on this file since 142 was 142, checked in by hozdoba, 11 years ago
File size: 12.1 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)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         BOOST_FOREACH(StdString groupid, path)
86            CheckError(nc_inq_ncid(retvalue, const_cast<char*>(groupid.c_str()), &retvalue));
87         return (retvalue);
88      }
89
90      int CONetCDF4::getVariable(const StdString & varname)
91      {
92         int varid = 0;
93         int grpid = this->getCurrentGroup();
94         CheckError(nc_inq_varid (grpid, varname.c_str(), &varid));
95         return (varid);
96      }
97
98      int CONetCDF4::getDimension(const StdString & dimname)
99      {
100         int dimid = 0;
101         int grpid = this->getCurrentGroup();
102         CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid));
103         return (dimid);
104      }
105
106      int CONetCDF4::getUnlimitedDimension(void)
107      {
108         int dimid = 0;
109         int grpid = this->getCurrentGroup();
110         CheckError(nc_inq_unlimdim (grpid, &dimid));
111         return (dimid);
112      }
113
114      std::vector<StdSize> CONetCDF4::getDimensions(const StdString & varname)
115      {
116         StdSize size = 0;
117         std::vector<StdSize> retvalue;
118         int grpid = this->getCurrentGroup();
119         int varid = this->getVariable(varname);
120         int nbdim = 0, *dimid = NULL;
121
122         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
123         dimid = new int[nbdim]();
124         CheckError(nc_inq_vardimid(grpid, varid, dimid));
125
126         for (int i = 0; i < nbdim; i++)
127         {
128            CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
129            if (size == NC_UNLIMITED)
130                size = UNLIMITED_DIM;
131            retvalue.push_back(size);
132         }
133
134         return (retvalue);
135      }
136
137      //---------------------------------------------------------------
138
139      const CONetCDF4::CONetCDF4Path & CONetCDF4::getCurrentPath(void) const
140      { return (this->path); }
141
142      void CONetCDF4::setCurrentPath(const CONetCDF4Path & path)
143      { this->path = path; }
144
145      //---------------------------------------------------------------
146
147      int CONetCDF4::addGroup(const StdString & name)
148      {
149         int retvalue = 0;
150         int grpid = this->getCurrentGroup();
151         CheckError(nc_def_grp(grpid, const_cast<char*>(name.c_str()), &retvalue));
152         return (retvalue);
153      }
154
155      int CONetCDF4::addDimension(const StdString& name, const StdSize size)
156      {
157         int retvalue = 0;
158         int grpid = this->getCurrentGroup();
159         if (size != UNLIMITED_DIM)
160            CheckError(nc_def_dim (grpid, name.c_str(), size, &retvalue));
161         else
162            CheckError(nc_def_dim (grpid, name.c_str(), NC_UNLIMITED, &retvalue));
163         return (retvalue);
164      }
165
166      int CONetCDF4::addVariable(const StdString & name, nc_type type,
167                                  const std::vector<StdString> & dim)
168      {
169         int retvalue = 0;
170         std::vector<int> dimids;
171         int grpid = this->getCurrentGroup();
172         BOOST_FOREACH(StdString dimid, dim)
173            dimids.push_back(this->getDimension(dimid));
174         CheckError(nc_def_var (grpid, name.c_str(), type, dimids.size(), &(dimids[0]), &retvalue));
175         return (retvalue);
176      }
177
178      //---------------------------------------------------------------
179
180      template <>
181         void CONetCDF4::addAttribute
182            (const StdString & name, const StdString & value, const StdString * varname )
183      {
184         int grpid = this->getCurrentGroup();
185         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
186         CheckError(nc_put_att(grpid, varid, name.c_str(), NC_CHAR, value.size()+1, value.c_str()));
187         //CheckError(nc_put_att_string(grpid, varid, name.c_str(), 1, &str));
188      }
189
190      template <>
191         void CONetCDF4::addAttribute
192            (const StdString & name, const double & value, const StdString * varname )
193      {
194         int grpid = this->getCurrentGroup();
195         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
196         CheckError(nc_put_att_double(grpid, varid, name.c_str(), NC_DOUBLE,1, &value));
197      }
198
199      template <>
200         void CONetCDF4::addAttribute
201            (const StdString & name, const float & value, const StdString * varname )
202      {
203         int grpid = this->getCurrentGroup();
204         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
205         CheckError(nc_put_att_float(grpid, varid, name.c_str(), NC_FLOAT, 1, &value));
206      }
207
208      template <>
209         void CONetCDF4::addAttribute
210            (const StdString & name, const int & value, const StdString * varname )
211      {
212         int grpid = this->getCurrentGroup();
213         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
214         CheckError(nc_put_att_int(grpid, varid, name.c_str(), NC_INT,1, &value));
215      }
216
217      //---------------------------------------------------------------
218
219      void CONetCDF4::getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size,
220                                        std::vector<StdSize> & sstart,
221                                        std::vector<StdSize> & scount,
222                                        const std::vector<StdSize> * start,
223                                        const std::vector<StdSize> * count)
224      {
225         std::vector<StdSize> sizes = this->getDimensions(name);
226         int i = 0;
227         BOOST_FOREACH(StdSize s, sizes)
228         {
229            if ((start != NULL) && (count != NULL))
230            {
231               if (s == UNLIMITED_DIM)
232               {
233                  sstart.push_back(record);
234                  scount.push_back(1);
235               }
236               else
237               {
238                  sstart.push_back((*start)[i]);
239                  scount.push_back((*count)[i]);
240                  array_size *= (*count)[i];
241                  i++;
242               }
243            }
244            else
245            {
246               if (s == UNLIMITED_DIM)
247               {
248                  sstart.push_back(record);
249                  scount.push_back(1);
250               }
251               else
252               {
253                  sstart.push_back(0);
254                  scount.push_back(sizes[i]);
255                  array_size *= sizes[i];
256               }
257               i++;
258            }
259         }
260      }
261
262      template <>
263         void CONetCDF4::writeData(const ARRAY(double, 1) data, const StdString & name,
264                                   bool collective, StdSize record,
265                                   const std::vector<StdSize> * start,
266                                   const std::vector<StdSize> * count)
267      {
268         int grpid = this->getCurrentGroup();
269         int varid = this->getVariable(name);
270         StdSize array_size = 1;
271         std::vector<StdSize> sstart, scount;
272
273         if (this->wmpi && collective)
274            CheckError(nc_var_par_access(grpid, varid, NC_COLLECTIVE));
275         if (this->wmpi && !collective)
276            CheckError(nc_var_par_access(grpid, varid, NC_INDEPENDENT));
277
278         this->getWriteDataInfos
279         (name, record, array_size,  sstart, scount, start, count);
280
281          //BOOST_FOREACH(StdSize  _s, sstart) std::cout << _s << std::endl;
282          //BOOST_FOREACH(StdSize __s, scount) std::cout <<__s << std::endl;
283          //std::cout << array_size << std::endl;
284          CheckError(nc_put_vara_double(grpid, varid, &(sstart[0]), &(scount[0]), data->data()));
285      }
286
287      template <>
288         void CONetCDF4::writeData(const ARRAY(int, 1) data, const StdString & name,
289                                   bool collective, StdSize record,
290                                   const std::vector<StdSize> * start,
291                                   const std::vector<StdSize> * count)
292      {
293         int grpid = this->getCurrentGroup();
294         int varid = this->getVariable(name);
295         StdSize array_size = 1;
296         std::vector<StdSize> sstart, scount;
297
298         if (this->wmpi && collective)
299            CheckError(nc_var_par_access(grpid, varid, NC_COLLECTIVE));
300         if (this->wmpi && !collective)
301            CheckError(nc_var_par_access(grpid, varid, NC_INDEPENDENT));
302
303         this->getWriteDataInfos
304         (name, record, array_size,  sstart, scount, start, count);
305          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data->data()));
306      }
307
308      template <>
309         void CONetCDF4::writeData(const ARRAY(float, 1) data, const StdString & name,
310                                   bool collective, StdSize record,
311                                   const std::vector<StdSize> * start,
312                                   const std::vector<StdSize> * count)
313      {
314         int grpid = this->getCurrentGroup();
315         int varid = this->getVariable(name);
316         StdSize array_size = 1;
317         std::vector<StdSize> sstart, scount;
318
319         if (this->wmpi && collective)
320            CheckError(nc_var_par_access(grpid, varid, NC_COLLECTIVE));
321         if (this->wmpi && !collective)
322            CheckError(nc_var_par_access(grpid, varid, NC_INDEPENDENT));
323
324         this->getWriteDataInfos
325         (name, record, array_size,  sstart, scount, start, count);
326          CheckError(nc_put_vara_float(grpid, varid, &(sstart[0]), &(scount[0]), data->data()));
327      }
328
329      void CONetCDF4::writeData(const boost::shared_ptr<CMask> data, const StdString & name)
330      {
331         int grpid = this->getCurrentGroup();
332         int varid = this->getVariable(name);
333         StdSize array_size = 1;
334         std::vector<StdSize> sstart, scount;
335
336         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
337          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data->getData()));
338      }
339
340      ///--------------------------------------------------------------
341   } // namespace io
342} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.