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

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

Output bounds for regular and curvilinear domains.

It was done only for unstructured domains.

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