source: XIOS/branchs/xios-1.0/src/output/nc4_data_output.cpp @ 609

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

Improve CF compliance: add a new axis attribute "bounds".

Fixes ticket #67.

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