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

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

Préparation nouvelle arborescence

File size: 12.4 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_MPIPOSIX, *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      //---------------------------------------------------------------
145     
146      std::vector<StdSize> CONetCDF4::getDimensions(const StdString & varname)
147      {
148         StdSize size = 0;
149         std::vector<StdSize> retvalue;
150         int grpid = this->getCurrentGroup();
151         int varid = this->getVariable(varname);
152         int nbdim = 0, *dimid = NULL;
153
154         CheckError(nc_inq_varndims(grpid, varid, &nbdim));
155         dimid = new int[nbdim]();
156         CheckError(nc_inq_vardimid(grpid, varid, dimid));
157
158         for (int i = 0; i < nbdim; i++)
159         {
160            CheckError(nc_inq_dimlen (grpid, dimid[i], &size));
161            if (size == NC_UNLIMITED)
162                size = UNLIMITED_DIM;
163            retvalue.push_back(size);
164         }
165
166         return (retvalue);
167      }
168
169      //---------------------------------------------------------------
170
171      const CONetCDF4::CONetCDF4Path & CONetCDF4::getCurrentPath(void) const
172      { return (this->path); }
173
174      void CONetCDF4::setCurrentPath(const CONetCDF4Path & path)
175      { this->path = path; }
176
177      //---------------------------------------------------------------
178
179      int CONetCDF4::addGroup(const StdString & name)
180      {
181         int retvalue = 0;
182         int grpid = this->getCurrentGroup();
183         CheckError(nc_def_grp(grpid, const_cast<char*>(name.c_str()), &retvalue));
184         return (retvalue);
185      }
186     
187      //---------------------------------------------------------------
188     
189      int CONetCDF4::addDimension(const StdString& name, const StdSize size)
190      {
191         int retvalue = 0;
192         int grpid = this->getCurrentGroup();
193         if (size != UNLIMITED_DIM)
194            CheckError(nc_def_dim (grpid, name.c_str(), size, &retvalue));
195         else
196            CheckError(nc_def_dim (grpid, name.c_str(), NC_UNLIMITED, &retvalue));
197         return (retvalue);
198      }
199     
200      //---------------------------------------------------------------
201     
202      int CONetCDF4::addVariable(const StdString & name, nc_type type,
203                                  const std::vector<StdString> & dim)
204      {
205         int retvalue = 0;
206         std::vector<int> dimids;
207         int grpid = this->getCurrentGroup();
208         
209         std::vector<StdString>::const_iterator
210            it  = dim.begin(), end = dim.end();
211
212         for (;it != end; it++)
213         {
214            const StdString & dimid = *it;
215            dimids.push_back(this->getDimension(dimid));
216         }
217         CheckError(nc_def_var (grpid, name.c_str(), type, dimids.size(), &(dimids[0]), &retvalue));
218         return (retvalue);
219      }
220
221      //---------------------------------------------------------------
222
223      template <>
224         void CONetCDF4::addAttribute
225            (const StdString & name, const StdString & value, const StdString * varname )
226      {
227         int grpid = this->getCurrentGroup();
228         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
229         CheckError(nc_put_att(grpid, varid, name.c_str(), NC_CHAR, value.size()+1, value.c_str()));
230         //CheckError(nc_put_att_string(grpid, varid, name.c_str(), 1, &str));
231      }
232     
233      //---------------------------------------------------------------
234     
235      template <>
236         void CONetCDF4::addAttribute
237            (const StdString & name, const double & value, const StdString * varname )
238      {
239         int grpid = this->getCurrentGroup();
240         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
241         CheckError(nc_put_att_double(grpid, varid, name.c_str(), NC_DOUBLE,1, &value));
242      }
243     
244      //---------------------------------------------------------------
245     
246      template <>
247         void CONetCDF4::addAttribute
248            (const StdString & name, const float & value, const StdString * varname )
249      {
250         int grpid = this->getCurrentGroup();
251         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
252         CheckError(nc_put_att_float(grpid, varid, name.c_str(), NC_FLOAT, 1, &value));
253      }
254     
255      //---------------------------------------------------------------
256     
257      template <>
258         void CONetCDF4::addAttribute
259            (const StdString & name, const int & value, const StdString * varname )
260      {
261         int grpid = this->getCurrentGroup();
262         int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname);
263         CheckError(nc_put_att_int(grpid, varid, name.c_str(), NC_INT,1, &value));
264      }
265
266      //---------------------------------------------------------------
267
268      void CONetCDF4::getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size,
269                                        std::vector<StdSize> & sstart,
270                                        std::vector<StdSize> & scount,
271                                        const std::vector<StdSize> * start,
272                                        const std::vector<StdSize> * count)
273      {
274         std::vector<StdSize> sizes = this->getDimensions(name);       
275         std::vector<StdSize>::const_iterator
276            it  = sizes.begin(), end = sizes.end();
277         int i = 0;
278
279         for (;it != end; it++)
280         {
281            StdSize  s = *it;
282            if ((start != NULL) && (count != NULL))
283            {
284               if (s == UNLIMITED_DIM)
285               {
286                  sstart.push_back(record);
287                  scount.push_back(1);
288               }
289               else
290               {
291                  sstart.push_back((*start)[i]);
292                  scount.push_back((*count)[i]);
293                  array_size *= (*count)[i];
294                  i++;
295               }
296            }
297            else
298            {
299               if (s == UNLIMITED_DIM)
300               {
301                  sstart.push_back(record);
302                  scount.push_back(1);
303               }
304               else
305               {
306                  sstart.push_back(0);
307                  scount.push_back(sizes[i]);
308                  array_size *= sizes[i];
309               }
310               i++;
311            }
312         }
313      }
314
315      //---------------------------------------------------------------
316
317      template <>
318         void CONetCDF4::writeData_(int grpid, int varid,
319                                    const std::vector<StdSize> & sstart,
320                                    const std::vector<StdSize> & scount, double * data)
321      {
322         CheckError(nc_put_vara_double(grpid, varid, &(sstart[0]), &(scount[0]), data));
323      }
324     
325      //---------------------------------------------------------------
326     
327      template <>
328         void CONetCDF4::writeData_(int grpid, int varid,
329                                    const std::vector<StdSize> & sstart,
330                                    const std::vector<StdSize> & scount, int * data)
331      {
332          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data));
333      }
334     
335      //---------------------------------------------------------------
336     
337      template <>
338         void CONetCDF4::writeData_(int grpid, int varid,
339                                    const std::vector<StdSize> & sstart,
340                                    const std::vector<StdSize> & scount, float * data)
341      {
342          CheckError(nc_put_vara_float(grpid, varid, &(sstart[0]), &(scount[0]), data));
343      }
344
345      //---------------------------------------------------------------
346
347      void CONetCDF4::writeData(const ARRAY(int, 2) data, const StdString & name)
348      {
349         int grpid = this->getCurrentGroup();
350         int varid = this->getVariable(name);
351         StdSize array_size = 1;
352         std::vector<StdSize> sstart, scount;
353
354         this->getWriteDataInfos(name, 0, array_size,  sstart, scount, NULL, NULL);
355         this->writeData_(grpid, varid, sstart, scount, data->data());
356      }
357
358      //---------------------------------------------------------------
359     
360      bool CONetCDF4::varExist(const StdString & varname)
361      {
362         int varid = 0;
363         int grpid = this->getCurrentGroup();
364         return (nc_inq_varid (grpid, varname.c_str(), &varid) == NC_NOERR);
365      }
366
367      ///--------------------------------------------------------------
368   } // namespace io
369} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.