source: XIOS/dev/dev_olga/src/node/axis.cpp @ 1099

Last change on this file since 1099 was 1099, checked in by mhnguyen, 7 years ago

Updating 2-level server

+) Make some changes in the way data rebuilt on each level of server
+) Make some changes in the order of functions call during close context to make sure that each server receives the global indexes before calculating index to send to next level
+) Modify some functions to make sure data sent to the correct server pool

Test
+) On Curie
+) Only test_client

  • 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: 43.5 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 "context_server.hpp"
11#include "xios_spl.hpp"
12#include "inverse_axis.hpp"
13#include "zoom_axis.hpp"
14#include "interpolate_axis.hpp"
15#include "server_distribution_description.hpp"
16#include "client_server_mapping_distributed.hpp"
17#include "distribution_client.hpp"
18
19namespace xios {
20
21   /// ////////////////////// Définitions ////////////////////// ///
22
23   CAxis::CAxis(void)
24      : CObjectTemplate<CAxis>()
25      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
26      , isClientAfterTransformationChecked(false)
27      , isDistributed_(false), hasBounds_(false), isCompressible_(false)
28      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
29      , transformationMap_(), hasValue(false), doZoomByIndex_(false)
30   {
31   }
32
33   CAxis::CAxis(const StdString & id)
34      : CObjectTemplate<CAxis>(id)
35      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
36      , isClientAfterTransformationChecked(false)
37      , isDistributed_(false), hasBounds_(false), isCompressible_(false)
38      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
39      , transformationMap_(), hasValue(false), doZoomByIndex_(false)
40   {
41   }
42
43   CAxis::~CAxis(void)
44   { /* Ne rien faire de plus */ }
45
46   std::map<StdString, ETranformationType> CAxis::transformationMapList_ = std::map<StdString, ETranformationType>();
47   bool CAxis::dummyTransformationMapList_ = CAxis::initializeTransformationMap(CAxis::transformationMapList_);
48   bool CAxis::initializeTransformationMap(std::map<StdString, ETranformationType>& m)
49   {
50     m["zoom_axis"] = TRANS_ZOOM_AXIS;
51     m["interpolate_axis"] = TRANS_INTERPOLATE_AXIS;
52     m["inverse_axis"] = TRANS_INVERSE_AXIS;
53     m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_AXIS;
54     m["extract_domain"] = TRANS_EXTRACT_DOMAIN_TO_AXIS;
55   }
56
57   ///---------------------------------------------------------------
58
59   const std::set<StdString> & CAxis::getRelFiles(void) const
60   {
61      return (this->relFiles);
62   }
63
64   bool CAxis::IsWritten(const StdString & filename) const
65   {
66      return (this->relFiles.find(filename) != this->relFiles.end());
67   }
68
69   bool CAxis::isWrittenCompressed(const StdString& filename) const
70   {
71      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
72   }
73
74   bool CAxis::isDistributed(void) const
75   {
76      return isDistributed_;
77   }
78
79   /*!
80    * Test whether the data defined on the axis can be outputted in a compressed way.
81    *
82    * \return true if and only if a mask was defined for this axis
83    */
84   bool CAxis::isCompressible(void) const
85   {
86      return isCompressible_;
87   }
88
89   void CAxis::addRelFile(const StdString & filename)
90   {
91      this->relFiles.insert(filename);
92   }
93
94   void CAxis::addRelFileCompressed(const StdString& filename)
95   {
96      this->relFilesCompressed.insert(filename);
97   }
98
99   //----------------------------------------------------------------
100
101   const std::vector<int>& CAxis::getIndexesToWrite(void) const
102   {
103     return indexesToWrite;
104   }
105
106   /*!
107     Returns the number of indexes written by each server.
108     \return the number of indexes written by each server
109   */
110   int CAxis::getNumberWrittenIndexes() const
111   {
112     return numberWrittenIndexes_;
113   }
114
115   /*!
116     Returns the total number of indexes written by the servers.
117     \return the total number of indexes written by the servers
118   */
119   int CAxis::getTotalNumberWrittenIndexes() const
120   {
121     return totalNumberWrittenIndexes_;
122   }
123
124   /*!
125     Returns the offset of indexes written by each server.
126     \return the offset of indexes written by each server
127   */
128   int CAxis::getOffsetWrittenIndexes() const
129   {
130     return offsetWrittenIndexes_;
131   }
132
133   /*!
134     Returns the start of indexes written by each server.
135     \return the start of indexes written by each server
136   */
137   int CAxis::getStartWriteIndex() const
138   {
139     return start_write_index_;
140   }
141
142   /*!
143     Returns the count of indexes written by each server.
144     \return the count of indexes written by each server
145   */
146   int CAxis::getCountWriteIndex() const
147   {
148     return count_write_index_;
149   }
150
151   /*!
152     Returns the local data written by each server.     
153   */
154   int CAxis::getLocalWriteSize() const
155   {
156     return local_write_size_;
157   }
158
159   /*!
160     Returns the global data written by all server.     
161   */
162   int CAxis::getGlobalWriteSize() const
163   {
164     return global_write_size_;
165   }
166
167   //----------------------------------------------------------------
168
169   /*!
170    * Compute the minimum buffer size required to send the attributes to the server(s).
171    *
172    * \return A map associating the server rank with its minimum buffer size.
173    */
174   std::map<int, StdSize> CAxis::getAttributesBufferSize()
175   {
176//     CContextClient* client = CContext::getCurrent()->client;
177     // For now the assumption is that secondary server pools consist of the same number of procs.
178     // CHANGE the line below if the assumption changes.
179     CContext* context = CContext::getCurrent();
180     CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[0] : context->client;
181
182     std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes();
183
184     bool isNonDistributed = (n == n_glo);
185
186     if (client->isServerLeader())
187     {
188       // size estimation for sendServerAttribut
189       size_t size = 6 * sizeof(size_t);
190       // size estimation for sendNonDistributedValue
191       if (isNonDistributed)
192         size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0));
193       size += CEventClient::headerSize + getId().size() + sizeof(size_t);
194
195       const std::list<int>& ranks = client->getRanksServerLeader();
196       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
197       {
198         if (size > attributesSizes[*itRank])
199           attributesSizes[*itRank] = size;
200       }
201     }
202
203     if (!isNonDistributed)
204     {
205       // size estimation for sendDistributedValue
206       boost::unordered_map<int, vector<size_t> >::const_iterator it, ite = indSrv_.end();
207       for (it = indSrv_.begin(); it != ite; ++it)
208       {
209         size_t sizeIndexEvent = CArray<int,1>::size(it->second.size());
210         if (isCompressible_)
211           sizeIndexEvent += CArray<int,1>::size(indWrittenSrv_[it->first].size());
212
213         size_t sizeValEvent = CArray<double,1>::size(it->second.size());
214         if (hasBounds_)
215           sizeValEvent += CArray<double,2>::size(2 * it->second.size());
216
217         size_t size = CEventClient::headerSize + getId().size() + sizeof(size_t) + std::max(sizeIndexEvent, sizeValEvent);
218         if (size > attributesSizes[it->first])
219           attributesSizes[it->first] = size;
220       }
221     }
222
223     return attributesSizes;
224   }
225
226   //----------------------------------------------------------------
227
228   StdString CAxis::GetName(void)   { return (StdString("axis")); }
229   StdString CAxis::GetDefName(void){ return (CAxis::GetName()); }
230   ENodeType CAxis::GetType(void)   { return (eAxis); }
231
232   //----------------------------------------------------------------
233
234   CAxis* CAxis::createAxis()
235   {
236     CAxis* axis = CAxisGroup::get("axis_definition")->createChild();
237     return axis;
238   }
239
240   void CAxis::fillInValues(const CArray<double,1>& values)
241   {
242     this->value = values;
243   }
244
245   void CAxis::checkAttributes(void)
246   {
247      if (this->n_glo.isEmpty())
248        ERROR("CAxis::checkAttributes(void)",
249              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
250              << "The axis is wrongly defined, attribute 'n_glo' must be specified");
251      StdSize size = this->n_glo.getValue();
252
253      if (!this->index.isEmpty())
254      {
255        if (n.isEmpty()) n = index.numElements();
256
257        // It's not so correct but if begin is not the first value of index
258        // then data on the local axis has user-defined distribution. In this case, begin has no meaning.
259        if (begin.isEmpty()) begin = index(0);         
260      }
261      else 
262      {
263        if (!this->begin.isEmpty())
264        {
265          if (begin < 0 || begin > size - 1)
266            ERROR("CAxis::checkAttributes(void)",
267                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
268                  << "The axis is wrongly defined, attribute 'begin' (" << begin.getValue() << ") must be non-negative and smaller than size-1 (" << size - 1 << ").");
269        }
270        else this->begin.setValue(0);
271
272        if (!this->n.isEmpty())
273        {
274          if (n < 0 || n > size)
275            ERROR("CAxis::checkAttributes(void)",
276                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
277                  << "The axis is wrongly defined, attribute 'n' (" << n.getValue() << ") must be non-negative and smaller than size (" << size << ").");
278        }
279        else this->n.setValue(size);
280
281        {
282          index.resize(n);
283          for (int i = 0; i < n; ++i) index(i) = i+begin;
284        }
285      }
286
287      if (!this->value.isEmpty())
288      {
289        StdSize true_size = value.numElements();
290        if (this->n.getValue() != true_size)
291          ERROR("CAxis::checkAttributes(void)",
292                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
293                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
294        this->hasValue = true;
295      }
296
297      this->checkData();
298      this->checkZoom();
299      this->checkMask();
300      this->checkBounds();
301
302      isDistributed_ = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) ||
303                       (!this->n.isEmpty() && (this->n != this->n_glo));
304   }
305
306   void CAxis::checkData()
307   {
308      if (data_begin.isEmpty()) data_begin.setValue(0);
309
310      if (data_n.isEmpty())
311      {
312        data_n.setValue(n);
313      }
314      else if (data_n.getValue() < 0)
315      {
316        ERROR("CAxis::checkData(void)",
317              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
318              << "The data size should be strictly positive ('data_n' = " << data_n.getValue() << ").");
319      }
320
321      if (data_index.isEmpty())
322      {
323        data_index.resize(data_n);
324        for (int i = 0; i < data_n; ++i) data_index(i) = i;
325      }
326   }
327
328   void CAxis::checkZoom(void)
329   {
330     if (global_zoom_begin.isEmpty()) global_zoom_begin.setValue(0);
331     if (global_zoom_n.isEmpty()) global_zoom_n.setValue(n_glo.getValue());
332     if (zoom_index.isEmpty())
333     {
334       zoom_index.setValue(index.getValue());
335     }
336     if (zoom_n.isEmpty()) zoom_n.setValue(n);
337     if (zoom_begin.isEmpty()) zoom_begin.setValue(begin);
338   }
339
340   void CAxis::checkMask()
341   {
342      if (!mask.isEmpty())
343      {
344         if (mask.extent(0) != n)
345           ERROR("CAxis::checkMask(void)",
346                 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
347                 << "The mask does not have the same size as the local domain." << std::endl
348                 << "Local size is " << n.getValue() << "." << std::endl
349                 << "Mask size is " << mask.extent(0) << ".");
350      }
351      else // (mask.isEmpty())
352      { // If no mask was defined, we create a default one without any masked point.
353         mask.resize(n);
354         for (int i = 0; i < n; ++i)
355         {
356           mask(i) = true;
357         }
358      }
359   }
360
361  void CAxis::checkBounds()
362  {
363    if (!bounds.isEmpty())
364    {
365      if (bounds.extent(0) != 2 || bounds.extent(1) != n)
366        ERROR("CAxis::checkAttributes(void)",
367              << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl
368              << "Axis size is " << n.getValue() << "." << std::endl
369              << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << ".");
370      hasBounds_ = true;
371    }
372    else hasBounds_ = false;
373  }
374
375  void CAxis::checkEligibilityForCompressedOutput()
376  {
377    // We don't check if the mask is valid here, just if a mask has been defined at this point.
378    isCompressible_ = !mask.isEmpty();
379  }
380
381  bool CAxis::dispatchEvent(CEventServer& event)
382   {
383      if (SuperClass::dispatchEvent(event)) return true;
384      else
385      {
386        switch(event.type)
387        {
388           case EVENT_ID_DISTRIBUTION_ATTRIBUTE :
389             recvDistributionAttribute(event);
390             return true;
391             break;
392          //  case EVENT_ID_INDEX:
393          //   recvIndex(event);
394          //   return true;
395          //   break;
396          case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES:
397            recvNonDistributedAttributes(event);
398            return true;
399            break;
400          case EVENT_ID_DISTRIBUTED_ATTRIBUTES:
401            recvDistributedAttributes(event);
402            return true;
403            break;
404           default :
405             ERROR("bool CAxis::dispatchEvent(CEventServer& event)",
406                    << "Unknown Event");
407           return false;
408         }
409      }
410   }
411
412   void CAxis::checkAttributesOnClient()
413   {
414     if (this->areClientAttributesChecked_) return;
415
416     this->checkAttributes();
417
418     this->areClientAttributesChecked_ = true;
419   }
420
421   void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid,
422                                                          CServerDistributionDescription::ServerDistributionType distType)
423   {
424     CContext* context=CContext::getCurrent() ;
425
426     if (this->isClientAfterTransformationChecked) return;
427     if (context->hasClient)
428     {
429       if (index.numElements() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType);
430     }
431
432     this->isClientAfterTransformationChecked = true;
433   }
434
435   // Send all checked attributes to server
436   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
437                                     CServerDistributionDescription::ServerDistributionType distType)
438   {
439     if (!this->areClientAttributesChecked_) checkAttributesOnClient();
440     if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation(globalDim, orderPositionInGrid, distType);
441     CContext* context = CContext::getCurrent();
442
443     if (this->isChecked) return;
444     if (context->hasClient) sendAttributes(globalDim, orderPositionInGrid, distType);   
445
446     this->isChecked = true;
447   }
448
449  void CAxis::sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
450                             CServerDistributionDescription::ServerDistributionType distType)
451  {
452     if (index.numElements() == n_glo.getValue())
453       sendNonDistributedAttributes();
454     else
455     {
456       sendDistributedAttributes();
457       sendDistributionAttribute(globalDim, orderPositionInGrid, distType);
458     }
459  }
460
461  void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid,
462                                     CServerDistributionDescription::ServerDistributionType distType)
463  {
464    CContext* context = CContext::getCurrent();
465
466    // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
467    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
468    for (int p = 0; p < nbSrvPools; ++p)
469    {
470      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
471      int nbServer = client->serverSize;
472      int range, clientSize = client->clientSize;
473      int rank = client->clientRank;
474
475      size_t ni = this->n.getValue();
476      size_t ibegin = this->begin.getValue();
477      size_t global_zoom_end = global_zoom_begin+global_zoom_n-1;
478      size_t nZoomCount = 0;
479      size_t nbIndex = index.numElements();
480
481      if (doZoomByIndex_) 
482      {
483        nZoomCount = zoom_index.numElements();
484      }
485      else
486      {
487        for (size_t idx = 0; idx < nbIndex; ++idx)
488        {
489          globalLocalIndexMap_[index(idx)] = idx;
490          size_t globalIndex = index(idx);
491          if (globalIndex >= global_zoom_begin && globalIndex <= global_zoom_end) ++nZoomCount;
492        }
493      }
494
495
496      CArray<size_t,1> globalIndexAxis(nbIndex);
497      std::vector<size_t> globalAxisZoom(nZoomCount);
498      nZoomCount = 0;
499      if (doZoomByIndex_) 
500      {
501        int nbIndexZoom = zoom_index.numElements();       
502        for (int i = 0; i < nbIndexZoom; ++i)
503        {   
504          globalIndexAxis(i) = zoom_index(i);
505        }
506      }
507      else 
508      {
509        for (size_t idx = 0; idx < nbIndex; ++idx)
510        {
511          size_t globalIndex = index(idx);
512          globalIndexAxis(idx) = globalIndex;
513          if (globalIndex >= global_zoom_begin && globalIndex <= global_zoom_end)
514          {
515            globalAxisZoom[nZoomCount] = globalIndex;
516            ++nZoomCount;
517          }
518        }
519
520        int end       = begin + n -1;       
521        zoom_begin    = global_zoom_begin > begin ? global_zoom_begin : begin;
522        int zoom_end  = global_zoom_end < end ? zoom_end : end;
523        zoom_n        = zoom_end-zoom_begin+1;
524      }
525
526      std::set<int> writtenInd;
527      if (isCompressible_)
528      {
529        for (int idx = 0; idx < data_index.numElements(); ++idx)
530        {
531          int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
532
533          if (ind >= 0 && ind < ni && mask(ind))
534          {
535            ind += ibegin;
536            if (ind >= global_zoom_begin && ind <= global_zoom_end)
537              writtenInd.insert(ind);
538          }
539        }
540      }
541
542      CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer, distType);
543      int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
544      CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
545      if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side*
546      {
547        std::vector<int> nGlobAxis(1);
548        nGlobAxis[0] = n_glo.getValue();
549
550        size_t globalSizeIndex = 1, indexBegin, indexEnd;
551        for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
552        indexBegin = 0;
553        if (globalSizeIndex <= clientSize)
554        {
555          indexBegin = rank%globalSizeIndex;
556          indexEnd = indexBegin;
557        }
558        else
559        {
560          for (int i = 0; i < clientSize; ++i)
561          {
562            range = globalSizeIndex / clientSize;
563            if (i < (globalSizeIndex%clientSize)) ++range;
564            if (i == client->clientRank) break;
565            indexBegin += range;
566          }
567          indexEnd = indexBegin + range - 1;
568        }
569
570        CArray<size_t,1> globalIndex(index.numElements());
571        for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
572          globalIndex(idx) = index(idx);
573
574        CServerDistributionDescription serverDescription(nGlobAxis, nbServer);
575        serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd));
576        CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
577        clientServerMap->computeServerIndexMapping(globalIndex);
578        globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
579        delete clientServerMap;
580      }
581      else
582      {
583        std::vector<size_t> globalIndexServer(n_glo.getValue());
584        for (size_t idx = 0; idx < n_glo.getValue(); ++idx)
585        {
586          globalIndexServer[idx] = idx;
587        }
588
589        for (int idx = 0; idx < nbServer; ++idx)
590        {
591          globalIndexAxisOnServer[idx] = globalIndexServer;
592        }
593      }
594
595      indSrv_.swap(globalIndexAxisOnServer);
596
597      // CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
598      //                                                      ite = globalIndexAxisOnServer.end();
599      CClientServerMapping::GlobalIndexMap::const_iterator it = indSrv_.begin(),
600                                                           ite = indSrv_.end();
601      // std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
602      //                                     iteVec = (globalAxisZoom).end();
603      // indSrv_.clear();
604      // indWrittenSrv_.clear();
605      // for (; it != ite; ++it)
606      // {
607      //   int rank = it->first;
608      //   const std::vector<size_t>& globalIndexTmp = it->second;
609      //   int nb = globalIndexTmp.size();
610
611      //   for (int i = 0; i < nb; ++i)
612      //   {
613      //     if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
614      //     {
615      //       indSrv_[rank].push_back(globalIndexTmp[i]);
616      //     }
617
618      //     if (writtenInd.count(globalIndexTmp[i]))
619      //     {
620      //       indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
621      //     }
622      //   }
623      // }
624
625      connectedServerRank_.clear();
626      for (it = indSrv_.begin(); it != ite; ++it) {
627        connectedServerRank_.push_back(it->first);
628      }
629
630      // if (!indSrv_.empty())
631      // {
632      //   std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
633      //                                                  iteIndSrv = indSrv_.end();
634      //   connectedServerRank_.clear();
635      //   for (; itIndSrv != iteIndSrv; ++itIndSrv)
636      //     connectedServerRank_.push_back(itIndSrv->first);
637      // }
638      nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
639    }
640  }
641
642
643  void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid,
644                                        CServerDistributionDescription::ServerDistributionType distType)
645  {
646    CContext* context = CContext::getCurrent();
647
648    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;
649    for (int i = 0; i < nbSrvPools; ++i)
650    {
651      CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i]
652                                                                         : context->client;
653      int nbServer = contextClientTmp->serverSize;
654
655      CServerDistributionDescription serverDescription(globalDim, nbServer);
656      serverDescription.computeServerDistribution();
657
658      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
659      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
660
661      globalDimGrid.resize(globalDim.size());
662      for (int idx = 0; idx < globalDim.size(); ++idx) globalDimGrid(idx) = globalDim[idx];
663
664      CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE);
665      if (contextClientTmp->isServerLeader())
666      {
667        std::list<CMessage> msgs;
668
669        const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
670        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
671        {
672          // Use const int to ensure CMessage holds a copy of the value instead of just a reference
673          const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
674          const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
675          const int end   = begin + ni - 1;
676
677          msgs.push_back(CMessage());
678          CMessage& msg = msgs.back();
679          msg << this->getId();
680          msg << ni << begin << end;
681          msg << global_zoom_begin.getValue() << global_zoom_n.getValue();
682          msg << isCompressible_;
683          msg << orderPositionInGrid;
684          msg << globalDimGrid;
685
686          event.push(*itRank,1,msg);
687        }
688        contextClientTmp->sendEvent(event);
689      }
690      else contextClientTmp->sendEvent(event);
691    }
692  }
693
694  // void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid,
695  //                                    CServerDistributionDescription::ServerDistributionType distType)
696  // {
697  //   CContext* context = CContext::getCurrent();
698  //   CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
699  //   int nbServer = client->serverSize;
700  //   int range, clientSize = client->clientSize;
701  //   int rank = client->clientRank;
702
703  //   size_t ni = this->n.getValue();
704  //   size_t ibegin = this->begin.getValue();
705  //   size_t zoom_end = global_zoom_begin+global_zoom_n-1;
706  //   size_t nZoomCount = 0;
707  //   size_t nbIndex = index.numElements();
708  //   for (size_t idx = 0; idx < nbIndex; ++idx)
709  //   {
710  //     size_t globalIndex = index(idx);
711  //     if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount;
712  //   }
713
714  //   CArray<size_t,1> globalIndexAxis(nbIndex);
715  //   std::vector<size_t> globalAxisZoom(nZoomCount);
716  //   nZoomCount = 0;
717  //   for (size_t idx = 0; idx < nbIndex; ++idx)
718  //   {
719  //     size_t globalIndex = index(idx);
720  //     globalIndexAxis(idx) = globalIndex;
721  //     if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
722  //     {
723  //       globalAxisZoom[nZoomCount] = globalIndex;
724  //       ++nZoomCount;
725  //     }
726  //   }
727
728  //   std::set<int> writtenInd;
729  //   if (isCompressible_)
730  //   {
731  //     for (int idx = 0; idx < data_index.numElements(); ++idx)
732  //     {
733  //       int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
734
735  //       if (ind >= 0 && ind < ni && mask(ind))
736  //       {
737  //         ind += ibegin;
738  //         if (ind >= global_zoom_begin && ind <= zoom_end)
739  //           writtenInd.insert(ind);
740  //       }
741  //     }
742  //   }
743
744  //   CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer);
745  //   int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
746  //   CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
747  //   if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side*
748  //   {
749  //     std::vector<int> nGlobAxis(1);
750  //     nGlobAxis[0] = n_glo.getValue();
751
752  //     size_t globalSizeIndex = 1, indexBegin, indexEnd;
753  //     for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
754  //     indexBegin = 0;
755  //     if (globalSizeIndex <= clientSize)
756  //     {
757  //       indexBegin = rank%globalSizeIndex;
758  //       indexEnd = indexBegin;
759  //     }
760  //     else
761  //     {
762  //       for (int i = 0; i < clientSize; ++i)
763  //       {
764  //         range = globalSizeIndex / clientSize;
765  //         if (i < (globalSizeIndex%clientSize)) ++range;
766  //         if (i == client->clientRank) break;
767  //         indexBegin += range;
768  //       }
769  //       indexEnd = indexBegin + range - 1;
770  //     }
771
772  //     CServerDistributionDescription serverDescription(nGlobAxis, nbServer);
773  //     serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd));
774  //     CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
775  //     clientServerMap->computeServerIndexMapping(globalIndexAxis);
776  //     globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
777  //     delete clientServerMap;
778  //   }
779  //   else
780  //   {
781  //     std::vector<size_t> globalIndexServer(n_glo.getValue());
782  //     for (size_t idx = 0; idx < n_glo.getValue(); ++idx)
783  //     {
784  //       globalIndexServer[idx] = idx;
785  //     }
786
787  //     for (int idx = 0; idx < nbServer; ++idx)
788  //     {
789  //       globalIndexAxisOnServer[idx] = globalIndexServer;
790  //     }
791  //   }
792
793  //   CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
794  //                                                        ite = globalIndexAxisOnServer.end();
795  //   std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
796  //                                       iteVec = (globalAxisZoom).end();
797  //   indSrv_.clear();
798  //   indWrittenSrv_.clear();
799  //   for (; it != ite; ++it)
800  //   {
801  //     int rank = it->first;
802  //     const std::vector<size_t>& globalIndexTmp = it->second;
803  //     int nb = globalIndexTmp.size();
804
805  //     for (int i = 0; i < nb; ++i)
806  //     {
807  //       if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
808  //       {
809  //         indSrv_[rank].push_back(globalIndexTmp[i]);
810  //       }
811
812  //       if (writtenInd.count(globalIndexTmp[i]))
813  //       {
814  //         indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
815  //       }
816  //     }
817  //   }
818
819  //   connectedServerRank_.clear();
820  //   for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) {
821  //     connectedServerRank_.push_back(it->first);
822  //   }
823
824  //   if (!indSrv_.empty())
825  //   {
826  //     std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
827  //                                                    iteIndSrv = indSrv_.end();
828  //     connectedServerRank_.clear();
829  //     for (; itIndSrv != iteIndSrv; ++itIndSrv)
830  //       connectedServerRank_.push_back(itIndSrv->first);
831  //   }
832  //   nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
833  // }
834
835  void CAxis::sendNonDistributedAttributes()
836  {
837    CContext* context = CContext::getCurrent();
838
839    // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
840    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
841    for (int p = 0; p < nbSrvPools; ++p)
842    {
843      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
844
845      CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES);
846      size_t nbIndex = index.numElements();
847      size_t nbDataIndex = 0;
848
849      for (int idx = 0; idx < data_index.numElements(); ++idx)
850      {
851        int ind = data_index(idx);
852        if (ind >= 0 && ind < nbIndex) ++nbDataIndex;
853      }
854
855      CArray<int,1> dataIndex(nbDataIndex);
856      nbDataIndex = 0;
857      for (int idx = 0; idx < data_index.numElements(); ++idx)
858      {
859        int ind = data_index(idx);
860        if (ind >= 0 && ind < nbIndex)
861        {
862          dataIndex(nbDataIndex) = ind;
863          ++nbDataIndex;
864        }
865      }
866
867      if (client->isServerLeader())
868      {
869        std::list<CMessage> msgs;
870
871        const std::list<int>& ranks = client->getRanksServerLeader();
872        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
873        {
874          msgs.push_back(CMessage());
875          CMessage& msg = msgs.back();
876          msg << this->getId();
877          msg << index.getValue() << dataIndex << zoom_index.getValue() << mask.getValue();
878          msg << hasValue;
879          if (hasValue) msg << value.getValue();
880
881          msg << hasBounds_;
882          if (hasBounds_) msg << bounds.getValue();
883
884          event.push(*itRank, 1, msg);
885        }
886        client->sendEvent(event);
887      }
888      else client->sendEvent(event);
889    }
890  }
891
892  void CAxis::recvNonDistributedAttributes(CEventServer& event)
893  {
894    list<CEventServer::SSubEvent>::iterator it;
895    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
896    {
897      CBufferIn* buffer = it->buffer;
898      string axisId;
899      *buffer >> axisId;
900      get(axisId)->recvNonDistributedAttributes(it->rank, *buffer);
901    }
902  }
903
904  void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer)
905  { 
906    CArray<int,1> tmp_index, tmp_data_index, tmp_zoom_index;
907    CArray<bool,1> tmp_mask;
908    CArray<double,1> tmp_val;
909    CArray<double,2> tmp_bnds;
910
911    buffer >> tmp_index;
912    index.reference(tmp_index);
913    buffer >> tmp_data_index;
914    data_index.reference(tmp_data_index);
915    buffer >> tmp_zoom_index;
916    zoom_index.reference(tmp_zoom_index);
917    buffer >> tmp_mask;
918    mask.reference(tmp_mask);
919    buffer >> hasValue;
920    if (hasValue)
921    {
922      buffer >> tmp_val;
923      value.reference(tmp_val);
924    }
925
926    buffer >> hasBounds_;
927    if (hasBounds_)
928    {
929      buffer >> tmp_bnds;
930      bounds.reference(tmp_bnds);
931    }
932
933    {     
934      count_write_index_ = zoom_index.numElements();           
935      start_write_index_ = 0;
936      local_write_size_ = count_write_index_;
937      global_write_size_ = count_write_index_;
938    }
939  }
940
941  void CAxis::sendDistributedAttributes(void)
942  {
943    int ns, n, i, j, ind, nv, idx;
944    CContext* context = CContext::getCurrent();
945
946    //int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
947    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
948    for (int p = 0; p < nbSrvPools; ++p)
949    {
950      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
951
952      CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES);
953
954      list<CMessage> listData;
955      list<CArray<int,1> > list_indi, list_dataInd, list_zoomInd;
956      list<CArray<bool,1> > list_mask;
957      list<CArray<double,1> > list_val;
958      list<CArray<double,2> > list_bounds;
959
960      int nbIndex = index.numElements();
961      CArray<int,1> dataIndex(nbIndex);
962      dataIndex = -1;
963      for (int inx = 0; inx < data_index.numElements(); ++inx)
964      {
965        if (0 <= data_index(inx) && data_index(inx) < nbIndex)
966          dataIndex(inx) = data_index(inx);
967      }
968
969      boost::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap;
970      iteMap = indSrv_.end();
971      for (int k = 0; k < connectedServerRank_.size(); ++k)
972      {
973        int nbData = 0;
974        int rank = connectedServerRank_[k];
975        int nbSendingClient = nbConnectedClients_[rank];
976        it = indSrv_.find(rank);
977        if (iteMap != it)
978          nbData = it->second.size();
979
980        list_indi.push_back(CArray<int,1>(nbData));
981        list_dataInd.push_back(CArray<int,1>(nbData));       
982        list_mask.push_back(CArray<bool,1>(nbData));
983
984        if (doZoomByIndex_)
985          list_zoomInd.push_back(CArray<int,1>(nbData));
986
987        if (hasValue)
988          list_val.push_back(CArray<double,1>(nbData));
989
990        if (hasBounds_)
991        {
992          list_bounds.push_back(CArray<double,2>(2,nbData));
993        }
994
995        CArray<int,1>& indi = list_indi.back();
996        CArray<int,1>& dataIndi = list_dataInd.back();       
997        CArray<bool,1>& maskIndi = list_mask.back();
998
999        for (n = 0; n < nbData; ++n)
1000        {
1001          idx = static_cast<int>(it->second[n]);
1002          indi(n) = idx;
1003
1004          ind = globalLocalIndexMap_[idx];
1005          dataIndi(n) = dataIndex(ind);
1006          maskIndi(n) = mask(ind);
1007
1008          if (doZoomByIndex_)
1009          {
1010            CArray<int,1>& zoomIndi = list_zoomInd.back();
1011            zoomIndi(n) = zoom_index(ind);
1012          }
1013
1014          if (hasValue)
1015          {
1016            CArray<double,1>& val = list_val.back();
1017            val(n) = value(ind);
1018          }
1019
1020          if (hasBounds_)
1021          {
1022            CArray<double,2>& boundsVal = list_bounds.back();
1023            boundsVal(0, n) = bounds(0,n);
1024            boundsVal(1, n) = bounds(1,n);
1025          }
1026        }
1027
1028        listData.push_back(CMessage());
1029        listData.back() << this->getId()
1030                        << list_indi.back() << list_dataInd.back() << list_mask.back();
1031
1032        listData.back() << doZoomByIndex_;           
1033        if (doZoomByIndex_)
1034          listData.back() << list_zoomInd.back();
1035
1036        listData.back() << hasValue;
1037        if (hasValue)
1038          listData.back() << list_val.back();
1039
1040        listData.back() << hasBounds_;
1041        if (hasBounds_)
1042          listData.back() << list_bounds.back();
1043
1044        eventData.push(rank, nbConnectedClients_[rank], listData.back());
1045      }
1046
1047      client->sendEvent(eventData);
1048    }
1049  }
1050
1051  void CAxis::recvDistributedAttributes(CEventServer& event)
1052  {
1053    string axisId;
1054    vector<int> ranks;
1055    vector<CBufferIn*> buffers;
1056
1057    list<CEventServer::SSubEvent>::iterator it;
1058    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1059    {
1060      ranks.push_back(it->rank);
1061      CBufferIn* buffer = it->buffer;
1062      *buffer >> axisId;
1063      buffers.push_back(buffer);
1064    }
1065    get(axisId)->recvDistributedAttributes(ranks, buffers);
1066  }
1067
1068  void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers)
1069  {
1070    int nbReceived = ranks.size();
1071    vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived), vec_zoomInd(nbReceived);   
1072    vector<CArray<bool,1> > vec_mask(nbReceived);
1073    vector<CArray<double,1> > vec_val(nbReceived);
1074    vector<CArray<double,2> > vec_bounds(nbReceived);
1075   
1076    for (int idx = 0; idx < nbReceived; ++idx)
1077    {     
1078      CBufferIn& buffer = *buffers[idx];
1079      buffer >> vec_indi[idx];
1080      buffer >> vec_dataInd[idx];     
1081      buffer >> vec_mask[idx];
1082
1083      buffer >> doZoomByIndex_;
1084      if (doZoomByIndex_)
1085        buffer >> vec_zoomInd[idx];
1086
1087      buffer >> hasValue;
1088      if (hasValue)
1089        buffer >> vec_val[idx];
1090
1091      buffer >> hasBounds_;
1092      if (hasBounds_)
1093        buffer >> vec_bounds[idx];
1094    }
1095
1096    int nbData = 0;
1097    for (int idx = 0; idx < nbReceived; ++idx)
1098    {
1099      nbData += vec_indi[idx].numElements();
1100    }
1101   
1102    index.resize(nbData);
1103    CArray<int,1> nonCompressedData(nbData);   
1104    mask.resize(nbData);
1105    if (hasValue)
1106      value.resize(nbData);
1107    if (hasBounds_)
1108      bounds.resize(2,nbData);
1109
1110    nbData = 0;
1111    for (int idx = 0; idx < nbReceived; ++idx)
1112    {
1113      CArray<int,1>& indi = vec_indi[idx];
1114      CArray<int,1>& dataIndi = vec_dataInd[idx];
1115      CArray<bool,1>& maskIndi = vec_mask[idx];
1116      int nb = indi.numElements();
1117      for (int n = 0; n < nb; ++n)
1118      {
1119        index(nbData) = indi(n);
1120        nonCompressedData(nbData) = (0 <= dataIndi(n)) ? nbData : -1;
1121        mask(nbData) = maskIndi(n);
1122        if (hasValue)
1123          value(nbData) = vec_val[idx](n);
1124        if (hasBounds_)
1125        {
1126          bounds(0,nbData) = vec_bounds[idx](0,n);
1127          bounds(1,nbData) = vec_bounds[idx](1,n);
1128        }
1129        ++nbData;
1130      }
1131    }
1132
1133    int nbIndex = index.numElements();
1134    int nbCompressedData = 0; 
1135    for (int idx = 0; idx < nonCompressedData.numElements(); ++idx)
1136    {
1137      if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex)
1138        ++nbCompressedData;       
1139    }
1140
1141    data_index.resize(nbCompressedData);
1142    nbCompressedData = 0;
1143    for (int idx = 0; idx < nonCompressedData.numElements(); ++idx)
1144    {
1145      if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex)
1146      {
1147        data_index(nbCompressedData) = nonCompressedData(idx);
1148        ++nbCompressedData;       
1149      }
1150    }
1151
1152    if (doZoomByIndex_)
1153    {
1154      int nbZoomIndex = 0;
1155      for (int idx = 0; idx < nbReceived; ++idx)
1156      {
1157        nbZoomIndex += vec_zoomInd[idx].numElements();
1158      }
1159
1160      zoom_index.resize(nbZoomIndex);
1161      nbZoomIndex = 0;     
1162      for (int idx = 0; idx < nbReceived; ++idx)
1163      {     
1164        CArray<int,1>& tmp = vec_zoomInd[idx];
1165        for (int i = 0; i < tmp.size(); ++i)
1166        {
1167          zoom_index(nbZoomIndex) = tmp(i);
1168          ++nbZoomIndex;
1169        }       
1170      }
1171    }
1172
1173
1174    // {
1175    //   CContextServer* server = CContext::getCurrent()->server;
1176    //   count_write_index_ = zoom_index.numElements();     
1177    //   MPI_Scan(&count_write_index_, &start_write_index_, 1, MPI_INT, MPI_SUM, server->intraComm);
1178    //   global_write_size_ = start_write_index_;
1179    //   start_write_index_ -= count_write_index_;
1180    //   local_write_size_ = count_write_index_;     
1181    // }
1182  }
1183
1184  void CAxis::recvDistributionAttribute(CEventServer& event)
1185  {
1186    CBufferIn* buffer = event.subEvents.begin()->buffer;
1187    string axisId;
1188    *buffer >> axisId;
1189    get(axisId)->recvDistributionAttribute(*buffer);
1190  }
1191
1192  void CAxis::recvDistributionAttribute(CBufferIn& buffer)
1193  {
1194    int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_n_tmp;
1195
1196    buffer >> ni_srv >> begin_srv >> end_srv;
1197    buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp;
1198    buffer >> isCompressible_;
1199    buffer >> orderPosInGrid;
1200    buffer >> globalDimGrid;
1201
1202    n.setValue(ni_srv);
1203    begin.setValue(begin_srv);
1204    global_zoom_begin = global_zoom_begin_tmp;
1205    global_zoom_n  = global_zoom_n_tmp;
1206    int global_zoom_end = global_zoom_begin + global_zoom_n - 1;
1207
1208    zoom_begin = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
1209    zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
1210    zoom_n  = zoom_end_srv - zoom_begin_srv + 1;
1211
1212    if (zoom_n<=0)
1213    {
1214      zoom_begin = 0; zoom_end_srv = 0; zoom_n = 0;
1215    }
1216
1217    if (n_glo == n)
1218    {
1219      zoom_begin = global_zoom_begin;
1220      zoom_end_srv   = global_zoom_end; //zoom_end;
1221      zoom_n     = zoom_end_srv - zoom_begin + 1;
1222    }
1223  }
1224
1225
1226  CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id)
1227  {
1228    transformationMap_.push_back(std::make_pair(transType, CTransformation<CAxis>::createTransformation(transType,id)));
1229    return transformationMap_.back().second;
1230  }
1231
1232  bool CAxis::hasTransformation()
1233  {
1234    return (!transformationMap_.empty());
1235  }
1236
1237  void CAxis::setTransformations(const TransMapTypes& axisTrans)
1238  {
1239    transformationMap_ = axisTrans;
1240  }
1241
1242  CAxis::TransMapTypes CAxis::getAllTransformations(void)
1243  {
1244    return transformationMap_;
1245  }
1246
1247  void CAxis::duplicateTransformation(CAxis* src)
1248  {
1249    if (src->hasTransformation())
1250    {
1251      this->setTransformations(src->getAllTransformations());
1252    }
1253  }
1254
1255  /*!
1256   * Go through the hierarchy to find the axis from which the transformations must be inherited
1257   */
1258  void CAxis::solveInheritanceTransformation()
1259  {
1260    if (hasTransformation() || !hasDirectAxisReference())
1261      return;
1262
1263    CAxis* axis = this;
1264    std::vector<CAxis*> refAxis;
1265    while (!axis->hasTransformation() && axis->hasDirectAxisReference())
1266    {
1267      refAxis.push_back(axis);
1268      axis = axis->getDirectAxisReference();
1269    }
1270
1271    if (axis->hasTransformation())
1272      for (size_t i = 0; i < refAxis.size(); ++i)
1273        refAxis[i]->setTransformations(axis->getAllTransformations());
1274  }
1275
1276  void CAxis::parse(xml::CXMLNode & node)
1277  {
1278    SuperClass::parse(node);
1279
1280    if (node.goToChildElement())
1281    {
1282      StdString nodeElementName;
1283      do
1284      {
1285        StdString nodeId("");
1286        if (node.getAttributes().end() != node.getAttributes().find("id"))
1287        { nodeId = node.getAttributes()["id"]; }
1288
1289        nodeElementName = node.getElementName();
1290        std::map<StdString, ETranformationType>::const_iterator ite = transformationMapList_.end(), it;
1291        it = transformationMapList_.find(nodeElementName);
1292        if (ite != it)
1293        {
1294          transformationMap_.push_back(std::make_pair(it->second, CTransformation<CAxis>::createTransformation(it->second,
1295                                                                                                               nodeId,
1296                                                                                                               &node)));
1297        }
1298        else
1299        {
1300          ERROR("void CAxis::parse(xml::CXMLNode & node)",
1301                << "The transformation " << nodeElementName << " has not been supported yet.");
1302        }
1303      } while (node.goToNextElement()) ;
1304      node.goToParentElement();
1305    }
1306  }
1307
1308  DEFINE_REF_FUNC(Axis,axis)
1309
1310   ///---------------------------------------------------------------
1311
1312} // namespace xios
Note: See TracBrowser for help on using the repository browser.