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

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

Fix: Do not use a hardcoded value for the "DOMAIN_dimensions_ids" attribute.

After the CF-compliance changes, the hardcoded value was sometimes wrong.

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