source: XIOS/trunk/src/output/nc4_data_output.cpp @ 527

Last change on this file since 527 was 527, checked in by rlacroix, 7 years ago

Make the variable typing stricter.

The type must now be one of:

  • bool
  • int or int32
  • int16
  • int64
  • float
  • double
  • string

WARNING: The variable type was previously not checked and using an unsupported type did not lead to any error message. Be aware that this change can make your existing configuration files invalid. However the adjustments required to adapt existing files should be minor.

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