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

Last change on this file since 624 was 624, checked in by mhnguyen, 9 years ago

Final tests of zoom and inverse on axis

+) Modify test_client and test_complete to work with new grid definition
+) Correct some bugs causing memory leak
+) Clean abundant code
+) Add more comments to new files

Test
+) On Curie
+) test_client and test_complete pass with correct results

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