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

Last change on this file since 467 was 465, checked in by ymipsl, 10 years ago

bug fix : field attribute prec was used without testing if it was defined.

YM

File size: 44.8 KB
RevLine 
[266]1
[219]2#include "nc4_data_output.hpp"
3
4#include <boost/lexical_cast.hpp>
[352]5#include "attribute_template.hpp"
6#include "group_template.hpp"
[219]7
8#include "file.hpp"
9#include "calendar.hpp"
[278]10#include "context.hpp"
[300]11#include "context_server.hpp"
[219]12
[335]13namespace xios
[219]14{
15      /// ////////////////////// Définitions ////////////////////// ///
16      CNc4DataOutput::CNc4DataOutput
17         (const StdString & filename, bool exist)
18            : SuperClass()
19            , SuperClassWriter(filename, exist)
20            , filename(filename)
21      {
22         StdString timeid = StdString("time_counter");
23         SuperClass::type = MULTI_FILE;
[391]24//         if (!exist)
25//            SuperClassWriter::addDimension(timeid);
[219]26      }
27
28      CNc4DataOutput::CNc4DataOutput
[379]29         (const StdString & filename, bool exist, MPI_Comm comm_file,bool multifile, bool isCollective)
[219]30            : SuperClass()
[379]31            , SuperClassWriter(filename, exist, &comm_file,multifile)
32            , comm_file(comm_file)
[219]33            , filename(filename)
[335]34            , isCollective(isCollective)
[219]35      {
36         StdString timeid = StdString("time_counter");
37
[286]38         SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE;
39         
[391]40 //        if (!exist)
41//            SuperClassWriter::addDimension(timeid);
[219]42      }
43
[286]44
[219]45      CNc4DataOutput::~CNc4DataOutput(void)
46      { /* Ne rien faire de plus */ }
47
48      ///--------------------------------------------------------------
49
50      const StdString & CNc4DataOutput::getFileName(void) const
51      {
52         return (this->filename);
53      }
54
55      //---------------------------------------------------------------
56
[347]57      void CNc4DataOutput::writeDomain_(CDomain* domain)
[219]58      {
[449]59         if (domain->type == CDomain::type_attr::unstructured)
60         {
61           writeUnstructuredDomain(domain) ;
62           return ;
63         }
64         
[347]65         CContext* context = CContext::getCurrent() ;
[300]66         CContextServer* server=context->server ;
67         
[219]68         if (domain->IsWritten(this->filename)) return;
69         domain->checkAttributes();
70         
[300]71         if (domain->isEmpty()) 
72           if (SuperClass::type==MULTI_FILE) return ;
[219]73
74         std::vector<StdString> dim0, dim1;
75         StdString domid     = (!domain->name.isEmpty())
76                             ? domain->name.getValue() : domain->getId();
[318]77         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
[449]78
79
80         StdString dimXid, dimYid ;
[391]81         
[449]82         switch (domain->type)
[433]83         {
[449]84           case CDomain::type_attr::curvilinear :
85             dimXid     = StdString("x").append(appendDomid);
86             dimYid     = StdString("y").append(appendDomid);
87             break ;
88           case CDomain::type_attr::regular :
89             dimXid     = StdString("lon").append(appendDomid);
90             dimYid     = StdString("lat").append(appendDomid);
91             break;
92           case CDomain::type_attr::unstructured :
93             dimXid     = StdString("cell").append(appendDomid);
94             break;
[433]95         }           
96         
[449]97         string lonid,latid,bounds_lonid,bounds_latid ;
[391]98/*
[300]99         StdString lonid_loc = (server->intraCommSize > 1)
[318]100                             ? StdString("lon").append(appendDomid).append("_local")
[278]101                             : lonid;
[300]102         StdString latid_loc = (server->intraCommSize > 1)
[318]103                             ? StdString("lat").append(appendDomid).append("_local")
[278]104                             : latid;
[391]105*/
[219]106
107         switch (SuperClass::type)
108         {
109            case (MULTI_FILE) :
110            {
[300]111//               if (domain->isEmpty()) return;
[286]112               
[300]113               if (server->intraCommSize > 1)
[286]114               {
[391]115//                 SuperClassWriter::addDimension(lonid, domain->zoom_ni.getValue());
116//                 SuperClassWriter::addDimension(latid, domain->zoom_nj.getValue());
[286]117               }
118
[449]119               switch (domain->type)
[286]120               {
[449]121                 case CDomain::type_attr::curvilinear :
122                   dim0.push_back(dimYid); dim0.push_back(dimXid);
123                   lonid = StdString("nav_lon").append(appendDomid);
124                   latid = StdString("nav_lat").append(appendDomid);
125                   break ;
126                 case CDomain::type_attr::regular :
127                   lonid = StdString("lon").append(appendDomid);
128                   latid = StdString("lat").append(appendDomid);
129                   dim0.push_back(dimYid);
130                   dim1.push_back(dimXid);
131                   break;
132                 case CDomain::type_attr::unstructured :
133                   lonid = StdString("lon").append(appendDomid);
134                   latid = StdString("lat").append(appendDomid);
135                   bounds_lonid=string("bounds_lon").append(appendDomid);
136                   bounds_latid=string("bounds_lat").append(appendDomid);
137                   dim0.push_back(dimXid);
138                   break;
[286]139               }
[449]140               
141               if (domain->type == CDomain::type_attr::unstructured)
142               {
143                 SuperClassWriter::addDimension(dimXid, domain->nj_glo);
144               }
[286]145               else
146               {
[449]147                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
148                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv);
[286]149               }
[449]150               
[300]151               if (server->intraCommSize > 1)
[278]152               {
[449]153                  if (domain->type != CDomain::type_attr::unstructured)
154                  {
155                    this->writeLocalAttributes(domain->zoom_ibegin_srv,
156                                               domain->zoom_ni_srv,
157                                               domain->zoom_jbegin_srv,
158                                               domain->zoom_nj_srv,
159                                               appendDomid);
[391]160                 
[449]161                    if (singleDomain) this->writeLocalAttributes_IOIPSL(domain->zoom_ibegin_srv,
162                                               domain->zoom_ni_srv,
163                                               domain->zoom_jbegin_srv,
164                                               domain->zoom_nj_srv,
165                                               domain->ni_glo,domain->nj_glo,
166                                               server->intraCommRank,server->intraCommSize);
167                 }
[278]168               }
169               
[449]170               switch (domain->type)
[219]171               {
[449]172                 case CDomain::type_attr::curvilinear :
173                   SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
174                   SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
175                   break ;
176                  case CDomain::type_attr::regular :
177                    SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
178                    SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
179                    break ;
180                  case CDomain::type_attr::unstructured :
181                    SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
182                    SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
[219]183               }
[449]184               
185               this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
186               this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
[219]187
188               dim0.clear();
[449]189               if (domain->type != CDomain::type_attr::unstructured) dim0.push_back(dimYid);
[391]190               dim0.push_back(dimXid);
[219]191
192
[300]193// supress mask               if (server->intraCommSize > 1)
194// supress mask               {
195// supress mask                  SuperClassWriter::addVariable(maskid, NC_INT, dim0);
196// supress mask
197// supress mask                  this->writeMaskAttributes(maskid,
198// supress mask                     domain->data_dim.getValue()/*,
199// supress mask                     domain->data_ni.getValue(),
200// supress mask                     domain->data_nj.getValue(),
201// supress mask                     domain->data_ibegin.getValue(),
202// supress mask                     domain->data_jbegin.getValue()*/);
203// supress mask               }
[219]204                 
[266]205               //SuperClassWriter::setDefaultValue(maskid, &dvm);
[219]206
207               SuperClassWriter::definition_end();
[449]208
209               switch (domain->type)
[384]210               {
[449]211                 case CDomain::type_attr::curvilinear :
212                   SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
213                   SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
214                   break; 
215                 case CDomain::type_attr::regular :
216                   CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
217                   SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
218                   CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
219                   SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
220                   break;
[384]221               }
[219]222               SuperClassWriter::definition_start();
223
224               break;
225            }
[286]226            case (ONE_FILE) :
227            {
[391]228               SuperClassWriter::addDimension(dimXid, domain->zoom_ni.getValue());
229               SuperClassWriter::addDimension(dimYid, domain->zoom_nj.getValue());
[286]230
231               
[449]232               switch (domain->type)
[286]233               {
[449]234                 case CDomain::type_attr::curvilinear :
235                   dim0.push_back(dimYid); dim0.push_back(dimXid);
236                   lonid = StdString("nav_lon").append(appendDomid);
237                   latid = StdString("nav_lat").append(appendDomid);
238                   SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
239                   SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
240                   break;
241
242                 case CDomain::type_attr::regular :
243                   dim0.push_back(dimYid);
244                   dim1.push_back(dimXid);
245                   lonid = StdString("lon").append(appendDomid);
246                   latid = StdString("lat").append(appendDomid);
247                   SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
248                   SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);
249                   break;
[286]250               }
251               this->writeAxisAttributes
[434]252                  (lonid, "X", "longitude", "Longitude", "degrees_east", domid);
[286]253               this->writeAxisAttributes
[434]254                  (latid, "Y", "latitude", "Latitude", "degrees_north", domid);
[286]255
256
257               SuperClassWriter::definition_end();
[449]258               switch (domain->type)
[286]259               {
[449]260                 case CDomain::type_attr::curvilinear :
[384]261                 {
[449]262                   std::vector<StdSize> start(2) ; 
263                   std::vector<StdSize> count(2) ;
264                   if (domain->isEmpty())
265                   {
266                     start[0]=0 ; start [1]=0 ; 
267                     count[0]=0 ; count[1]=0 ; 
268                   }
269                   else
270                   {
271                     start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; 
272                     count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ; 
273                   }
274                 
275                   SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
276                   SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
277                   break;
[384]278                 }
[449]279                 case CDomain::type_attr::regular :
[384]280                 {
[449]281                   std::vector<StdSize> start(1) ; 
282                   std::vector<StdSize> count(1) ;
283                   if (domain->isEmpty())
284                   {
285                     start[0]=0 ; 
286                     count[0]=0 ; 
287                     SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
288                     SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);                 }
289                   else
290                   {
291                     start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; 
292                     count[0]=domain->zoom_nj_srv ; 
293                     CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
294                     SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
295
296                     start[0]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; 
297                     count[0]=domain->zoom_ni_srv ; 
298                     CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
299                     SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
300                   }
301                   break;
[384]302                 }
[286]303               }
[449]304               SuperClassWriter::definition_start();
305               break;
306            }           
307            default :
308               ERROR("CNc4DataOutput::writeDomain(domain)",
309                     << "[ type = " << SuperClass::type << "]"
310                     << " not implemented yet !");
311         }
312         domain->addRelFile(this->filename);
313      }
314
315      void CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)
316      {
317         CContext* context = CContext::getCurrent() ;
318         CContextServer* server=context->server ;
319         
320         if (domain->IsWritten(this->filename)) return;
321         domain->checkAttributes();
322         
323         if (domain->isEmpty()) 
324           if (SuperClass::type==MULTI_FILE) return ;
325
326         std::vector<StdString> dim0, dim1;
327         StdString domid     = (!domain->name.isEmpty())
328                             ? domain->name.getValue() : domain->getId();
329         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
330
331
332         StdString dimXid = StdString("cell").append(appendDomid);
333         StdString dimVertId = StdString("nvertex").append(appendDomid);
334       
335         string lonid,latid,bounds_lonid,bounds_latid ;
336
337         switch (SuperClass::type)
338         {
339            case (MULTI_FILE) :
340            {
341               lonid = StdString("lon").append(appendDomid);
342               latid = StdString("lat").append(appendDomid);
343               dim0.push_back(dimXid);
344
345               SuperClassWriter::addDimension(dimXid, domain->zoom_nj_srv);
346               SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
347               SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
348               
349               bounds_lonid = StdString("bounds_lon").append(appendDomid);
350               bounds_latid = StdString("bounds_lat").append(appendDomid);
351             
352               
353               this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
354               if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
355               this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);
356               if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
357               if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
358               dim0.clear();
359               if (domain->hasBounds)
360               { 
361                 dim0.push_back(dimXid);
362                 dim0.push_back(dimVertId);
363                 SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
364                 SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
365               }
366               
367               dim0.clear();
368               dim0.push_back(dimXid);
369
370               SuperClassWriter::definition_end();
371
372               SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
373               SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
374               
375               if (domain->hasBounds)
376               { 
377                 SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
378                 SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
379               }
380               SuperClassWriter::definition_start();
381               break ;
382            }
383
384            case (ONE_FILE) :
385            {
386               lonid = StdString("lon").append(appendDomid);
387               latid = StdString("lat").append(appendDomid);
388               bounds_lonid = StdString("bounds_lon").append(appendDomid);
389               bounds_latid = StdString("bounds_lat").append(appendDomid);
390               dim0.push_back(dimXid);
391               SuperClassWriter::addDimension(dimXid, domain->nj_glo);
392               SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);
393               SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);
394               this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid);
395               if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid);
396               this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid);                                           
397               if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
398               if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
399               dim0.clear();
400               
401               if (domain->hasBounds) 
402               {
403                 dim0.push_back(dimXid);
404                 dim0.push_back(dimVertId);
405                 SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);
406                 SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);
407               }
408               
409               SuperClassWriter::definition_end();
410               
411               std::vector<StdSize> start(1), startBounds(2) ; 
412               std::vector<StdSize> count(1), countBounds(2) ;
413               if (domain->isEmpty())
414               {
415                 start[0]=0 ; 
416                 count[0]=0 ; 
[450]417                 startBounds[1]=0 ; 
418                 countBounds[1]=domain->nvertex ;
[449]419                 startBounds[0]=0 ; 
[450]420                 countBounds[0]=0 ; 
[449]421               }
[286]422               else
423               {
[449]424                 start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ; 
425                 count[0]=domain->zoom_nj_srv ; 
[450]426                 startBounds[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ; 
427                 startBounds[1]=0 ; 
428                 countBounds[0]=domain->zoom_nj_srv ;   
429                 countBounds[1]=domain->nvertex ;
[286]430               }
[449]431               SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
432               SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
433               if (domain->hasBounds) 
434               {
[450]435                 SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
[449]436                 SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds);
437               }
438 
439               
[286]440               SuperClassWriter::definition_start();
[449]441
[286]442               break;
443            }           
[219]444            default :
445               ERROR("CNc4DataOutput::writeDomain(domain)",
446                     << "[ type = " << SuperClass::type << "]"
447                     << " not implemented yet !");
448         }
449         domain->addRelFile(this->filename);
450      }
451      //--------------------------------------------------------------
452
[347]453      void CNc4DataOutput::writeAxis_(CAxis* axis)
[219]454      {
455         if (axis->IsWritten(this->filename)) return;
456         axis->checkAttributes();
[351]457         StdSize zoom_size=axis->zoom_size.getValue() ;
458         StdSize zoom_begin=axis->zoom_begin.getValue()-1 ;
459         
[219]460         std::vector<StdString> dims;
461         StdString axisid = (!axis->name.isEmpty())
462                           ? axis->name.getValue() : axis->getId();
[351]463         SuperClassWriter::addDimension(axisid, zoom_size);
[219]464         dims.push_back(axisid);
[286]465         
[219]466         switch (SuperClass::type)
467         {
[286]468            case (MULTI_FILE ) :
469            {}
[278]470            case (ONE_FILE) :
[219]471            {
472               SuperClassWriter::addVariable(axisid, NC_FLOAT, dims);
473
474               SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid);
475
476               if (!axis->standard_name.isEmpty())
477                  SuperClassWriter::addAttribute
478                     ("standard_name",  axis->standard_name.getValue(), &axisid);
479
480               if (!axis->long_name.isEmpty())
481                  SuperClassWriter::addAttribute
482                     ("long_name", axis->long_name.getValue(), &axisid);
483
484               if (!axis->unit.isEmpty())
485                  SuperClassWriter::addAttribute
486                     ("units", axis->unit.getValue(), &axisid);
487
[399]488              if (!axis->positive.isEmpty())
489                if (axis->positive==CAxis::positive_attr::up) SuperClassWriter::addAttribute("positive", string("up"), &axisid);
490                else   SuperClassWriter::addAttribute("positive", string("down"), &axisid);
491
[219]492               SuperClassWriter::definition_end();
[351]493               
[369]494               CArray<double,1> axis_value(zoom_size) ;
495               for(StdSize i = 0 ; i < zoom_size ; i++) axis_value(i)=axis->value(i+zoom_begin) ;
496               SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
[351]497               
[219]498               SuperClassWriter::definition_start();
499
500               break;
501            }
502            default :
503               ERROR("CNc4DataOutput::writeDomain(domain)",
504                     << "[ type = " << SuperClass::type << "]"
505                     << " not implemented yet !");
506         }
507         axis->addRelFile(this->filename);
[391]508     }
509     
510     void CNc4DataOutput::writeTimeDimension_(void)
511     {
[449]512       SuperClassWriter::addDimension("time_counter");
[391]513     }
[219]514      //--------------------------------------------------------------
515
[347]516      void CNc4DataOutput::writeField_(CField* field)
[219]517      {
[347]518         CContext* context = CContext::getCurrent() ;
[300]519         CContextServer* server=context->server ;
520
[219]521         std::vector<StdString> dims, coodinates;
[347]522         CGrid* grid = field->grid;
523         CDomain* domain = grid->domain;
[286]524           
525         if (domain->isEmpty()) 
526           if (SuperClass::type==MULTI_FILE) return ;
[219]527
528         StdString timeid    = StdString("time_counter");
529         StdString domid     = (!domain->name.isEmpty())
530                             ? domain->name.getValue() : domain->getId();
[318]531         StdString appendDomid  = (singleDomain) ? "" : "_"+domid ;
[434]532 
[449]533//         bool isCurvilinear = domain->isCurvilinear ;
534//         bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ;
[434]535         
536         StdString dimXid,dimYid ;
537       
[449]538         switch (domain->type)
[434]539         {
[449]540           case CDomain::type_attr::curvilinear :
541             dimXid     = StdString("x").append(appendDomid);
542             dimYid     = StdString("y").append(appendDomid);
543             break ;
544           case CDomain::type_attr::regular :
545             dimXid     = StdString("lon").append(appendDomid);
546             dimYid     = StdString("lat").append(appendDomid);
547             break ;
548           case CDomain::type_attr::unstructured :
549             dimXid     = StdString("cell").append(appendDomid);
550             break ;
551        }
[434]552         
553/*
[300]554         StdString lonid_loc = (server->intraCommSize > 1)
[318]555                             ? StdString("lon").append(appendDomid).append("_local")
[278]556                             : lonid;
[300]557         StdString latid_loc = (server->intraCommSize > 1)
[318]558                             ? StdString("lat").append(appendDomid).append("_local")
[278]559                             : latid;
[391]560*/
[219]561         StdString fieldid   = (!field->name.isEmpty())
562                             ? field->name.getValue() : field->getBaseFieldReference()->getId();
563
[300]564//         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
565//         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
[434]566//          bool isCurvilinear = domain->isCurvilinear ;
[300]567         
[464]568         nc_type type ;
569         if (field->prec.isEmpty()) type =  NC_FLOAT ;
570         else
571         {
572           if (field->prec==2) type = NC_SHORT ;
573           else if (field->prec==4)  type =  NC_FLOAT ;
574           else if (field->prec==8)   type =  NC_DOUBLE ; 
575         }
576                     
[449]577         bool wtime   = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once);
[219]578                         
579         if (wtime)
580         {
[449]581           
582            //StdOStringStream oss;
583           // oss << "time_" << field->operation.getValue()
584           //     << "_" << field->getRelFile()->output_freq.getValue();
585          //oss
586            if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));
587            else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));
[219]588            dims.push_back(timeid);
589         }
590
591         if (!grid->axis_ref.isEmpty())
592         {
[347]593            CAxis* axis = grid->axis ;
[300]594            StdString axisid = (!axis->name.isEmpty()) ? axis->name.getValue() : axis->getId();
[219]595            dims.push_back(axisid);
596            coodinates.push_back(axisid);
597         }
598
[449]599         switch (domain->type)
[219]600         {
[449]601           case CDomain::type_attr::curvilinear :
602             coodinates.push_back(StdString("nav_lon").append(appendDomid));
603             coodinates.push_back(StdString("nav_lat").append(appendDomid));
604             break;
605           case CDomain::type_attr::regular :             
606           case CDomain::type_attr::unstructured :   
607            coodinates.push_back(StdString("lon").append(appendDomid));
[391]608            coodinates.push_back(StdString("lat").append(appendDomid));
[449]609             break;
[219]610         }
611
[454]612         if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid);
[449]613         dims.push_back(dimXid);
[286]614         
615         SuperClassWriter::addVariable(fieldid, type, dims);
616         
617         if (!field->standard_name.isEmpty())
618            SuperClassWriter::addAttribute
619               ("standard_name",  field->standard_name.getValue(), &fieldid);
[219]620
[286]621         if (!field->long_name.isEmpty())
622            SuperClassWriter::addAttribute
623               ("long_name", field->long_name.getValue(), &fieldid);
[219]624
[286]625         if (!field->unit.isEmpty())
626            SuperClassWriter::addAttribute
627               ("units", field->unit.getValue(), &fieldid);
[463]628
629          if (!field->valid_min.isEmpty())
630            SuperClassWriter::addAttribute
631               ("valid_min", field->valid_min.getValue(), &fieldid);
632
633         if (!field->valid_max.isEmpty())
634            SuperClassWriter::addAttribute
635               ("valid_max", field->valid_max.getValue(), &fieldid);
[464]636
637          if (!field->scale_factor.isEmpty())
638            SuperClassWriter::addAttribute
639               ("scale_factor", field->scale_factor.getValue(), &fieldid);
640
641           if (!field->add_offset.isEmpty())
642            SuperClassWriter::addAttribute
643               ("add_offset", field->add_offset.getValue(), &fieldid);
[463]644                                           
[286]645         SuperClassWriter::addAttribute
646               ("online_operation", field->operation.getValue(), &fieldid);
[219]647               
[286]648         if (wtime)
649         {
[437]650            CDuration duration ;
651
[448]652            duration=CDuration::FromString(field->freq_op) ;
[437]653            duration.solveTimeStep(*(context->calendar));
654            SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid);
655
[448]656            duration=CDuration::FromString(field->getRelFile()->output_freq) ;
[437]657            duration.solveTimeStep(*(context->calendar));
658            SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid);
[286]659         }
660         
661         if (!field->default_value.isEmpty())
662         {
663            double default_value = field->default_value.getValue();
664            float fdefault_value = (float)default_value;
665            if (type == NC_DOUBLE)
666               SuperClassWriter::setDefaultValue(fieldid, &default_value);
667            else
668               SuperClassWriter::setDefaultValue(fieldid, &fdefault_value);
669         }
670         else
671         {
672            double * default_value = NULL;
673            SuperClassWriter::setDefaultValue(fieldid, default_value);
674         }             
[219]675
[286]676         {  // Ecriture des coordonnées
677         
678            StdString coordstr; //boost::algorithm::join(coodinates, " ")
679            std::vector<StdString>::iterator
680               itc = coodinates.begin(), endc = coodinates.end();
681           
682            for (; itc!= endc; itc++)
683            {
684               StdString & coord = *itc;
685               if (itc+1 != endc)
686                     coordstr.append(coord).append(" ");
687               else  coordstr.append(coord);
688            }
[219]689
[286]690            SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid);
[219]691
692         }
[286]693
[219]694      }
695
696      //--------------------------------------------------------------
697
[347]698      void CNc4DataOutput::writeFile_ (CFile* file)
[219]699      {
700         StdString filename = (!file->name.isEmpty())
701                            ? file->name.getValue() : file->getId();
702         StdString description = (!file->description.isEmpty())
703                               ? file->description.getValue()
[335]704                               : StdString("Created by xios");
[219]705         this->writeFileAttributes(filename, description,
706                                   StdString ("CF-1.1"),
707                                   StdString("An IPSL model"),
708                                   this->getTimeStamp());
[318]709         if (file->nbDomain==1) singleDomain=true ;
710         else singleDomain=false ;
[219]711      }
[321]712 
713      void CNc4DataOutput::syncFile_ (void)
714      {
715         SuperClassWriter::sync() ;
716      }
[219]717
[286]718      void CNc4DataOutput::closeFile_ (void)
719      {
720         SuperClassWriter::close() ;
721      }
722
[219]723      //---------------------------------------------------------------
724
725      StdString CNc4DataOutput::getTimeStamp(void) const
726      {
727         const int buffer_size = 100;
728         time_t rawtime;
729         struct tm * timeinfo = NULL;
730         char buffer [buffer_size];
731
732         time ( &rawtime );
733         timeinfo = localtime ( &rawtime );
734         strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);
735
736         return (StdString(buffer));
737      }
738     
739      //---------------------------------------------------------------
740     
[347]741      void CNc4DataOutput::writeFieldData_ (CField*  field)
[219]742      {
[347]743         CContext* context = CContext::getCurrent() ;
[321]744//          if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ;
[413]745         CContextServer* server=context->server ;
[300]746
[347]747         CGrid* grid = field->grid ;
748         CDomain* domain = grid->domain ;
[286]749         
[335]750         if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return;
[286]751
752
[300]753         StdString fieldid   = (!field->name.isEmpty()) 
[219]754                             ? field->name.getValue() 
755                             : field->getBaseFieldReference()->getId();
[278]756                             
757         StdOStringStream oss;
[449]758         string timeAxisId ;
759         if (field->foperation->timeType() == func::CFunctor::instant)  timeAxisId="time_instant" ;
760         else if (field->foperation->timeType() == func::CFunctor::centered)  timeAxisId="time_centered" ;
761
[278]762             
[369]763         CArray<double,1> time_data(1) ;
[449]764         CArray<double,1> time_counter(1) ;
765               
766        bool wtime   = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once));
[444]767                                 
768        if (wtime)
769        {
[449]770          time_counter(0)= (Time(*field->last_Write_srv)+Time(*field->lastlast_Write_srv))/2 -Time(context->calendar->getTimeOrigin());
771          if (field->foperation->timeType() == func::CFunctor::instant) 
772            time_data(0) = Time(*field->last_Write_srv)-Time(context->calendar->getTimeOrigin());
773          else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0);
774         
[444]775         }
[413]776         
777         
778         bool isRoot ;
779         if (server->intraCommRank==0) isRoot=true ;
780         else isRoot=false ;
[464]781         
782         if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
783         {
784           double scaleFactor=1. ;
785           double addOffset=0. ;
786           if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ;
787           if (!field->add_offset.isEmpty()) addOffset=field->add_offset ;
788           field->scaleFactorAddOffset(scaleFactor,addOffset) ;
789         }
790           
[219]791         if (grid->hasAxis()) // 3D
792         {
[347]793            CAxis* axis = grid->axis ;
[369]794            CArray<double,3> field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ;
[384]795            if (!field->default_value.isEmpty()) field_data3D = field->default_value ;
[464]796
[300]797            field->outputField(field_data3D);
[464]798
[465]799            if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ;
[464]800
[286]801            switch (SuperClass::type)
802           {
803              case (MULTI_FILE) :
804              {
[335]805                 SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1);
[449]806                 if (wtime) 
807                 {
808                   SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
809                   SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
810                 }
[286]811                 break ;
812              }
813              case (ONE_FILE) :
814              {
815                 std::vector<StdSize> start(3) ; 
816                 std::vector<StdSize> count(3) ;
817                 if (domain->isEmpty())
818                 {
819                   start[0]=0 ; start[1]=0 ; start[2]=0 ;
820                   count[0]=0 ; count[1]=0 ; start[2]=0 ;
821                 }
822                 else
823                 {
824//                 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 ;
[300]825                   start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ;
[351]826                   count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue();
[286]827                 }
[335]828                 SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count );
[449]829                 if (wtime) 
830                 {
831                   SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot );
832                   SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot );
833                 }
[286]834                 break;
835              }
836            }
[219]837           
838         }
839         else // 2D
840         {
[369]841            CArray<double,2> field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ;
[384]842            if (!field->default_value.isEmpty()) field_data2D = field->default_value ;
[300]843            field->outputField(field_data2D);
[465]844            if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ;
[286]845            switch (SuperClass::type)
846            {
847              case (MULTI_FILE) :
848              {
[335]849                SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1);
[449]850                if (wtime) 
851                {
852                  SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1);
853                  SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1);
854                }
[286]855                break;
856              }
857              case (ONE_FILE) :
858              {
859                 std::vector<StdSize> start(2) ; 
860                 std::vector<StdSize> count(2) ;
861                 if (domain->isEmpty())
862                 {
863                   start[0]=0 ; start[1]=0 ;
864                   count[0]=0 ; count[1]=0 ;
865                 }
866                 else
867                 {
[300]868                   start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; 
869                   count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
[286]870                 }
[300]871
[335]872                 SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count);
[449]873                 if (wtime) 
874                 {
875                   SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot);
876                   SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot);
877                 }                   
[413]878                 break; 
[286]879             
880              }
881            }
[219]882         }
883      }
884
885      //---------------------------------------------------------------
886
887      void CNc4DataOutput::writeTimeAxis_
[347]888                  (CField*    field,
[343]889                   const boost::shared_ptr<CCalendar> cal)
[219]890      {
891         StdOStringStream oss;
[444]892         
[449]893//         if (field->operation.getValue().compare("once") == 0) return ;
894         if (field->foperation->timeType() == func::CFunctor::once) return ;
895                               
896//         oss << "time_" << field->operation.getValue()
897//             << "_" << field->getRelFile()->output_freq.getValue();
898         
899         string  axisid ;   
900         if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ;
901         else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ;
902         
[219]903         std::vector<StdString> dims;
[449]904//         StdString axisid = oss.str();
[219]905         StdString timeid = StdString("time_counter");
906
907         dims.push_back(timeid);
908         if (!SuperClassWriter::varExist(axisid))
909         {
910            SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
[449]911           
[343]912            CDate timeOrigin=cal->getTimeOrigin() ;
[316]913//            StdOStringStream oss2;
914//            oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" "
915//                <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ;
916//            StdString strInitdate=oss2.str() ;
[334]917            StdString strTimeOrigin=timeOrigin.toString() ;
[219]918            this->writeTimeAxisAttributes
[292]919               (axisid, cal->getType(),
[334]920                StdString("seconds since ").append(strTimeOrigin),
921                strTimeOrigin);
[219]922         }
923
[449]924         dims.clear() ;
925         axisid = "time_counter" ;
926         timeid = "time_counter" ;
927
928         dims.push_back(timeid);
929         if (!SuperClassWriter::varExist(axisid))
930         {
931            SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims);
932            SuperClassWriter::addAttribute("axis", string("T"), &axisid);
933            CDate timeOrigin=cal->getTimeOrigin() ;
934            StdString strTimeOrigin=timeOrigin.toString() ;
935            this->writeTimeAxisAttributes
936               (axisid, cal->getType(),
937                StdString("seconds since ").append(strTimeOrigin),
938                strTimeOrigin);
939         }         
940         
941
[219]942      }
943
944      //---------------------------------------------------------------
945     
946      void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name,
947                                                   const StdString & calendar,
948                                                   const StdString & units,
949                                                   const StdString & time_origin,
950                                                   const StdString & standard_name,
951                                                   const StdString & long_name,
952                                                   const StdString & title)
953      {
954         SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
955         SuperClassWriter::addAttribute("long_name",     long_name    , &axis_name);
956         SuperClassWriter::addAttribute("title",         title        , &axis_name);
957         SuperClassWriter::addAttribute("calendar",      calendar     , &axis_name);
958         SuperClassWriter::addAttribute("units",         units        , &axis_name);
959         SuperClassWriter::addAttribute("time_origin",   time_origin  , &axis_name);
960      }
961     
962      //---------------------------------------------------------------
963
964      void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name,
965                                               const StdString & axis,
966                                               const StdString & standard_name,
967                                               const StdString & long_name,
968                                               const StdString & units,
969                                               const StdString & nav_model)
970      {
971         SuperClassWriter::addAttribute("axis"         , axis         , &axis_name);
972         SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name);
973         SuperClassWriter::addAttribute("long_name"    , long_name    , &axis_name);
974         SuperClassWriter::addAttribute("units"        , units        , &axis_name);
975         SuperClassWriter::addAttribute("nav_model"    , nav_model    , &axis_name);
976      }
977
978      //---------------------------------------------------------------
979     
980      void CNc4DataOutput::writeLocalAttributes
981         (int ibegin, int ni, int jbegin, int nj, StdString domid)
982      {
[318]983         SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin);
984         SuperClassWriter::addAttribute(StdString("ni"    ).append(domid), ni);
985         SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin);
986         SuperClassWriter::addAttribute(StdString("nj"    ).append(domid), nj);
[219]987      }
988
[391]989     void CNc4DataOutput::writeLocalAttributes_IOIPSL
990         (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)
991      {
992         CArray<int,1> array(2) ;
993
994         SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ;
995         SuperClassWriter::addAttribute("DOMAIN_number", rank) ;
996         array=1,2 ;
997         SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ;
998         array=ni_glo,nj_glo ;
999         SuperClassWriter::addAttribute("DOMAIN_size_global", array) ;
1000         array=ni,nj ;
1001         SuperClassWriter::addAttribute("DOMAIN_size_local", array) ;
1002         array=ibegin,jbegin ;
1003         SuperClassWriter::addAttribute("DOMAIN_position_first", array) ;
1004         array=ibegin+ni-1,jbegin+nj-1 ;
1005         SuperClassWriter::addAttribute("DOMAIN_position_last",array) ;
1006         array=0,0 ;
1007         SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ;
1008         SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array);
1009         SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ;
1010/*
1011         SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ;
1012         SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ;
1013         SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ;
1014         SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ;
1015*/
1016
1017      }
[219]1018      //---------------------------------------------------------------
1019
1020      void CNc4DataOutput:: writeFileAttributes(const StdString & name,
1021                                                const StdString & description,
1022                                                const StdString & conventions,
1023                                                const StdString & production,
1024                                                const StdString & timeStamp)
1025      {
1026         SuperClassWriter::addAttribute("name"       , name);
1027         SuperClassWriter::addAttribute("description", description);
1028         SuperClassWriter::addAttribute("conventions", conventions);
1029         SuperClassWriter::addAttribute("production" , production);
1030         SuperClassWriter::addAttribute("timeStamp"  , timeStamp);
1031      }
1032
1033      //---------------------------------------------------------------
1034
1035      void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name,
1036                                               int data_dim,
1037                                               int data_ni,
1038                                               int data_nj,
1039                                               int data_ibegin,
1040                                               int data_jbegin)
1041      {
1042         SuperClassWriter::addAttribute("data_dim"   , data_dim   , &mask_name);
1043         SuperClassWriter::addAttribute("data_ni"    , data_ni    , &mask_name);
1044         SuperClassWriter::addAttribute("data_nj"    , data_nj    , &mask_name);
1045         SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name);
1046         SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name);
1047      }
1048
1049      ///--------------------------------------------------------------
1050
[335]1051} // namespace xios
Note: See TracBrowser for help on using the repository browser.