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

Last change on this file since 183 was 183, checked in by hozdoba, 10 years ago
File size: 15.4 KB
Line 
1#include "nc4_data_output.hpp"
2
3#include <boost/lexical_cast.hpp>
4#include "attribute_template_impl.hpp"
5
6#include "file.hpp"
7
8namespace xmlioserver
9{
10   namespace io
11   {
12      /// ////////////////////// Définitions ////////////////////// ///
13      CNc4DataOutput::CNc4DataOutput
14         (const StdString & filename, bool exist)
15            : SuperClass()
16            , SuperClassWriter(filename, exist)
17            , filename(filename)
18      {
19         StdString timeid = StdString("time_counter");
20         SuperClass::type = MULTI_FILE;
21         if (!exist)
22            SuperClassWriter::addDimension(timeid);
23      }
24
25      CNc4DataOutput::CNc4DataOutput
26         (const StdString & filename, bool exist, bool multigroup, MPI_Comm comm_server)
27            : SuperClass()
28            , SuperClassWriter(filename, exist, &comm_server)
29            , comm_server(comm_server)
30            , filename(filename)
31      {
32         StdString timeid = StdString("time_counter");
33         SuperClass::type = (multigroup) ? MULTI_GROUP : ONE_FILE;
34         if (!exist)
35            SuperClassWriter::addDimension(timeid);
36      }
37
38      CNc4DataOutput::CNc4DataOutput
39         (const StdString & filename, bool exist, bool multigroup, comm::MPIComm comm_server, bool)
40            : SuperClass()
41            , SuperClassWriter(filename, exist, &comm_server, true)
42            , filename(filename)
43      {
44         StdString timeid = StdString("time_counter");
45         SuperClass::type = (multigroup) ? MULTI_GROUP : ONE_FILE;
46         if (!exist)
47            SuperClassWriter::addDimension(timeid);
48      }
49
50      CNc4DataOutput::~CNc4DataOutput(void)
51      { /* Ne rien faire de plus */ }
52
53      ///--------------------------------------------------------------
54
55      const StdString & CNc4DataOutput::getFileName(void) const
56      {
57         return (this->filename);
58      }
59
60      //---------------------------------------------------------------
61
62      void CNc4DataOutput::writeDomain_(const boost::shared_ptr<tree::CDomain> domain)
63      {
64         if (domain->IsWritten(this->filename)) return;
65         domain->checkAttributes();
66
67         std::vector<StdString> dim0, dim1;
68         StdString domid     = (!domain->name.isEmpty())
69                             ? domain->name.getValue() : domain->getId();
70         StdString lonid     = StdString("lon_").append(domid);
71         StdString latid     = StdString("lat_").append(domid);
72         StdString lonid_loc = StdString("lon_").append(domid).append("_local");
73         StdString latid_loc = StdString("lat_").append(domid).append("_local");
74         StdString maskid    = StdString("mask_").append(domid).append("_local");
75
76         ARRAY(int, 2) mask = domain->getLocalMask();
77
78         unsigned int ssize = domain->ni.getValue() * domain->nj.getValue();
79         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
80
81         SuperClassWriter::addDimension(lonid, domain->ni_glo.getValue());
82         SuperClassWriter::addDimension(latid, domain->nj_glo.getValue());
83
84         if (isCurvilinear)
85         {
86            dim0.push_back(latid_loc); dim0.push_back(lonid_loc);
87            lonid = StdString("nav_lon_").append(domid);
88            latid = StdString("nav_lat_").append(domid);
89         }
90         else
91         {
92            dim0.push_back(latid_loc);
93            dim1.push_back(lonid_loc);
94         }
95         switch (SuperClass::type)
96         {
97            case (MULTI_FILE) :
98            {
99               SuperClassWriter::addDimension(lonid_loc, domain->ni.getValue());
100               SuperClassWriter::addDimension(latid_loc, domain->nj.getValue());
101               this->writeLocalAttributes(domain->ibegin.getValue(), domain->iend.getValue(),
102                                          domain->jbegin.getValue(), domain->jend.getValue(),
103                                          domid);
104               if (isCurvilinear)
105               {
106                  SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
107                  SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
108               }
109               else
110               {
111                  SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
112                  SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
113               }
114               this->writeAxisAttributes
115                  (latid, "X", "longitude", "Longitude", "degrees_east", domid);
116               this->writeAxisAttributes
117                  (lonid, "Y", "latitude", "Latitude", "degrees_north", domid);
118
119               dim0.clear();
120               dim0.push_back(latid_loc);
121               dim0.push_back(lonid_loc);
122
123               SuperClassWriter::addVariable(maskid, NC_INT, dim0);
124
125               this->writeMaskAttributes(maskid,
126                  domain->data_dim.getValue()/*,
127                  domain->data_ni.getValue(),
128                  domain->data_nj.getValue(),
129                  domain->data_ibegin.getValue(),
130                  domain->data_jbegin.getValue()*/);
131
132               SuperClassWriter::definition_end();
133               SuperClassWriter::writeData(domain->latvalue.getValue(), latid, true, 0);
134               SuperClassWriter::writeData(domain->lonvalue.getValue(), lonid, true, 0);
135               SuperClassWriter::writeData(mask, maskid);
136               SuperClassWriter::definition_start();
137
138               break;
139            }
140            default :
141               ERROR("CNc4DataOutput::writeDomain(domain)",
142                     << "[ type = " << SuperClass::type << "]"
143                     << " not implemented yet !");
144         }
145         domain->addRelFile(this->filename);
146      }
147
148      //--------------------------------------------------------------
149
150      void CNc4DataOutput::writeAxis_(const boost::shared_ptr<tree::CAxis> axis)
151      {
152         if (axis->IsWritten(this->filename)) return;
153         axis->checkAttributes();
154         std::vector<StdString> dims;
155         StdString axisid = (!axis->name.isEmpty())
156                           ? axis->name.getValue() : axis->getId();
157         SuperClassWriter::addDimension(axisid, axis->size.getValue());
158         dims.push_back(axisid);
159
160         switch (SuperClass::type)
161         {
162            case (MULTI_FILE) :
163            {
164               SuperClassWriter::addVariable(axisid, NC_FLOAT, dims);
165
166               SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid);
167
168               if (!axis->standard_name.isEmpty())
169                  SuperClassWriter::addAttribute
170                     ("standard_name",  axis->standard_name.getValue(), &axisid);
171
172               if (!axis->long_name.isEmpty())
173                  SuperClassWriter::addAttribute
174                     ("long_name", axis->long_name.getValue(), &axisid);
175
176               if (!axis->unit.isEmpty())
177                  SuperClassWriter::addAttribute
178                     ("units", axis->unit.getValue(), &axisid);
179
180               SuperClassWriter::definition_end();
181               SuperClassWriter::writeData(axis->zvalue.getValue(), axisid, true, 0);
182               SuperClassWriter::definition_start();
183
184               break;
185            }
186            default :
187               ERROR("CNc4DataOutput::writeDomain(domain)",
188                     << "[ type = " << SuperClass::type << "]"
189                     << " not implemented yet !");
190         }
191         axis->addRelFile(this->filename);
192      }
193
194      //--------------------------------------------------------------
195
196      void CNc4DataOutput::writeField_(const boost::shared_ptr<tree::CField> field)
197      {
198         std::vector<StdString> dims, coodinates;
199         boost::shared_ptr<CGrid> grid =
200            CObjectFactory::GetObject<CGrid>(field->grid_ref.getValue());
201         boost::shared_ptr<CDomain> domain =
202            CObjectFactory::GetObject<CDomain>(grid->domain_ref.getValue());
203
204         StdString timeid    = StdString("time_counter");
205         StdString domid     = (!domain->name.isEmpty())
206                             ? domain->name.getValue() : domain->getId();
207         StdString lonid     = StdString("lon_").append(domid);
208         StdString latid     = StdString("lat_").append(domid);
209         StdString lonid_loc = StdString("lon_").append(domid).append("_local");
210         StdString latid_loc = StdString("lat_").append(domid).append("_local");
211         StdString fieldid   = (!field->name.isEmpty())
212                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
213
214         unsigned int ssize = domain->ni.getValue() * domain->nj.getValue();
215         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
216
217         nc_type type = (!field->prec.isEmpty() &&
218                        ( field->prec.getValue() == 4))
219                        ? NC_FLOAT : NC_DOUBLE;
220         bool wtime   = !(!field->operation.isEmpty() &&
221                         ( field->operation.getValue().compare("once") == 0));
222
223         if (wtime) dims.push_back(timeid);
224
225         if (!grid->axis_ref.isEmpty())
226         {
227            boost::shared_ptr<CAxis> axis =
228               CObjectFactory::GetObject<CAxis>(grid->axis_ref.getValue());
229            StdString axisid = (!axis->name.isEmpty())
230                             ? axis->name.getValue() : axis->getId();
231            dims.push_back(axisid);
232            coodinates.push_back(axisid);
233         }
234
235         if (isCurvilinear)
236         {
237            coodinates.push_back(StdString("nav_lat_").append(domid));
238            coodinates.push_back(StdString("nav_lon_").append(domid));
239         }
240         else
241         {
242            coodinates.push_back(latid);
243            coodinates.push_back(lonid);
244         }
245
246         switch (SuperClass::type)
247         {
248            case (MULTI_FILE) :
249            {
250               dims.push_back(latid_loc);
251               dims.push_back(lonid_loc);
252               SuperClassWriter::addVariable(fieldid, type, dims);
253
254               if (!field->standard_name.isEmpty())
255                  SuperClassWriter::addAttribute
256                     ("standard_name",  field->standard_name.getValue(), &fieldid);
257
258               if (!field->long_name.isEmpty())
259                  SuperClassWriter::addAttribute
260                     ("long_name", field->long_name.getValue(), &fieldid);
261
262               if (!field->unit.isEmpty())
263                  SuperClassWriter::addAttribute
264                     ("units", field->unit.getValue(), &fieldid);
265
266               if (!field->operation.isEmpty())
267                  SuperClassWriter::addAttribute
268                     ("online_operation", field->operation.getValue(), &fieldid);
269
270               { 
271                  StdString coordstr; //boost::algorithm::join(coodinates, " ")
272                  std::vector<StdString>::iterator
273                     itc = coodinates.begin(), endc = coodinates.end();
274                 
275                  for (; itc!= endc; itc++)
276                  {
277                     StdString & coord = *itc;
278                     if (itc+1 != endc)
279                           coordstr.append(coord).append(" ");
280                     else  coordstr.append(coord);
281                  }
282
283                  SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
284
285               }
286
287               break;
288            }
289            default :
290               ERROR("CNc4DataOutput::writeDomain(domain)",
291                     << "[ type = " << SuperClass::type << "]"
292                     << " not implemented yet !");
293         }
294      }
295
296      //--------------------------------------------------------------
297
298      void CNc4DataOutput::writeFile_ (const boost::shared_ptr<tree::CFile> file)
299      {
300         StdString filename = (!file->name.isEmpty())
301                            ? file->name.getValue() : file->getId();
302         StdString description = (!file->description.isEmpty())
303                               ? file->description.getValue()
304                               : StdString("Created by xmlioserver");
305         this->writeFileAttributes(filename, description,
306                                   StdString ("CF-1.1"),
307                                   StdString("An IPSL model"),
308                                   this->getTimeStamp());
309      }
310
311      //---------------------------------------------------------------
312
313      StdString CNc4DataOutput::getTimeStamp(void) const
314      {
315         const int buffer_size = 100;
316         time_t rawtime;
317         struct tm * timeinfo = NULL;
318         char buffer [buffer_size];
319
320         time ( &rawtime );
321         timeinfo = localtime ( &rawtime );
322         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
323
324         return (StdString(buffer));
325      }
326
327      //---------------------------------------------------------------
328      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
329                                               const StdString & axis,
330                                               const StdString & standard_name,
331                                               const StdString & long_name,
332                                               const StdString & units,
333                                               const StdString & nav_model)
334      {
335         SuperClassWriter::addAttribute("axis"         , axis         , &axis_name);
336         SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
337         SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
338         SuperClassWriter::addAttribute("units"        , units        , &axis_name);
339         SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
340      }
341
342      void CNc4DataOutput::writeLocalAttributes
343         (int ibegin, int iend, int jbegin, int jend, StdString domid)
344      {
345         SuperClassWriter::addAttribute(StdString("ibegin_").append(domid), ibegin);
346         SuperClassWriter::addAttribute(StdString("iend_"  ).append(domid), iend);
347         SuperClassWriter::addAttribute(StdString("jbegin_").append(domid), jbegin);
348         SuperClassWriter::addAttribute(StdString("jend_"  ).append(domid), jend);
349      }
350
351      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
352                                                const StdString & description,
353                                                const StdString & conventions,
354                                                const StdString & production,
355                                                const StdString & timeStamp)
356      {
357         SuperClassWriter::addAttribute("name"       , name);
358         SuperClassWriter::addAttribute("description", description);
359         SuperClassWriter::addAttribute("conventions", conventions);
360         SuperClassWriter::addAttribute("production" , production);
361         SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
362      }
363
364      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
365                                               int data_dim,
366                                               int data_ni,
367                                               int data_nj,
368                                               int data_ibegin,
369                                               int data_jbegin)
370      {
371         SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
372         SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
373         SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
374         SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
375         SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
376      }
377
378      ///--------------------------------------------------------------
379
380   } // namespace io
381} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.