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

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

Append mode

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