Index: XIOS/trunk/inputs/Version2/iodef.xml
===================================================================
--- XIOS/trunk/inputs/Version2/iodef.xml	(revision 622)
+++ XIOS/trunk/inputs/Version2/iodef.xml	(revision 623)
@@ -43,9 +43,10 @@
      <axis id="axis_E" axis_ref="axis_B">
         <inverse_axis />
-        <inverse_axis />
-<!--        <zoom_axis zoom_begin="1" zoom_size="3" />-->
+
+        <zoom_axis zoom_begin="0" zoom_size="4" />
+<!--        <inverse_axis />-->
      </axis>
      <axis id="axis_F" axis_ref="axis_A">
-       <inverse_axis />
+<!--       <inverse_axis />-->
      </axis>
    </axis_definition>
@@ -63,4 +64,5 @@
        <grid id="grid_Axis">
          <axis axis_ref="axis_D" />
+
        </grid>
        <grid id="grid_Two_Axis">
@@ -70,8 +72,6 @@
        <grid id="grid_Axis_tranformed">
 <!--         <domain domain_ref="domain_A" />-->
-<!--         <axis axis_ref="axis_E" />-->
          <axis axis_ref="axis_F" />
          <axis axis_ref="axis_E" />
-
        </grid>
        <grid id="grid_All_Axis">
Index: XIOS/trunk/src/attribute_map.cpp
===================================================================
--- XIOS/trunk/src/attribute_map.cpp	(revision 622)
+++ XIOS/trunk/src/attribute_map.cpp	(revision 623)
@@ -144,4 +144,22 @@
       }
 
+      void CAttributeMap::duplicateAttributes(const CAttributeMap* const srcAttr)
+      {
+         typedef std::pair<StdString, CAttribute*> StdStrAttPair;
+
+         SuperClassMap::const_iterator it = srcAttr->begin(), end = srcAttr->end();
+         for (; it != end; it++)
+         {
+            const StdStrAttPair& el = *it;
+            if (this->hasAttribute(el.first))
+            {
+               if (!el.second->isEmpty())
+               {
+                 this->setAttribute(el.first, el.second);
+               }
+            }
+         }
+      }
+
       //---------------------------------------------------------------
 /*
Index: XIOS/trunk/src/attribute_map.hpp
===================================================================
--- XIOS/trunk/src/attribute_map.hpp	(revision 622)
+++ XIOS/trunk/src/attribute_map.hpp	(revision 623)
@@ -30,5 +30,5 @@
             void setAttributes(const xml::THashAttributes & attributes);
             void setAttributes(const CAttributeMap * const _parent, bool apply=true);
-
+            void duplicateAttributes(const CAttributeMap* const _parent);
             void clearAllAttributes(void);
 
Index: XIOS/trunk/src/client_server_mapping_distributed.cpp
===================================================================
--- XIOS/trunk/src/client_server_mapping_distributed.cpp	(revision 622)
+++ XIOS/trunk/src/client_server_mapping_distributed.cpp	(revision 623)
@@ -37,6 +37,4 @@
    \param [in] localIndexOnClient local index on client
 */
-//void CClientServerMappingDistributed::computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
-//                                                                const CArray<int,1>& localIndexOnClient)
 void CClientServerMappingDistributed::computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient)
 {
@@ -180,6 +178,6 @@
   }
 
-  if (0 != recvBuffIndexGlobal) delete recvBuffIndexGlobal;
-  if (0 != recvBuffIndexServer) delete recvBuffIndexServer;
+  if (0 != maxNbIndexDemandedFromOthers) delete [] recvBuffIndexGlobal;
+  if (0 != nbIndexReceivedFromOthers) delete [] recvBuffIndexServer;
   delete [] sendBuff;
   delete [] recvBuff;
Index: XIOS/trunk/src/distribution_client.cpp
===================================================================
--- XIOS/trunk/src/distribution_client.cpp	(revision 622)
+++ XIOS/trunk/src/distribution_client.cpp	(revision 623)
@@ -13,9 +13,10 @@
 CDistributionClient::CDistributionClient(int rank, int dims, CArray<size_t,1>* globalIndex)
    : CDistribution(rank, dims, globalIndex),
-   localDataIndex_(0), axisDomainOrder_(),
+   globalDataSendToServer_(0), localDataIndex_(0), localDataIndexSendToServer_(0), localMaskIndex_(0),
+   axisDomainOrder_(),
    nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_(),nZoomBegin_(), nZoomEnd_(),
    dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_(),
    gridMask_(), localDomainIndex_(), localAxisIndex_(), indexMap_(), indexDomainData_(), indexAxisData_(),
-   isDataDistributed_(true), axisNum_(0), domainNum_(0), localDataIndexSendToServer_(0), nIndexDomain_(), nIndexAxis_()
+   isDataDistributed_(true), axisNum_(0), domainNum_(0), nIndexDomain_(), nIndexAxis_()
 {
 }
@@ -23,9 +24,10 @@
 CDistributionClient::CDistributionClient(int rank, CGrid* grid)
    : CDistribution(rank, 0, 0),
-   localDataIndex_(0), axisDomainOrder_(),
+   globalDataSendToServer_(0), localDataIndex_(0), localDataIndexSendToServer_(0), localMaskIndex_(0),
+   axisDomainOrder_(),
    nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_(),nZoomBegin_(), nZoomEnd_(),
    dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_(),
    gridMask_(), localDomainIndex_(), localAxisIndex_(), indexMap_(), indexDomainData_(), indexAxisData_(),
-   isDataDistributed_(true), axisNum_(0), domainNum_(0), localDataIndexSendToServer_(0), nIndexDomain_(), nIndexAxis_()
+   isDataDistributed_(true), axisNum_(0), domainNum_(0), nIndexDomain_(), nIndexAxis_()
 {
   readDistributionInfo(grid);
@@ -39,4 +41,5 @@
   if (0 != localDataIndex_) delete localDataIndex_;
   if (0 != localDataIndexSendToServer_) delete localDataIndexSendToServer_;
+  if (0 != localMaskIndex_) delete localMaskIndex_;
 }
 
@@ -145,4 +148,5 @@
     axisMasks_[i].resize(axisList[i]->mask.numElements());
     axisMasks_[i] = axisList[i]->mask;
+    std::cout << "axisMask " << axisMasks_[i] << std::endl;
   }
 
@@ -197,6 +201,6 @@
       nBeginLocal_.at(indexMap_[idx]+1) = 0;
       nBeginGlobal_.at(indexMap_[idx]+1) = domList[domIndex]->jbegin;
-      nZoomBegin_.at((indexMap_[idx]+1)) = domList[domIndex]->zoom_jbegin;
-      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->zoom_jbegin + domList[domIndex]->zoom_nj-1;
+//      nZoomBegin_.at((indexMap_[idx]+1)) = domList[domIndex]->zoom_jbegin;
+//      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->zoom_jbegin + domList[domIndex]->zoom_nj-1;
 
       dataBegin_.at(indexMap_[idx]+1) = (2 == domList[domIndex]->data_dim) ? domList[domIndex]->data_jbegin.getValue() : -1;
@@ -209,6 +213,6 @@
       nBeginLocal_.at(indexMap_[idx]) = 0;
       nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
-      nZoomBegin_.at((indexMap_[idx])) = domList[domIndex]->zoom_ibegin;
-      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->zoom_ibegin + domList[domIndex]->zoom_ni-1;
+//      nZoomBegin_.at((indexMap_[idx])) = domList[domIndex]->zoom_ibegin;
+//      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->zoom_ibegin + domList[domIndex]->zoom_ni-1;
 
       dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
@@ -229,6 +233,6 @@
       nBeginLocal_.at(indexMap_[idx]) = 0;
       nBeginGlobal_.at(indexMap_[idx]) = axisList[axisIndex]->ibegin.getValue();
-      nZoomBegin_.at((indexMap_[idx])) = axisList[axisIndex]->zoom_begin;
-      nZoomEnd_.at((indexMap_[idx])) = axisList[axisIndex]->zoom_begin + axisList[axisIndex]->zoom_size-1;
+      nZoomBegin_.at((indexMap_[idx])) = axisList[axisIndex]->global_zoom_begin;
+      nZoomEnd_.at((indexMap_[idx])) = axisList[axisIndex]->global_zoom_begin + axisList[axisIndex]->global_zoom_size-1;
 
       dataBegin_.at(indexMap_[idx]) = axisList[axisIndex]->data_begin.getValue();
@@ -393,6 +397,6 @@
 
   //   Compute size of the global index on client
-  std::vector<int> idxLoop(numElement_,0);
-  std::vector<int> currentIndex(this->dims_);
+  std::vector<StdSize> idxLoop(numElement_,0);
+  std::vector<StdSize> currentIndex(this->dims_,0);
   int innerLoopSize = eachElementSize[0];
   size_t idx = 0, indexLocalDataOnClientCount = 0, indexSend2ServerCount = 0;
@@ -445,5 +449,5 @@
       else currentIndex[0]   = localAxisIndex_[idxAxis][i];
 
-      int gridMaskIndex = currentIndex[0];
+      StdSize gridMaskIndex = currentIndex[0];
       int mulDimMask = 1;
       for (int k = 1; k < this->dims_; ++k)
@@ -473,4 +477,5 @@
   localDataIndex_ = new CArray<int,1>(indexLocalDataOnClientCount);
   localDataIndexSendToServer_ = new CArray<int,1>(indexSend2ServerCount);
+  localMaskIndex_ = new CArray<int,1>(indexSend2ServerCount);
 
   // We need to loop with data index
@@ -481,4 +486,5 @@
   int countLocalData = 0;
   std::vector<int> correctOuterIndex(numElement_,0);
+  bool isOuterIndexCorrect = true;
   while (idx < ssize)
   {
@@ -490,5 +496,5 @@
         correctOuterIndex[i] = 0;
         ++idxLoop[i+1];
-        ++correctOuterIndex[i+1];
+        if (isOuterIndexCorrect) ++correctOuterIndex[i+1];
       }
     }
@@ -510,4 +516,5 @@
           currentIndex[indexMap_[i]]   = localDomainIndex_[idxDomain][correctOuterIndex[i]];
           currentIndex[indexMap_[i]+1] = localDomainIndex_[idxDomain*2+1][correctOuterIndex[i]];
+          isIndexDomainDataCorrect &= true;
         }
         else isIndexDomainDataCorrect = false;
@@ -519,4 +526,5 @@
         {
           currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][correctOuterIndex[i]];
+          isIndexAxisDataCorrect &= true;
         }
         else isIndexAxisDataCorrect = false;
@@ -524,4 +532,6 @@
       }
     }
+
+    isOuterIndexCorrect = (isIndexAxisDataCorrect) && (isIndexDomainDataCorrect);
 
     // Inner most index
@@ -530,4 +540,7 @@
     for (int i = 0; i < innerLoopSize; ++i)
     {
+      bool isCurrentIndexDomainDataCorrect = isIndexDomainDataCorrect;
+      bool isCurrentIndexAxisDataCorrect = isIndexAxisDataCorrect;
+
       if (axisDomainOrder_(0))
       {
@@ -536,8 +549,8 @@
           currentIndex[0] = localDomainIndex_[idxDomain][correctIndexDomain];
           currentIndex[1] = localDomainIndex_[idxDomain+1][correctIndexDomain];
-          isIndexDomainDataCorrect = true;
+          isCurrentIndexDomainDataCorrect &= true;
           ++correctIndexDomain;
         }
-        else isIndexDomainDataCorrect = false;
+        else isCurrentIndexDomainDataCorrect = false;
       }
       else
@@ -546,8 +559,8 @@
         {
           currentIndex[0] = localAxisIndex_[idxAxis][correctIndexAxis];
-          isIndexAxisDataCorrect = true;
+          isCurrentIndexAxisDataCorrect &= true;
           ++correctIndexAxis;
         }
-        else isIndexAxisDataCorrect = false;
+        else isCurrentIndexAxisDataCorrect = false;
       }
 
@@ -560,6 +573,6 @@
       }
 
-      if (isIndexDomainDataCorrect &&
-          isIndexAxisDataCorrect &&
+      if (isCurrentIndexDomainDataCorrect &&
+          isCurrentIndexAxisDataCorrect &&
           gridMask_(gridMaskIndex))
       {
@@ -582,4 +595,5 @@
           (*this->globalDataSendToServer_)(indexSend2ServerCount) = globalIndex;
           (*localDataIndexSendToServer_)(indexSend2ServerCount) = indexLocalDataOnClientCount;
+          (*localMaskIndex_)(indexSend2ServerCount) = gridMaskIndex;
           ++indexSend2ServerCount;
         }
@@ -649,4 +663,12 @@
 
 /*!
+  Return local mask index of client
+*/
+const CArray<int,1>& CDistributionClient::getLocalMaskIndexOnClient() const
+{
+  return (*localMaskIndex_);
+}
+
+/*!
   Return local data index on client which are sent to servers
 */
Index: XIOS/trunk/src/distribution_client.hpp
===================================================================
--- XIOS/trunk/src/distribution_client.hpp	(revision 622)
+++ XIOS/trunk/src/distribution_client.hpp	(revision 623)
@@ -39,7 +39,9 @@
     virtual const CArray<int,1>& getLocalDataIndexSendToServer() const;
     const CArray<size_t,1>& getGlobalDataIndexSendToServer() const;
+    const CArray<int,1>& getLocalMaskIndexOnClient() const;
 
     std::vector<int> getNGlob() { return nGlob_; }
     std::vector<int> getDataNIndex() { return dataNIndex_; }
+
     bool isDataDistributed() { return isDataDistributed_; }
 
@@ -73,4 +75,5 @@
     CArray<int,1>* localDataIndex_;
     CArray<int,1>* localDataIndexSendToServer_;
+    CArray<int,1>* localMaskIndex_;
 
   private:
Index: XIOS/trunk/src/filter/axis_algorithm_inverse.cpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_inverse.cpp	(revision 623)
+++ XIOS/trunk/src/filter/axis_algorithm_inverse.cpp	(revision 623)
@@ -0,0 +1,35 @@
+#include "axis_algorithm_inverse.hpp"
+
+namespace xios {
+
+CAxisAlgorithmInverse::CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource)
+ : CAxisAlgorithmTransformation(axisDestination, axisSource)
+{
+  if (axisDestination->size.getValue() != axisSource->size.getValue())
+  {
+    ERROR("CAxisAlgorithmInverse::CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource)",
+           << "Two axis have different size"
+           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
+           << "Size of axis destionation " <<axisDestination->getId() << " is " << axisDestination->size.getValue());
+  }
+
+
+  axisDestGlobalSize_ = axisDestination->size.getValue();
+  int niDest = axisDestination->ni.getValue();
+  int ibeginDest = axisDestination->ibegin.getValue();
+
+  for (int idx = 0; idx < niDest; ++idx)
+    if ((axisDestination->mask)(idx)) axisDestGlobalIndex_.push_back(ibeginDest+idx);
+  this->computeIndexSourceMapping();
+}
+
+void CAxisAlgorithmInverse::computeIndexSourceMapping()
+{
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+
+  int globalIndexSize = axisDestGlobalIndex_.size();
+  for (int idx = 0; idx < globalIndexSize; ++idx)
+    transMap[axisDestGlobalIndex_[idx]].push_back(axisDestGlobalSize_-axisDestGlobalIndex_[idx]-1);
+}
+
+}
Index: XIOS/trunk/src/filter/axis_algorithm_inverse.hpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_inverse.hpp	(revision 623)
+++ XIOS/trunk/src/filter/axis_algorithm_inverse.hpp	(revision 623)
@@ -0,0 +1,20 @@
+#ifndef __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
+#define __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
+
+#include "axis_algorithm_transformation.hpp"
+#include "axis.hpp"
+
+namespace xios {
+
+class CAxisAlgorithmInverse : public CAxisAlgorithmTransformation
+{
+public:
+  CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource);
+
+  virtual ~CAxisAlgorithmInverse() {}
+
+  virtual void computeIndexSourceMapping();
+};
+
+}
+#endif // __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
Index: XIOS/trunk/src/filter/axis_algorithm_zoom.cpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_zoom.cpp	(revision 623)
+++ XIOS/trunk/src/filter/axis_algorithm_zoom.cpp	(revision 623)
@@ -0,0 +1,66 @@
+#include "axis_algorithm_zoom.hpp"
+
+namespace xios {
+
+CAxisAlgorithmZoom::CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)
+: CAxisAlgorithmTransformation(axisDestination, axisSource), axisDest_(axisDestination), axisSrc_(axisSource)
+{
+  zoomAxis->checkValid(axisSource);
+  zoomBegin_ = zoomAxis->zoom_begin.getValue();
+  zoomEnd_   = zoomAxis->zoom_end.getValue();
+  zoomSize_  = zoomAxis->zoom_size.getValue();
+
+  if (zoomSize_ > axisSource->size.getValue())
+  {
+    ERROR("CAxisAlgorithmZoom::CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)",
+           << "Zoom size is greater than size of axis source"
+           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
+           << "Zoom size is " << zoomSize_ );
+  }
+
+  computeIndexSourceMapping();
+}
+
+void CAxisAlgorithmZoom::computeIndexSourceMapping()
+{
+  StdSize niSource = axisSrc_->ni.getValue();
+  StdSize ibeginSource = axisSrc_->ibegin.getValue();
+  StdSize iendSource = ibeginSource + niSource - 1;
+
+  StdSize ibegin = std::max(ibeginSource, zoomBegin_);
+  StdSize iend = std::min(iendSource, zoomEnd_);
+  StdSize ni = iend + 1 - ibegin;
+  if (iend < ibegin) ni = 0;
+
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  for (StdSize idx = 0; idx < ni; ++idx)
+  {
+    transMap[ibegin+idx].push_back(ibegin+idx);
+  }
+
+  updateZoom();
+  updateAxisDestinationMask();
+}
+
+void CAxisAlgorithmZoom::updateZoom()
+{
+  axisDest_->global_zoom_begin = zoomBegin_;
+  axisDest_->global_zoom_size  = zoomSize_;
+}
+
+void CAxisAlgorithmZoom::updateAxisDestinationMask()
+{
+  StdSize niMask = axisDest_->mask.numElements();
+  StdSize iBeginMask = axisDest_->ibegin.getValue();
+  StdSize globalIndexMask = 0;
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  std::map<int, std::vector<int> >::const_iterator ite = (transMap).end();
+  for (StdSize idx = 0; idx < niMask; ++idx)
+  {
+    globalIndexMask = iBeginMask + idx;
+    if (transMap.find(globalIndexMask) == ite)
+      (axisDest_->mask)(idx) = false;
+  }
+}
+
+}
Index: XIOS/trunk/src/filter/axis_algorithm_zoom.hpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_zoom.hpp	(revision 623)
+++ XIOS/trunk/src/filter/axis_algorithm_zoom.hpp	(revision 623)
@@ -0,0 +1,33 @@
+#ifndef __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
+#define __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
+
+#include "axis_algorithm_transformation.hpp"
+#include "axis.hpp"
+#include "zoom_axis.hpp"
+
+namespace xios {
+
+class CAxisAlgorithmZoom : public CAxisAlgorithmTransformation
+{
+public:
+  CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis);
+
+  virtual ~CAxisAlgorithmZoom() {}
+
+  virtual void computeIndexSourceMapping();
+
+private:
+  void updateAxisDestinationMask();
+  void updateZoom();
+private:
+  StdSize zoomBegin_;
+  StdSize zoomEnd_;
+  StdSize zoomSize_;
+
+private:
+  CAxis* axisDest_;
+  CAxis* axisSrc_;
+};
+
+}
+#endif // __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
Index: XIOS/trunk/src/filter/axis_inverse.cpp
===================================================================
--- XIOS/trunk/src/filter/axis_inverse.cpp	(revision 622)
+++ 	(revision )
@@ -1,34 +1,0 @@
-#include "axis_inverse.hpp"
-
-namespace xios {
-
-CAxisInverse::CAxisInverse(CAxis* axisDestination, CAxis* axisSource)
- : CAxisAlgorithmTransformation(axisDestination, axisSource)
-{
-  if (axisDestination->size.getValue() != axisSource->size.getValue())
-  {
-    ERROR("CAxisInverse::CAxisInverse(CAxis* axisDestination, CAxis* axisSource)",
-           << "Two axis have different size"
-           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
-           << "Size of axis destionation " <<axisDestination->getId() << " is " << axisDestination->size.getValue());
-  }
-
-
-  axisDestGlobalSize_ = axisDestination->size.getValue();
-  int niDest = axisDestination->ni.getValue();
-  int ibeginDest = axisDestination->ibegin.getValue();
-
-  for (int idx = 0; idx < niDest; ++idx) axisDestGlobalIndex_.push_back(ibeginDest+idx);
-  this->computeIndexSourceMapping();
-}
-
-void CAxisInverse::computeIndexSourceMapping()
-{
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-
-  int globalIndexSize = axisDestGlobalIndex_.size();
-  for (int idx = 0; idx < globalIndexSize; ++idx)
-    transMap[axisDestGlobalIndex_[idx]].push_back(axisDestGlobalSize_-axisDestGlobalIndex_[idx]-1);
-}
-
-}
Index: XIOS/trunk/src/filter/axis_inverse.hpp
===================================================================
--- XIOS/trunk/src/filter/axis_inverse.hpp	(revision 622)
+++ 	(revision )
@@ -1,20 +1,0 @@
-#ifndef __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
-#define __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
-
-#include "axis_algorithm_transformation.hpp"
-#include "axis.hpp"
-
-namespace xios {
-
-class CAxisInverse : public CAxisAlgorithmTransformation //public CConcreteAlgo
-{
-public:
-  CAxisInverse(CAxis* axisDestination, CAxis* axisSource);
-
-  virtual ~CAxisInverse() {}
-
-  virtual void computeIndexSourceMapping();
-};
-
-}
-#endif // __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
Index: XIOS/trunk/src/filter/axis_zoom.cpp
===================================================================
--- XIOS/trunk/src/filter/axis_zoom.cpp	(revision 622)
+++ 	(revision )
@@ -1,54 +1,0 @@
-#include "axis_zoom.hpp"
-
-namespace xios {
-
-CAxisZoom::CAxisZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)
-: CAxisAlgorithmTransformation(axisDestination, axisSource), axisDest_(axisDestination), axisSrc_(axisSource)
-{
-  zoomAxis->checkValid(axisSource);
-  zoomBegin_ = zoomAxis->zoom_begin.getValue();
-  zoomEnd_   = zoomAxis->zoom_end.getValue();
-  zoomSize_  = zoomAxis->zoom_size.getValue();
-
-  if (zoomSize_ > axisSource->size.getValue())
-  {
-    ERROR("CAxisZoom::CAxisZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)",
-           << "Zoom size is greater than size of axis source"
-           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
-           << "Zoom size is " << zoomSize_ );
-  }
-
-  // Axis destination now must have new size equal to zoom size
-  axisDestination->size.setValue(zoomSize_);
-  computeIndexSourceMapping();
-}
-
-void CAxisZoom::computeIndexSourceMapping()
-{
-  StdSize niSource = axisSrc_->ni.getValue();
-  StdSize ibeginSource = axisSrc_->ibegin.getValue();
-  StdSize iendSource = ibeginSource + niSource - 1;
-
-  StdSize ibegin = std::max(ibeginSource, zoomBegin_);
-  StdSize iend = std::min(iendSource, zoomEnd_);
-  StdSize ni = iend + 1 - ibegin;
-  if (ibeginSource > zoomEnd_)
-  {
-    axisDest_->ibegin.setValue(0);
-    axisDest_->ni.setValue(0);
-  }
-  else
-  {
-    axisDest_->ibegin.setValue(ibegin - zoomBegin_);
-    axisDest_->ni.setValue(ni);
-  }
-
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  StdSize axisDestIBegin = axisDest_->ibegin.getValue();
-  for (StdSize idx = 0; idx < ni; ++idx)
-  {
-    transMap[axisDestIBegin+idx].push_back(ibegin+idx);
-  }
-}
-
-}
Index: XIOS/trunk/src/filter/axis_zoom.hpp
===================================================================
--- XIOS/trunk/src/filter/axis_zoom.hpp	(revision 622)
+++ 	(revision )
@@ -1,30 +1,0 @@
-#ifndef __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
-#define __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
-
-#include "axis_algorithm_transformation.hpp"
-#include "axis.hpp"
-#include "zoom_axis.hpp"
-
-namespace xios {
-
-class CAxisZoom : public CAxisAlgorithmTransformation
-{
-public:
-  CAxisZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis);
-
-  virtual ~CAxisZoom() {}
-
-  virtual void computeIndexSourceMapping();
-
-private:
-  StdSize zoomBegin_;
-  StdSize zoomEnd_;
-  StdSize zoomSize_;
-
-private:
-  CAxis* axisDest_;
-  CAxis* axisSrc_;
-};
-
-}
-#endif // __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
Index: XIOS/trunk/src/filter/concrete_algo.hpp
===================================================================
--- XIOS/trunk/src/filter/concrete_algo.hpp	(revision 622)
+++ 	(revision )
@@ -1,25 +1,0 @@
-#ifndef __XIOS_CONCRETE_ALGORITHM_HPP__
-#define __XIOS_CONCRETE_ALGORITHM_HPP__
-
-#include <map>
-#include <vector>
-
-namespace xios {
-
-class CConcreteAlgo
-{
-public:
-  CConcreteAlgo() : transformationMapping_() {}
-
-  virtual ~CConcreteAlgo() {}
-
-  virtual void computeIndexSourceMapping(const std::map<int, std::vector<int> >&) = 0;
-
-  const std::map<int, std::vector<int> >& getTransformationMapping() const { return transformationMapping_; }
-
-protected:
-  std::map<int, std::vector<int> > transformationMapping_;
-};
-
-}
-#endif // __XIOS_CONCRETE_ALGORITHM_HPP__
Index: XIOS/trunk/src/filter/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/filter/generic_algorithm_transformation.hpp	(revision 622)
+++ XIOS/trunk/src/filter/generic_algorithm_transformation.hpp	(revision 623)
@@ -20,5 +20,5 @@
                                 std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
 
-                                  /*!
+  /*!
   Compute global index mapping from one element of destination grid to the corresponding element of source grid
   */
Index: XIOS/trunk/src/filter/grid_transformation.cpp
===================================================================
--- XIOS/trunk/src/filter/grid_transformation.cpp	(revision 622)
+++ XIOS/trunk/src/filter/grid_transformation.cpp	(revision 623)
@@ -1,5 +1,13 @@
+/*!
+   \file grid_transformation.cpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Interface for all transformations.
+ */
 #include "grid_transformation.hpp"
-#include "axis_inverse.hpp"
-#include "axis_zoom.hpp"
+#include "axis_algorithm_inverse.hpp"
+#include "axis_algorithm_zoom.hpp"
 #include "context.hpp"
 #include "context_client.hpp"
@@ -35,5 +43,5 @@
   {
     CAxis* axis = CAxis::createAxis();
-    axisSrcTmp[idx]->duplicateAttributes(axis);
+    axis->setAttributes(axisSrcTmp[idx]);
     axisSrc.push_back(axis);
   }
@@ -42,5 +50,5 @@
   {
     CDomain* domain = CDomain::createDomain();
-    domainSrcTmp[idx]->duplicateAttributes(domain);
+    domain->setAttributes(domainSrcTmp[idx]);
     domainSrc.push_back(domain);
   }
@@ -168,8 +176,8 @@
     case TRANS_ZOOM_AXIS:
       zoomAxis = dynamic_cast<CZoomAxis*> (it->second);
-      algo = new CAxisZoom(axisListDestP[axisIndex], axisListSrcP[axisIndex], zoomAxis);
+      algo = new CAxisAlgorithmZoom(axisListDestP[axisIndex], axisListSrcP[axisIndex], zoomAxis);
       break;
     case TRANS_INVERSE_AXIS:
-      algo = new CAxisInverse(axisListDestP[axisIndex], axisListSrcP[axisIndex]);
+      algo = new CAxisAlgorithmInverse(axisListDestP[axisIndex], axisListSrcP[axisIndex]);
       break;
     default:
@@ -196,5 +204,5 @@
     case TRANS_INVERSE_AXIS:
       axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
-      axisListDestP[axisIndex]->duplicateAttributes(axisListSrcP[axisIndex]);
+      axisListSrcP[axisIndex]->duplicateAttributes(axisListDestP[axisIndex]);
       break;
     default:
@@ -226,4 +234,5 @@
     const CArray<size_t,1>& globalIndexGridDestSendToServer = distributionClientDest.getGlobalDataIndexSendToServer();
 
+   std::cout << "global index grid  dest send to server " << globalIndexGridDestSendToServer << std::endl;
     // ComputeTransformation of global index of each element
     std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension();
@@ -241,6 +250,7 @@
   }
 
- std::cout << "global index destination 0 " << *globalIndexOfCurrentGridSource_ << std::endl;
- std::cout << "global index destination 1 " << *globalIndexOfOriginalGridSource_ << std::endl;
+ std::cout << "global index destination 0 final " << *globalIndexOfCurrentGridSource_ << std::endl;
+ std::cout << "global index destination 1 final " << *globalIndexOfOriginalGridSource_ << std::endl;
+  updateFinalGridDestination();
   computeFinalTransformationMapping();
 }
@@ -248,30 +258,58 @@
 
 /*!
-  Compute index mapping representing transformation between two grids
-  Each domain and each axis can contain some information of transformation, these information are then converted into
-form of global index mapping reprensenting transformation between two grids.
+  After applying the algorithms, there are some informations on grid destination needing change, for now, there are:
+   +) mask
 */
-void CGridTransformation::computeTransformation()
-{
-//  const CArray<size_t,1>& globalIndexGridDestSendToServer = gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
-//  std::list<std::pair<int,CGenericAlgorithmTransformation*> >::const_iterator itbMap, itMap, iteMap;
-//  itbMap = algoTransformation_.begin();
-//  iteMap = algoTransformation_.end();
-//
-//  std::vector<CGenericAlgorithmTransformation*>::const_iterator itbVec, itVec, iteVec;
-//
-//  for (itMap = itbMap; itMap != iteMap; ++itMap)
-//  {
-//    int elementPosition = itMap->first;
-//    itbVec = (itMap->second).begin();
-//    iteVec = (itMap->second).end();
-//    for (itVec = itbVec; itVec != iteVec; ++itVec)
-//    {
-//      (*itVec)->computeGlobalSourceIndex(elementPosition,
-//                                         gridDestinationDimensionSize_,
-//                                         globalIndexGridDestSendToServer,
-//                                         globaIndexMapFromDestToSource_);
-//    }
-//  }
+void CGridTransformation::updateFinalGridDestination()
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+
+  //First of all, retrieve info of local mask of grid destination
+  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
+  const CArray<int, 1>& localMaskIndexOnClientDest = distributionClientDest.getLocalMaskIndexOnClient();
+  std::cout << "local mask " << localMaskIndexOnClientDest << std::endl;
+
+  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
+  std::cout << "global index " << globalIndexOnClientDest <<  std::endl;
+  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
+  itbArr = globalIndexOnClientDest.begin();
+  iteArr = globalIndexOnClientDest.end();
+
+  // Then find out which index became invalid (become masked after being applied the algorithms, or demande some masked points from grid source)
+  int num = globalIndexOfOriginalGridSource_->numElements();
+  const size_t sfmax = NumTraits<unsigned long>::sfmax();
+  int maskIndexNum = 0;
+  for (int idx = 0; idx < num; ++idx)
+  {
+    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
+    {
+      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
+      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
+      if (iteArr != itArr) ++maskIndexNum;
+    }
+  }
+
+  CArray<int,1>* maskIndexToModify = new CArray<int,1>(maskIndexNum);
+  maskIndexNum = 0;
+  for (int idx = 0; idx < num; ++idx)
+  {
+    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
+    {
+      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
+      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
+      if (iteArr != itArr)
+      {
+        int localIdx = std::distance(itbArr, itArr);
+        (*maskIndexToModify)(maskIndexNum) = (localMaskIndexOnClientDest)(localIdx);
+        ++maskIndexNum;
+      }
+    }
+  }
+
+  std::cout << "index to modify " << *maskIndexToModify << std::endl;
+  gridDestination_->modifyMask(*maskIndexToModify);
+
+  delete maskIndexToModify;
 }
 
@@ -302,6 +340,12 @@
  for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
 
+ std::cout << "global index destination 0 before" << *globalIndexOfCurrentGridSource_ << std::endl;
+ std::cout << "global index destination 1 before" << *globalIndexOfOriginalGridSource_ << std::endl;
+
+ typedef unsigned long Scalar;
  unsigned long* sendBuff, *currentSendBuff;
  if (0 != sendBuffSize) sendBuff = new unsigned long [sendBuffSize];
+ for (StdSize idx = 0; idx < sendBuffSize; ++idx) sendBuff[idx] = NumTraits<Scalar>::sfmax();
+
  int currentBuffPosition = 0;
  for (itSend = itbSend; itSend != iteSend; ++itSend)
@@ -332,4 +376,6 @@
  unsigned long* recvBuff, *currentRecvBuff;
  if (0 != recvBuffSize) recvBuff = new unsigned long [recvBuffSize];
+ for (StdSize idx = 0; idx < recvBuffSize; ++idx) recvBuff[idx] = NumTraits<Scalar>::sfmax();
+
  int currentRecvBuffPosition = 0;
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
@@ -353,6 +399,22 @@
  }
 
- globalIndexOfCurrentGridSource_->resize(nbCurrentGridSource);
- globalIndexOfOriginalGridSource_->resize(nbCurrentGridSource);
+ if (globalIndexOfCurrentGridSource_->numElements()  != nbCurrentGridSource)
+ {
+   if ((0 != nbCurrentGridSource) && (0 != globalIndexOfCurrentGridSource_))
+   {
+     delete globalIndexOfCurrentGridSource_;
+     globalIndexOfCurrentGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
+   }
+ }
+
+ if (globalIndexOfOriginalGridSource_->numElements() != nbCurrentGridSource)
+ {
+   if ((0 != nbCurrentGridSource) && (0 != globalIndexOfOriginalGridSource_))
+   {
+     delete globalIndexOfOriginalGridSource_;
+     globalIndexOfOriginalGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
+   }
+ }
+
  int k = 0;
  currentRecvBuff = recvBuff;
@@ -372,4 +434,6 @@
  }
 
+ std::cout << "global index destination 0 after " << *globalIndexOfCurrentGridSource_ << std::endl;
+ std::cout << "global index destination 1 after " << *globalIndexOfOriginalGridSource_ << std::endl;
  if (0 != sendBuffSize) delete [] sendBuff;
  if (0 != recvBuffSize) delete [] recvBuff;
@@ -391,7 +455,9 @@
 
   int nb = globalIndexOfCurrentGridSource_->numElements();
+  const size_t sfmax = NumTraits<unsigned long>::sfmax();
   for (int idx = 0; idx < nb; ++idx)
   {
-    globaIndexMapFromDestToSource[(*globalIndexOfCurrentGridSource_)(idx)].insert((*globalIndexOfOriginalGridSource_)(idx));
+    if (sfmax != (*globalIndexOfOriginalGridSource_)(idx))
+      globaIndexMapFromDestToSource[(*globalIndexOfCurrentGridSource_)(idx)].insert((*globalIndexOfOriginalGridSource_)(idx));
   }
 
@@ -403,17 +469,18 @@
 
   CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
-  CDistributionClient distributionClientSrc(client->clientRank, gridSource_);
-
-  CArray<int, 1> localIndexOnClientDest = distributionClientDest.getLocalDataIndexOnClient(); //gridDestination_->getDistributionClient()->getLocalDataIndexOnClient();
-  CArray<size_t,1> globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer(); //gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
+  CDistributionClient distributionClientSrc(client->clientRank, originalGridSource_);
+
+//  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexOnClient(); //gridDestination_->getDistributionClient()->getLocalDataIndexOnClient();
+  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexSendToServer();
+  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer(); //gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
 
  std::cout << "dest: local index " << localIndexOnClientDest << std::endl;
  std::cout << "dest: global index " << globalIndexOnClientDest << std::endl;
-  CArray<int, 1> localIndexOnClientSrc = distributionClientSrc.getLocalDataIndexOnClient(); //gridSource_->getDistributionClient()->getLocalDataIndexOnClient();
-  CArray<size_t,1> globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
+  const CArray<int, 1>& localIndexOnClientSrc = distributionClientSrc.getLocalDataIndexOnClient(); //gridSource_->getDistributionClient()->getLocalDataIndexOnClient();
+  const CArray<size_t,1>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
  std::cout << "src: local index " << localIndexOnClientSrc << std::endl;
  std::cout << "src: global index " << globalIndexOnClientSrc << std::endl;
   std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
-  CArray<size_t, 1>::iterator itbArr, itArr, iteArr;
+  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
 
   std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
@@ -439,9 +506,10 @@
         {
           int localIdx = std::distance(itbArr, itArr);
-//          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = localIndexOnClientDest(localIdx); // Local index of un-extracted data (only domain)
-          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = (localIdx); // Local index of extracted data
+          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = localIndexOnClientDest(localIdx); // Local index of un-extracted data (only domain)
+//          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = (localIdx); // Local index of extracted data
         }
       }
     }
+//    std::cout << "local index to receive from source Rank = " << sourceRank << (*localIndexToReceiveOnGridDest_[sourceRank][i]) << std::endl;
   }
 
@@ -468,4 +536,5 @@
       }
     }
+    std::cout << "local index to send to dest Rank = " << destRank << (*localIndexToSendFromGridSource_[destRank]) << std::endl;
   }
 }
Index: XIOS/trunk/src/filter/grid_transformation.hpp
===================================================================
--- XIOS/trunk/src/filter/grid_transformation.hpp	(revision 622)
+++ XIOS/trunk/src/filter/grid_transformation.hpp	(revision 623)
@@ -1,2 +1,10 @@
+/*!
+   \file grid_transformation.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Interface for all transformations.
+ */
 #ifndef __XIOS_GRID_TRANSFORMATION_HPP__
 #define __XIOS_GRID_TRANSFORMATION_HPP__
@@ -12,4 +20,15 @@
 class CGrid;
 
+/*!
+  \class CGridTransformation
+  This class is an interface for all transformations to interact with the rest of XIOS.
+The class, firstly, tries to get all information relating to requested transformations by retrieving directly from grid.
+Then with all these information, all necessary transformations will be be created by generic class \class CGenericAlgorithmTransformation.
+Because there are information exchange among clients to accomplish the transformations (e.g: some index need retrieving from other clients),
+this class uses class \class CTransformationMapping to fulfill this demand.
+For each transformation, a new temporary grid source is created.
+For a consequential transformations (e.g: inversing -> zoom -> inversing -> ...),
+the grid destination of current transformation will be grid source of the next transformation
+*/
 class CGridTransformation
 {
@@ -38,26 +57,43 @@
   void computeFinalTransformationMapping();
   void computeTransformationFromOriginalGridSource(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
+  void updateFinalGridDestination();
 
 private:
+  //! Grid source on transformation
   CGrid* gridSource_;
+
+  //! Grid destination on transformation
   CGrid* gridDestination_;
+
+  //! The grid source of the first transformation (original grid source)
   CGrid* originalGridSource_;
 
+  //! Grid source dimension size
   std::vector<int> gridSourceDimensionSize_;
+
+  //! Grid destination dimension size
   std::vector<int> gridDestinationDimensionSize_;
 
 private:
   typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
+  //! List of algorithm types and their order
+  ListAlgoType listAlgos_;
 
   // Mapping between position of an element in grid and its transformation (if any)
   std::list<CGenericAlgorithmTransformation*> algoTransformation_;
-  ListAlgoType listAlgos_;
+
+  //! Mapping of (grid) global index representing tranformation.
   std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource_;
 
+  //! Local index of data to send from grid source
   std::map<int, CArray<int,1>* > localIndexToSendFromGridSource_;
+
+  //! Local index of data to receive on grid destination
   std::map<int, std::vector<CArray<int,1>* > > localIndexToReceiveOnGridDest_;
 
+  //! Position of axis and domain in grid
   std::map<int, int> elementPosition2AxisPositionInGrid_, elementPosition2DomainPositionInGrid_;
 
+  //! (Grid) Global index of grid source
   CArray<size_t,1>* globalIndexOfCurrentGridSource_;
   CArray<size_t,1>* globalIndexOfOriginalGridSource_;
Index: XIOS/trunk/src/filter/transformation_mapping.cpp
===================================================================
--- XIOS/trunk/src/filter/transformation_mapping.cpp	(revision 622)
+++ XIOS/trunk/src/filter/transformation_mapping.cpp	(revision 623)
@@ -1,2 +1,11 @@
+/*!
+   \file transformation_mapping.cpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Take charge of communication among clients to exchange transformed data.
+ */
+
 #include "transformation_mapping.hpp"
 #include <boost/unordered_map.hpp>
@@ -14,7 +23,7 @@
   int clientRank = client->clientRank;
 
-  CDistributionClient distributionClientDest(client->clientRank, gridSource_);
+  CDistributionClient distributionClientSrc(client->clientRank, gridSource_);
 
-  const CArray<size_t,1>& globalIndexGridSrc = distributionClientDest.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
+  const CArray<size_t,1>& globalIndexGridSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
   boost::unordered_map<size_t,int> globalIndexOfServer;
   int globalIndexSize = globalIndexGridSrc.numElements();
@@ -24,4 +33,5 @@
   }
 
+  std::cout << "global index grid src " << globalIndexGridSrc << std::endl;
   gridIndexClientClientMapping_ = new CClientServerMappingDistributed(globalIndexOfServer,
                                                                       client->intraComm,
@@ -151,4 +161,9 @@
 }
 
+/*!
+  Return (grid) global index on grid destination. This mapping contains the rank of client source (that sends info to grid destination)
+and the corresponding global index to write on grid destination.
+  \return global index mapping to receive on grid destination
+*/
 const std::map<int,std::vector<std::vector<size_t> > >& CTransformationMapping::getGlobalIndexReceivedOnGridDestMapping() const
 {
@@ -156,4 +171,9 @@
 }
 
+/*!
+  Return (grid) global index on grid source. This mapping contains the rank of client destination (which receives transformation info) and
+the corresponding global index to send
+  \return global index mapping to send on grid source
+*/
 const std::map<int,std::vector<size_t> >& CTransformationMapping::getGlobalIndexSendToGridDestMapping() const
 {
Index: XIOS/trunk/src/filter/transformation_mapping.hpp
===================================================================
--- XIOS/trunk/src/filter/transformation_mapping.hpp	(revision 622)
+++ XIOS/trunk/src/filter/transformation_mapping.hpp	(revision 623)
@@ -1,2 +1,10 @@
+/*!
+   \file transformation_mapping.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Take charge of communication among clients to exchange transformed data.
+ */
 #ifndef __XIOS_TRANSFORMATION_MAPPING_HPP__
 #define __XIOS_TRANSFORMATION_MAPPING_HPP__
Index: XIOS/trunk/src/node/axis.cpp
===================================================================
--- XIOS/trunk/src/node/axis.cpp	(revision 622)
+++ XIOS/trunk/src/node/axis.cpp	(revision 623)
@@ -18,5 +18,5 @@
       , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
       , isDistributed_(false)
-      , transformationMap_()
+      , transformationMap_(), global_zoom_begin(0), global_zoom_size(0)
    {
    }
@@ -26,5 +26,5 @@
       , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
       , isDistributed_(false)
-      , transformationMap_()
+      , transformationMap_(), global_zoom_begin(0), global_zoom_size(0)
    {
    }
@@ -67,9 +67,4 @@
      CAxis* axis = CAxisGroup::get("axis_definition")->createChild();
      return axis;
-   }
-
-   void CAxis::duplicateAttributes(CAxis* axis)
-   {
-     axis->setAttributes(this);
    }
 
@@ -101,12 +96,13 @@
       else this->ni.setValue(size);
       std::cout <<  "value " <<  value <<  std::endl;
-      StdSize true_size = value.numElements();
-      if (this->ni.getValue() != true_size)
-         ERROR("CAxis::checkAttributes(void)",
-               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
-
+//      StdSize true_size = value.numElements();
+//      if (this->ni.getValue() != true_size)
+//         ERROR("CAxis::checkAttributes(void)",
+//               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
+
+      if (0 == global_zoom_size) global_zoom_size = size;
       this->checkData();
       this->checkMask();
-      this->checkZoom();
+//      this->checkZoom();
 
       if (!bounds.isEmpty())
@@ -281,4 +277,5 @@
         msg << this->getId();
         msg << ni << begin << end;
+        msg<<global_zoom_begin<<global_zoom_size;
 
         event.push(*itRank,1,msg);
@@ -299,11 +296,13 @@
   void CAxis::recvServerAttribut(CBufferIn& buffer)
   {
-    int zoom_end = zoom_begin.getValue()+zoom_size.getValue()-1;
-    int ni_srv, begin_srv, end_srv;
-
-    buffer>>ni_srv>>begin_srv>>end_srv;
-
-    zoom_begin_srv = zoom_begin.getValue() > begin_srv ? zoom_begin.getValue() : begin_srv;
-    zoom_end_srv   = zoom_end < end_srv ? zoom_end : end_srv;
+    int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_size_tmp;
+
+    buffer>>ni_srv>>begin_srv>>end_srv>>global_zoom_begin_tmp>>global_zoom_size_tmp;
+    global_zoom_begin = global_zoom_begin_tmp;
+    global_zoom_size  = global_zoom_size_tmp;
+    int global_zoom_end = global_zoom_begin + global_zoom_size - 1;
+
+    zoom_begin_srv = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
+    zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
     zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
 
@@ -315,6 +314,6 @@
     if (size == ni)
     {
-      zoom_begin_srv = zoom_begin.getValue();
-      zoom_end_srv   = zoom_end;
+      zoom_begin_srv = global_zoom_begin;
+      zoom_end_srv   = global_zoom_end; //zoom_end;
       zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
     }
Index: XIOS/trunk/src/node/axis.hpp
===================================================================
--- XIOS/trunk/src/node/axis.hpp	(revision 622)
+++ XIOS/trunk/src/node/axis.hpp	(revision 623)
@@ -65,5 +65,4 @@
          /// Accesseurs ///
          const std::set<StdString> & getRelFiles(void) const;
-         void duplicateAttributes(CAxis* axis);
 
          /// Test ///
@@ -104,5 +103,5 @@
         int zoom_begin_srv, zoom_end_srv, zoom_size_srv;
         int ni_srv, begin_srv, end_srv;
-
+        int global_zoom_begin, global_zoom_size;  // The real global zoom begin and zoom size after axis is transformed (zoomed)
       private :
          void checkData();
Index: XIOS/trunk/src/node/field.cpp
===================================================================
--- XIOS/trunk/src/node/field.cpp	(revision 622)
+++ XIOS/trunk/src/node/field.cpp	(revision 623)
@@ -551,9 +551,9 @@
      }
      solveGridDomainAxisRef(doSending2Sever);
-     solveCheckMaskIndex(doSending2Sever);
      if (context->hasClient)
      {
        solveTransformedGrid();
      }
+     solveCheckMaskIndex(doSending2Sever);
    }
 
@@ -784,5 +784,5 @@
            fieldRef->addReference(this);
            fieldRef->solveGridDomainAxisRef(false);
-           fieldRef->solveCheckMaskIndex(false);
+//           fieldRef->solveCheckMaskIndex(false);
            break;
          }
@@ -798,5 +798,5 @@
          fieldRef->addReference(this);
          fieldRef->solveGridDomainAxisRef(false);
-         fieldRef->solveCheckMaskIndex(false);
+//         fieldRef->solveCheckMaskIndex(false);
        }
 
@@ -857,4 +857,5 @@
        CArray<int,1>* localIndex_p = itSend->second;
        int countSize = localIndex_p->numElements();
+       std::cout << "Data Source " <<  dataSrc <<  std::endl;
        for (int idx = 0; idx < countSize; ++idx)
        {
@@ -887,4 +888,5 @@
          }
        }
+       std::cout << "Data Destination " <<  dataDest <<  std::endl;
      }
 
Index: XIOS/trunk/src/node/grid.cpp
===================================================================
--- XIOS/trunk/src/node/grid.cpp	(revision 622)
+++ XIOS/trunk/src/node/grid.cpp	(revision 623)
@@ -298,4 +298,28 @@
       }
    }
+
+   void CGrid::modifyMask(const CArray<int,1>& indexToModify)
+   {
+      using namespace std;
+      std::vector<CDomain*> domainP = this->getDomains();
+      std::vector<CAxis*> axisP = this->getAxis();
+      int dim = domainP.size() * 2 + axisP.size();
+
+      switch (dim) {
+        case 1:
+          modifyGridMask(mask1, indexToModify);
+          break;
+        case 2:
+          modifyGridMask(mask2, indexToModify);
+          break;
+        case 3:
+          modifyGridMask(mask3, indexToModify);
+          break;
+
+        default:
+          break;
+      }
+   }
+
    //---------------------------------------------------------------
 
@@ -850,5 +874,5 @@
             nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
             nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
-            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->zoom_begin;
+            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;
             nGlob[indexMap[i]] = axisList[axisId]->size;
             ++axisId;
@@ -1158,4 +1182,7 @@
     transformations_ = new CGridTransformation(transformedGrid, this);
     transformations_->computeAll();
+
+    // Ok, now need to compute index of grid source
+    checkMaskIndex(false);
   }
 
Index: XIOS/trunk/src/node/grid.hpp
===================================================================
--- XIOS/trunk/src/node/grid.hpp	(revision 622)
+++ XIOS/trunk/src/node/grid.hpp	(revision 623)
@@ -190,8 +190,4 @@
          bool isTransformed();
          void setTransformed();
-//         EElementType getGridElementType();
-//
-//         std::vector<ETransformationType> getTransformations();
-//         const std::vector<CGenericAlgorithm*>& getTransformationAlgo();
 
       public:
@@ -210,4 +206,5 @@
          map<int, CArray<size_t, 1>* > outIndexFromClient;
          void checkMask(void) ;
+         void modifyMask(const CArray<int,1>& indexToModify);
 
       private:
@@ -217,4 +214,7 @@
                           const std::vector<CArray<bool,1>* >& axisMasks,
                           const CArray<bool,1>& axisDomainOrder);
+        template<int N>
+        void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify);
+
         void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
         void setVirtualDomainGroup();
@@ -366,5 +366,5 @@
         maskIndex += idxLoop[k]*mulDim;
       }
-      *(gridMask.dataFirst()+maskIndex) = maskValue;
+      *(gridMask.dataFirst()+maskIndex) &= maskValue;
 
       ++idxLoop[0];
@@ -374,4 +374,19 @@
    }
 
+   /*!
+     Modify the current mask of grid, the local index to be modified will take value false
+     \param [in/out] gridMask current mask of grid
+     \param [in] indexToModify local index to modify
+   */
+   template<int N>
+   void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify)
+   {
+     bool valueToModify = false;
+     int num = indexToModify.numElements();
+     for (int idx = 0; idx < num; ++idx)
+     {
+       *(gridMask.dataFirst()+indexToModify(idx)) = valueToModify;
+     }
+   }
    ///--------------------------------------------------------------
 
Index: XIOS/trunk/src/node/zoom_axis.cpp
===================================================================
--- XIOS/trunk/src/node/zoom_axis.cpp	(revision 622)
+++ XIOS/trunk/src/node/zoom_axis.cpp	(revision 623)
@@ -25,6 +25,6 @@
   void CZoomAxis::checkValid(CAxis* axisDest)
   {
-    StdSize axisIBegin, axisNi, axisSize;
-    StdSize zoom_begin, zoom_end, zoom_size;
+    int axisIBegin, axisNi, axisSize;
+    int zoom_begin, zoom_end, zoom_size;
 
     axisIBegin = axisDest->ibegin.getValue();
@@ -36,7 +36,7 @@
     zoom_end   = (this->zoom_end.isEmpty()) ?  (axisSize - 1) : this->zoom_end.getValue() ;
 
-    if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1 ;
-    if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1 ;
-    if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1 ;
+    if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1;
+    if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1;
+    if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1;
 
     if ((zoom_begin < 0) || (zoom_begin > axisSize-1) || (zoom_end<0) || (zoom_end>axisSize-1) || (zoom_size<1) || (zoom_size>axisSize) || (zoom_begin>zoom_end))
Index: XIOS/trunk/src/output/nc4_data_output.cpp
===================================================================
--- XIOS/trunk/src/output/nc4_data_output.cpp	(revision 622)
+++ XIOS/trunk/src/output/nc4_data_output.cpp	(revision 623)
@@ -600,5 +600,6 @@
         int zoom_begin_srv = axis->zoom_begin_srv;
         int zoom_size  = (MULTI_FILE == SuperClass::type) ? zoom_size_srv : axis->zoom_size;
-        int zoom_begin = (MULTI_FILE == SuperClass::type) ? zoom_begin_srv : axis->zoom_begin;
+                                                              : axis->global_zoom_size;
+                                                              : axis->global_zoom_begin;
 
 
@@ -1361,4 +1362,5 @@
            if (!field->prec.isEmpty() && field->prec==2) fieldData=round(fieldData) ;
 
+           std::cout << "fieldData "<< fieldData << std::endl;
            switch (SuperClass::type)
            {
Index: XIOS/trunk/src/test/test_new_features.f90
===================================================================
--- XIOS/trunk/src/test/test_new_features.f90	(revision 622)
+++ XIOS/trunk/src/test/test_new_features.f90	(revision 623)
@@ -23,4 +23,5 @@
   TYPE(xios_file) :: file_hdl
   LOGICAL :: ok
+  LOGICAL,ALLOCATABLE :: mask_glo(:),mask(:)
 
   DOUBLE PRECISION,DIMENSION(ni_glo,nj_glo) :: lon_glo,lat_glo
@@ -81,4 +82,12 @@
 
   ALLOCATE(lon(ni,nj),lat(ni,nj),field_A(0:ni+1,-1:nj+2,llm),lonvalue(ni*nj), field_Axis(nAxis), field_All_Axis(1:ni,1:nj,llm), lvaln(nAxis), lval_ni(ni), lval_nj(nj), field_Two_Axis(ni_glo,1:nj))
+  ALLOCATE(mask(nj))
+  DO i = 1, nj
+!    IF (MOD(i,2)>=0) THEN
+!      mask(i)=.FALSE.
+!    ELSE
+      mask(i)=.TRUE.
+!    ENDIF
+  ENDDO
   lon(:,:)=lon_glo(ibegin+1:iend+1,jbegin+1:jend+1)
   lat(:,:)=lat_glo(ibegin+1:iend+1,jbegin+1:jend+1)
@@ -99,5 +108,5 @@
 
   CALL xios_set_axis_attr("axis_A", size=ni_glo, ibegin=ibegin, ni=ni, value=lval_ni)
-  CALL xios_set_axis_attr("axis_B", size=nj_glo, ibegin=jbegin, ni=nj, value=lval_nj)
+  CALL xios_set_axis_attr("axis_B", size=nj_glo, ibegin=jbegin, ni=nj, value=lval_nj, mask=mask)
   CALL xios_set_axis_attr("axis_C", size=llm, value=lval)
   CALL xios_set_axis_attr("axis_D", size=llm, ibegin=axisBegin, ni=nAxis, value=lvaln)
Index: XIOS/trunk/src/utils.hpp
===================================================================
--- XIOS/trunk/src/utils.hpp	(revision 622)
+++ XIOS/trunk/src/utils.hpp	(revision 623)
@@ -13,4 +13,5 @@
 
 #include <vector>
+#include <limits>
 #include "array_new.hpp"
 #include "exception.hpp"
@@ -187,4 +188,23 @@
     }
   };
+
+template<typename K>
+struct NumTraits {
+    typedef K Type;
+};
+
+template<>
+struct NumTraits<unsigned long>
+{
+  typedef unsigned long Scalar;
+  typedef Scalar magnitudeType;
+
+  static inline Scalar sfmin() {
+    return std::numeric_limits<Scalar>::min();
+  }
+  static inline Scalar sfmax() {
+    return std::numeric_limits<Scalar>::max();
+  }
+};
 }
 
