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

Last change on this file since 501 was 501, checked in by ymipsl, 10 years ago

Add licence copyright to all file ond directory src using the command :
svn propset -R copyright -F header_licence src

XIOS is now officialy under CeCILL licence

YM

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