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

Last change on this file since 625 was 625, checked in by mhnguyen, 7 years ago

Correcting some compilation errors during merge

Test
+) On Curie
+) test_client and test_complete pass with correct results (there are some difference due to zoom)

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