diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 29d85143800acde0b28afb991052e04f5e06a882..151f0f4f5952232c9698010e7e135452e4339a6d 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -103,3 +103,8 @@ OTB_CREATE_APPLICATION(NAME SARMetadataCorrection
                        SOURCES otbSARMetadataCorrection.cxx
                        LINK_LIBRARIES ${${otb-module}_LIBRARIES}
 )
+
+OTB_CREATE_APPLICATION(NAME SAROrthoInterferogram
+                       SOURCES otbSAROrthoInterferogram.cxx
+                       LINK_LIBRARIES ${${otb-module}_LIBRARIES}
+)
diff --git a/app/otbSAROrthoInterferogram.cxx b/app/otbSAROrthoInterferogram.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8943cf069370caf37f00679a9b08b54908ebaa31
--- /dev/null
+++ b/app/otbSAROrthoInterferogram.cxx
@@ -0,0 +1,173 @@
+/*
+ * 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 "otbSARCompensatedComplexImageFilter.h"
+#include "otbSARGroupedByOrthoImageFilter.h"
+
+#include "otbWrapperOutputImageParameter.h"
+#include "otbWrapperTypes.h"
+
+#include <iostream>
+#include <string>
+#include <fstream>
+
+namespace otb
+{
+
+  namespace Wrapper
+  {
+
+    class SAROrthoInterferogram : public Application
+    {
+    public:
+      typedef SAROrthoInterferogram Self;
+      typedef itk::SmartPointer<Self> Pointer; 
+
+      itkNewMacro(Self);
+      itkTypeMacro(SAROrthoInterferogram, otb::Wrapper::Application);
+
+      // Filters
+      typedef otb::SARCompensatedComplexImageFilter<ComplexFloatImageType, FloatVectorImageType, FloatVectorImageType> CompensatedComplexFilterType;
+      typedef otb::SARGroupedByOrthoImageFilter<FloatVectorImageType, FloatImageType, FloatVectorImageType> GroupedByOrthoFilterType;
+
+    private:
+      void DoInit() override
+      {
+	SetName("SAROrthoInterferogram");
+	SetDescription("Interferogram into ground geometry between two SAR images.");
+
+	SetDocLongDescription("This application builds the interferogram into ground geometry between two"
+        " SAR images.");
+
+	//Optional descriptors
+	SetDocLimitations("Only Sentinel 1 (IW and StripMap mode) and Cosmo products are supported for now.");
+	SetDocAuthors("OTB-Team");
+	SetDocSeeAlso(" ");
+	AddDocTag(Tags::SAR);
+	AddDocTag("DiapOTB");
+
+	//Parameter declarations
+	AddParameter(ParameterType_InputImage,  "insarslave",   "Input SAR Slave image (Coregistrated image)");
+	SetParameterDescription("insarslave", "Input SAR Slave image (Coregistrated image).");
+
+	AddParameter(ParameterType_InputImage,  "insarmaster",   "Input SAR Master image");
+	SetParameterDescription("insarmaster", "Input SAR Master image.");
+
+	AddParameter(ParameterType_InputImage,  "topographicphase",   "Input Topographic Phase (estimation with DEM projection)");
+	SetParameterDescription("topographicphase", "Input Topographic Phase (estimation with DEM projection).");
+	MandatoryOff("topographicphase");
+
+        AddParameter(ParameterType_InputImage,  "incartmeanmaster",   "Input Cartesian Mean Master image");
+	SetParameterDescription("incartmeanmaster", "Input Cartesian Mean Master image.");
+
+        AddParameter(ParameterType_InputImage,  "indem",   "Input DEM");
+        SetParameterDescription("indem", "GetGround geometry thanks to DEM (only metadata).");
+	
+	AddParameter(ParameterType_Float, "gain", "Gain to apply for amplitude estimation");
+	SetParameterDescription("gain","Gain to apply for amplitude estimation");
+	SetDefaultParameterFloat("gain", 0.1);
+	SetMinimumParameterFloatValue("gain", 0);
+	MandatoryOff("gain");
+
+	AddParameter(ParameterType_OutputImage, "out", "Interferogram");
+	SetParameterDescription("out","Output Vector Image : Interferogram.");
+
+	AddRAMParameter();
+
+	SetDocExampleParameterValue("insarslave","s1b-s4-slc-vv-20160929t014610-20160929t014634-002277-003d71-002.tiff");
+	SetDocExampleParameterValue("insarmaster","s1a-s4-slc-vv-20160818t014650-20160818t014715-012648-013db1-002_SLC.tiff");
+        SetDocExampleParameterValue("incartmeanmaster","CartesianMaster.tiff");
+        SetDocExampleParameterValue("indem","S21E055.hgt");
+	SetDocExampleParameterValue("gain","0.1");
+	SetDocExampleParameterValue("out","s1b-s1a-s4-interferogram.tiff");
+      }
+
+      void DoUpdateParameters() override
+      {
+	// Nothing to do here : all parameters are independent
+      }
+
+      void DoExecute() override
+      { 
+	// Get numeric parameters
+	double factor_gain = GetParameterFloat("gain");
+	
+	otbAppLogINFO(<<"Gain Factor : "<<factor_gain);
+
+	/////////////////////////////////// Compensated Complex Filter ////////////////////////////////////////
+	// Instanciate the first filter
+	CompensatedComplexFilterType::Pointer filterCompensatedComplex = CompensatedComplexFilterType::New();
+	m_Ref.push_back(filterCompensatedComplex.GetPointer());
+	
+	// Execute the Pipeline
+	ComplexFloatImageType::Pointer SARMasterPtr;
+	SARMasterPtr = GetParameterComplexFloatImage("insarmaster");
+
+	ComplexFloatImageType::Pointer SARSlavePtr;
+	SARSlavePtr = GetParameterComplexFloatImage("insarslave");
+
+	// Two Main inputs
+	filterCompensatedComplex->SetMasterInput(SARMasterPtr);
+	filterCompensatedComplex->SetSlaveInput(SARSlavePtr);
+
+	// One optionnal input
+	if (GetParameterByKey("topographicphase")->HasValue())
+	  {
+	    filterCompensatedComplex->SetTopographicPhaseInput(GetParameterImage("topographicphase"));
+	  }
+	
+
+	/////////////////////////////// GroupedBy Filter (for ground geometry) //////////////////////////////////
+	// Instanciate the second filter
+	FloatImageType::Pointer inputDEM =  GetParameterFloatImage("indem");
+	GroupedByOrthoFilterType::Pointer filterGroupedBy = GroupedByOrthoFilterType::New();
+	m_Ref.push_back(filterGroupedBy.GetPointer());
+	filterGroupedBy->SetSARImageKeyWorList(SARMasterPtr->GetImageKeywordlist());
+	filterGroupedBy->SetDEMImagePtr(inputDEM);
+
+	
+	// Execute the Pipeline
+	FloatVectorImageType::Pointer CartMeanPtr;
+	CartMeanPtr = GetParameterFloatVectorImage("incartmeanmaster");
+
+
+	filterGroupedBy->SetCartesianMeanInput(CartMeanPtr);
+	filterGroupedBy->SetCompensatedComplexInput(filterCompensatedComplex->GetOutput());
+	
+
+	// Main Output
+	SetParameterOutputImage("out", filterGroupedBy->GetOutput());
+
+      }
+      // Vector for filters 
+      std::vector<itk::ProcessObject::Pointer> m_Ref;
+
+    };
+
+  }
+
+}
+
+
+ 
+OTB_APPLICATION_EXPORT(otb::Wrapper::SAROrthoInterferogram)
diff --git a/include/otbSARCompensatedComplexImageFilter.h b/include/otbSARCompensatedComplexImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..38a9490b58540364c9567db6c4f48a0b5912b42c
--- /dev/null
+++ b/include/otbSARCompensatedComplexImageFilter.h
@@ -0,0 +1,207 @@
+/*
+ * 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 otbSARCompensatedComplexImageFilter_h
+#define otbSARCompensatedComplexImageFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "itkSmartPointer.h"
+#include "itkPoint.h"
+
+#include "itkSimpleFastMutexLock.h"
+
+#include "itkImageScanlineConstIterator.h"
+#include "itkImageScanlineIterator.h"
+
+#include "otbImageKeywordlist.h"
+
+
+namespace otb
+{
+/** \class SARCompensatedComplexImageFilter 
+ * \brief Creates an temporary image (to estimate conjugate multiplication) between two images. 
+ * 
+ * This filter built the conjugate multiplication between a master and a slave image.
+ * A topographic phase can be used to create this temporary image.
+ *
+ * The output is a vector image with real part, imag part and modulus of conjugate multiplication.
+ *
+ * \ingroup DiapOTBModule
+ */
+
+  template <typename TImageSAR, typename TImagePhase, typename TImageOut> 
+  class ITK_EXPORT SARCompensatedComplexImageFilter :
+    public itk::ImageToImageFilter<TImageSAR,TImageOut>
+{
+public:
+
+  // Standard class typedefs
+  typedef SARCompensatedComplexImageFilter                    Self;
+  typedef itk::ImageToImageFilter<TImageSAR,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(SARCompensatedComplexImageFilter,ImageToImageFilter);
+
+  /** Typedef to image input type (master and slave reech images) :  otb::Image (Complex)  */
+  typedef TImageSAR                                  ImageSARType;
+  /** Typedef to describe the inout image pointer type. */
+  typedef typename ImageSARType::Pointer             ImageSARPointer;
+  typedef typename ImageSARType::ConstPointer        ImageSARConstPointer;
+  /** Typedef to describe the inout image region type. */
+  typedef typename ImageSARType::RegionType          ImageSARRegionType;
+  /** Typedef to describe the type of pixel and point for inout image. */
+  typedef typename ImageSARType::PixelType           ImageSARPixelType;
+  typedef typename ImageSARType::PointType           ImageSARPointType;
+  /** Typedef to describe the image index, size types and spacing for inout image. */
+  typedef typename ImageSARType::IndexType           ImageSARIndexType;
+  typedef typename ImageSARType::IndexValueType      ImageSARIndexValueType;
+  typedef typename ImageSARType::SizeType            ImageSARSizeType;
+  typedef typename ImageSARType::SizeValueType       ImageSARSizeValueType;
+  typedef typename ImageSARType::SpacingType         ImageSARSpacingType;
+  typedef typename ImageSARType::SpacingValueType    ImageSARSpacingValueType;
+  
+  /** Typedef to image output type : otb::VectorImage  */
+  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>;
+
+  // Typedef for topographic Phase
+  typedef TImagePhase                                      ImagePhaseType;
+  typedef typename ImagePhaseType::Pointer                 ImagePhasePointer;
+  typedef typename ImagePhaseType::ConstPointer            ImagePhaseConstPointer;
+  typedef typename ImagePhaseType::RegionType              ImagePhaseRegionType;
+  typedef typename ImagePhaseType::IndexType               ImagePhaseIndexType;
+  typedef typename ImagePhaseType::IndexValueType          ImagePhaseIndexValueType;
+  typedef typename ImagePhaseType::SizeType                ImagePhaseSizeType;
+  typedef typename ImagePhaseType::SizeValueType           ImagePhaseSizeValueType;
+
+  // Typedef for iterators
+  typedef itk::ImageScanlineConstIterator< ImageSARType > InputSARIterator;
+  typedef itk::ImageScanlineConstIterator< ImagePhaseType > InputPhaseIterator;
+  typedef itk::ImageScanlineIterator< ImageOutType > OutputIterator;
+
+  typedef itk::SimpleFastMutexLock         MutexType;
+
+    
+  // Setter/Getter for inputs (SAR images and potentially topographic phase) 
+  /** Connect one of the operands for interferometry : Master */
+  void SetMasterInput( const ImageSARType* image);
+
+  /** Connect one of the operands for interferometry : Coregistrated Slave */
+  void SetSlaveInput(const ImageSARType* image);
+
+  /** Connect one of the operands for interferometry : Coregistrated Slave */
+  void SetTopographicPhaseInput(const ImagePhaseType* imagePhaseTopo);
+
+  /** Get the inputs */
+  const ImageSARType* GetMasterInput() const;
+  const ImageSARType * GetSlaveInput() const;
+  const ImagePhaseType * GetTopographicPhaseInput() const;
+
+
+protected:
+  // Constructor
+  SARCompensatedComplexImageFilter();
+
+  // Destructor
+  virtual ~SARCompensatedComplexImageFilter() ITK_OVERRIDE;
+
+  // Print
+  void PrintSelf(std::ostream & os, itk::Indent indent) const ITK_OVERRIDE;
+  
+  /** SARCompensatedComplexImageFilter produces an image which are into output geometry. The differences between 
+   * output and input images can be the size of images and the dimensions. 
+   * As such, SARCompensatedComplexImageFilter needs to provide an implementation for 
+   * GenerateOutputInformation() in order to inform the pipeline execution model. 
+   */ 
+  virtual void GenerateOutputInformation() ITK_OVERRIDE;
+
+  /** SARCompensatedComplexImageFilter needs a input requested region that corresponds to the margin and shifts 
+   * into the requested region of our output requested region. The output requested region needs to be modified
+   * to construct as wanted tiles with input size.
+   * As such, TilesAnalysesImageFilter needs to provide an implementation for 
+   * GenerateInputRequestedRegion() in order to inform the pipeline execution model. 
+   * \sa ProcessObject::GenerateInputRequestedRegion() */
+  virtual void GenerateInputRequestedRegion() ITK_OVERRIDE;
+
+
+  /** 
+   * SARCompensatedComplexImageFilterr can be implemented as a multithreaded filter.
+   * Therefore, this implementation provides a ThreadedGenerateData() routine
+   * which is called for each processing thread. The main 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() */
+  virtual void ThreadedGenerateData(const ImageOutRegionType& outputRegionForThread, 
+				    itk::ThreadIdType threadId) ITK_OVERRIDE;
+  
+  virtual void ThreadedGenerateDataWithoutTopographicPhase(const ImageOutRegionType& outputRegionForThread, 
+							   itk::ThreadIdType threadId);
+  virtual void ThreadedGenerateDataWithTopographicPhase(const ImageOutRegionType& outputRegionForThread, 
+							itk::ThreadIdType threadId);
+
+
+ private:
+  SARCompensatedComplexImageFilter(const Self&); // purposely not implemented
+  void operator=(const Self &); // purposely not 
+
+  // SAR Dimensions
+  int m_nbLinesSAR;
+  int m_nbColSAR;
+
+  
+
+};
+
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbSARCompensatedComplexImageFilter.txx"
+#endif
+
+
+
+#endif
diff --git a/include/otbSARCompensatedComplexImageFilter.txx b/include/otbSARCompensatedComplexImageFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..8644b0b259151b46edcfc6278f1dfda46ed14674
--- /dev/null
+++ b/include/otbSARCompensatedComplexImageFilter.txx
@@ -0,0 +1,461 @@
+/*
+ * 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 otbSARCompensatedComplexImageFilter_txx
+#define otbSARCompensatedComplexImageFilter_txx
+
+#include "otbSARCompensatedComplexImageFilter.h"
+
+#include "itkImageScanlineConstIterator.h"
+#include "itkImageScanlineIterator.h"
+#include "itkProgressReporter.h"
+#include "itkNumericTraitsPointPixel.h"
+#include "itkContinuousIndex.h"
+
+#include "ossim/ossimSarSensorModel.h"
+
+#include <cmath>
+#include <algorithm>
+
+
+namespace otb
+{
+  /** 
+   * Constructor with default initialization
+   */
+  template <class TImageSAR, class TImagePhase, class TImageOut> 
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >::SARCompensatedComplexImageFilter()
+    :  m_nbLinesSAR(0), m_nbColSAR(0)
+  {
+    // Inputs required and/or needed
+    this->SetNumberOfRequiredInputs(2);
+    this->SetNumberOfIndexedInputs(3);
+  }
+    
+  /** 
+   * Destructor
+   */
+  template <class TImageSAR, class TImagePhase, class TImageOut> 
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >::~SARCompensatedComplexImageFilter()
+  {
+  }
+
+  /**
+   * Print
+   */
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::PrintSelf(std::ostream & os, itk::Indent indent) const
+  {
+    Superclass::PrintSelf(os, indent);
+  }
+
+  /**
+   * Set Master Image
+   */ 
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+ SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::SetMasterInput(const ImageSARType* image )
+  {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(0, const_cast<ImageSARType *>(image));
+  }
+
+  /**
+   * Set Coregistrated Slave Image
+   */ 
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+ SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::SetSlaveInput(const ImageSARType* image )
+  {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(1, const_cast<ImageSARType *>(image));
+  }
+
+  /**
+   * Set Topographic phase
+   */ 
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::SetTopographicPhaseInput(const ImagePhaseType* phaseTopoImage)
+  {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(2, const_cast<ImagePhaseType *>(phaseTopoImage));
+  }
+
+  /**
+   * Get Master Image
+   */ 
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  const typename SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >::ImageSARType *
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::GetMasterInput() const
+  {
+    if (this->GetNumberOfInputs()<1)
+      {
+	return 0;
+      }
+    return static_cast<const ImageSARType *>(this->itk::ProcessObject::GetInput(0));
+  }
+
+  /**
+   * Get Coregistrated Slave Image
+   */ 
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  const typename SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >::ImageSARType *
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::GetSlaveInput() const
+  {
+    if (this->GetNumberOfInputs()<2)
+      {
+	return 0;
+      }
+    return static_cast<const ImageSARType *>(this->itk::ProcessObject::GetInput(1));
+  }
+
+  /**
+   * Get Phase Topographic
+   */ 
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  const typename SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >::ImagePhaseType *
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::GetTopographicPhaseInput() const
+  {
+    if (this->GetNumberOfInputs()<3)
+      {
+	return 0;
+      }
+    return static_cast<const ImagePhaseType *>(this->itk::ProcessObject::GetInput(2));
+  }
+
+  /**
+   * Method GenerateOutputInformaton()
+   **/
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::GenerateOutputInformation()
+  {
+    // Call superclass implementation
+    Superclass::GenerateOutputInformation();
+
+    // Get pointers to the inputs and output
+    ImageSARConstPointer masterPtr = this->GetMasterInput();
+    ImageSARConstPointer slavePtr = this->GetSlaveInput();
+    ImageOutPointer outputPtr = this->GetOutput();
+
+    // KeyWordList
+    ImageKeywordlist masterKWL = masterPtr->GetImageKeywordlist();
+
+    // Master SAR Dimensions
+    m_nbLinesSAR = this->GetMasterInput()->GetLargestPossibleRegion().GetSize()[1];
+    m_nbColSAR = this->GetMasterInput()->GetLargestPossibleRegion().GetSize()[0];
+  
+    /////////////////////// Main Output : conjugate multiplication (into SAR geometry) ///////////////////////
+    // Vector Image  :
+    // At Least 3 Components :  
+    //                _ real part
+    //                _ imag part
+    //                _ modulus
+    outputPtr->SetNumberOfComponentsPerPixel(3);
+
+    // The output is defined with the Master SAR Image
+    // Origin, Spacing and Size (SAR master geometry)
+    ImageOutPointType outOrigin;
+    outOrigin = masterPtr->GetOrigin();
+    ImageOutSpacingType outSP;
+    outSP = masterPtr->GetSpacing();
+
+    // Define Output Largest Region
+    ImageOutRegionType outputLargestPossibleRegion = masterPtr->GetLargestPossibleRegion();
+
+    outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
+    outputPtr->SetOrigin(outOrigin);
+    outputPtr->SetSpacing(outSP);
+
+    // Add ML factors and bands meaning into keyWordList
+    ImageKeywordlist outputKWL = masterKWL;
+    outputKWL.AddKey("support_data.band.Amplitude", std::to_string(0));
+    outputKWL.AddKey("support_data.band.Phase", std::to_string(1));
+    outputKWL.AddKey("support_data.band.Coherency", std::to_string(2));
+
+    // Set new keyword list to output image
+    outputPtr->SetImageKeywordList(outputKWL);    
+
+    ///////// Checks (with input topographic phase keywordlists/metadata) /////////////
+    // Check ML Factors (must be 1 to have the same geometry than SAR images)
+     if (this->GetTopographicPhaseInput() != nullptr)
+       {
+	 // Get ImagKeyWordList
+	 ImageKeywordlist topoKWL = this->GetTopographicPhaseInput()->GetImageKeywordlist();
+	 
+	 if (topoKWL.HasKey("support_data.ml_ran") && topoKWL.HasKey("support_data.ml_azi"))
+	   {
+	     // Get Master ML Factors
+	     unsigned int topo_MLRan = atoi(topoKWL.GetMetadataByKey("support_data.ml_ran").c_str());
+	     unsigned int topo_MLAzi = atoi(topoKWL.GetMetadataByKey("support_data.ml_azi").c_str());
+	
+	     if ((topo_MLRan != 1) || (topo_MLAzi != 1))
+	       {
+		 itkExceptionMacro(<<"Error, ML Factor for topographic phase are different than 1.");
+	       }
+	   }
+       }
+  }
+
+
+
+  /** 
+   * Method GenerateInputRequestedRegion
+   */
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::GenerateInputRequestedRegion()
+  {
+    // call the superclass' implementation of this method
+    Superclass::GenerateInputRequestedRegion();
+    
+    // Get Output requested region
+    ImageOutRegionType outputRequestedRegion = this->GetOutput()->GetRequestedRegion();
+
+    // Input Region = Output region
+    ImageSARPointer  masterPtr = const_cast< ImageSARType * >( this->GetMasterInput() );
+    ImageSARPointer  slavePtr = const_cast< ImageSARType * >( this->GetSlaveInput() );
+    
+    masterPtr->SetRequestedRegion(outputRequestedRegion);
+    slavePtr->SetRequestedRegion(outputRequestedRegion);
+
+    ///////////// Find the region into topographic phase image (if needed) /////////////
+    if (this->GetTopographicPhaseInput() != nullptr)
+      {
+	ImagePhasePointer  phasePtr = const_cast< ImagePhaseType * >( this->GetTopographicPhaseInput() );
+	phasePtr->SetRequestedRegion(outputRequestedRegion);
+      }
+  }
+  
+
+  /**
+   * Method ThreadedGenerateData
+   */
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::ThreadedGenerateData(const ImageOutRegionType & outputRegionForThread,
+			 itk::ThreadIdType threadId)
+  {
+    if (this->GetTopographicPhaseInput() == nullptr)
+      {
+	// Process for line
+	this->ThreadedGenerateDataWithoutTopographicPhase(outputRegionForThread,threadId);
+      } 
+    else
+      {
+	// Process for column
+	this->ThreadedGenerateDataWithTopographicPhase(outputRegionForThread,threadId);
+      } 
+  }
+
+  /**
+   * Method ThreadedGenerateDataWithoutTopographicPhase
+   */
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::ThreadedGenerateDataWithoutTopographicPhase(const ImageOutRegionType & outputRegionForThread,
+						itk::ThreadIdType threadId)
+  {
+    //  Define/declare an iterator that will walk the input regions for this
+    // thread. 
+    InputSARIterator  inMasterIt(this->GetMasterInput(), outputRegionForThread);
+    InputSARIterator  inSlaveIt(this->GetSlaveInput(), outputRegionForThread);
+
+    // Define/declare an iterator that will walk the output region for this
+    // thread.
+    OutputIterator outIt(this->GetOutput(), outputRegionForThread);
+
+    // Support progress methods/callbacks
+    itk::ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() );
+
+    inMasterIt.GoToBegin();
+    inSlaveIt.GoToBegin();
+    outIt.GoToBegin();
+    
+    // Output Pixel (VectorImage Pixel)
+    ImageOutPixelType outPixel;
+    outPixel.Reserve(3);
+
+    // For each Line
+    while ( !inMasterIt.IsAtEnd() && !inSlaveIt.IsAtEnd() && !outIt.IsAtEnd())
+      {
+	inMasterIt.GoToBeginOfLine();
+	inSlaveIt.GoToBeginOfLine();
+	outIt.GoToBeginOfLine();
+	
+	    // For each column
+	    while (!inMasterIt.IsAtEndOfLine() && !inSlaveIt.IsAtEndOfLine() && !outIt.IsAtEndOfLine())
+	      {
+		// Conjugate multiplication (master * conj(slave))
+		double real_interfero = (inMasterIt.Get().real()*inSlaveIt.Get().real() + 
+					 inMasterIt.Get().imag()*inSlaveIt.Get().imag());
+
+		double imag_interfero = (inMasterIt.Get().imag()*inSlaveIt.Get().real() - 
+					 inMasterIt.Get().real()*inSlaveIt.Get().imag());
+
+		///////////// Output assignations ///////////////
+		outPixel[0] = real_interfero;
+
+			
+		outPixel[1] = imag_interfero;
+			
+			
+		outPixel[2] = sqrt((real_interfero*real_interfero) + 
+							 (imag_interfero*imag_interfero));
+
+		
+		outIt.Set(outPixel);
+	    
+		// Next colunm inputs
+		++inMasterIt;
+		++inSlaveIt;
+		// Next colunm output
+		++outIt;
+	      }
+	  
+	    // Next line intputs
+	    inMasterIt.NextLine();
+	    inSlaveIt.NextLine();
+	    // Next line output
+	    outIt.NextLine();
+      }
+  }
+
+   /**
+   * Method ThreadedGenerateDataWithtTopographicPhase
+   */
+  template<class TImageSAR, class TImagePhase, class TImageOut>
+  void
+  SARCompensatedComplexImageFilter< TImageSAR, TImagePhase, TImageOut >
+  ::ThreadedGenerateDataWithTopographicPhase(const ImageOutRegionType & outputRegionForThread,
+						itk::ThreadIdType threadId)
+  {
+    //  Define/declare an iterator that will walk the input regions for this
+    // thread. 
+    InputSARIterator  inMasterIt(this->GetMasterInput(), outputRegionForThread);
+    InputSARIterator  inSlaveIt(this->GetSlaveInput(), outputRegionForThread);
+
+    // Define/declare an iterator that will walk the output region for this
+    // thread.
+    OutputIterator outIt(this->GetOutput(), outputRegionForThread);
+
+    // Topographic phase
+    InputPhaseIterator inTopoPhaseIt(this->GetTopographicPhaseInput(), outputRegionForThread);
+
+    // Support progress methods/callbacks
+    itk::ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() );
+
+    inMasterIt.GoToBegin();
+    inSlaveIt.GoToBegin();
+    inTopoPhaseIt.GoToBegin();
+    outIt.GoToBegin();
+    
+    // Output Pixel (VectorImage Pixel)
+    ImageOutPixelType outPixel;
+    outPixel.Reserve(3);
+
+    // For each Line
+    while ( !inMasterIt.IsAtEnd() && !inSlaveIt.IsAtEnd() && !outIt.IsAtEnd())
+      {
+	inMasterIt.GoToBeginOfLine();
+	inSlaveIt.GoToBeginOfLine();
+	inTopoPhaseIt.GoToBeginOfLine();
+	outIt.GoToBeginOfLine();
+	
+	    // For each column
+	    while (!inMasterIt.IsAtEndOfLine() && !inSlaveIt.IsAtEndOfLine() && !outIt.IsAtEndOfLine())
+	      {
+		// Check isData (grom topographic phase)
+		if (inTopoPhaseIt.Get()[1] != 0)
+		  {			
+		    // Complex Raw interferogram (master * conj(slave))
+		    double real_RawInterfero = (inMasterIt.Get().real()*inSlaveIt.Get().real() + 
+						inMasterIt.Get().imag()*inSlaveIt.Get().imag());
+
+		    double imag_RawInterfero = (inMasterIt.Get().imag()*inSlaveIt.Get().real() - 
+						inMasterIt.Get().real()*inSlaveIt.Get().imag());
+
+		    ///////////// Topographoc phase as complex number ////////////////
+		    double topoPhase = inTopoPhaseIt.Get()[0];
+				
+		    double complexTopoPhase_Re = std::cos(topoPhase);
+		    double complexTopoPhase_Im = std::sin(topoPhase);
+
+	
+		    // Multiply the conj(complexTopoPhase) with complex raw interferogram
+		    double real_interfero = (real_RawInterfero * complexTopoPhase_Re + 
+					     imag_RawInterfero * complexTopoPhase_Im);
+		    double imag_interfero = (imag_RawInterfero * complexTopoPhase_Re - 
+					     real_RawInterfero * complexTopoPhase_Im);
+
+		    ///////////// Output assignations ///////////////
+		    outPixel[0] = real_interfero;
+
+			
+		    outPixel[1] = imag_interfero;
+			
+			
+		    outPixel[2] = sqrt((real_interfero*real_interfero) + 
+				       (imag_interfero*imag_interfero));
+		  }
+		else
+		  {
+		    outPixel[0] = 0;
+		    outPixel[1] = 0;
+		    outPixel[2] = 0;
+		    outPixel[3] = 0;
+		  }
+	
+		outIt.Set(outPixel);
+	    
+		// Next colunm inputs
+		++inMasterIt;
+		++inSlaveIt;
+		++inTopoPhaseIt;
+		// Next colunm output
+		++outIt;
+	      }
+	  
+	    // Next line intputs
+	    inMasterIt.NextLine();
+	    inSlaveIt.NextLine();
+	    inTopoPhaseIt.NextLine();
+	    // Next line output
+	    outIt.NextLine();
+      }
+  }
+
+
+  } /*namespace otb*/
+
+#endif
diff --git a/include/otbSARGroupedByOrthoImageFilter.h b/include/otbSARGroupedByOrthoImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..37f647a1ad98b9b5a028f9aa7687dfe2f18a7c0f
--- /dev/null
+++ b/include/otbSARGroupedByOrthoImageFilter.h
@@ -0,0 +1,230 @@
+/*
+ * 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 otbSARGroupedByOrthoImageFilter_h
+#define otbSARGroupedByOrthoImageFilter_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 "-Woverloaded-virtual"
+#if defined(__GNUC__) && (__GNUC__ > 5)
+#pragma GCC diagnostic ignored "-Wnonnull-compare"
+#endif
+#   include "ossim/base/ossimGeoidEgm96.h"
+# pragma GCC diagnostic pop
+#else
+#   include "ossim/base/ossimGeoidEgm96.h"
+#endif
+
+
+namespace otb
+{
+/** \class SARGroupedByOrthoImageFilter 
+ * \brief Creates an interferogram into ground geometry between two images. 
+ * 
+ * This filter built the Ortho interferogram between a master and a slave image.
+ *
+ * The output is a vector image with amplitude, phase and coherency.
+ *
+ * \ingroup DiapOTBModule
+ */
+
+  template <typename TImageVector, typename TImageDEM, typename TImageOut> 
+  class ITK_EXPORT SARGroupedByOrthoImageFilter :
+    public itk::ImageToImageFilter<TImageVector,TImageOut>
+{
+public:
+
+  // Standard class typedefs
+  typedef SARGroupedByOrthoImageFilter                    Self;
+  typedef itk::ImageToImageFilter<TImageVector,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(SARGroupedByOrthoImageFilter,ImageToImageFilter);
+
+  /** Typedef to vector image input type : otb::VectorImage  */
+  typedef TImageVector                                  ImageVectorType;
+  /** Typedef to describe the output image pointer type. */
+  typedef typename ImageVectorType::Pointer             ImageVectorPointer;
+  typedef typename ImageVectorType::ConstPointer        ImageVectorConstPointer;
+  /** Typedef to describe the output image region type. */
+  typedef typename ImageVectorType::RegionType          ImageVectorRegionType;
+  /** Typedef to describe the type of pixel and point for output image. */
+  typedef typename ImageVectorType::PixelType           ImageVectorPixelType;
+  typedef typename ImageVectorType::PointType           ImageVectorPointType;
+  /** Typedef to describe the image index, size types and spacing for output image. */
+  typedef typename ImageVectorType::IndexType           ImageVectorIndexType;
+  typedef typename ImageVectorType::IndexValueType      ImageVectorIndexValueType;
+  typedef typename ImageVectorType::SizeType            ImageVectorSizeType;
+  typedef typename ImageVectorType::SizeValueType       ImageVectorSizeValueType;
+  typedef typename ImageVectorType::SpacingType         ImageVectorSpacingType;
+  typedef typename ImageVectorType::SpacingValueType    ImageVectorSpacingValueType;
+  
+  /** Typedef to image output type : otb::VectorImage  */
+  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;
+
+  /** Typedef to dem type : otb::Image  */
+  typedef TImageDEM                                  ImageDEMType;
+  /** Typedef to describe the output image pointer type. */
+  typedef typename ImageDEMType::Pointer             ImageDEMPointer;
+  typedef typename ImageDEMType::ConstPointer        ImageDEMConstPointer;
+  typedef typename ImageDEMType::SpacingType         ImageDEMSpacingType;
+  typedef typename ImageDEMType::SpacingValueType    ImageDEMSpacingValueType;
+
+  // DEMHandler
+  typedef otb::DEMHandler DEMHandlerType;
+  typedef typename DEMHandlerType::Pointer DEMHandlerPointerType;
+
+  
+  // Define Point2DType and Point3DType
+  using Point2DType = itk::Point<double,2>;
+  using Point3DType = itk::Point<double,3>;
+  typedef double  ValueType;
+
+  // Typedef for iterators
+  typedef itk::ImageScanlineConstIterator< ImageVectorType > InputIterator;
+  typedef itk::ImageScanlineIterator< ImageOutType > OutputIterator;
+
+  
+    
+  // Setter/Getter for inputs (Cartesian mean and GroupedByOrtho) 
+  /** Connect one of the operands for interferometry : Master */
+  void SetCartesianMeanInput( const ImageVectorType* image);
+
+  /** Connect one of the operands for interferometry : Coregistrated Slave */
+  void SetCompensatedComplexInput(const ImageVectorType* image);
+
+  /** Get the inputs */
+  const ImageVectorType* GetCartesianMeanInput() const;
+  const ImageVectorType* GetCompensatedComplexInput() const;
+
+  
+  // Setter for metadata
+  void SetSARImageKeyWorList(ImageKeywordlist sarImageKWL);
+  void SetDEMImagePtr(ImageDEMPointer demPtr);
+
+protected:
+  // Constructor
+  SARGroupedByOrthoImageFilter();
+
+  // Destructor
+  virtual ~SARGroupedByOrthoImageFilter() ITK_OVERRIDE;
+
+  // Print
+  void PrintSelf(std::ostream & os, itk::Indent indent) const ITK_OVERRIDE;
+  
+  /** SARGroupedByOrthoImageFilter produces an image which are into output geometry. The differences between 
+   * output and input images can be the size of images and the dimensions. 
+   * As such, SARGroupedByOrthoImageFilter needs to provide an implementation for 
+   * GenerateOutputInformation() in order to inform the pipeline execution model. 
+   */ 
+  virtual void GenerateOutputInformation() ITK_OVERRIDE;
+
+  /** SARGroupedByOrthoImageFilter needs a input requested region that corresponds to the margin and shifts 
+   * into the requested region of our output requested region. The output requested region needs to be modified
+   * to construct as wanted tiles with input size.
+   * As such, TilesAnalysesImageFilter needs to provide an implementation for 
+   * GenerateInputRequestedRegion() in order to inform the pipeline execution model. 
+   * \sa ProcessObject::GenerateInputRequestedRegion() */
+  virtual void GenerateInputRequestedRegion() ITK_OVERRIDE;
+
+  /**
+   * OutputRegionToInputRegion returns the input SAR region 
+   */
+  ImageVectorRegionType OutputRegionToInputRegion(const ImageOutRegionType& outputRegion,
+						  bool & intoInputImage) const;
+
+
+  /** 
+   * SARGroupedByOrthoImageFilterr can be implemented as a multithreaded filter.
+   * Therefore, this implementation provides a ThreadedGenerateData() routine
+   * which is called for each processing thread. The main 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() */
+  virtual void ThreadedGenerateData(const ImageOutRegionType& outputRegionForThread, 
+				    itk::ThreadIdType threadId) ITK_OVERRIDE;
+
+
+ private:
+  SARGroupedByOrthoImageFilter(const Self&); // purposely not implemented
+  void operator=(const Self &); // purposely not 
+
+  // Instance of SarSensorModelAdapter
+  SarSensorModelAdapter::Pointer m_SarSensorModelAdapter; 
+
+  // SAR Image KeyWorldList
+  ImageKeywordlist m_SarImageKwl;
+
+  ossimGeoidEgm96 * m_geoidEmg96;
+  
+  // DEM
+  ImageDEMConstPointer m_DEMPtr;
+
+  float m_Gain;
+
+  int m_nbLinesSAR;
+  int m_nbColSAR;
+
+};
+
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbSARGroupedByOrthoImageFilter.txx"
+#endif
+
+
+
+#endif
diff --git a/include/otbSARGroupedByOrthoImageFilter.txx b/include/otbSARGroupedByOrthoImageFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..bb6105306270dab41d481853fa55f659c82872fd
--- /dev/null
+++ b/include/otbSARGroupedByOrthoImageFilter.txx
@@ -0,0 +1,664 @@
+/*
+ * 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 otbSARGroupedByOrthoImageFilter_txx
+#define otbSARGroupedByOrthoImageFilter_txx
+
+#include "otbSARGroupedByOrthoImageFilter.h"
+
+#include "itkImageScanlineConstIterator.h"
+#include "itkImageScanlineIterator.h"
+#include "itkProgressReporter.h"
+#include "itkNumericTraitsPointPixel.h"
+#include "itkContinuousIndex.h"
+
+#include "otbConfigurationManager.h"
+
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#include "ossim/base/ossimGpt.h"
+#include "ossim/base/ossimEcefPoint.h"
+#pragma GCC diagnostic pop
+#else
+#include "ossim/base/ossimGpt.h"
+#include "ossim/base/ossimEcefPoint.h"
+#endif
+
+#include <cmath>
+#include <algorithm>
+
+
+namespace otb
+{
+  /** 
+   * Constructor with default initialization
+   */
+  template <class TImageVector, class TImageDEM, class TImageOut> 
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >::SARGroupedByOrthoImageFilter()
+    :  m_SarSensorModelAdapter(ITK_NULLPTR), m_geoidEmg96(NULL), m_DEMPtr(ITK_NULLPTR), m_Gain(1.)
+  {
+    // Inputs required 
+    this->SetNumberOfRequiredInputs(2);
+
+    std::cout << "ConfigurationManager::GetGeoidFile() = " << ConfigurationManager::GetGeoidFile() << std::endl;
+   
+    DEMHandlerPointerType DEMHandler = DEMHandler::Instance();
+    
+    m_geoidEmg96 = 0;
+    const std::string isEmg96 =  "egm96";
+
+    if (!(ConfigurationManager::GetGeoidFile().empty()))
+      {
+	// DEMHandler instance to specify the geoid file
+	DEMHandler->OpenGeoidFile(ConfigurationManager::GetGeoidFile()); 
+
+	// If Geoid by default (emg96) instanciate directly a ossimGeoidEgm96 (increase performance)
+	std::size_t found = ConfigurationManager::GetGeoidFile().find(isEmg96);
+	if (found!=std::string::npos)
+	  {
+	    m_geoidEmg96 = new ossimGeoidEgm96(ossimFilename(ConfigurationManager::GetGeoidFile()));
+	  }
+      }
+    
+  }
+    
+  /** 
+   * Destructor
+   */
+  template <class TImageVector, class TImageDEM, class TImageOut> 
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >::~SARGroupedByOrthoImageFilter()
+  {
+    if (m_geoidEmg96)
+      {
+	delete m_geoidEmg96;
+	m_geoidEmg96 = 0;
+      }
+  }
+
+  /**
+   * Print
+   */
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  void
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::PrintSelf(std::ostream & os, itk::Indent indent) const
+  {
+    Superclass::PrintSelf(os, indent);
+  }
+
+  /**
+   * Set Master Image
+   */ 
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  void
+ SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::SetCartesianMeanInput(const ImageVectorType* image )
+  {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(0, const_cast<ImageVectorType *>(image));
+  }
+
+  /**
+   * Set Coregistrated Slave Image
+   */ 
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  void
+ SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::SetCompensatedComplexInput(const ImageVectorType* image )
+  {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(1, const_cast<ImageVectorType *>(image));
+  }
+
+  /**
+   * Get Master Image
+   */ 
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  const typename SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >::ImageVectorType *
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::GetCartesianMeanInput() const
+  {
+    if (this->GetNumberOfInputs()<1)
+      {
+	return 0;
+      }
+    return static_cast<const ImageVectorType *>(this->itk::ProcessObject::GetInput(0));
+  }
+
+  /**
+   * Get Coregistrated Slave Image
+   */ 
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  const typename SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >::ImageVectorType *
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::GetCompensatedComplexInput() const
+  {
+    if (this->GetNumberOfInputs()<2)
+      {
+	return 0;
+      }
+    return static_cast<const ImageVectorType *>(this->itk::ProcessObject::GetInput(1));
+  }
+
+/**
+ * Set Sar Image keyWordList
+ */ 
+template<class TImageVector, class TImageDEM, class TImageOut>
+void
+SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+::SetSARImageKeyWorList(ImageKeywordlist sarImageKWL)
+{
+  m_SarImageKwl = sarImageKWL;
+}
+
+/**
+ * Set DEM Pointer
+ */ 
+template<class TImageVector, class TImageDEM, class TImageOut>
+void
+SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+::SetDEMImagePtr(ImageDEMPointer demPtr)
+{
+  m_DEMPtr = demPtr;
+}
+
+  /**
+   * Method GenerateOutputInformaton()
+   **/
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  void
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::GenerateOutputInformation()
+  {
+    // Call superclass implementation
+    Superclass::GenerateOutputInformation();
+
+    // Get pointer to output
+    ImageOutPointer outputPtr = this->GetOutput();
+  
+    /////////////////////// Main Output : interferogram (into Ground geometry) ///////////////////////
+    // Vector Image  :
+    // At Least 3 Components :  
+    //                _ amplitude
+    //                _ phase
+    //                _ coherency
+    outputPtr->SetNumberOfComponentsPerPixel(4);
+
+    // The output is defined with the DEM Image
+    // Origin, Spacing and Size (Ground geometry)
+    ImageOutPointType outOrigin;
+    outOrigin = m_DEMPtr->GetOrigin();
+    
+    // Define Output Largest Region
+    ImageOutRegionType outputLargestPossibleRegion = m_DEMPtr->GetLargestPossibleRegion();
+    outputLargestPossibleRegion.SetSize(m_DEMPtr->GetLargestPossibleRegion().GetSize());
+    outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
+    outputPtr->SetOrigin(outOrigin);
+    outputPtr->SetSignedSpacing(m_DEMPtr->GetSignedSpacing());
+
+    // Projection Ref
+    outputPtr->SetProjectionRef(m_DEMPtr->GetProjectionRef());
+    
+    // Create and Initilaze the SarSensorModelAdapter
+    m_SarSensorModelAdapter = SarSensorModelAdapter::New();
+    bool loadOk = m_SarSensorModelAdapter->LoadState(m_SarImageKwl);
+    
+    if(!loadOk || !m_SarSensorModelAdapter->IsValidSensorModel())
+      {
+	itkExceptionMacro(<<"SAR image does not contain a valid SAR sensor model.");
+      }
+
+    // Add Bands meaning into keyWordList
+    ImageKeywordlist outputKWL;
+    outputKWL.AddKey("support_data.band.Amplitude", std::to_string(0));
+    outputKWL.AddKey("support_data.band.Phase", std::to_string(1));
+    outputKWL.AddKey("support_data.band.Coherency", std::to_string(2));
+
+    // Set new keyword list to output image
+    outputPtr->SetImageKeywordList(outputKWL);    
+
+    m_nbLinesSAR = this->GetCompensatedComplexInput()->GetLargestPossibleRegion().GetSize()[1];
+    m_nbColSAR = this->GetCompensatedComplexInput()->GetLargestPossibleRegion().GetSize()[0];
+  }
+
+/** 
+* Method OutputREgionToInputRegion
+*/
+template<class TImageVector, class TImageDEM, class TImageOut>
+typename SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >::ImageVectorRegionType 
+SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+::OutputRegionToInputRegion(const ImageOutRegionType& outputRegion, 
+			    bool & intoInputImage) const
+{
+  // Compute the input requested region (size and start index)
+  // Use the image transformations to insure an input requested region
+  ImageOutSizeType  outputRequestedRegionSize = outputRegion.GetSize();
+  ImageOutIndexType outputRequestedRegionIndex = outputRegion.GetIndex();
+  
+  // Here we are breaking traditional pipeline steps because we need to access the input field data
+  // so as to compute the input image requested region
+  // The direct localisation (SAR to DEM) is performed in order to determine the DEM region (input) 
+  // represented by the SAR region (output)
+  
+  int nbColSAR = m_nbColSAR;
+  int nbLinesSAR = m_nbLinesSAR;   
+  
+
+  //std::cout << "nbColSAR and nbLineSAR : " << nbColSAR << " , " <<  nbLinesSAR << std::endl;
+
+  // Margin to apply on direct localisation for the four sides.
+  int margin = 100;
+  
+  // Indice for the SAR bloc (determined by the Pipeline)
+  ImageOutIndexType id[4] ;
+  id[0][0] = outputRequestedRegionIndex[0];
+  id[0][1] = outputRequestedRegionIndex[1];
+  id[1][0] = outputRequestedRegionIndex[0];
+  id[1][1] = outputRequestedRegionIndex[1] + outputRequestedRegionSize[1];
+  id[2][0] = outputRequestedRegionIndex[0] + outputRequestedRegionSize[0];
+  id[2][1] = outputRequestedRegionIndex[1];
+  id[3][0] = outputRequestedRegionIndex[0] + outputRequestedRegionSize[0];
+  id[3][1] = outputRequestedRegionIndex[1] + outputRequestedRegionSize[1];
+  
+  Point2DType pixelSAR_Into_MNT_LatLon(0);
+  Point2DType pixelSAR(0);
+  //  ImageType::IndexType pixelSAR_Into_MNT;
+  itk::ContinuousIndex<double,2> pixelSAR_Into_MNT;
+  
+  Point3DType demGeoPoint;
+  Point2DType demLatLonPoint;
+  Point2DType col_row(0);
+  Point2DType y_z(0);
+  ossimGpt gptPt;
+
+  // Initialie the first and last DEM indice
+  int firstL, firstC, lastL, lastC; 
+  
+  firstL = nbLinesSAR;
+  lastL = 0;
+  firstC = nbColSAR;
+  lastC = 0;
+  intoInputImage = true;
+  
+  //std::cout << "At the beggindg of OuputToInput  intoInputImage = " << intoInputImage << " And  firstC, firstL, lastC, lastL : " << firstC << ", " << firstL << ", " << lastC << ", " << lastL 
+  //	    << std::endl;
+
+  
+  // For each side of the output region
+  for (int i = 0; i < 4; i++) 
+    {
+      // Transform index to Lat/Lon Point
+      m_DEMPtr->TransformIndexToPhysicalPoint(id[i], demLatLonPoint);
+      demGeoPoint[0] = demLatLonPoint[0];
+      demGeoPoint[1] = demLatLonPoint[1];
+      
+      // Get elevation from earth geoid thanks to DEMHandler or ossimgeoidEmg96
+      double h = 0;
+      if (m_geoidEmg96)
+	{
+	  gptPt.lon =  demLatLonPoint[0];
+	  gptPt.lat =  demLatLonPoint[1];
+	  h = m_geoidEmg96->offsetFromEllipsoid(gptPt);
+	}
+      //demGeoPoint[2] = h;
+      demGeoPoint[2] = 0;
+
+      // Call the method of sarSensorModelAdapter
+      m_SarSensorModelAdapter->WorldToLineSampleYZ(demGeoPoint, col_row, y_z);
+      
+      // Assigne the limits
+      if (firstL > col_row[1])
+	{
+	  firstL = col_row[1];
+	}
+      
+      if (lastL < col_row[1])
+	{
+	  lastL = col_row[1];
+	}
+
+      if (firstC > col_row[0])
+	{
+	  firstC = col_row[0];
+	}
+      
+      if (lastC < col_row[0])
+	{
+	  lastC = col_row[0];
+	}
+
+    }
+
+  // Apply the marge
+  firstL -= margin;
+  firstC -= margin;
+  lastL +=  margin;
+  lastC +=  margin;
+
+  // Check the limits
+  if (firstC < 0)
+    {
+      firstC = 0;
+    } 
+  if (firstL < 0)
+    {
+      firstL = 0;
+    } 
+  if (lastC > nbColSAR-1)
+    {
+      lastC = nbColSAR-1;
+    } 
+  if (lastL > nbLinesSAR-1)
+    {
+      lastL = nbLinesSAR-1;
+    } 
+
+
+  // Check if into input Image
+   
+  if (firstC > nbColSAR-1 || firstL > nbLinesSAR-1)
+    {
+      intoInputImage = false; 
+    } 
+  if (lastC <= 0 || lastL <= 0)
+    {
+      intoInputImage = false; 
+    } 
+
+
+  // Transform sides to region
+  ImageVectorIndexType inputRequestedRegionIndex; 
+  ImageVectorRegionType inputRequestedRegion = outputRegion;
+  if (intoInputImage)
+    {
+      inputRequestedRegionIndex[0] = static_cast<ImageVectorIndexValueType>(firstC);
+      inputRequestedRegionIndex[1] = static_cast<ImageVectorIndexValueType>(firstL);
+      ImageVectorSizeType inputRequestedRegionSize;
+      inputRequestedRegionSize[0] = static_cast<ImageVectorIndexValueType>(lastC - firstC);
+      inputRequestedRegionSize[1] = static_cast<ImageVectorIndexValueType>(lastL - firstL);  
+
+      inputRequestedRegion.SetIndex(inputRequestedRegionIndex);
+      inputRequestedRegion.SetSize(inputRequestedRegionSize);
+
+      //std::cout << "Pouet : " << inputRequestedRegion << std::endl;
+    }
+
+   // std::cout << "At the end of OuputToInput : " <<  inputRequestedRegion << " with intoInputImage = " << intoInputImage << " And  firstC, firstL, lastC, lastL : " << firstC << ", " << firstL << ", " << lastC << ", " << lastL 
+   // 	     << std::endl;
+
+  //std::cout << "At the end of OuputToInput : " <<  inputRequestedRegion.GetSize() << std::endl;
+
+  return inputRequestedRegion;  
+}
+
+  /** 
+   * Method GenerateInputRequestedRegion
+   */
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  void
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::GenerateInputRequestedRegion()
+  {
+    // call the superclass' implementation of this method
+    Superclass::GenerateInputRequestedRegion();
+    
+    // Get Output requested region
+    ImageOutRegionType outputRequestedRegion = this->GetOutput()->GetRequestedRegion();
+
+    // Input Region with OutputToInputRegion
+    bool isIntoInputImages;
+    ImageVectorRegionType inputRequestedRegion = OutputRegionToInputRegion(outputRequestedRegion, 
+									   isIntoInputImages);
+    ImageVectorPointer  cartesianMeanPtr = const_cast< ImageVectorType * >( this->GetCartesianMeanInput() );
+    ImageVectorPointer  compensatedComplexPtr = const_cast< ImageVectorType * >( this->GetCompensatedComplexInput() );
+    
+    //std::cout << "inputRequestedRegion : " << inputRequestedRegion << std::endl; 
+
+    //if (isIntoInputImages)
+    // {
+	cartesianMeanPtr->SetRequestedRegion(inputRequestedRegion);
+	compensatedComplexPtr->SetRequestedRegion(inputRequestedRegion);
+    //   }
+    // else
+    //   {
+    // 	itkExceptionMacro(<<"DEM and SAR geometry do not match.");
+    //   }
+  }
+  
+
+  /**
+   * Method ThreadedGenerateDataWithoutTopographicPhase
+   */
+  template<class TImageVector, class TImageDEM, class TImageOut>
+  void
+  SARGroupedByOrthoImageFilter< TImageVector, TImageDEM, TImageOut >
+  ::ThreadedGenerateData(const ImageOutRegionType & outputRegionForThread,
+			 itk::ThreadIdType threadId)
+  {
+   
+    // Compute corresponding input region
+    bool isIntoInputImage = true;
+    ImageVectorRegionType inputRegionForThread = OutputRegionToInputRegion(outputRegionForThread, isIntoInputImage);
+
+
+    //std::cout << "Pouet : " << inputRegionForThread << " With " << isIntoInputImage << std::endl;
+
+    // Support progress methods/callbacks
+    itk::ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() );
+    
+    // Iterator on output (Ground geometry)
+    OutputIterator OutIt(this->GetOutput(), outputRegionForThread);
+    OutIt.GoToBegin();
+      
+    // Temporary arrays to store outputRegion pixels
+    int regionSize = outputRegionForThread.GetSize()[0] * outputRegionForThread.GetSize()[1];
+    ValueType * tmpArray_real = new ValueType[regionSize];
+    ValueType * tmpArray_imag = new ValueType[regionSize];
+    ValueType * tmpArray_mod = new ValueType[regionSize];
+    ValueType * tmpArray_count = new ValueType[regionSize];
+
+    Point2DType demLonLatPoint;
+    itk::ContinuousIndex<double,2> pixel_Into_DEM_index;
+    ImageOutIndexType index;
+
+    // Init Temporary array (to zero)
+    for (unsigned int i = 0; i < regionSize; i++) 
+      {
+	tmpArray_real[i] = static_cast<ValueType>(0);
+	tmpArray_imag[i] = static_cast<ValueType>(0);
+	tmpArray_mod[i] = static_cast<ValueType>(0);
+	tmpArray_count[i] = static_cast<ValueType>(0);
+      }
+
+
+    // Scan input and estimate ortho geometry if output Region corresponds to input SAR image
+    if (isIntoInputImage)
+      {
+	// Iterators on inputs (SAR geometry)
+	InputIterator CartMeanIt(this->GetCartesianMeanInput(), inputRegionForThread);
+	InputIterator CompComplexIt(this->GetCompensatedComplexInput(), inputRegionForThread);
+	
+	CartMeanIt.GoToBegin();
+	CompComplexIt.GoToBegin();
+	
+	// Scan the input Region
+	// for each line
+	while ( !CartMeanIt.IsAtEnd() && !CompComplexIt.IsAtEnd())
+	  {
+	    CartMeanIt.GoToBeginOfLine();
+	    CompComplexIt.GoToBeginOfLine();
+
+	    // For each column
+	    while (!CartMeanIt.IsAtEndOfLine() && !CompComplexIt.IsAtEndOfLine())
+	      {
+		// Get elt from cartesian mean image (X, Y and Z) and create an ECEF point with its
+		ossimEcefPoint cartPoint(CartMeanIt.Get()[0], CartMeanIt.Get()[1], CartMeanIt.Get()[2]);
+		
+		// Conversion into World point
+		ossimGpt worldPoint(cartPoint);
+		
+		demLonLatPoint[0] = worldPoint.lon;
+		demLonLatPoint[1] = worldPoint.lat;
+	
+		// Get Nearest index into DEM/Ground Geometry
+		// Transform into continuous index 
+		m_DEMPtr->TransformPhysicalPointToContinuousIndex(demLonLatPoint, 
+								  pixel_Into_DEM_index);
+      
+		// Integer index 
+		index [0] = static_cast<int>(pixel_Into_DEM_index[0]);	
+		index [1] = static_cast<int>(pixel_Into_DEM_index[1]);
+            
+		// Check if index into outputRegionForThread
+		if (index[0] >= outputRegionForThread.GetIndex()[0] && 
+		    index[0] < (outputRegionForThread.GetIndex()[0] + 
+				outputRegionForThread.GetSize()[0]) &&
+		    index[1] >= outputRegionForThread.GetIndex()[1] && 
+		    index[1] < (outputRegionForThread.GetIndex()[1] + 
+				outputRegionForThread.GetSize()[1]))
+		  {
+		    //std::cout << "index : " << index << std::endl;
+		    
+		    // Accumulations for CompensatedComplex for current ground index
+		    int index_intoArray = static_cast<int>((index[0]-outputRegionForThread.GetIndex()[0]) + 
+							   (index[1] - outputRegionForThread.GetIndex()[1]) * 
+							   outputRegionForThread.GetSize()[0]);
+		    
+		    if (index_intoArray > regionSize) 
+		      {
+			std::cout << "WTF !! " << std::endl;
+			std::cout << "index[0] = " << index[0] << " And " << "index[1] = " << index[1] << 
+			  std::endl;
+			std::cout << "outputRegionForThread.GetIndex()[0] = " << 
+			  outputRegionForThread.GetIndex()[0] << " outputRegionForThread.GetIndex()[1] = " << 
+			  outputRegionForThread.GetIndex()[1] << std::endl;
+			std::cout << "outputRegionForThread.GetSize()[0] = " << 
+			  outputRegionForThread.GetSize()[0] << " outputRegionForThread.GetSize()[1] = " << 
+			  outputRegionForThread.GetSize()[1] << std::endl;
+			
+
+			std::cout << "index_intoArray = " << index_intoArray << " And  index_intoArray " <<
+			  regionSize << std::endl;
+		      }
+		    
+		    if (index[0] == 1261 && index[1] == 634)
+		      {
+			std::cout << "Rien ????????????" << std::endl;
+		      }
+		    
+		    if (index[0] == 1557 && index[1] == 2038)
+		      {
+			std::cout << "de la donnee !!!!!!" << std::endl;
+		      }
+
+		    tmpArray_real[index_intoArray] += CompComplexIt.Get()[0];
+		    tmpArray_imag[index_intoArray] += CompComplexIt.Get()[1];
+		    tmpArray_mod[index_intoArray] += CompComplexIt.Get()[2];
+		    
+		    ++tmpArray_count[index_intoArray]; 
+		  }
+		++ CartMeanIt;
+		++ CompComplexIt;
+		  
+	      }
+		  
+	    // Next line
+	    CartMeanIt.NextLine();
+	    CompComplexIt.NextLine();
+	  }
+	
+      } // End scan inputs
+
+    
+    // Loop on output
+    ImageOutPixelType pixelOutput;
+    pixelOutput.Reserve(4);
+    int index_intoArray = 0;
+
+    // For each line
+    while ( !OutIt.IsAtEnd())
+      {
+	OutIt.GoToBeginOfLine();
+
+	// For each colunm
+	while (!OutIt.IsAtEndOfLine())
+	  {
+	    if (tmpArray_count[index_intoArray] > 0)
+	      {
+		double mod_Acc = sqrt(tmpArray_real[index_intoArray]*tmpArray_real[index_intoArray] + 
+				      tmpArray_imag[index_intoArray]*tmpArray_imag[index_intoArray]);
+
+		// Amplitude
+		pixelOutput[0] = m_Gain * 
+		  sqrt((tmpArray_mod[index_intoArray]/(tmpArray_count[index_intoArray])));
+		
+		// Phase
+		pixelOutput[1] = std::atan2(tmpArray_imag[index_intoArray], 
+					    tmpArray_real[index_intoArray]);
+		
+		// Mod 2*Pi
+		pixelOutput[1] =  pixelOutput[1]-(2*M_PI)*floor(pixelOutput[1]/(2*M_PI));
+		
+		// Coherency
+		pixelOutput[2] = mod_Acc / tmpArray_mod[index_intoArray] ;
+		
+		// IsData 		
+		pixelOutput[3] = tmpArray_count[index_intoArray];
+	      }
+	    else
+	      {
+		pixelOutput[0] = 0;
+		pixelOutput[1] = 0;
+		pixelOutput[2] = 0;
+		pixelOutput[3] = 0;
+	      }
+	
+	    // Assigne Main output (Groun geometry) 
+	    OutIt.Set(pixelOutput);
+	    progress.CompletedPixel();	
+		
+	    // Next colunm
+	    ++OutIt;
+	    ++index_intoArray;
+	  }
+	    
+	// Next line
+	OutIt.NextLine();
+      }
+	
+		
+    // Free Memory	
+    delete  tmpArray_real;
+    tmpArray_real = 0;
+    delete  tmpArray_imag;
+    tmpArray_imag = 0;
+    delete  tmpArray_mod;
+    tmpArray_mod = 0;
+    delete  tmpArray_count;
+    tmpArray_count = 0;
+         
+  }
+
+
+
+  } /*namespace otb*/
+
+#endif