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

Last change on this file since 204 was 202, checked in by hozdoba, 13 years ago
File size: 12.4 KB
RevLine 
[152]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      }
[189]16     
17      //---------------------------------------------------------------
18     
[152]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      }
[189]33     
34      //---------------------------------------------------------------
35     
[152]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      }
[189]63     
64      //---------------------------------------------------------------
65     
[152]66      void CONetCDF4::definition_start(void)
[189]67      { 
68         CheckError(nc_redef(this->ncidp));
69      }
70     
71      //---------------------------------------------------------------
72     
[152]73      void CONetCDF4::definition_end(void)
[189]74      { 
75         CheckError(nc_enddef(this->ncidp));
76      }
77     
78      //---------------------------------------------------------------
79     
[152]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      //---------------------------------------------------------------
[189]91     
[152]92      int CONetCDF4::getCurrentGroup(void)
93      {
94         return (this->getGroup(this->getCurrentPath()));
95      }
[189]96     
97      //---------------------------------------------------------------
98     
[152]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      }
[189]113     
114      //---------------------------------------------------------------
115     
[152]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      }
[189]123     
124      //---------------------------------------------------------------
125     
[152]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      }
[189]133     
134      //---------------------------------------------------------------
135     
[152]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      }
[189]143     
144      //---------------------------------------------------------------
145     
[152]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      }
[189]186     
187      //---------------------------------------------------------------
188     
[152]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      }
[189]199     
200      //---------------------------------------------------------------
201     
[152]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      }
[189]232     
233      //---------------------------------------------------------------
234     
[152]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      }
[189]243     
244      //---------------------------------------------------------------
245     
[152]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      }
[189]254     
255      //---------------------------------------------------------------
256     
[152]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
[189]315      //---------------------------------------------------------------
316
[152]317      template <>
[189]318         void CONetCDF4::writeData_(int grpid, int varid,
319                                    const std::vector<StdSize> & sstart,
320                                    const std::vector<StdSize> & scount, double * data)
[152]321      {
[189]322         CheckError(nc_put_vara_double(grpid, varid, &(sstart[0]), &(scount[0]), data));
[152]323      }
[189]324     
325      //---------------------------------------------------------------
326     
[152]327      template <>
[189]328         void CONetCDF4::writeData_(int grpid, int varid,
329                                    const std::vector<StdSize> & sstart,
330                                    const std::vector<StdSize> & scount, int * data)
[152]331      {
[189]332          CheckError(nc_put_vara_int(grpid, varid, &(sstart[0]), &(scount[0]), data));
[152]333      }
[189]334     
335      //---------------------------------------------------------------
336     
[152]337      template <>
[189]338         void CONetCDF4::writeData_(int grpid, int varid,
339                                    const std::vector<StdSize> & sstart,
340                                    const std::vector<StdSize> & scount, float * data)
[152]341      {
[189]342          CheckError(nc_put_vara_float(grpid, varid, &(sstart[0]), &(scount[0]), data));
343      }
[152]344
[189]345      //---------------------------------------------------------------
[152]346
[183]347      void CONetCDF4::writeData(const ARRAY(int, 2) data, const StdString & name)
[152]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);
[189]355         this->writeData_(grpid, varid, sstart, scount, data->data());
[152]356      }
357
[202]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
[152]367      ///--------------------------------------------------------------
368   } // namespace io
369} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.