diff --git a/include/otbSARTemporalCorrelationGridImageFilter.h b/include/otbSARTemporalCorrelationGridImageFilter.h
index f0085955f9b0275bbd3fe18e986da48925cfb9c0..3ed5d683e764ec4fec9cdafaaf5edf448ce6fcb8 100644
--- a/include/otbSARTemporalCorrelationGridImageFilter.h
+++ b/include/otbSARTemporalCorrelationGridImageFilter.h
@@ -184,7 +184,7 @@ namespace otb
     /**
      * OutputRegionToInputRegion assigne master and slave regions 
      */
-    void OutputRegionToInputRegion(const ImageOutRegionType& outputRegion) const;
+    void OutputRegionToInputRegion(const ImageOutRegionType& outputRegion);
 
     /** SARTemporalCorrelationGridImageFilter can be implemented as a multithreaded filter.
      * Therefore, this implementation provides a ThreadedGenerateData() routine
@@ -242,6 +242,9 @@ namespace otb
     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
diff --git a/include/otbSARTemporalCorrelationGridImageFilter.txx b/include/otbSARTemporalCorrelationGridImageFilter.txx
index d51e18eda9176506f8526ee8ba5a70b2dc14b1e0..38191291b28e81fe7b017e0fef437c6d08ba991d 100644
--- a/include/otbSARTemporalCorrelationGridImageFilter.txx
+++ b/include/otbSARTemporalCorrelationGridImageFilter.txx
@@ -65,6 +65,8 @@ namespace otb
 
     m_CorrelationThreshold = 0.3;
 
+    m_FirstLCOffset = true;
+
     m_MLran = 3;
     m_MLazi = 3;
   }
@@ -224,25 +226,42 @@ namespace otb
     ImageOutSpacingType outputSpacing = static_cast<ImageOutSpacingType>(masterPtr->GetSpacing());
     ImageOutPointType outputOrigin = static_cast<ImageOutPointType>(masterPtr->GetOrigin());
 
-    // First/Last Colunm and row
-    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);
+    // 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;
-       
+	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];
+	  }
+      }
 
-    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);
@@ -259,6 +278,16 @@ namespace otb
     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); 
   }
 
@@ -268,11 +297,13 @@ namespace otb
   template<class TImageIn, class TImageOut>
   void
   SARTemporalCorrelationGridImageFilter< TImageIn, TImageOut >
-  ::OutputRegionToInputRegion(const ImageOutRegionType& outputRegion) const
+  ::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];
@@ -295,14 +326,32 @@ namespace otb
 	masterRequestedIndex[dim] *= m_GridStep_ML[dim];
       }
     
-    int firstC_Grid = std::max (1 + m_WinCor_ran, 1 + m_WinCor_ran - m_RoughShift_ran + m_WinAround_ShiftRan);
-    int firstL_Grid = std::max (1 + m_WinCor_azi, 1 + m_WinCor_azi - m_RoughShift_azi + m_WinAround_ShiftAzi);
-
+    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) + firstC_Grid;
-    masterRequestedSize[1] += (2*m_WinCor_azi+1) + firstL_Grid;
+    masterRequestedSize[0] += (2*m_WinCor_ran+1);
+    masterRequestedSize[1] += (2*m_WinCor_azi+1);
 
     masterRequestedRegion.SetSize(masterRequestedSize);
     masterRequestedRegion.SetIndex(masterRequestedIndex);
@@ -424,6 +473,8 @@ namespace otb
     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;
@@ -463,10 +514,26 @@ namespace otb
     std::vector<double> slave;
 
     // First L/C for the grid
-    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 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())
       {
@@ -484,8 +551,8 @@ namespace otb
 	      }
 
 	    // To center correlation estimation and shift to the first L/C
-	    masterIndex[0] -= (m_WinCor_ran-firstC);
-	    masterIndex[1] -= (m_WinCor_azi-firstL);
+	    masterIndex[0] -= (m_WinCor_ran-firstC_Grid);
+	    masterIndex[1] -= (m_WinCor_azi-firstL_Grid);
 
 	    // Build the master region (for correlation estimation)
 	    ImageInRegionType masterCurrentRegion;