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

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

Improve CF compliance: Minor tweaks and improvements.

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