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

Last change on this file since 611 was 611, checked in by rlacroix, 9 years ago

Improve CF compliance: Add a new domain attribute "area".

Fixes ticket #68.

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