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

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

Add support for indexed output.

If the new field attribute "indexed_output" is set to true and a mask is defined (either at grid, domain or axis level), the indexed data will be outputed instead of the full data with missing values.

See http://cfconventions.org/Data/cf-conventions/cf-conventions-1.5/build/cf-conventions.html#compression-by-gathering for more information.

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