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

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

Improve CF compliance: add a new axis attribute "bounds".

Fixes ticket #67.

  • 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.7 KB
Line 
1
2#include "nc4_data_output.hpp"
3
4#include <boost/lexical_cast.hpp>
5#include "attribute_template.hpp"
6#include "group_template.hpp"
7
8#include "file.hpp"
9#include "calendar.hpp"
10#include "context.hpp"
11#include "context_server.hpp"
12#include "netCdfException.hpp"
13#include "exception.hpp"
14
15namespace xios
16{
17      /// ////////////////////// Définitions ////////////////////// ///
18      CNc4DataOutput::CNc4DataOutput
19         (const StdString & filename, bool exist)
20            : SuperClass()
21            , SuperClassWriter(filename, exist)
22            , filename(filename)
23      {
24         StdString timeid = StdString("time_counter");
25         SuperClass::type = MULTI_FILE;
26//         if (!exist)
27//            SuperClassWriter::addDimension(timeid);
28      }
29
30      CNc4DataOutput::CNc4DataOutput
31         (const StdString & filename, bool exist, 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        int zoom_size_srv  = axis->zoom_size_srv;
487        int zoom_begin_srv = axis->zoom_begin_srv;
488        int zoom_size  = (MULTI_FILE == SuperClass::type) ? zoom_size_srv : axis->zoom_size;
489        int zoom_begin = (MULTI_FILE == SuperClass::type) ? zoom_begin_srv : axis->zoom_begin;
490
491
492        std::vector<StdString> dims;
493        StdString axisid = !axis->name.isEmpty() ? axis->name.getValue() : axis->getId();
494        try
495        {
496          SuperClassWriter::addDimension(axisid, zoom_size);
497          dims.push_back(axisid);
498
499          switch (SuperClass::type)
500          {
501            case MULTI_FILE:
502            case ONE_FILE:
503            {
504              SuperClassWriter::addVariable(axisid, NC_FLOAT, dims);
505
506              SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid);
507
508              if (!axis->name.isEmpty())
509                SuperClassWriter::addAttribute("name", axis->name.getValue(), &axisid);
510
511              if (!axis->standard_name.isEmpty())
512                SuperClassWriter::addAttribute("standard_name", axis->standard_name.getValue(), &axisid);
513
514              if (!axis->long_name.isEmpty())
515                SuperClassWriter::addAttribute("long_name", axis->long_name.getValue(), &axisid);
516
517              if (!axis->unit.isEmpty())
518                SuperClassWriter::addAttribute("units", axis->unit.getValue(), &axisid);
519
520              if (!axis->positive.isEmpty())
521                if (axis->positive == CAxis::positive_attr::up) SuperClassWriter::addAttribute("positive", string("up"), &axisid);
522                else SuperClassWriter::addAttribute("positive", string("down"), &axisid);
523
524              StdString axisBoundsId = axisid + "_bounds";
525              if (!axis->bounds.isEmpty())
526              {
527                dims.push_back("axis_nbounds");
528                SuperClassWriter::addVariable(axisBoundsId, NC_FLOAT, dims);
529                SuperClassWriter::addAttribute("bounds", axisBoundsId, &axisid);
530              }
531
532              SuperClassWriter::definition_end();
533
534              CArray<double,1> axis_value(zoom_size);
535              for (int 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              if (!axis->bounds.isEmpty())
539              {
540                CArray<double,2> axisBounds(zoom_size, 2);
541                for (int i = 0; i < zoom_size_srv; i++)
542                {
543                  axisBounds(i, 0) = axis->bounds(i + zoom_begin_srv, 0);
544                  axisBounds(i, 1) = axis->bounds(i + zoom_begin_srv, 1);
545                }
546                SuperClassWriter::writeData(axisBounds, axisBoundsId, isCollective, 0);
547              }
548
549              SuperClassWriter::definition_start();
550
551              break;
552            }
553            default :
554              ERROR("CNc4DataOutput::writeDomain(domain)",
555                    << "[ type = " << SuperClass::type << "]"
556                    << " not implemented yet !");
557          }
558        }
559        catch (CNetCdfException& e)
560        {
561          StdString msg("On writing the axis : ");
562          msg.append(axisid); msg.append("\n");
563          msg.append("In the context : ");
564          CContext* context = CContext::getCurrent() ;
565          msg.append(context->getId()); msg.append("\n");
566          msg.append(e.what());
567          ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg);
568        }
569        axis->addRelFile(this->filename);
570     }
571
572     void CNc4DataOutput::writeTimeDimension_(void)
573     {
574       try
575       {
576        SuperClassWriter::addDimension("time_counter");
577        SuperClassWriter::addDimension("time_bounds", 2);
578       }
579       catch (CNetCdfException& e)
580       {
581         StdString msg("On writing time dimension : time_couter, time_bounds \n");
582         msg.append("In the context : ");
583         CContext* context = CContext::getCurrent() ;
584         msg.append(context->getId()); msg.append("\n");
585         msg.append(e.what());
586         ERROR("CNc4DataOutput::writeTimeDimension_(void)", << msg);
587       }
588     }
589      //--------------------------------------------------------------
590
591      void CNc4DataOutput::writeField_(CField* field)
592      {
593         CContext* context = CContext::getCurrent() ;
594         CContextServer* server=context->server ;
595
596         std::vector<StdString> dims, coodinates;
597         CGrid* grid = field->grid;
598         if (!grid->doGridHaveDataToWrite())
599          if (SuperClass::type==MULTI_FILE) return ;
600
601         CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
602         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0;
603         std::vector<StdString> domainList = grid->getDomainList();
604         std::vector<StdString> axisList   = grid->getAxisList();
605
606         StdString timeid  = StdString("time_counter");
607         StdString dimXid,dimYid;
608         std::deque<StdString> dimIdList, dimCoordList;
609
610         for (int i = 0; i < numElement; ++i)
611         {
612           if (axisDomainOrder(i))
613           {
614             CDomain* domain = CDomain::get(domainList[idxDomain]);
615             StdString domid = (!domain->name.isEmpty())
616                                 ? domain->name.getValue() : domain->getId();
617             StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
618             switch (domain->type)
619             {
620               case CDomain::type_attr::curvilinear :
621                 dimXid     = StdString("x").append(appendDomid);
622                 dimIdList.push_back(dimXid);
623                 dimYid     = StdString("y").append(appendDomid);
624                 dimIdList.push_back(dimYid);
625                 dimCoordList.push_back(StdString("nav_lon").append(appendDomid));
626                 dimCoordList.push_back(StdString("nav_lat").append(appendDomid));
627                 break ;
628               case CDomain::type_attr::regular :
629                 dimXid     = StdString("lon").append(appendDomid);
630                 dimIdList.push_back(dimXid);
631                 dimYid     = StdString("lat").append(appendDomid);
632                 dimIdList.push_back(dimYid);
633                 break ;
634               case CDomain::type_attr::unstructured :
635                 dimXid     = StdString("cell").append(appendDomid);
636                 dimIdList.push_back(dimXid);
637                 dimCoordList.push_back(StdString("lon").append(appendDomid));
638                 dimCoordList.push_back(StdString("lat").append(appendDomid));
639                 break ;
640            }
641            ++idxDomain;
642           }
643           else
644           {
645             CAxis* axis = CAxis::get(axisList[idxAxis]);
646             StdString axisid = (!axis->name.isEmpty())
647                                ? axis->name.getValue() : axis->getId();
648             dimIdList.push_back(axisid);
649             dimCoordList.push_back(axisid);
650            ++idxAxis;
651           }
652         }
653
654/*
655         StdString lonid_loc = (server->intraCommSize > 1)
656                             ? StdString("lon").append(appendDomid).append("_local")
657                             : lonid;
658         StdString latid_loc = (server->intraCommSize > 1)
659                             ? StdString("lat").append(appendDomid).append("_local")
660                             : latid;
661*/
662         StdString fieldid   = (!field->name.isEmpty())
663                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
664
665//         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
666//         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
667//          bool isCurvilinear = domain->isCurvilinear ;
668
669         nc_type type ;
670         if (field->prec.isEmpty()) type =  NC_FLOAT ;
671         else
672         {
673           if (field->prec==2) type = NC_SHORT ;
674           else if (field->prec==4)  type =  NC_FLOAT ;
675           else if (field->prec==8)   type =  NC_DOUBLE ;
676         }
677
678         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
679
680         if (wtime)
681         {
682
683            //StdOStringStream oss;
684           // oss << "time_" << field->operation.getValue()
685           //     << "_" << field->getRelFile()->output_freq.getValue();
686          //oss
687            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
688            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
689            dims.push_back(timeid);
690         }
691
692         while (!dimIdList.empty())
693         {
694           dims.push_back(dimIdList.back());
695           dimIdList.pop_back();
696         }
697
698         while (!dimCoordList.empty())
699         {
700           coodinates.push_back(dimCoordList.back());
701           dimCoordList.pop_back();
702         }
703
704         try
705         {
706           SuperClassWriter::addVariable(fieldid, type, dims);
707
708           if (!field->standard_name.isEmpty())
709              SuperClassWriter::addAttribute
710                 ("standard_name",  field->standard_name.getValue(), &fieldid);
711
712           if (!field->long_name.isEmpty())
713              SuperClassWriter::addAttribute
714                 ("long_name", field->long_name.getValue(), &fieldid);
715
716           if (!field->unit.isEmpty())
717              SuperClassWriter::addAttribute
718                 ("units", field->unit.getValue(), &fieldid);
719
720            if (!field->valid_min.isEmpty())
721              SuperClassWriter::addAttribute
722                 ("valid_min", field->valid_min.getValue(), &fieldid);
723
724           if (!field->valid_max.isEmpty())
725              SuperClassWriter::addAttribute
726                 ("valid_max", field->valid_max.getValue(), &fieldid);
727
728            if (!field->scale_factor.isEmpty())
729              SuperClassWriter::addAttribute
730                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
731
732             if (!field->add_offset.isEmpty())
733              SuperClassWriter::addAttribute
734                 ("add_offset", field->add_offset.getValue(), &fieldid);
735
736           SuperClassWriter::addAttribute
737                 ("online_operation", field->operation.getValue(), &fieldid);
738
739          // write child variables as attributes
740
741
742           vector<CVariable*> listVars = field->getAllVariables() ;
743           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
744
745
746           if (wtime)
747           {
748              CDuration duration = field->freq_op.getValue();
749              duration.solveTimeStep(*(context->calendar));
750              SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid);
751
752              duration = field->getRelFile()->output_freq.getValue();
753              duration.solveTimeStep(*(context->calendar));
754              SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid);
755           }
756
757           if (!field->default_value.isEmpty())
758           {
759              double default_value = field->default_value.getValue();
760              float fdefault_value = (float)default_value;
761              if (type == NC_DOUBLE)
762                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
763              else
764                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
765           }
766           else
767              SuperClassWriter::setDefaultValue(fieldid, (double*)NULL);
768
769            if (field->compression_level.isEmpty())
770              field->compression_level = field->file->compression_level.isEmpty() ? 0 : field->file->compression_level;
771            SuperClassWriter::setCompressionLevel(fieldid, field->compression_level);
772
773           {  // Ecriture des coordonnées
774
775              StdString coordstr; //boost::algorithm::join(coodinates, " ")
776              std::vector<StdString>::iterator
777                 itc = coodinates.begin(), endc = coodinates.end();
778
779              for (; itc!= endc; itc++)
780              {
781                 StdString & coord = *itc;
782                 if (itc+1 != endc)
783                       coordstr.append(coord).append(" ");
784                 else  coordstr.append(coord);
785              }
786
787              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
788
789           }
790         }
791         catch (CNetCdfException& e)
792         {
793           StdString msg("On writing field : ");
794           msg.append(fieldid); msg.append("\n");
795           msg.append("In the context : ");
796           msg.append(context->getId()); msg.append("\n");
797           msg.append(e.what());
798           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
799         }
800      }
801
802
803//      void CNc4DataOutput::writeField_(CField* field)
804//      {
805//         CContext* context = CContext::getCurrent() ;
806//         CContextServer* server=context->server ;
807//
808//         std::vector<StdString> dims, coodinates;
809//         CGrid* grid = field->grid;
810//         CDomain* domain = grid->domain;
811//
812//         if (domain->isEmpty())
813//           if (SuperClass::type==MULTI_FILE) return ;
814//
815//         StdString timeid    = StdString("time_counter");
816//         StdString domid     = (!domain->name.isEmpty())
817//                             ? domain->name.getValue() : domain->getId();
818//         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
819//
820////         bool isCurvilinear = domain->isCurvilinear ;
821////         bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ;
822//
823//         StdString dimXid,dimYid ;
824//
825//         switch (domain->type)
826//         {
827//           case CDomain::type_attr::curvilinear :
828//             dimXid     = StdString("x").append(appendDomid);
829//             dimYid     = StdString("y").append(appendDomid);
830//             break ;
831//           case CDomain::type_attr::regular :
832//             dimXid     = StdString("lon").append(appendDomid);
833//             dimYid     = StdString("lat").append(appendDomid);
834//             break ;
835//           case CDomain::type_attr::unstructured :
836//             dimXid     = StdString("cell").append(appendDomid);
837//             break ;
838//        }
839//
840///*
841//         StdString lonid_loc = (server->intraCommSize > 1)
842//                             ? StdString("lon").append(appendDomid).append("_local")
843//                             : lonid;
844//         StdString latid_loc = (server->intraCommSize > 1)
845//                             ? StdString("lat").append(appendDomid).append("_local")
846//                             : latid;
847//*/
848//         StdString fieldid   = (!field->name.isEmpty())
849//                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
850//
851////         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
852////         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
853////          bool isCurvilinear = domain->isCurvilinear ;
854//
855//         nc_type type ;
856//         if (field->prec.isEmpty()) type =  NC_FLOAT ;
857//         else
858//         {
859//           if (field->prec==2) type = NC_SHORT ;
860//           else if (field->prec==4)  type =  NC_FLOAT ;
861//           else if (field->prec==8)   type =  NC_DOUBLE ;
862//         }
863//
864//         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
865//
866//         if (wtime)
867//         {
868//
869//            //StdOStringStream oss;
870//           // oss << "time_" << field->operation.getValue()
871//           //     << "_" << field->getRelFile()->output_freq.getValue();
872//          //oss
873//            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
874//            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
875//            dims.push_back(timeid);
876//         }
877//
878//         std::vector<StdString> axisList = grid->getAxisList();
879//         if (!axisList.empty())
880//         {
881//           std::vector<StdString>::const_iterator itAxis = axisList.begin(), iteAxis = axisList.end();
882//           for (; itAxis != iteAxis; ++itAxis)
883//           {
884//             CAxis* axis = CAxis::get(*itAxis);
885//             StdString axisid = (!axis->name.isEmpty())
886//                                ? axis->name.getValue() : axis->getId();
887//
888//             dims.push_back(axisid);
889//             coodinates.push_back(axisid);
890//           }
891//         }
892//
893//         switch (domain->type)
894//         {
895//           case CDomain::type_attr::curvilinear :
896//             coodinates.push_back(StdString("nav_lon").append(appendDomid));
897//             coodinates.push_back(StdString("nav_lat").append(appendDomid));
898//             break;
899//           case CDomain::type_attr::regular :
900//           case CDomain::type_attr::unstructured :
901//            coodinates.push_back(StdString("lon").append(appendDomid));
902//            coodinates.push_back(StdString("lat").append(appendDomid));
903//             break;
904//         }
905//
906//         if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid);
907//         dims.push_back(dimXid);
908//
909//         try
910//         {
911//           SuperClassWriter::addVariable(fieldid, type, dims);
912//
913//           if (!field->standard_name.isEmpty())
914//              SuperClassWriter::addAttribute
915//                 ("standard_name",  field->standard_name.getValue(), &fieldid);
916//
917//           if (!field->long_name.isEmpty())
918//              SuperClassWriter::addAttribute
919//                 ("long_name", field->long_name.getValue(), &fieldid);
920//
921//           if (!field->unit.isEmpty())
922//              SuperClassWriter::addAttribute
923//                 ("units", field->unit.getValue(), &fieldid);
924//
925//            if (!field->valid_min.isEmpty())
926//              SuperClassWriter::addAttribute
927//                 ("valid_min", field->valid_min.getValue(), &fieldid);
928//
929//           if (!field->valid_max.isEmpty())
930//              SuperClassWriter::addAttribute
931//                 ("valid_max", field->valid_max.getValue(), &fieldid);
932//
933//            if (!field->scale_factor.isEmpty())
934//              SuperClassWriter::addAttribute
935//                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
936//
937//             if (!field->add_offset.isEmpty())
938//              SuperClassWriter::addAttribute
939//                 ("add_offset", field->add_offset.getValue(), &fieldid);
940//
941//           SuperClassWriter::addAttribute
942//                 ("online_operation", field->operation.getValue(), &fieldid);
943//
944//          // write child variables as attributes
945//
946//
947//           vector<CVariable*> listVars = field->getAllVariables() ;
948//           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
949//
950//
951//           if (wtime)
952//           {
953//              CDuration duration = field->freq_op.getValue();
954//              duration.solveTimeStep(*(context->calendar));
955//              SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid);
956//
957//              duration = field->getRelFile()->output_freq.getValue();
958//              duration.solveTimeStep(*(context->calendar));
959//              SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid);
960//           }
961//
962//           if (!field->default_value.isEmpty())
963//           {
964//              double default_value = field->default_value.getValue();
965//              float fdefault_value = (float)default_value;
966//              if (type == NC_DOUBLE)
967//                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
968//              else
969//                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
970//           }
971//           else
972//              SuperClassWriter::setDefaultValue(fieldid, (double*)NULL);
973//
974//           {  // Ecriture des coordonnées
975//
976//              StdString coordstr; //boost::algorithm::join(coodinates, " ")
977//              std::vector<StdString>::iterator
978//                 itc = coodinates.begin(), endc = coodinates.end();
979//
980//              for (; itc!= endc; itc++)
981//              {
982//                 StdString & coord = *itc;
983//                 if (itc+1 != endc)
984//                       coordstr.append(coord).append(" ");
985//                 else  coordstr.append(coord);
986//              }
987//
988//              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
989//
990//           }
991//         }
992//         catch (CNetCdfException& e)
993//         {
994//           StdString msg("On writing field : ");
995//           msg.append(fieldid); msg.append("\n");
996//           msg.append("In the context : ");
997//           msg.append(context->getId()); msg.append("\n");
998//           msg.append(e.what());
999//           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
1000//         }
1001//      }
1002
1003      //--------------------------------------------------------------
1004
1005      void CNc4DataOutput::writeFile_ (CFile* file)
1006      {
1007         StdString filename = (!file->name.isEmpty())
1008                            ? file->name.getValue() : file->getId();
1009         StdString description = (!file->description.isEmpty())
1010                               ? file->description.getValue()
1011                               : StdString("Created by xios");
1012
1013         singleDomain = (file->nbDomains == 1);
1014
1015         try
1016         {
1017           this->writeFileAttributes(filename, description,
1018                                     StdString("CF-1.1"),
1019                                     StdString("An IPSL model"),
1020                                     this->getTimeStamp());
1021
1022           if (file->nbAxis >= 1)
1023             SuperClassWriter::addDimension("axis_nbounds", 2);
1024         }
1025         catch (CNetCdfException& e)
1026         {
1027           StdString msg("On writing file : ");
1028           msg.append(filename); msg.append("\n");
1029           msg.append("In the context : ");
1030           CContext* context = CContext::getCurrent() ;
1031           msg.append(context->getId()); msg.append("\n");
1032           msg.append(e.what());
1033           ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg);
1034         }
1035      }
1036
1037      void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)
1038      {
1039        string name ;
1040        if (!var->name.isEmpty()) name=var->name ;
1041        else if (var->hasId()) name=var->getId() ;
1042        else return ;
1043
1044        try
1045        {
1046          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1047            addAttribute(name, var->getData<int>(), &fieldId);
1048          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1049            addAttribute(name, var->getData<short int>(), &fieldId);
1050          else if (var->type.getValue() == CVariable::type_attr::t_float)
1051            addAttribute(name, var->getData<float>(), &fieldId);
1052          else if (var->type.getValue() == CVariable::type_attr::t_double)
1053            addAttribute(name, var->getData<double>(), &fieldId);
1054          else if (var->type.getValue() == CVariable::type_attr::t_string)
1055            addAttribute(name, var->getData<string>(), &fieldId);
1056          else
1057            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)",
1058                  << "Unsupported variable of type " << var->type.getStringValue());
1059        }
1060       catch (CNetCdfException& e)
1061       {
1062         StdString msg("On writing attributes of variable with name : ");
1063         msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n");
1064         msg.append("In the context : ");
1065         CContext* context = CContext::getCurrent() ;
1066         msg.append(context->getId()); msg.append("\n");
1067         msg.append(e.what());
1068         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg);
1069       }
1070     }
1071
1072     void CNc4DataOutput::writeAttribute_ (CVariable* var)
1073     {
1074        string name ;
1075        if (!var->name.isEmpty()) name=var->name ;
1076        else if (var->hasId()) name=var->getId() ;
1077        else return ;
1078        try
1079        {
1080          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1081            addAttribute(name, var->getData<int>());
1082          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1083            addAttribute(name, var->getData<short int>());
1084          else if (var->type.getValue() == CVariable::type_attr::t_float)
1085            addAttribute(name, var->getData<float>());
1086          else if (var->type.getValue() == CVariable::type_attr::t_double)
1087            addAttribute(name, var->getData<double>());
1088          else if (var->type.getValue() == CVariable::type_attr::t_string)
1089            addAttribute(name, var->getData<string>());
1090          else
1091            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)",
1092                  << "Unsupported variable of type " << var->type.getStringValue());
1093        }
1094       catch (CNetCdfException& e)
1095       {
1096         StdString msg("On writing attributes of variable with name : ");
1097         msg.append(name); msg.append("\n");
1098         msg.append("In the context : ");
1099         CContext* context = CContext::getCurrent() ;
1100         msg.append(context->getId()); msg.append("\n");
1101         msg.append(e.what());
1102         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg);
1103       }
1104     }
1105
1106      void CNc4DataOutput::syncFile_ (void)
1107      {
1108        try
1109        {
1110          SuperClassWriter::sync() ;
1111        }
1112        catch (CNetCdfException& e)
1113        {
1114         StdString msg("On synchronizing the write among processes");
1115         msg.append("In the context : ");
1116         CContext* context = CContext::getCurrent() ;
1117         msg.append(context->getId()); msg.append("\n");
1118         msg.append(e.what());
1119         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1120        }
1121      }
1122
1123      void CNc4DataOutput::closeFile_ (void)
1124      {
1125        try
1126        {
1127          SuperClassWriter::close() ;
1128        }
1129        catch (CNetCdfException& e)
1130        {
1131         StdString msg("On closing file");
1132         msg.append("In the context : ");
1133         CContext* context = CContext::getCurrent() ;
1134         msg.append(context->getId()); msg.append("\n");
1135         msg.append(e.what());
1136         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1137        }
1138
1139      }
1140
1141      //---------------------------------------------------------------
1142
1143      StdString CNc4DataOutput::getTimeStamp(void) const
1144      {
1145         const int buffer_size = 100;
1146         time_t rawtime;
1147         struct tm * timeinfo = NULL;
1148         char buffer [buffer_size];
1149
1150         time ( &rawtime );
1151         timeinfo = localtime ( &rawtime );
1152         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
1153
1154         return (StdString(buffer));
1155      }
1156
1157      //---------------------------------------------------------------
1158
1159      void CNc4DataOutput::writeFieldData_ (CField*  field)
1160      {
1161         CContext* context = CContext::getCurrent() ;
1162//          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
1163         CContextServer* server=context->server ;
1164
1165         CGrid* grid = field->grid ;
1166
1167         if (!grid->doGridHaveDataToWrite())
1168          if (SuperClass::type==MULTI_FILE || !isCollective) return ;
1169
1170         StdString fieldid   = (!field->name.isEmpty())
1171                             ? field->name.getValue()
1172                             : field->getBaseFieldReference()->getId();
1173
1174         StdOStringStream oss;
1175         string timeAxisId ;
1176         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
1177         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
1178
1179         StdString timeBoundId("time_counter_bounds");
1180
1181         StdString timeAxisBoundId;
1182         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
1183         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
1184
1185         CArray<double,1> time_data(1) ;
1186         CArray<double,1> time_counter(1) ;
1187         CArray<double,1> time_counter_bound(2);
1188         CArray<double,1> time_data_bound(2);
1189
1190        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
1191
1192        if (wtime)
1193        {
1194          time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2;
1195          if (field->foperation->timeType() == func::CFunctor::instant)
1196            time_data(0) = Time(*field->last_Write_srv);
1197          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
1198
1199          time_counter_bound(0) = Time(*field->lastlast_Write_srv);
1200          time_counter_bound(1) = Time(*field->last_Write_srv);
1201          if (field->foperation->timeType() == func::CFunctor::instant)
1202            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv);
1203          else if (field->foperation->timeType() == func::CFunctor::centered)
1204          {
1205            time_data_bound(0) = time_counter_bound(0);
1206            time_data_bound(1) = time_counter_bound(1);
1207          }
1208         }
1209
1210         bool isRoot ;
1211         if (server->intraCommRank==0) isRoot=true ;
1212         else isRoot=false ;
1213
1214         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1215         {
1216           double scaleFactor=1. ;
1217           double addOffset=0. ;
1218           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
1219           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
1220           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
1221         }
1222
1223         try
1224         {
1225           CArray<double,1> fieldData(grid->getWrittenDataSize());
1226           if (!field->default_value.isEmpty()) fieldData = field->default_value;
1227           field->outputField(fieldData);
1228           if (!field->prec.isEmpty() && field->prec==2) fieldData=round(fieldData) ;
1229
1230           switch (SuperClass::type)
1231           {
1232              case (MULTI_FILE) :
1233              {
1234                 SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1);
1235                 if (wtime)
1236                 {
1237                   SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1238                   SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1239                   SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1240                   SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1241                 }
1242                 break ;
1243              }
1244              case (ONE_FILE) :
1245              {
1246                std::vector<int> nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal();
1247                std::vector<int> nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer();
1248                std::vector<int> nZoomSizeServer  = grid->getDistributionServer()->getZoomSizeServer();
1249
1250                int ssize = nZoomBeginGlobal.size();
1251
1252                std::vector<StdSize> start(ssize) ;
1253                std::vector<StdSize> count(ssize) ;
1254
1255                for (int i = 0; i < ssize; ++i)
1256                {
1257                  start[i] = nZoomBeginServer[ssize-i-1] - nZoomBeginGlobal[ssize-i-1];
1258                  count[i] = nZoomSizeServer[ssize-i-1];
1259                }
1260
1261                SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1,&start,&count );
1262                if (wtime)
1263                {
1264                  SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1265                  SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1266                  SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1267                  SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1268                }
1269
1270                break;
1271              }
1272            }
1273         }
1274         catch (CNetCdfException& e)
1275         {
1276           StdString msg("On writing field data: ");
1277           msg.append(fieldid); msg.append("\n");
1278           msg.append("In the context : ");
1279           msg.append(context->getId()); msg.append("\n");
1280           msg.append(e.what());
1281           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1282         }
1283      }
1284
1285//      //---------------------------------------------------------------
1286//
1287//      void CNc4DataOutput::writeFieldData_ (CField*  field)
1288//      {
1289//         CContext* context = CContext::getCurrent() ;
1290////          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
1291//         CContextServer* server=context->server ;
1292//
1293//         CGrid* grid = field->grid ;
1294//         CDomain* domain = grid->domain ;
1295//
1296//         if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return;
1297//
1298//
1299//         StdString fieldid   = (!field->name.isEmpty())
1300//                             ? field->name.getValue()
1301//                             : field->getBaseFieldReference()->getId();
1302//
1303//         StdOStringStream oss;
1304//         string timeAxisId ;
1305//         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
1306//         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
1307//
1308//         StdString timeBoundId("time_counter_bounds");
1309//
1310//         StdString timeAxisBoundId;
1311//         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
1312//         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
1313//
1314//         CArray<double,1> time_data(1) ;
1315//         CArray<double,1> time_counter(1) ;
1316//         CArray<double,1> time_counter_bound(2);
1317//         CArray<double,1> time_data_bound(2);
1318//
1319//        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
1320//
1321//        if (wtime)
1322//        {
1323//          time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2;
1324//          if (field->foperation->timeType() == func::CFunctor::instant)
1325//            time_data(0) = Time(*field->last_Write_srv);
1326//          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
1327//
1328//          time_counter_bound(0) = Time(*field->lastlast_Write_srv);
1329//          time_counter_bound(1) = Time(*field->last_Write_srv);
1330//          if (field->foperation->timeType() == func::CFunctor::instant)
1331//            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv);
1332//          else if (field->foperation->timeType() == func::CFunctor::centered)
1333//          {
1334//            time_data_bound(0) = time_counter_bound(0);
1335//            time_data_bound(1) = time_counter_bound(1);
1336//          }
1337//         }
1338//
1339//         bool isRoot ;
1340//         if (server->intraCommRank==0) isRoot=true ;
1341//         else isRoot=false ;
1342//
1343//         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1344//         {
1345//           double scaleFactor=1. ;
1346//           double addOffset=0. ;
1347//           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
1348//           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
1349//           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
1350//         }
1351//
1352//         try
1353//         {
1354//           if (grid->hasAxis()) // 3D
1355//           {
1356//              CAxis* axis = grid->axis ;
1357//              CArray<double,3> field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ;
1358//              if (!field->default_value.isEmpty()) field_data3D = field->default_value ;
1359//
1360//              field->outputField(field_data3D);
1361//
1362//              if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ;
1363//
1364//              switch (SuperClass::type)
1365//             {
1366//                case (MULTI_FILE) :
1367//                {
1368//                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1);
1369//                   if (wtime)
1370//                   {
1371//                     SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1372//                     SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1373//                     SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1374//                     SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1375//                   }
1376//                   break ;
1377//                }
1378//                case (ONE_FILE) :
1379//                {
1380//                   std::vector<StdSize> start(3) ;
1381//                   std::vector<StdSize> count(3) ;
1382//                   if (domain->isEmpty())
1383//                   {
1384//                     start[0]=0 ; start[1]=0 ; start[2]=0 ;
1385//                     count[0]=0 ; count[1]=0 ; start[2]=0 ;
1386//                   }
1387//                   else
1388//                   {
1389//  //                 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 ;
1390//                     start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ;
1391//                     count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue();
1392//                   }
1393//                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count );
1394//                   if (wtime)
1395//                   {
1396//                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1397//                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1398//                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1399//                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1400//                   }
1401//                   break;
1402//                }
1403//              }
1404//
1405//           }
1406//           else // 2D
1407//           {
1408//              CArray<double,2> field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ;
1409//              if (!field->default_value.isEmpty()) field_data2D = field->default_value ;
1410//              field->outputField(field_data2D);
1411//              if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ;
1412//              switch (SuperClass::type)
1413//              {
1414//                case (MULTI_FILE) :
1415//                {
1416//                  SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1);
1417//                  if (wtime)
1418//                  {
1419//                    SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1420//                    SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1421//                    SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1422//                    SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1423//                  }
1424//                  break;
1425//                }
1426//                case (ONE_FILE) :
1427//                {
1428//                   std::vector<StdSize> start(2) ;
1429//                   std::vector<StdSize> count(2) ;
1430//                   if (domain->isEmpty())
1431//                   {
1432//                     start[0]=0 ; start[1]=0 ;
1433//                     count[0]=0 ; count[1]=0 ;
1434//                   }
1435//                   else
1436//                   {
1437//                     start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
1438//                     count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
1439//                   }
1440//
1441//                   SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count);
1442//                   if (wtime)
1443//                   {
1444//                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot);
1445//                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot);
1446//                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot);
1447//                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1448//                   }
1449//                   break;
1450//
1451//                }
1452//              }
1453//           }
1454//         }
1455//         catch (CNetCdfException& e)
1456//         {
1457//           StdString msg("On writing field data: ");
1458//           msg.append(fieldid); msg.append("\n");
1459//           msg.append("In the context : ");
1460//           msg.append(context->getId()); msg.append("\n");
1461//           msg.append(e.what());
1462//           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1463//         }
1464//      }
1465
1466      //---------------------------------------------------------------
1467
1468      void CNc4DataOutput::writeTimeAxis_
1469                  (CField*    field,
1470                   const boost::shared_ptr<CCalendar> cal)
1471      {
1472         StdOStringStream oss;
1473
1474//         if (field->operation.getValue().compare("once") == 0) return ;
1475         if (field->foperation->timeType() == func::CFunctor::once) return ;
1476
1477//         oss << "time_" << field->operation.getValue()
1478//             << "_" << field->getRelFile()->output_freq.getValue();
1479
1480//         StdString axisid = oss.str();
1481//         if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ;
1482//         else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ;
1483
1484         StdString axisid("time_centered") ;
1485         StdString axisBoundId("time_centered_bounds");
1486         StdString timeid("time_counter");
1487         StdString timeBoundId("time_bounds");
1488
1489         if (field->foperation->timeType() == func::CFunctor::instant)
1490         {
1491            axisid = "time_instant";
1492            axisBoundId = "time_instant_bounds";
1493         }
1494
1495         try
1496         {
1497          // Adding time_instant or time_centered
1498           std::vector<StdString> dims;
1499           dims.push_back(timeid);
1500           if (!SuperClassWriter::varExist(axisid))
1501           {
1502              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1503
1504              CDate timeOrigin=cal->getTimeOrigin() ;
1505              StdOStringStream oss2;
1506  //            oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" "
1507  //                <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ;
1508              StdString strInitdate=oss2.str() ;
1509              StdString strTimeOrigin=timeOrigin.toString() ;
1510              this->writeTimeAxisAttributes
1511                 (axisid, cal->getType(),
1512                  StdString("seconds since ").append(strTimeOrigin),
1513                  strTimeOrigin, axisBoundId);
1514           }
1515
1516           // Adding time_instant_bounds or time_centered_bounds variables
1517           if (!SuperClassWriter::varExist(axisBoundId))
1518           {
1519              dims.clear() ;
1520              dims.push_back(timeid);
1521              dims.push_back(timeBoundId);
1522              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1523           }
1524
1525           // Adding time_counter
1526           axisid = "time_counter" ;
1527           axisBoundId = "time_counter_bounds" ;
1528           dims.clear() ;
1529           dims.push_back(timeid);
1530           if (!SuperClassWriter::varExist(axisid))
1531           {
1532              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1533              SuperClassWriter::addAttribute("axis", string("T"), &axisid);
1534              CDate timeOrigin=cal->getTimeOrigin() ;
1535              StdString strTimeOrigin=timeOrigin.toString() ;
1536
1537              this->writeTimeAxisAttributes
1538                 (axisid, cal->getType(),
1539                  StdString("seconds since ").append(strTimeOrigin),
1540                  strTimeOrigin, axisBoundId);
1541           }
1542
1543           // Adding time_counter_bound dimension
1544           if (!SuperClassWriter::varExist(axisBoundId))
1545           {
1546              dims.clear();
1547              dims.push_back(timeid);
1548              dims.push_back(timeBoundId);
1549              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1550           }
1551         }
1552         catch (CNetCdfException& e)
1553         {
1554           StdString msg("On writing time axis data: ");
1555           msg.append("In the context : ");
1556           CContext* context = CContext::getCurrent() ;
1557           msg.append(context->getId()); msg.append("\n");
1558           msg.append(e.what());
1559           ERROR("CNc4DataOutput::writeTimeAxis_ (CField*    field, \
1560                  const boost::shared_ptr<CCalendar> cal)", << msg);
1561         }
1562      }
1563
1564      //---------------------------------------------------------------
1565
1566      void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name,
1567                                                   const StdString & calendar,
1568                                                   const StdString & units,
1569                                                   const StdString & time_origin,
1570                                                   const StdString & time_bounds,
1571                                                   const StdString & standard_name,
1572                                                   const StdString & long_name,
1573                                                   const StdString & title)
1574      {
1575         try
1576         {
1577           SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1578           SuperClassWriter::addAttribute("long_name",     long_name    , &axis_name);
1579           SuperClassWriter::addAttribute("title",         title        , &axis_name);
1580           SuperClassWriter::addAttribute("calendar",      calendar     , &axis_name);
1581           SuperClassWriter::addAttribute("units",         units        , &axis_name);
1582           SuperClassWriter::addAttribute("time_origin",   time_origin  , &axis_name);
1583           SuperClassWriter::addAttribute("bounds",        time_bounds  , &axis_name);
1584         }
1585         catch (CNetCdfException& e)
1586         {
1587           StdString msg("On writing time axis Attribute: ");
1588           msg.append("In the context : ");
1589           CContext* context = CContext::getCurrent() ;
1590           msg.append(context->getId()); msg.append("\n");
1591           msg.append(e.what());
1592           ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \
1593                                                   const StdString & calendar,\
1594                                                   const StdString & units, \
1595                                                   const StdString & time_origin, \
1596                                                   const StdString & time_bounds, \
1597                                                   const StdString & standard_name, \
1598                                                   const StdString & long_name, \
1599                                                   const StdString & title)", << msg);
1600         }
1601      }
1602
1603      //---------------------------------------------------------------
1604
1605      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
1606                                               const StdString & axis,
1607                                               const StdString & standard_name,
1608                                               const StdString & long_name,
1609                                               const StdString & units,
1610                                               const StdString & nav_model)
1611      {
1612         try
1613         {
1614          SuperClassWriter::addAttribute("axis"         , axis         , &axis_name);
1615          SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1616          SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
1617          SuperClassWriter::addAttribute("units"        , units        , &axis_name);
1618          SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
1619         }
1620         catch (CNetCdfException& e)
1621         {
1622           StdString msg("On writing Axis Attribute: ");
1623           msg.append("In the context : ");
1624           CContext* context = CContext::getCurrent() ;
1625           msg.append(context->getId()); msg.append("\n");
1626           msg.append(e.what());
1627           ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \
1628                                               const StdString & axis, \
1629                                               const StdString & standard_name, \
1630                                               const StdString & long_name, \
1631                                               const StdString & units, \
1632                                               const StdString & nav_model)", << msg);
1633         }
1634      }
1635
1636      //---------------------------------------------------------------
1637
1638      void CNc4DataOutput::writeLocalAttributes
1639         (int ibegin, int ni, int jbegin, int nj, StdString domid)
1640      {
1641        try
1642        {
1643         SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin);
1644         SuperClassWriter::addAttribute(StdString("ni"    ).append(domid), ni);
1645         SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin);
1646         SuperClassWriter::addAttribute(StdString("nj"    ).append(domid), nj);
1647        }
1648        catch (CNetCdfException& e)
1649        {
1650           StdString msg("On writing Local Attributes: ");
1651           msg.append("In the context : ");
1652           CContext* context = CContext::getCurrent() ;
1653           msg.append(context->getId()); msg.append("\n");
1654           msg.append(e.what());
1655           ERROR("CNc4DataOutput::writeLocalAttributes \
1656                  (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg);
1657        }
1658
1659      }
1660
1661     void CNc4DataOutput::writeLocalAttributes_IOIPSL
1662         (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)
1663      {
1664         CArray<int,1> array(2) ;
1665
1666         try
1667         {
1668           SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ;
1669           SuperClassWriter::addAttribute("DOMAIN_number", rank) ;
1670           array=1,2 ;
1671           SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ;
1672           array=ni_glo,nj_glo ;
1673           SuperClassWriter::addAttribute("DOMAIN_size_global", array) ;
1674           array=ni,nj ;
1675           SuperClassWriter::addAttribute("DOMAIN_size_local", array) ;
1676           array=ibegin,jbegin ;
1677           SuperClassWriter::addAttribute("DOMAIN_position_first", array) ;
1678           array=ibegin+ni-1,jbegin+nj-1 ;
1679           SuperClassWriter::addAttribute("DOMAIN_position_last",array) ;
1680           array=0,0 ;
1681           SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ;
1682           SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array);
1683           SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ;
1684  /*
1685           SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ;
1686           SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ;
1687           SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ;
1688           SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ;
1689  */
1690         }
1691         catch (CNetCdfException& e)
1692         {
1693           StdString msg("On writing Local Attributes IOI PSL \n");
1694           msg.append("In the context : ");
1695           CContext* context = CContext::getCurrent() ;
1696           msg.append(context->getId()); msg.append("\n");
1697           msg.append(e.what());
1698           ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \
1699                  (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg);
1700         }
1701      }
1702      //---------------------------------------------------------------
1703
1704      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
1705                                                const StdString & description,
1706                                                const StdString & conventions,
1707                                                const StdString & production,
1708                                                const StdString & timeStamp)
1709      {
1710         try
1711         {
1712           SuperClassWriter::addAttribute("name"       , name);
1713           SuperClassWriter::addAttribute("description", description);
1714           SuperClassWriter::addAttribute("conventions", conventions);
1715           SuperClassWriter::addAttribute("production" , production);
1716           SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
1717         }
1718         catch (CNetCdfException& e)
1719         {
1720           StdString msg("On writing File Attributes \n ");
1721           msg.append("In the context : ");
1722           CContext* context = CContext::getCurrent() ;
1723           msg.append(context->getId()); msg.append("\n");
1724           msg.append(e.what());
1725           ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \
1726                                                const StdString & description, \
1727                                                const StdString & conventions, \
1728                                                const StdString & production, \
1729                                                const StdString & timeStamp)", << msg);
1730         }
1731      }
1732
1733      //---------------------------------------------------------------
1734
1735      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
1736                                               int data_dim,
1737                                               int data_ni,
1738                                               int data_nj,
1739                                               int data_ibegin,
1740                                               int data_jbegin)
1741      {
1742         try
1743         {
1744           SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
1745           SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
1746           SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
1747           SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
1748           SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
1749         }
1750         catch (CNetCdfException& e)
1751         {
1752           StdString msg("On writing Mask Attributes \n ");
1753           msg.append("In the context : ");
1754           CContext* context = CContext::getCurrent() ;
1755           msg.append(context->getId()); msg.append("\n");
1756           msg.append(e.what());
1757           ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \
1758                                               int data_dim, \
1759                                               int data_ni, \
1760                                               int data_nj, \
1761                                               int data_ibegin, \
1762                                               int data_jbegin)", << msg);
1763         }
1764      }
1765
1766      ///--------------------------------------------------------------
1767
1768} // namespace xios
Note: See TracBrowser for help on using the repository browser.