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

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

Mise à jour depuis un autre dépôt

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