source: XIOS/trunk/src/io/nc4_data_output.cpp @ 802

Last change on this file since 802 was 802, checked in by rlacroix, 8 years ago

Add a new file attribute time_counter_name.

Users can now modify the name of the time counter dimension and axis name.

  • 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
  • Property svn:executable set to *
File size: 82.9 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         SuperClass::type = MULTI_FILE;
25      }
26
27      CNc4DataOutput::CNc4DataOutput
28         (const StdString & filename, bool exist, bool useClassicFormat,
29          MPI_Comm comm_file,bool multifile, bool isCollective, const StdString& timeCounterName)
30            : SuperClass()
31            , SuperClassWriter(filename, exist, useClassicFormat, &comm_file, multifile, timeCounterName)
32            , comm_file(comm_file)
33            , filename(filename)
34            , isCollective(isCollective)
35      {
36         SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE;
37      }
38
39
40      CNc4DataOutput::~CNc4DataOutput(void)
41      { /* Ne rien faire de plus */ }
42
43      ///--------------------------------------------------------------
44
45      const StdString & CNc4DataOutput::getFileName(void) const
46      {
47         return (this->filename);
48      }
49
50      //---------------------------------------------------------------
51
52      void CNc4DataOutput::writeDomain_(CDomain* domain)
53      {
54         if (domain->type == CDomain::type_attr::unstructured)
55         {
56           writeUnstructuredDomain(domain) ;
57           return ;
58         }
59
60         CContext* context = CContext::getCurrent() ;
61         CContextServer* server=context->server ;
62
63         if (domain->IsWritten(this->filename)) return;
64         domain->checkAttributes();
65
66         if (domain->isEmpty())
67           if (SuperClass::type==MULTI_FILE) return ;
68
69         std::vector<StdString> dim0, dim1;
70         StdString domid = domain->getDomainOutputName();
71         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
72         if (isWrittenDomain(domid)) return ;
73         else setWrittenDomain(domid);
74
75
76         StdString dimXid, dimYid ;
77
78         bool isRegularDomain = (domain->type == CDomain::type_attr::rectilinear);
79         switch (domain->type)
80         {
81           case CDomain::type_attr::curvilinear :
82             dimXid     = StdString("x").append(appendDomid);
83             dimYid     = StdString("y").append(appendDomid);
84             break ;
85           case CDomain::type_attr::rectilinear :
86             dimXid     = StdString("lon").append(appendDomid);
87             dimYid     = StdString("lat").append(appendDomid);
88             break;
89         }
90
91         StdString dimVertId = StdString("nvertex").append(appendDomid);
92
93         string lonid,latid,bounds_lonid,bounds_latid ;
94         string areaId = "area" + appendDomid;
95/*
96         StdString lonid_loc = (server->intraCommSize > 1)
97                             ? StdString("lon").append(appendDomid).append("_local")
98                             : lonid;
99         StdString latid_loc = (server->intraCommSize > 1)
100                             ? StdString("lat").append(appendDomid).append("_local")
101                             : latid;
102*/
103
104         try
105         {
106           switch (SuperClass::type)
107           {
108              case (MULTI_FILE) :
109              {
110  //               if (domain->isEmpty()) return;
111
112                 if (server->intraCommSize > 1)
113                 {
114  //                 SuperClassWriter::addDimension(lonid, domain->zoom_ni.getValue());
115  //                 SuperClassWriter::addDimension(latid, domain->zoom_nj.getValue());
116                 }
117
118                 switch (domain->type)
119                 {
120                   case CDomain::type_attr::curvilinear :
121                     dim0.push_back(dimYid); dim0.push_back(dimXid);
122                     lonid = StdString("nav_lon").append(appendDomid);
123                     latid = StdString("nav_lat").append(appendDomid);
124                     break ;
125                   case CDomain::type_attr::rectilinear :
126                     lonid = StdString("lon").append(appendDomid);
127                     latid = StdString("lat").append(appendDomid);
128                     dim0.push_back(dimYid);
129                     dim1.push_back(dimXid);
130                     break;
131                 }
132
133                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
134                 bounds_latid = StdString("bounds_lat").append(appendDomid);
135
136                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
137                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv);
138
139                 if (domain->hasBounds)
140                   SuperClassWriter::addDimension(dimVertId, domain->nvertex);
141
142                 if (server->intraCommSize > 1)
143                 {
144                   this->writeLocalAttributes(domain->zoom_ibegin_srv,
145                                              domain->zoom_ni_srv,
146                                              domain->zoom_jbegin_srv,
147                                              domain->zoom_nj_srv,
148                                              appendDomid);
149
150                   if (singleDomain)
151                    this->writeLocalAttributes_IOIPSL(dimXid, dimYid,
152                                                      domain->zoom_ibegin_srv,
153                                                      domain->zoom_ni_srv,
154                                                      domain->zoom_jbegin_srv,
155                                                      domain->zoom_nj_srv,
156                                                      domain->ni_glo,domain->nj_glo,
157                                                      server->intraCommRank,server->intraCommSize);
158                 }
159
160                 if (domain->hasLonLat)
161                 {
162                   switch (domain->type)
163                   {
164                     case CDomain::type_attr::curvilinear :
165                       SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
166                       SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
167                       break ;
168                      case CDomain::type_attr::rectilinear :
169                        SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
170                        SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
171                        break ;
172                   }
173
174                   this->writeAxisAttributes(lonid, isRegularDomain ? "X" : "", "longitude", "Longitude", "degrees_east", domid);
175                   this->writeAxisAttributes(latid, isRegularDomain ? "Y" : "", "latitude", "Latitude", "degrees_north", domid);
176
177                   if (domain->hasBounds)
178                   {
179                     SuperClassWriter::addAttribute("bounds", bounds_lonid, &lonid);
180                     SuperClassWriter::addAttribute("bounds", bounds_latid, &latid);
181
182                     dim0.clear();
183                     dim0.push_back(dimYid);
184                     dim0.push_back(dimXid);
185                     dim0.push_back(dimVertId);
186                     SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
187                     SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
188                   }
189                 }
190
191                 dim0.clear();
192                 dim0.push_back(dimYid);
193                 dim0.push_back(dimXid);
194
195
196  // supress mask               if (server->intraCommSize > 1)
197  // supress mask               {
198  // supress mask                  SuperClassWriter::addVariable(maskid, NC_INT, dim0);
199  // supress mask
200  // supress mask                  this->writeMaskAttributes(maskid,
201  // supress mask                     domain->data_dim.getValue()/*,
202  // supress mask                     domain->data_ni.getValue(),
203  // supress mask                     domain->data_nj.getValue(),
204  // supress mask                     domain->data_ibegin.getValue(),
205  // supress mask                     domain->data_jbegin.getValue()*/);
206  // supress mask               }
207
208                 //SuperClassWriter::setDefaultValue(maskid, &dvm);
209
210                 if (domain->hasArea)
211                 {
212                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
213                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
214                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
215                 }
216
217                 SuperClassWriter::definition_end();
218
219                 if (domain->hasLonLat)
220                 {
221                   switch (domain->type)
222                   {
223                     case CDomain::type_attr::curvilinear :
224                       SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
225                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
226                       break;
227                     case CDomain::type_attr::rectilinear :
228                       CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
229                       SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
230                       CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
231                       SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
232                       break;
233                   }
234
235                   if (domain->hasBounds)
236                   {
237                     SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
238                     SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
239                   }
240                 }
241
242                 if (domain->hasArea)
243                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0);
244
245                 SuperClassWriter::definition_start();
246
247                 break;
248              }
249              case (ONE_FILE) :
250              {
251                 SuperClassWriter::addDimension(dimXid, domain->global_zoom_ni);
252                 SuperClassWriter::addDimension(dimYid, domain->global_zoom_nj);
253
254                 if (domain->hasBounds)
255                   SuperClassWriter::addDimension(dimVertId, domain->nvertex);
256
257                 if (domain->hasLonLat)
258                 {
259                   switch (domain->type)
260                   {
261                     case CDomain::type_attr::curvilinear :
262                       dim0.push_back(dimYid); dim0.push_back(dimXid);
263                       lonid = StdString("nav_lon").append(appendDomid);
264                       latid = StdString("nav_lat").append(appendDomid);
265                       SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
266                       SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
267                       break;
268
269                     case CDomain::type_attr::rectilinear :
270                       dim0.push_back(dimYid);
271                       dim1.push_back(dimXid);
272                       lonid = StdString("lon").append(appendDomid);
273                       latid = StdString("lat").append(appendDomid);
274                       SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
275                       SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
276                       break;
277                   }
278
279                   bounds_lonid = StdString("bounds_lon").append(appendDomid);
280                   bounds_latid = StdString("bounds_lat").append(appendDomid);
281
282                   this->writeAxisAttributes
283                      (lonid, isRegularDomain ? "X" : "", "longitude", "Longitude", "degrees_east", domid);
284                   this->writeAxisAttributes
285                      (latid, isRegularDomain ? "Y" : "", "latitude", "Latitude", "degrees_north", domid);
286
287                   if (domain->hasBounds)
288                   {
289                     SuperClassWriter::addAttribute("bounds", bounds_lonid, &lonid);
290                     SuperClassWriter::addAttribute("bounds", bounds_latid, &latid);
291
292                     dim0.clear();
293                     dim0.push_back(dimYid);
294                     dim0.push_back(dimXid);
295                     dim0.push_back(dimVertId);
296                     SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
297                     SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
298                   }
299                 }
300
301                 if (domain->hasArea)
302                 {
303                   dim0.clear();
304                   dim0.push_back(dimYid); dim0.push_back(dimXid);
305                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
306                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
307                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
308                   dim0.clear();
309                 }
310
311                 SuperClassWriter::definition_end();
312
313                 switch (domain->type)
314                 {
315                   case CDomain::type_attr::curvilinear :
316                   {
317                     std::vector<StdSize> start(2) ;
318                     std::vector<StdSize> count(2) ;
319                     if (domain->isEmpty())
320                     {
321                       start[0]=0 ; start[1]=0 ;
322                       count[0]=0 ; count[1]=0 ;
323                     }
324                     else
325                     {
326                       start[1]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
327                       start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
328                       count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
329                     }
330
331                     if (domain->hasLonLat)
332                     {
333                       SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
334                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
335                     }
336                     break;
337                   }
338                   case CDomain::type_attr::rectilinear :
339                   {
340                     if (domain->hasLonLat)
341                     {
342                       std::vector<StdSize> start(1) ;
343                       std::vector<StdSize> count(1) ;
344                       if (domain->isEmpty())
345                       {
346                         start[0]=0 ;
347                         count[0]=0 ;
348                         SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
349                         SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
350
351                       }
352                       else
353                       {
354                         start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
355                         count[0]=domain->zoom_nj_srv ;
356                         CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
357                         SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
358
359                         start[0]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
360                         count[0]=domain->zoom_ni_srv ;
361                         CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
362                         SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
363                       }
364                     }
365                     break;
366                   }
367                 }
368
369                 if (domain->hasBounds)
370                 {
371                   std::vector<StdSize> start(3);
372                   std::vector<StdSize> count(3);
373                   if (domain->isEmpty())
374                   {
375                     start[2] = start[1] = start[0] = 0;
376                     count[2] = count[1] = count[0] = 0;
377                   }
378                   else
379                   {
380                     start[2] = 0;
381                     start[1] = domain->zoom_ibegin_srv - domain->global_zoom_ibegin;
382                     start[0] = domain->zoom_jbegin_srv - domain->global_zoom_jbegin;
383                     count[2] = domain->nvertex;
384                     count[1] = domain->zoom_ni_srv;
385                     count[0] = domain->zoom_nj_srv;
386                   }
387
388                   SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0, &start, &count);
389                   SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0, &start, &count);
390                 }
391
392                 if (domain->hasArea)
393                 {
394                   std::vector<StdSize> start(2);
395                   std::vector<StdSize> count(2);
396
397                   if (domain->isEmpty())
398                   {
399                     start[0] = 0; start[1] = 0;
400                     count[0] = 0; count[1] = 0;
401                   }
402                   else
403                   {
404                     start[1] = domain->zoom_ibegin_srv - domain->global_zoom_ibegin;
405                     start[0] = domain->zoom_jbegin_srv - domain->global_zoom_jbegin;
406                     count[1] = domain->zoom_ni_srv;
407                     count[0] = domain->zoom_nj_srv;
408                   }
409
410                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count);
411                 }
412
413                 SuperClassWriter::definition_start();
414                 break;
415              }
416              default :
417                 ERROR("CNc4DataOutput::writeDomain(domain)",
418                       << "[ type = " << SuperClass::type << "]"
419                       << " not implemented yet !");
420           }
421         }
422         catch (CNetCdfException& e)
423         {
424           StdString msg("On writing the domain : ");
425           msg.append(domid); msg.append("\n");
426           msg.append("In the context : ");
427           msg.append(context->getId()); msg.append("\n");
428           msg.append(e.what());
429           ERROR("CNc4DataOutput::writeDomain_(CDomain* domain)", << msg);
430         }
431
432         domain->addRelFile(this->filename);
433      }
434
435      void CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)
436      {
437         CContext* context = CContext::getCurrent() ;
438         CContextServer* server=context->server ;
439
440         if (domain->IsWritten(this->filename)) return;
441         domain->checkAttributes();
442
443         if (domain->isEmpty())
444           if (SuperClass::type==MULTI_FILE) return ;
445
446         std::vector<StdString> dim0, dim1;
447         StdString domid = domain->getDomainOutputName();
448         if (isWrittenDomain(domid)) return ;
449         else setWrittenDomain(domid);
450
451         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
452
453
454         StdString dimXid = StdString("cell").append(appendDomid);
455         StdString dimVertId = StdString("nvertex").append(appendDomid);
456
457         string lonid,latid,bounds_lonid,bounds_latid ;
458         string areaId = "area" + appendDomid;
459
460         try
461         {
462           switch (SuperClass::type)
463           {
464              case (MULTI_FILE) :
465              {
466                 dim0.push_back(dimXid);
467                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
468
469                 lonid = StdString("lon").append(appendDomid);
470                 latid = StdString("lat").append(appendDomid);
471                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
472                 bounds_latid = StdString("bounds_lat").append(appendDomid);
473                 if (domain->hasLonLat)
474                 {
475                   SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
476                   SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
477                   this->writeAxisAttributes(lonid, "", "longitude", "Longitude", "degrees_east", domid);
478                   if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
479                   this->writeAxisAttributes(latid, "", "latitude", "Latitude", "degrees_north", domid);
480                   if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
481                   if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
482                 }
483
484                 dim0.clear();
485                 if (domain->hasBounds)
486                 {
487                   dim0.push_back(dimXid);
488                   dim0.push_back(dimVertId);
489                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
490                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
491                 }
492
493                 dim0.clear();
494                 dim0.push_back(dimXid);
495                 if (domain->hasArea)
496                 {
497                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
498                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
499                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
500                 }
501
502                 SuperClassWriter::definition_end();
503
504                 if (domain->hasLonLat)
505                 {
506                   SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
507                   SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
508                   if (domain->hasBounds)
509                   {
510                     SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
511                     SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
512                   }
513                 }
514
515                 if (domain->hasArea)
516                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0);
517
518                 SuperClassWriter::definition_start();
519                 break ;
520              }
521
522              case (ONE_FILE) :
523              {
524                 lonid = StdString("lon").append(appendDomid);
525                 latid = StdString("lat").append(appendDomid);
526                 bounds_lonid = StdString("bounds_lon").append(appendDomid);
527                 bounds_latid = StdString("bounds_lat").append(appendDomid);
528                 dim0.push_back(dimXid);
529                 SuperClassWriter::addDimension(dimXid, domain->ni_glo);
530                 if (domain->hasLonLat)
531                 {
532                   SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
533                   SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
534
535                   this->writeAxisAttributes(lonid, "", "longitude", "Longitude", "degrees_east", domid);
536                   if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
537                   this->writeAxisAttributes(latid, "", "latitude", "Latitude", "degrees_north", domid);
538                   if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
539                   if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
540                 }
541                 dim0.clear();
542
543                 if (domain->hasBounds)
544                 {
545                   dim0.push_back(dimXid);
546                   dim0.push_back(dimVertId);
547                   SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
548                   SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
549                 }
550
551                 if (domain->hasArea)
552                 {
553                   dim0.clear();
554                   dim0.push_back(dimXid);
555                   SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);
556                   SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId);
557                   SuperClassWriter::addAttribute("units", StdString("m2"), &areaId);
558                 }
559
560                 SuperClassWriter::definition_end();
561
562                 std::vector<StdSize> start(1), startBounds(2) ;
563                 std::vector<StdSize> count(1), countBounds(2) ;
564                 if (domain->isEmpty())
565                 {
566                   start[0]=0 ;
567                   count[0]=0 ;
568                   startBounds[1]=0 ;
569                   countBounds[1]=domain->nvertex ;
570                   startBounds[0]=0 ;
571                   countBounds[0]=0 ;
572                 }
573                 else
574                 {
575                   start[0]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
576                   count[0]=domain->zoom_ni_srv ;
577                   startBounds[0]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
578                   startBounds[1]=0 ;
579                   countBounds[0]=domain->zoom_ni_srv ;
580                   countBounds[1]=domain->nvertex ;
581                 }
582
583                 if (domain->hasLonLat)
584                 {
585                   SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
586                   SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
587                   if (domain->hasBounds)
588                   {
589                     SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
590                     SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds);
591                   }
592                 }
593
594                 if (domain->hasArea)
595                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count);
596
597                 SuperClassWriter::definition_start();
598
599                 break;
600              }
601              default :
602                 ERROR("CNc4DataOutput::writeDomain(domain)",
603                       << "[ type = " << SuperClass::type << "]"
604                       << " not implemented yet !");
605           }
606         }
607         catch (CNetCdfException& e)
608         {
609           StdString msg("On writing the domain : ");
610           msg.append(domid); msg.append("\n");
611           msg.append("In the context : ");
612           msg.append(context->getId()); msg.append("\n");
613           msg.append(e.what());
614           ERROR("CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)", << msg);
615         }
616         domain->addRelFile(this->filename);
617      }
618      //--------------------------------------------------------------
619
620      void CNc4DataOutput::writeAxis_(CAxis* axis)
621      {
622        if (axis->IsWritten(this->filename)) return;
623        axis->checkAttributes();
624        int zoom_size_srv  = axis->zoom_size_srv;
625        int zoom_begin_srv = axis->zoom_begin_srv;
626        int zoom_size  = (MULTI_FILE == SuperClass::type) ? zoom_size_srv
627                                                              : axis->global_zoom_size;
628        int zoom_begin = (MULTI_FILE == SuperClass::type) ? zoom_begin_srv
629                                                              : axis->global_zoom_begin;
630
631        if ((0 == zoom_size_srv) && (MULTI_FILE == SuperClass::type)) return;
632
633        std::vector<StdString> dims;
634        StdString axisid = axis->getAxisOutputName();
635        if (isWrittenAxis(axisid)) return ;
636        else setWrittenAxis(axisid);
637
638        try
639        {
640          SuperClassWriter::addDimension(axisid, zoom_size);
641          dims.push_back(axisid);
642          SuperClassWriter::addVariable(axisid, NC_FLOAT, dims);
643
644          if (!axis->name.isEmpty())
645            SuperClassWriter::addAttribute("name", axis->name.getValue(), &axisid);
646
647          if (!axis->standard_name.isEmpty())
648            SuperClassWriter::addAttribute("standard_name", axis->standard_name.getValue(), &axisid);
649
650          if (!axis->long_name.isEmpty())
651            SuperClassWriter::addAttribute("long_name", axis->long_name.getValue(), &axisid);
652
653          if (!axis->unit.isEmpty())
654            SuperClassWriter::addAttribute("units", axis->unit.getValue(), &axisid);
655
656          if (!axis->positive.isEmpty())
657          {
658            SuperClassWriter::addAttribute("axis", string("Z"), &axisid);
659            SuperClassWriter::addAttribute("positive",
660                                           (axis->positive == CAxis::positive_attr::up) ? string("up") : string("down"),
661                                           &axisid);
662          }
663
664          StdString axisBoundsId = axisid + "_bounds";
665          if (!axis->bounds.isEmpty())
666          {
667            dims.push_back("axis_nbounds");
668            SuperClassWriter::addVariable(axisBoundsId, NC_FLOAT, dims);
669            SuperClassWriter::addAttribute("bounds", axisBoundsId, &axisid);
670          }
671
672          SuperClassWriter::definition_end();
673          switch (SuperClass::type)
674          {
675            case MULTI_FILE:
676            {
677              CArray<double,1> axis_value(zoom_size_srv);
678              for (int i = 0; i < zoom_size_srv; i++) axis_value(i) = axis->value_srv(i);
679              SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
680
681              if (!axis->bounds.isEmpty())
682                SuperClassWriter::writeData(axis->bound_srv, axisBoundsId, isCollective, 0);
683
684              SuperClassWriter::definition_start();
685
686              break;
687            }
688            case ONE_FILE:
689            {
690              CArray<double,1> axis_value(zoom_size_srv);
691              axis_value = axis->value_srv;
692
693              std::vector<StdSize> start(1), startBounds(2) ;
694              std::vector<StdSize> count(1), countBounds(2) ;
695              start[0] = startBounds[0] = zoom_begin_srv-axis->global_zoom_begin;
696              count[0] = countBounds[0] = zoom_size_srv;
697              startBounds[1] = 0;
698              countBounds[1] = 2;
699              SuperClassWriter::writeData(axis_value, axisid, isCollective, 0, &start, &count);
700
701              if (!axis->bounds.isEmpty())
702                SuperClassWriter::writeData(axis->bound_srv, axisBoundsId, isCollective, 0, &startBounds, &countBounds);
703
704              SuperClassWriter::definition_start();
705
706              break;
707            }
708            default :
709              ERROR("CNc4DataOutput::writeDomain(domain)",
710                    << "[ type = " << SuperClass::type << "]"
711                    << " not implemented yet !");
712          }
713        }
714        catch (CNetCdfException& e)
715        {
716          StdString msg("On writing the axis : ");
717          msg.append(axisid); msg.append("\n");
718          msg.append("In the context : ");
719          CContext* context = CContext::getCurrent() ;
720          msg.append(context->getId()); msg.append("\n");
721          msg.append(e.what());
722          ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg);
723        }
724        axis->addRelFile(this->filename);
725     }
726
727     //--------------------------------------------------------------
728
729     void CNc4DataOutput::writeGridCompressed_(CGrid* grid)
730     {
731       if (grid->isScalarGrid() || grid->isWrittenCompressed(this->filename)) return;
732
733       try
734       {
735         CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
736         std::vector<StdString> domainList = grid->getDomainList();
737         std::vector<StdString> axisList   = grid->getAxisList();
738         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0;
739
740         std::vector<StdString> dims;
741
742         if (grid->isCompressible())
743         {
744           StdString varId = grid->getId() + "_points";
745
746           int nbIndexes = (SuperClass::type == MULTI_FILE) ? grid->getNumberWrittenIndexes() : grid->getTotalNumberWrittenIndexes();
747           SuperClassWriter::addDimension(varId, nbIndexes);
748
749           dims.push_back(varId);
750           SuperClassWriter::addVariable(varId, NC_INT, dims);
751
752           StdOStringStream compress;
753           for (int i = numElement - 1; i >= 0; --i)
754           {
755             if (axisDomainOrder(i))
756             {
757               CDomain* domain = CDomain::get(domainList[domainList.size() - idxDomain - 1]);
758               StdString domId = domain->getDomainOutputName();
759               StdString appendDomId  = singleDomain ? "" : "_" + domId;
760
761               switch (domain->type)
762               {
763                 case CDomain::type_attr::curvilinear:
764                   compress << "y" << appendDomId << " x" << appendDomId;
765                   break;
766                 case CDomain::type_attr::rectilinear:
767                   compress << "lat" << appendDomId << " lon" << appendDomId;
768                   break;
769                 case CDomain::type_attr::unstructured:
770                   compress << "cell" << appendDomId;
771                   break;
772               }
773               ++idxDomain;
774             }
775             else
776             {
777               CAxis* axis = CAxis::get(axisList[axisList.size() - idxAxis - 1]);
778               compress << axis->getAxisOutputName();
779               ++idxAxis;
780             }
781
782             if (i != 0) compress << ' ';
783           }
784           SuperClassWriter::addAttribute("compress", compress.str(), &varId);
785
786           grid->computeCompressedIndex();
787
788           CArray<int, 1> indexes(grid->getNumberWrittenIndexes());
789           std::map<int, CArray<size_t, 1> >::const_iterator it;
790           for (it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
791           {
792             const CArray<size_t, 1> compressedIndexes = grid->compressedOutIndexFromClient[it->first];
793             for (int i = 0; i < it->second.numElements(); i++)
794               indexes(compressedIndexes(i)) = it->second(i);
795           }
796
797           switch (SuperClass::type)
798           {
799             case (MULTI_FILE):
800             {
801               SuperClassWriter::writeData(indexes, varId, isCollective, 0);
802               break;
803             }
804             case (ONE_FILE):
805             {
806               if (grid->doGridHaveDataDistributed())
807                 grid->getDistributionServer()->computeGlobalIndex(indexes);
808
809               std::vector<StdSize> start, count;
810               start.push_back(grid->getOffsetWrittenIndexes());
811               count.push_back(grid->getNumberWrittenIndexes());
812
813               SuperClassWriter::writeData(indexes, varId, isCollective, 0, &start, &count);
814               break;
815             }
816           }
817         }
818         else
819         {
820           for (int i = 0; i < numElement; ++i)
821           {
822             StdString varId, compress;
823             CArray<int, 1> indexes;
824             bool isDistributed;
825             StdSize nbIndexes, totalNbIndexes, offset;
826             int firstGlobalIndex;
827
828             if (axisDomainOrder(i))
829             {
830               CDomain* domain = CDomain::get(domainList[idxDomain]);
831               StdString domId = domain->getDomainOutputName();
832
833               if (!domain->isCompressible()
834                    || domain->type == CDomain::type_attr::unstructured
835                    || domain->isWrittenCompressed(this->filename)
836                    || isWrittenCompressedDomain(domId))
837                 continue;
838
839               StdString appendDomId  = singleDomain ? "" : "_" + domId;
840
841               varId = domId + "_points";
842               switch (domain->type)
843               {
844                 case CDomain::type_attr::curvilinear:
845                   compress = "y" + appendDomId + " x" + appendDomId;
846                   break;
847                 case CDomain::type_attr::rectilinear:
848                   compress = "lat" + appendDomId + " lon" + appendDomId;
849                   break;
850               }
851
852               const std::vector<int>& indexesToWrite = domain->getIndexesToWrite();
853               indexes.resize(indexesToWrite.size());
854               for (int n = 0; n < indexes.numElements(); ++n)
855                 indexes(n) = indexesToWrite[n];
856
857               isDistributed = domain->isDistributed();
858               nbIndexes = domain->getNumberWrittenIndexes();
859               totalNbIndexes = domain->getTotalNumberWrittenIndexes();
860               offset = domain->getOffsetWrittenIndexes();
861               firstGlobalIndex = domain->ibegin + domain->jbegin * domain->ni_glo;
862
863               domain->addRelFileCompressed(this->filename);
864               setWrittenCompressedDomain(domId);
865               ++idxDomain;
866             }
867             else
868             {
869               CAxis* axis = CAxis::get(axisList[idxAxis]);
870               StdString axisId = axis->getAxisOutputName();
871
872               if (!axis->isCompressible()
873                    || axis->isWrittenCompressed(this->filename)
874                    || isWrittenCompressedAxis(axisId))
875                 continue;
876
877               varId = axisId + "_points";
878               compress = axisId;
879
880               const std::vector<int>& indexesToWrite = axis->getIndexesToWrite();
881               indexes.resize(indexesToWrite.size());
882               for (int n = 0; n < indexes.numElements(); ++n)
883                 indexes(n) = indexesToWrite[n];
884
885               isDistributed = axis->isDistributed();
886               nbIndexes = axis->getNumberWrittenIndexes();
887               totalNbIndexes = axis->getTotalNumberWrittenIndexes();
888               offset = axis->getOffsetWrittenIndexes();
889               firstGlobalIndex = axis->begin;
890
891               axis->addRelFileCompressed(this->filename);
892               setWrittenCompressedAxis(axisId);
893               ++idxAxis;
894             }
895
896             if (!varId.empty())
897             {
898               SuperClassWriter::addDimension(varId, (SuperClass::type == MULTI_FILE) ? nbIndexes : totalNbIndexes);
899
900               dims.clear();
901               dims.push_back(varId);
902               SuperClassWriter::addVariable(varId, NC_INT, dims);
903
904               SuperClassWriter::addAttribute("compress", compress, &varId);
905
906               switch (SuperClass::type)
907               {
908                 case (MULTI_FILE):
909                 {
910                   indexes -= firstGlobalIndex;
911                   SuperClassWriter::writeData(indexes, varId, isCollective, 0);
912                   break;
913                 }
914                 case (ONE_FILE):
915                 {
916                   std::vector<StdSize> start, count;
917                   start.push_back(offset);
918                   count.push_back(nbIndexes);
919
920                   SuperClassWriter::writeData(indexes, varId, isCollective, 0, &start, &count);
921                   break;
922                 }
923               }
924             }
925           }
926
927           if (!dims.empty())
928             grid->computeCompressedIndex();
929         }
930
931         grid->addRelFileCompressed(this->filename);
932       }
933       catch (CNetCdfException& e)
934       {
935         StdString msg("On writing compressed grid : ");
936         msg.append(grid->getId()); msg.append("\n");
937         msg.append("In the context : ");
938         CContext* context = CContext::getCurrent();
939         msg.append(context->getId()); msg.append("\n");
940         msg.append(e.what());
941         ERROR("CNc4DataOutput::writeGridCompressed_(CGrid* grid)", << msg);
942       }
943     }
944
945     //--------------------------------------------------------------
946
947     void CNc4DataOutput::writeTimeDimension_(void)
948     {
949       try
950       {
951        SuperClassWriter::addDimension(getTimeCounterName());
952       }
953       catch (CNetCdfException& e)
954       {
955         StdString msg("On writing time dimension : time_couter\n");
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::writeTimeDimension_(void)", << msg);
961       }
962     }
963
964      //--------------------------------------------------------------
965
966      void CNc4DataOutput::writeField_(CField* field)
967      {
968         CContext* context = CContext::getCurrent() ;
969         CContextServer* server=context->server ;
970
971         std::vector<StdString> dims, coodinates;
972         CGrid* grid = field->grid;
973         if (!grid->doGridHaveDataToWrite())
974          if (SuperClass::type==MULTI_FILE) return ;
975
976         CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
977         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0;
978         std::vector<StdString> domainList = grid->getDomainList();
979         std::vector<StdString> axisList   = grid->getAxisList();
980
981         StdString timeid  = getTimeCounterName();
982         StdString dimXid,dimYid;
983         std::deque<StdString> dimIdList, dimCoordList;
984         bool hasArea = false;
985         StdString cellMeasures = "area:";
986         bool compressedOutput = !field->indexed_output.isEmpty() && field->indexed_output;
987
988         for (int i = 0; i < numElement; ++i)
989         {
990           if (axisDomainOrder(i))
991           {
992             CDomain* domain = CDomain::get(domainList[idxDomain]);
993             StdString domId = domain->getDomainOutputName();
994             StdString appendDomId  = singleDomain ? "" : "_" + domId ;
995
996             if (compressedOutput && domain->isCompressible() && domain->type != CDomain::type_attr::unstructured)
997             {
998               dimIdList.push_back(domId + "_points");
999               field->setUseCompressedOutput();
1000             }
1001
1002             switch (domain->type)
1003             {
1004               case CDomain::type_attr::curvilinear:
1005                 if (!compressedOutput || !domain->isCompressible())
1006                 {
1007                   dimXid     = StdString("x").append(appendDomId);
1008                   dimIdList.push_back(dimXid);
1009                   dimYid     = StdString("y").append(appendDomId);
1010                   dimIdList.push_back(dimYid);
1011                 }
1012                 dimCoordList.push_back(StdString("nav_lon").append(appendDomId));
1013                 dimCoordList.push_back(StdString("nav_lat").append(appendDomId));
1014                 break ;
1015               case CDomain::type_attr::rectilinear:
1016                 if (!compressedOutput || !domain->isCompressible())
1017                 {
1018                   dimXid     = StdString("lon").append(appendDomId);
1019                   dimIdList.push_back(dimXid);
1020                   dimYid     = StdString("lat").append(appendDomId);
1021                   dimIdList.push_back(dimYid);
1022                 }
1023                 break ;
1024               case CDomain::type_attr::unstructured:
1025                 dimXid     = StdString("cell").append(appendDomId);
1026                 dimIdList.push_back(dimXid);
1027                 dimCoordList.push_back(StdString("lon").append(appendDomId));
1028                 dimCoordList.push_back(StdString("lat").append(appendDomId));
1029                 break ;
1030             }
1031             if (domain->hasArea)
1032             {
1033               hasArea = true;
1034               cellMeasures += " area" + appendDomId;
1035             }
1036             ++idxDomain;
1037           }
1038           else
1039           {
1040             CAxis* axis = CAxis::get(axisList[idxAxis]);
1041             StdString axisId = axis->getAxisOutputName();
1042
1043             if (compressedOutput && axis->isCompressible())
1044             {
1045               dimIdList.push_back(axisId + "_points");
1046               field->setUseCompressedOutput();
1047             }
1048             else
1049               dimIdList.push_back(axisId);
1050
1051             dimCoordList.push_back(axisId);
1052             ++idxAxis;
1053           }
1054         }
1055
1056/*
1057         StdString lonid_loc = (server->intraCommSize > 1)
1058                             ? StdString("lon").append(appendDomid).append("_local")
1059                             : lonid;
1060         StdString latid_loc = (server->intraCommSize > 1)
1061                             ? StdString("lat").append(appendDomid).append("_local")
1062                             : latid;
1063*/
1064         StdString fieldid = field->getFieldOutputName();
1065
1066//         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
1067//         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
1068//          bool isCurvilinear = domain->isCurvilinear ;
1069
1070         nc_type type ;
1071         if (field->prec.isEmpty()) type =  NC_FLOAT ;
1072         else
1073         {
1074           if (field->prec==2) type = NC_SHORT ;
1075           else if (field->prec==4)  type =  NC_FLOAT ;
1076           else if (field->prec==8)   type =  NC_DOUBLE ;
1077         }
1078
1079         bool wtime   = !(!field->operation.isEmpty() && field->getOperationTimeType() == func::CFunctor::once);
1080
1081         if (wtime)
1082         {
1083
1084            //StdOStringStream oss;
1085           // oss << "time_" << field->operation.getValue()
1086           //     << "_" << field->getRelFile()->output_freq.getValue();
1087          //oss
1088            if (field->getOperationTimeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
1089            else if (field->getOperationTimeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
1090            dims.push_back(timeid);
1091         }
1092
1093         if (compressedOutput && grid->isCompressible())
1094         {
1095           dims.push_back(grid->getId() + "_points");
1096           field->setUseCompressedOutput();
1097         }
1098         else
1099         {
1100           while (!dimIdList.empty())
1101           {
1102             dims.push_back(dimIdList.back());
1103             dimIdList.pop_back();
1104           }
1105         }
1106
1107         while (!dimCoordList.empty())
1108         {
1109           coodinates.push_back(dimCoordList.back());
1110           dimCoordList.pop_back();
1111         }
1112
1113         try
1114         {
1115           SuperClassWriter::addVariable(fieldid, type, dims);
1116
1117           if (!field->standard_name.isEmpty())
1118              SuperClassWriter::addAttribute
1119                 ("standard_name",  field->standard_name.getValue(), &fieldid);
1120
1121           if (!field->long_name.isEmpty())
1122              SuperClassWriter::addAttribute
1123                 ("long_name", field->long_name.getValue(), &fieldid);
1124
1125           if (!field->unit.isEmpty())
1126              SuperClassWriter::addAttribute
1127                 ("units", field->unit.getValue(), &fieldid);
1128
1129            if (!field->valid_min.isEmpty())
1130              SuperClassWriter::addAttribute
1131                 ("valid_min", field->valid_min.getValue(), &fieldid);
1132
1133           if (!field->valid_max.isEmpty())
1134              SuperClassWriter::addAttribute
1135                 ("valid_max", field->valid_max.getValue(), &fieldid);
1136
1137            if (!field->scale_factor.isEmpty())
1138              SuperClassWriter::addAttribute
1139                 ("scale_factor", field->scale_factor.getValue(), &fieldid);
1140
1141             if (!field->add_offset.isEmpty())
1142              SuperClassWriter::addAttribute
1143                 ("add_offset", field->add_offset.getValue(), &fieldid);
1144
1145           SuperClassWriter::addAttribute
1146                 ("online_operation", field->operation.getValue(), &fieldid);
1147
1148          // write child variables as attributes
1149
1150
1151           vector<CVariable*> listVars = field->getAllVariables() ;
1152           for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ;
1153
1154
1155           if (wtime)
1156           {
1157              CDuration freqOp = field->freq_op.getValue();
1158              freqOp.solveTimeStep(*context->calendar);
1159              StdString freqOpStr = freqOp.toStringUDUnits();
1160              SuperClassWriter::addAttribute("interval_operation", freqOpStr, &fieldid);
1161
1162              CDuration freqOut = field->getRelFile()->output_freq.getValue();
1163              freqOut.solveTimeStep(*context->calendar);
1164              SuperClassWriter::addAttribute("interval_write", freqOut.toStringUDUnits(), &fieldid);
1165
1166              StdString cellMethods = "time: ";
1167              if (field->operation.getValue() == "instant") cellMethods += "point";
1168              else if (field->operation.getValue() == "average") cellMethods += "mean";
1169              else if (field->operation.getValue() == "accumulate") cellMethods += "sum";
1170              else cellMethods += field->operation;
1171              if (freqOp.resolve(*context->calendar) != freqOut.resolve(*context->calendar))
1172                cellMethods += " (interval: " + freqOpStr + ")";
1173              SuperClassWriter::addAttribute("cell_methods", cellMethods, &fieldid);
1174           }
1175
1176           if (hasArea)
1177             SuperClassWriter::addAttribute("cell_measures", cellMeasures, &fieldid);
1178
1179           if (!field->default_value.isEmpty())
1180           {
1181              double default_value = field->default_value.getValue();
1182              float fdefault_value = (float)default_value;
1183              if (type == NC_DOUBLE)
1184                 SuperClassWriter::setDefaultValue(fieldid, &default_value);
1185              else
1186                 SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
1187           }
1188           else
1189              SuperClassWriter::setDefaultValue(fieldid, (double*)NULL);
1190
1191            if (field->compression_level.isEmpty())
1192              field->compression_level = field->file->compression_level.isEmpty() ? 0 : field->file->compression_level;
1193            SuperClassWriter::setCompressionLevel(fieldid, field->compression_level);
1194
1195           {  // Ecriture des coordonnées
1196
1197              StdString coordstr; //boost::algorithm::join(coodinates, " ")
1198              std::vector<StdString>::iterator
1199                 itc = coodinates.begin(), endc = coodinates.end();
1200
1201              for (; itc!= endc; itc++)
1202              {
1203                 StdString & coord = *itc;
1204                 if (itc+1 != endc)
1205                       coordstr.append(coord).append(" ");
1206                 else  coordstr.append(coord);
1207              }
1208
1209              SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
1210
1211           }
1212         }
1213         catch (CNetCdfException& e)
1214         {
1215           StdString msg("On writing field : ");
1216           msg.append(fieldid); msg.append("\n");
1217           msg.append("In the context : ");
1218           msg.append(context->getId()); msg.append("\n");
1219           msg.append(e.what());
1220           ERROR("CNc4DataOutput::writeField_(CField* field)", << msg);
1221         }
1222      }
1223
1224      //--------------------------------------------------------------
1225
1226      void CNc4DataOutput::writeFile_ (CFile* file)
1227      {
1228         StdString filename = file->getFileOutputName();
1229         StdString description = (!file->description.isEmpty())
1230                               ? file->description.getValue()
1231                               : StdString("Created by xios");
1232
1233         singleDomain = (file->nbDomains == 1);
1234
1235         try
1236         {
1237           this->writeFileAttributes(filename, description,
1238                                     StdString("CF-1.5"),
1239                                     StdString("An IPSL model"),
1240                                     this->getTimeStamp());
1241
1242           if (!appendMode)
1243             SuperClassWriter::addDimension("axis_nbounds", 2);
1244         }
1245         catch (CNetCdfException& e)
1246         {
1247           StdString msg("On writing file : ");
1248           msg.append(filename); msg.append("\n");
1249           msg.append("In the context : ");
1250           CContext* context = CContext::getCurrent() ;
1251           msg.append(context->getId()); msg.append("\n");
1252           msg.append(e.what());
1253           ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg);
1254         }
1255      }
1256
1257      void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)
1258      {
1259        StdString name = var->getVariableOutputName();
1260
1261        try
1262        {
1263          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1264            addAttribute(name, var->getData<int>(), &fieldId);
1265          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1266            addAttribute(name, var->getData<short int>(), &fieldId);
1267          else if (var->type.getValue() == CVariable::type_attr::t_float)
1268            addAttribute(name, var->getData<float>(), &fieldId);
1269          else if (var->type.getValue() == CVariable::type_attr::t_double)
1270            addAttribute(name, var->getData<double>(), &fieldId);
1271          else if (var->type.getValue() == CVariable::type_attr::t_string)
1272            addAttribute(name, var->getData<string>(), &fieldId);
1273          else
1274            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)",
1275                  << "Unsupported variable of type " << var->type.getStringValue());
1276        }
1277       catch (CNetCdfException& e)
1278       {
1279         StdString msg("On writing attributes of variable with name : ");
1280         msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n");
1281         msg.append("In the context : ");
1282         CContext* context = CContext::getCurrent() ;
1283         msg.append(context->getId()); msg.append("\n");
1284         msg.append(e.what());
1285         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg);
1286       }
1287     }
1288
1289     void CNc4DataOutput::writeAttribute_ (CVariable* var)
1290     {
1291        StdString name = var->getVariableOutputName();
1292
1293        try
1294        {
1295          if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32)
1296            addAttribute(name, var->getData<int>());
1297          else if (var->type.getValue() == CVariable::type_attr::t_int16)
1298            addAttribute(name, var->getData<short int>());
1299          else if (var->type.getValue() == CVariable::type_attr::t_float)
1300            addAttribute(name, var->getData<float>());
1301          else if (var->type.getValue() == CVariable::type_attr::t_double)
1302            addAttribute(name, var->getData<double>());
1303          else if (var->type.getValue() == CVariable::type_attr::t_string)
1304            addAttribute(name, var->getData<string>());
1305          else
1306            ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)",
1307                  << "Unsupported variable of type " << var->type.getStringValue());
1308        }
1309       catch (CNetCdfException& e)
1310       {
1311         StdString msg("On writing attributes of variable with name : ");
1312         msg.append(name); msg.append("\n");
1313         msg.append("In the context : ");
1314         CContext* context = CContext::getCurrent() ;
1315         msg.append(context->getId()); msg.append("\n");
1316         msg.append(e.what());
1317         ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg);
1318       }
1319     }
1320
1321      void CNc4DataOutput::syncFile_ (void)
1322      {
1323        try
1324        {
1325          SuperClassWriter::sync() ;
1326        }
1327        catch (CNetCdfException& e)
1328        {
1329         StdString msg("On synchronizing the write among processes");
1330         msg.append("In the context : ");
1331         CContext* context = CContext::getCurrent() ;
1332         msg.append(context->getId()); msg.append("\n");
1333         msg.append(e.what());
1334         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1335        }
1336      }
1337
1338      void CNc4DataOutput::closeFile_ (void)
1339      {
1340        try
1341        {
1342          SuperClassWriter::close() ;
1343        }
1344        catch (CNetCdfException& e)
1345        {
1346         StdString msg("On closing file");
1347         msg.append("In the context : ");
1348         CContext* context = CContext::getCurrent() ;
1349         msg.append(context->getId()); msg.append("\n");
1350         msg.append(e.what());
1351         ERROR("CNc4DataOutput::syncFile_ (void)", << msg);
1352        }
1353
1354      }
1355
1356      //---------------------------------------------------------------
1357
1358      StdString CNc4DataOutput::getTimeStamp(void) const
1359      {
1360         const int buffer_size = 100;
1361         time_t rawtime;
1362         struct tm * timeinfo = NULL;
1363         char buffer [buffer_size];
1364
1365         time ( &rawtime );
1366         timeinfo = localtime ( &rawtime );
1367         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
1368
1369         return (StdString(buffer));
1370      }
1371
1372      //---------------------------------------------------------------
1373
1374      void CNc4DataOutput::writeFieldData_ (CField*  field)
1375      {
1376        CContext* context = CContext::getCurrent();
1377        CContextServer* server = context->server;
1378        CGrid* grid = field->grid;
1379
1380        if (!grid->doGridHaveDataToWrite())
1381          if (SuperClass::type == MULTI_FILE || !isCollective) return;
1382
1383        StdString fieldid = field->getFieldOutputName();
1384
1385        StdOStringStream oss;
1386        string timeAxisId;
1387        if (field->getOperationTimeType() == func::CFunctor::instant) timeAxisId = "time_instant";
1388        else if (field->getOperationTimeType() == func::CFunctor::centered) timeAxisId = "time_centered";
1389
1390        StdString timeBoundId = getTimeCounterName() + "_bounds";
1391
1392        StdString timeAxisBoundId;
1393        if (field->getOperationTimeType() == func::CFunctor::instant) timeAxisBoundId = "time_instant_bounds";
1394        else if (field->getOperationTimeType() == func::CFunctor::centered) timeAxisBoundId = "time_centered_bounds";
1395
1396        if (!field->wasWritten())
1397        {
1398          if (appendMode && field->file->record_offset.isEmpty())
1399          {
1400            field->resetNStep(getRecordFromTime(field->last_Write_srv) + 1);
1401          }
1402
1403          field->setWritten();
1404        }
1405
1406
1407        CArray<double,1> time_data(1);
1408        CArray<double,1> time_data_bound(2);
1409        CArray<double,1> time_counter(1);
1410        CArray<double,1> time_counter_bound(2);
1411
1412        bool wtime = (field->getOperationTimeType() != func::CFunctor::once);
1413
1414        if (wtime)
1415        {
1416          Time lastWrite = field->last_Write_srv;
1417          Time lastLastWrite = field->lastlast_Write_srv;
1418
1419          if (field->getOperationTimeType() == func::CFunctor::instant)
1420            time_data(0) = lastWrite;
1421          else if (field->getOperationTimeType() == func::CFunctor::centered)
1422            time_data(0) = (lastWrite + lastLastWrite) / 2;
1423
1424          if (field->getOperationTimeType() == func::CFunctor::instant)
1425            time_data_bound(0) = time_data_bound(1) = lastWrite;
1426          else if (field->getOperationTimeType() == func::CFunctor::centered)
1427          {
1428            time_data_bound(0) = lastLastWrite;
1429            time_data_bound(1) = lastWrite;
1430          }
1431
1432          if (field->file->time_counter == CFile::time_counter_attr::instant)
1433            time_counter(0) = lastWrite;
1434          else if (field->file->time_counter == CFile::time_counter_attr::centered)
1435            time_counter(0) = (lastWrite + lastLastWrite) / 2;
1436          else if (field->file->time_counter == CFile::time_counter_attr::record)
1437            time_counter(0) = field->getNStep() - 1;
1438
1439
1440          if (field->file->time_counter == CFile::time_counter_attr::instant)
1441            time_counter_bound(0) = time_counter_bound(1) = lastWrite;
1442          else if (field->file->time_counter == CFile::time_counter_attr::centered)
1443          {
1444            time_counter_bound(0) = lastLastWrite;
1445            time_counter_bound(1) = lastWrite;
1446          }
1447          else if (field->file->time_counter == CFile::time_counter_attr::record)
1448            time_counter_bound(0) = time_counter_bound(1) = field->getNStep() - 1;
1449        }
1450
1451         bool isRoot = (server->intraCommRank == 0);
1452
1453         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
1454         {
1455           double scaleFactor = 1.0;
1456           double addOffset = 0.0;
1457           if (!field->scale_factor.isEmpty()) scaleFactor = field->scale_factor;
1458           if (!field->add_offset.isEmpty()) addOffset = field->add_offset;
1459           field->scaleFactorAddOffset(scaleFactor, addOffset);
1460         }
1461
1462         try
1463         {
1464           size_t writtenSize;
1465           if (field->getUseCompressedOutput())
1466             writtenSize = grid->getNumberWrittenIndexes();
1467           else
1468             writtenSize = grid->getWrittenDataSize();
1469
1470           CArray<double,1> fieldData(writtenSize);
1471           if (!field->default_value.isEmpty()) fieldData = field->default_value;
1472
1473           if (field->getUseCompressedOutput())
1474             field->outputCompressedField(fieldData);
1475           else
1476             field->outputField(fieldData);
1477
1478           if (!field->prec.isEmpty() && field->prec == 2) fieldData = round(fieldData);
1479
1480           switch (SuperClass::type)
1481           {
1482              case (MULTI_FILE) :
1483              {
1484                 SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep() - 1);
1485                 if (wtime)
1486                 {
1487                   SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep() - 1);
1488                   SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1);
1489                   if (field->file->time_counter != CFile::time_counter_attr::none)
1490                   {
1491                     SuperClassWriter::writeData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1);
1492                     if (field->file->time_counter != CFile::time_counter_attr::record)
1493                       SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1);
1494                   }
1495                 }
1496                 break;
1497              }
1498              case (ONE_FILE) :
1499              {
1500                const std::vector<int>& nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal();
1501                const std::vector<int>& nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer();
1502                const std::vector<int>& nZoomSizeServer  = grid->getDistributionServer()->getZoomSizeServer();
1503
1504                std::vector<StdSize> start, count;
1505
1506                if (field->getUseCompressedOutput())
1507                {
1508                  if (grid->isCompressible())
1509                  {
1510                    start.push_back(grid->getOffsetWrittenIndexes());
1511                    count.push_back(grid->getNumberWrittenIndexes());
1512                  }
1513                  else
1514                  {
1515                    CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
1516                    std::vector<StdString> domainList = grid->getDomainList();
1517                    std::vector<StdString> axisList   = grid->getAxisList();
1518                    int numElement = axisDomainOrder.numElements();
1519                    int idxDomain = domainList.size() - 1, idxAxis = axisList.size() - 1;
1520                    int idx = nZoomBeginGlobal.size() - 1;
1521
1522                    start.reserve(nZoomBeginGlobal.size());
1523                    count.reserve(nZoomBeginGlobal.size());
1524
1525
1526                    for (int i = numElement - 1; i >= 0; --i)
1527                    {
1528                      if (axisDomainOrder(i))
1529                      {
1530                        CDomain* domain = CDomain::get(domainList[idxDomain]);
1531
1532                        if (domain->isCompressible())
1533                        {
1534                          start.push_back(domain->getOffsetWrittenIndexes());
1535                          count.push_back(domain->getNumberWrittenIndexes());
1536                          idx -= 2;
1537                        }
1538                        else
1539                        {
1540                          if ((domain->type) != CDomain::type_attr::unstructured)
1541                          {
1542                            start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
1543                            count.push_back(nZoomSizeServer[idx]);
1544                          }
1545                          --idx;
1546                          start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
1547                          count.push_back(nZoomSizeServer[idx]);
1548                          --idx;
1549                        }
1550                        --idxDomain;
1551                      }
1552                      else
1553                      {
1554                        CAxis* axis = CAxis::get(axisList[idxAxis]);
1555
1556                        if (axis->isCompressible())
1557                        {
1558                          start.push_back(axis->getOffsetWrittenIndexes());
1559                          count.push_back(axis->getNumberWrittenIndexes());
1560                        }
1561                        else
1562                        {
1563                          start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
1564                          count.push_back(nZoomSizeServer[idx]);
1565                        }
1566
1567                        --idxAxis;
1568                        --idx;
1569                      }
1570                    }
1571                  }
1572                }
1573                else
1574                {
1575
1576                  CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
1577                  std::vector<StdString> domainList = grid->getDomainList();
1578                  std::vector<StdString> axisList   = grid->getAxisList();
1579                  int numElement = axisDomainOrder.numElements();
1580                  int idxDomain = domainList.size() - 1, idxAxis = axisList.size() - 1;
1581                  int idx = nZoomBeginGlobal.size() - 1;
1582
1583                  start.reserve(nZoomBeginGlobal.size());
1584                  count.reserve(nZoomBeginGlobal.size());
1585
1586                  for (int i = numElement - 1; i >= 0; --i)
1587                  {
1588                    if (axisDomainOrder(i))
1589                    {
1590                      CDomain* domain = CDomain::get(domainList[idxDomain]);
1591                      if ((domain->type) != CDomain::type_attr::unstructured)
1592                      {
1593                        start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
1594                        count.push_back(nZoomSizeServer[idx]);
1595                      }
1596                      --idx ;
1597                      start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
1598                      count.push_back(nZoomSizeServer[idx]);
1599                      --idx ;
1600                      --idxDomain;
1601                    }
1602                    else
1603                    {
1604                      start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
1605                      count.push_back(nZoomSizeServer[idx]);
1606                      --idx;
1607                     }
1608                  }
1609                }
1610
1611                SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep() - 1, &start, &count);
1612                if (wtime)
1613                {
1614                   SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep() - 1, isRoot);
1615                   SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1, isRoot);
1616                   if (field->file->time_counter != CFile::time_counter_attr::none)
1617                   {
1618                     SuperClassWriter::writeTimeAxisData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1, isRoot);
1619                     if (field->file->time_counter != CFile::time_counter_attr::record)
1620                       SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1, isRoot);
1621                   }
1622                }
1623
1624                break;
1625              }
1626            }
1627         }
1628         catch (CNetCdfException& e)
1629         {
1630           StdString msg("On writing field data: ");
1631           msg.append(fieldid); msg.append("\n");
1632           msg.append("In the context : ");
1633           msg.append(context->getId()); msg.append("\n");
1634           msg.append(e.what());
1635           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
1636         }
1637      }
1638
1639      //---------------------------------------------------------------
1640
1641      void CNc4DataOutput::writeTimeAxis_
1642                  (CField*    field,
1643                   const boost::shared_ptr<CCalendar> cal)
1644      {
1645         StdOStringStream oss;
1646
1647         if (field->getOperationTimeType() == func::CFunctor::once) return ;
1648
1649//         oss << "time_" << field->operation.getValue()
1650//             << "_" << field->getRelFile()->output_freq.getValue();
1651
1652//         StdString axisid = oss.str();
1653//         if (field->getOperationTimeType() == func::CFunctor::centered) axisid="time_centered" ;
1654//         else if (field->getOperationTimeType() == func::CFunctor::instant) axisid="time_instant" ;
1655
1656         StdString axisid("time_centered") ;
1657         StdString axisBoundId("time_centered_bounds");
1658         StdString timeid(getTimeCounterName());
1659         StdString timeBoundId("axis_nbounds");
1660
1661         if (field->getOperationTimeType() == func::CFunctor::instant)
1662         {
1663            axisid = "time_instant";
1664            axisBoundId = "time_instant_bounds";
1665         }
1666
1667         try
1668         {
1669          // Adding time_instant or time_centered
1670           std::vector<StdString> dims;
1671           dims.push_back(timeid);
1672           if (!SuperClassWriter::varExist(axisid))
1673           {
1674              SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1675
1676              CDate timeOrigin=cal->getTimeOrigin() ;
1677              StdOStringStream oss2;
1678  //            oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" "
1679  //                <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ;
1680              StdString strInitdate=oss2.str() ;
1681              StdString strTimeOrigin=timeOrigin.toString() ;
1682              this->writeTimeAxisAttributes
1683                 (axisid, cal->getType(),
1684                  StdString("seconds since ").append(strTimeOrigin),
1685                  strTimeOrigin, axisBoundId);
1686           }
1687
1688           // Adding time_instant_bounds or time_centered_bounds variables
1689           if (!SuperClassWriter::varExist(axisBoundId))
1690           {
1691              dims.clear() ;
1692              dims.push_back(timeid);
1693              dims.push_back(timeBoundId);
1694              SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1695           }
1696
1697           if (field->file->time_counter != CFile::time_counter_attr::none)
1698           {
1699             // Adding time_counter
1700             axisid = getTimeCounterName();
1701             axisBoundId = getTimeCounterName() + "_bounds";
1702             dims.clear();
1703             dims.push_back(timeid);
1704             if (!SuperClassWriter::varExist(axisid))
1705             {
1706                SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
1707                SuperClassWriter::addAttribute("axis", string("T"), &axisid);
1708
1709                if (field->file->time_counter != CFile::time_counter_attr::record)
1710                {
1711                  CDate timeOrigin = cal->getTimeOrigin();
1712                  StdString strTimeOrigin = timeOrigin.toString();
1713
1714                  this->writeTimeAxisAttributes(axisid, cal->getType(),
1715                                                StdString("seconds since ").append(strTimeOrigin),
1716                                                strTimeOrigin, axisBoundId);
1717                }
1718             }
1719
1720             // Adding time_counter_bound dimension
1721             if (field->file->time_counter != CFile::time_counter_attr::record)
1722             {
1723                if (!SuperClassWriter::varExist(axisBoundId))
1724                {
1725                  dims.clear();
1726                  dims.push_back(timeid);
1727                  dims.push_back(timeBoundId);
1728                  SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims);
1729                }
1730             }
1731           }
1732         }
1733         catch (CNetCdfException& e)
1734         {
1735           StdString msg("On writing time axis data: ");
1736           msg.append("In the context : ");
1737           CContext* context = CContext::getCurrent() ;
1738           msg.append(context->getId()); msg.append("\n");
1739           msg.append(e.what());
1740           ERROR("CNc4DataOutput::writeTimeAxis_ (CField*    field, \
1741                  const boost::shared_ptr<CCalendar> cal)", << msg);
1742         }
1743      }
1744
1745      //---------------------------------------------------------------
1746
1747      void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name,
1748                                                   const StdString & calendar,
1749                                                   const StdString & units,
1750                                                   const StdString & time_origin,
1751                                                   const StdString & time_bounds,
1752                                                   const StdString & standard_name,
1753                                                   const StdString & long_name)
1754      {
1755         try
1756         {
1757           SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1758           SuperClassWriter::addAttribute("long_name",     long_name    , &axis_name);
1759           SuperClassWriter::addAttribute("calendar",      calendar     , &axis_name);
1760           SuperClassWriter::addAttribute("units",         units        , &axis_name);
1761           SuperClassWriter::addAttribute("time_origin",   time_origin  , &axis_name);
1762           SuperClassWriter::addAttribute("bounds",        time_bounds  , &axis_name);
1763         }
1764         catch (CNetCdfException& e)
1765         {
1766           StdString msg("On writing time axis Attribute: ");
1767           msg.append("In the context : ");
1768           CContext* context = CContext::getCurrent() ;
1769           msg.append(context->getId()); msg.append("\n");
1770           msg.append(e.what());
1771           ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \
1772                                                          const StdString & calendar,\
1773                                                          const StdString & units, \
1774                                                          const StdString & time_origin, \
1775                                                          const StdString & time_bounds, \
1776                                                          const StdString & standard_name, \
1777                                                          const StdString & long_name)", << msg);
1778         }
1779      }
1780
1781      //---------------------------------------------------------------
1782
1783      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
1784                                               const StdString & axis,
1785                                               const StdString & standard_name,
1786                                               const StdString & long_name,
1787                                               const StdString & units,
1788                                               const StdString & nav_model)
1789      {
1790         try
1791         {
1792          if (!axis.empty())
1793            SuperClassWriter::addAttribute("axis"       , axis         , &axis_name);
1794
1795          SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
1796          SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
1797          SuperClassWriter::addAttribute("units"        , units        , &axis_name);
1798          SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
1799         }
1800         catch (CNetCdfException& e)
1801         {
1802           StdString msg("On writing Axis Attribute: ");
1803           msg.append("In the context : ");
1804           CContext* context = CContext::getCurrent() ;
1805           msg.append(context->getId()); msg.append("\n");
1806           msg.append(e.what());
1807           ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \
1808                                                      const StdString & axis, \
1809                                                      const StdString & standard_name, \
1810                                                      const StdString & long_name, \
1811                                                      const StdString & units, \
1812                                                      const StdString & nav_model)", << msg);
1813         }
1814      }
1815
1816      //---------------------------------------------------------------
1817
1818      void CNc4DataOutput::writeLocalAttributes
1819         (int ibegin, int ni, int jbegin, int nj, StdString domid)
1820      {
1821        try
1822        {
1823         SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin);
1824         SuperClassWriter::addAttribute(StdString("ni"    ).append(domid), ni);
1825         SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin);
1826         SuperClassWriter::addAttribute(StdString("nj"    ).append(domid), nj);
1827        }
1828        catch (CNetCdfException& e)
1829        {
1830           StdString msg("On writing Local Attributes: ");
1831           msg.append("In the context : ");
1832           CContext* context = CContext::getCurrent() ;
1833           msg.append(context->getId()); msg.append("\n");
1834           msg.append(e.what());
1835           ERROR("CNc4DataOutput::writeLocalAttributes \
1836                  (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg);
1837        }
1838
1839      }
1840
1841      void CNc4DataOutput::writeLocalAttributes_IOIPSL(const StdString& dimXid, const StdString& dimYid,
1842                                                       int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)
1843      {
1844         CArray<int,1> array(2) ;
1845
1846         try
1847         {
1848           SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ;
1849           SuperClassWriter::addAttribute("DOMAIN_number", rank) ;
1850           array = SuperClassWriter::getDimension(dimXid) + 1, SuperClassWriter::getDimension(dimYid) + 1;
1851           SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ;
1852           array=ni_glo,nj_glo ;
1853           SuperClassWriter::addAttribute("DOMAIN_size_global", array) ;
1854           array=ni,nj ;
1855           SuperClassWriter::addAttribute("DOMAIN_size_local", array) ;
1856           array=ibegin,jbegin ;
1857           SuperClassWriter::addAttribute("DOMAIN_position_first", array) ;
1858           array=ibegin+ni-1,jbegin+nj-1 ;
1859           SuperClassWriter::addAttribute("DOMAIN_position_last",array) ;
1860           array=0,0 ;
1861           SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ;
1862           SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array);
1863           SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ;
1864  /*
1865           SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ;
1866           SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ;
1867           SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ;
1868           SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ;
1869  */
1870         }
1871         catch (CNetCdfException& e)
1872         {
1873           StdString msg("On writing Local Attributes IOIPSL \n");
1874           msg.append("In the context : ");
1875           CContext* context = CContext::getCurrent() ;
1876           msg.append(context->getId()); msg.append("\n");
1877           msg.append(e.what());
1878           ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \
1879                  (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg);
1880         }
1881      }
1882      //---------------------------------------------------------------
1883
1884      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
1885                                                const StdString & description,
1886                                                const StdString & conventions,
1887                                                const StdString & production,
1888                                                const StdString & timeStamp)
1889      {
1890         try
1891         {
1892           SuperClassWriter::addAttribute("name"       , name);
1893           SuperClassWriter::addAttribute("description", description);
1894           SuperClassWriter::addAttribute("title"      , description);
1895           SuperClassWriter::addAttribute("Conventions", conventions);
1896           SuperClassWriter::addAttribute("production" , production);
1897           SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
1898         }
1899         catch (CNetCdfException& e)
1900         {
1901           StdString msg("On writing File Attributes \n ");
1902           msg.append("In the context : ");
1903           CContext* context = CContext::getCurrent() ;
1904           msg.append(context->getId()); msg.append("\n");
1905           msg.append(e.what());
1906           ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \
1907                                                const StdString & description, \
1908                                                const StdString & conventions, \
1909                                                const StdString & production, \
1910                                                const StdString & timeStamp)", << msg);
1911         }
1912      }
1913
1914      //---------------------------------------------------------------
1915
1916      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
1917                                               int data_dim,
1918                                               int data_ni,
1919                                               int data_nj,
1920                                               int data_ibegin,
1921                                               int data_jbegin)
1922      {
1923         try
1924         {
1925           SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
1926           SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
1927           SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
1928           SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
1929           SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
1930         }
1931         catch (CNetCdfException& e)
1932         {
1933           StdString msg("On writing Mask Attributes \n ");
1934           msg.append("In the context : ");
1935           CContext* context = CContext::getCurrent() ;
1936           msg.append(context->getId()); msg.append("\n");
1937           msg.append(e.what());
1938           ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \
1939                                               int data_dim, \
1940                                               int data_ni, \
1941                                               int data_nj, \
1942                                               int data_ibegin, \
1943                                               int data_jbegin)", << msg);
1944         }
1945      }
1946
1947      ///--------------------------------------------------------------
1948
1949      StdSize CNc4DataOutput::getRecordFromTime(Time time)
1950      {
1951        std::map<Time, StdSize>::const_iterator it = timeToRecordCache.find(time);
1952        if (it == timeToRecordCache.end())
1953        {
1954          StdString timeAxisBoundsId(getTimeCounterName() + "_bounds");
1955          if (!SuperClassWriter::varExist(timeAxisBoundsId))
1956            timeAxisBoundsId = "time_instant_bounds";
1957
1958          CArray<double,2> timeAxisBounds;
1959          SuperClassWriter::getTimeAxisBounds(timeAxisBounds, timeAxisBoundsId, isCollective);
1960
1961          StdSize record = 0;
1962          double dtime(time);
1963          for (int n = timeAxisBounds.extent(1) - 1; n >= 0; n--)
1964          {
1965            if (timeAxisBounds(1, n) < dtime)
1966            {
1967              record = n + 1;
1968              break;
1969            }
1970          }
1971          it = timeToRecordCache.insert(std::make_pair(time, record)).first;
1972        }
1973        return it->second;
1974      }
1975
1976      ///--------------------------------------------------------------
1977
1978      bool CNc4DataOutput::isWrittenDomain(const std::string& domainName) const
1979      {
1980        return (this->writtenDomains.find(domainName) != this->writtenDomains.end());
1981      }
1982
1983      bool CNc4DataOutput::isWrittenCompressedDomain(const std::string& domainName) const
1984      {
1985        return (this->writtenCompressedDomains.find(domainName) != this->writtenCompressedDomains.end());
1986      }
1987
1988      bool CNc4DataOutput::isWrittenAxis(const std::string& axisName) const
1989      {
1990        return (this->writtenAxis.find(axisName) != this->writtenAxis.end());
1991      }
1992
1993      bool CNc4DataOutput::isWrittenCompressedAxis(const std::string& axisName) const
1994      {
1995        return (this->writtenCompressedAxis.find(axisName) != this->writtenCompressedAxis.end());
1996      }
1997
1998      void CNc4DataOutput::setWrittenDomain(const std::string& domainName)
1999      {
2000        this->writtenDomains.insert(domainName);
2001      }
2002
2003      void CNc4DataOutput::setWrittenCompressedDomain(const std::string& domainName)
2004      {
2005        this->writtenCompressedDomains.insert(domainName);
2006      }
2007
2008      void CNc4DataOutput::setWrittenAxis(const std::string& axisName)
2009      {
2010        this->writtenAxis.insert(axisName);
2011      }
2012
2013      void CNc4DataOutput::setWrittenCompressedAxis(const std::string& axisName)
2014      {
2015        this->writtenCompressedAxis.insert(axisName);
2016      }
2017} // namespace xios
Note: See TracBrowser for help on using the repository browser.