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

Last change on this file since 538 was 538, checked in by rlacroix, 10 years ago

Convert more attributes to use the new duration type:

  • field: freq_op and freq_offset
  • file: output_freq, sync_freq and split_freq.

Remember that you now have to use the "xios_duration" type instead of strings to get/set those attributes through the Fortran interface.

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