diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 790164a1cf69a3f50aadafc798247c358a1cbb8d..dd339f5ab7bfa4d76c5e1ea0d35c64bb2a34d03f 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -98,3 +98,9 @@ OTB_CREATE_APPLICATION(NAME SARESD
                        SOURCES otbSARESD.cxx
                        LINK_LIBRARIES ${${otb-module}_LIBRARIES}
 )
+
+OTB_CREATE_APPLICATION(NAME SARCorrelationRough
+                       SOURCES otbSARCorrelationRough.cxx
+                       LINK_LIBRARIES ${${otb-module}_LIBRARIES}
+)
+
diff --git a/app/otbSARCorrectionGrid.cxx b/app/otbSARCorrectionGrid.cxx
index 5547de7a3f54a7ddba01d05308bcf2eefd40db6c..75af1927780aa3844cde33abc052e32262b4aab6 100644
--- a/app/otbSARCorrectionGrid.cxx
+++ b/app/otbSARCorrectionGrid.cxx
@@ -24,6 +24,11 @@
 #include "otbSARStreamingGridInformationImageFilter.h"
 #include "otbSARCorrectionGridImageFilter.h"
 
+#include "otbMultiToMonoChannelExtractROI.h"
+#include "otbImageList.h"
+#include "otbImageListToVectorImageFilter.h"
+#include "itkAddImageFilter.h"
+
 #include <iostream>
 #include <string>
 #include <fstream>
@@ -44,7 +49,16 @@ public:
 
   // Filters
   typedef otb::SARCorrectionGridImageFilter<FloatVectorImageType, FloatVectorImageType> CorrectionGridFilterType;
-  typedef otb::SARStreamingGridInformationImageFilter<FloatVectorImageType> MeanFilterType;
+  typedef otb::SARStreamingGridInformationImageFilter<FloatVectorImageType>             MeanFilterType;
+  typedef otb::ImageList<FloatImageType>                                                ImageListType;
+  typedef otb::ImageListToVectorImageFilter<ImageListType,
+                                       FloatVectorImageType >                           ListConcatenerFilterType;
+  typedef otb::MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,
+                                       FloatImageType::PixelType>                       ExtractROIFilterType;
+  typedef itk::AddImageFilter <FloatImageType, FloatImageType, FloatImageType>          AddFilterType;
+
+  typedef ObjectList<ExtractROIFilterType>                                              ExtractROIFilterListType;
+  typedef ObjectList<AddFilterType>                                                     AddFilterListType;
   
 
 private:
@@ -87,6 +101,10 @@ private:
     SetMinimumParameterFloatValue("gap", 0.01);
     MandatoryOff("gap");
 
+    AddParameter(ParameterType_String, "advantage", "Give an advantage to DEM or Correlation Grid");
+    SetParameterDescription("advantage","Give an advantage to DEM or Correlation Grid.");
+    MandatoryOff("advantage");
+
     AddRAMParameter();
 
     SetDocExampleParameterValue("indemgrid","./demGrid.tiff");
@@ -109,39 +127,156 @@ void DoExecute() override
   otbAppLogINFO(<<"Threshold on correlation rate :"<<threshold);
   otbAppLogINFO(<<"Gap on the difference between grid values and mean values: "<<gap);
 
+  std::string advantage = GetParameterString("advantage");
+  bool demGridToFavor = true;
+    
+  if (advantage == "correlation" || advantage == "cor" || advantage == "corgrid")
+    {
+      demGridToFavor = false;
+    } 
+     
+  if (demGridToFavor)
+    {
+      otbAppLogINFO(<<"Opt in favor of projection (DEMGrid)");
+    }
+  else
+    {
+      otbAppLogINFO(<<"Opt in favor of correlation (CorGrid)");
+    }
+
+  
   // Get input grids
   FloatVectorImageType::Pointer DEMGridPtr = GetParameterFloatVectorImage("indemgrid");
   FloatVectorImageType::Pointer CorGridPtr = GetParameterFloatVectorImage("incorgrid");
   
-  // Mean Persistent Filter
-  MeanFilterType::Pointer filterMean = MeanFilterType::New();
-  m_Ref.push_back(filterMean.GetPointer());
-
-  // Configure Mean Filter
-  filterMean->SetThreshold(threshold);
-  filterMean->SetInput(DEMGridPtr);
-  filterMean->SetEstimateMean(true);
-
-  // Get mean values
-  filterMean->Update();
-  double meanRange, meanAzimut;
-  filterMean->GetMean(meanRange, meanAzimut);
-
-  // Correction Filter
-  CorrectionGridFilterType::Pointer filterCorrectionGrid = CorrectionGridFilterType::New();
-  m_Ref.push_back(filterCorrectionGrid.GetPointer());
+  if (demGridToFavor)
+    {
+      // Mean Persistent Filter
+      MeanFilterType::Pointer filterMean = MeanFilterType::New();
+      m_Ref.push_back(filterMean.GetPointer());
+
+      // Configure Mean Filter
+      filterMean->SetThreshold(threshold);
+      filterMean->SetInput(DEMGridPtr);
+      filterMean->SetEstimateMean(true);
+
+      // Get mean values
+      filterMean->Update();
+      double meanRange, meanAzimut;
+      filterMean->GetMean(meanRange, meanAzimut);
+
+      // Correction Filter
+      CorrectionGridFilterType::Pointer filterCorrectionGrid = CorrectionGridFilterType::New();
+      m_Ref.push_back(filterCorrectionGrid.GetPointer());
+  
+      // Configure CorrectionGrid Filter
+      filterCorrectionGrid->SetThreshold(threshold);
+      filterCorrectionGrid->SetGap(gap);
+      filterCorrectionGrid->SetMeanRange(meanRange);
+      filterCorrectionGrid->SetMeanAzimut(meanAzimut);
   
-  // Configure CorrectionGrid Filter
-  filterCorrectionGrid->SetThreshold(threshold);
-  filterCorrectionGrid->SetGap(gap);
-  filterCorrectionGrid->SetMeanRange(meanRange);
-  filterCorrectionGrid->SetMeanAzimut(meanAzimut);
+      // Define the main pipeline
+      filterCorrectionGrid->SetDEMGridInput(DEMGridPtr);
+      filterCorrectionGrid->SetCorGridInput(CorGridPtr);
   
-  // Define the main pipeline
-  filterCorrectionGrid->SetDEMGridInput(DEMGridPtr);
-  filterCorrectionGrid->SetCorGridInput(CorGridPtr);
+      SetParameterOutputImage("out", filterCorrectionGrid->GetOutput());
+    }
+  else
+    {
+      // Mean Persistent Filters (for the two grids)
+      MeanFilterType::Pointer filterMeanDEM = MeanFilterType::New();
+      m_Ref.push_back(filterMeanDEM.GetPointer());
+
+      MeanFilterType::Pointer filterMeanCor = MeanFilterType::New();
+      m_Ref.push_back(filterMeanCor.GetPointer());
+
+      // Configure Mean Filters
+      filterMeanDEM->SetThreshold(threshold);
+      filterMeanDEM->SetInput(DEMGridPtr);
+      filterMeanDEM->SetEstimateMean(true);
+
+      filterMeanCor->SetThreshold(threshold);
+      filterMeanCor->SetInput(CorGridPtr);
+      filterMeanCor->SetEstimateMean(true);
+
+      // Get mean values
+      filterMeanDEM->Update();
+      double meanRangeDEM, meanAzimutDEM;
+      filterMeanDEM->GetMean(meanRangeDEM, meanAzimutDEM);
+
+      filterMeanCor->Update();
+      double meanRangeCor, meanAzimutCor;
+      filterMeanCor->GetMean(meanRangeCor, meanAzimutCor);
+
+      // Difference between means
+      double diffMeanRange = meanRangeCor - meanRangeDEM;
+      double diffMeanAzimut = meanAzimutCor - meanAzimutDEM;
+
+      std::cout << "diffMeanRange = " << diffMeanRange << std::endl;
+      std::cout << "diffMeanAzimut = " << diffMeanAzimut << std::endl;
+
+      // Offset for DEMGrid (Correction with the difference)
+      // Instanciate all filters
+      ListConcatenerFilterType::Pointer m_Concatener =
+	ListConcatenerFilterType::New();
+      ExtractROIFilterListType::Pointer m_ExtractorList = 
+	ExtractROIFilterListType::New();
+      AddFilterListType::Pointer m_AddOffsetList = 
+	AddFilterListType::New();
+      ImageListType::Pointer m_ImageList =
+	ImageListType::New();
+
+      // Check number of components (at least two : range and azimut)
+      unsigned int nbComponents = DEMGridPtr->GetNumberOfComponentsPerPixel();
+      if (nbComponents < 2)
+	{
+	  otbAppLogFATAL(<< "Input grid has to contain at least two components");
+	}  
+
+      // Extract eah band and apply the corresponding offset
+      for (unsigned int i = 0; i < nbComponents; ++i)
+	{
+	  // Instanciate filters
+	  ExtractROIFilterType::Pointer extractor = 
+	    ExtractROIFilterType::New();
+	  AddFilterType::Pointer addOffset = 
+	    AddFilterType::New();
+
+	  // Set the channel to extract
+	  extractor->SetInput(DEMGridPtr);
+	  extractor->SetChannel(i+1);      
+	  extractor->UpdateOutputInformation();
+	  m_ExtractorList->PushBack(extractor);
+
+	  addOffset->SetInput(extractor->GetOutput());
+
+	  // Adapt offset according to the numnber of band
+	  if (i == 0)
+	    {
+	      addOffset->SetConstant2(diffMeanRange);
+	    }
+	  else if (i == 1)
+	    {
+	      addOffset->SetConstant2(diffMeanAzimut);
+	    }
+	  else
+	    {
+	      addOffset->SetConstant2(0);
+	    }
+      
+      
+	  m_AddOffsetList->PushBack(addOffset);
+	  m_ImageList->PushBack(addOffset->GetOutput() );
+      
+	}
   
-  SetParameterOutputImage("out", filterCorrectionGrid->GetOutput());
+      m_Concatener->SetInput( m_ImageList );
+
+      SetParameterOutputImage("out", m_Concatener->GetOutput());
+      RegisterPipeline();
+      //SetParameterOutputImage("out", DEMGridPtr);
+
+    }
       
 }
    // Vector for filters 
diff --git a/app/otbSARCorrelationGrid.cxx b/app/otbSARCorrelationGrid.cxx
index b908e2946afdefd6354871efff10aff6f913ba41..7976294dc787d51ade71678a69debb13785e7598 100644
--- a/app/otbSARCorrelationGrid.cxx
+++ b/app/otbSARCorrelationGrid.cxx
@@ -21,7 +21,10 @@
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
-#include "otbSARCorrelationGridImageFilter.h"
+#include "itkFFTNormalizedCorrelationImageFilter.h"
+#include "itkMinimumMaximumImageCalculator.h"
+
+#include "otbSARTemporalCorrelationGridImageFilter.h"
 
 #include <iostream>
 #include <string>
@@ -42,22 +45,23 @@ public:
   itkTypeMacro(SARCorrelationGrid, otb::Wrapper::Application);
 
   // Filters
-  typedef otb::SARCorrelationGridImageFilter<FloatImageType, FloatVectorImageType> CorGridFilterType;
+  typedef itk::FFTNormalizedCorrelationImageFilter<FloatImageType, FloatImageType>          CorFilterType;
+  typedef itk::MinimumMaximumImageCalculator< FloatImageType>			            MinMaxCalculatorType;
+  typedef otb::SARTemporalCorrelationGridImageFilter<FloatImageType, FloatVectorImageType>  CorGridFilterType;
   
 
 private:
   void DoInit() override
   {
     SetName("SARCorrelationGrid");
-    SetDescription("Computes SAR correlation grid.");
+    SetDescription("Computes SAR correlation shift (into temporal domain).");
 
-    SetDocLongDescription("This application creates a deformation grid based "
-      "on correlation estimation.\nThe output grid is a VectorImage composed of"
-      " three values : shift in range, shift in azimut and a correlation rate. "
-      "The inputs of this application are MultiLooked images (real images).");
+    SetDocLongDescription("This application computes correlation shifts between two images : "
+    "shift in range and shift in azimut. "
+    "The inputs of this application are MultiLooked images (real images).");
 
     //Optional descriptors
-    SetDocLimitations("Only Sentinel 1 products are supported for now.");
+    SetDocLimitations("Only Sentinel 1 products and Cosmo are supported for now.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
     AddDocTag(Tags::SAR);
@@ -69,13 +73,6 @@ private:
     AddParameter(ParameterType_InputImage,  "inslave",   "Input Slave image (real image)");
     SetParameterDescription("inslave", "Slave Image (real image).");
 
-    AddParameter(ParameterType_InputFilename,  "indem",   "Input DEM directory");
-    SetParameterDescription("indem", "Input DEM directory to help projection.");
-    MandatoryOff("indem");
-    
-    AddParameter(ParameterType_OutputImage, "out", "Output Correlation grid (Vector Image)");
-    SetParameterDescription("out","Output Correlation Grid Vector Image (Shift_ran, Shift_azi, Correlation_rate).");
-
     AddParameter(ParameterType_Int, "mlran", "MultiLook factor on distance");
     SetParameterDescription("mlran","MultiLook factor on distance.");
     SetDefaultParameterInt("mlran", 3);
@@ -87,12 +84,6 @@ private:
     SetDefaultParameterInt("mlazi", 3);
     SetMinimumParameterIntValue("mlazi", 1);
     MandatoryOff("mlazi");
-    
-    AddParameter(ParameterType_Int, "patchsize", "Size of patch into each dimension for correlation estimation");
-    SetParameterDescription("patchsize","Size of patch into each dimension for correlation estimation.");
-    SetDefaultParameterInt("patchsize", 20);
-    SetMinimumParameterIntValue("patchsize", 1);
-    MandatoryOff("patchsize");
 
     AddParameter(ParameterType_Int, "gridsteprange", "Grid step for range dimension (into SLC/SAR geometry)");
     SetParameterDescription("gridsteprange","Grid step for range dimension (into SLC/SAR geometry).");
@@ -106,18 +97,21 @@ private:
     SetMinimumParameterIntValue("gridstepazimut", 1);
     MandatoryOff("gridstepazimut");
 
-    AddParameter(ParameterType_Int,"subpixel","Subpixel measure");
-    SetParameterDescription("subpixel", "Subpixel measure.");
-    SetDefaultParameterInt("subpixel", 10);
-    SetMinimumParameterIntValue("subpixel", 1);
-    MandatoryOff("subpixel");
+    AddParameter(ParameterType_Int, "nooffset", "Set 0 to offset of first Line and Colunm of output grid");
+    SetParameterDescription("nooffset", "If 1, then no offset for the first L/C if output grid.");
+    SetDefaultParameterInt("nooffset", 0);
+    SetMinimumParameterIntValue("nooffset", 0);
+    MandatoryOff("nooffset");
 
+    // Parameter Output
+    AddParameter(ParameterType_OutputImage, "out", "Output Correlation grid (Vector Image)");
+    SetParameterDescription("out","Output Correlation Grid Vector Image (Shift_ran, Shift_azi, Correlation_rate).");
+    
     AddRAMParameter();
 
-    SetDocExampleParameterValue("indem","./DEMDir");
     SetDocExampleParameterValue("inmaster","s1a-s4-slc-vv-20160818t014650-20160818t014715-012648-013db1-002_ML.tiff");
     SetDocExampleParameterValue("inslave","s1b-s4-slc-vv-20160929t014610-20160929t014634-002277-003d71-002_ML.tiff");
-    SetDocExampleParameterValue("out","corGrid.tif");
+    SetDocExampleParameterValue("out", "out_CorrelationGrid.tiff");
   }
 
   void DoUpdateParameters() override
@@ -132,38 +126,57 @@ void DoExecute() override
   int factorML_ran = GetParameterInt("mlran");
   int grid_step_azi = GetParameterInt("gridstepazimut");
   int grid_step_ran = GetParameterInt("gridsteprange");
-  int patch_size = GetParameterInt("patchsize");
-  int subpixel = GetParameterInt("subpixel");
+  int nooffset = GetParameterInt("nooffset");
 
   // Log information
   otbAppLogINFO(<<"ML Factor on azimut :"<<factorML_azi);
   otbAppLogINFO(<<"ML Factor on range : "<<factorML_ran);
   otbAppLogINFO(<<"Grid Step for range : "<<grid_step_ran);
   otbAppLogINFO(<<"Grid Step for azimut : "<<grid_step_azi);
-  otbAppLogINFO(<<"Patch Size : "<<patch_size);
-  otbAppLogINFO(<<"SubPixel Measure : "<<subpixel);
 
   // Get master and slave image
   FloatImageType::Pointer MasterPtr = GetParameterFloatImage("inmaster");
   FloatImageType::Pointer SlavePtr = GetParameterFloatImage("inslave");
+   
   
-  // CorrelationGrid Filter
+  // Correlation Filter
+  CorFilterType::Pointer correlationFilter = CorFilterType::New();
+  m_Ref.push_back(correlationFilter.GetPointer());
+  correlationFilter->SetFixedImage(MasterPtr);
+  correlationFilter->SetMovingImage(SlavePtr);
+  correlationFilter->Update();
+
+  // Min/Max calculator
+  MinMaxCalculatorType::Pointer minMaxFilter = MinMaxCalculatorType::New();
+  minMaxFilter->SetImage(correlationFilter->GetOutput());
+  minMaxFilter->ComputeMaximum();
+
+  float shiftSLC_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
+		       minMaxFilter->GetIndexOfMaximum()[0]) * static_cast<float>(factorML_ran);
+  float shiftSLC_azimut = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2.)
+			-minMaxFilter->GetIndexOfMaximum()[1]) * static_cast<float>(factorML_azi);
+
+  float shiftML_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
+			  minMaxFilter->GetIndexOfMaximum()[0]);
+  float shiftML_azimut = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2.)
+  -minMaxFilter->GetIndexOfMaximum()[1]);
+
+  // Correlation Grid Filter 
   CorGridFilterType::Pointer filterCorrelationGrid = CorGridFilterType::New();
   m_Ref.push_back(filterCorrelationGrid.GetPointer());
 
   // Configure CorrelationGrid Filter
   filterCorrelationGrid->SetMLran(factorML_ran);
   filterCorrelationGrid->SetMLazi(factorML_azi);
-  filterCorrelationGrid->SetPatchSizePerDim(patch_size);
   filterCorrelationGrid->SetGridStep(grid_step_ran, grid_step_azi);
-  filterCorrelationGrid->SetSubPixelAccuracy(subpixel);
-  // Set DEM Directory if required
-  if (GetParameterByKey("indem")->HasValue())
+  filterCorrelationGrid->SetRoughShift_ran(shiftML_range);
+  filterCorrelationGrid->SetRoughShift_azi(shiftML_azimut);
+  if (nooffset)
     {
-      std::string demDir = GetParameterString("indem");
-      filterCorrelationGrid->activateDEM(demDir);
+      filterCorrelationGrid->SetFirstLCOffset(false);
     }
 
+  
   // Define the main pipeline 
   filterCorrelationGrid->SetMasterInput(MasterPtr);
   filterCorrelationGrid->SetSlaveInput(SlavePtr);
diff --git a/app/otbSARCorrelationRough.cxx b/app/otbSARCorrelationRough.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..39f9e00c0a841fa6909933b3e3e51917261dbafb
--- /dev/null
+++ b/app/otbSARCorrelationRough.cxx
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2005-2018 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "otbWrapperApplication.h"
+#include "otbWrapperApplicationFactory.h"
+
+#include "itkFFTNormalizedCorrelationImageFilter.h"
+#include "itkMinimumMaximumImageCalculator.h"
+
+#include <iostream>
+#include <string>
+#include <fstream>
+
+namespace otb
+{
+namespace Wrapper
+{
+
+class SARCorrelationRough : public Application
+{
+public:
+  typedef SARCorrelationRough Self;
+  typedef itk::SmartPointer<Self> Pointer; 
+
+  itkNewMacro(Self);
+  itkTypeMacro(SARCorrelationRough, otb::Wrapper::Application);
+
+  // Filters
+typedef itk::FFTNormalizedCorrelationImageFilter<FloatImageType, FloatImageType> CorFilterType;
+typedef itk::MinimumMaximumImageCalculator< FloatImageType>			    MinMaxCalculatorType;
+
+private:
+  void DoInit() override
+  {
+    SetName("SARCorrelationRough");
+    SetDescription("Computes SAR correlation shift (rough shifts).");
+
+    SetDocLongDescription("This application comutes rough shifts between two images : "
+    "shift in range and shift in azimut. "
+    "The inputs of this application are MultiLooked images (real images).");
+
+    //Optional descriptors
+    SetDocLimitations("Only Sentinel 1 products and Cosmo are supported for now.");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso(" ");
+    AddDocTag(Tags::SAR);
+
+    //Parameter declarations
+    AddParameter(ParameterType_InputImage,  "inmaster",   "Input Master image (real image)");
+    SetParameterDescription("inmaster", "Master Image (real image).");
+
+    AddParameter(ParameterType_InputImage,  "inslave",   "Input Slave image (real image)");
+    SetParameterDescription("inslave", "Slave Image (real image).");
+
+    AddParameter(ParameterType_Int, "mlran", "MultiLook factor on distance");
+    SetParameterDescription("mlran","MultiLook factor on distance.");
+    SetDefaultParameterInt("mlran", 3);
+    SetMinimumParameterIntValue("mlran", 1);
+    MandatoryOff("mlran");
+    
+    AddParameter(ParameterType_Int, "mlazi", "MultiLook factor on azimut");
+    SetParameterDescription("mlazi","MultiLook factor on azimut.");
+    SetDefaultParameterInt("mlazi", 3);
+    SetMinimumParameterIntValue("mlazi", 1);
+    MandatoryOff("mlazi");
+    
+    // Parameter Output
+    AddParameter(ParameterType_Float,"shiftranslc","rough shift in range dimension into SLC geometry (output of this application)");
+    SetParameterDescription("shiftranslc", "rough shift in range into SLC geometry.");
+    SetParameterRole("shiftranslc", Role_Output);
+    SetDefaultParameterFloat("shiftranslc", 0);
+
+    AddParameter(ParameterType_Float,"shiftazislc","rough shift in azimut dimension into SLC geometry (output of this application)");
+    SetParameterDescription("shiftazislc", "rough shift in azimut into SLC geometry .");
+    SetParameterRole("shiftazislc", Role_Output);
+    SetDefaultParameterFloat("shiftazislc", 0);
+
+    AddParameter(ParameterType_Float,"shiftranml","rough shift in range dimension into ML geometry (output of this application)");
+    SetParameterDescription("shiftranml", "rough shift in range into ML geometry.");
+    SetParameterRole("shiftranml", Role_Output);
+    SetDefaultParameterFloat("shiftranml", 0);
+
+    AddParameter(ParameterType_Float,"shiftaziml","rough shift in azimut dimension into ML geometry (output of this application)");
+    SetParameterDescription("shiftaziml", "rough shift in azimut into ML geometry .");
+    SetParameterRole("shiftaziml", Role_Output);
+    SetDefaultParameterFloat("shiftaziml", 0);
+   
+    AddRAMParameter();
+
+    SetDocExampleParameterValue("inmaster","s1a-s4-slc-vv-20160818t014650-20160818t014715-012648-013db1-002_ML.tiff");
+    SetDocExampleParameterValue("inslave","s1b-s4-slc-vv-20160929t014610-20160929t014634-002277-003d71-002_ML.tiff");
+  }
+
+  void DoUpdateParameters() override
+  {
+// Nothing to do here : all parameters are independent
+  }
+
+void DoExecute() override
+{  
+  // Get numeric parameters
+  int factorML_azi = GetParameterInt("mlazi");
+  int factorML_ran = GetParameterInt("mlran");
+
+  // Log information
+  otbAppLogINFO(<<"ML Factor on azimut :"<<factorML_azi);
+  otbAppLogINFO(<<"ML Factor on range : "<<factorML_ran);
+
+  // Get master and slave image
+  FloatImageType::Pointer MasterPtr = GetParameterFloatImage("inmaster");
+  FloatImageType::Pointer SlavePtr = GetParameterFloatImage("inslave");
+   
+  
+  // Correlation Filter
+  CorFilterType::Pointer correlationFilter = CorFilterType::New();
+  m_Ref.push_back(correlationFilter.GetPointer());
+  correlationFilter->SetFixedImage(MasterPtr);
+  correlationFilter->SetMovingImage(SlavePtr);
+  correlationFilter->Update();
+
+  // Min/Max calculator
+  MinMaxCalculatorType::Pointer minMaxFilter = MinMaxCalculatorType::New();
+  minMaxFilter->SetImage(correlationFilter->GetOutput());
+  minMaxFilter->ComputeMaximum();
+
+  float shiftSLC_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
+		       minMaxFilter->GetIndexOfMaximum()[0]) * static_cast<float>(factorML_ran);
+  float shiftSLC_azimut = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2.)
+			-minMaxFilter->GetIndexOfMaximum()[1]) * static_cast<float>(factorML_azi);
+
+  float shiftML_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
+			  minMaxFilter->GetIndexOfMaximum()[0]);
+  float shiftML_azimut = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2.)
+			   -minMaxFilter->GetIndexOfMaximum()[1]);
+
+  // Assigne Outputs
+  SetParameterFloat("shiftranslc", shiftSLC_range);
+  SetParameterFloat("shiftazislc", shiftSLC_azimut);
+  
+  SetParameterFloat("shiftranml", shiftML_range);
+  SetParameterFloat("shiftaziml", shiftML_azimut);
+}
+   // Vector for filters 
+  std::vector<itk::ProcessObject::Pointer> m_Ref;
+};
+
+
+}
+
+}
+
+OTB_APPLICATION_EXPORT(otb::Wrapper::SARCorrelationRough)
diff --git a/app/otbSARFineDeformationGrid.cxx b/app/otbSARFineDeformationGrid.cxx
index 3353a57490f688220433d82001c6322ae3c7dcf3..4686a1eeddb8b8fb26214860b51de9624d1b76ae 100644
--- a/app/otbSARFineDeformationGrid.cxx
+++ b/app/otbSARFineDeformationGrid.cxx
@@ -107,12 +107,6 @@ private:
     SetMinimumParameterIntValue("mlazi", 1);
     MandatoryOff("mlazi");
     
-    AddParameter(ParameterType_Int, "patchsize", "Size of patch into each dimension for correlation estimation");
-    SetParameterDescription("patchsize","Size of patch into each dimension for correlation estimation.");
-    SetDefaultParameterInt("patchsize", 20);
-    SetMinimumParameterIntValue("patchsize", 1);
-    MandatoryOff("patchsize");
-
     AddParameter(ParameterType_Int, "gridsteprange", "Grid step for range dimension (into SLC/SAR geometry)");
     SetParameterDescription("gridsteprange","Grid step for range dimension (into SLC/SAR geometry).");
     SetDefaultParameterInt("gridsteprange", 150);
@@ -125,12 +119,6 @@ private:
     SetMinimumParameterIntValue("gridstepazimut", 1);
     MandatoryOff("gridstepazimut");
 
-    AddParameter(ParameterType_Int,"subpixel","Subpixel measure");
-    SetParameterDescription("subpixel", "Subpixel measure.");
-    SetDefaultParameterInt("subpixel", 10);
-    SetMinimumParameterIntValue("subpixel", 1);
-    MandatoryOff("subpixel");
-
     AddParameter(ParameterType_Float, "threshold", "Threshold for correlation rate");
     SetParameterDescription("threshold","Threshold for correlation rate.");
     SetDefaultParameterFloat("threshold", 0.3);
@@ -142,6 +130,10 @@ private:
     SetDefaultParameterFloat("gap", 0.7);
     SetMinimumParameterFloatValue("gap", 0.01);
     MandatoryOff("gap");
+
+    AddParameter(ParameterType_String, "advantage", "Give an advantage to DEM or Correlation Grid");
+    SetParameterDescription("advantage","Give an advantage to DEM or Correlation Grid.");
+    MandatoryOff("advantage");
     
     SetDocExampleParameterValue("indem","S21E055.hgt");
     SetDocExampleParameterValue("insarmaster","s1a-s4-slc-vv-20160818t014650-20160818t014715-012648-013db1-002_SLC.tiff");
@@ -171,21 +163,39 @@ private:
     int factor_ran = GetParameterInt("mlran");
     int grid_step_azi = GetParameterInt("gridstepazimut");
     int grid_step_ran = GetParameterInt("gridsteprange");
-    int patch_size = GetParameterInt("patchsize");
-    int subpixel = GetParameterInt("subpixel");
     float threshold = GetParameterFloat("threshold");
     float gap = GetParameterFloat("gap");
+
+    std::string advantage = GetParameterString("advantage");
+    bool demGridToFavor = true;
+    
+    if (advantage == "correlation" || advantage == "cor" || advantage == "corgrid")
+      {
+	demGridToFavor = false;
+      } 
      
+    if (demGridToFavor)
+      {
+	otbAppLogINFO(<<"Opt in favor of projection (DEMGrid)");
+      }
+    else
+      {
+	otbAppLogINFO(<<"Opt in favor of correlation (CorGrid)");
+      }
+
+
     // Execute the Pipelone with internal applications
     // First application : SARCorrelationGrid
     GetInternalApplication("CorGridApp")->SetParameterInputImage("inmaster", inputMasterML);
     GetInternalApplication("CorGridApp")->SetParameterInputImage("inslave", inputSlaveML);
     GetInternalApplication("CorGridApp")->SetParameterInt("mlran", factor_ran);
     GetInternalApplication("CorGridApp")->SetParameterInt("mlazi", factor_azi);
-    GetInternalApplication("CorGridApp")->SetParameterInt("patchsize", patch_size);
     GetInternalApplication("CorGridApp")->SetParameterInt("gridsteprange", grid_step_ran);
     GetInternalApplication("CorGridApp")->SetParameterInt("gridstepazimut", grid_step_azi);
-    GetInternalApplication("CorGridApp")->SetParameterInt("subpixel", subpixel);
+    if (demGridToFavor)
+      {
+	GetInternalApplication("CorGridApp")->SetParameterInt("nooffset", 1);
+      }
     ExecuteInternal("CorGridApp");
 
     // Second application : SARDEMGrid
@@ -206,13 +216,14 @@ private:
     GetInternalApplication("DEMGridApp")->SetParameterInt("gridstepazimut", grid_step_azi);
     ExecuteInternal("DEMGridApp");
     
-    // Third (and last) application : SARMultiLook   
+    // Third (and last) application : SARMultiLook
     GetInternalApplication("CorrectionGridApp")->SetParameterInputImage("indemgrid", 
 			                 GetInternalApplication("DEMGridApp")->GetParameterOutputImage("out"));
     GetInternalApplication("CorrectionGridApp")->SetParameterInputImage("incorgrid", 
 					GetInternalApplication("CorGridApp")->GetParameterOutputImage("out"));
     GetInternalApplication("CorrectionGridApp")->SetParameterFloat("threshold", threshold);
     GetInternalApplication("CorrectionGridApp")->SetParameterFloat("gap", gap);
+    GetInternalApplication("CorrectionGridApp")->SetParameterString("advantage", advantage);
     ExecuteInternal("CorrectionGridApp");
     
     // Retrive the output of CorrectionGridApp
diff --git a/app/otbSARFineMetadata.cxx b/app/otbSARFineMetadata.cxx
index fb6069706f7c9727ad4b206a907ad6576b20097a..308af0d93a8b3e4399eaec32bed543f2ee724f74 100644
--- a/app/otbSARFineMetadata.cxx
+++ b/app/otbSARFineMetadata.cxx
@@ -22,6 +22,7 @@
 #include "otbWrapperApplicationFactory.h"
 
 #include "otbSARStreamingGridHistogramFilter.h"
+#include "otbSARUpdateMetadataImageFilter.h"
 
 #include <iostream>
 #include <string>
@@ -30,11 +31,20 @@
 #include <cmath>
 
 // include ossim
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
 #include "ossim/ossimTimeUtilities.h"
 #include "ossim/base/ossimKeywordlist.h"
 #include "ossim/base/ossimString.h"
 #include "ossim/base/ossimDate.h"
-
+#pragma GCC diagnostic pop
+#else
+#include "ossim/ossimTimeUtilities.h"
+#include "ossim/base/ossimKeywordlist.h"
+#include "ossim/base/ossimString.h"
+#include "ossim/base/ossimDate.h"
+#endif
 
 namespace otb
 {
@@ -52,6 +62,7 @@ public:
 
 // Filter
   typedef otb::SARStreamingGridHistogramFilter<FloatVectorImageType> GridHistogramType;
+  typedef otb::SARUpdateMetadataImageFilter<ComplexFloatImageType>   UpdateMetadataeFilter;
 
   // Time/Date ossim 
   typedef ossimplugins::time::ModifiedJulianDate TimeType;
@@ -101,6 +112,9 @@ private:
     AddParameter(ParameterType_Float,"slantrange","Slant near range (output of this application)");
     SetParameterDescription("slantrange", "Slant near range (output of this application).");
     SetParameterRole("slantrange", Role_Output);
+
+    AddParameter(ParameterType_OutputImage, "out", "Output image with precise metadata");
+    SetParameterDescription("out","Output image with precise metadata.");
     
     AddRAMParameter();
 
@@ -214,7 +228,15 @@ private:
     SetParameterString("timefirstline", fineTimeFirstLine);
 
     SetParameterFloat("slantrange", fineSlantRange);
-  
+
+    // Copie input image and update the metadata into a naw geom file
+    UpdateMetadataeFilter::Pointer updateMetadataFilter = UpdateMetadataeFilter::New();
+    m_Ref.push_back(updateMetadataFilter.GetPointer());
+    updateMetadataFilter->SetTimeFirstLine(fineTimeFirstLine);
+    updateMetadataFilter->SetSlantRange(fineSlantRange);
+    updateMetadataFilter->SetInput(SARPtr);
+
+    SetParameterOutputImage("out", updateMetadataFilter->GetOutput());
   }
 
   // Vector for filters 
diff --git a/include/otbSARDEMPolygonsAnalysisImageFilter.txx b/include/otbSARDEMPolygonsAnalysisImageFilter.txx
index 388997225c0fde787827516834c11662431cda93..34229bed64a14ead442d4401d8db7476cecbcf27 100644
--- a/include/otbSARDEMPolygonsAnalysisImageFilter.txx
+++ b/include/otbSARDEMPolygonsAnalysisImageFilter.txx
@@ -179,9 +179,13 @@ namespace otb
     // Set the margin
     int nbLinesSAR = m_SarImagePtr->GetLargestPossibleRegion().GetSize()[1];
     int nbLinesDEM = m_DemImagePtr->GetLargestPossibleRegion().GetSize()[1];
-    if (nbLinesSAR > nbLinesDEM)
+    if (nbLinesSAR/2 > nbLinesDEM)
       { 
-	m_Margin = (nbLinesSAR/nbLinesDEM)*5;
+	m_Margin = (nbLinesSAR/nbLinesDEM)*30;
+      }
+    else if (nbLinesSAR > nbLinesDEM)
+      {
+	m_Margin = (nbLinesSAR/nbLinesDEM)*60;
       }
     else
       {
@@ -1102,6 +1106,7 @@ namespace otb
 		while (!InIt_UR.IsAtEndOfLine() && !InIt_LR.IsAtEndOfLine())
 		  {
 		    UL_line = InIt_UL.Get()[1];
+
 		    // Protect Memory access and input access
 		    if (UL_line > ind_Line_Into_SARGeo - m_Margin && UL_line < ind_Line_Into_SARGeo + m_Margin)
 		      { 	 
@@ -1109,7 +1114,7 @@ namespace otb
 			UR_col = InIt_UR.Get()[0];
 			LR_col = InIt_LR.Get()[0];
 			LL_col = InIt_LL.Get()[0];
-
+		
 			// Check if No Data		    
 			if (!(UL_col == m_NoData || UR_col == m_NoData || LR_col == m_NoData 
 			      || LL_col == m_NoData))
diff --git a/include/otbSARDEMProjectionImageFilter.txx b/include/otbSARDEMProjectionImageFilter.txx
index da9ba196b899bef948fae568b2b09453f4ead39c..d70299e22e0f2620fcf878fc91f5f83f35d80945 100644
--- a/include/otbSARDEMProjectionImageFilter.txx
+++ b/include/otbSARDEMProjectionImageFilter.txx
@@ -29,8 +29,16 @@
 #include "itkProgressReporter.h"
 #include "itkNumericTraitsPointPixel.h"
 
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
 #include "ossim/base/ossimFilename.h"
 #include "ossim/base/ossimGpt.h"
+#pragma GCC diagnostic pop
+#else
+#include "ossim/base/ossimFilename.h"
+#include "ossim/base/ossimGpt.h"
+#endif
 
 #include <cmath>
 
diff --git a/include/otbSARDopplerCentroidFreqImageFilter.txx b/include/otbSARDopplerCentroidFreqImageFilter.txx
index 593e81b4ad02821f88bc4daab3ed0ea5d999cc63..a401dfb3f330c67b3e8a4e2e3a9bf77b328c5bb2 100644
--- a/include/otbSARDopplerCentroidFreqImageFilter.txx
+++ b/include/otbSARDopplerCentroidFreqImageFilter.txx
@@ -90,7 +90,7 @@ namespace otb
     
     for (std::size_t listId=0; listId!= nbLists ; ++listId) 
       {
-	const int pos = sprintf(fmRatePrefix_, "%s%d.", FM_PREFIX.c_str(), (listId+1));
+	const int pos = sprintf(fmRatePrefix_, "%s%zu.", FM_PREFIX.c_str(), (listId+1));
 	assert(pos > 0 && pos < sizeof(fmRatePrefix_));
 	const std::string FMPrefix(fmRatePrefix_, pos);
 
@@ -120,7 +120,7 @@ namespace otb
     
     for (std::size_t listId=0; listId!= nbLists ; ++listId) 
       {
-	const int pos = sprintf(dcfPrefix_, "%s%d.", DCF_PREFIX.c_str(), (listId+1));
+	const int pos = sprintf(dcfPrefix_, "%s%zu.", DCF_PREFIX.c_str(), (listId+1));
 	assert(pos > 0 && pos < sizeof(dcfPrefix_));
 	const std::string DCFPrefix(dcfPrefix_, pos);
 
diff --git a/include/otbSARESDOffsetsImageFilter.txx b/include/otbSARESDOffsetsImageFilter.txx
index 90dbcab741dc7ee29c8b17116d93a80fd91b9756..fc47727cb249bfb0b4b64ec99884a04e85c611d3 100644
--- a/include/otbSARESDOffsetsImageFilter.txx
+++ b/include/otbSARESDOffsetsImageFilter.txx
@@ -184,9 +184,6 @@ namespace otb
 	// For each colunm
 	while (!OutIt.IsAtEndOfLine() && !In1It.IsAtEndOfLine() && !In2It.IsAtEndOfLine()) 
 	  {
-	    // Output index
-	    ImageIndexType index = OutIt.GetIndex();
-
 	    double diff_DopCentroid = In1It.Get() - In2It.Get();
 
 	    // Shift for azimut dimension
diff --git a/include/otbSARCorrelationGridImageFilter.h b/include/otbSARFFTCorrelationGridImageFilter.h
similarity index 91%
rename from include/otbSARCorrelationGridImageFilter.h
rename to include/otbSARFFTCorrelationGridImageFilter.h
index 2beff8226b3fbd291f17405846f70500cc20f5ed..35533c5c206522e0811fb578faabd5d09e6cc54d 100644
--- a/include/otbSARCorrelationGridImageFilter.h
+++ b/include/otbSARFFTCorrelationGridImageFilter.h
@@ -18,8 +18,8 @@
  * limitations under the License.
  */
 
-#ifndef otbSARCorrelationGridImageFilter_h
-#define otbSARCorrelationGridImageFilter_h
+#ifndef otbSARFFTCorrelationGridImageFilter_h
+#define otbSARFFTCorrelationGridImageFilter_h
 
 #include "itkImageToImageFilter.h"
 #include "itkSmartPointer.h"
@@ -35,22 +35,23 @@
 
 namespace otb
 {
-  /** \class SARCorrelationGridImageFilter 
+  /** \class SARFFTCorrelationGridImageFilter 
    * \brief Estimates a deformation grid between two images (master and slave) for the azimut and range 
    * dimension. A correlation rate is also calculated. The DEM can be used. 
    * 
-   * This filter performs the estimation of deformations between two images (the images are reals).
+   * This filter performs the estimation of deformations between two images (the images are reals) in spectral 
+   * domain.
    * 
    * \ingroup DiapOTBModule
    */
 
-  template <typename TImageIn,  typename TImageOut> class ITK_EXPORT SARCorrelationGridImageFilter :
+  template <typename TImageIn,  typename TImageOut> class ITK_EXPORT SARFFTCorrelationGridImageFilter :
     public itk::ImageToImageFilter<TImageIn,TImageOut>
   {
   public:
 
     // Standard class typedefs
-    typedef SARCorrelationGridImageFilter                    Self;
+    typedef SARFFTCorrelationGridImageFilter                    Self;
     typedef itk::ImageToImageFilter<TImageIn,TImageOut>    Superclass;
     typedef itk::SmartPointer<Self>                        Pointer;
     typedef itk::SmartPointer<const Self>                  ConstPointer;
@@ -169,23 +170,23 @@ namespace otb
   
   protected:
     // Constructor
-    SARCorrelationGridImageFilter();
+    SARFFTCorrelationGridImageFilter();
 
     // Destructor
-    virtual ~SARCorrelationGridImageFilter() ITK_OVERRIDE {};
+    virtual ~SARFFTCorrelationGridImageFilter() ITK_OVERRIDE {};
 
     // Print
     void PrintSelf(std::ostream & os, itk::Indent indent) const ITK_OVERRIDE;
   
-    /** SARCorrelationGridImageFilter produces an vector image to indicate the deformation for the two dimensions 
+    /** SARFFTCorrelationGridImageFilter produces an vector image to indicate the deformation for the two dimensions 
      * and the correlation rate. The differences between output and input images are the size of images and the 
      * dimensions. The input images a classic images and the output is a otb::VectorImage with three components.
-     * As such, SARCorrelationGridImageFilter needs to provide an implementation for 
+     * As such, SARFFTCorrelationGridImageFilter needs to provide an implementation for 
      * GenerateOutputInformation() in order to inform the pipeline execution model. 
      */ 
     virtual void GenerateOutputInformation() ITK_OVERRIDE;
 
-    /** SARCorrelationGridImageFilter needs input requested regions (for master and slave images) that 
+    /** SARFFTCorrelationGridImageFilter needs input requested regions (for master and slave images) that 
      * corresponds to the projection into the requested region of the deformation grid (our output requested 
      * region).  
      * As such, SARQuadraticAveragingImageFilter needs to provide an implementation for 
@@ -198,7 +199,7 @@ namespace otb
      */
     void OutputRegionToInputRegion(const ImageOutRegionType& outputRegion) const;
 
-    /** SARCorrelationGridImageFilter can be implemented as a multithreaded filter.
+    /** SARFFTCorrelationGridImageFilter can be implemented as a multithreaded filter.
      * Therefore, this implementation provides a ThreadedGenerateData() routine
      * which is called for each processing thread. The output image data is
      * allocated automatically by the superclass prior to calling
@@ -218,7 +219,7 @@ namespace otb
 
 
   private:
-    SARCorrelationGridImageFilter(const Self&); // purposely not implemented
+    SARFFTCorrelationGridImageFilter(const Self&); // purposely not implemented
     void operator=(const Self &); // purposely not 
     
     /** Coarse correlation threshold */
@@ -268,7 +269,7 @@ namespace otb
 } // End namespace otb
 
 #ifndef OTB_MANUAL_INSTANTIATION
-#include "otbSARCorrelationGridImageFilter.txx"
+#include "otbSARFFTCorrelationGridImageFilter.txx"
 #endif
 
 
diff --git a/include/otbSARCorrelationGridImageFilter.txx b/include/otbSARFFTCorrelationGridImageFilter.txx
similarity index 93%
rename from include/otbSARCorrelationGridImageFilter.txx
rename to include/otbSARFFTCorrelationGridImageFilter.txx
index 6300fe1c5597ecaea224f490b59c925a2bf62bac..9b064c17a118a03ffaf1e157b2f6500c3887c5a7 100644
--- a/include/otbSARCorrelationGridImageFilter.txx
+++ b/include/otbSARFFTCorrelationGridImageFilter.txx
@@ -18,10 +18,10 @@
  * limitations under the License.
  */
 
-#ifndef otbSARCorrelationGridImageFilter_txx
-#define otbSARCorrelationGridImageFilter_txx
+#ifndef otbSARFFTCorrelationGridImageFilter_txx
+#define otbSARFFTCorrelationGridImageFilter_txx
 
-#include "otbSARCorrelationGridImageFilter.h"
+#include "otbSARFFTCorrelationGridImageFilter.h"
 
 #include "itkImageScanlineConstIterator.h"
 #include "itkImageRegionIterator.h"
@@ -45,7 +45,7 @@ namespace otb
    * Constructor with default initialization
    */
   template <class TImageIn, class TImageOut> 
-  SARCorrelationGridImageFilter< TImageIn ,TImageOut >::SARCorrelationGridImageFilter()
+  SARFFTCorrelationGridImageFilter< TImageIn ,TImageOut >::SARFFTCorrelationGridImageFilter()
   {
     this->SetNumberOfRequiredInputs(2);
  
@@ -70,7 +70,7 @@ namespace otb
    */ 
   template <class TImageIn, class TImageOut> 
   void
-  SARCorrelationGridImageFilter< TImageIn ,TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn ,TImageOut >
   ::SetMasterInput(const ImageInType* image )
   {
     // Process object is not const-correct so the const casting is required.
@@ -82,7 +82,7 @@ namespace otb
    */ 
   template <class TImageIn, class TImageOut> 
   void
-  SARCorrelationGridImageFilter< TImageIn ,TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn ,TImageOut >
   ::SetSlaveInput(const ImageInType* image)
   {
     // Process object is not const-correct so the const casting is required.
@@ -93,8 +93,8 @@ namespace otb
    * Get Master Image
    */ 
   template <class TImageIn, class TImageOut> 
-  const typename SARCorrelationGridImageFilter< TImageIn ,TImageOut>::ImageInType *
-  SARCorrelationGridImageFilter< TImageIn ,TImageOut >
+  const typename SARFFTCorrelationGridImageFilter< TImageIn ,TImageOut>::ImageInType *
+  SARFFTCorrelationGridImageFilter< TImageIn ,TImageOut >
   ::GetMasterInput() const
   {
     if (this->GetNumberOfInputs()<1)
@@ -108,8 +108,8 @@ namespace otb
    * Get Slave Image
    */ 
   template <class TImageIn, class TImageOut> 
-  const typename SARCorrelationGridImageFilter< TImageIn ,TImageOut>::ImageInType *
-  SARCorrelationGridImageFilter< TImageIn ,TImageOut >
+  const typename SARFFTCorrelationGridImageFilter< TImageIn ,TImageOut>::ImageInType *
+  SARFFTCorrelationGridImageFilter< TImageIn ,TImageOut >
   ::GetSlaveInput() const
   {
     if (this->GetNumberOfInputs()<2)
@@ -124,7 +124,7 @@ namespace otb
    */
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::PrintSelf(std::ostream & os, itk::Indent indent) const
   {
     Superclass::PrintSelf(os, indent);
@@ -140,7 +140,7 @@ namespace otb
    */
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::activateDEM(const std::string DEMDirectory)
   {
     DEMHandlerPointerType DEMHandler = DEMHandler::Instance();
@@ -153,7 +153,7 @@ namespace otb
    **/
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::GenerateOutputInformation()
   {    
     // Call superclass implementation
@@ -269,7 +269,7 @@ namespace otb
    */
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::OutputRegionToInputRegion(const ImageOutRegionType& outputRegion) const
   {
     // Get pointers to inputs
@@ -302,7 +302,7 @@ namespace otb
 
     //////////////////// Requested region for slave ////////////////////
     //int max_shift = 10;
-    int max_shift = 50;
+    int max_shift = 200;
     int firstL, firstC, lastL, lastC; 
     // Transform back into slave region index space with an maximum shift between master and slave
     ImageInIndexType slaveIndex;
@@ -350,7 +350,7 @@ namespace otb
     masterRequestedRegion.PadByRadius( m_PatchSizePerDim / 2 );
     slaveRequestedRegion.PadByRadius( m_PatchSizePerDim / 2 );
     
-    // Crop the fixed region at the fixed's largest possible region
+    // Crop the fixed region at the fixed's largest possible region (or buffered)
      if ( masterRequestedRegion.Crop(masterPtr->GetLargestPossibleRegion()))
       {
 	masterPtr->SetRequestedRegion( masterRequestedRegion );
@@ -400,7 +400,7 @@ namespace otb
    */
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::GenerateInputRequestedRegion()
   {
     // Call the superclass' implementation of this method
@@ -416,7 +416,7 @@ namespace otb
    */
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::BeforeThreadedGenerateData()
   { 
     // Get the number of threads
@@ -511,6 +511,7 @@ namespace otb
 	m_slaveExtractPieceTab[i]->SetRegions(slaveRegion);
 	m_slaveExtractPieceTab[i]->Allocate();
       }
+
   }
 
   /**
@@ -518,10 +519,10 @@ namespace otb
    */
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::AfterThreadedGenerateData()
   {
-    // Get the number of threads
+   // Get the number of threads
     unsigned int nbThreads = this->GetNumberOfThreads();
     
     for (unsigned int i = 0; i < nbThreads; i++) 
@@ -558,7 +559,7 @@ namespace otb
    */
   template<class TImageIn, class TImageOut>
   void
-  SARCorrelationGridImageFilter< TImageIn, TImageOut >
+  SARFFTCorrelationGridImageFilter< TImageIn, TImageOut >
   ::ThreadedGenerateData(const ImageOutRegionType& outputRegionForThread,
 			 itk::ThreadIdType threadId)
   {
@@ -670,6 +671,25 @@ namespace otb
 		slaveCurrentRegion.SetIndex(currentSlaveIndex);
 	      }
 
+	    // Check Size
+	    if (slaveCurrentRegion.GetIndex()[0] + slaveCurrentRegion.GetSize()[0]  > slavePtr->GetLargestPossibleRegion().GetSize()[0]
+		|| slaveCurrentRegion.GetIndex()[1] + slaveCurrentRegion.GetSize()[1]  > slavePtr->GetLargestPossibleRegion().GetSize()[1])
+	      {
+		for(unsigned int i = 0; i < ImageInType::ImageDimension; i++)
+		  {
+		    if (slaveCurrentRegion.GetIndex()[i] + slaveCurrentRegion.GetSize()[i]  > slavePtr->GetLargestPossibleRegion().GetSize()[i])
+		      {
+			currentSlaveSize[i] = slavePtr->GetLargestPossibleRegion().GetSize()[i] - slaveCurrentRegion.GetIndex()[i];
+
+			if (slaveCurrentRegion.GetIndex()[i] >= slavePtr->GetLargestPossibleRegion().GetSize()[i])
+			  {
+			    currentSlaveSize[i] = 0;
+			  }
+		      }
+		  }
+		slaveCurrentRegion.SetSize(currentSlaveSize);
+	      }
+
 	    // Rescale values to adapt the deformation
 	    double rescale_range = masterCurrentRegion.GetSize()[0];
 	    double rescale_azimut = masterCurrentRegion.GetSize()[1];
diff --git a/include/otbSARTemporalCorrelationGridImageFilter.h b/include/otbSARTemporalCorrelationGridImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..76002481bdb0f44c8c084a4a0ebce6499b362158
--- /dev/null
+++ b/include/otbSARTemporalCorrelationGridImageFilter.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2005-2018 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef otbSARTemporalCorrelationGridImageFilter_h
+#define otbSARTemporalCorrelationGridImageFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "itkSmartPointer.h"
+#include "itkPoint.h"
+
+#include "otbImageKeywordlist.h"
+#include "otbGenericRSTransform.h"
+#include "itkMinimumMaximumImageCalculator.h"
+#include "itkStatisticsImageFilter.h"
+#include "itkRescaleIntensityImageFilter.h"
+
+#include "itkFFTWCommon.h"
+
+namespace otb
+{
+  /** \class SARTemporalCorrelationGridImageFilter 
+   * \brief Estimates a deformation grid between two images (master and slave) for the azimut and range 
+   * dimension. A correlation rate is also calculated. The correlation is estimed into the temporal domain
+   * 
+   * This filter performs the estimation of deformations between two images (the images are reals).
+   * 
+   * \ingroup DiapOTBModule
+   */
+
+  template <typename TImageIn,  typename TImageOut> class ITK_EXPORT SARTemporalCorrelationGridImageFilter :
+    public itk::ImageToImageFilter<TImageIn,TImageOut>
+  {
+  public:
+
+    // Standard class typedefs
+    typedef SARTemporalCorrelationGridImageFilter                    Self;
+    typedef itk::ImageToImageFilter<TImageIn,TImageOut>    Superclass;
+    typedef itk::SmartPointer<Self>                        Pointer;
+    typedef itk::SmartPointer<const Self>                  ConstPointer;
+
+    // Method for creation through object factory
+    itkNewMacro(Self);
+    // Run-time type information
+    itkTypeMacro(SARCorrelationGridFilter,ImageToImageFilter);
+
+    /** Typedef to image input type : otb::Image for master and slave images */
+    typedef TImageIn                                  ImageInType;
+    /** Typedef to describe the inout image pointer type. */
+    typedef typename ImageInType::Pointer             ImageInPointer;
+    typedef typename ImageInType::ConstPointer        ImageInConstPointer;
+    /** Typedef to describe the inout image region type. */
+    typedef typename ImageInType::RegionType          ImageInRegionType;
+    /** Typedef to describe the type of pixel and point for inout image. */
+    typedef typename ImageInType::PixelType           ImageInPixelType;
+    typedef typename ImageInType::PointType           ImageInPointType;
+    /** Typedef to describe the image index, size types and spacing for inout image. */
+    typedef typename ImageInType::IndexType           ImageInIndexType;
+    typedef typename ImageInType::IndexValueType      ImageInIndexValueType;
+    typedef typename ImageInType::SizeType            ImageInSizeType;
+    typedef typename ImageInType::SizeValueType       ImageInSizeValueType;
+    typedef typename ImageInType::SpacingType         ImageInSpacingType;
+    typedef typename ImageInType::SpacingValueType    ImageInSpacingValueType;
+  
+    /** Typedef to image output type : otb::VectorImage with three components (range deformations, 
+	azimut deformations and correlation rate) */
+    typedef TImageOut                                  ImageOutType;
+    /** Typedef to describe the output image pointer type. */
+    typedef typename ImageOutType::Pointer             ImageOutPointer;
+    typedef typename ImageOutType::ConstPointer        ImageOutConstPointer;
+    /** Typedef to describe the output image region type. */
+    typedef typename ImageOutType::RegionType          ImageOutRegionType;
+    /** Typedef to describe the type of pixel and point for output image. */
+    typedef typename ImageOutType::PixelType           ImageOutPixelType;
+    typedef typename ImageOutType::PointType           ImageOutPointType;
+    /** Typedef to describe the image index, size types and spacing for output image. */
+    typedef typename ImageOutType::IndexType           ImageOutIndexType;
+    typedef typename ImageOutType::IndexValueType      ImageOutIndexValueType;
+    typedef typename ImageOutType::SizeType            ImageOutSizeType;
+    typedef typename ImageOutType::SizeValueType       ImageOutSizeValueType;
+    typedef typename ImageOutType::SpacingType         ImageOutSpacingType;
+    typedef typename ImageOutType::SpacingValueType    ImageOutSpacingValueType;
+
+
+    // Define Point2DType and Point3DType
+    using Point2DType = itk::Point<double,2>;
+    using Point3DType = itk::Point<double,3>;
+
+
+    // Define Filter used here (ie : RSTRansform from Master to Slave)
+    typedef typename itk::MinimumMaximumImageCalculator< ImageInType>			    MinMaxCalculatorType;
+    typedef typename itk::RescaleIntensityImageFilter< ImageInType, ImageInType >           RescaleFilterType;
+
+     // ITK proxy to the fftw library
+    typedef typename itk::fftw::Proxy<ImageInPixelType> FFTWProxyType;
+    typedef typename FFTWProxyType::ComplexType         FFTProxyComplexType;
+    typedef typename FFTWProxyType::PixelType           FFTProxyPixelType;
+    typedef typename FFTWProxyType::PlanType            FFTProxyPlanType;
+
+    // Setter/Getter
+    itkSetMacro(RoughShift_ran, int);
+    itkGetMacro(RoughShift_ran, int);
+    itkSetMacro(RoughShift_azi, int);
+    itkGetMacro(RoughShift_azi, int);
+
+    /** Set/Get fine coherency threshold */
+    itkSetMacro(CorrelationThreshold, double);
+    itkGetMacro(CorrelationThreshold, double);
+
+    /** Set/Get unsigned int grid step */
+    void SetGridStep(unsigned int stepRange, unsigned int stepAzimut)
+    {
+      m_GridStep[0] = stepRange;
+      m_GridStep[1] = stepAzimut;
+    }
+    unsigned int GetGridStepRange()
+    {
+      return m_GridStep[0];
+    }
+    unsigned int GetGridStepAzimut()
+    {
+      return m_GridStep[1];
+    }
+    /** Set/Get ML factors */
+    itkSetMacro(MLran, unsigned int);
+    itkGetMacro(MLran, unsigned int);
+    itkSetMacro(MLazi, unsigned int);
+    itkGetMacro(MLazi, unsigned int);
+
+    itkSetMacro(FirstLCOffset, bool);
+    itkGetMacro(FirstLCOffset, bool);
+
+    // Setter/Getter for master and slave images (inputs)
+    /** Connect one of the operands for registration */
+    void SetMasterInput( const ImageInType* image);
+
+    /** Connect one of the operands for registration */
+    void SetSlaveInput(const ImageInType* image);
+
+    /** Get the inputs */
+    const ImageInType * GetMasterInput() const;
+    const ImageInType * GetSlaveInput() const;
+  
+  protected:
+    // Constructor
+    SARTemporalCorrelationGridImageFilter();
+
+    // Destructor
+    virtual ~SARTemporalCorrelationGridImageFilter() ITK_OVERRIDE {};
+
+    // Print
+    void PrintSelf(std::ostream & os, itk::Indent indent) const ITK_OVERRIDE;
+  
+    /** SARTemporalCorrelationGridImageFilter produces an vector image to indicate the deformation for the two dimensions 
+     * and the correlation rate. The differences between output and input images are the size of images and the 
+     * dimensions. The input images a classic images and the output is a otb::VectorImage with three components.
+     * As such, SARTemporalCorrelationGridImageFilter needs to provide an implementation for 
+     * GenerateOutputInformation() in order to inform the pipeline execution model. 
+     */ 
+    virtual void GenerateOutputInformation() ITK_OVERRIDE;
+
+    /** SARTemporalCorrelationGridImageFilter needs input requested regions (for master and slave images) that 
+     * corresponds to the projection into the requested region of the deformation grid (our output requested 
+     * region).  
+     * As such, SARQuadraticAveragingImageFilter needs to provide an implementation for 
+     * GenerateInputRequestedRegion() in order to inform the pipeline execution model. 
+     * \sa ProcessObject::GenerateInputRequestedRegion() */
+    virtual void GenerateInputRequestedRegion() ITK_OVERRIDE;
+
+    /**
+     * OutputRegionToInputRegion assigne master and slave regions 
+     */
+    void OutputRegionToInputRegion(const ImageOutRegionType& outputRegion);
+
+    /** SARTemporalCorrelationGridImageFilter can be implemented as a multithreaded filter.
+     * Therefore, this implementation provides a ThreadedGenerateData() routine
+     * which is called for each processing thread. The output image data is
+     * allocated automatically by the superclass prior to calling
+     * ThreadedGenerateData().  ThreadedGenerateData can only write to the
+     * portion of the output image specified by the parameter
+     * "outputRegionForThread"
+     *
+     * \sa ImageToImageFilter::ThreadedGenerateData(),
+     *     ImageToImageFilter::GenerateData() */
+    void ThreadedGenerateData(const ImageOutRegionType& outputRegionForThread,
+			      itk::ThreadIdType threadId ) override;
+
+
+  private:
+    SARTemporalCorrelationGridImageFilter(const Self&); // purposely not implemented
+    void operator=(const Self &); // purposely not 
+
+    /** Function to interpolate the best interger shift */
+    void PIC(float TAB_PIC[3][3], float *DX, float *DY, float *VAL_MAX, int *CR) const;
+
+    inline double Correlation(const std::vector<double>& master,
+			      const std::vector<double>& slave) const;
+
+    inline double CorrelationDiapason(const std::vector<double>& master,
+			      const std::vector<double>& slave) const;
+    
+    /** Coarse correlation threshold */
+    double m_CorrelationThreshold;
+
+    /** Grid step */
+    ImageInSizeType m_GridStep;
+
+    /** Grid step into ML geometry */
+    ImageInSizeType m_GridStep_ML;
+
+    /** ML factors (in range and in azimut) */
+    unsigned int m_MLran;
+    unsigned int m_MLazi;
+
+    /** Input rough shifts */
+    int m_RoughShift_ran;
+    int m_RoughShift_azi;
+
+    /** Search Window around rough shifts (into ML geometry) */
+    int m_WinAround_ShiftRan;
+    int m_WinAround_ShiftAzi;
+
+    /** Window size to estimate correlation */
+    int m_WinCor_ran;
+    int m_WinCor_azi;
+
+    // Extract Parameters
+    ImageInPointer * m_masterExtractPieceTab;
+    ImageInPointer * m_slaveExtractPieceTab;
+
+    // Boolean to add an offset on the first L/C on the grid
+    bool m_FirstLCOffset;
+    
+  };
+
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbSARTemporalCorrelationGridImageFilter.txx"
+#endif
+
+
+
+#endif
diff --git a/include/otbSARTemporalCorrelationGridImageFilter.txx b/include/otbSARTemporalCorrelationGridImageFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..38191291b28e81fe7b017e0fef437c6d08ba991d
--- /dev/null
+++ b/include/otbSARTemporalCorrelationGridImageFilter.txx
@@ -0,0 +1,864 @@
+/*
+ * Copyright (C) 2005-2018 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef otbSARTemporalCorrelationGridImageFilter_txx
+#define otbSARTemporalCorrelationGridImageFilter_txx
+
+#include "otbSARTemporalCorrelationGridImageFilter.h"
+
+#include "itkImageScanlineConstIterator.h"
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkImageScanlineIterator.h"
+#include "itkProgressReporter.h"
+#include "itkNumericTraitsPointPixel.h"
+#include "itkContinuousIndex.h"
+
+#include "otbDEMHandler.h"
+
+#include "itkFFTWCommon.h"
+#include "itkFFTWGlobalConfiguration.h"
+
+#include <cmath>
+
+
+namespace otb
+{
+  /** 
+   * Constructor with default initialization
+   */
+  template <class TImageIn, class TImageOut> 
+  SARTemporalCorrelationGridImageFilter< TImageIn ,TImageOut >::SARTemporalCorrelationGridImageFilter()
+  {
+    this->SetNumberOfRequiredInputs(2);
+ 
+    // Default window sizes
+    m_WinAround_ShiftRan = 10;
+    m_WinAround_ShiftAzi = 20;
+    m_WinCor_ran = 10;
+    m_WinCor_azi = 10;    
+ 
+    // Default rough shits (0)
+    m_RoughShift_ran = 0;
+    m_RoughShift_azi = 0;
+
+    // Grid Step
+    m_GridStep.Fill(1);
+    m_GridStep_ML.Fill(1);
+
+    m_CorrelationThreshold = 0.3;
+
+    m_FirstLCOffset = true;
+
+    m_MLran = 3;
+    m_MLazi = 3;
+  }
+
+  /**
+   * Set Master Image
+   */ 
+  template <class TImageIn, class TImageOut> 
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn ,TImageOut >
+  ::SetMasterInput(const ImageInType* image )
+  {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(0, const_cast<ImageInType *>(image));
+  }
+
+  /**
+   * Set Slave Image
+   */ 
+  template <class TImageIn, class TImageOut> 
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn ,TImageOut >
+  ::SetSlaveInput(const ImageInType* image)
+  {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(1, const_cast<ImageInType *>(image));
+  }
+
+  /**
+   * Get Master Image
+   */ 
+  template <class TImageIn, class TImageOut> 
+  const typename SARTemporalCorrelationGridImageFilter< TImageIn ,TImageOut>::ImageInType *
+  SARTemporalCorrelationGridImageFilter< TImageIn ,TImageOut >
+  ::GetMasterInput() const
+  {
+    if (this->GetNumberOfInputs()<1)
+      {
+	return 0;
+      }
+    return static_cast<const ImageInType *>(this->itk::ProcessObject::GetInput(0));
+  }
+
+  /**
+   * Get Slave Image
+   */ 
+  template <class TImageIn, class TImageOut> 
+  const typename SARTemporalCorrelationGridImageFilter< TImageIn ,TImageOut>::ImageInType *
+  SARTemporalCorrelationGridImageFilter< TImageIn ,TImageOut >
+  ::GetSlaveInput() const
+  {
+    if (this->GetNumberOfInputs()<2)
+      {
+	return 0;
+      }
+    return static_cast<const ImageInType *>(this->itk::ProcessObject::GetInput(1));
+  }
+
+  /**
+   * Print
+   */
+  template<class TImageIn, class TImageOut>
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::PrintSelf(std::ostream & os, itk::Indent indent) const
+  {
+    Superclass::PrintSelf(os, indent);
+    
+    os << indent << "ML range factor : " << m_MLran << std::endl;
+    os << indent << "ML azimut factor : " << m_MLazi << std::endl;
+    os << indent << "Step for the grid : " << m_GridStep[0] << ", " << m_GridStep[1] << std::endl;
+  }
+
+  /**
+   * Method GenerateOutputInformaton()
+   **/
+  template<class TImageIn, class TImageOut>
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::GenerateOutputInformation()
+  {    
+    // Call superclass implementation
+    Superclass::GenerateOutputInformation();
+
+    // Get pointers to the input and output
+    ImageInType * masterPtr  = const_cast<ImageInType * >(this->GetMasterInput());
+    ImageInType * slavePtr  = const_cast<ImageInType * >(this->GetSlaveInput());
+    ImageOutPointer outputPtr = this->GetOutput();
+  
+    // Check GridSteps (must be a multiple of ML Factors)
+    if (m_GridStep[0] % m_MLran)
+      {
+	itkExceptionMacro(<<"GridSteps range mot a multiple of MLRan.");
+      }
+    if (m_GridStep[1] % m_MLazi)
+      {
+	itkExceptionMacro(<<"GridSteps azimut mot a multiple of MLAzi.");
+      }
+
+    m_GridStep_ML[0] = m_GridStep[0]/m_MLran;
+    m_GridStep_ML[1] = m_GridStep[1]/m_MLazi;
+
+    ///////// Checks (with input keywordlists/metadata) /////////////
+    // Check ML Factors (inputs of this filter with Master and Slave metadata)
+    // Get Master and Slave Keywordlist
+    ImageKeywordlist masterKWL = masterPtr->GetImageKeywordlist();
+    ImageKeywordlist slaveKWL = slavePtr->GetImageKeywordlist();
+
+    if (masterKWL.HasKey("support_data.ml_ran") && masterKWL.HasKey("support_data.ml_azi"))
+      {
+	// Get Master ML Factors
+	unsigned int master_MLRan = atoi(masterKWL.GetMetadataByKey("support_data.ml_ran").c_str());
+	unsigned int master_MLAzi = atoi(masterKWL.GetMetadataByKey("support_data.ml_azi").c_str());
+
+	if (slaveKWL.HasKey("support_data.ml_ran") && slaveKWL.HasKey("support_data.ml_azi"))
+	  {
+	    // Get Slave ML Factors
+	    unsigned int slave_MLRan = atoi(slaveKWL.GetMetadataByKey("support_data.ml_ran").c_str());
+	    unsigned int slave_MLAzi = atoi(slaveKWL.GetMetadataByKey("support_data.ml_azi").c_str());
+
+	    if ((slave_MLRan != master_MLRan) || (slave_MLAzi != master_MLAzi))
+	      {
+		itkExceptionMacro(<<"ML Factor betwwen master and slave are different.");
+	      }
+	  }
+	
+	if ((master_MLRan != m_MLran) || (master_MLAzi != m_MLazi))
+	  {
+	    itkExceptionMacro(<<"ML Factor betwwen master and inputs of this application are different.");
+	  }
+      }
+    else
+      {
+	if (slaveKWL.HasKey("support_data.ml_ran") && slaveKWL.HasKey("support_data.ml_azi"))
+	  {
+	    // Get Slave ML Factors
+	    unsigned int slave_MLRan = atoi(slaveKWL.GetMetadataByKey("support_data.ml_ran").c_str());
+	    unsigned int slave_MLAzi = atoi(slaveKWL.GetMetadataByKey("support_data.ml_azi").c_str());
+	    
+	    if ((slave_MLRan != m_MLran) || (slave_MLAzi != m_MLazi))
+	      {
+		itkExceptionMacro(<<"ML Factor betwwen slave and inputs of this application are different.");
+	      }
+	  }
+      }
+
+    // Set the number of Components for the Output VectorImage
+    // 3 Components :  
+    //                _ range shift between Master and Slave
+    //                _ azimut shift between Master and Slave
+    //                _ correlation rate
+    outputPtr->SetNumberOfComponentsPerPixel(3);
+
+    // Update size and spacing according to grid step
+    ImageOutRegionType largestRegion  = static_cast<ImageOutRegionType>(masterPtr->GetLargestPossibleRegion());
+    ImageOutSizeType outputSize = static_cast<ImageOutSizeType>(largestRegion.GetSize());
+    ImageOutSpacingType outputSpacing = static_cast<ImageOutSpacingType>(masterPtr->GetSpacing());
+    ImageOutPointType outputOrigin = static_cast<ImageOutPointType>(masterPtr->GetOrigin());
+
+    // First/Last Colunm and row with an offet
+    int firstC_master = 0;
+    int firstL_master = 0;
+    if (m_FirstLCOffset)
+      {
+	int firstC = std::max (1 + m_WinCor_ran, 1 + m_WinCor_ran - m_RoughShift_ran + m_WinAround_ShiftRan);
+	int firstL = std::max (1 + m_WinCor_azi, 1 + m_WinCor_azi - m_RoughShift_azi + m_WinAround_ShiftAzi);
+	int lastC = std::min(slavePtr->GetLargestPossibleRegion().GetSize()[0] - m_RoughShift_ran - 
+			     m_WinAround_ShiftRan - m_WinCor_ran, 
+			     masterPtr->GetLargestPossibleRegion().GetSize()[0]- m_WinCor_ran);
+	int lastL = std::min(slavePtr->GetLargestPossibleRegion().GetSize()[1] - m_RoughShift_azi - 
+			     m_WinAround_ShiftAzi- m_WinCor_azi, 
+			     masterPtr->GetLargestPossibleRegion().GetSize()[1] - m_WinCor_azi);
+    
+	outputSize[0]= lastC - firstC + 1;
+	outputSize[1] = lastL - firstL + 1;
+
+	for(unsigned int dim = 0; dim < ImageOutType::ImageDimension; ++dim)
+	  {
+	    outputSize[dim] = (outputSize[dim] - outputSize[dim]%m_GridStep_ML[dim]) / m_GridStep_ML[dim];
+	    outputSpacing[dim] *= m_GridStep_ML[dim];
+	  }
+
+	firstL_master   = firstL + (lastL - firstL + 1 - m_GridStep_ML[1] * (outputSize[1])) / 2;
+	firstC_master = firstC + (lastC - firstC + 1 - m_GridStep_ML[0] * (outputSize[0])) / 2;
+      }
+    else
+      {
+	for(unsigned int dim = 0; dim < ImageOutType::ImageDimension; ++dim)
+	  {
+	    outputSize[dim] = (outputSize[dim] - outputSize[dim]%m_GridStep_ML[dim]) / m_GridStep_ML[dim];
+	    outputSpacing[dim] *= m_GridStep_ML[dim];
+	  }
+      }
+
+    
+    
+    // Set spacing
+    outputPtr->SetSpacing(outputSpacing);
+
+    // Set origin
+    outputPtr->SetOrigin(outputOrigin);
+
+    // Set largest region size
+    largestRegion.SetSize(outputSize);
+    outputPtr->SetLargestPossibleRegion(largestRegion);
+
+    // Add GridSteps into KeyWordList
+    ImageKeywordlist outputKWL;
+    outputKWL.AddKey("support_data.gridstep.range", std::to_string(m_GridStep[0]));
+    outputKWL.AddKey("support_data.gridstep.azimut", std::to_string(m_GridStep[1]));
+    
+    if (m_FirstLCOffset)
+      {
+	// Add first L/C into SLC geometry
+	float firstC_SLC = (firstC_master)*m_MLran;  
+	float firstL_SLC = (firstL_master)*m_MLazi;
+
+	outputKWL.AddKey("support_data.grid.first_row", std::to_string(firstL_SLC));
+	outputKWL.AddKey("support_data.grid.first_column", std::to_string(firstC_SLC));
+      }
+
+    outputPtr->SetImageKeywordList(outputKWL); 
+  }
+
+  /** 
+   * Method OutputRegionToInputRegion for GenerateInputRequestedRegion
+   */
+  template<class TImageIn, class TImageOut>
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::OutputRegionToInputRegion(const ImageOutRegionType& outputRegion)
+  {
+    // Get pointers to inputs
+    ImageInType * masterPtr = const_cast<ImageInType * >(GetMasterInput());
+    ImageInType * slavePtr = const_cast<ImageInType * >(GetSlaveInput());
+
+    ImageOutPointer outputPtr = this->GetOutput();
+    
+    int nbColSlave = slavePtr->GetLargestPossibleRegion().GetSize()[0];
+    int nbLinesSlave = slavePtr->GetLargestPossibleRegion().GetSize()[1];
+    
+    /////////////////////// Requested region for master ////////////////////
+    // Correlation grid is bonded to the master image => should represent with the 
+    // m_Grid_step the output requested region
+    // get a copy of the master requested region (should equal the output
+    // requested region)
+    ImageInRegionType masterRequestedRegion, slaveRequestedRegion;
+    masterRequestedRegion = outputRegion;
+
+    // Apply grid step
+    ImageInSizeType masterRequestedSize = masterRequestedRegion.GetSize();
+    ImageInIndexType masterRequestedIndex = masterRequestedRegion.GetIndex();
+  
+    for(unsigned int dim = 0; dim < ImageOutType::ImageDimension; ++dim)
+      {
+	masterRequestedSize [dim] *= m_GridStep_ML[dim];
+	masterRequestedIndex[dim] *= m_GridStep_ML[dim];
+      }
+    
+    int firstC_Grid = 0;
+    int firstL_Grid = 0;
+
+     if (m_FirstLCOffset)
+       {
+	 int firstC = std::max (1 + m_WinCor_ran, 1 + m_WinCor_ran - m_RoughShift_ran + m_WinAround_ShiftRan);
+	 int firstL = std::max (1 + m_WinCor_azi, 1 + m_WinCor_azi - m_RoughShift_azi + m_WinAround_ShiftAzi);
+	 int lastC = std::min(slavePtr->GetLargestPossibleRegion().GetSize()[0] - m_RoughShift_ran - 
+			      m_WinAround_ShiftRan - m_WinCor_ran, 
+			      masterPtr->GetLargestPossibleRegion().GetSize()[0]- m_WinCor_ran);
+	 int lastL = std::min(slavePtr->GetLargestPossibleRegion().GetSize()[1] - m_RoughShift_azi - 
+			      m_WinAround_ShiftAzi- m_WinCor_azi, 
+			      masterPtr->GetLargestPossibleRegion().GetSize()[1] - m_WinCor_azi);
+	 
+
+	 firstC_Grid = firstC + (lastC - firstC + 1 - m_GridStep_ML[0] * 
+				 (outputPtr->GetLargestPossibleRegion().GetSize()[0])) / 2;
+	 firstL_Grid = firstL + (lastL - firstL + 1 - m_GridStep_ML[1] * 
+				 (outputPtr->GetLargestPossibleRegion().GetSize()[1])) / 2;
+       }
+     
+    // With correlation window and first row/colunm
+    masterRequestedIndex[0] -= (m_WinCor_ran - firstC_Grid);
+    masterRequestedIndex[1] -= (m_WinCor_azi - firstL_Grid);
+    masterRequestedSize[0] += (2*m_WinCor_ran+1);
+    masterRequestedSize[1] += (2*m_WinCor_azi+1);
+
+    masterRequestedRegion.SetSize(masterRequestedSize);
+    masterRequestedRegion.SetIndex(masterRequestedIndex);
+
+    masterPtr->SetRequestedRegion(masterRequestedRegion);
+
+     // Crop the fixed region at the fixed's largest possible region (or buffered)
+     if ( masterRequestedRegion.Crop(masterPtr->GetLargestPossibleRegion()))
+      {
+	masterPtr->SetRequestedRegion( masterRequestedRegion );
+      }
+    else
+      {
+	// Couldn't crop the region (requested region is outside the largest
+	// possible region).  Throw an exception.
+	// store what we tried to request (prior to trying to crop)
+	masterPtr->SetRequestedRegion( masterRequestedRegion );
+	
+	// Build an exception
+	itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
+	std::ostringstream msg;
+	msg << this->GetNameOfClass()
+	    << "::GenerateInputRequestedRegion()";
+	e.SetLocation(msg.str().c_str());
+	e.SetDescription("Requested region is (at least partially) outside the largest possible region of image 1.");
+	e.SetDataObject(masterPtr);
+	throw e;
+      }
+    
+    //////////////////// Requested region for slave ////////////////////
+    int firstL, firstC, lastL, lastC; 
+    // Transform back into slave region index space with an maximum shift between master and slave
+    ImageInIndexType slaveIndex;
+   
+    // Find requested region
+    ImageInSizeType slaveSize;
+
+    // Set the max_shift (margin)
+    firstL = masterRequestedIndex[1] - m_RoughShift_azi - m_WinAround_ShiftAzi - m_WinCor_azi;
+    firstC = masterRequestedIndex[0] - m_RoughShift_ran - m_WinAround_ShiftRan - m_WinCor_ran;
+    lastL = masterRequestedIndex[1] + masterRequestedSize[1] + m_RoughShift_azi + m_WinAround_ShiftAzi + 
+      m_WinCor_azi;
+    lastC =  masterRequestedIndex[0] + masterRequestedSize[0] + m_RoughShift_ran + m_WinAround_ShiftRan + m_WinCor_ran;
+
+    // Check the limits
+    if (firstC < 0)
+      {
+	firstC = 0;
+      } 
+    if (firstL < 0)
+      {
+	firstL = 0;
+      } 
+    if (lastC > nbColSlave-1)
+      {
+	lastC = nbColSlave-1;
+      } 
+    if (lastL > nbLinesSlave-1)
+      {
+	lastL = nbLinesSlave-1;
+      } 
+
+    
+    slaveIndex[0] = static_cast<ImageInIndexValueType>(firstC);
+    slaveIndex[1] = static_cast<ImageInIndexValueType>(firstL);
+    slaveSize[0] = static_cast<ImageInIndexValueType>(lastC - firstC)+1;
+    slaveSize[1] = static_cast<ImageInIndexValueType>(lastL - firstL)+1;
+
+    slaveRequestedRegion.SetIndex(slaveIndex);
+    slaveRequestedRegion.SetSize(slaveSize);
+
+    // crop the moving region at the moving's largest possible region
+    if ( slaveRequestedRegion.Crop(slavePtr->GetLargestPossibleRegion()))
+      {
+	slavePtr->SetRequestedRegion( slaveRequestedRegion );
+      }
+    else
+      {
+	// Couldn't crop the region (requested region is outside the largest
+	// possible region). This case might happen so we do not throw any exception but
+	// request a null region instead
+	slaveSize.Fill(0);
+	slaveRequestedRegion.SetSize(slaveSize);
+	slaveIndex.Fill(0);
+	slaveRequestedRegion.SetIndex(slaveIndex);
+	
+	// store what we tried to request (prior to trying to crop)
+	slavePtr->SetRequestedRegion(slaveRequestedRegion);
+      }
+  }
+
+
+  /** 
+   * Method GenerateInputRequestedRegion
+   */
+  template<class TImageIn, class TImageOut>
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::GenerateInputRequestedRegion()
+  {
+    // Call the superclass' implementation of this method
+    Superclass::GenerateInputRequestedRegion();
+  
+    ImageOutRegionType outputRequestedRegion = this->GetOutput()->GetRequestedRegion();
+    this->OutputRegionToInputRegion(outputRequestedRegion);
+   }
+ 
+
+ /**
+   * Method BeforeThreadedGenerateData
+   */
+  template<class TImageIn, class TImageOut>
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::ThreadedGenerateData(const ImageOutRegionType& outputRegionForThread,
+			 itk::ThreadIdType threadId)
+  {
+    // Get pointers to inputs
+    const ImageInType * masterPtr = this->GetMasterInput();
+    const ImageInType * slavePtr = this->GetSlaveInput();
+
+    ImageOutPointer outPtr = this->GetOutput();
+
+    // Typedef for iterators
+    typedef itk::ImageScanlineIterator< ImageOutType > OutputIterator;
+    typedef itk::ImageRegionConstIterator<ImageInType> MasterSlaveIt;
+    typedef itk::ImageRegionIterator<ImageInType> ExtractIt;
+    
+    // Iterator on output (Grid geometry)
+    OutputIterator OutIt(this->GetOutput(), outputRegionForThread);
+    OutIt.GoToBegin();
+    
+    ImageOutPixelType pixelCorrelationGrid;
+    pixelCorrelationGrid.Reserve(3);
+
+    // Support progress methods/callbacks
+    itk::ProgressReporter progress(this, threadId, this->GetOutput()->GetRequestedRegion().GetNumberOfPixels());
+
+    int nbColSlave = slavePtr->GetLargestPossibleRegion().GetSize()[0];
+    int nbLinesSlave = slavePtr->GetLargestPossibleRegion().GetSize()[1];
+
+    // Array to store correlation rate for each pixel and each shift
+    double arrayRate [2*m_WinAround_ShiftAzi+1][2*m_WinAround_ShiftRan+1];
+    float arrayPic[3][3];
+
+    float dx, dy, VAL_MAX;
+    int checkInterpolation;
+
+    // Size for correlation estimation
+    ImageInSizeType masterSize;
+    masterSize[0] = 2*m_WinCor_ran+1;
+    masterSize[1] = 2*m_WinCor_azi+1;
+
+    ImageInSizeType slaveSize;
+    slaveSize[0] = 2*m_WinCor_ran+1;
+    slaveSize[1] = 2*m_WinCor_azi+1;
+
+    // vector master and slave
+    std::vector<double> master;
+    std::vector<double> slave;
+
+    // First L/C for the grid
+    int firstC_Grid = 0;
+    int firstL_Grid = 0;
+
+    if (m_FirstLCOffset)
+       {
+	 int firstC = std::max (1 + m_WinCor_ran, 1 + m_WinCor_ran - m_RoughShift_ran + m_WinAround_ShiftRan);
+	 int firstL = std::max (1 + m_WinCor_azi, 1 + m_WinCor_azi - m_RoughShift_azi + m_WinAround_ShiftAzi);
+	 int lastC = std::min(slavePtr->GetLargestPossibleRegion().GetSize()[0] - m_RoughShift_ran - 
+			      m_WinAround_ShiftRan - m_WinCor_ran, 
+			      masterPtr->GetLargestPossibleRegion().GetSize()[0]- m_WinCor_ran);
+	 int lastL = std::min(slavePtr->GetLargestPossibleRegion().GetSize()[1] - m_RoughShift_azi - 
+			      m_WinAround_ShiftAzi- m_WinCor_azi, 
+			      masterPtr->GetLargestPossibleRegion().GetSize()[1] - m_WinCor_azi);
+	 
+	 firstC_Grid = firstC + (lastC - firstC + 1 - m_GridStep_ML[0] * 
+				 (outPtr->GetLargestPossibleRegion().GetSize()[0])) / 2;
+	 firstL_Grid = firstL + (lastL - firstL + 1 - m_GridStep_ML[1] * 
+				 (outPtr->GetLargestPossibleRegion().GetSize()[1])) / 2;
+       }
+
+    // For each line of output 
+    while ( !OutIt.IsAtEnd())
+      {
+	OutIt.GoToBeginOfLine();
+
+	// For each colunm of the grid
+       	while (!OutIt.IsAtEndOfLine()) 
+	  {
+	    // Get index
+	    ImageInIndexType masterIndex;
+	    
+	    for(unsigned int dim = 0; dim < ImageInType::ImageDimension; ++dim)
+	      {
+		masterIndex[dim] = OutIt.GetIndex()[dim] * m_GridStep_ML[dim]; // Grid geometry
+	      }
+
+	    // To center correlation estimation and shift to the first L/C
+	    masterIndex[0] -= (m_WinCor_ran-firstC_Grid);
+	    masterIndex[1] -= (m_WinCor_azi-firstL_Grid);
+
+	    // Build the master region (for correlation estimation)
+	    ImageInRegionType masterCurrentRegion;
+	    masterCurrentRegion.SetIndex(masterIndex);
+	    masterCurrentRegion.SetSize(masterSize);
+	    masterCurrentRegion.Crop(masterPtr->GetLargestPossibleRegion());
+	    
+	    // Iterators on master Ptr
+	    MasterSlaveIt masterIt(masterPtr, masterCurrentRegion);
+	    masterIt.GoToBegin();
+
+	    
+	    // Fill master patch
+	    master.clear();
+	    while( !masterIt.IsAtEnd())
+	      {
+		// Add to the master vector
+		double value = masterIt.Get();
+		master.push_back(value);
+
+		++masterIt;
+	      }
+
+	    // Best integer shifts and correlation rate
+	    int bestShift_ran = 0;
+	    int bestShift_azi = 0;
+	    double bestRate = 0;
+
+	    // Loop on shift around rough ones
+	    for (int l = -m_WinAround_ShiftAzi; l <= m_WinAround_ShiftAzi; l++)
+	      {
+		for (int c = -m_WinAround_ShiftRan; c <= m_WinAround_ShiftRan; c++)
+		  {
+		    // Find slave index for current shifts
+		    ImageInIndexType slaveIndex;
+		    slaveIndex[0] = masterIndex[0] + c + m_RoughShift_ran;
+		    slaveIndex[1] = masterIndex[1] + l + m_RoughShift_azi;
+		    //slaveIndex[0] = masterIndex[0];
+		    //slaveIndex[1] = masterIndex[1];
+
+		    // Check Index
+		    if (slaveIndex[0] < 0)
+		      {
+			slaveIndex[0] = 0;
+		      }
+		    if (slaveIndex[1] < 0) 
+		      {
+			slaveIndex[1] = 0;
+		      }
+		    if (slaveIndex[0] > (nbColSlave-(2*m_WinCor_ran)))
+		      {
+			slaveIndex[0] = nbColSlave-2*m_WinCor_ran;
+		      }
+		    if (slaveIndex[1] > (nbLinesSlave-(2*m_WinCor_azi)))
+		      {
+			slaveIndex[1] = nbLinesSlave-2*m_WinCor_azi;
+		      }
+
+		    
+		    // Build the slave region (for correlation estimation)
+		    ImageInRegionType slaveCurrentRegion;
+		    slaveCurrentRegion.SetIndex(slaveIndex);
+		    slaveCurrentRegion.SetSize(slaveSize);
+		    slaveCurrentRegion.Crop(slavePtr->GetLargestPossibleRegion());
+	    
+		    // Iterators on slave Ptr
+		    MasterSlaveIt slaveIt(slavePtr, slaveCurrentRegion);
+		    slaveIt.GoToBegin();
+	    
+		    // Fill slave patch
+		    slave.clear();
+		    while (!slaveIt.IsAtEnd())
+		      {
+			// Add to the slave vector
+			double value = slaveIt.Get();
+			slave.push_back(value);
+
+			++slaveIt;
+		      }
+		    
+		    //arrayRate[l][c] = Correlation(master, slave);
+
+		    arrayRate[l + m_WinAround_ShiftAzi][c + m_WinAround_ShiftRan] = 
+		      CorrelationDiapason(master, slave);
+
+		    if (arrayRate[l+ m_WinAround_ShiftAzi][c+ m_WinAround_ShiftRan] > bestRate)
+		      {
+			bestRate = arrayRate[l + m_WinAround_ShiftAzi][c + m_WinAround_ShiftRan];
+			bestShift_ran = c;
+			bestShift_azi = l;
+		      }
+		  }
+	      }
+
+
+	    // Function PIC on the best shifts (interpolation)
+	    if ((std::abs(bestShift_ran) < m_WinAround_ShiftRan) && 
+		(std::abs(bestShift_azi) < m_WinAround_ShiftAzi) && 
+		(bestRate >= m_CorrelationThreshold))
+	      {
+		// Built array_pic
+		for (int k=-1;k<2;k++)
+		  for (int  j=-1;j<2;j++)
+		    arrayPic[k+1][j+1] = static_cast<float>(arrayRate[bestShift_azi + k + m_WinAround_ShiftAzi]
+							    [bestShift_ran + j + m_WinAround_ShiftRan]);
+		
+		// Launch interpolation
+		PIC(arrayPic, &dx, &dy, &VAL_MAX, &checkInterpolation);
+		
+		pixelCorrelationGrid[0] = m_RoughShift_ran + bestShift_ran + dx; 
+		pixelCorrelationGrid[1] = m_RoughShift_azi + bestShift_azi + dy; 
+		pixelCorrelationGrid[2] = VAL_MAX;
+
+		//std::cout << arrayPic[1][1] << " at " << bestShift_ran << " , " << bestShift_azi << std::endl;
+				
+	      }
+	    else 
+	      {
+		pixelCorrelationGrid[0] = m_RoughShift_ran + bestShift_ran; 
+		pixelCorrelationGrid[1] = m_RoughShift_azi + bestShift_azi; 
+		pixelCorrelationGrid[2] = 0;
+	      }	
+	    
+	    
+	    // Correlation into SLC geometry and not ML geometry
+	    pixelCorrelationGrid[0] *= m_MLran;
+	    pixelCorrelationGrid[1] *= m_MLazi;
+
+	    // Assign Output
+	    OutIt.Set(pixelCorrelationGrid);
+	    progress.CompletedPixel();
+	    
+	    // Next Colunm for output
+	    ++OutIt;
+	  }
+	
+	// Next Line for output 
+	OutIt.NextLine();
+      }
+  }
+
+
+  /**
+   * Method PIC
+   */
+  template<class TImageIn, class TImageOut>
+  void
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::PIC(float TAB_PIC[3][3], float *DX, float *DY, float *VAL_MAX, int *CR) const
+  {
+    float		TAB_COS[3]= {-0.5,1.,-0.5};
+    float		TAB_SIN[3]= {-0.8660254,0.,+0.8660254};
+    float		SXF,SYF,SF,N,A1,B1,SDXF,SDYF,A2,B2;
+    float		AX, AY;
+    int			i, j;
+	
+    // The method of least squares in cosinus
+    *CR = 1;
+    SF   = 0.;
+    SXF  = 0.;
+    SYF  = 0.;
+  
+    for (i=-1;i<2;i++)
+      {
+	for (j=-1;j<2;j++)
+	  {
+	    SF  = SF  + TAB_PIC[i+1][j+1];
+	    SXF = SXF + TAB_PIC[i+1][j+1]*TAB_COS[j+1];		
+	    SYF = SYF + TAB_PIC[i+1][j+1]*TAB_COS[i+1];	
+	  }	
+      }
+
+    N = SF / 9.;
+    A1 = SXF/ 4.5;
+    B1 = SYF/ 4.5;
+   
+    // The method of least squares in sinus
+    SDXF  = 0.; 
+    SDYF  = 0.;
+	  
+    for (i=-1;i<2;i++)
+      {
+	for (j=-1;j<2;j++)
+	  {
+	    SDXF = SDXF + TAB_PIC[i+1][j+1]*TAB_SIN[j+1];		
+	    SDYF = SDYF + TAB_PIC[i+1][j+1]*TAB_SIN[i+1];	
+	  }	
+      }
+
+    A2 = SDXF/3.;        // 4*.75
+    B2 = SDYF/3.;        // 4*.75 
+             
+    A2 = A2/1.5;
+    B2 = B2/1.5; 
+	
+    // Max
+    AX = std::sqrt (A1*A1+A2*A2);
+    AY = std::sqrt (B1*B1+B2*B2);
+
+    if (AX*AY == 0.)
+      {                                                                                                        
+      	*VAL_MAX = -1.;
+        *DX = 0.; 
+        *DY = 0.;               
+        return;
+      } 
+    
+    *DX = std::atan2 (A2,A1) /(2*M_PI/3.);
+    *DY = std::atan2 (B2,B1) /(2*M_PI/3.);
+
+    *VAL_MAX  = N + (AX + AY)* 0.5;
+    *VAL_MAX  = std::max(*VAL_MAX,TAB_PIC[1][1]);
+    *VAL_MAX  = std::min(static_cast<float>(1.),*VAL_MAX);
+	                                                                                                  
+    // Check values                                                                                             
+    if ((fabs((double)*DX)>.75) || (fabs((double)*DY)>.75))
+      {                                                                                   
+      	*VAL_MAX = -3.;  
+        *DX = 0.; 
+        *DY = 0.;                  
+      }
+	
+    return;                                                                                                                                
+	
+  }
+
+  template<class TImageIn, class TImageOut>
+  double
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::Correlation(const std::vector<double>& master, const std::vector<double>& slave) const
+  {
+    double meanSlave = 0;
+    double meanMaster = 0;
+    double correlationValue = 0;
+
+    // Compute means
+    for(unsigned int i = 0; i < master.size(); ++i)
+      {
+	meanSlave += slave[i];
+	meanMaster += master[i];
+      }
+    meanSlave /= slave.size();
+    meanMaster /= master.size();
+
+    double crossProd = 0.;
+    double squareSumMaster = 0.;
+    double squareSumSlave = 0.;
+
+
+    // Compute correlation
+    for(unsigned int i = 0; i < master.size(); ++i)
+      {
+	crossProd += (slave[i]-meanSlave) * (master[i]-meanMaster);
+	squareSumSlave += (slave[i]-meanSlave) * (slave[i]-meanSlave);
+	squareSumMaster += (master[i]-meanMaster) * (master[i]-meanMaster);
+      }
+
+    correlationValue = std::abs(crossProd/(std::sqrt(squareSumSlave)*std::sqrt(squareSumMaster)));
+
+    return correlationValue;
+  }
+
+   template<class TImageIn, class TImageOut>
+  double
+  SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
+  ::CorrelationDiapason(const std::vector<double>& master, const std::vector<double>& slave) const
+  {
+    double sumSlave = 0;
+    double sumMaster = 0;
+    double sumMasterSlave = 0;
+    double sumSlaveSquare = 0;
+    double sumMasterSquare = 0;
+
+    double correlationValue = 0;
+
+    // Compute sum, sum square and cross prod
+    for(unsigned int i = 0; i < master.size(); ++i)
+      {
+	sumSlave += slave[i];
+	sumMaster += master[i];
+	sumMasterSlave += slave[i]*master[i];
+	sumSlaveSquare += slave[i]*slave[i];
+	sumMasterSquare += master[i]*master[i];
+      }
+    
+    // Compute means
+    double meanMaster = sumMaster/master.size();
+    double meanSlave = sumSlave/slave.size();
+    
+    // Compute sigma and covariance
+    double sigmaMaster = sumMasterSquare/master.size() - (meanMaster*meanMaster);
+    double sigmaSlave = sumSlaveSquare/slave.size() - (meanSlave*meanSlave);
+    double covariance = sumMasterSlave/master.size();
+  
+
+
+    if (sigmaMaster > 0 && sigmaSlave > 0)
+      {
+	correlationValue = (covariance - (meanMaster*meanSlave))/(std::sqrt(sigmaMaster*sigmaSlave));
+      }
+
+    return correlationValue;
+  }
+  
+
+
+} /*namespace otb*/
+
+#endif
diff --git a/include/otbSARUpdateMetadataImageFilter.h b/include/otbSARUpdateMetadataImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..1784d496d7641209e94f3b33fe51a8bb7564aa0f
--- /dev/null
+++ b/include/otbSARUpdateMetadataImageFilter.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2005-2018 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef otbSARUpdateMetadataImageFilter_h
+#define otbSARUpdateMetadataImageFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "itkSmartPointer.h"
+#include "itkPoint.h"
+
+#include "itkImageScanlineConstIterator.h"
+#include "itkImageScanlineIterator.h"
+
+#include "otbImageKeywordlist.h"
+#include "otbSarSensorModelAdapter.h"
+
+#if defined(__GNUC__) || defined(__clang__)
+# pragma GCC diagnostic push
+#   pragma GCC diagnostic ignored "-Wunused-parameter"
+#   pragma GCC diagnostic ignored "-Woverloaded-virtual"
+#   pragma GCC diagnostic ignored "-Wshadow"
+#   include "ossim/ossimTimeUtilities.h"
+
+# pragma GCC diagnostic pop
+
+#else
+#   include "ossim/ossimTimeUtilities.h"
+#endif
+
+#if defined(USE_BOOST_TIME)
+#  include <boost/date_time/posix_time/posix_time.hpp>
+#include <ostream>
+#endif
+
+namespace otb
+{
+/** \class SARUpdateMetadataImageFilter 
+ * \brief Update some metadata after a correction chain. 
+ * 
+ * This filter updates some metadata (only metadata, input image remains the same).
+ *
+ * \ingroup DiapOTBModule
+ */
+
+  template <typename TImage> 
+  class ITK_EXPORT SARUpdateMetadataImageFilter :
+    public itk::ImageToImageFilter<TImage,TImage>
+{
+public:
+
+  // Standard class typedefs
+  typedef SARUpdateMetadataImageFilter                    Self;
+  typedef itk::ImageToImageFilter<TImage,TImage>         Superclass;
+  typedef itk::SmartPointer<Self>                        Pointer;
+  typedef itk::SmartPointer<const Self>                  ConstPointer;
+
+  /** Typedef to image input/output type  */
+  typedef TImage                                  ImageType;
+  /** Typedef to describe the inout image pointer type. */
+  typedef typename ImageType::Pointer             ImagePointer;
+  typedef typename ImageType::RegionType          ImageRegionType;
+
+  // Method for creation through object factory
+  itkNewMacro(Self);
+  // Run-time type information
+  itkTypeMacro(SARUpdateMetadataImageFilter,ImageToImageFilter);
+  
+   // Setter
+  itkSetMacro(TimeFirstLine, std::string);
+  itkSetMacro(SlantRange, double);
+
+  // Getter
+  itkGetMacro(TimeFirstLine, std::string);
+  itkGetMacro(SlantRange, double);
+
+
+protected:
+  // Constructor
+  SARUpdateMetadataImageFilter()
+    {
+      m_TimeFirstLine = "";
+      m_SlantRange = 0.;
+    };
+
+  // Destructor
+  virtual ~SARUpdateMetadataImageFilter() {};
+
+  // Print
+  void PrintSelf(std::ostream & os, itk::Indent indent) const ITK_OVERRIDE;
+
+  /** SARUpdateMetadataImageFilter updates the imagekeywordlist for new output metadata.
+   * As such, SARUpdateMetadataImageFilter needs to provide an implementation for 
+   * GenerateOutputInformation() in order to inform the pipeline execution model. 
+   */ 
+  virtual void GenerateOutputInformation() ITK_OVERRIDE;
+
+  void ThreadedGenerateData(const ImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) 
+    ITK_OVERRIDE;
+   
+ private:
+  SARUpdateMetadataImageFilter(const Self&); // purposely not implemented
+  void operator=(const Self &); // purposely not 
+
+  // Precise metadata 
+  std::string m_TimeFirstLine;
+  double m_SlantRange;
+
+};
+
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbSARUpdateMetadataImageFilter.txx"
+#endif
+
+
+
+#endif
diff --git a/include/otbSARUpdateMetadataImageFilter.txx b/include/otbSARUpdateMetadataImageFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..13bbffbe204bb4d2da2195555902fe767ae19ff0
--- /dev/null
+++ b/include/otbSARUpdateMetadataImageFilter.txx
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2005-2018 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef otbSARUpdateMetadataImageFilter_txx
+#define otbSARUpdateMetadataImageFilter_txx
+
+#include "otbSARUpdateMetadataImageFilter.h"
+
+#include "itkImageRegionConstIterator.h"
+#include "itkImageRegionIterator.h"
+
+#include <cmath>
+#include <algorithm>
+
+namespace otb
+{
+   /**
+   * Print
+   */
+  template<class TImage>
+  void
+  SARUpdateMetadataImageFilter< TImage >
+  ::PrintSelf(std::ostream & os, itk::Indent indent) const
+  {
+    Superclass::PrintSelf(os, indent);
+
+    os << indent << "Precise first line time  : " << m_TimeFirstLine << std::endl;
+    os << indent << "Precise Slant range : " << m_SlantRange << std::endl;
+  }
+
+  
+  /**
+   * Method GenerateOutputInformaton()
+   **/
+  template<class TImage>
+  void
+  SARUpdateMetadataImageFilter< TImage >
+  ::GenerateOutputInformation()
+  {
+    // Call superclass implementation
+    Superclass::GenerateOutputInformation();
+
+    // Get Input and Output ptr
+    ImagePointer outputPtr = this->GetOutput();
+    ImagePointer inputPtr = const_cast< ImageType * >(this->GetInput());
+        
+    // Set new keyword list to output image with precise metadata
+    ImageKeywordlist outputKWL = inputPtr->GetImageKeywordlist();
+    //outputKWL.SetMetadataByKey("support_data.first_line_time", m_TimeFirstLine);
+    //outputKWL.SetMetadataByKey("support_data.slant_range_to_first_pixel", m_SlantRange);
+
+    std::ostringstream str_slantRange;
+    str_slantRange.precision(14);
+    str_slantRange << std::fixed << m_SlantRange;
+
+    std::cout << "str_slantRange = " << str_slantRange.str() << std::endl;
+
+    outputKWL.AddKey("support_data.first_line_time", m_TimeFirstLine);
+    outputKWL.AddKey("support_data.slant_range_to_first_pixel", str_slantRange.str());
+    outputPtr->SetImageKeywordList(outputKWL);     
+  }
+
+  
+  template<class TImage>
+  void
+  SARUpdateMetadataImageFilter< TImage >
+  ::ThreadedGenerateData(const ImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
+  {
+    // Get Input and Output ptr
+    ImagePointer outputPtr = this->GetOutput();
+    ImagePointer inputPtr = const_cast< ImageType * >(this->GetInput());
+
+    // Same region
+    ImageRegionType inputRegion = outputRegionForThread;
+     
+    // Iterators
+    typedef itk::ImageRegionConstIterator<ImageType> InItType;
+    typedef itk::ImageRegionIterator<ImageType> OutItType;
+
+    InItType InIt(inputPtr, inputRegion);
+    InIt.GoToBegin();
+
+    OutItType OutIt(outputPtr, outputRegionForThread);
+    OutIt.GoToBegin();
+
+    // Copy input image into output
+    while (!InIt.IsAtEnd())
+      {
+	OutIt.Set(InIt.Get());
+
+	++OutIt; 
+	++InIt;
+      }
+  }
+
+} /*namespace otb*/
+
+#endif
diff --git a/include/otbTilesExampleFunctor.h b/include/otbTilesExampleFunctor.h
index 4c9f7fe4ced99d5e2994307151596f483adde26f..a7d9f477a386593c6a96fe9ee367b24959e7764b 100644
--- a/include/otbTilesExampleFunctor.h
+++ b/include/otbTilesExampleFunctor.h
@@ -111,7 +111,7 @@ public:
 
   // Process
   void Process(ImageInPointer inputPtr, ImageOutRegionType outputRegion, ImageOutPixelType * TilesResult, 
-	       int threadId=0)
+	       int /*threadId=0*/)
   {
     // Transpose outputRegion (current tile) into input image
     // Input (= output now)
diff --git a/json_schemas/schema_S1SM.json b/json_schemas/schema_S1SM.json
index 8605109824bb68cc0578e3772dcbe8e5c6b5eac4..e649de737ca723bdd7e2df4b51ef9368f8c5f792 100644
--- a/json_schemas/schema_S1SM.json
+++ b/json_schemas/schema_S1SM.json
@@ -30,6 +30,14 @@
 		    "additionalProperties": false,
 		    "properties": {"output_dir": {"type": "string"}}
 		}
+		"sensor": 
+		{
+		    "type": "object",
+		    "required": ["satellite", "mode"],
+		    "additionalProperties": false,
+		    "properties": {"satellite": {"type": "string"},
+				   "mode": {"type": "string"}}
+		}
 	    },
 	    "additionalProperties": false,
 	    "required": ["in", "out"]
diff --git a/python_src/diapOTB.py b/python_src/diapOTB.py
index f99ef79afeaab02462dff2f901d682bd2e18b990..e59c71d7d96435155d164c365d9cd20961bc63a6 100644
--- a/python_src/diapOTB.py
+++ b/python_src/diapOTB.py
@@ -35,7 +35,7 @@ from jsonschema import validate
 import os
 import sys
 import argparse
-
+import h5py
 
 import otbApplication as otb
 
@@ -108,6 +108,13 @@ if __name__ == "__main__":
     dem =  dict_Global['in']['DEM_Path']
     output_dir = dict_Global['out']['output_dir']
 
+    satellite = "default"
+    mode = "default"
+
+    if 'sensor' in dict_Global:
+        satellite = dict_Global['sensor']['satellite']
+        mode = dict_Global['sensor']['mode']
+
     # Pre_Processing
     ml_range = dict_PreProcessing['parameter']['ML_range'] 
     ml_azimut = dict_PreProcessing['parameter']['ML_azimut']
@@ -158,7 +165,60 @@ if __name__ == "__main__":
     master_Image_base = os.path.basename(master_Image)
     slave_Image_base = os.path.basename(slave_Image)
 
-    
+    # Check extension (if .h5 => HDF5 file => Cosmo Sensor)
+    master_ext = master_Image.split(".")[-1:]
+    slave_ext = slave_Image.split(".")[-1:]
+
+    print ("master_ext = " + master_ext[0] + "\n")
+    print ("salve_ext = " + slave_ext[0] + "\n")
+
+    if master_ext[0] == "h5" :
+        master_H5 = h5py.File(master_Image, 'r')
+        lDataSet_master = list(master_H5.keys())
+       
+
+        if len(lDataSet_master) != 1 :
+            print("H5 input files does not contain the expected dataset \n")
+            quit()
+
+        if lDataSet_master[0] != "S01" :
+            print("H5 input files does not contain the expected dataset \n")
+            quit()
+
+        master_S01 = dict(master_H5['S01'])
+        
+        if not 'SBI' in master_S01:
+            print("H5 input files does not contain the expected dataset \n")
+            quit()
+
+        # Change the name of master and slave image to read directly the //S01/SBI
+        master_Image = "HDF5:" + master_Image + "://S01/SBI"
+        # Adapt sattelite
+        satellite = "cosmo"
+
+
+    if slave_ext[0] == "h5" :      
+        slave_H5 = h5py.File(slave_Image, 'r')
+        lDataSet_slave = list(slave_H5.keys())
+
+        if len(lDataSet_slave) != 1 :
+            print("H5 input files does not contain the expected dataset \n")
+            quit()
+
+        if lDataSet_slave[0] != "S01" :
+            print("H5 input files does not contain the expected dataset \n")
+            quit()
+
+        slave_S01 = dict(slave_H5['S01'])
+        
+        if not 'SBI' in slave_S01 :
+            print("H5 input files does not contain the expected dataset \n")
+            quit()
+        
+        slave_Image = "HDF5:" + slave_Image + "://S01/SBI"
+
+    print("master_Image = " + master_Image + "\n") 
+    print("slave_Image = " + slave_Image + "\n") 
 
     ####################### Pre Processing Chain ##########################
     ######## SARDoppler Application #######
@@ -241,8 +301,6 @@ if __name__ == "__main__":
         appCorGrid.SetParameterInt("mlazi",ml_correlSimu_azimut)
         appCorGrid.SetParameterInt("gridsteprange", correlSimu_gridstep_range)
         appCorGrid.SetParameterInt("gridstepazimut", correlSimu_gridstep_azimut)
-        appCorGrid.SetParameterInt("patchsize", 20)
-        appCorGrid.SetParameterInt("subpixel", 10)
         appCorGrid.SetParameterString("ram", "4000")
         #appCorGrid.Execute()
         appCorGrid.ExecuteAndWriteOutput()
@@ -306,11 +364,12 @@ if __name__ == "__main__":
     appFineDeformationGrid.SetParameterInt("mlazi", ml_geoGrid_azimut)
     appFineDeformationGrid.SetParameterInt("gridsteprange", geoGrid_gridstep_range)
     appFineDeformationGrid.SetParameterInt("gridstepazimut", geoGrid_gridstep_azimut)
-    appFineDeformationGrid.SetParameterInt("patchsize", 20)
-    appFineDeformationGrid.SetParameterInt("subpixel", 10)
     appFineDeformationGrid.SetParameterFloat("threshold", geoGrid_threshold)
     appFineDeformationGrid.SetParameterFloat("gap", geoGrid_gap)
     appFineDeformationGrid.SetParameterString("out", os.path.join(output_dir, fine_grid))
+    # Projection is not reliable for cosmo sensor => correction of all values with correlation grid
+    if satellite == "cosmo" or satellite == "CSK" :
+        appFineDeformationGrid.SetParameterString("advantage", "correlation")
     appFineDeformationGrid.SetParameterString("ram", "4000")
     appFineDeformationGrid.ExecuteAndWriteOutput()
 
diff --git a/python_src/diapOTB_S1IW.py b/python_src/diapOTB_S1IW.py
index 2dee6f144d5198ff1626bdf374b8570c7ce53429..7639b60c8075572d15fa70b26eadc6cef486d66b 100644
--- a/python_src/diapOTB_S1IW.py
+++ b/python_src/diapOTB_S1IW.py
@@ -449,8 +449,6 @@ if __name__ == "__main__":
         appFineDeformationGrid.SetParameterInt("mlazi", ml_geoGrid_azimut)
         appFineDeformationGrid.SetParameterInt("gridsteprange", geoGrid_gridstep_range)
         appFineDeformationGrid.SetParameterInt("gridstepazimut", geoGrid_gridstep_azimut)
-        appFineDeformationGrid.SetParameterInt("patchsize", 20)
-        appFineDeformationGrid.SetParameterInt("subpixel", 10)
         appFineDeformationGrid.SetParameterFloat("threshold", geoGrid_threshold)
         appFineDeformationGrid.SetParameterFloat("gap", geoGrid_gap)
         appFineDeformationGrid.SetParameterString("out", os.path.join(burst_dir, fine_grid))
diff --git a/test/otbSARDopplerCentroidFreqImageFilterTest.cxx b/test/otbSARDopplerCentroidFreqImageFilterTest.cxx
index a983cdd2413b6d61ebb4e963bb502c7cf9f10511..cb2844db5724119a16eaf49d20794ee2f2b30b2d 100644
--- a/test/otbSARDopplerCentroidFreqImageFilterTest.cxx
+++ b/test/otbSARDopplerCentroidFreqImageFilterTest.cxx
@@ -39,8 +39,7 @@ int otbSARDopplerCentroidFreqFilterTest(int argc, char * argv[])
   
   // Image type
   const unsigned int Dimension = 2;
-  typedef otb::Image <std::complex<float>, 2>       ImageSARInType ;
-  typedef otb::Image <float, 2>                       FloatImageType;
+  typedef otb::Image <float, Dimension>              FloatImageType;
   typedef otb::VectorImage<float>                    FloatVectorImageType;
 
   // Reader