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

Last change on this file since 607 was 607, checked in by rlacroix, 9 years ago

Improve the error message when compression cannot be used.

  • 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.2 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            SuperClassWriter::setCompressionLevel(fieldid, field->compression_level);
761
762           {  // Ecriture des coordonnées
763
764              StdString coordstr; //boost::algorithm::join(coodinates, " ")
765              std::vector<StdString>::iterator
766                 itc = coodinates.begin(), endc = coodinates.end();
767
768              for (; itc!= endc; itc++)
769              {
770                 StdString & coord = *itc;
771                 if (itc+1 != endc)
772                       coordstr.append(coord).append(" ");
773                 else  coordstr.append(coord);
774              }
775
776              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
777
778           }
779         }
780         catch (CNetCdfException& e)
781         {
782           StdString msg("On writing field : ");
783           msg.append(fieldid); msg.append("\n");
784           msg.append("In the context : ");
785           msg.append(context->getId()); msg.append("\n");
786           msg.append(e.what());
787           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
788         }
789      }
790
791
792//      void CNc4DataOutput::writeField_(CField* field)
793//      {
794//         CContext* context = CContext::getCurrent() ;
795//         CContextServer* server=context->server ;
796//
797//         std::vector<StdString> dims, coodinates;
798//         CGrid* grid = field->grid;
799//         CDomain* domain = grid->domain;
800//
801//         if (domain->isEmpty())
802//           if (SuperClass::type==MULTI_FILE) return ;
803//
804//         StdString timeid    = StdString("time_counter");
805//         StdString domid     = (!domain->name.isEmpty())
806//                             ? domain->name.getValue() : domain->getId();
807//         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
808//
809////         bool isCurvilinear = domain->isCurvilinear ;
810////         bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ;
811//
812//         StdString dimXid,dimYid ;
813//
814//         switch (domain->type)
815//         {
816//           case CDomain::type_attr::curvilinear :
817//             dimXid     = StdString("x").append(appendDomid);
818//             dimYid     = StdString("y").append(appendDomid);
819//             break ;
820//           case CDomain::type_attr::regular :
821//             dimXid     = StdString("lon").append(appendDomid);
822//             dimYid     = StdString("lat").append(appendDomid);
823//             break ;
824//           case CDomain::type_attr::unstructured :
825//             dimXid     = StdString("cell").append(appendDomid);
826//             break ;
827//        }
828//
829///*
830//         StdString lonid_loc = (server->intraCommSize > 1)
831//                             ? StdString("lon").append(appendDomid).append("_local")
832//                             : lonid;
833//         StdString latid_loc = (server->intraCommSize > 1)
834//                             ? StdString("lat").append(appendDomid).append("_local")
835//                             : latid;
836//*/
837//         StdString fieldid   = (!field->name.isEmpty())
838//                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
839//
840////         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
841////         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
842////          bool isCurvilinear = domain->isCurvilinear ;
843//
844//         nc_type type ;
845//         if (field->prec.isEmpty()) type =  NC_FLOAT ;
846//         else
847//         {
848//           if (field->prec==2) type = NC_SHORT ;
849//           else if (field->prec==4)  type =  NC_FLOAT ;
850//           else if (field->prec==8)   type =  NC_DOUBLE ;
851//         }
852//
853//         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
854//
855//         if (wtime)
856//         {
857//
858//            //StdOStringStream oss;
859//           // oss << "time_" << field->operation.getValue()
860//           //     << "_" << field->getRelFile()->output_freq.getValue();
861//          //oss
862//            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
863//            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
864//            dims.push_back(timeid);
865//         }
866//
867//         std::vector<StdString> axisList = grid->getAxisList();
868//         if (!axisList.empty())
869//         {
870//           std::vector<StdString>::const_iterator itAxis = axisList.begin(), iteAxis = axisList.end();
871//           for (; itAxis != iteAxis; ++itAxis)
872//           {
873//             CAxis* axis = CAxis::get(*itAxis);
874//             StdString axisid = (!axis->name.isEmpty())
875//                                ? axis->name.getValue() : axis->getId();
876//
877//             dims.push_back(axisid);
878//             coodinates.push_back(axisid);
879//           }
880//         }
881//
882//         switch (domain->type)
883//         {
884//           case CDomain::type_attr::curvilinear :
885//             coodinates.push_back(StdString("nav_lon").append(appendDomid));
886//             coodinates.push_back(StdString("nav_lat").append(appendDomid));
887//             break;
888//           case CDomain::type_attr::regular :
889//           case CDomain::type_attr::unstructured :
890//            coodinates.push_back(StdString("lon").append(appendDomid));
891//            coodinates.push_back(StdString("lat").append(appendDomid));
892//             break;
893//         }
894//
895//         if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid);
896//         dims.push_back(dimXid);
897//
898//         try
899//         {
900//           SuperClassWriter::addVariable(fieldid, type, dims);
901//
902//           if (!field->standard_name.isEmpty())
903//              SuperClassWriter::addAttribute
904//                 ("standard_name",  field->standard_name.getValue(), &fieldid);
905//
906//           if (!field->long_name.isEmpty())
907//              SuperClassWriter::addAttribute
908//                 ("long_name", field->long_name.getValue(), &fieldid);
909//
910//           if (!field->unit.isEmpty())
911//              SuperClassWriter::addAttribute
912//                 ("units", field->unit.getValue(), &fieldid);
913//
914//            if (!field->valid_min.isEmpty())
915//              SuperClassWriter::addAttribute
916//                 ("valid_min", field->valid_min.getValue(), &fieldid);
917//
918//           if (!field->valid_max.isEmpty())
919//              SuperClassWriter::addAttribute
920//                 ("valid_max", field->valid_max.getValue(), &fieldid);
921//
922//            if (!field->scale_factor.isEmpty())
923//              SuperClassWriter::addAttribute
924//                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
925//
926//             if (!field->add_offset.isEmpty())
927//              SuperClassWriter::addAttribute
928//                 ("add_offset", field->add_offset.getValue(), &fieldid);
929//
930//           SuperClassWriter::addAttribute
931//                 ("online_operation", field->operation.getValue(), &fieldid);
932//
933//          // write child variables as attributes
934//
935//
936//           vector<CVariable*> listVars = field->getAllVariables() ;
937//           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
938//
939//
940//           if (wtime)
941//           {
942//              CDuration duration = field->freq_op.getValue();
943//              duration.solveTimeStep(*(context->calendar));
944//              SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid);
945//
946//              duration = field->getRelFile()->output_freq.getValue();
947//              duration.solveTimeStep(*(context->calendar));
948//              SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid);
949//           }
950//
951//           if (!field->default_value.isEmpty())
952//           {
953//              double default_value = field->default_value.getValue();
954//              float fdefault_value = (float)default_value;
955//              if (type == NC_DOUBLE)
956//                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
957//              else
958//                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
959//           }
960//           else
961//              SuperClassWriter::setDefaultValue(fieldid, (double*)NULL);
962//
963//           {  // Ecriture des coordonnées
964//
965//              StdString coordstr; //boost::algorithm::join(coodinates, " ")
966//              std::vector<StdString>::iterator
967//                 itc = coodinates.begin(), endc = coodinates.end();
968//
969//              for (; itc!= endc; itc++)
970//              {
971//                 StdString & coord = *itc;
972//                 if (itc+1 != endc)
973//                       coordstr.append(coord).append(" ");
974//                 else  coordstr.append(coord);
975//              }
976//
977//              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
978//
979//           }
980//         }
981//         catch (CNetCdfException& e)
982//         {
983//           StdString msg("On writing field : ");
984//           msg.append(fieldid); msg.append("\n");
985//           msg.append("In the context : ");
986//           msg.append(context->getId()); msg.append("\n");
987//           msg.append(e.what());
988//           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
989//         }
990//      }
991
992      //--------------------------------------------------------------
993
994      void CNc4DataOutput::writeFile_ (CFile* file)
995      {
996         StdString filename = (!file->name.isEmpty())
997                            ? file->name.getValue() : file->getId();
998         StdString description = (!file->description.isEmpty())
999                               ? file->description.getValue()
1000                               : StdString("Created by xios");
1001         try
1002         {
1003           this->writeFileAttributes(filename, description,
1004                                     StdString ("CF-1.1"),
1005                                     StdString("An IPSL model"),
1006                                     this->getTimeStamp());
1007         }
1008         catch (CNetCdfException& e)
1009         {
1010           StdString msg("On writing file : ");
1011           msg.append(filename); msg.append("\n");
1012           msg.append("In the context : ");
1013           CContext* context = CContext::getCurrent() ;
1014           msg.append(context->getId()); msg.append("\n");
1015           msg.append(e.what());
1016           ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg);
1017         }
1018         if (file->nbDomain==1) singleDomain=true ;
1019         else singleDomain=false ;
1020      }
1021
1022      void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)
1023      {
1024        string name ;
1025        if (!var->name.isEmpty()) name=var->name ;
1026        else if (var->hasId()) name=var->getId() ;
1027        else return ;
1028
1029        try
1030        {
1031          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1032            addAttribute(name, var->getData<int>(), &fieldId);
1033          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1034            addAttribute(name, var->getData<short int>(), &fieldId);
1035          else if (var->type.getValue() == CVariable::type_attr::t_float)
1036            addAttribute(name, var->getData<float>(), &fieldId);
1037          else if (var->type.getValue() == CVariable::type_attr::t_double)
1038            addAttribute(name, var->getData<double>(), &fieldId);
1039          else if (var->type.getValue() == CVariable::type_attr::t_string)
1040            addAttribute(name, var->getData<string>(), &fieldId);
1041          else
1042            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)",
1043                  << "Unsupported variable of type " << var->type.getStringValue());
1044        }
1045       catch (CNetCdfException& e)
1046       {
1047         StdString msg("On writing attributes of variable with name : ");
1048         msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n");
1049         msg.append("In the context : ");
1050         CContext* context = CContext::getCurrent() ;
1051         msg.append(context->getId()); msg.append("\n");
1052         msg.append(e.what());
1053         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg);
1054       }
1055     }
1056
1057     void CNc4DataOutput::writeAttribute_ (CVariable* var)
1058     {
1059        string name ;
1060        if (!var->name.isEmpty()) name=var->name ;
1061        else if (var->hasId()) name=var->getId() ;
1062        else return ;
1063        try
1064        {
1065          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1066            addAttribute(name, var->getData<int>());
1067          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1068            addAttribute(name, var->getData<short int>());
1069          else if (var->type.getValue() == CVariable::type_attr::t_float)
1070            addAttribute(name, var->getData<float>());
1071          else if (var->type.getValue() == CVariable::type_attr::t_double)
1072            addAttribute(name, var->getData<double>());
1073          else if (var->type.getValue() == CVariable::type_attr::t_string)
1074            addAttribute(name, var->getData<string>());
1075          else
1076            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)",
1077                  << "Unsupported variable of type " << var->type.getStringValue());
1078        }
1079       catch (CNetCdfException& e)
1080       {
1081         StdString msg("On writing attributes of variable with name : ");
1082         msg.append(name); msg.append("\n");
1083         msg.append("In the context : ");
1084         CContext* context = CContext::getCurrent() ;
1085         msg.append(context->getId()); msg.append("\n");
1086         msg.append(e.what());
1087         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg);
1088       }
1089     }
1090
1091      void CNc4DataOutput::syncFile_ (void)
1092      {
1093        try
1094        {
1095          SuperClassWriter::sync() ;
1096        }
1097        catch (CNetCdfException& e)
1098        {
1099         StdString msg("On synchronizing the write among processes");
1100         msg.append("In the context : ");
1101         CContext* context = CContext::getCurrent() ;
1102         msg.append(context->getId()); msg.append("\n");
1103         msg.append(e.what());
1104         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1105        }
1106      }
1107
1108      void CNc4DataOutput::closeFile_ (void)
1109      {
1110        try
1111        {
1112          SuperClassWriter::close() ;
1113        }
1114        catch (CNetCdfException& e)
1115        {
1116         StdString msg("On closing file");
1117         msg.append("In the context : ");
1118         CContext* context = CContext::getCurrent() ;
1119         msg.append(context->getId()); msg.append("\n");
1120         msg.append(e.what());
1121         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1122        }
1123
1124      }
1125
1126      //---------------------------------------------------------------
1127
1128      StdString CNc4DataOutput::getTimeStamp(void) const
1129      {
1130         const int buffer_size = 100;
1131         time_t rawtime;
1132         struct tm * timeinfo = NULL;
1133         char buffer [buffer_size];
1134
1135         time ( &rawtime );
1136         timeinfo = localtime ( &rawtime );
1137         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
1138
1139         return (StdString(buffer));
1140      }
1141
1142      //---------------------------------------------------------------
1143
1144      void CNc4DataOutput::writeFieldData_ (CField*  field)
1145      {
1146         CContext* context = CContext::getCurrent() ;
1147//          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
1148         CContextServer* server=context->server ;
1149
1150         CGrid* grid = field->grid ;
1151
1152         if (!grid->doGridHaveDataToWrite())
1153          if (SuperClass::type==MULTI_FILE || !isCollective) return ;
1154
1155         StdString fieldid   = (!field->name.isEmpty())
1156                             ? field->name.getValue()
1157                             : field->getBaseFieldReference()->getId();
1158
1159         StdOStringStream oss;
1160         string timeAxisId ;
1161         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
1162         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
1163
1164         StdString timeBoundId("time_counter_bounds");
1165
1166         StdString timeAxisBoundId;
1167         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
1168         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
1169
1170         CArray<double,1> time_data(1) ;
1171         CArray<double,1> time_counter(1) ;
1172         CArray<double,1> time_counter_bound(2);
1173         CArray<double,1> time_data_bound(2);
1174
1175        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
1176
1177        if (wtime)
1178        {
1179          time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2;
1180          if (field->foperation->timeType() == func::CFunctor::instant)
1181            time_data(0) = Time(*field->last_Write_srv);
1182          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
1183
1184          time_counter_bound(0) = Time(*field->lastlast_Write_srv);
1185          time_counter_bound(1) = Time(*field->last_Write_srv);
1186          if (field->foperation->timeType() == func::CFunctor::instant)
1187            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv);
1188          else if (field->foperation->timeType() == func::CFunctor::centered)
1189          {
1190            time_data_bound(0) = time_counter_bound(0);
1191            time_data_bound(1) = time_counter_bound(1);
1192          }
1193         }
1194
1195         bool isRoot ;
1196         if (server->intraCommRank==0) isRoot=true ;
1197         else isRoot=false ;
1198
1199         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1200         {
1201           double scaleFactor=1. ;
1202           double addOffset=0. ;
1203           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
1204           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
1205           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
1206         }
1207
1208         try
1209         {
1210           CArray<double,1> fieldData(grid->getWrittenDataSize());
1211           if (!field->default_value.isEmpty()) fieldData = field->default_value;
1212           field->outputField(fieldData);
1213           if (!field->prec.isEmpty() && field->prec==2) fieldData=round(fieldData) ;
1214
1215           switch (SuperClass::type)
1216           {
1217              case (MULTI_FILE) :
1218              {
1219                 SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1);
1220                 if (wtime)
1221                 {
1222                   SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1223                   SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1224                   SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1225                   SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1226                 }
1227                 break ;
1228              }
1229              case (ONE_FILE) :
1230              {
1231                std::vector<int> nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal();
1232                std::vector<int> nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer();
1233                std::vector<int> nZoomSizeServer  = grid->getDistributionServer()->getZoomSizeServer();
1234
1235                int ssize = nZoomBeginGlobal.size();
1236
1237                std::vector<StdSize> start(ssize) ;
1238                std::vector<StdSize> count(ssize) ;
1239
1240                for (int i = 0; i < ssize; ++i)
1241                {
1242                  start[i] = nZoomBeginServer[ssize-i-1] - nZoomBeginGlobal[ssize-i-1];
1243                  count[i] = nZoomSizeServer[ssize-i-1];
1244                }
1245
1246                SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1,&start,&count );
1247                if (wtime)
1248                {
1249                  SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1250                  SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1251                  SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1252                  SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1253                }
1254
1255                break;
1256              }
1257            }
1258         }
1259         catch (CNetCdfException& e)
1260         {
1261           StdString msg("On writing field data: ");
1262           msg.append(fieldid); msg.append("\n");
1263           msg.append("In the context : ");
1264           msg.append(context->getId()); msg.append("\n");
1265           msg.append(e.what());
1266           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1267         }
1268      }
1269
1270//      //---------------------------------------------------------------
1271//
1272//      void CNc4DataOutput::writeFieldData_ (CField*  field)
1273//      {
1274//         CContext* context = CContext::getCurrent() ;
1275////          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
1276//         CContextServer* server=context->server ;
1277//
1278//         CGrid* grid = field->grid ;
1279//         CDomain* domain = grid->domain ;
1280//
1281//         if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return;
1282//
1283//
1284//         StdString fieldid   = (!field->name.isEmpty())
1285//                             ? field->name.getValue()
1286//                             : field->getBaseFieldReference()->getId();
1287//
1288//         StdOStringStream oss;
1289//         string timeAxisId ;
1290//         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
1291//         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
1292//
1293//         StdString timeBoundId("time_counter_bounds");
1294//
1295//         StdString timeAxisBoundId;
1296//         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
1297//         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
1298//
1299//         CArray<double,1> time_data(1) ;
1300//         CArray<double,1> time_counter(1) ;
1301//         CArray<double,1> time_counter_bound(2);
1302//         CArray<double,1> time_data_bound(2);
1303//
1304//        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
1305//
1306//        if (wtime)
1307//        {
1308//          time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2;
1309//          if (field->foperation->timeType() == func::CFunctor::instant)
1310//            time_data(0) = Time(*field->last_Write_srv);
1311//          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
1312//
1313//          time_counter_bound(0) = Time(*field->lastlast_Write_srv);
1314//          time_counter_bound(1) = Time(*field->last_Write_srv);
1315//          if (field->foperation->timeType() == func::CFunctor::instant)
1316//            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv);
1317//          else if (field->foperation->timeType() == func::CFunctor::centered)
1318//          {
1319//            time_data_bound(0) = time_counter_bound(0);
1320//            time_data_bound(1) = time_counter_bound(1);
1321//          }
1322//         }
1323//
1324//         bool isRoot ;
1325//         if (server->intraCommRank==0) isRoot=true ;
1326//         else isRoot=false ;
1327//
1328//         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1329//         {
1330//           double scaleFactor=1. ;
1331//           double addOffset=0. ;
1332//           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
1333//           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
1334//           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
1335//         }
1336//
1337//         try
1338//         {
1339//           if (grid->hasAxis()) // 3D
1340//           {
1341//              CAxis* axis = grid->axis ;
1342//              CArray<double,3> field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ;
1343//              if (!field->default_value.isEmpty()) field_data3D = field->default_value ;
1344//
1345//              field->outputField(field_data3D);
1346//
1347//              if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ;
1348//
1349//              switch (SuperClass::type)
1350//             {
1351//                case (MULTI_FILE) :
1352//                {
1353//                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1);
1354//                   if (wtime)
1355//                   {
1356//                     SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1357//                     SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1358//                     SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1359//                     SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1360//                   }
1361//                   break ;
1362//                }
1363//                case (ONE_FILE) :
1364//                {
1365//                   std::vector<StdSize> start(3) ;
1366//                   std::vector<StdSize> count(3) ;
1367//                   if (domain->isEmpty())
1368//                   {
1369//                     start[0]=0 ; start[1]=0 ; start[2]=0 ;
1370//                     count[0]=0 ; count[1]=0 ; start[2]=0 ;
1371//                   }
1372//                   else
1373//                   {
1374//  //                 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 ;
1375//                     start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ;
1376//                     count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue();
1377//                   }
1378//                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count );
1379//                   if (wtime)
1380//                   {
1381//                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1382//                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1383//                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1384//                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1385//                   }
1386//                   break;
1387//                }
1388//              }
1389//
1390//           }
1391//           else // 2D
1392//           {
1393//              CArray<double,2> field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ;
1394//              if (!field->default_value.isEmpty()) field_data2D = field->default_value ;
1395//              field->outputField(field_data2D);
1396//              if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ;
1397//              switch (SuperClass::type)
1398//              {
1399//                case (MULTI_FILE) :
1400//                {
1401//                  SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1);
1402//                  if (wtime)
1403//                  {
1404//                    SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1405//                    SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1406//                    SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1407//                    SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1408//                  }
1409//                  break;
1410//                }
1411//                case (ONE_FILE) :
1412//                {
1413//                   std::vector<StdSize> start(2) ;
1414//                   std::vector<StdSize> count(2) ;
1415//                   if (domain->isEmpty())
1416//                   {
1417//                     start[0]=0 ; start[1]=0 ;
1418//                     count[0]=0 ; count[1]=0 ;
1419//                   }
1420//                   else
1421//                   {
1422//                     start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
1423//                     count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
1424//                   }
1425//
1426//                   SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count);
1427//                   if (wtime)
1428//                   {
1429//                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot);
1430//                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot);
1431//                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot);
1432//                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1433//                   }
1434//                   break;
1435//
1436//                }
1437//              }
1438//           }
1439//         }
1440//         catch (CNetCdfException& e)
1441//         {
1442//           StdString msg("On writing field data: ");
1443//           msg.append(fieldid); msg.append("\n");
1444//           msg.append("In the context : ");
1445//           msg.append(context->getId()); msg.append("\n");
1446//           msg.append(e.what());
1447//           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1448//         }
1449//      }
1450
1451      //---------------------------------------------------------------
1452
1453      void CNc4DataOutput::writeTimeAxis_
1454                  (CField*    field,
1455                   const boost::shared_ptr<CCalendar> cal)
1456      {
1457         StdOStringStream oss;
1458
1459//         if (field->operation.getValue().compare("once") == 0) return ;
1460         if (field->foperation->timeType() == func::CFunctor::once) return ;
1461
1462//         oss << "time_" << field->operation.getValue()
1463//             << "_" << field->getRelFile()->output_freq.getValue();
1464
1465//         StdString axisid = oss.str();
1466//         if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ;
1467//         else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ;
1468
1469         StdString axisid("time_centered") ;
1470         StdString axisBoundId("time_centered_bounds");
1471         StdString timeid("time_counter");
1472         StdString timeBoundId("time_bounds");
1473
1474         if (field->foperation->timeType() == func::CFunctor::instant)
1475         {
1476            axisid = "time_instant";
1477            axisBoundId = "time_instant_bounds";
1478         }
1479
1480         try
1481         {
1482          // Adding time_instant or time_centered
1483           std::vector<StdString> dims;
1484           dims.push_back(timeid);
1485           if (!SuperClassWriter::varExist(axisid))
1486           {
1487              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1488
1489              CDate timeOrigin=cal->getTimeOrigin() ;
1490              StdOStringStream oss2;
1491  //            oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" "
1492  //                <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ;
1493              StdString strInitdate=oss2.str() ;
1494              StdString strTimeOrigin=timeOrigin.toString() ;
1495              this->writeTimeAxisAttributes
1496                 (axisid, cal->getType(),
1497                  StdString("seconds since ").append(strTimeOrigin),
1498                  strTimeOrigin, axisBoundId);
1499           }
1500
1501           // Adding time_instant_bounds or time_centered_bounds variables
1502           if (!SuperClassWriter::varExist(axisBoundId))
1503           {
1504              dims.clear() ;
1505              dims.push_back(timeid);
1506              dims.push_back(timeBoundId);
1507              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1508           }
1509
1510           // Adding time_counter
1511           axisid = "time_counter" ;
1512           axisBoundId = "time_counter_bounds" ;
1513           dims.clear() ;
1514           dims.push_back(timeid);
1515           if (!SuperClassWriter::varExist(axisid))
1516           {
1517              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1518              SuperClassWriter::addAttribute("axis", string("T"), &axisid);
1519              CDate timeOrigin=cal->getTimeOrigin() ;
1520              StdString strTimeOrigin=timeOrigin.toString() ;
1521
1522              this->writeTimeAxisAttributes
1523                 (axisid, cal->getType(),
1524                  StdString("seconds since ").append(strTimeOrigin),
1525                  strTimeOrigin, axisBoundId);
1526           }
1527
1528           // Adding time_counter_bound dimension
1529           if (!SuperClassWriter::varExist(axisBoundId))
1530           {
1531              dims.clear();
1532              dims.push_back(timeid);
1533              dims.push_back(timeBoundId);
1534              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1535           }
1536         }
1537         catch (CNetCdfException& e)
1538         {
1539           StdString msg("On writing time axis data: ");
1540           msg.append("In the context : ");
1541           CContext* context = CContext::getCurrent() ;
1542           msg.append(context->getId()); msg.append("\n");
1543           msg.append(e.what());
1544           ERROR("CNc4DataOutput::writeTimeAxis_ (CField*    field, \
1545                  const boost::shared_ptr<CCalendar> cal)", << msg);
1546         }
1547      }
1548
1549      //---------------------------------------------------------------
1550
1551      void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name,
1552                                                   const StdString & calendar,
1553                                                   const StdString & units,
1554                                                   const StdString & time_origin,
1555                                                   const StdString & time_bounds,
1556                                                   const StdString & standard_name,
1557                                                   const StdString & long_name,
1558                                                   const StdString & title)
1559      {
1560         try
1561         {
1562           SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1563           SuperClassWriter::addAttribute("long_name",     long_name    , &axis_name);
1564           SuperClassWriter::addAttribute("title",         title        , &axis_name);
1565           SuperClassWriter::addAttribute("calendar",      calendar     , &axis_name);
1566           SuperClassWriter::addAttribute("units",         units        , &axis_name);
1567           SuperClassWriter::addAttribute("time_origin",   time_origin  , &axis_name);
1568           SuperClassWriter::addAttribute("bounds",        time_bounds  , &axis_name);
1569         }
1570         catch (CNetCdfException& e)
1571         {
1572           StdString msg("On writing time axis Attribute: ");
1573           msg.append("In the context : ");
1574           CContext* context = CContext::getCurrent() ;
1575           msg.append(context->getId()); msg.append("\n");
1576           msg.append(e.what());
1577           ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \
1578                                                   const StdString & calendar,\
1579                                                   const StdString & units, \
1580                                                   const StdString & time_origin, \
1581                                                   const StdString & time_bounds, \
1582                                                   const StdString & standard_name, \
1583                                                   const StdString & long_name, \
1584                                                   const StdString & title)", << msg);
1585         }
1586      }
1587
1588      //---------------------------------------------------------------
1589
1590      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
1591                                               const StdString & axis,
1592                                               const StdString & standard_name,
1593                                               const StdString & long_name,
1594                                               const StdString & units,
1595                                               const StdString & nav_model)
1596      {
1597         try
1598         {
1599          SuperClassWriter::addAttribute("axis"         , axis         , &axis_name);
1600          SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1601          SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
1602          SuperClassWriter::addAttribute("units"        , units        , &axis_name);
1603          SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
1604         }
1605         catch (CNetCdfException& e)
1606         {
1607           StdString msg("On writing Axis Attribute: ");
1608           msg.append("In the context : ");
1609           CContext* context = CContext::getCurrent() ;
1610           msg.append(context->getId()); msg.append("\n");
1611           msg.append(e.what());
1612           ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \
1613                                               const StdString & axis, \
1614                                               const StdString & standard_name, \
1615                                               const StdString & long_name, \
1616                                               const StdString & units, \
1617                                               const StdString & nav_model)", << msg);
1618         }
1619      }
1620
1621      //---------------------------------------------------------------
1622
1623      void CNc4DataOutput::writeLocalAttributes
1624         (int ibegin, int ni, int jbegin, int nj, StdString domid)
1625      {
1626        try
1627        {
1628         SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin);
1629         SuperClassWriter::addAttribute(StdString("ni"    ).append(domid), ni);
1630         SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin);
1631         SuperClassWriter::addAttribute(StdString("nj"    ).append(domid), nj);
1632        }
1633        catch (CNetCdfException& e)
1634        {
1635           StdString msg("On writing Local Attributes: ");
1636           msg.append("In the context : ");
1637           CContext* context = CContext::getCurrent() ;
1638           msg.append(context->getId()); msg.append("\n");
1639           msg.append(e.what());
1640           ERROR("CNc4DataOutput::writeLocalAttributes \
1641                  (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg);
1642        }
1643
1644      }
1645
1646     void CNc4DataOutput::writeLocalAttributes_IOIPSL
1647         (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)
1648      {
1649         CArray<int,1> array(2) ;
1650
1651         try
1652         {
1653           SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ;
1654           SuperClassWriter::addAttribute("DOMAIN_number", rank) ;
1655           array=1,2 ;
1656           SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ;
1657           array=ni_glo,nj_glo ;
1658           SuperClassWriter::addAttribute("DOMAIN_size_global", array) ;
1659           array=ni,nj ;
1660           SuperClassWriter::addAttribute("DOMAIN_size_local", array) ;
1661           array=ibegin,jbegin ;
1662           SuperClassWriter::addAttribute("DOMAIN_position_first", array) ;
1663           array=ibegin+ni-1,jbegin+nj-1 ;
1664           SuperClassWriter::addAttribute("DOMAIN_position_last",array) ;
1665           array=0,0 ;
1666           SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ;
1667           SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array);
1668           SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ;
1669  /*
1670           SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ;
1671           SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ;
1672           SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ;
1673           SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ;
1674  */
1675         }
1676         catch (CNetCdfException& e)
1677         {
1678           StdString msg("On writing Local Attributes IOI PSL \n");
1679           msg.append("In the context : ");
1680           CContext* context = CContext::getCurrent() ;
1681           msg.append(context->getId()); msg.append("\n");
1682           msg.append(e.what());
1683           ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \
1684                  (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg);
1685         }
1686      }
1687      //---------------------------------------------------------------
1688
1689      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
1690                                                const StdString & description,
1691                                                const StdString & conventions,
1692                                                const StdString & production,
1693                                                const StdString & timeStamp)
1694      {
1695         try
1696         {
1697           SuperClassWriter::addAttribute("name"       , name);
1698           SuperClassWriter::addAttribute("description", description);
1699           SuperClassWriter::addAttribute("conventions", conventions);
1700           SuperClassWriter::addAttribute("production" , production);
1701           SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
1702         }
1703         catch (CNetCdfException& e)
1704         {
1705           StdString msg("On writing File Attributes \n ");
1706           msg.append("In the context : ");
1707           CContext* context = CContext::getCurrent() ;
1708           msg.append(context->getId()); msg.append("\n");
1709           msg.append(e.what());
1710           ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \
1711                                                const StdString & description, \
1712                                                const StdString & conventions, \
1713                                                const StdString & production, \
1714                                                const StdString & timeStamp)", << msg);
1715         }
1716      }
1717
1718      //---------------------------------------------------------------
1719
1720      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
1721                                               int data_dim,
1722                                               int data_ni,
1723                                               int data_nj,
1724                                               int data_ibegin,
1725                                               int data_jbegin)
1726      {
1727         try
1728         {
1729           SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
1730           SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
1731           SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
1732           SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
1733           SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
1734         }
1735         catch (CNetCdfException& e)
1736         {
1737           StdString msg("On writing Mask Attributes \n ");
1738           msg.append("In the context : ");
1739           CContext* context = CContext::getCurrent() ;
1740           msg.append(context->getId()); msg.append("\n");
1741           msg.append(e.what());
1742           ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \
1743                                               int data_dim, \
1744                                               int data_ni, \
1745                                               int data_nj, \
1746                                               int data_ibegin, \
1747                                               int data_jbegin)", << msg);
1748         }
1749      }
1750
1751      ///--------------------------------------------------------------
1752
1753} // namespace xios
Note: See TracBrowser for help on using the repository browser.