source: XIOS/branchs/xios-1.0/src/output/nc4_data_output.cpp @ 616

Last change on this file since 616 was 616, checked in by rlacroix, 6 years ago

Cosmetics: Remove old unstructured code.

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 62.7 KB
Line 
1
2#include "nc4_data_output.hpp"
3
4#include <boost/lexical_cast.hpp>
5#include "attribute_template.hpp"
6#include "group_template.hpp"
7
8#include "file.hpp"
9#include "calendar.hpp"
10#include "context.hpp"
11#include "context_server.hpp"
12#include "netCdfException.hpp"
13#include "exception.hpp"
14
15namespace xios
16{
17      /// ////////////////////// Définitions ////////////////////// ///
18      CNc4DataOutput::CNc4DataOutput
19         (const StdString & filename, bool exist)
20            : SuperClass()
21            , SuperClassWriter(filename, exist)
22            , filename(filename)
23      {
24         StdString timeid = StdString("time_counter");
25         SuperClass::type = MULTI_FILE;
26//         if (!exist)
27//            SuperClassWriter::addDimension(timeid);
28      }
29
30      CNc4DataOutput::CNc4DataOutput
31         (const StdString & filename, bool exist, MPI_Comm comm_file,bool multifile, bool isCollective)
32            : SuperClass()
33            , SuperClassWriter(filename, exist, &comm_file,multifile)
34            , comm_file(comm_file)
35            , filename(filename)
36            , isCollective(isCollective)
37      {
38         StdString timeid = StdString("time_counter");
39
40         SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE;
41
42 //        if (!exist)
43//            SuperClassWriter::addDimension(timeid);
44      }
45
46
47      CNc4DataOutput::~CNc4DataOutput(void)
48      { /* Ne rien faire de plus */ }
49
50      ///--------------------------------------------------------------
51
52      const StdString & CNc4DataOutput::getFileName(void) const
53      {
54         return (this->filename);
55      }
56
57      //---------------------------------------------------------------
58
59      void CNc4DataOutput::writeDomain_(CDomain* domain)
60      {
61         if (domain->type == CDomain::type_attr::unstructured)
62         {
63           writeUnstructuredDomain(domain) ;
64           return ;
65         }
66
67         CContext* context = CContext::getCurrent() ;
68         CContextServer* server=context->server ;
69
70         if (domain->IsWritten(this->filename)) return;
71         domain->checkAttributes();
72
73         if (domain->isEmpty())
74           if (SuperClass::type==MULTI_FILE) return ;
75
76         std::vector<StdString> dim0, dim1;
77         StdString domid     = (!domain->name.isEmpty())
78                             ? domain->name.getValue() : domain->getId();
79         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
80
81
82         StdString dimXid, dimYid ;
83
84         bool isRegularDomain = (domain->type == CDomain::type_attr::regular);
85         switch (domain->type)
86         {
87           case CDomain::type_attr::curvilinear :
88             dimXid     = StdString("x").append(appendDomid);
89             dimYid     = StdString("y").append(appendDomid);
90             break ;
91           case CDomain::type_attr::regular :
92             dimXid     = StdString("lon").append(appendDomid);
93             dimYid     = StdString("lat").append(appendDomid);
94             break;
95         }
96
97         string lonid,latid,bounds_lonid,bounds_latid ;
98         string areaId = "area" + appendDomid;
99/*
100         StdString lonid_loc = (server->intraCommSize > 1)
101                             ? StdString("lon").append(appendDomid).append("_local")
102                             : lonid;
103         StdString latid_loc = (server->intraCommSize > 1)
104                             ? StdString("lat").append(appendDomid).append("_local")
105                             : latid;
106*/
107
108         try
109         {
110           switch (SuperClass::type)
111           {
112              case (MULTI_FILE) :
113              {
114  //               if (domain->isEmpty()) return;
115
116                 if (server->intraCommSize > 1)
117                 {
118  //                 SuperClassWriter::addDimension(lonid, domain->zoom_ni.getValue());
119  //                 SuperClassWriter::addDimension(latid, domain->zoom_nj.getValue());
120                 }
121
122                 switch (domain->type)
123                 {
124                   case CDomain::type_attr::curvilinear :
125                     dim0.push_back(dimYid); dim0.push_back(dimXid);
126                     lonid = StdString("nav_lon").append(appendDomid);
127                     latid = StdString("nav_lat").append(appendDomid);
128                     break ;
129                   case CDomain::type_attr::regular :
130                     lonid = StdString("lon").append(appendDomid);
131                     latid = StdString("lat").append(appendDomid);
132                     dim0.push_back(dimYid);
133                     dim1.push_back(dimXid);
134                     break;
135                 }
136
137                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
138                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv);
139
140                 if (server->intraCommSize > 1)
141                 {
142                   this->writeLocalAttributes(domain->zoom_ibegin_srv,
143                                              domain->zoom_ni_srv,
144                                              domain->zoom_jbegin_srv,
145                                              domain->zoom_nj_srv,
146                                              appendDomid);
147
148                   if (singleDomain) this->writeLocalAttributes_IOIPSL(domain->zoom_ibegin_srv,
149                                                 domain->zoom_ni_srv,
150                                                 domain->zoom_jbegin_srv,
151                                                 domain->zoom_nj_srv,
152                                                 domain->ni_glo,domain->nj_glo,
153                                                 server->intraCommRank,server->intraCommSize);
154                 }
155
156                 switch (domain->type)
157                 {
158                   case CDomain::type_attr::curvilinear :
159                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
160                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
161                     break ;
162                    case CDomain::type_attr::regular :
163                      SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
164                      SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
165                      break ;
166                 }
167
168                 this->writeAxisAttributes(lonid, isRegularDomain ? "X" : "", "longitude", "Longitude", "degrees_east", domid);
169                 this->writeAxisAttributes(latid, isRegularDomain ? "Y" : "", "latitude", "Latitude", "degrees_north", domid);
170
171                 dim0.clear();
172                 dim0.push_back(dimYid);
173                 dim0.push_back(dimXid);
174
175
176  // supress mask               if (server->intraCommSize > 1)
177  // supress mask               {
178  // supress mask                  SuperClassWriter::addVariable(maskid, NC_INT, dim0);
179  // supress mask
180  // supress mask                  this->writeMaskAttributes(maskid,
181  // supress mask                     domain->data_dim.getValue()/*,
182  // supress mask                     domain->data_ni.getValue(),
183  // supress mask                     domain->data_nj.getValue(),
184  // supress mask                     domain->data_ibegin.getValue(),
185  // supress mask                     domain->data_jbegin.getValue()*/);
186  // supress mask               }
187
188                 //SuperClassWriter::setDefaultValue(maskid, &dvm);
189
190                 if (domain->hasArea)
191                 {
192                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
193                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
194                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
195                 }
196
197                 SuperClassWriter::definition_end();
198
199                 switch (domain->type)
200                 {
201                   case CDomain::type_attr::curvilinear :
202                     SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
203                     SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
204                     break;
205                   case CDomain::type_attr::regular :
206                     CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
207                     SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
208                     CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
209                     SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
210                     break;
211                 }
212
213                 if (domain->hasArea)
214                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0);
215
216                 SuperClassWriter::definition_start();
217
218                 break;
219              }
220              case (ONE_FILE) :
221              {
222                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni.getValue());
223                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj.getValue());
224
225                 switch (domain->type)
226                 {
227                   case CDomain::type_attr::curvilinear :
228                     dim0.push_back(dimYid); dim0.push_back(dimXid);
229                     lonid = StdString("nav_lon").append(appendDomid);
230                     latid = StdString("nav_lat").append(appendDomid);
231                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
232                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
233                     break;
234
235                   case CDomain::type_attr::regular :
236                     dim0.push_back(dimYid);
237                     dim1.push_back(dimXid);
238                     lonid = StdString("lon").append(appendDomid);
239                     latid = StdString("lat").append(appendDomid);
240                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
241                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
242                     break;
243                 }
244
245                 if (domain->hasArea)
246                 {
247                   dim0.clear();
248                   dim0.push_back(dimYid); dim0.push_back(dimXid);
249                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
250                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
251                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
252                   dim0.clear();
253                 }
254
255                 this->writeAxisAttributes
256                    (lonid, isRegularDomain ? "X" : "", "longitude", "Longitude", "degrees_east", domid);
257                 this->writeAxisAttributes
258                    (latid, isRegularDomain ? "Y" : "", "latitude", "Latitude", "degrees_north", domid);
259
260                 SuperClassWriter::definition_end();
261
262                 switch (domain->type)
263                 {
264                   case CDomain::type_attr::curvilinear :
265                   {
266                     std::vector<StdSize> start(2) ;
267                     std::vector<StdSize> count(2) ;
268                     if (domain->isEmpty())
269                     {
270                       start[0]=0 ; start[1]=0 ;
271                       count[0]=0 ; count[1]=0 ;
272                     }
273                     else
274                     {
275                       start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
276                       count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
277                     }
278
279                     SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
280                     SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
281                     break;
282                   }
283                   case CDomain::type_attr::regular :
284                   {
285                     std::vector<StdSize> start(1) ;
286                     std::vector<StdSize> count(1) ;
287                     if (domain->isEmpty())
288                     {
289                       start[0]=0 ;
290                       count[0]=0 ;
291                       SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
292                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);                 }
293                     else
294                     {
295                       start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
296                       count[0]=domain->zoom_nj_srv ;
297                       CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
298                       SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
299
300                       start[0]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ;
301                       count[0]=domain->zoom_ni_srv ;
302                       CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
303                       SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
304                     }
305                     break;
306                   }
307                 }
308
309                 if (domain->hasArea)
310                 {
311                   std::vector<StdSize> start(2);
312                   std::vector<StdSize> count(2);
313
314                   if (domain->isEmpty())
315                   {
316                     start[0] = 0; start[1] = 0;
317                     count[0] = 0; count[1] = 0;
318                   }
319                   else
320                   {
321                     start[1] = domain->zoom_ibegin_srv - domain->zoom_ibegin.getValue();
322                     start[0] = domain->zoom_jbegin_srv - domain->zoom_jbegin.getValue();
323                     count[1] = domain->zoom_ni_srv;
324                     count[0] = domain->zoom_nj_srv;
325                   }
326
327                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count);
328                 }
329
330                 SuperClassWriter::definition_start();
331
332                 break;
333              }
334              default :
335                 ERROR("CNc4DataOutput::writeDomain(domain)",
336                       << "[ type = " << SuperClass::type << "]"
337                       << " not implemented yet !");
338           }
339         }
340         catch (CNetCdfException& e)
341         {
342           StdString msg("On writing the domain : ");
343           msg.append(domid); msg.append("\n");
344           msg.append("In the context : ");
345           msg.append(context->getId()); msg.append("\n");
346           msg.append(e.what());
347           ERROR("CNc4DataOutput::writeDomain_(CDomain* domain)", << msg);
348         }
349
350         domain->addRelFile(this->filename);
351      }
352
353      void CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)
354      {
355         CContext* context = CContext::getCurrent() ;
356         CContextServer* server=context->server ;
357
358         if (domain->IsWritten(this->filename)) return;
359         domain->checkAttributes();
360
361         if (domain->isEmpty())
362           if (SuperClass::type==MULTI_FILE) return ;
363
364         std::vector<StdString> dim0, dim1;
365         StdString domid     = (!domain->name.isEmpty())
366                             ? domain->name.getValue() : domain->getId();
367         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
368
369
370         StdString dimXid = StdString("cell").append(appendDomid);
371         StdString dimVertId = StdString("nvertex").append(appendDomid);
372
373         string lonid,latid,bounds_lonid,bounds_latid ;
374         string areaId = "area" + appendDomid;
375
376         try
377         {
378           switch (SuperClass::type)
379           {
380              case (MULTI_FILE) :
381              {
382                 lonid = StdString("lon").append(appendDomid);
383                 latid = StdString("lat").append(appendDomid);
384                 dim0.push_back(dimXid);
385
386                 SuperClassWriter::addDimension(dimXid, domain->zoom_nj_srv);
387                 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
388                 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
389
390                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
391                 bounds_latid = StdString("bounds_lat").append(appendDomid);
392
393
394                 this->writeAxisAttributes(lonid, "", "longitude", "Longitude", "degrees_east", domid);
395                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
396                 this->writeAxisAttributes(latid, "", "latitude", "Latitude", "degrees_north", domid);
397                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
398                 if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
399                 dim0.clear();
400                 if (domain->hasBounds)
401                 {
402                   dim0.push_back(dimXid);
403                   dim0.push_back(dimVertId);
404                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
405                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
406                 }
407
408                 dim0.clear();
409                 dim0.push_back(dimXid);
410
411                 if (domain->hasArea)
412                 {
413                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
414                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
415                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
416                 }
417
418                 SuperClassWriter::definition_end();
419
420                 SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
421                 SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
422
423                 if (domain->hasBounds)
424                 {
425                   SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
426                   SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
427                 }
428
429                 if (domain->hasArea)
430                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0);
431
432                 SuperClassWriter::definition_start();
433                 break ;
434              }
435
436              case (ONE_FILE) :
437              {
438                 lonid = StdString("lon").append(appendDomid);
439                 latid = StdString("lat").append(appendDomid);
440                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
441                 bounds_latid = StdString("bounds_lat").append(appendDomid);
442                 dim0.push_back(dimXid);
443                 SuperClassWriter::addDimension(dimXid, domain->nj_glo);
444                 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
445                 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
446                 this->writeAxisAttributes(lonid, "", "longitude", "Longitude", "degrees_east", domid);
447                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
448                 this->writeAxisAttributes(latid, "", "latitude", "Latitude", "degrees_north", domid);
449                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
450                 if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
451                 dim0.clear();
452
453                 if (domain->hasBounds)
454                 {
455                   dim0.push_back(dimXid);
456                   dim0.push_back(dimVertId);
457                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
458                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
459                 }
460
461                 if (domain->hasArea)
462                 {
463                   dim0.clear();
464                   dim0.push_back(dimXid);
465                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
466                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
467                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
468                 }
469
470                 SuperClassWriter::definition_end();
471
472                 std::vector<StdSize> start(1), startBounds(2) ;
473                 std::vector<StdSize> count(1), countBounds(2) ;
474                 if (domain->isEmpty())
475                 {
476                   start[0]=0 ;
477                   count[0]=0 ;
478                   startBounds[1]=0 ;
479                   countBounds[1]=domain->nvertex ;
480                   startBounds[0]=0 ;
481                   countBounds[0]=0 ;
482                 }
483                 else
484                 {
485                   start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
486                   count[0]=domain->zoom_nj_srv ;
487                   startBounds[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
488                   startBounds[1]=0 ;
489                   countBounds[0]=domain->zoom_nj_srv ;
490                   countBounds[1]=domain->nvertex ;
491                 }
492                 SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
493                 SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
494                 if (domain->hasBounds)
495                 {
496                   SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
497                   SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds);
498                 }
499
500                 if (domain->hasArea)
501                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count);
502
503                 SuperClassWriter::definition_start();
504
505                 break;
506              }
507              default :
508                 ERROR("CNc4DataOutput::writeDomain(domain)",
509                       << "[ type = " << SuperClass::type << "]"
510                       << " not implemented yet !");
511           }
512         }
513         catch (CNetCdfException& e)
514         {
515           StdString msg("On writing the domain : ");
516           msg.append(domid); msg.append("\n");
517           msg.append("In the context : ");
518           msg.append(context->getId()); msg.append("\n");
519           msg.append(e.what());
520           ERROR("CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)", << msg);
521         }
522         domain->addRelFile(this->filename);
523      }
524      //--------------------------------------------------------------
525
526      void CNc4DataOutput::writeAxis_(CAxis* axis)
527      {
528         if (axis->IsWritten(this->filename)) return;
529         axis->checkAttributes();
530         int zoom_size = axis->zoom_size.getValue();
531         int zoom_begin = axis->zoom_begin.getValue() - 1;
532
533
534         std::vector<StdString> dims;
535         StdString axisid = (!axis->name.isEmpty())
536                           ? axis->name.getValue() : axis->getId();
537         try
538         {
539           SuperClassWriter::addDimension(axisid, zoom_size);
540           dims.push_back(axisid);
541
542           switch (SuperClass::type)
543           {
544              case (MULTI_FILE ) :
545              {}
546              case (ONE_FILE) :
547              {
548                 SuperClassWriter::addVariable(axisid, NC_FLOAT, dims);
549
550                 if (!axis->standard_name.isEmpty())
551                    SuperClassWriter::addAttribute
552                       ("standard_name",  axis->standard_name.getValue(), &axisid);
553
554                 if (!axis->long_name.isEmpty())
555                    SuperClassWriter::addAttribute
556                       ("long_name", axis->long_name.getValue(), &axisid);
557
558                 if (!axis->unit.isEmpty())
559                    SuperClassWriter::addAttribute
560                       ("units", axis->unit.getValue(), &axisid);
561
562                 if (!axis->positive.isEmpty())
563                 {
564                   SuperClassWriter::addAttribute("axis", string("Z"), &axisid);
565                   SuperClassWriter::addAttribute("positive",
566                                                  (axis->positive == CAxis::positive_attr::up) ? string("up") : string("down"),
567                                                  &axisid);
568                 }
569
570                 StdString axisBoundsId = axisid + "_bounds";
571                 if (!axis->bounds.isEmpty())
572                 {
573                   dims.push_back("axis_nbounds");
574                   SuperClassWriter::addVariable(axisBoundsId, NC_FLOAT, dims);
575                   SuperClassWriter::addAttribute("bounds", axisBoundsId, &axisid);
576                 }
577
578                 SuperClassWriter::definition_end();
579
580                 CArray<double,1> axis_value(zoom_size);
581                 for(int i = 0 ; i < zoom_size; i++) axis_value(i) = axis->value(i+zoom_begin);
582                 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
583
584                 if (!axis->bounds.isEmpty())
585                 {
586                   CArray<double,2> axisBounds(2, zoom_size);
587                   for (int i = 0; i < zoom_size; i++)
588                   {
589                     axisBounds(0, i) = axis->bounds(i + zoom_begin, 0);
590                     axisBounds(1, i) = axis->bounds(i + zoom_begin, 1);
591                   }
592                   SuperClassWriter::writeData(axisBounds, axisBoundsId, isCollective, 0);
593                 }
594
595                 SuperClassWriter::definition_start();
596
597                 break;
598              }
599              default :
600                 ERROR("CNc4DataOutput::writeDomain(domain)",
601                       << "[ type = " << SuperClass::type << "]"
602                       << " not implemented yet !");
603           }
604         }
605         catch (CNetCdfException& e)
606         {
607           StdString msg("On writing the axis : ");
608           msg.append(axisid); msg.append("\n");
609           msg.append("In the context : ");
610           CContext* context = CContext::getCurrent() ;
611           msg.append(context->getId()); msg.append("\n");
612           msg.append(e.what());
613           ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg);
614         }
615         axis->addRelFile(this->filename);
616     }
617
618     void CNc4DataOutput::writeTimeDimension_(void)
619     {
620       try
621       {
622         SuperClassWriter::addDimension("time_counter");
623       }
624       catch (CNetCdfException& e)
625       {
626         StdString msg("On writing time dimension : time_couter\n");
627         msg.append("In the context : ");
628         CContext* context = CContext::getCurrent() ;
629         msg.append(context->getId()); msg.append("\n");
630         msg.append(e.what());
631         ERROR("CNc4DataOutput::writeTimeDimension_(void)", << msg);
632       }
633     }
634      //--------------------------------------------------------------
635
636      void CNc4DataOutput::writeField_(CField* field)
637      {
638         CContext* context = CContext::getCurrent() ;
639         CContextServer* server=context->server ;
640
641         std::vector<StdString> dims, coodinates;
642         CGrid* grid = field->grid;
643         CDomain* domain = grid->domain;
644
645         if (domain->isEmpty())
646           if (SuperClass::type==MULTI_FILE) return ;
647
648         StdString timeid    = StdString("time_counter");
649         StdString domid     = (!domain->name.isEmpty())
650                             ? domain->name.getValue() : domain->getId();
651         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
652
653//         bool isCurvilinear = domain->isCurvilinear ;
654//         bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ;
655
656         StdString dimXid,dimYid ;
657
658         switch (domain->type)
659         {
660           case CDomain::type_attr::curvilinear :
661             dimXid     = StdString("x").append(appendDomid);
662             dimYid     = StdString("y").append(appendDomid);
663             break ;
664           case CDomain::type_attr::regular :
665             dimXid     = StdString("lon").append(appendDomid);
666             dimYid     = StdString("lat").append(appendDomid);
667             break ;
668           case CDomain::type_attr::unstructured :
669             dimXid     = StdString("cell").append(appendDomid);
670             break ;
671        }
672
673/*
674         StdString lonid_loc = (server->intraCommSize > 1)
675                             ? StdString("lon").append(appendDomid).append("_local")
676                             : lonid;
677         StdString latid_loc = (server->intraCommSize > 1)
678                             ? StdString("lat").append(appendDomid).append("_local")
679                             : latid;
680*/
681         StdString fieldid   = (!field->name.isEmpty())
682                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
683
684//         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
685//         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
686//          bool isCurvilinear = domain->isCurvilinear ;
687
688         nc_type type ;
689         if (field->prec.isEmpty()) type =  NC_FLOAT ;
690         else
691         {
692           if (field->prec==2) type = NC_SHORT ;
693           else if (field->prec==4)  type =  NC_FLOAT ;
694           else if (field->prec==8)   type =  NC_DOUBLE ;
695         }
696
697         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
698
699         if (wtime)
700         {
701
702            //StdOStringStream oss;
703           // oss << "time_" << field->operation.getValue()
704           //     << "_" << field->getRelFile()->output_freq.getValue();
705          //oss
706            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
707            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
708            dims.push_back(timeid);
709         }
710
711         if (!grid->axis_ref.isEmpty())
712         {
713            CAxis* axis = grid->axis ;
714            StdString axisid = (!axis->name.isEmpty()) ? axis->name.getValue() : axis->getId();
715            dims.push_back(axisid);
716            coodinates.push_back(axisid);
717         }
718
719         switch (domain->type)
720         {
721           case CDomain::type_attr::curvilinear :
722             coodinates.push_back(StdString("nav_lon").append(appendDomid));
723             coodinates.push_back(StdString("nav_lat").append(appendDomid));
724             break;
725           case CDomain::type_attr::regular :
726           case CDomain::type_attr::unstructured :
727            coodinates.push_back(StdString("lon").append(appendDomid));
728            coodinates.push_back(StdString("lat").append(appendDomid));
729             break;
730         }
731
732         if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid);
733         dims.push_back(dimXid);
734
735         try
736         {
737           SuperClassWriter::addVariable(fieldid, type, dims);
738
739           if (!field->standard_name.isEmpty())
740              SuperClassWriter::addAttribute
741                 ("standard_name",  field->standard_name.getValue(), &fieldid);
742
743           if (!field->long_name.isEmpty())
744              SuperClassWriter::addAttribute
745                 ("long_name", field->long_name.getValue(), &fieldid);
746
747           if (!field->unit.isEmpty())
748              SuperClassWriter::addAttribute
749                 ("units", field->unit.getValue(), &fieldid);
750
751            if (!field->valid_min.isEmpty())
752              SuperClassWriter::addAttribute
753                 ("valid_min", field->valid_min.getValue(), &fieldid);
754
755           if (!field->valid_max.isEmpty())
756              SuperClassWriter::addAttribute
757                 ("valid_max", field->valid_max.getValue(), &fieldid);
758
759            if (!field->scale_factor.isEmpty())
760              SuperClassWriter::addAttribute
761                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
762
763             if (!field->add_offset.isEmpty())
764              SuperClassWriter::addAttribute
765                 ("add_offset", field->add_offset.getValue(), &fieldid);
766
767           SuperClassWriter::addAttribute
768                 ("online_operation", field->operation.getValue(), &fieldid);
769
770          // write child variables as attributes
771
772
773           vector<CVariable*> listVars = field->getAllVariables() ;
774           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
775
776
777           if (wtime)
778           {
779              CDuration freqOp = CDuration::FromString(field->freq_op);
780              freqOp.solveTimeStep(*context->calendar);
781              StdString freqOpStr = freqOp.toStringUDUnits();
782              SuperClassWriter::addAttribute("interval_operation", freqOpStr, &fieldid);
783
784              CDuration freqOut = CDuration::FromString(field->getRelFile()->output_freq);
785              freqOut.solveTimeStep(*context->calendar);
786              SuperClassWriter::addAttribute("interval_write", freqOut.toStringUDUnits(), &fieldid);
787
788              StdString cellMethods = coodinates.front() + ": ";
789              if (field->operation.getValue() == "instant") cellMethods += "point";
790              else if (field->operation.getValue() == "average") cellMethods += "mean";
791              else if (field->operation.getValue() == "accumulate") cellMethods += "sum";
792              else cellMethods += field->operation;
793              if (freqOp.resolve(*context->calendar) != freqOut.resolve(*context->calendar))
794                cellMethods += " (interval: " + freqOpStr + ")";
795              SuperClassWriter::addAttribute("cell_methods", cellMethods, &fieldid);
796           }
797
798           if (domain->hasArea)
799             SuperClassWriter::addAttribute("cell_measures", "area: area" + appendDomid, &fieldid);
800
801           if (!field->default_value.isEmpty())
802           {
803              double default_value = field->default_value.getValue();
804              float fdefault_value = (float)default_value;
805              if (type == NC_DOUBLE)
806                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
807              else
808                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
809           }
810           else
811           {
812              double * default_value = NULL;
813              SuperClassWriter::setDefaultValue(fieldid, default_value);
814           }
815
816           if (field->compression_level.isEmpty())
817             field->compression_level = field->file->compression_level.isEmpty() ? 0 : field->file->compression_level;
818           SuperClassWriter::setCompressionLevel(fieldid, field->compression_level);
819
820           {  // Ecriture des coordonnées
821
822              StdString coordstr; //boost::algorithm::join(coodinates, " ")
823              std::vector<StdString>::iterator
824                 itc = coodinates.begin(), endc = coodinates.end();
825
826              for (; itc!= endc; itc++)
827              {
828                 StdString & coord = *itc;
829                 if (itc+1 != endc)
830                       coordstr.append(coord).append(" ");
831                 else  coordstr.append(coord);
832              }
833
834              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
835
836           }
837         }
838         catch (CNetCdfException& e)
839         {
840           StdString msg("On writing field : ");
841           msg.append(fieldid); msg.append("\n");
842           msg.append("In the context : ");
843           msg.append(context->getId()); msg.append("\n");
844           msg.append(e.what());
845           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
846         }
847      }
848
849      //--------------------------------------------------------------
850
851      void CNc4DataOutput::writeFile_ (CFile* file)
852      {
853         StdString filename = (!file->name.isEmpty())
854                            ? file->name.getValue() : file->getId();
855         StdString description = (!file->description.isEmpty())
856                               ? file->description.getValue()
857                               : StdString("Created by xios");
858
859         singleDomain = (file->nbDomains == 1);
860
861         try
862         {
863           this->writeFileAttributes(filename, description,
864                                     StdString("CF-1.5"),
865                                     StdString("An IPSL model"),
866                                     this->getTimeStamp());
867
868           SuperClassWriter::addDimension("axis_nbounds", 2);
869         }
870         catch (CNetCdfException& e)
871         {
872           StdString msg("On writing file : ");
873           msg.append(filename); msg.append("\n");
874           msg.append("In the context : ");
875           CContext* context = CContext::getCurrent() ;
876           msg.append(context->getId()); msg.append("\n");
877           msg.append(e.what());
878           ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg);
879         }
880      }
881
882      void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)
883      {
884        string name ;
885        if (!var->name.isEmpty()) name=var->name ;
886        else if (var->hasId()) name=var->getId() ;
887        else return ;
888
889        try
890        {
891          if (var->getVarType()==CVariable::t_int) addAttribute(name,var->getData<int>(),&fieldId) ;
892          else if (var->getVarType()==CVariable::t_short_int) addAttribute(name,var->getData<short int>(),&fieldId) ;
893          else if (var->getVarType()==CVariable::t_long_int) addAttribute(name,var->getData<long int>(),&fieldId) ;
894          else if (var->getVarType()==CVariable::t_float) addAttribute(name,var->getData<float>(),&fieldId) ;
895          else if (var->getVarType()==CVariable::t_double) addAttribute(name,var->getData<double>(),&fieldId) ;
896          else addAttribute(name,var->getData<string>(),&fieldId) ;
897        }
898       catch (CNetCdfException& e)
899       {
900         StdString msg("On writing attributes of variable with name : ");
901         msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n");
902         msg.append("In the context : ");
903         CContext* context = CContext::getCurrent() ;
904         msg.append(context->getId()); msg.append("\n");
905         msg.append(e.what());
906         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg);
907       }
908     }
909
910     void CNc4DataOutput::writeAttribute_ (CVariable* var)
911     {
912        string name ;
913        if (!var->name.isEmpty()) name=var->name ;
914        else if (var->hasId()) name=var->getId() ;
915        else return ;
916        try
917        {
918          if (var->getVarType()==CVariable::t_int) addAttribute(name,var->getData<int>()) ;
919          else if (var->getVarType()==CVariable::t_short_int) addAttribute(name,var->getData<short int>()) ;
920          else if (var->getVarType()==CVariable::t_long_int) addAttribute(name,var->getData<long int>()) ;
921          else if (var->getVarType()==CVariable::t_float) addAttribute(name,var->getData<float>()) ;
922          else if (var->getVarType()==CVariable::t_double) addAttribute(name,var->getData<double>()) ;
923          else addAttribute(name,var->getData<string>()) ;
924        }
925       catch (CNetCdfException& e)
926       {
927         StdString msg("On writing attributes of variable with name : ");
928         msg.append(name); msg.append("\n");
929         msg.append("In the context : ");
930         CContext* context = CContext::getCurrent() ;
931         msg.append(context->getId()); msg.append("\n");
932         msg.append(e.what());
933         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg);
934       }
935     }
936
937      void CNc4DataOutput::syncFile_ (void)
938      {
939        try
940        {
941          SuperClassWriter::sync() ;
942        }
943        catch (CNetCdfException& e)
944        {
945         StdString msg("On synchronizing the write among processes");
946         msg.append("In the context : ");
947         CContext* context = CContext::getCurrent() ;
948         msg.append(context->getId()); msg.append("\n");
949         msg.append(e.what());
950         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
951        }
952      }
953
954      void CNc4DataOutput::closeFile_ (void)
955      {
956        try
957        {
958          SuperClassWriter::close() ;
959        }
960        catch (CNetCdfException& e)
961        {
962         StdString msg("On closing file");
963         msg.append("In the context : ");
964         CContext* context = CContext::getCurrent() ;
965         msg.append(context->getId()); msg.append("\n");
966         msg.append(e.what());
967         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
968        }
969
970      }
971
972      //---------------------------------------------------------------
973
974      StdString CNc4DataOutput::getTimeStamp(void) const
975      {
976         const int buffer_size = 100;
977         time_t rawtime;
978         struct tm * timeinfo = NULL;
979         char buffer [buffer_size];
980
981         time ( &rawtime );
982         timeinfo = localtime ( &rawtime );
983         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
984
985         return (StdString(buffer));
986      }
987
988      //---------------------------------------------------------------
989
990      void CNc4DataOutput::writeFieldData_ (CField*  field)
991      {
992         CContext* context = CContext::getCurrent() ;
993//          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
994         CContextServer* server=context->server ;
995
996         CGrid* grid = field->grid ;
997         CDomain* domain = grid->domain ;
998
999         if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return;
1000
1001
1002         StdString fieldid   = (!field->name.isEmpty())
1003                             ? field->name.getValue()
1004                             : field->getBaseFieldReference()->getId();
1005
1006         StdOStringStream oss;
1007         string timeAxisId ;
1008         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
1009         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
1010
1011         StdString timeBoundId("time_counter_bounds");
1012
1013         StdString timeAxisBoundId;
1014         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
1015         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
1016
1017         CArray<double,1> time_data(1) ;
1018         CArray<double,1> time_counter(1) ;
1019         CArray<double,1> time_counter_bound(2);
1020         CArray<double,1> time_data_bound(2);
1021
1022        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
1023
1024        if (wtime)
1025        {
1026          time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2;
1027          if (field->foperation->timeType() == func::CFunctor::instant)
1028            time_data(0) = Time(*field->last_Write_srv);
1029          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
1030
1031          time_counter_bound(0) = Time(*field->lastlast_Write_srv);
1032          time_counter_bound(1) = Time(*field->last_Write_srv);
1033          if (field->foperation->timeType() == func::CFunctor::instant)
1034            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv);
1035          else if (field->foperation->timeType() == func::CFunctor::centered)
1036          {
1037            time_data_bound(0) = time_counter_bound(0);
1038            time_data_bound(1) = time_counter_bound(1);
1039          }
1040         }
1041
1042         bool isRoot ;
1043         if (server->intraCommRank==0) isRoot=true ;
1044         else isRoot=false ;
1045
1046         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1047         {
1048           double scaleFactor=1. ;
1049           double addOffset=0. ;
1050           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
1051           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
1052           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
1053         }
1054
1055         try
1056         {
1057           if (grid->hasAxis()) // 3D
1058           {
1059              CAxis* axis = grid->axis ;
1060              CArray<double,3> field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ;
1061              if (!field->default_value.isEmpty()) field_data3D = field->default_value ;
1062
1063              field->outputField(field_data3D);
1064
1065              if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ;
1066
1067              switch (SuperClass::type)
1068             {
1069                case (MULTI_FILE) :
1070                {
1071                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1);
1072                   if (wtime)
1073                   {
1074                     SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1075                     SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1076                     SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1077                     SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1078                   }
1079                   break ;
1080                }
1081                case (ONE_FILE) :
1082                {
1083                   std::vector<StdSize> start(3) ;
1084                   std::vector<StdSize> count(3) ;
1085                   if (domain->isEmpty())
1086                   {
1087                     start[0]=0 ; start[1]=0 ; start[2]=0 ;
1088                     count[0]=0 ; count[1]=0 ; start[2]=0 ;
1089                   }
1090                   else
1091                   {
1092  //                 start[2]=domain->zoom_ibegin_loc.getValue()-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_loc.getValue()-domain->zoom_jbegin.getValue() ; start[0]=0 ;
1093                     start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ;
1094                     count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue();
1095                   }
1096                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count );
1097                   if (wtime)
1098                   {
1099                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1100                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1101                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1102                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1103                   }
1104                   break;
1105                }
1106              }
1107
1108           }
1109           else // 2D
1110           {
1111              CArray<double,2> field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ;
1112              if (!field->default_value.isEmpty()) field_data2D = field->default_value ;
1113              field->outputField(field_data2D);
1114              if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ;
1115              switch (SuperClass::type)
1116              {
1117                case (MULTI_FILE) :
1118                {
1119                  SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1);
1120                  if (wtime)
1121                  {
1122                    SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1123                    SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1124                    SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1125                    SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1126                  }
1127                  break;
1128                }
1129                case (ONE_FILE) :
1130                {
1131                   std::vector<StdSize> start(2) ;
1132                   std::vector<StdSize> count(2) ;
1133                   if (domain->isEmpty())
1134                   {
1135                     start[0]=0 ; start[1]=0 ;
1136                     count[0]=0 ; count[1]=0 ;
1137                   }
1138                   else
1139                   {
1140                     start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
1141                     count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
1142                   }
1143
1144                   SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count);
1145                   if (wtime)
1146                   {
1147                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot);
1148                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot);
1149                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot);
1150                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1151                   }
1152                   break;
1153
1154                }
1155              }
1156           }
1157         }
1158         catch (CNetCdfException& e)
1159         {
1160           StdString msg("On writing field data: ");
1161           msg.append(fieldid); msg.append("\n");
1162           msg.append("In the context : ");
1163           msg.append(context->getId()); msg.append("\n");
1164           msg.append(e.what());
1165           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1166         }
1167      }
1168
1169      //---------------------------------------------------------------
1170
1171      void CNc4DataOutput::writeTimeAxis_
1172                  (CField*    field,
1173                   const boost::shared_ptr<CCalendar> cal)
1174      {
1175         StdOStringStream oss;
1176
1177//         if (field->operation.getValue().compare("once") == 0) return ;
1178         if (field->foperation->timeType() == func::CFunctor::once) return ;
1179
1180//         oss << "time_" << field->operation.getValue()
1181//             << "_" << field->getRelFile()->output_freq.getValue();
1182
1183//         StdString axisid = oss.str();
1184//         if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ;
1185//         else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ;
1186
1187         StdString axisid("time_centered") ;
1188         StdString axisBoundId("time_centered_bounds");
1189         StdString timeid("time_counter");
1190         StdString timeBoundId("axis_nbounds");
1191
1192         if (field->foperation->timeType() == func::CFunctor::instant)
1193         {
1194            axisid = "time_instant";
1195            axisBoundId = "time_instant_bounds";
1196         }
1197
1198         try
1199         {
1200          // Adding time_instant or time_centered
1201           std::vector<StdString> dims;
1202           dims.push_back(timeid);
1203           if (!SuperClassWriter::varExist(axisid))
1204           {
1205              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1206
1207              CDate timeOrigin=cal->getTimeOrigin() ;
1208              StdOStringStream oss2;
1209  //            oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" "
1210  //                <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ;
1211              StdString strInitdate=oss2.str() ;
1212              StdString strTimeOrigin=timeOrigin.toString() ;
1213              this->writeTimeAxisAttributes
1214                 (axisid, cal->getType(),
1215                  StdString("seconds since ").append(strTimeOrigin),
1216                  strTimeOrigin, axisBoundId);
1217           }
1218
1219           // Adding time_instant_bounds or time_centered_bounds variables
1220           if (!SuperClassWriter::varExist(axisBoundId))
1221           {
1222              dims.clear() ;
1223              dims.push_back(timeid);
1224              dims.push_back(timeBoundId);
1225              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1226           }
1227
1228           // Adding time_counter
1229           axisid = "time_counter" ;
1230           axisBoundId = "time_counter_bounds" ;
1231           dims.clear() ;
1232           dims.push_back(timeid);
1233           if (!SuperClassWriter::varExist(axisid))
1234           {
1235              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1236              SuperClassWriter::addAttribute("axis", string("T"), &axisid);
1237              CDate timeOrigin=cal->getTimeOrigin() ;
1238              StdString strTimeOrigin=timeOrigin.toString() ;
1239
1240              this->writeTimeAxisAttributes
1241                 (axisid, cal->getType(),
1242                  StdString("seconds since ").append(strTimeOrigin),
1243                  strTimeOrigin, axisBoundId);
1244           }
1245
1246           // Adding time_counter_bound dimension
1247           if (!SuperClassWriter::varExist(axisBoundId))
1248           {
1249              dims.clear();
1250              dims.push_back(timeid);
1251              dims.push_back(timeBoundId);
1252              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1253           }
1254         }
1255         catch (CNetCdfException& e)
1256         {
1257           StdString msg("On writing time axis data: ");
1258           msg.append("In the context : ");
1259           CContext* context = CContext::getCurrent() ;
1260           msg.append(context->getId()); msg.append("\n");
1261           msg.append(e.what());
1262           ERROR("CNc4DataOutput::writeTimeAxis_ (CField*    field, \
1263                  const boost::shared_ptr<CCalendar> cal)", << msg);
1264         }
1265      }
1266
1267      //---------------------------------------------------------------
1268
1269      void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name,
1270                                                   const StdString & calendar,
1271                                                   const StdString & units,
1272                                                   const StdString & time_origin,
1273                                                   const StdString & time_bounds,
1274                                                   const StdString & standard_name,
1275                                                   const StdString & long_name)
1276      {
1277         try
1278         {
1279           SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1280           SuperClassWriter::addAttribute("long_name",     long_name    , &axis_name);
1281           SuperClassWriter::addAttribute("calendar",      calendar     , &axis_name);
1282           SuperClassWriter::addAttribute("units",         units        , &axis_name);
1283           SuperClassWriter::addAttribute("time_origin",   time_origin  , &axis_name);
1284           SuperClassWriter::addAttribute("bounds",        time_bounds  , &axis_name);
1285         }
1286         catch (CNetCdfException& e)
1287         {
1288           StdString msg("On writing time axis Attribute: ");
1289           msg.append("In the context : ");
1290           CContext* context = CContext::getCurrent() ;
1291           msg.append(context->getId()); msg.append("\n");
1292           msg.append(e.what());
1293           ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \
1294                                                          const StdString & calendar,\
1295                                                          const StdString & units, \
1296                                                          const StdString & time_origin, \
1297                                                          const StdString & time_bounds, \
1298                                                          const StdString & standard_name, \
1299                                                          const StdString & long_name)", << msg);
1300         }
1301      }
1302
1303      //---------------------------------------------------------------
1304
1305      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
1306                                               const StdString & axis,
1307                                               const StdString & standard_name,
1308                                               const StdString & long_name,
1309                                               const StdString & units,
1310                                               const StdString & nav_model)
1311      {
1312         try
1313         {
1314          if (!axis.empty())
1315            SuperClassWriter::addAttribute("axis"       , axis         , &axis_name);
1316
1317          SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1318          SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
1319          SuperClassWriter::addAttribute("units"        , units        , &axis_name);
1320          SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
1321         }
1322         catch (CNetCdfException& e)
1323         {
1324           StdString msg("On writing Axis Attribute: ");
1325           msg.append("In the context : ");
1326           CContext* context = CContext::getCurrent() ;
1327           msg.append(context->getId()); msg.append("\n");
1328           msg.append(e.what());
1329           ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \
1330                                                      const StdString & axis, \
1331                                                      const StdString & standard_name, \
1332                                                      const StdString & long_name, \
1333                                                      const StdString & units, \
1334                                                      const StdString & nav_model)", << msg);
1335         }
1336      }
1337
1338      //---------------------------------------------------------------
1339
1340      void CNc4DataOutput::writeLocalAttributes
1341         (int ibegin, int ni, int jbegin, int nj, StdString domid)
1342      {
1343        try
1344        {
1345         SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin);
1346         SuperClassWriter::addAttribute(StdString("ni"    ).append(domid), ni);
1347         SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin);
1348         SuperClassWriter::addAttribute(StdString("nj"    ).append(domid), nj);
1349        }
1350        catch (CNetCdfException& e)
1351        {
1352           StdString msg("On writing Local Attributes: ");
1353           msg.append("In the context : ");
1354           CContext* context = CContext::getCurrent() ;
1355           msg.append(context->getId()); msg.append("\n");
1356           msg.append(e.what());
1357           ERROR("CNc4DataOutput::writeLocalAttributes \
1358                  (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg);
1359        }
1360
1361      }
1362
1363     void CNc4DataOutput::writeLocalAttributes_IOIPSL
1364         (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)
1365      {
1366         CArray<int,1> array(2) ;
1367
1368         try
1369         {
1370           SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ;
1371           SuperClassWriter::addAttribute("DOMAIN_number", rank) ;
1372           array=1,2 ;
1373           SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ;
1374           array=ni_glo,nj_glo ;
1375           SuperClassWriter::addAttribute("DOMAIN_size_global", array) ;
1376           array=ni,nj ;
1377           SuperClassWriter::addAttribute("DOMAIN_size_local", array) ;
1378           array=ibegin,jbegin ;
1379           SuperClassWriter::addAttribute("DOMAIN_position_first", array) ;
1380           array=ibegin+ni-1,jbegin+nj-1 ;
1381           SuperClassWriter::addAttribute("DOMAIN_position_last",array) ;
1382           array=0,0 ;
1383           SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ;
1384           SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array);
1385           SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ;
1386  /*
1387           SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ;
1388           SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ;
1389           SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ;
1390           SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ;
1391  */
1392         }
1393         catch (CNetCdfException& e)
1394         {
1395           StdString msg("On writing Local Attributes IOI PSL \n");
1396           msg.append("In the context : ");
1397           CContext* context = CContext::getCurrent() ;
1398           msg.append(context->getId()); msg.append("\n");
1399           msg.append(e.what());
1400           ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \
1401                  (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg);
1402         }
1403      }
1404      //---------------------------------------------------------------
1405
1406      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
1407                                                const StdString & description,
1408                                                const StdString & conventions,
1409                                                const StdString & production,
1410                                                const StdString & timeStamp)
1411      {
1412         try
1413         {
1414           SuperClassWriter::addAttribute("name"       , name);
1415           SuperClassWriter::addAttribute("description", description);
1416           SuperClassWriter::addAttribute("title"      , description);
1417           SuperClassWriter::addAttribute("Conventions", conventions);
1418           SuperClassWriter::addAttribute("production" , production);
1419           SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
1420         }
1421         catch (CNetCdfException& e)
1422         {
1423           StdString msg("On writing File Attributes \n ");
1424           msg.append("In the context : ");
1425           CContext* context = CContext::getCurrent() ;
1426           msg.append(context->getId()); msg.append("\n");
1427           msg.append(e.what());
1428           ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \
1429                                                const StdString & description, \
1430                                                const StdString & conventions, \
1431                                                const StdString & production, \
1432                                                const StdString & timeStamp)", << msg);
1433         }
1434      }
1435
1436      //---------------------------------------------------------------
1437
1438      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
1439                                               int data_dim,
1440                                               int data_ni,
1441                                               int data_nj,
1442                                               int data_ibegin,
1443                                               int data_jbegin)
1444      {
1445         try
1446         {
1447           SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
1448           SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
1449           SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
1450           SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
1451           SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
1452         }
1453         catch (CNetCdfException& e)
1454         {
1455           StdString msg("On writing Mask Attributes \n ");
1456           msg.append("In the context : ");
1457           CContext* context = CContext::getCurrent() ;
1458           msg.append(context->getId()); msg.append("\n");
1459           msg.append(e.what());
1460           ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \
1461                                               int data_dim, \
1462                                               int data_ni, \
1463                                               int data_nj, \
1464                                               int data_ibegin, \
1465                                               int data_jbegin)", << msg);
1466         }
1467      }
1468
1469      ///--------------------------------------------------------------
1470
1471} // namespace xios
Note: See TracBrowser for help on using the repository browser.