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

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

Support NetCDF4 compression.

Only available for non-parallel output so either if only one server is used or if the multiple file mode is enabled).

  • 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: 75.5 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
121  //                 SuperClassWriter::addDimension(lonid, domain->zoom_ni.getValue());
122  //                 SuperClassWriter::addDimension(latid, domain->zoom_nj.getValue());
123                 }
124
125                 switch (domain->type)
126                 {
127                   case CDomain::type_attr::curvilinear :
128                     dim0.push_back(dimYid); dim0.push_back(dimXid);
129                     lonid = StdString("nav_lon").append(appendDomid);
130                     latid = StdString("nav_lat").append(appendDomid);
131                     break ;
132                   case CDomain::type_attr::regular :
133                     lonid = StdString("lon").append(appendDomid);
134                     latid = StdString("lat").append(appendDomid);
135                     dim0.push_back(dimYid);
136                     dim1.push_back(dimXid);
137                     break;
138                   case CDomain::type_attr::unstructured :
139                     lonid = StdString("lon").append(appendDomid);
140                     latid = StdString("lat").append(appendDomid);
141                     bounds_lonid=string("bounds_lon").append(appendDomid);
142                     bounds_latid=string("bounds_lat").append(appendDomid);
143                     dim0.push_back(dimXid);
144                     break;
145                 }
146
147                 if (domain->type == CDomain::type_attr::unstructured)
148                 {
149                   SuperClassWriter::addDimension(dimXid, domain->nj_glo);
150                 }
151                 else
152                 {
153                   SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
154                   SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv);
155                 }
156
157                 if (server->intraCommSize > 1)
158                 {
159                    if (domain->type != CDomain::type_attr::unstructured)
160                    {
161                      this->writeLocalAttributes(domain->zoom_ibegin_srv,
162                                                 domain->zoom_ni_srv,
163                                                 domain->zoom_jbegin_srv,
164                                                 domain->zoom_nj_srv,
165                                                 appendDomid);
166
167                      if (singleDomain) this->writeLocalAttributes_IOIPSL(domain->zoom_ibegin_srv,
168                                                 domain->zoom_ni_srv,
169                                                 domain->zoom_jbegin_srv,
170                                                 domain->zoom_nj_srv,
171                                                 domain->ni_glo,domain->nj_glo,
172                                                 server->intraCommRank,server->intraCommSize);
173                   }
174                 }
175
176                 switch (domain->type)
177                 {
178                   case CDomain::type_attr::curvilinear :
179                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
180                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
181                     break ;
182                    case CDomain::type_attr::regular :
183                      SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
184                      SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
185                      break ;
186                    case CDomain::type_attr::unstructured :
187                      SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
188                      SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
189                 }
190
191                 this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
192                 this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
193
194                 dim0.clear();
195                 if (domain->type != CDomain::type_attr::unstructured) dim0.push_back(dimYid);
196                 dim0.push_back(dimXid);
197
198
199  // supress mask               if (server->intraCommSize > 1)
200  // supress mask               {
201  // supress mask                  SuperClassWriter::addVariable(maskid, NC_INT, dim0);
202  // supress mask
203  // supress mask                  this->writeMaskAttributes(maskid,
204  // supress mask                     domain->data_dim.getValue()/*,
205  // supress mask                     domain->data_ni.getValue(),
206  // supress mask                     domain->data_nj.getValue(),
207  // supress mask                     domain->data_ibegin.getValue(),
208  // supress mask                     domain->data_jbegin.getValue()*/);
209  // supress mask               }
210
211                 //SuperClassWriter::setDefaultValue(maskid, &dvm);
212
213                 SuperClassWriter::definition_end();
214
215                 switch (domain->type)
216                 {
217                   case CDomain::type_attr::curvilinear :
218                     SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
219                     SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
220                     break;
221                   case CDomain::type_attr::regular :
222                     CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
223                     SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
224                     CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
225                     SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
226                     break;
227                 }
228                 SuperClassWriter::definition_start();
229
230                 break;
231              }
232              case (ONE_FILE) :
233              {
234                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni.getValue());
235                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj.getValue());
236
237
238                 switch (domain->type)
239                 {
240                   case CDomain::type_attr::curvilinear :
241                     dim0.push_back(dimYid); dim0.push_back(dimXid);
242                     lonid = StdString("nav_lon").append(appendDomid);
243                     latid = StdString("nav_lat").append(appendDomid);
244                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
245                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
246                     break;
247
248                   case CDomain::type_attr::regular :
249                     dim0.push_back(dimYid);
250                     dim1.push_back(dimXid);
251                     lonid = StdString("lon").append(appendDomid);
252                     latid = StdString("lat").append(appendDomid);
253                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
254                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
255                     break;
256                 }
257                 this->writeAxisAttributes
258                    (lonid, "X", "longitude", "Longitude", "degrees_east", domid);
259                 this->writeAxisAttributes
260                    (latid, "Y", "latitude", "Latitude", "degrees_north", domid);
261
262
263                 SuperClassWriter::definition_end();
264                 switch (domain->type)
265                 {
266                   case CDomain::type_attr::curvilinear :
267                   {
268                     std::vector<StdSize> start(2) ;
269                     std::vector<StdSize> count(2) ;
270                     if (domain->isEmpty())
271                     {
272                       start[0]=0 ; start [1]=0 ;
273                       count[0]=0 ; count[1]=0 ;
274                     }
275                     else
276                     {
277                       start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
278                       count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
279                     }
280
281                     SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
282                     SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
283                     break;
284                   }
285                   case CDomain::type_attr::regular :
286                   {
287                     std::vector<StdSize> start(1) ;
288                     std::vector<StdSize> count(1) ;
289                     if (domain->isEmpty())
290                     {
291                       start[0]=0 ;
292                       count[0]=0 ;
293                       SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
294                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);                 }
295                     else
296                     {
297                       start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
298                       count[0]=domain->zoom_nj_srv ;
299                       CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
300                       SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
301
302                       start[0]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ;
303                       count[0]=domain->zoom_ni_srv ;
304                       CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
305                       SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
306                     }
307                     break;
308                   }
309                 }
310                 SuperClassWriter::definition_start();
311                 break;
312              }
313              default :
314                 ERROR("CNc4DataOutput::writeDomain(domain)",
315                       << "[ type = " << SuperClass::type << "]"
316                       << " not implemented yet !");
317           }
318         }
319         catch (CNetCdfException& e)
320         {
321           StdString msg("On writing the domain : ");
322           msg.append(domid); msg.append("\n");
323           msg.append("In the context : ");
324           msg.append(context->getId()); msg.append("\n");
325           msg.append(e.what());
326           ERROR("CNc4DataOutput::writeDomain_(CDomain* domain)", << msg);
327         }
328
329         domain->addRelFile(this->filename);
330      }
331
332      void CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)
333      {
334         CContext* context = CContext::getCurrent() ;
335         CContextServer* server=context->server ;
336
337         if (domain->IsWritten(this->filename)) return;
338         domain->checkAttributes();
339
340         if (domain->isEmpty())
341           if (SuperClass::type==MULTI_FILE) return ;
342
343         std::vector<StdString> dim0, dim1;
344         StdString domid     = (!domain->name.isEmpty())
345                             ? domain->name.getValue() : domain->getId();
346         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
347
348
349         StdString dimXid = StdString("cell").append(appendDomid);
350         StdString dimVertId = StdString("nvertex").append(appendDomid);
351
352         string lonid,latid,bounds_lonid,bounds_latid ;
353
354         try
355         {
356           switch (SuperClass::type)
357           {
358              case (MULTI_FILE) :
359              {
360                 lonid = StdString("lon").append(appendDomid);
361                 latid = StdString("lat").append(appendDomid);
362                 dim0.push_back(dimXid);
363
364                 SuperClassWriter::addDimension(dimXid, domain->zoom_nj_srv);
365                 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
366                 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
367
368                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
369                 bounds_latid = StdString("bounds_lat").append(appendDomid);
370
371
372                 this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
373                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
374                 this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
375                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
376                 if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
377                 dim0.clear();
378                 if (domain->hasBounds)
379                 {
380                   dim0.push_back(dimXid);
381                   dim0.push_back(dimVertId);
382                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
383                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
384                 }
385
386                 dim0.clear();
387                 dim0.push_back(dimXid);
388
389                 SuperClassWriter::definition_end();
390
391                 SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
392                 SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
393
394                 if (domain->hasBounds)
395                 {
396                   SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
397                   SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
398                 }
399                 SuperClassWriter::definition_start();
400                 break ;
401              }
402
403              case (ONE_FILE) :
404              {
405                 lonid = StdString("lon").append(appendDomid);
406                 latid = StdString("lat").append(appendDomid);
407                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
408                 bounds_latid = StdString("bounds_lat").append(appendDomid);
409                 dim0.push_back(dimXid);
410                 SuperClassWriter::addDimension(dimXid, domain->nj_glo);
411                 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
412                 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
413                 this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
414                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
415                 this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
416                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
417                 if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
418                 dim0.clear();
419
420                 if (domain->hasBounds)
421                 {
422                   dim0.push_back(dimXid);
423                   dim0.push_back(dimVertId);
424                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
425                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
426                 }
427
428                 SuperClassWriter::definition_end();
429
430                 std::vector<StdSize> start(1), startBounds(2) ;
431                 std::vector<StdSize> count(1), countBounds(2) ;
432                 if (domain->isEmpty())
433                 {
434                   start[0]=0 ;
435                   count[0]=0 ;
436                   startBounds[1]=0 ;
437                   countBounds[1]=domain->nvertex ;
438                   startBounds[0]=0 ;
439                   countBounds[0]=0 ;
440                 }
441                 else
442                 {
443                   start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
444                   count[0]=domain->zoom_nj_srv ;
445                   startBounds[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
446                   startBounds[1]=0 ;
447                   countBounds[0]=domain->zoom_nj_srv ;
448                   countBounds[1]=domain->nvertex ;
449                 }
450                 SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
451                 SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
452                 if (domain->hasBounds)
453                 {
454                   SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
455                   SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds);
456                 }
457
458
459                 SuperClassWriter::definition_start();
460
461                 break;
462              }
463              default :
464                 ERROR("CNc4DataOutput::writeDomain(domain)",
465                       << "[ type = " << SuperClass::type << "]"
466                       << " not implemented yet !");
467           }
468         }
469         catch (CNetCdfException& e)
470         {
471           StdString msg("On writing the domain : ");
472           msg.append(domid); msg.append("\n");
473           msg.append("In the context : ");
474           msg.append(context->getId()); msg.append("\n");
475           msg.append(e.what());
476           ERROR("CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)", << msg);
477         }
478         domain->addRelFile(this->filename);
479      }
480      //--------------------------------------------------------------
481
482      void CNc4DataOutput::writeAxis_(CAxis* axis)
483      {
484         if (axis->IsWritten(this->filename)) return;
485         axis->checkAttributes();
486         StdSize zoom_size_srv=axis->zoom_size_srv;
487         StdSize zoom_begin_srv=axis->zoom_begin_srv;
488         StdSize zoom_size  = (MULTI_FILE == SuperClass::type) ? zoom_size_srv
489                                                              : axis->zoom_size;
490         StdSize zoom_begin = (MULTI_FILE == SuperClass::type) ? zoom_begin_srv
491                                                              : axis->zoom_begin;
492
493
494         std::vector<StdString> dims;
495         StdString axisid = (!axis->name.isEmpty())
496                             ? axis->name.getValue() : axis->getId();
497         try
498         {
499           SuperClassWriter::addDimension(axisid, zoom_size);
500           dims.push_back(axisid);
501
502           switch (SuperClass::type)
503           {
504              case (MULTI_FILE ) :
505              {}
506              case (ONE_FILE) :
507              {
508                 SuperClassWriter::addVariable(axisid, NC_FLOAT, dims);
509
510                 SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid);
511
512                 if (!axis->name.isEmpty())
513                    SuperClassWriter::addAttribute
514                       ("name", axis->name.getValue(), &axisid);
515
516                 if (!axis->standard_name.isEmpty())
517                    SuperClassWriter::addAttribute
518                       ("standard_name",  axis->standard_name.getValue(), &axisid);
519
520                 if (!axis->long_name.isEmpty())
521                    SuperClassWriter::addAttribute
522                       ("long_name", axis->long_name.getValue(), &axisid);
523
524                 if (!axis->unit.isEmpty())
525                    SuperClassWriter::addAttribute
526                       ("units", axis->unit.getValue(), &axisid);
527
528                if (!axis->positive.isEmpty())
529                  if (axis->positive==CAxis::positive_attr::up) SuperClassWriter::addAttribute("positive", string("up"), &axisid);
530                  else   SuperClassWriter::addAttribute("positive", string("down"), &axisid);
531
532                 SuperClassWriter::definition_end();
533
534                 CArray<double,1> axis_value(zoom_size) ;
535                 for(StdSize i = 0 ; i < zoom_size_srv ; i++) axis_value(i)=axis->value(i+zoom_begin_srv) ;
536                 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
537
538                 SuperClassWriter::definition_start();
539
540                 break;
541              }
542              default :
543                 ERROR("CNc4DataOutput::writeDomain(domain)",
544                       << "[ type = " << SuperClass::type << "]"
545                       << " not implemented yet !");
546           }
547         }
548         catch (CNetCdfException& e)
549         {
550           StdString msg("On writing the axis : ");
551           msg.append(axisid); msg.append("\n");
552           msg.append("In the context : ");
553           CContext* context = CContext::getCurrent() ;
554           msg.append(context->getId()); msg.append("\n");
555           msg.append(e.what());
556           ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg);
557         }
558         axis->addRelFile(this->filename);
559     }
560
561     void CNc4DataOutput::writeTimeDimension_(void)
562     {
563       try
564       {
565        SuperClassWriter::addDimension("time_counter");
566        SuperClassWriter::addDimension("time_bounds", 2);
567       }
568       catch (CNetCdfException& e)
569       {
570         StdString msg("On writing time dimension : time_couter, time_bounds \n");
571         msg.append("In the context : ");
572         CContext* context = CContext::getCurrent() ;
573         msg.append(context->getId()); msg.append("\n");
574         msg.append(e.what());
575         ERROR("CNc4DataOutput::writeTimeDimension_(void)", << msg);
576       }
577     }
578      //--------------------------------------------------------------
579
580      void CNc4DataOutput::writeField_(CField* field)
581      {
582         CContext* context = CContext::getCurrent() ;
583         CContextServer* server=context->server ;
584
585         std::vector<StdString> dims, coodinates;
586         CGrid* grid = field->grid;
587         if (!grid->doGridHaveDataToWrite())
588          if (SuperClass::type==MULTI_FILE) return ;
589
590         CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
591         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0;
592         std::vector<StdString> domainList = grid->getDomainList();
593         std::vector<StdString> axisList   = grid->getAxisList();
594
595         StdString timeid  = StdString("time_counter");
596         StdString dimXid,dimYid;
597         std::deque<StdString> dimIdList, dimCoordList;
598
599         for (int i = 0; i < numElement; ++i)
600         {
601           if (axisDomainOrder(i))
602           {
603             CDomain* domain = CDomain::get(domainList[idxDomain]);
604             StdString domid = (!domain->name.isEmpty())
605                                 ? domain->name.getValue() : domain->getId();
606             StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
607             switch (domain->type)
608             {
609               case CDomain::type_attr::curvilinear :
610                 dimXid     = StdString("x").append(appendDomid);
611                 dimIdList.push_back(dimXid);
612                 dimYid     = StdString("y").append(appendDomid);
613                 dimIdList.push_back(dimYid);
614                 dimCoordList.push_back(StdString("nav_lon").append(appendDomid));
615                 dimCoordList.push_back(StdString("nav_lat").append(appendDomid));
616                 break ;
617               case CDomain::type_attr::regular :
618                 dimXid     = StdString("lon").append(appendDomid);
619                 dimIdList.push_back(dimXid);
620                 dimYid     = StdString("lat").append(appendDomid);
621                 dimIdList.push_back(dimYid);
622                 break ;
623               case CDomain::type_attr::unstructured :
624                 dimXid     = StdString("cell").append(appendDomid);
625                 dimIdList.push_back(dimXid);
626                 dimCoordList.push_back(StdString("lon").append(appendDomid));
627                 dimCoordList.push_back(StdString("lat").append(appendDomid));
628                 break ;
629            }
630            ++idxDomain;
631           }
632           else
633           {
634             CAxis* axis = CAxis::get(axisList[idxAxis]);
635             StdString axisid = (!axis->name.isEmpty())
636                                ? axis->name.getValue() : axis->getId();
637             dimIdList.push_back(axisid);
638             dimCoordList.push_back(axisid);
639            ++idxAxis;
640           }
641         }
642
643/*
644         StdString lonid_loc = (server->intraCommSize > 1)
645                             ? StdString("lon").append(appendDomid).append("_local")
646                             : lonid;
647         StdString latid_loc = (server->intraCommSize > 1)
648                             ? StdString("lat").append(appendDomid).append("_local")
649                             : latid;
650*/
651         StdString fieldid   = (!field->name.isEmpty())
652                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
653
654//         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
655//         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
656//          bool isCurvilinear = domain->isCurvilinear ;
657
658         nc_type type ;
659         if (field->prec.isEmpty()) type =  NC_FLOAT ;
660         else
661         {
662           if (field->prec==2) type = NC_SHORT ;
663           else if (field->prec==4)  type =  NC_FLOAT ;
664           else if (field->prec==8)   type =  NC_DOUBLE ;
665         }
666
667         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
668
669         if (wtime)
670         {
671
672            //StdOStringStream oss;
673           // oss << "time_" << field->operation.getValue()
674           //     << "_" << field->getRelFile()->output_freq.getValue();
675          //oss
676            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
677            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
678            dims.push_back(timeid);
679         }
680
681         while (!dimIdList.empty())
682         {
683           dims.push_back(dimIdList.back());
684           dimIdList.pop_back();
685         }
686
687         while (!dimCoordList.empty())
688         {
689           coodinates.push_back(dimCoordList.back());
690           dimCoordList.pop_back();
691         }
692
693         try
694         {
695           SuperClassWriter::addVariable(fieldid, type, dims);
696
697           if (!field->standard_name.isEmpty())
698              SuperClassWriter::addAttribute
699                 ("standard_name",  field->standard_name.getValue(), &fieldid);
700
701           if (!field->long_name.isEmpty())
702              SuperClassWriter::addAttribute
703                 ("long_name", field->long_name.getValue(), &fieldid);
704
705           if (!field->unit.isEmpty())
706              SuperClassWriter::addAttribute
707                 ("units", field->unit.getValue(), &fieldid);
708
709            if (!field->valid_min.isEmpty())
710              SuperClassWriter::addAttribute
711                 ("valid_min", field->valid_min.getValue(), &fieldid);
712
713           if (!field->valid_max.isEmpty())
714              SuperClassWriter::addAttribute
715                 ("valid_max", field->valid_max.getValue(), &fieldid);
716
717            if (!field->scale_factor.isEmpty())
718              SuperClassWriter::addAttribute
719                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
720
721             if (!field->add_offset.isEmpty())
722              SuperClassWriter::addAttribute
723                 ("add_offset", field->add_offset.getValue(), &fieldid);
724
725           SuperClassWriter::addAttribute
726                 ("online_operation", field->operation.getValue(), &fieldid);
727
728          // write child variables as attributes
729
730
731           vector<CVariable*> listVars = field->getAllVariables() ;
732           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
733
734
735           if (wtime)
736           {
737              CDuration duration = field->freq_op.getValue();
738              duration.solveTimeStep(*(context->calendar));
739              SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid);
740
741              duration = field->getRelFile()->output_freq.getValue();
742              duration.solveTimeStep(*(context->calendar));
743              SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid);
744           }
745
746           if (!field->default_value.isEmpty())
747           {
748              double default_value = field->default_value.getValue();
749              float fdefault_value = (float)default_value;
750              if (type == NC_DOUBLE)
751                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
752              else
753                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
754           }
755           else
756              SuperClassWriter::setDefaultValue(fieldid, (double*)NULL);
757
758            if (field->compression_level.isEmpty())
759              field->compression_level = field->file->compression_level.isEmpty() ? 0 : field->file->compression_level;
760            if (field->compression_level < 0 || field->compression_level > 9)
761              ERROR("void CNc4DataOutput::writeField_(CField* field)",
762                    "Invalid compression level, the value should range between 0 and 9.");
763            SuperClassWriter::setCompressionLevel(fieldid, field->compression_level);
764
765           {  // Ecriture des coordonnées
766
767              StdString coordstr; //boost::algorithm::join(coodinates, " ")
768              std::vector<StdString>::iterator
769                 itc = coodinates.begin(), endc = coodinates.end();
770
771              for (; itc!= endc; itc++)
772              {
773                 StdString & coord = *itc;
774                 if (itc+1 != endc)
775                       coordstr.append(coord).append(" ");
776                 else  coordstr.append(coord);
777              }
778
779              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
780
781           }
782         }
783         catch (CNetCdfException& e)
784         {
785           StdString msg("On writing field : ");
786           msg.append(fieldid); msg.append("\n");
787           msg.append("In the context : ");
788           msg.append(context->getId()); msg.append("\n");
789           msg.append(e.what());
790           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
791         }
792      }
793
794
795//      void CNc4DataOutput::writeField_(CField* field)
796//      {
797//         CContext* context = CContext::getCurrent() ;
798//         CContextServer* server=context->server ;
799//
800//         std::vector<StdString> dims, coodinates;
801//         CGrid* grid = field->grid;
802//         CDomain* domain = grid->domain;
803//
804//         if (domain->isEmpty())
805//           if (SuperClass::type==MULTI_FILE) return ;
806//
807//         StdString timeid    = StdString("time_counter");
808//         StdString domid     = (!domain->name.isEmpty())
809//                             ? domain->name.getValue() : domain->getId();
810//         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
811//
812////         bool isCurvilinear = domain->isCurvilinear ;
813////         bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ;
814//
815//         StdString dimXid,dimYid ;
816//
817//         switch (domain->type)
818//         {
819//           case CDomain::type_attr::curvilinear :
820//             dimXid     = StdString("x").append(appendDomid);
821//             dimYid     = StdString("y").append(appendDomid);
822//             break ;
823//           case CDomain::type_attr::regular :
824//             dimXid     = StdString("lon").append(appendDomid);
825//             dimYid     = StdString("lat").append(appendDomid);
826//             break ;
827//           case CDomain::type_attr::unstructured :
828//             dimXid     = StdString("cell").append(appendDomid);
829//             break ;
830//        }
831//
832///*
833//         StdString lonid_loc = (server->intraCommSize > 1)
834//                             ? StdString("lon").append(appendDomid).append("_local")
835//                             : lonid;
836//         StdString latid_loc = (server->intraCommSize > 1)
837//                             ? StdString("lat").append(appendDomid).append("_local")
838//                             : latid;
839//*/
840//         StdString fieldid   = (!field->name.isEmpty())
841//                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
842//
843////         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
844////         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
845////          bool isCurvilinear = domain->isCurvilinear ;
846//
847//         nc_type type ;
848//         if (field->prec.isEmpty()) type =  NC_FLOAT ;
849//         else
850//         {
851//           if (field->prec==2) type = NC_SHORT ;
852//           else if (field->prec==4)  type =  NC_FLOAT ;
853//           else if (field->prec==8)   type =  NC_DOUBLE ;
854//         }
855//
856//         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
857//
858//         if (wtime)
859//         {
860//
861//            //StdOStringStream oss;
862//           // oss << "time_" << field->operation.getValue()
863//           //     << "_" << field->getRelFile()->output_freq.getValue();
864//          //oss
865//            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
866//            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
867//            dims.push_back(timeid);
868//         }
869//
870//         std::vector<StdString> axisList = grid->getAxisList();
871//         if (!axisList.empty())
872//         {
873//           std::vector<StdString>::const_iterator itAxis = axisList.begin(), iteAxis = axisList.end();
874//           for (; itAxis != iteAxis; ++itAxis)
875//           {
876//             CAxis* axis = CAxis::get(*itAxis);
877//             StdString axisid = (!axis->name.isEmpty())
878//                                ? axis->name.getValue() : axis->getId();
879//
880//             dims.push_back(axisid);
881//             coodinates.push_back(axisid);
882//           }
883//         }
884//
885//         switch (domain->type)
886//         {
887//           case CDomain::type_attr::curvilinear :
888//             coodinates.push_back(StdString("nav_lon").append(appendDomid));
889//             coodinates.push_back(StdString("nav_lat").append(appendDomid));
890//             break;
891//           case CDomain::type_attr::regular :
892//           case CDomain::type_attr::unstructured :
893//            coodinates.push_back(StdString("lon").append(appendDomid));
894//            coodinates.push_back(StdString("lat").append(appendDomid));
895//             break;
896//         }
897//
898//         if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid);
899//         dims.push_back(dimXid);
900//
901//         try
902//         {
903//           SuperClassWriter::addVariable(fieldid, type, dims);
904//
905//           if (!field->standard_name.isEmpty())
906//              SuperClassWriter::addAttribute
907//                 ("standard_name",  field->standard_name.getValue(), &fieldid);
908//
909//           if (!field->long_name.isEmpty())
910//              SuperClassWriter::addAttribute
911//                 ("long_name", field->long_name.getValue(), &fieldid);
912//
913//           if (!field->unit.isEmpty())
914//              SuperClassWriter::addAttribute
915//                 ("units", field->unit.getValue(), &fieldid);
916//
917//            if (!field->valid_min.isEmpty())
918//              SuperClassWriter::addAttribute
919//                 ("valid_min", field->valid_min.getValue(), &fieldid);
920//
921//           if (!field->valid_max.isEmpty())
922//              SuperClassWriter::addAttribute
923//                 ("valid_max", field->valid_max.getValue(), &fieldid);
924//
925//            if (!field->scale_factor.isEmpty())
926//              SuperClassWriter::addAttribute
927//                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
928//
929//             if (!field->add_offset.isEmpty())
930//              SuperClassWriter::addAttribute
931//                 ("add_offset", field->add_offset.getValue(), &fieldid);
932//
933//           SuperClassWriter::addAttribute
934//                 ("online_operation", field->operation.getValue(), &fieldid);
935//
936//          // write child variables as attributes
937//
938//
939//           vector<CVariable*> listVars = field->getAllVariables() ;
940//           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
941//
942//
943//           if (wtime)
944//           {
945//              CDuration duration = field->freq_op.getValue();
946//              duration.solveTimeStep(*(context->calendar));
947//              SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid);
948//
949//              duration = field->getRelFile()->output_freq.getValue();
950//              duration.solveTimeStep(*(context->calendar));
951//              SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid);
952//           }
953//
954//           if (!field->default_value.isEmpty())
955//           {
956//              double default_value = field->default_value.getValue();
957//              float fdefault_value = (float)default_value;
958//              if (type == NC_DOUBLE)
959//                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
960//              else
961//                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
962//           }
963//           else
964//              SuperClassWriter::setDefaultValue(fieldid, (double*)NULL);
965//
966//           {  // Ecriture des coordonnées
967//
968//              StdString coordstr; //boost::algorithm::join(coodinates, " ")
969//              std::vector<StdString>::iterator
970//                 itc = coodinates.begin(), endc = coodinates.end();
971//
972//              for (; itc!= endc; itc++)
973//              {
974//                 StdString & coord = *itc;
975//                 if (itc+1 != endc)
976//                       coordstr.append(coord).append(" ");
977//                 else  coordstr.append(coord);
978//              }
979//
980//              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
981//
982//           }
983//         }
984//         catch (CNetCdfException& e)
985//         {
986//           StdString msg("On writing field : ");
987//           msg.append(fieldid); msg.append("\n");
988//           msg.append("In the context : ");
989//           msg.append(context->getId()); msg.append("\n");
990//           msg.append(e.what());
991//           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
992//         }
993//      }
994
995      //--------------------------------------------------------------
996
997      void CNc4DataOutput::writeFile_ (CFile* file)
998      {
999         StdString filename = (!file->name.isEmpty())
1000                            ? file->name.getValue() : file->getId();
1001         StdString description = (!file->description.isEmpty())
1002                               ? file->description.getValue()
1003                               : StdString("Created by xios");
1004         try
1005         {
1006           this->writeFileAttributes(filename, description,
1007                                     StdString ("CF-1.1"),
1008                                     StdString("An IPSL model"),
1009                                     this->getTimeStamp());
1010         }
1011         catch (CNetCdfException& e)
1012         {
1013           StdString msg("On writing file : ");
1014           msg.append(filename); msg.append("\n");
1015           msg.append("In the context : ");
1016           CContext* context = CContext::getCurrent() ;
1017           msg.append(context->getId()); msg.append("\n");
1018           msg.append(e.what());
1019           ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg);
1020         }
1021         if (file->nbDomain==1) singleDomain=true ;
1022         else singleDomain=false ;
1023      }
1024
1025      void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)
1026      {
1027        string name ;
1028        if (!var->name.isEmpty()) name=var->name ;
1029        else if (var->hasId()) name=var->getId() ;
1030        else return ;
1031
1032        try
1033        {
1034          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1035            addAttribute(name, var->getData<int>(), &fieldId);
1036          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1037            addAttribute(name, var->getData<short int>(), &fieldId);
1038          else if (var->type.getValue() == CVariable::type_attr::t_float)
1039            addAttribute(name, var->getData<float>(), &fieldId);
1040          else if (var->type.getValue() == CVariable::type_attr::t_double)
1041            addAttribute(name, var->getData<double>(), &fieldId);
1042          else if (var->type.getValue() == CVariable::type_attr::t_string)
1043            addAttribute(name, var->getData<string>(), &fieldId);
1044          else
1045            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)",
1046                  << "Unsupported variable of type " << var->type.getStringValue());
1047        }
1048       catch (CNetCdfException& e)
1049       {
1050         StdString msg("On writing attributes of variable with name : ");
1051         msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n");
1052         msg.append("In the context : ");
1053         CContext* context = CContext::getCurrent() ;
1054         msg.append(context->getId()); msg.append("\n");
1055         msg.append(e.what());
1056         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg);
1057       }
1058     }
1059
1060     void CNc4DataOutput::writeAttribute_ (CVariable* var)
1061     {
1062        string name ;
1063        if (!var->name.isEmpty()) name=var->name ;
1064        else if (var->hasId()) name=var->getId() ;
1065        else return ;
1066        try
1067        {
1068          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1069            addAttribute(name, var->getData<int>());
1070          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1071            addAttribute(name, var->getData<short int>());
1072          else if (var->type.getValue() == CVariable::type_attr::t_float)
1073            addAttribute(name, var->getData<float>());
1074          else if (var->type.getValue() == CVariable::type_attr::t_double)
1075            addAttribute(name, var->getData<double>());
1076          else if (var->type.getValue() == CVariable::type_attr::t_string)
1077            addAttribute(name, var->getData<string>());
1078          else
1079            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)",
1080                  << "Unsupported variable of type " << var->type.getStringValue());
1081        }
1082       catch (CNetCdfException& e)
1083       {
1084         StdString msg("On writing attributes of variable with name : ");
1085         msg.append(name); msg.append("\n");
1086         msg.append("In the context : ");
1087         CContext* context = CContext::getCurrent() ;
1088         msg.append(context->getId()); msg.append("\n");
1089         msg.append(e.what());
1090         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg);
1091       }
1092     }
1093
1094      void CNc4DataOutput::syncFile_ (void)
1095      {
1096        try
1097        {
1098          SuperClassWriter::sync() ;
1099        }
1100        catch (CNetCdfException& e)
1101        {
1102         StdString msg("On synchronizing the write among processes");
1103         msg.append("In the context : ");
1104         CContext* context = CContext::getCurrent() ;
1105         msg.append(context->getId()); msg.append("\n");
1106         msg.append(e.what());
1107         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1108        }
1109      }
1110
1111      void CNc4DataOutput::closeFile_ (void)
1112      {
1113        try
1114        {
1115          SuperClassWriter::close() ;
1116        }
1117        catch (CNetCdfException& e)
1118        {
1119         StdString msg("On closing file");
1120         msg.append("In the context : ");
1121         CContext* context = CContext::getCurrent() ;
1122         msg.append(context->getId()); msg.append("\n");
1123         msg.append(e.what());
1124         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1125        }
1126
1127      }
1128
1129      //---------------------------------------------------------------
1130
1131      StdString CNc4DataOutput::getTimeStamp(void) const
1132      {
1133         const int buffer_size = 100;
1134         time_t rawtime;
1135         struct tm * timeinfo = NULL;
1136         char buffer [buffer_size];
1137
1138         time ( &rawtime );
1139         timeinfo = localtime ( &rawtime );
1140         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
1141
1142         return (StdString(buffer));
1143      }
1144
1145      //---------------------------------------------------------------
1146
1147      void CNc4DataOutput::writeFieldData_ (CField*  field)
1148      {
1149         CContext* context = CContext::getCurrent() ;
1150//          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
1151         CContextServer* server=context->server ;
1152
1153         CGrid* grid = field->grid ;
1154
1155         if (!grid->doGridHaveDataToWrite())
1156          if (SuperClass::type==MULTI_FILE || !isCollective) return ;
1157
1158         StdString fieldid   = (!field->name.isEmpty())
1159                             ? field->name.getValue()
1160                             : field->getBaseFieldReference()->getId();
1161
1162         StdOStringStream oss;
1163         string timeAxisId ;
1164         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
1165         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
1166
1167         StdString timeBoundId("time_counter_bounds");
1168
1169         StdString timeAxisBoundId;
1170         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
1171         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
1172
1173         CArray<double,1> time_data(1) ;
1174         CArray<double,1> time_counter(1) ;
1175         CArray<double,1> time_counter_bound(2);
1176         CArray<double,1> time_data_bound(2);
1177
1178        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
1179
1180        if (wtime)
1181        {
1182          time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2;
1183          if (field->foperation->timeType() == func::CFunctor::instant)
1184            time_data(0) = Time(*field->last_Write_srv);
1185          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
1186
1187          time_counter_bound(0) = Time(*field->lastlast_Write_srv);
1188          time_counter_bound(1) = Time(*field->last_Write_srv);
1189          if (field->foperation->timeType() == func::CFunctor::instant)
1190            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv);
1191          else if (field->foperation->timeType() == func::CFunctor::centered)
1192          {
1193            time_data_bound(0) = time_counter_bound(0);
1194            time_data_bound(1) = time_counter_bound(1);
1195          }
1196         }
1197
1198         bool isRoot ;
1199         if (server->intraCommRank==0) isRoot=true ;
1200         else isRoot=false ;
1201
1202         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1203         {
1204           double scaleFactor=1. ;
1205           double addOffset=0. ;
1206           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
1207           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
1208           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
1209         }
1210
1211         try
1212         {
1213           CArray<double,1> fieldData(grid->getWrittenDataSize());
1214           if (!field->default_value.isEmpty()) fieldData = field->default_value;
1215           field->outputField(fieldData);
1216           if (!field->prec.isEmpty() && field->prec==2) fieldData=round(fieldData) ;
1217
1218           switch (SuperClass::type)
1219           {
1220              case (MULTI_FILE) :
1221              {
1222                 SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1);
1223                 if (wtime)
1224                 {
1225                   SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1226                   SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1227                   SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1228                   SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1229                 }
1230                 break ;
1231              }
1232              case (ONE_FILE) :
1233              {
1234                std::vector<int> nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal();
1235                std::vector<int> nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer();
1236                std::vector<int> nZoomSizeServer  = grid->getDistributionServer()->getZoomSizeServer();
1237
1238                int ssize = nZoomBeginGlobal.size();
1239
1240                std::vector<StdSize> start(ssize) ;
1241                std::vector<StdSize> count(ssize) ;
1242
1243                for (int i = 0; i < ssize; ++i)
1244                {
1245                  start[i] = nZoomBeginServer[ssize-i-1] - nZoomBeginGlobal[ssize-i-1];
1246                  count[i] = nZoomSizeServer[ssize-i-1];
1247                }
1248
1249                SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1,&start,&count );
1250                if (wtime)
1251                {
1252                  SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1253                  SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1254                  SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1255                  SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1256                }
1257
1258                break;
1259              }
1260            }
1261         }
1262         catch (CNetCdfException& e)
1263         {
1264           StdString msg("On writing field data: ");
1265           msg.append(fieldid); msg.append("\n");
1266           msg.append("In the context : ");
1267           msg.append(context->getId()); msg.append("\n");
1268           msg.append(e.what());
1269           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1270         }
1271      }
1272
1273//      //---------------------------------------------------------------
1274//
1275//      void CNc4DataOutput::writeFieldData_ (CField*  field)
1276//      {
1277//         CContext* context = CContext::getCurrent() ;
1278////          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
1279//         CContextServer* server=context->server ;
1280//
1281//         CGrid* grid = field->grid ;
1282//         CDomain* domain = grid->domain ;
1283//
1284//         if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return;
1285//
1286//
1287//         StdString fieldid   = (!field->name.isEmpty())
1288//                             ? field->name.getValue()
1289//                             : field->getBaseFieldReference()->getId();
1290//
1291//         StdOStringStream oss;
1292//         string timeAxisId ;
1293//         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
1294//         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
1295//
1296//         StdString timeBoundId("time_counter_bounds");
1297//
1298//         StdString timeAxisBoundId;
1299//         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
1300//         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
1301//
1302//         CArray<double,1> time_data(1) ;
1303//         CArray<double,1> time_counter(1) ;
1304//         CArray<double,1> time_counter_bound(2);
1305//         CArray<double,1> time_data_bound(2);
1306//
1307//        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
1308//
1309//        if (wtime)
1310//        {
1311//          time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2;
1312//          if (field->foperation->timeType() == func::CFunctor::instant)
1313//            time_data(0) = Time(*field->last_Write_srv);
1314//          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
1315//
1316//          time_counter_bound(0) = Time(*field->lastlast_Write_srv);
1317//          time_counter_bound(1) = Time(*field->last_Write_srv);
1318//          if (field->foperation->timeType() == func::CFunctor::instant)
1319//            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv);
1320//          else if (field->foperation->timeType() == func::CFunctor::centered)
1321//          {
1322//            time_data_bound(0) = time_counter_bound(0);
1323//            time_data_bound(1) = time_counter_bound(1);
1324//          }
1325//         }
1326//
1327//         bool isRoot ;
1328//         if (server->intraCommRank==0) isRoot=true ;
1329//         else isRoot=false ;
1330//
1331//         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1332//         {
1333//           double scaleFactor=1. ;
1334//           double addOffset=0. ;
1335//           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
1336//           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
1337//           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
1338//         }
1339//
1340//         try
1341//         {
1342//           if (grid->hasAxis()) // 3D
1343//           {
1344//              CAxis* axis = grid->axis ;
1345//              CArray<double,3> field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ;
1346//              if (!field->default_value.isEmpty()) field_data3D = field->default_value ;
1347//
1348//              field->outputField(field_data3D);
1349//
1350//              if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ;
1351//
1352//              switch (SuperClass::type)
1353//             {
1354//                case (MULTI_FILE) :
1355//                {
1356//                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1);
1357//                   if (wtime)
1358//                   {
1359//                     SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1360//                     SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1361//                     SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1362//                     SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1363//                   }
1364//                   break ;
1365//                }
1366//                case (ONE_FILE) :
1367//                {
1368//                   std::vector<StdSize> start(3) ;
1369//                   std::vector<StdSize> count(3) ;
1370//                   if (domain->isEmpty())
1371//                   {
1372//                     start[0]=0 ; start[1]=0 ; start[2]=0 ;
1373//                     count[0]=0 ; count[1]=0 ; start[2]=0 ;
1374//                   }
1375//                   else
1376//                   {
1377//  //                 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 ;
1378//                     start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ;
1379//                     count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue();
1380//                   }
1381//                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count );
1382//                   if (wtime)
1383//                   {
1384//                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1385//                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1386//                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1387//                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1388//                   }
1389//                   break;
1390//                }
1391//              }
1392//
1393//           }
1394//           else // 2D
1395//           {
1396//              CArray<double,2> field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ;
1397//              if (!field->default_value.isEmpty()) field_data2D = field->default_value ;
1398//              field->outputField(field_data2D);
1399//              if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ;
1400//              switch (SuperClass::type)
1401//              {
1402//                case (MULTI_FILE) :
1403//                {
1404//                  SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1);
1405//                  if (wtime)
1406//                  {
1407//                    SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1408//                    SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1409//                    SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1410//                    SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1411//                  }
1412//                  break;
1413//                }
1414//                case (ONE_FILE) :
1415//                {
1416//                   std::vector<StdSize> start(2) ;
1417//                   std::vector<StdSize> count(2) ;
1418//                   if (domain->isEmpty())
1419//                   {
1420//                     start[0]=0 ; start[1]=0 ;
1421//                     count[0]=0 ; count[1]=0 ;
1422//                   }
1423//                   else
1424//                   {
1425//                     start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
1426//                     count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
1427//                   }
1428//
1429//                   SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count);
1430//                   if (wtime)
1431//                   {
1432//                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot);
1433//                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot);
1434//                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot);
1435//                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1436//                   }
1437//                   break;
1438//
1439//                }
1440//              }
1441//           }
1442//         }
1443//         catch (CNetCdfException& e)
1444//         {
1445//           StdString msg("On writing field data: ");
1446//           msg.append(fieldid); msg.append("\n");
1447//           msg.append("In the context : ");
1448//           msg.append(context->getId()); msg.append("\n");
1449//           msg.append(e.what());
1450//           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1451//         }
1452//      }
1453
1454      //---------------------------------------------------------------
1455
1456      void CNc4DataOutput::writeTimeAxis_
1457                  (CField*    field,
1458                   const boost::shared_ptr<CCalendar> cal)
1459      {
1460         StdOStringStream oss;
1461
1462//         if (field->operation.getValue().compare("once") == 0) return ;
1463         if (field->foperation->timeType() == func::CFunctor::once) return ;
1464
1465//         oss << "time_" << field->operation.getValue()
1466//             << "_" << field->getRelFile()->output_freq.getValue();
1467
1468//         StdString axisid = oss.str();
1469//         if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ;
1470//         else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ;
1471
1472         StdString axisid("time_centered") ;
1473         StdString axisBoundId("time_centered_bounds");
1474         StdString timeid("time_counter");
1475         StdString timeBoundId("time_bounds");
1476
1477         if (field->foperation->timeType() == func::CFunctor::instant)
1478         {
1479            axisid = "time_instant";
1480            axisBoundId = "time_instant_bounds";
1481         }
1482
1483         try
1484         {
1485          // Adding time_instant or time_centered
1486           std::vector<StdString> dims;
1487           dims.push_back(timeid);
1488           if (!SuperClassWriter::varExist(axisid))
1489           {
1490              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1491
1492              CDate timeOrigin=cal->getTimeOrigin() ;
1493              StdOStringStream oss2;
1494  //            oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" "
1495  //                <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ;
1496              StdString strInitdate=oss2.str() ;
1497              StdString strTimeOrigin=timeOrigin.toString() ;
1498              this->writeTimeAxisAttributes
1499                 (axisid, cal->getType(),
1500                  StdString("seconds since ").append(strTimeOrigin),
1501                  strTimeOrigin, axisBoundId);
1502           }
1503
1504           // Adding time_instant_bounds or time_centered_bounds variables
1505           if (!SuperClassWriter::varExist(axisBoundId))
1506           {
1507              dims.clear() ;
1508              dims.push_back(timeid);
1509              dims.push_back(timeBoundId);
1510              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1511           }
1512
1513           // Adding time_counter
1514           axisid = "time_counter" ;
1515           axisBoundId = "time_counter_bounds" ;
1516           dims.clear() ;
1517           dims.push_back(timeid);
1518           if (!SuperClassWriter::varExist(axisid))
1519           {
1520              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1521              SuperClassWriter::addAttribute("axis", string("T"), &axisid);
1522              CDate timeOrigin=cal->getTimeOrigin() ;
1523              StdString strTimeOrigin=timeOrigin.toString() ;
1524
1525              this->writeTimeAxisAttributes
1526                 (axisid, cal->getType(),
1527                  StdString("seconds since ").append(strTimeOrigin),
1528                  strTimeOrigin, axisBoundId);
1529           }
1530
1531           // Adding time_counter_bound dimension
1532           if (!SuperClassWriter::varExist(axisBoundId))
1533           {
1534              dims.clear();
1535              dims.push_back(timeid);
1536              dims.push_back(timeBoundId);
1537              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1538           }
1539         }
1540         catch (CNetCdfException& e)
1541         {
1542           StdString msg("On writing time axis data: ");
1543           msg.append("In the context : ");
1544           CContext* context = CContext::getCurrent() ;
1545           msg.append(context->getId()); msg.append("\n");
1546           msg.append(e.what());
1547           ERROR("CNc4DataOutput::writeTimeAxis_ (CField*    field, \
1548                  const boost::shared_ptr<CCalendar> cal)", << msg);
1549         }
1550      }
1551
1552      //---------------------------------------------------------------
1553
1554      void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name,
1555                                                   const StdString & calendar,
1556                                                   const StdString & units,
1557                                                   const StdString & time_origin,
1558                                                   const StdString & time_bounds,
1559                                                   const StdString & standard_name,
1560                                                   const StdString & long_name,
1561                                                   const StdString & title)
1562      {
1563         try
1564         {
1565           SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1566           SuperClassWriter::addAttribute("long_name",     long_name    , &axis_name);
1567           SuperClassWriter::addAttribute("title",         title        , &axis_name);
1568           SuperClassWriter::addAttribute("calendar",      calendar     , &axis_name);
1569           SuperClassWriter::addAttribute("units",         units        , &axis_name);
1570           SuperClassWriter::addAttribute("time_origin",   time_origin  , &axis_name);
1571           SuperClassWriter::addAttribute("bounds",        time_bounds  , &axis_name);
1572         }
1573         catch (CNetCdfException& e)
1574         {
1575           StdString msg("On writing time axis Attribute: ");
1576           msg.append("In the context : ");
1577           CContext* context = CContext::getCurrent() ;
1578           msg.append(context->getId()); msg.append("\n");
1579           msg.append(e.what());
1580           ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \
1581                                                   const StdString & calendar,\
1582                                                   const StdString & units, \
1583                                                   const StdString & time_origin, \
1584                                                   const StdString & time_bounds, \
1585                                                   const StdString & standard_name, \
1586                                                   const StdString & long_name, \
1587                                                   const StdString & title)", << msg);
1588         }
1589      }
1590
1591      //---------------------------------------------------------------
1592
1593      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
1594                                               const StdString & axis,
1595                                               const StdString & standard_name,
1596                                               const StdString & long_name,
1597                                               const StdString & units,
1598                                               const StdString & nav_model)
1599      {
1600         try
1601         {
1602          SuperClassWriter::addAttribute("axis"         , axis         , &axis_name);
1603          SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1604          SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
1605          SuperClassWriter::addAttribute("units"        , units        , &axis_name);
1606          SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
1607         }
1608         catch (CNetCdfException& e)
1609         {
1610           StdString msg("On writing Axis Attribute: ");
1611           msg.append("In the context : ");
1612           CContext* context = CContext::getCurrent() ;
1613           msg.append(context->getId()); msg.append("\n");
1614           msg.append(e.what());
1615           ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \
1616                                               const StdString & axis, \
1617                                               const StdString & standard_name, \
1618                                               const StdString & long_name, \
1619                                               const StdString & units, \
1620                                               const StdString & nav_model)", << msg);
1621         }
1622      }
1623
1624      //---------------------------------------------------------------
1625
1626      void CNc4DataOutput::writeLocalAttributes
1627         (int ibegin, int ni, int jbegin, int nj, StdString domid)
1628      {
1629        try
1630        {
1631         SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin);
1632         SuperClassWriter::addAttribute(StdString("ni"    ).append(domid), ni);
1633         SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin);
1634         SuperClassWriter::addAttribute(StdString("nj"    ).append(domid), nj);
1635        }
1636        catch (CNetCdfException& e)
1637        {
1638           StdString msg("On writing Local Attributes: ");
1639           msg.append("In the context : ");
1640           CContext* context = CContext::getCurrent() ;
1641           msg.append(context->getId()); msg.append("\n");
1642           msg.append(e.what());
1643           ERROR("CNc4DataOutput::writeLocalAttributes \
1644                  (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg);
1645        }
1646
1647      }
1648
1649     void CNc4DataOutput::writeLocalAttributes_IOIPSL
1650         (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)
1651      {
1652         CArray<int,1> array(2) ;
1653
1654         try
1655         {
1656           SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ;
1657           SuperClassWriter::addAttribute("DOMAIN_number", rank) ;
1658           array=1,2 ;
1659           SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ;
1660           array=ni_glo,nj_glo ;
1661           SuperClassWriter::addAttribute("DOMAIN_size_global", array) ;
1662           array=ni,nj ;
1663           SuperClassWriter::addAttribute("DOMAIN_size_local", array) ;
1664           array=ibegin,jbegin ;
1665           SuperClassWriter::addAttribute("DOMAIN_position_first", array) ;
1666           array=ibegin+ni-1,jbegin+nj-1 ;
1667           SuperClassWriter::addAttribute("DOMAIN_position_last",array) ;
1668           array=0,0 ;
1669           SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ;
1670           SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array);
1671           SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ;
1672  /*
1673           SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ;
1674           SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ;
1675           SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ;
1676           SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ;
1677  */
1678         }
1679         catch (CNetCdfException& e)
1680         {
1681           StdString msg("On writing Local Attributes IOI PSL \n");
1682           msg.append("In the context : ");
1683           CContext* context = CContext::getCurrent() ;
1684           msg.append(context->getId()); msg.append("\n");
1685           msg.append(e.what());
1686           ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \
1687                  (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg);
1688         }
1689      }
1690      //---------------------------------------------------------------
1691
1692      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
1693                                                const StdString & description,
1694                                                const StdString & conventions,
1695                                                const StdString & production,
1696                                                const StdString & timeStamp)
1697      {
1698         try
1699         {
1700           SuperClassWriter::addAttribute("name"       , name);
1701           SuperClassWriter::addAttribute("description", description);
1702           SuperClassWriter::addAttribute("conventions", conventions);
1703           SuperClassWriter::addAttribute("production" , production);
1704           SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
1705         }
1706         catch (CNetCdfException& e)
1707         {
1708           StdString msg("On writing File Attributes \n ");
1709           msg.append("In the context : ");
1710           CContext* context = CContext::getCurrent() ;
1711           msg.append(context->getId()); msg.append("\n");
1712           msg.append(e.what());
1713           ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \
1714                                                const StdString & description, \
1715                                                const StdString & conventions, \
1716                                                const StdString & production, \
1717                                                const StdString & timeStamp)", << msg);
1718         }
1719      }
1720
1721      //---------------------------------------------------------------
1722
1723      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
1724                                               int data_dim,
1725                                               int data_ni,
1726                                               int data_nj,
1727                                               int data_ibegin,
1728                                               int data_jbegin)
1729      {
1730         try
1731         {
1732           SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
1733           SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
1734           SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
1735           SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
1736           SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
1737         }
1738         catch (CNetCdfException& e)
1739         {
1740           StdString msg("On writing Mask Attributes \n ");
1741           msg.append("In the context : ");
1742           CContext* context = CContext::getCurrent() ;
1743           msg.append(context->getId()); msg.append("\n");
1744           msg.append(e.what());
1745           ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \
1746                                               int data_dim, \
1747                                               int data_ni, \
1748                                               int data_nj, \
1749                                               int data_ibegin, \
1750                                               int data_jbegin)", << msg);
1751         }
1752      }
1753
1754      ///--------------------------------------------------------------
1755
1756} // namespace xios
Note: See TracBrowser for help on using the repository browser.