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

Last change on this file since 1129 was 1129, checked in by mhnguyen, 5 years ago

Updating two-level server.
Each client now can play the role of server: It can forward data to other clients or write data like a server.
Each client must combine all data received from other client(s) before forward them or write them on files

+) Correct some bugs of exchange data_index in domain and axis
+) Reorder some functions in context.cpp to make sure that all necessary attributes are available before computing index
+) Add the mapping index for client to write data.

Test
+) On Curie
+) test_client and test_complete
+) Mode:

  • Only one level: Correct
  • Two levels: Work if using ddt (bug)

+) Only zoom is tested but other transformations should work
+) No reading test

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