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

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

Cosmetics: Remove old unstructured code.

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