source: XMLIO_V2/dev/dev_rv/src/xmlio/node/field.cpp @ 265

Last change on this file since 265 was 265, checked in by hozdoba, 10 years ago

Corrections après tests sur titane

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