source: XMLIO_V2/dev/dev_rv/src/xmlio/node/domain.cpp @ 182

Last change on this file since 182 was 182, checked in by hozdoba, 12 years ago
File size: 15.5 KB
Line 
1#include "domain.hpp"
2
3#include "attribute_template_impl.hpp"
4#include "object_template_impl.hpp"
5#include "group_template_impl.hpp"
6
7#include <algorithm>
8
9namespace xmlioserver {
10namespace tree {
11   
12   /// ////////////////////// Définitions ////////////////////// ///
13
14   CDomain::CDomain(void)
15      : CObjectTemplate<CDomain>(), CDomainAttributes()
16      , isChecked(false), local_mask(new CMask()), relFiles()
17      , ibegin_sub(), iend_sub(), jbegin_sub(), jend_sub()
18      , lonvalue_sub(), latvalue_sub()
19   { /* Ne rien faire de plus */ }
20
21   CDomain::CDomain(const StdString & id)
22      : CObjectTemplate<CDomain>(id), CDomainAttributes()
23      , isChecked(false), local_mask(new CMask()), relFiles()
24      , ibegin_sub(), iend_sub(), jbegin_sub(), jend_sub()
25      , lonvalue_sub(), latvalue_sub()
26   { /* Ne rien faire de plus */ }
27
28   CDomain::~CDomain(void)
29   { 
30      this->local_mask.reset();
31      for (StdSize i = 0; i < this->lonvalue_sub.size(); i++)
32      {
33         this->lonvalue_sub[i].reset();
34         this->latvalue_sub[i].reset();
35      }     
36   }
37
38   ///---------------------------------------------------------------
39
40   const std::set<StdString> & CDomain::getRelFiles(void) const
41   {
42      return (this->relFiles);
43   }
44
45   //----------------------------------------------------------------
46
47   bool CDomain::IsWritten(const StdString & filename) const
48   {
49      return (this->relFiles.find(filename) != this->relFiles.end());
50   }
51
52   //----------------------------------------------------------------
53
54   void CDomain::addRelFile(const StdString & filename)
55   {
56      this->relFiles.insert(filename);
57   }
58
59   //----------------------------------------------------------------
60
61   void CDomain::fromBinary(StdIStream & is)
62   {
63      SuperClass::fromBinary(is);
64     
65      this->ibegin_sub.push_back(this->ibegin.getValue());
66      this->jbegin_sub.push_back(this->jbegin.getValue());
67      this->iend_sub.push_back(this->iend.getValue());
68      this->jend_sub.push_back(this->jend.getValue()); 
69     
70      this->latvalue_sub.push_back(this->latvalue.getValue());
71      this->lonvalue_sub.push_back(this->lonvalue.getValue());   
72     
73#define CLEAR_ATT(name_)\
74      SuperClassAttribute::operator[](#name_)->clear()
75
76         CLEAR_ATT(mask);
77         CLEAR_ATT(data_n_index);
78         CLEAR_ATT(data_i_index);
79         CLEAR_ATT(data_j_index);
80         
81         CLEAR_ATT(data_ni);
82         CLEAR_ATT(data_nj);
83         CLEAR_ATT(data_ibegin);
84         CLEAR_ATT(data_jbegin);
85         
86         CLEAR_ATT(ni);
87         CLEAR_ATT(nj);
88         
89#undef CLEAR_ATT
90
91      this->ibegin.setValue(*std::min_element(this->ibegin_sub.begin(),this->ibegin_sub.end()));
92      this->jbegin.setValue(*std::min_element(this->jbegin_sub.begin(),this->jbegin_sub.end()));
93      this->iend.setValue(*std::max_element(this->iend_sub.begin(),this->iend_sub.end()));
94      this->jend.setValue(*std::max_element(this->jend_sub.begin(),this->jend_sub.end()));
95   }
96
97   //----------------------------------------------------------------
98
99   StdString CDomain::GetName(void)   { return (StdString("domain")); }
100   StdString CDomain::GetDefName(void){ return (CDomain::GetName()); }
101   ENodeType CDomain::GetType(void)   { return (eDomain); }
102
103   //----------------------------------------------------------------
104
105   void CDomain::checkGlobalDomain(void)
106   {
107      if ((ni_glo.isEmpty() || ni_glo.getValue() <= 0 ) ||
108          (ni_glo.isEmpty() || nj_glo.getValue() <= 0 ))
109         ERROR("CDomain::checkAttributes(void)",
110               << "Le domaine global est mal défini,"
111               << " vérifiez les valeurs de \'ni_glo\' et \'nj_glo\' !") ;
112   }
113
114
115   //----------------------------------------------------------------
116
117   void CDomain::checkLocalIDomain(void)
118   {
119      if (!ni.isEmpty() && !ibegin.isEmpty() && iend.isEmpty())
120         iend.setValue(ibegin.getValue() + ni.getValue() - 1) ;
121
122      else if (!ni.isEmpty() && !iend.isEmpty()   && ibegin.isEmpty())
123         ibegin.setValue( - ni.getValue() + iend.getValue() + 1) ;
124
125      else if (!ibegin.isEmpty() && !iend.isEmpty() && ni.isEmpty())
126         ni.setValue(iend.getValue() - ibegin.getValue() + 1) ;
127
128      else if (!ibegin.isEmpty() && !iend.isEmpty() &&
129               !ni.isEmpty() && (iend.getValue() != ibegin.getValue() + ni.getValue() - 1))
130      {
131         ERROR("CDomain::checkAttributes(void)",
132               << "Le domaine est mal défini,"
133               << " iend est différent de (ibegin + ni - 1) !") ;
134      }
135      else
136      {
137         ERROR("CDomain::checkAttributes(void)",
138               << "Le domaine est mal défini,"
139               << " deux valeurs au moins parmis iend, ibegin, ni doivent être définies !") ;
140      }
141
142
143      if (ni.getValue() < 0 || ibegin.getValue() > iend.getValue() ||
144          ibegin.getValue() < 1 || iend.getValue() > ni_glo.getValue())
145         ERROR("CDomain::checkAttributes(void)",
146               << "Domaine local mal défini,"
147               << " vérifiez les valeurs ni, ni_glo, ibegin, iend") ;
148
149   }
150
151   //----------------------------------------------------------------
152
153   void CDomain::checkLocalJDomain(void)
154   {
155      if (!nj.isEmpty() && !jbegin.isEmpty() && jend.isEmpty())
156         jend.setValue(jbegin.getValue() + nj.getValue() - 1) ;
157
158      else if (!nj.isEmpty() && !jend.isEmpty() && jbegin.isEmpty())
159         jbegin.setValue( - nj.getValue() + jend.getValue() + 1) ;
160
161      else if (!jbegin.isEmpty() && !jend.isEmpty() && nj.isEmpty())
162         nj.setValue(jend.getValue() - jbegin.getValue() + 1) ;
163
164      else if (!jbegin.isEmpty() && !jend.isEmpty() &&
165               !nj.isEmpty() && (jend.getValue() != jbegin.getValue() + nj.getValue() - 1))
166      {
167         ERROR("CDomain::checkAttributes(void)",
168               << "Le domaine est mal défini,"
169               << " iend est différent de (jbegin + nj - 1) !") ;
170      }
171      else
172      {
173         ERROR("CDomain::checkAttributes(void)",
174               << "Le domaine est mal défini,"
175               << " deux valeurs au moins parmis jend, jbegin, nj doivent être définies !") ;
176      }
177
178      if (nj.getValue() < 0 || jbegin.getValue() > jend.getValue() ||
179          jbegin.getValue() < 1 || jend.getValue() > nj_glo.getValue())
180         ERROR("CDomain::checkAttributes(void)",
181               << "Domaine local mal défini,"
182               << " vérifiez les valeurs nj, nj_glo, jbegin, jend") ;
183   }
184
185
186   //----------------------------------------------------------------
187
188   void CDomain::checkMask(void)
189   {
190      if (!mask.isEmpty())
191      {
192         unsigned int niu = ni.getValue(), nju = nj.getValue();
193         if ((mask.getValue()->shape()[0] != niu) ||
194             (mask.getValue()->shape()[1] != nju))
195            ERROR("CDomain::checkAttributes(void)",
196                  <<"Le masque n'a pas la même taille que le domaine local") ;
197      }
198      else // (!mask.hasValue())
199      { // Si aucun masque n'est défini,
200        // on en crée un nouveau qui valide l'intégralité du domaine.
201         ARRAY_CREATE(__arr, bool, 2, [ni.getValue()][nj.getValue()]);
202         for (int i = 0; i < ni.getValue(); i++)
203            for (int j = 0; j < nj.getValue(); j++)
204               (*__arr)[i][j] = true;
205         mask.setValue(__arr);
206         __arr.reset();
207      }
208   }
209
210
211   //----------------------------------------------------------------
212
213   void CDomain::checkDomainData(void)
214   {     
215      if (!data_dim.isEmpty() &&
216         !(data_dim.getValue() == 1 || data_dim.getValue() == 2))
217      {
218         ERROR("CDomain::checkAttributes(void)",
219               << "Dimension des données non comptatible (doit être 1 ou 2) !") ;
220      }
221      else if (data_dim.isEmpty())
222      {
223         ERROR("CDomain::checkAttributes(void)",
224               << "Dimension des données non définie !") ;
225      }
226
227      if (data_ibegin.isEmpty())
228         data_ibegin.setValue(0) ;
229      if (data_jbegin.isEmpty() && (data_dim.getValue() == 2))
230           data_jbegin.setValue(0) ;
231
232      if (!data_ni.isEmpty() && (data_ni.getValue() <= 0))
233      {
234         ERROR("CDomain::checkAttributes(void)",
235               << "Dimension des données négative (data_ni).") ;
236      }
237      else if (data_ni.isEmpty())
238      {
239         data_ni.setValue((data_dim.getValue() == 1)
240                           ? (ni.getValue() * nj.getValue())
241                           : ni.getValue());
242      }
243
244      if (data_dim.getValue() == 2)
245      {
246         if (!data_nj.isEmpty() && (data_nj.getValue() <= 0) )
247         {
248            ERROR("CDomain::checkAttributes(void)",
249                  << "Dimension des données négative (data_nj).") ;
250         }
251         else if (data_nj.isEmpty())
252            data_nj.setValue(nj.getValue()) ;
253      }
254
255   }
256
257   //----------------------------------------------------------------
258
259   void CDomain::checkCompression(void)
260   {
261      if (!data_i_index.isEmpty())
262      {
263         int ssize = data_i_index.getValue()->size();
264         if (!data_n_index.isEmpty() &&
265            (data_n_index.getValue() != ssize))
266         {
267            ERROR("CDomain::checkAttributes(void)",
268                  <<"Dimension data_i_index incompatible avec data_n_index.") ;
269         }
270         else if (data_n_index.isEmpty())
271            data_n_index.setValue(ssize) ;
272
273         if (data_dim.getValue() == 2)
274         {
275            if (!data_j_index.isEmpty() &&
276               (data_j_index.getValue()->size() != data_i_index.getValue()->size()))
277            {
278               ERROR("CDomain::checkAttributes(void)",
279                     <<"Dimension data_j_index incompatible avec data_i_index.") ;
280            }
281            else if (data_j_index.isEmpty())
282            {
283               ERROR("CDomain::checkAttributes(void)",
284                     <<"La donnée data_j_index doit être renseignée !") ;
285            }
286         }
287      }
288      else
289      {
290         if (!data_n_index.isEmpty() ||
291            ((data_dim.getValue() == 2) && (!data_j_index.isEmpty())))
292            ERROR("CDomain::checkAttributes(void)", << "data_i_index non défini") ;
293      }
294
295      if (data_n_index.isEmpty())
296      { // -> bloc re-vérifié OK
297         if (data_dim.getValue() == 1)
298         {
299            const int dni = data_ni.getValue();
300            ARRAY_CREATE(__arri, int, 1, [dni]);
301            data_n_index.setValue(dni);
302            for (int i = 0; i < dni; i++)
303               (*__arri)[i] = i+1 ;
304            data_i_index.setValue(__arri) ;
305         }
306         else   // (data_dim == 2)
307         {
308            const int dni = data_ni.getValue() * data_nj.getValue();
309           
310            ARRAY_CREATE(__arri, int, 1, [dni]);
311            ARRAY_CREATE(__arrj, int, 1, [dni]);               
312            data_n_index.setValue(dni);
313           
314            for(int count = 0, i = 0; i  < data_ni.getValue(); i++)
315            {
316               for(int j = 0; j < data_nj.getValue(); j++, count++)
317               { 
318                  (*__arri)[count] = i+1 ;
319                  (*__arrj)[count] = j+1 ;
320               }
321            }
322            data_i_index.setValue(__arri) ;
323            data_j_index.setValue(__arrj) ;           
324            __arri.reset();
325            __arrj.reset();
326         }
327      }
328   }
329
330   //----------------------------------------------------------------
331   
332   void CDomain::completeLonLat(void)
333   {
334      ARRAY(double, 1) lonvalue_ = this->lonvalue.getValue(),
335                       latvalue_ = this->latvalue.getValue();
336                       
337      if (this->data_dim.getValue() == 2)
338      {
339         StdSize dn = this->ni.getValue()*this->nj.getValue();
340         lonvalue_->resize(boost::extents[dn]);
341         latvalue_->resize(boost::extents[dn]);
342
343         for (StdSize k = 0; k < lonvalue_sub.size(); k++)
344         {
345            int l = 0;
346            ARRAY(double, 1) lonvalue_loc = this->lonvalue_sub[k],
347                             latvalue_loc = this->latvalue_sub[k];
348            const int ibegin_loc = ibegin_sub[k], iend_loc = iend_sub[k],
349                      jbegin_loc = jbegin_sub[k], jend_loc = jend_sub[k];
350                                                                 
351            for (int i = ibegin_loc-1; i <= (iend_loc-1); i++)
352            {
353               for (int j = jbegin_loc-1; j <= (jend_loc-1); j++)
354               {
355                  (*lonvalue_)[i+j*this->ni.getValue()] = (*lonvalue_loc)[l];             
356                  (*latvalue_)[i+j*this->ni.getValue()] = (*latvalue_loc)[l++];
357               }
358            }
359         }   
360         
361      }
362      else
363      {
364         StdSize dn = this->ni.getValue();
365         lonvalue_->resize(boost::extents[dn]);
366         latvalue_->resize(boost::extents[dn]);
367         
368         for (StdSize k = 0; k < lonvalue_sub.size(); k++)
369         {
370            int l = 0;
371            ARRAY(double, 1) lonvalue_loc = this->lonvalue_sub[k],
372                             latvalue_loc = this->latvalue_sub[k];
373            const int ibegin_loc = ibegin_sub[k], iend_loc = iend_sub[k],
374                      jbegin_loc = jbegin_sub[k], jend_loc = jend_sub[k];
375                     
376            for (int i = ibegin_loc-1; i <= (iend_loc-1); i++)
377               (*lonvalue_)[i] = (*lonvalue_loc)[l++];
378               
379            for (int j = jbegin_loc-1, l = 0; j <= (jend_loc-1); j++)
380               (*latvalue_)[j] = (*latvalue_loc)[l++];
381         }         
382      }
383   }
384
385   //----------------------------------------------------------------
386
387   void CDomain::checkAttributes(void)
388   {
389      if (this->isChecked) return;
390
391      this->checkGlobalDomain();
392      this->checkLocalIDomain();
393      this->checkLocalJDomain();
394
395      if (this->latvalue_sub.size() == 0)
396      {
397         this->checkMask();
398         this->checkDomainData();
399         this->checkCompression();
400      }
401      else
402      {
403         this->completeLonLat();
404      }
405      this->completeMask();
406
407      this->isChecked = true;
408   }
409   
410   //----------------------------------------------------------------
411   
412   void CDomain::completeMask(void)
413   {
414      this->local_mask->resize(ni.getValue(), nj.getValue());
415      /*this->local_mask->setDataPosition
416         (data_dim.getValue(), data_ni.getValue(), data_nj.getValue(),
417          data_ibegin.getValue(), data_jbegin.getValue(), data_n_index.getValue(),
418          data_i_index.getValue(), data_j_index.getValue());*/
419   }
420
421   //----------------------------------------------------------------
422
423   boost::shared_ptr<CMask> CDomain::getLocalMask(void) const
424   {
425      return (this->local_mask);
426   }
427   
428   //----------------------------------------------------------------
429   
430   const std::vector<int> & CDomain::getIBeginSub(void) const
431   {
432      return (this->ibegin_sub);
433   }
434   
435   //----------------------------------------------------------------
436   
437   const std::vector<int> & CDomain::getIEndSub(void) const
438   {
439      return (this->iend_sub);
440   }
441   
442   //----------------------------------------------------------------
443   
444   const std::vector<int> & CDomain::getJBeginSub(void) const
445   {
446      return (this->jbegin_sub);
447   }
448   
449   //----------------------------------------------------------------
450   
451   const std::vector<int> & CDomain::getJEndSub(void) const
452   {
453      return (this->iend_sub);
454   }
455   
456   //----------------------------------------------------------------
457   
458   const std::vector<ARRAY(double, 1)> & CDomain::getLonValueSub(void) const
459   {
460      return (this->lonvalue_sub);
461   }
462   
463   //----------------------------------------------------------------
464   
465   const std::vector<ARRAY(double, 1)> & CDomain::getLatValueSub(void) const
466   {
467      return (this->latvalue_sub);
468   }   
469   
470   ///---------------------------------------------------------------
471
472} // namespace tree
473} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.