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

Last change on this file since 517 was 517, checked in by rlacroix, 7 years ago

Add a new attribute to the file definition so that the output format can be controlled.

Currently the supported formats are "netcdf4" and "netcdf4_classic". The "format" attribute is optional. The "netcdf4" format will be used when no format is explicitly defined. Since "netcdf4" is the format which was previously used by XIOS, existing configuration files will not be affected by this change.

If "netcdf4_classic" is used, the output file(s) will be created using the classic NetCDF format. This format can be used with the attribute "type" set to "one_file" if the NetCDF4 library was compiled with Parallel NetCDF support (--enable-pnetcdf).

  • 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: 59.3 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         switch (domain->type)
86         {
87           case CDomain::type_attr::curvilinear :
88             dimXid     = StdString("x").append(appendDomid);
89             dimYid     = StdString("y").append(appendDomid);
90             break ;
91           case CDomain::type_attr::regular :
92             dimXid     = StdString("lon").append(appendDomid);
93             dimYid     = StdString("lat").append(appendDomid);
94             break;
95           case CDomain::type_attr::unstructured :
96             dimXid     = StdString("cell").append(appendDomid);
97             break;
98         }
99
100         string lonid,latid,bounds_lonid,bounds_latid ;
101/*
102         StdString lonid_loc = (server->intraCommSize > 1)
103                             ? StdString("lon").append(appendDomid).append("_local")
104                             : lonid;
105         StdString latid_loc = (server->intraCommSize > 1)
106                             ? StdString("lat").append(appendDomid).append("_local")
107                             : latid;
108*/
109
110         try
111         {
112           switch (SuperClass::type)
113           {
114              case (MULTI_FILE) :
115              {
116  //               if (domain->isEmpty()) return;
117
118                 if (server->intraCommSize > 1)
119                 {
120  //                 SuperClassWriter::addDimension(lonid, domain->zoom_ni.getValue());
121  //                 SuperClassWriter::addDimension(latid, domain->zoom_nj.getValue());
122                 }
123
124                 switch (domain->type)
125                 {
126                   case CDomain::type_attr::curvilinear :
127                     dim0.push_back(dimYid); dim0.push_back(dimXid);
128                     lonid = StdString("nav_lon").append(appendDomid);
129                     latid = StdString("nav_lat").append(appendDomid);
130                     break ;
131                   case CDomain::type_attr::regular :
132                     lonid = StdString("lon").append(appendDomid);
133                     latid = StdString("lat").append(appendDomid);
134                     dim0.push_back(dimYid);
135                     dim1.push_back(dimXid);
136                     break;
137                   case CDomain::type_attr::unstructured :
138                     lonid = StdString("lon").append(appendDomid);
139                     latid = StdString("lat").append(appendDomid);
140                     bounds_lonid=string("bounds_lon").append(appendDomid);
141                     bounds_latid=string("bounds_lat").append(appendDomid);
142                     dim0.push_back(dimXid);
143                     break;
144                 }
145
146                 if (domain->type == CDomain::type_attr::unstructured)
147                 {
148                   SuperClassWriter::addDimension(dimXid, domain->nj_glo);
149                 }
150                 else
151                 {
152                   SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
153                   SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv);
154                 }
155
156                 if (server->intraCommSize > 1)
157                 {
158                    if (domain->type != CDomain::type_attr::unstructured)
159                    {
160                      this->writeLocalAttributes(domain->zoom_ibegin_srv,
161                                                 domain->zoom_ni_srv,
162                                                 domain->zoom_jbegin_srv,
163                                                 domain->zoom_nj_srv,
164                                                 appendDomid);
165
166                      if (singleDomain) this->writeLocalAttributes_IOIPSL(domain->zoom_ibegin_srv,
167                                                 domain->zoom_ni_srv,
168                                                 domain->zoom_jbegin_srv,
169                                                 domain->zoom_nj_srv,
170                                                 domain->ni_glo,domain->nj_glo,
171                                                 server->intraCommRank,server->intraCommSize);
172                   }
173                 }
174
175                 switch (domain->type)
176                 {
177                   case CDomain::type_attr::curvilinear :
178                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
179                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
180                     break ;
181                    case CDomain::type_attr::regular :
182                      SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
183                      SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
184                      break ;
185                    case CDomain::type_attr::unstructured :
186                      SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
187                      SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
188                 }
189
190                 this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
191                 this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
192
193                 dim0.clear();
194                 if (domain->type != CDomain::type_attr::unstructured) 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                 SuperClassWriter::definition_end();
213
214                 switch (domain->type)
215                 {
216                   case CDomain::type_attr::curvilinear :
217                     SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
218                     SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
219                     break;
220                   case CDomain::type_attr::regular :
221                     CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
222                     SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
223                     CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
224                     SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
225                     break;
226                 }
227                 SuperClassWriter::definition_start();
228
229                 break;
230              }
231              case (ONE_FILE) :
232              {
233                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni.getValue());
234                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj.getValue());
235
236
237                 switch (domain->type)
238                 {
239                   case CDomain::type_attr::curvilinear :
240                     dim0.push_back(dimYid); dim0.push_back(dimXid);
241                     lonid = StdString("nav_lon").append(appendDomid);
242                     latid = StdString("nav_lat").append(appendDomid);
243                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
244                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
245                     break;
246
247                   case CDomain::type_attr::regular :
248                     dim0.push_back(dimYid);
249                     dim1.push_back(dimXid);
250                     lonid = StdString("lon").append(appendDomid);
251                     latid = StdString("lat").append(appendDomid);
252                     SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
253                     SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
254                     break;
255                 }
256                 this->writeAxisAttributes
257                    (lonid, "X", "longitude", "Longitude", "degrees_east", domid);
258                 this->writeAxisAttributes
259                    (latid, "Y", "latitude", "Latitude", "degrees_north", domid);
260
261
262                 SuperClassWriter::definition_end();
263                 switch (domain->type)
264                 {
265                   case CDomain::type_attr::curvilinear :
266                   {
267                     std::vector<StdSize> start(2) ;
268                     std::vector<StdSize> count(2) ;
269                     if (domain->isEmpty())
270                     {
271                       start[0]=0 ; start [1]=0 ;
272                       count[0]=0 ; count[1]=0 ;
273                     }
274                     else
275                     {
276                       start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
277                       count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
278                     }
279
280                     SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
281                     SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
282                     break;
283                   }
284                   case CDomain::type_attr::regular :
285                   {
286                     std::vector<StdSize> start(1) ;
287                     std::vector<StdSize> count(1) ;
288                     if (domain->isEmpty())
289                     {
290                       start[0]=0 ;
291                       count[0]=0 ;
292                       SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
293                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);                 }
294                     else
295                     {
296                       start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
297                       count[0]=domain->zoom_nj_srv ;
298                       CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
299                       SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
300
301                       start[0]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ;
302                       count[0]=domain->zoom_ni_srv ;
303                       CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
304                       SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
305                     }
306                     break;
307                   }
308                 }
309                 SuperClassWriter::definition_start();
310                 break;
311              }
312              default :
313                 ERROR("CNc4DataOutput::writeDomain(domain)",
314                       << "[ type = " << SuperClass::type << "]"
315                       << " not implemented yet !");
316           }
317         }
318         catch (CNetCdfException& e)
319         {
320           StdString msg("On writing the domain : ");
321           msg.append(domid); msg.append("\n");
322           msg.append("In the context : ");
323           msg.append(context->getId()); msg.append("\n");
324           msg.append(e.what());
325           ERROR("CNc4DataOutput::writeDomain_(CDomain* domain)", << msg);
326         }
327
328         domain->addRelFile(this->filename);
329      }
330
331      void CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)
332      {
333         CContext* context = CContext::getCurrent() ;
334         CContextServer* server=context->server ;
335
336         if (domain->IsWritten(this->filename)) return;
337         domain->checkAttributes();
338
339         if (domain->isEmpty())
340           if (SuperClass::type==MULTI_FILE) return ;
341
342         std::vector<StdString> dim0, dim1;
343         StdString domid     = (!domain->name.isEmpty())
344                             ? domain->name.getValue() : domain->getId();
345         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
346
347
348         StdString dimXid = StdString("cell").append(appendDomid);
349         StdString dimVertId = StdString("nvertex").append(appendDomid);
350
351         string lonid,latid,bounds_lonid,bounds_latid ;
352
353         try
354         {
355           switch (SuperClass::type)
356           {
357              case (MULTI_FILE) :
358              {
359                 lonid = StdString("lon").append(appendDomid);
360                 latid = StdString("lat").append(appendDomid);
361                 dim0.push_back(dimXid);
362
363                 SuperClassWriter::addDimension(dimXid, domain->zoom_nj_srv);
364                 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
365                 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
366
367                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
368                 bounds_latid = StdString("bounds_lat").append(appendDomid);
369
370
371                 this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
372                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
373                 this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
374                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
375                 if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
376                 dim0.clear();
377                 if (domain->hasBounds)
378                 {
379                   dim0.push_back(dimXid);
380                   dim0.push_back(dimVertId);
381                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
382                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
383                 }
384
385                 dim0.clear();
386                 dim0.push_back(dimXid);
387
388                 SuperClassWriter::definition_end();
389
390                 SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
391                 SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
392
393                 if (domain->hasBounds)
394                 {
395                   SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
396                   SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
397                 }
398                 SuperClassWriter::definition_start();
399                 break ;
400              }
401
402              case (ONE_FILE) :
403              {
404                 lonid = StdString("lon").append(appendDomid);
405                 latid = StdString("lat").append(appendDomid);
406                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
407                 bounds_latid = StdString("bounds_lat").append(appendDomid);
408                 dim0.push_back(dimXid);
409                 SuperClassWriter::addDimension(dimXid, domain->nj_glo);
410                 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
411                 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
412                 this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
413                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
414                 this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
415                 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
416                 if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
417                 dim0.clear();
418
419                 if (domain->hasBounds)
420                 {
421                   dim0.push_back(dimXid);
422                   dim0.push_back(dimVertId);
423                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
424                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
425                 }
426
427                 SuperClassWriter::definition_end();
428
429                 std::vector<StdSize> start(1), startBounds(2) ;
430                 std::vector<StdSize> count(1), countBounds(2) ;
431                 if (domain->isEmpty())
432                 {
433                   start[0]=0 ;
434                   count[0]=0 ;
435                   startBounds[1]=0 ;
436                   countBounds[1]=domain->nvertex ;
437                   startBounds[0]=0 ;
438                   countBounds[0]=0 ;
439                 }
440                 else
441                 {
442                   start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
443                   count[0]=domain->zoom_nj_srv ;
444                   startBounds[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
445                   startBounds[1]=0 ;
446                   countBounds[0]=domain->zoom_nj_srv ;
447                   countBounds[1]=domain->nvertex ;
448                 }
449                 SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
450                 SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
451                 if (domain->hasBounds)
452                 {
453                   SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
454                   SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds);
455                 }
456
457
458                 SuperClassWriter::definition_start();
459
460                 break;
461              }
462              default :
463                 ERROR("CNc4DataOutput::writeDomain(domain)",
464                       << "[ type = " << SuperClass::type << "]"
465                       << " not implemented yet !");
466           }
467         }
468         catch (CNetCdfException& e)
469         {
470           StdString msg("On writing the domain : ");
471           msg.append(domid); msg.append("\n");
472           msg.append("In the context : ");
473           msg.append(context->getId()); msg.append("\n");
474           msg.append(e.what());
475           ERROR("CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)", << msg);
476         }
477         domain->addRelFile(this->filename);
478      }
479      //--------------------------------------------------------------
480
481      void CNc4DataOutput::writeAxis_(CAxis* axis)
482      {
483         if (axis->IsWritten(this->filename)) return;
484         axis->checkAttributes();
485         StdSize zoom_size=axis->zoom_size.getValue() ;
486         StdSize zoom_begin=axis->zoom_begin.getValue()-1 ;
487
488
489         std::vector<StdString> dims;
490         StdString axisid = (!axis->name.isEmpty())
491                           ? axis->name.getValue() : axis->getId();
492         try
493         {
494           SuperClassWriter::addDimension(axisid, zoom_size);
495           dims.push_back(axisid);
496
497           switch (SuperClass::type)
498           {
499              case (MULTI_FILE ) :
500              {}
501              case (ONE_FILE) :
502              {
503                 SuperClassWriter::addVariable(axisid, NC_FLOAT, dims);
504
505                 SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid);
506
507                 if (!axis->standard_name.isEmpty())
508                    SuperClassWriter::addAttribute
509                       ("standard_name",  axis->standard_name.getValue(), &axisid);
510
511                 if (!axis->long_name.isEmpty())
512                    SuperClassWriter::addAttribute
513                       ("long_name", axis->long_name.getValue(), &axisid);
514
515                 if (!axis->unit.isEmpty())
516                    SuperClassWriter::addAttribute
517                       ("units", axis->unit.getValue(), &axisid);
518
519                if (!axis->positive.isEmpty())
520                  if (axis->positive==CAxis::positive_attr::up) SuperClassWriter::addAttribute("positive", string("up"), &axisid);
521                  else   SuperClassWriter::addAttribute("positive", string("down"), &axisid);
522
523                 SuperClassWriter::definition_end();
524
525                 CArray<double,1> axis_value(zoom_size) ;
526                 for(StdSize i = 0 ; i < zoom_size ; i++) axis_value(i)=axis->value(i+zoom_begin) ;
527                 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
528
529                 SuperClassWriter::definition_start();
530
531                 break;
532              }
533              default :
534                 ERROR("CNc4DataOutput::writeDomain(domain)",
535                       << "[ type = " << SuperClass::type << "]"
536                       << " not implemented yet !");
537           }
538         }
539         catch (CNetCdfException& e)
540         {
541           StdString msg("On writing the axis : ");
542           msg.append(axisid); msg.append("\n");
543           msg.append("In the context : ");
544           CContext* context = CContext::getCurrent() ;
545           msg.append(context->getId()); msg.append("\n");
546           msg.append(e.what());
547           ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg);
548         }
549         axis->addRelFile(this->filename);
550     }
551
552     void CNc4DataOutput::writeTimeDimension_(void)
553     {
554       try
555       {
556        SuperClassWriter::addDimension("time_counter");
557        SuperClassWriter::addDimension("time_bounds", 2);
558       }
559       catch (CNetCdfException& e)
560       {
561         StdString msg("On writing time dimension : time_couter, time_bounds \n");
562         msg.append("In the context : ");
563         CContext* context = CContext::getCurrent() ;
564         msg.append(context->getId()); msg.append("\n");
565         msg.append(e.what());
566         ERROR("CNc4DataOutput::writeTimeDimension_(void)", << msg);
567       }
568     }
569      //--------------------------------------------------------------
570
571      void CNc4DataOutput::writeField_(CField* field)
572      {
573         CContext* context = CContext::getCurrent() ;
574         CContextServer* server=context->server ;
575
576         std::vector<StdString> dims, coodinates;
577         CGrid* grid = field->grid;
578         CDomain* domain = grid->domain;
579
580         if (domain->isEmpty())
581           if (SuperClass::type==MULTI_FILE) return ;
582
583         StdString timeid    = StdString("time_counter");
584         StdString domid     = (!domain->name.isEmpty())
585                             ? domain->name.getValue() : domain->getId();
586         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
587
588//         bool isCurvilinear = domain->isCurvilinear ;
589//         bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ;
590
591         StdString dimXid,dimYid ;
592
593         switch (domain->type)
594         {
595           case CDomain::type_attr::curvilinear :
596             dimXid     = StdString("x").append(appendDomid);
597             dimYid     = StdString("y").append(appendDomid);
598             break ;
599           case CDomain::type_attr::regular :
600             dimXid     = StdString("lon").append(appendDomid);
601             dimYid     = StdString("lat").append(appendDomid);
602             break ;
603           case CDomain::type_attr::unstructured :
604             dimXid     = StdString("cell").append(appendDomid);
605             break ;
606        }
607
608/*
609         StdString lonid_loc = (server->intraCommSize > 1)
610                             ? StdString("lon").append(appendDomid).append("_local")
611                             : lonid;
612         StdString latid_loc = (server->intraCommSize > 1)
613                             ? StdString("lat").append(appendDomid).append("_local")
614                             : latid;
615*/
616         StdString fieldid   = (!field->name.isEmpty())
617                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
618
619//         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
620//         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
621//          bool isCurvilinear = domain->isCurvilinear ;
622
623         nc_type type ;
624         if (field->prec.isEmpty()) type =  NC_FLOAT ;
625         else
626         {
627           if (field->prec==2) type = NC_SHORT ;
628           else if (field->prec==4)  type =  NC_FLOAT ;
629           else if (field->prec==8)   type =  NC_DOUBLE ;
630         }
631
632         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
633
634         if (wtime)
635         {
636
637            //StdOStringStream oss;
638           // oss << "time_" << field->operation.getValue()
639           //     << "_" << field->getRelFile()->output_freq.getValue();
640          //oss
641            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
642            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
643            dims.push_back(timeid);
644         }
645
646         if (!grid->axis_ref.isEmpty())
647         {
648            CAxis* axis = grid->axis ;
649            StdString axisid = (!axis->name.isEmpty()) ? axis->name.getValue() : axis->getId();
650            dims.push_back(axisid);
651            coodinates.push_back(axisid);
652         }
653
654         switch (domain->type)
655         {
656           case CDomain::type_attr::curvilinear :
657             coodinates.push_back(StdString("nav_lon").append(appendDomid));
658             coodinates.push_back(StdString("nav_lat").append(appendDomid));
659             break;
660           case CDomain::type_attr::regular :
661           case CDomain::type_attr::unstructured :
662            coodinates.push_back(StdString("lon").append(appendDomid));
663            coodinates.push_back(StdString("lat").append(appendDomid));
664             break;
665         }
666
667         if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid);
668         dims.push_back(dimXid);
669
670         try
671         {
672           SuperClassWriter::addVariable(fieldid, type, dims);
673
674           if (!field->standard_name.isEmpty())
675              SuperClassWriter::addAttribute
676                 ("standard_name",  field->standard_name.getValue(), &fieldid);
677
678           if (!field->long_name.isEmpty())
679              SuperClassWriter::addAttribute
680                 ("long_name", field->long_name.getValue(), &fieldid);
681
682           if (!field->unit.isEmpty())
683              SuperClassWriter::addAttribute
684                 ("units", field->unit.getValue(), &fieldid);
685
686            if (!field->valid_min.isEmpty())
687              SuperClassWriter::addAttribute
688                 ("valid_min", field->valid_min.getValue(), &fieldid);
689
690           if (!field->valid_max.isEmpty())
691              SuperClassWriter::addAttribute
692                 ("valid_max", field->valid_max.getValue(), &fieldid);
693
694            if (!field->scale_factor.isEmpty())
695              SuperClassWriter::addAttribute
696                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
697
698             if (!field->add_offset.isEmpty())
699              SuperClassWriter::addAttribute
700                 ("add_offset", field->add_offset.getValue(), &fieldid);
701
702           SuperClassWriter::addAttribute
703                 ("online_operation", field->operation.getValue(), &fieldid);
704
705          // write child variables as attributes
706
707
708           vector<CVariable*> listVars = field->getAllVariables() ;
709           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
710
711
712           if (wtime)
713           {
714              CDuration duration ;
715
716              duration=CDuration::FromString(field->freq_op) ;
717              duration.solveTimeStep(*(context->calendar));
718              SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid);
719
720              duration=CDuration::FromString(field->getRelFile()->output_freq) ;
721              duration.solveTimeStep(*(context->calendar));
722              SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid);
723           }
724
725           if (!field->default_value.isEmpty())
726           {
727              double default_value = field->default_value.getValue();
728              float fdefault_value = (float)default_value;
729              if (type == NC_DOUBLE)
730                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
731              else
732                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
733           }
734           else
735              SuperClassWriter::setDefaultValue(fieldid, (double*)NULL);
736
737           {  // Ecriture des coordonnées
738
739              StdString coordstr; //boost::algorithm::join(coodinates, " ")
740              std::vector<StdString>::iterator
741                 itc = coodinates.begin(), endc = coodinates.end();
742
743              for (; itc!= endc; itc++)
744              {
745                 StdString & coord = *itc;
746                 if (itc+1 != endc)
747                       coordstr.append(coord).append(" ");
748                 else  coordstr.append(coord);
749              }
750
751              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
752
753           }
754         }
755         catch (CNetCdfException& e)
756         {
757           StdString msg("On writing field : ");
758           msg.append(fieldid); msg.append("\n");
759           msg.append("In the context : ");
760           msg.append(context->getId()); msg.append("\n");
761           msg.append(e.what());
762           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
763         }
764      }
765
766      //--------------------------------------------------------------
767
768      void CNc4DataOutput::writeFile_ (CFile* file)
769      {
770         StdString filename = (!file->name.isEmpty())
771                            ? file->name.getValue() : file->getId();
772         StdString description = (!file->description.isEmpty())
773                               ? file->description.getValue()
774                               : StdString("Created by xios");
775         try
776         {
777           this->writeFileAttributes(filename, description,
778                                     StdString ("CF-1.1"),
779                                     StdString("An IPSL model"),
780                                     this->getTimeStamp());
781         }
782         catch (CNetCdfException& e)
783         {
784           StdString msg("On writing file : ");
785           msg.append(filename); msg.append("\n");
786           msg.append("In the context : ");
787           CContext* context = CContext::getCurrent() ;
788           msg.append(context->getId()); msg.append("\n");
789           msg.append(e.what());
790           ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg);
791         }
792         if (file->nbDomain==1) singleDomain=true ;
793         else singleDomain=false ;
794      }
795
796      void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)
797      {
798        string name ;
799        if (!var->name.isEmpty()) name=var->name ;
800        else if (var->hasId()) name=var->getId() ;
801        else return ;
802
803        try
804        {
805          if (var->getVarType()==CVariable::t_int) addAttribute(name,var->getData<int>(),&fieldId) ;
806          else if (var->getVarType()==CVariable::t_short_int) addAttribute(name,var->getData<short int>(),&fieldId) ;
807          else if (var->getVarType()==CVariable::t_long_int) addAttribute(name,var->getData<long int>(),&fieldId) ;
808          else if (var->getVarType()==CVariable::t_float) addAttribute(name,var->getData<float>(),&fieldId) ;
809          else if (var->getVarType()==CVariable::t_double) addAttribute(name,var->getData<double>(),&fieldId) ;
810          else addAttribute(name,var->getData<string>(),&fieldId) ;
811        }
812       catch (CNetCdfException& e)
813       {
814         StdString msg("On writing attributes of variable with name : ");
815         msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n");
816         msg.append("In the context : ");
817         CContext* context = CContext::getCurrent() ;
818         msg.append(context->getId()); msg.append("\n");
819         msg.append(e.what());
820         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg);
821       }
822     }
823
824     void CNc4DataOutput::writeAttribute_ (CVariable* var)
825     {
826        string name ;
827        if (!var->name.isEmpty()) name=var->name ;
828        else if (var->hasId()) name=var->getId() ;
829        else return ;
830        try
831        {
832          if (var->getVarType()==CVariable::t_int) addAttribute(name,var->getData<int>()) ;
833          else if (var->getVarType()==CVariable::t_short_int) addAttribute(name,var->getData<short int>()) ;
834          else if (var->getVarType()==CVariable::t_long_int) addAttribute(name,var->getData<long int>()) ;
835          else if (var->getVarType()==CVariable::t_float) addAttribute(name,var->getData<float>()) ;
836          else if (var->getVarType()==CVariable::t_double) addAttribute(name,var->getData<double>()) ;
837          else addAttribute(name,var->getData<string>()) ;
838        }
839       catch (CNetCdfException& e)
840       {
841         StdString msg("On writing attributes of variable with name : ");
842         msg.append(name); msg.append("\n");
843         msg.append("In the context : ");
844         CContext* context = CContext::getCurrent() ;
845         msg.append(context->getId()); msg.append("\n");
846         msg.append(e.what());
847         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg);
848       }
849     }
850
851      void CNc4DataOutput::syncFile_ (void)
852      {
853        try
854        {
855          SuperClassWriter::sync() ;
856        }
857        catch (CNetCdfException& e)
858        {
859         StdString msg("On synchronizing the write among processes");
860         msg.append("In the context : ");
861         CContext* context = CContext::getCurrent() ;
862         msg.append(context->getId()); msg.append("\n");
863         msg.append(e.what());
864         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
865        }
866      }
867
868      void CNc4DataOutput::closeFile_ (void)
869      {
870        try
871        {
872          SuperClassWriter::close() ;
873        }
874        catch (CNetCdfException& e)
875        {
876         StdString msg("On closing file");
877         msg.append("In the context : ");
878         CContext* context = CContext::getCurrent() ;
879         msg.append(context->getId()); msg.append("\n");
880         msg.append(e.what());
881         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
882        }
883
884      }
885
886      //---------------------------------------------------------------
887
888      StdString CNc4DataOutput::getTimeStamp(void) const
889      {
890         const int buffer_size = 100;
891         time_t rawtime;
892         struct tm * timeinfo = NULL;
893         char buffer [buffer_size];
894
895         time ( &rawtime );
896         timeinfo = localtime ( &rawtime );
897         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
898
899         return (StdString(buffer));
900      }
901
902      //---------------------------------------------------------------
903
904      void CNc4DataOutput::writeFieldData_ (CField*  field)
905      {
906         CContext* context = CContext::getCurrent() ;
907//          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
908         CContextServer* server=context->server ;
909
910         CGrid* grid = field->grid ;
911         CDomain* domain = grid->domain ;
912
913         if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return;
914
915
916         StdString fieldid   = (!field->name.isEmpty())
917                             ? field->name.getValue()
918                             : field->getBaseFieldReference()->getId();
919
920         StdOStringStream oss;
921         string timeAxisId ;
922         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
923         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
924
925         StdString timeBoundId("time_counter_bounds");
926
927         StdString timeAxisBoundId;
928         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisBoundId="time_instant_bounds" ;
929         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisBoundId="time_centered_bounds" ;
930
931         CArray<double,1> time_data(1) ;
932         CArray<double,1> time_counter(1) ;
933         CArray<double,1> time_counter_bound(2);
934         CArray<double,1> time_data_bound(2);
935
936        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
937
938        if (wtime)
939        {
940          time_counter(0)= (Time(*field->last_Write_srv)+Time(*field->lastlast_Write_srv))/2 -Time(context->calendar->getTimeOrigin());
941          if (field->foperation->timeType() == func::CFunctor::instant)
942            time_data(0) = Time(*field->last_Write_srv)-Time(context->calendar->getTimeOrigin());
943          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
944
945          time_counter_bound(0) = Time(*field->lastlast_Write_srv) - Time(context->calendar->getTimeOrigin());
946          time_counter_bound(1) = Time(*field->last_Write_srv) - Time(context->calendar->getTimeOrigin());
947          if (field->foperation->timeType() == func::CFunctor::instant)
948            time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv)-Time(context->calendar->getTimeOrigin());
949          else if (field->foperation->timeType() == func::CFunctor::centered)
950          {
951            time_data_bound(0) = time_counter_bound(0);
952            time_data_bound(1) = time_counter_bound(1);
953          }
954         }
955
956         bool isRoot ;
957         if (server->intraCommRank==0) isRoot=true ;
958         else isRoot=false ;
959
960         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
961         {
962           double scaleFactor=1. ;
963           double addOffset=0. ;
964           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
965           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
966           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
967         }
968
969         try
970         {
971           if (grid->hasAxis()) // 3D
972           {
973              CAxis* axis = grid->axis ;
974              CArray<double,3> field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ;
975              if (!field->default_value.isEmpty()) field_data3D = field->default_value ;
976
977              field->outputField(field_data3D);
978
979              if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ;
980
981              switch (SuperClass::type)
982             {
983                case (MULTI_FILE) :
984                {
985                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1);
986                   if (wtime)
987                   {
988                     SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
989                     SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
990                     SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
991                     SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
992                   }
993                   break ;
994                }
995                case (ONE_FILE) :
996                {
997                   std::vector<StdSize> start(3) ;
998                   std::vector<StdSize> count(3) ;
999                   if (domain->isEmpty())
1000                   {
1001                     start[0]=0 ; start[1]=0 ; start[2]=0 ;
1002                     count[0]=0 ; count[1]=0 ; start[2]=0 ;
1003                   }
1004                   else
1005                   {
1006  //                 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 ;
1007                     start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ;
1008                     count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue();
1009                   }
1010                   SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count );
1011                   if (wtime)
1012                   {
1013                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
1014                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
1015                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot );
1016                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1017                   }
1018                   break;
1019                }
1020              }
1021
1022           }
1023           else // 2D
1024           {
1025              CArray<double,2> field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ;
1026              if (!field->default_value.isEmpty()) field_data2D = field->default_value ;
1027              field->outputField(field_data2D);
1028              if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ;
1029              switch (SuperClass::type)
1030              {
1031                case (MULTI_FILE) :
1032                {
1033                  SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1);
1034                  if (wtime)
1035                  {
1036                    SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
1037                    SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
1038                    SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1);
1039                    SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1);
1040                  }
1041                  break;
1042                }
1043                case (ONE_FILE) :
1044                {
1045                   std::vector<StdSize> start(2) ;
1046                   std::vector<StdSize> count(2) ;
1047                   if (domain->isEmpty())
1048                   {
1049                     start[0]=0 ; start[1]=0 ;
1050                     count[0]=0 ; count[1]=0 ;
1051                   }
1052                   else
1053                   {
1054                     start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
1055                     count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
1056                   }
1057
1058                   SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count);
1059                   if (wtime)
1060                   {
1061                     SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot);
1062                     SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot);
1063                     SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot);
1064                     SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot);
1065                   }
1066                   break;
1067
1068                }
1069              }
1070           }
1071         }
1072         catch (CNetCdfException& e)
1073         {
1074           StdString msg("On writing field data: ");
1075           msg.append(fieldid); msg.append("\n");
1076           msg.append("In the context : ");
1077           msg.append(context->getId()); msg.append("\n");
1078           msg.append(e.what());
1079           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1080         }
1081      }
1082
1083      //---------------------------------------------------------------
1084
1085      void CNc4DataOutput::writeTimeAxis_
1086                  (CField*    field,
1087                   const boost::shared_ptr<CCalendar> cal)
1088      {
1089         StdOStringStream oss;
1090
1091//         if (field->operation.getValue().compare("once") == 0) return ;
1092         if (field->foperation->timeType() == func::CFunctor::once) return ;
1093
1094//         oss << "time_" << field->operation.getValue()
1095//             << "_" << field->getRelFile()->output_freq.getValue();
1096
1097//         StdString axisid = oss.str();
1098//         if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ;
1099//         else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ;
1100
1101         StdString axisid("time_centered") ;
1102         StdString axisBoundId("time_centered_bounds");
1103         StdString timeid("time_counter");
1104         StdString timeBoundId("time_bounds");
1105
1106         if (field->foperation->timeType() == func::CFunctor::instant)
1107         {
1108            axisid = "time_instant";
1109            axisBoundId = "time_instant_bounds";
1110         }
1111
1112         try
1113         {
1114          // Adding time_instant or time_centered
1115           std::vector<StdString> dims;
1116           dims.push_back(timeid);
1117           if (!SuperClassWriter::varExist(axisid))
1118           {
1119              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1120
1121              CDate timeOrigin=cal->getTimeOrigin() ;
1122              StdOStringStream oss2;
1123  //            oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" "
1124  //                <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ;
1125              StdString strInitdate=oss2.str() ;
1126              StdString strTimeOrigin=timeOrigin.toString() ;
1127              this->writeTimeAxisAttributes
1128                 (axisid, cal->getType(),
1129                  StdString("seconds since ").append(strTimeOrigin),
1130                  strTimeOrigin, axisBoundId);
1131           }
1132
1133           // Adding time_instant_bounds or time_centered_bounds variables
1134           if (!SuperClassWriter::varExist(axisBoundId))
1135           {
1136              dims.clear() ;
1137              dims.push_back(timeid);
1138              dims.push_back(timeBoundId);
1139              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1140           }
1141
1142           // Adding time_counter
1143           axisid = "time_counter" ;
1144           axisBoundId = "time_counter_bounds" ;
1145           dims.clear() ;
1146           dims.push_back(timeid);
1147           if (!SuperClassWriter::varExist(axisid))
1148           {
1149              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1150              SuperClassWriter::addAttribute("axis", string("T"), &axisid);
1151              CDate timeOrigin=cal->getTimeOrigin() ;
1152              StdString strTimeOrigin=timeOrigin.toString() ;
1153
1154              this->writeTimeAxisAttributes
1155                 (axisid, cal->getType(),
1156                  StdString("seconds since ").append(strTimeOrigin),
1157                  strTimeOrigin, axisBoundId);
1158           }
1159
1160           // Adding time_counter_bound dimension
1161           if (!SuperClassWriter::varExist(axisBoundId))
1162           {
1163              dims.clear();
1164              dims.push_back(timeid);
1165              dims.push_back(timeBoundId);
1166              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1167           }
1168         }
1169         catch (CNetCdfException& e)
1170         {
1171           StdString msg("On writing time axis data: ");
1172           msg.append("In the context : ");
1173           CContext* context = CContext::getCurrent() ;
1174           msg.append(context->getId()); msg.append("\n");
1175           msg.append(e.what());
1176           ERROR("CNc4DataOutput::writeTimeAxis_ (CField*    field, \
1177                  const boost::shared_ptr<CCalendar> cal)", << msg);
1178         }
1179      }
1180
1181      //---------------------------------------------------------------
1182
1183      void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name,
1184                                                   const StdString & calendar,
1185                                                   const StdString & units,
1186                                                   const StdString & time_origin,
1187                                                   const StdString & time_bounds,
1188                                                   const StdString & standard_name,
1189                                                   const StdString & long_name,
1190                                                   const StdString & title)
1191      {
1192         try
1193         {
1194           SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1195           SuperClassWriter::addAttribute("long_name",     long_name    , &axis_name);
1196           SuperClassWriter::addAttribute("title",         title        , &axis_name);
1197           SuperClassWriter::addAttribute("calendar",      calendar     , &axis_name);
1198           SuperClassWriter::addAttribute("units",         units        , &axis_name);
1199           SuperClassWriter::addAttribute("time_origin",   time_origin  , &axis_name);
1200           SuperClassWriter::addAttribute("bounds",        time_bounds  , &axis_name);
1201         }
1202         catch (CNetCdfException& e)
1203         {
1204           StdString msg("On writing time axis Attribute: ");
1205           msg.append("In the context : ");
1206           CContext* context = CContext::getCurrent() ;
1207           msg.append(context->getId()); msg.append("\n");
1208           msg.append(e.what());
1209           ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \
1210                                                   const StdString & calendar,\
1211                                                   const StdString & units, \
1212                                                   const StdString & time_origin, \
1213                                                   const StdString & time_bounds, \
1214                                                   const StdString & standard_name, \
1215                                                   const StdString & long_name, \
1216                                                   const StdString & title)", << msg);
1217         }
1218      }
1219
1220      //---------------------------------------------------------------
1221
1222      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
1223                                               const StdString & axis,
1224                                               const StdString & standard_name,
1225                                               const StdString & long_name,
1226                                               const StdString & units,
1227                                               const StdString & nav_model)
1228      {
1229         try
1230         {
1231          SuperClassWriter::addAttribute("axis"         , axis         , &axis_name);
1232          SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1233          SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
1234          SuperClassWriter::addAttribute("units"        , units        , &axis_name);
1235          SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
1236         }
1237         catch (CNetCdfException& e)
1238         {
1239           StdString msg("On writing Axis Attribute: ");
1240           msg.append("In the context : ");
1241           CContext* context = CContext::getCurrent() ;
1242           msg.append(context->getId()); msg.append("\n");
1243           msg.append(e.what());
1244           ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \
1245                                               const StdString & axis, \
1246                                               const StdString & standard_name, \
1247                                               const StdString & long_name, \
1248                                               const StdString & units, \
1249                                               const StdString & nav_model)", << msg);
1250         }
1251      }
1252
1253      //---------------------------------------------------------------
1254
1255      void CNc4DataOutput::writeLocalAttributes
1256         (int ibegin, int ni, int jbegin, int nj, StdString domid)
1257      {
1258        try
1259        {
1260         SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin);
1261         SuperClassWriter::addAttribute(StdString("ni"    ).append(domid), ni);
1262         SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin);
1263         SuperClassWriter::addAttribute(StdString("nj"    ).append(domid), nj);
1264        }
1265        catch (CNetCdfException& e)
1266        {
1267           StdString msg("On writing Local Attributes: ");
1268           msg.append("In the context : ");
1269           CContext* context = CContext::getCurrent() ;
1270           msg.append(context->getId()); msg.append("\n");
1271           msg.append(e.what());
1272           ERROR("CNc4DataOutput::writeLocalAttributes \
1273                  (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg);
1274        }
1275
1276      }
1277
1278     void CNc4DataOutput::writeLocalAttributes_IOIPSL
1279         (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)
1280      {
1281         CArray<int,1> array(2) ;
1282
1283         try
1284         {
1285           SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ;
1286           SuperClassWriter::addAttribute("DOMAIN_number", rank) ;
1287           array=1,2 ;
1288           SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ;
1289           array=ni_glo,nj_glo ;
1290           SuperClassWriter::addAttribute("DOMAIN_size_global", array) ;
1291           array=ni,nj ;
1292           SuperClassWriter::addAttribute("DOMAIN_size_local", array) ;
1293           array=ibegin,jbegin ;
1294           SuperClassWriter::addAttribute("DOMAIN_position_first", array) ;
1295           array=ibegin+ni-1,jbegin+nj-1 ;
1296           SuperClassWriter::addAttribute("DOMAIN_position_last",array) ;
1297           array=0,0 ;
1298           SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ;
1299           SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array);
1300           SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ;
1301  /*
1302           SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ;
1303           SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ;
1304           SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ;
1305           SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ;
1306  */
1307         }
1308         catch (CNetCdfException& e)
1309         {
1310           StdString msg("On writing Local Attributes IOI PSL \n");
1311           msg.append("In the context : ");
1312           CContext* context = CContext::getCurrent() ;
1313           msg.append(context->getId()); msg.append("\n");
1314           msg.append(e.what());
1315           ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \
1316                  (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg);
1317         }
1318      }
1319      //---------------------------------------------------------------
1320
1321      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
1322                                                const StdString & description,
1323                                                const StdString & conventions,
1324                                                const StdString & production,
1325                                                const StdString & timeStamp)
1326      {
1327         try
1328         {
1329           SuperClassWriter::addAttribute("name"       , name);
1330           SuperClassWriter::addAttribute("description", description);
1331           SuperClassWriter::addAttribute("conventions", conventions);
1332           SuperClassWriter::addAttribute("production" , production);
1333           SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
1334         }
1335         catch (CNetCdfException& e)
1336         {
1337           StdString msg("On writing File Attributes \n ");
1338           msg.append("In the context : ");
1339           CContext* context = CContext::getCurrent() ;
1340           msg.append(context->getId()); msg.append("\n");
1341           msg.append(e.what());
1342           ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \
1343                                                const StdString & description, \
1344                                                const StdString & conventions, \
1345                                                const StdString & production, \
1346                                                const StdString & timeStamp)", << msg);
1347         }
1348      }
1349
1350      //---------------------------------------------------------------
1351
1352      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
1353                                               int data_dim,
1354                                               int data_ni,
1355                                               int data_nj,
1356                                               int data_ibegin,
1357                                               int data_jbegin)
1358      {
1359         try
1360         {
1361           SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
1362           SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
1363           SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
1364           SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
1365           SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
1366         }
1367         catch (CNetCdfException& e)
1368         {
1369           StdString msg("On writing Mask Attributes \n ");
1370           msg.append("In the context : ");
1371           CContext* context = CContext::getCurrent() ;
1372           msg.append(context->getId()); msg.append("\n");
1373           msg.append(e.what());
1374           ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \
1375                                               int data_dim, \
1376                                               int data_ni, \
1377                                               int data_nj, \
1378                                               int data_ibegin, \
1379                                               int data_jbegin)", << msg);
1380         }
1381      }
1382
1383      ///--------------------------------------------------------------
1384
1385} // namespace xios
Note: See TracBrowser for help on using the repository browser.