source: XMLIO_V2/dev/common/src/xmlio/node/field.cpp @ 286

Last change on this file since 286 was 286, checked in by ymipsl, 13 years ago

reprise en main de la version de H. Ozdoba. Correction de différentes erreurs de conception et bug.
Version NEMO operationnel en client/server, interoperabilita avec OASIS, reconstition de fichiers via netcdf4/HDF5

YM

File size: 13.3 KB
Line 
1#include "field.hpp"
2
3#include "attribute_template_impl.hpp"
4#include "object_template_impl.hpp"
5#include "group_template_impl.hpp"
6
7#include "node_type.hpp"
8#include "calendar_util.hpp"
9#include "xios_manager.hpp"
10
11namespace xmlioserver{
12namespace tree {
13   
14   /// ////////////////////// Définitions ////////////////////// ///
15
16   CField::CField(void)
17      : CObjectTemplate<CField>(), CFieldAttributes()
18      , refObject(), baseRefObject()
19      , grid(), file()
20      , freq_operation(), freq_write()
21      , nstep(0)
22      , last_Write(), last_operation()
23      , foperation()
24      , data(new CArray<double, 1>(boost::extents[0]))
25   { /* Ne rien faire de plus */ }
26
27   CField::CField(const StdString & id)
28      : CObjectTemplate<CField>(id), CFieldAttributes()
29      , refObject(), baseRefObject()
30      , grid(), file()
31      , freq_operation(), freq_write()
32      , nstep(0)
33      , last_Write(), last_operation()
34      , foperation()
35      , data(new CArray<double, 1>(boost::extents[0]))
36   { /* Ne rien faire de plus */ }
37
38   CField::~CField(void)
39   {
40      this->grid.reset() ;
41      this->file.reset() ;
42      this->foperation.reset() ;
43      this->data.reset() ;
44   }
45
46   //----------------------------------------------------------------
47
48   bool CField::updateDataServer
49      (const date::CDate & currDate,
50       const std::deque<ARRAY(double, 1)> storedClient)
51   {
52      const date::CDate opeDate      = *last_operation + freq_operation;
53      const date::CDate writeDate    = *last_Write     + freq_write; 
54     
55      if (opeDate <= currDate)
56      {
57         if (this->data->num_elements() != this->grid->storeIndex[0]->num_elements())
58         {
59            this->data->resize(boost::extents[this->grid->storeIndex[0] ->num_elements()]);
60         } 
61         ARRAY_CREATE(input, double, 1, [this->data->num_elements()]);
62         this->grid->inputFieldServer(storedClient, input);         
63         (*this->foperation)(input);
64         *last_operation = currDate;
65      }
66      if (writeDate < (currDate + freq_operation))
67      {
68         this->foperation->final();
69         this->incrementNStep();
70         *last_Write = writeDate;
71         return (true);       
72      }
73      return (false);
74   }
75
76   //----------------------------------------------------------------
77
78   void CField::setRelFile(const boost::shared_ptr<CFile> _file)
79   { 
80      this->file = _file; 
81   }
82
83   //----------------------------------------------------------------
84
85   StdString CField::GetName(void)   { return (StdString("field")); }
86   StdString CField::GetDefName(void){ return (CField::GetName()); }
87   ENodeType CField::GetType(void)   { return (eField); }
88
89   //----------------------------------------------------------------
90
91   boost::shared_ptr<CGrid> CField::getRelGrid(void) const
92   { 
93      return (this->grid); 
94   }
95
96   //----------------------------------------------------------------
97
98   boost::shared_ptr<CFile> CField::getRelFile(void) const
99   { 
100      return (this->file);
101   }
102   
103   StdSize CField::getNStep(void) const
104   {
105      return (this->nstep);
106   }
107   
108   void CField::incrementNStep(void)
109   {
110      this->nstep++;
111   }
112
113   //----------------------------------------------------------------
114
115   boost::shared_ptr<CField> CField::getDirectFieldReference(void) const
116   {
117      if (this->field_ref.isEmpty())
118         return (this->getBaseFieldReference());
119
120      if (! CObjectFactory::HasObject<CField>(this->field_ref.getValue()))
121         ERROR("CField::getDirectFieldReference(void)",
122               << "[ ref_name = " << this->field_ref.getValue() << "]"
123               << " invalid field name !");
124
125      return (CObjectFactory::GetObject<CField>(this->field_ref.getValue()));
126   }
127
128   //----------------------------------------------------------------
129
130   const boost::shared_ptr<CField> CField::getBaseFieldReference(void) const
131   { 
132      return (baseRefObject); 
133   }
134
135   //----------------------------------------------------------------
136
137   const std::vector<boost::shared_ptr<CField> > & CField::getAllReference(void) const 
138   { 
139      return (refObject);
140   }
141
142   //----------------------------------------------------------------
143
144   const StdString & CField::getBaseFieldId(void) const
145   { 
146      return (this->getBaseFieldReference()->getId());
147   }
148   
149   //----------------------------------------------------------------
150   
151   const date::CDuration & CField::getFreqOperation(void) const
152   {
153      return (this->freq_operation);
154   }
155   
156   //----------------------------------------------------------------
157   const date::CDuration & CField::getFreqWrite(void) const
158   {
159      return (this->freq_write);
160   }
161   
162   //----------------------------------------------------------------
163         
164   boost::shared_ptr<func::CFunctor> CField::getFieldOperation(void) const
165   {
166      return (this->foperation);
167   }
168
169   //----------------------------------------------------------------
170
171   bool CField::hasDirectFieldReference(void) const
172   { 
173      return (!this->field_ref.isEmpty()); 
174   }
175   
176   //----------------------------------------------------------------
177   
178   ARRAY(double, 1) CField::getData(void) const
179   {
180      return(this->data);
181   }
182
183   //----------------------------------------------------------------
184
185   boost::shared_ptr<date::CDate> CField::getLastWriteDate(void) const
186   {
187      return(this->last_Write);
188   }
189
190   //----------------------------------------------------------------
191
192   boost::shared_ptr<date::CDate> CField::getLastOperationDate(void) const
193   {
194      return(this->last_operation);
195   }
196
197   //----------------------------------------------------------------
198
199   void CField::solveRefInheritance(void)
200   {
201      std::set<CField *> sset;
202      boost::shared_ptr<CField> refer_sptr;
203      CField * refer_ptr = this;
204     
205      this->baseRefObject = CObjectFactory::GetObject<CField>(this);
206     
207      while (refer_ptr->hasDirectFieldReference())
208      {
209         refer_sptr = refer_ptr->getDirectFieldReference();
210         refer_ptr  = refer_sptr.get();
211
212         if(sset.end() != sset.find(refer_ptr))
213         {
214            DEBUG (<< "Dépendance circulaire stoppée pour l'objet de type CField sur "
215                   << "\"" + refer_ptr->getId() + "\" !");
216            break;
217         }
218
219         SuperClassAttribute::setAttributes(refer_ptr);
220         sset.insert(refer_ptr);
221         baseRefObject = refer_sptr;
222//ym         refObject.push_back(refer_sptr);
223      }
224   }
225
226   //----------------------------------------------------------------
227
228   void  CField::solveOperation(void)
229   {
230      using namespace func;
231      using namespace date;
232       
233      StdString id = this->getBaseFieldReference()->getId();
234      boost::shared_ptr<CContext> _context =
235         CObjectFactory::GetObject<CContext>(CObjectFactory::GetCurrentContextId());
236
237      if (operation.isEmpty() || freq_op.isEmpty() || this->file->output_freq.isEmpty())
238      {
239         ERROR("CField::solveOperation(void)",
240               << "[ id = " << id << "]"
241               << "Impossible de définir une opération pour le champ !");
242      }
243     
244      CDuration freq_offset_ = NoneDu;
245      if (!freq_offset.isEmpty())
246      {
247         freq_offset_ = CDuration::FromString(freq_offset.getValue());
248      }
249      else
250      {
251         freq_offset.setValue(NoneDu.toString());
252      } 
253
254      if (CXIOSManager::GetStatus() == CXIOSManager::LOC_SERVER)
255      {
256         this->freq_operation =
257             CDuration::FromString(this->file->output_freq.getValue());
258         this->freq_write     =
259             CDuration::FromString(this->file->output_freq.getValue());
260         this->last_Write     = boost::shared_ptr<xmlioserver::date::CDate>
261                        (new date::CDate(_context->getCalendar()->getInitDate()));
262         this->last_operation = boost::shared_ptr<xmlioserver::date::CDate>
263                        (new date::CDate(_context->getCalendar()->getInitDate()));
264         this->foperation     =
265             boost::shared_ptr<func::CFunctor>(new CInstant(this->data));
266             
267         const CDuration toffset = this->freq_operation - freq_offset_ - _context->getCalendar()->getTimeStep(); 
268         *this->last_operation   = *this->last_operation - toffset; 
269      }
270      else
271      {                 
272         this->freq_operation = CDuration::FromString(freq_op.getValue());
273         this->freq_write     = CDuration::FromString(this->file->output_freq.getValue());
274         this->last_Write     = boost::shared_ptr<xmlioserver::date::CDate>
275                        (new date::CDate(_context->getCalendar()->getInitDate()));
276         this->last_operation = boost::shared_ptr<xmlioserver::date::CDate>
277                        (new date::CDate(_context->getCalendar()->getInitDate()));
278                       
279         const CDuration toffset = this->freq_operation - freq_offset_ - _context->getCalendar()->getTimeStep(); 
280         *this->last_operation   = *this->last_operation - toffset; 
281         
282#define DECLARE_FUNCTOR(MType, mtype)              \
283   if  (operation.getValue().compare(#mtype) == 0) \
284   {                                               \
285      boost::shared_ptr<func::CFunctor>            \
286            foperation_(new C##MType(this->data)); \
287      this->foperation = foperation_;              \
288      return;                                      \
289   }
290   
291#include "functor_type.conf"
292         
293         ERROR("CField::solveOperation(void)",
294               << "[ operation = " << operation.getValue() << "]"
295               << "L'opération n'est pas définie dans le code !");
296      }
297   }
298   
299   //----------------------------------------------------------------
300   
301   void CField::fromBinary(StdIStream & is)
302   {
303      SuperClass::fromBinary(is);
304#define CLEAR_ATT(name_)\
305      SuperClassAttribute::operator[](#name_)->clear()
306
307         CLEAR_ATT(domain_ref);
308         CLEAR_ATT(axis_ref);
309#undef CLEAR_ATT
310
311   }
312
313   //----------------------------------------------------------------
314
315   void CField::solveGridReference(void)
316   {
317      boost::shared_ptr<CDomain> domain;
318      boost::shared_ptr<CAxis> axis;
319
320      if (!domain_ref.isEmpty())
321      {
322         if (CObjectFactory::HasObject<CDomain>(domain_ref.getValue()))
323            domain = CObjectFactory::GetObject<CDomain>(domain_ref.getValue()) ;
324         else
325            ERROR("CField::solveGridReference(void)",
326                  << "Référence au domaine nommé \'"
327                  << domain_ref.getValue() << "\' incorrecte") ;
328      }
329
330      if (!axis_ref.isEmpty())
331      {
332         if (CObjectFactory::HasObject<CAxis>(axis_ref.getValue()))
333            axis = CObjectFactory::GetObject<CAxis>(axis_ref.getValue()) ;
334         else
335            ERROR("CField::solveGridReference(void)",
336                  << "Référence à l'axe nommé \'"
337                  << axis_ref.getValue() <<"\' incorrecte") ;
338      }
339
340      if (!grid_ref.isEmpty())
341      {
342         if (CObjectFactory::HasObject<CGrid>(grid_ref.getValue()))
343            this->grid = CObjectFactory::GetObject<CGrid>(grid_ref.getValue()) ;
344         else
345            ERROR("CField::solveGridReference(void)",
346                  << "Référence à la grille nommée \'"
347                  << grid_ref.getValue() << "\' incorrecte");
348         if (!domain_ref.isEmpty())
349            DEBUG(<< "Définition conjointe de la grille "
350                  << "et du domaine, la grille prévaut..." );
351         if (!axis_ref.isEmpty())
352            DEBUG(<< "Définition conjointe de la grille "
353                  << "et de l'axe vertical, la grille prévaut...") ;
354      }
355      else
356      {
357         if (!domain_ref.isEmpty())
358         {
359            if (!axis_ref.isEmpty())
360            {
361               this->grid = CGrid::CreateGrid(domain, axis) ;
362               this->grid_ref.setValue(this->grid->getId());
363            }
364            else
365            {
366               this->grid = CGrid::CreateGrid(domain) ;
367               this->grid_ref.setValue(this->grid->getId());
368            }
369         }
370         else
371         {
372            ERROR("CField::solveGridReference(void)",
373                  << "Le domaine horizontal pour le champ X n'est pas défini");
374         }
375      }
376      grid->solveReference() ;
377   }
378
379   } // namespace tree
380
381   ///-------------------------------------------------------------------
382
383   template <>
384      void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)
385   {
386      if (this->group_ref.isEmpty()) return;
387      StdString gref = this->group_ref.getValue();
388
389      if (!CObjectFactory::HasObject<CFieldGroup>(gref))
390         ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)",
391               << "[ gref = " << gref << "]"
392               << " invalid group name !");
393
394      boost::shared_ptr<CFieldGroup> group
395               = CObjectFactory::GetObject<CFieldGroup>(gref);
396      boost::shared_ptr<CFieldGroup> owner
397               = CObjectFactory::GetObject<CFieldGroup>
398                  (boost::polymorphic_downcast<CFieldGroup*>(this));
399
400      std::vector<boost::shared_ptr<CField> > allChildren  = group->getAllChildren();
401      std::vector<boost::shared_ptr<CField> >::iterator
402         it = allChildren.begin(), end = allChildren.end();
403     
404      for (; it != end; it++)
405      {
406         boost::shared_ptr<CField> child = *it;
407         if (child->hasId())
408            CGroupFactory::CreateChild(owner)->field_ref.setValue(child->getId());
409      }
410   }
411
412   ///-------------------------------------------------------------------
413
414} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.