source: XIOS/trunk/src/node/axis.cpp @ 623

Last change on this file since 623 was 623, checked in by mhnguyen, 9 years ago

Implementing transformation algorithm: zoom axis (local commit)

+) Implement zoom axis: zoomed points are points not masked
+) Correct some minor bugs

Test
+) Ok with normal cases: zoom in the last of transformation list
+) There is still a bug in case of zoom then inverse

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
  • Property svn:executable set to *
File size: 13.4 KB
Line 
1#include "axis.hpp"
2
3#include "attribute_template.hpp"
4#include "object_template.hpp"
5#include "group_template.hpp"
6#include "message.hpp"
7#include "type.hpp"
8#include "context.hpp"
9#include "context_client.hpp"
10#include "xios_spl.hpp"
11
12namespace xios {
13
14   /// ////////////////////// Définitions ////////////////////// ///
15
16   CAxis::CAxis(void)
17      : CObjectTemplate<CAxis>()
18      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
19      , isDistributed_(false)
20      , transformationMap_(), global_zoom_begin(0), global_zoom_size(0)
21   {
22   }
23
24   CAxis::CAxis(const StdString & id)
25      : CObjectTemplate<CAxis>(id)
26      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
27      , isDistributed_(false)
28      , transformationMap_(), global_zoom_begin(0), global_zoom_size(0)
29   {
30   }
31
32   CAxis::~CAxis(void)
33   { /* Ne rien faire de plus */ }
34
35   ///---------------------------------------------------------------
36
37   const std::set<StdString> & CAxis::getRelFiles(void) const
38   {
39      return (this->relFiles);
40   }
41
42   bool CAxis::IsWritten(const StdString & filename) const
43   {
44      return (this->relFiles.find(filename) != this->relFiles.end());
45   }
46
47   bool CAxis::isDistributed(void) const
48   {
49      return isDistributed_;
50   }
51
52   void CAxis::addRelFile(const StdString & filename)
53   {
54      this->relFiles.insert(filename);
55   }
56
57   //----------------------------------------------------------------
58
59   StdString CAxis::GetName(void)   { return (StdString("axis")); }
60   StdString CAxis::GetDefName(void){ return (CAxis::GetName()); }
61   ENodeType CAxis::GetType(void)   { return (eAxis); }
62
63   //----------------------------------------------------------------
64
65   CAxis* CAxis::createAxis()
66   {
67     CAxis* axis = CAxisGroup::get("axis_definition")->createChild();
68     return axis;
69   }
70
71   void CAxis::checkAttributes(void)
72   {
73      if (this->size.isEmpty())
74         ERROR("CAxis::checkAttributes(void)",
75               << "Attribute <size> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be specified");
76      StdSize size = this->size.getValue();
77
78      isDistributed_ = !this->ibegin.isEmpty() || !this->ni.isEmpty();
79
80      if (!this->ibegin.isEmpty())
81      {
82        StdSize ibegin = this->ibegin.getValue();
83        if ((ibegin < 0) || (ibegin > size-1))
84          ERROR("CAxis::checkAttributes(void)",
85                << "Attribute <ibegin> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size-1");
86      }
87      else this->ibegin.setValue(0);
88
89      if (!this->ni.isEmpty())
90      {
91        StdSize ni = this->ni.getValue();
92        if ((ni < 0) || (ni > size))
93          ERROR("CAxis::checkAttributes(void)",
94                << "Attribute <ni> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size");
95      }
96      else this->ni.setValue(size);
97      std::cout <<  "value " <<  value <<  std::endl;
98//      StdSize true_size = value.numElements();
99//      if (this->ni.getValue() != true_size)
100//         ERROR("CAxis::checkAttributes(void)",
101//               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
102
103      if (0 == global_zoom_size) global_zoom_size = size;
104      this->checkData();
105      this->checkMask();
106//      this->checkZoom();
107
108      if (!bounds.isEmpty())
109      {
110        if (bounds.extent(0) != size || bounds.extent(1) != 2)
111            ERROR("CAxis::checkAttributes(void)",
112                  << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension axis size x 2" << endl
113                  << "Axis size is " << size << endl
114                  << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1));
115      }
116   }
117
118   void CAxis::checkData()
119   {
120      if (data_begin.isEmpty()) data_begin.setValue(0);
121      if (!data_n.isEmpty() && data_n.getValue() <= 0)
122      {
123        ERROR("CAxis::checkData(void)",
124              << "Data dimension is negative (data_n).");
125      }
126      else if (data_n.isEmpty())
127        data_n.setValue(ni.getValue());
128
129      if (data_index.isEmpty())
130      {
131        int dn = data_n.getValue();
132        data_index.resize(dn);
133        for (int i = 0; i < dn; ++i) data_index(i) = (i+1);
134      }
135   }
136
137   void CAxis::checkZoom(void)
138   {
139      StdSize zoom_begin,zoom_end, zoom_size, axisSize;
140
141      zoom_begin = this->zoom_begin.isEmpty() ? 0 : this->zoom_begin.getValue();
142      zoom_size  = this->zoom_size.isEmpty() ? size.getValue() : this->zoom_size.getValue();
143      zoom_end   = this->zoom_end.isEmpty() ? (size.getValue() - 1) : this->zoom_end.getValue();
144
145      if (this->zoom_begin.isEmpty()) zoom_begin = zoom_end - zoom_size + 1;
146      if (this->zoom_end.isEmpty()) zoom_end = zoom_begin + zoom_size - 1;
147      if (this->zoom_size.isEmpty()) zoom_size = zoom_end - zoom_begin + 1;
148      axisSize = size.getValue();
149
150      if ( (zoom_begin < 0) || (zoom_begin > axisSize-1) || (zoom_end<0) || (zoom_end>axisSize-1) || (zoom_size<1) || (zoom_size>axisSize) || (zoom_begin>zoom_end))
151        ERROR("CAxis::checkAttributes(void)",
152              << "One or more attributes among <zoom_begin>, <zoom_end>, <zoom_size> of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
153
154      this->zoom_begin.setValue(zoom_begin);
155      this->zoom_end.setValue(zoom_end);
156      this->zoom_size.setValue(zoom_size);
157   }
158
159   void CAxis::checkMask()
160   {
161      int begin_mask = 0,
162          end_mask = ni.getValue()-1;
163
164      if (!zoom_begin.isEmpty())
165      {
166         int zoom_end = zoom_begin.getValue() + zoom_size.getValue() - 1;
167
168         begin_mask = std::max(ibegin.getValue(), zoom_begin.getValue());
169         end_mask   = std::min(ibegin.getValue() + ni.getValue()-1, zoom_end);
170
171         begin_mask -= ibegin.getValue();
172         end_mask   -= ibegin.getValue();
173      }
174
175
176      if (!mask.isEmpty())
177      {
178         if (mask.extent(0) != ni)
179            ERROR("CAxis::checkMask(void)",
180                  << "the mask has not the same size than the local axis" << endl
181                  << "Local size is " << ni << "x" << endl
182                  << "Mask size is " << mask.extent(0) << "x");
183         for (int i = 0; i < ni; ++i)
184         {
185           if (i < begin_mask && i > end_mask)  mask(i) = false;
186         }
187      }
188      else // (!mask.hasValue())
189      { // Si aucun masque n'est défini,
190        // on en crée un nouveau qui valide l'intégralité du domaine.
191         mask.resize(ni);
192         for (int i = 0; i < ni.getValue(); ++i)
193         {
194               if (i >= begin_mask && i <= end_mask)
195                 mask(i) = true;
196               else  mask(i) = false;
197         }
198      }
199   }
200
201  bool CAxis::dispatchEvent(CEventServer& event)
202   {
203      if (SuperClass::dispatchEvent(event)) return true;
204      else
205      {
206        switch(event.type)
207        {
208           case EVENT_ID_SERVER_ATTRIBUT :
209             recvServerAttribut(event);
210             return true;
211             break;
212           default :
213             ERROR("bool CContext::dispatchEvent(CEventServer& event)",
214                    << "Unknown Event");
215           return false;
216         }
217      }
218   }
219
220   void CAxis::checkAttributesOnClient(const std::vector<int>& globalDim, int orderPositionInGrid,
221                                       CServerDistributionDescription::ServerDistributionType distType)
222   {
223     if (this->areClientAttributesChecked_) return;
224
225     this->checkAttributes();
226
227     this->areClientAttributesChecked_ = true;
228   }
229
230   // Send all checked attributes to server
231   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
232                                     CServerDistributionDescription::ServerDistributionType distType)
233   {
234     if (!this->areClientAttributesChecked_) checkAttributesOnClient(globalDim,
235                                                                     orderPositionInGrid,
236                                                                     distType);
237     CContext* context = CContext::getCurrent();
238
239     if (this->isChecked) return;
240     if (context->hasClient)
241     {
242       sendServerAttribut(globalDim, orderPositionInGrid, distType);
243     }
244
245     this->isChecked = true;
246   }
247
248  void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
249                                 CServerDistributionDescription::ServerDistributionType distType)
250  {
251    CContext* context = CContext::getCurrent();
252    CContextClient* client = context->client;
253
254    CServerDistributionDescription serverDescription(globalDim);
255
256    int nbServer = client->serverSize;
257
258    serverDescription.computeServerDistribution(nbServer, false, distType);
259    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
260    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
261
262    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
263    if (client->isServerLeader())
264    {
265      std::list<CMessage> msgs;
266
267      const std::list<int>& ranks = client->getRanksServerLeader();
268      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
269      {
270        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
271        const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
272        const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
273        const int end   = begin + ni - 1;
274
275        msgs.push_back(CMessage());
276        CMessage& msg = msgs.back();
277        msg << this->getId();
278        msg << ni << begin << end;
279        msg<<global_zoom_begin<<global_zoom_size;
280
281        event.push(*itRank,1,msg);
282      }
283      client->sendEvent(event);
284    }
285    else client->sendEvent(event);
286  }
287
288  void CAxis::recvServerAttribut(CEventServer& event)
289  {
290    CBufferIn* buffer = event.subEvents.begin()->buffer;
291    string axisId;
292    *buffer >> axisId;
293    get(axisId)->recvServerAttribut(*buffer);
294  }
295
296  void CAxis::recvServerAttribut(CBufferIn& buffer)
297  {
298    int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_size_tmp;
299
300    buffer>>ni_srv>>begin_srv>>end_srv>>global_zoom_begin_tmp>>global_zoom_size_tmp;
301    global_zoom_begin = global_zoom_begin_tmp;
302    global_zoom_size  = global_zoom_size_tmp;
303    int global_zoom_end = global_zoom_begin + global_zoom_size - 1;
304
305    zoom_begin_srv = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
306    zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
307    zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
308
309    if (zoom_size_srv<=0)
310    {
311      zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0;
312    }
313
314    if (size == ni)
315    {
316      zoom_begin_srv = global_zoom_begin;
317      zoom_end_srv   = global_zoom_end; //zoom_end;
318      zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
319    }
320  }
321
322  bool CAxis::hasTransformation()
323  {
324    return (!transformationMap_.empty());
325  }
326
327  void CAxis::setTransformations(const TransMapTypes& axisTrans)
328  {
329    transformationMap_ = axisTrans;
330  }
331
332  CAxis::TransMapTypes CAxis::getAllTransformations(void)
333  {
334    return transformationMap_;
335  }
336
337  /*!
338    Check the validity of all transformations applied on axis
339  This functions is called AFTER all inherited attributes are solved
340  */
341  void CAxis::checkTransformations()
342  {
343    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
344                                  ite = transformationMap_.end();
345    for (it = itb; it != ite; ++it)
346    {
347      (it->second)->checkValid(this);
348    }
349  }
350
351  void CAxis::solveInheritanceTransformation()
352  {
353    if (this->hasTransformation()) return;
354
355    std::vector<CAxis*> refAxis;
356    CAxis* refer_sptr;
357    CAxis* refer_ptr = this;
358    while (refer_ptr->hasDirectAxisReference())
359    {
360      refAxis.push_back(refer_ptr);
361      refer_sptr = refer_ptr->getDirectAxisReference();
362      refer_ptr  = refer_sptr;
363      if (refer_ptr->hasTransformation()) break;
364    }
365
366    if (refer_ptr->hasTransformation())
367      for (int idx = 0; idx < refAxis.size(); ++idx)
368        refAxis[idx]->setTransformations(refer_ptr->getAllTransformations());
369  }
370
371  void CAxis::parse(xml::CXMLNode & node)
372  {
373    SuperClass::parse(node);
374
375    if (node.goToChildElement())
376    {
377      StdString inverseAxisDefRoot("inverse_axis_definition");
378      StdString inverse("inverse_axis");
379      StdString zoomAxisDefRoot("zoom_axis_definition");
380      StdString zoom("zoom_axis");
381      do
382      {
383        if (node.getElementName() == inverse) {
384          CInverseAxis* tmp = (CInverseAxisGroup::get(inverseAxisDefRoot))->createChild();
385          tmp->parse(node);
386          transformationMap_.push_back(std::make_pair(TRANS_INVERSE_AXIS,tmp));
387        } else if (node.getElementName() == zoom) {
388          CZoomAxis* tmp = (CZoomAxisGroup::get(zoomAxisDefRoot))->createChild();
389          tmp->parse(node);
390          transformationMap_.push_back(std::make_pair(TRANS_ZOOM_AXIS,tmp));
391        }
392      } while (node.goToNextElement()) ;
393      node.goToParentElement();
394    }
395  }
396
397  DEFINE_REF_FUNC(Axis,axis)
398
399   ///---------------------------------------------------------------
400
401} // namespace xios
Note: See TracBrowser for help on using the repository browser.