diff --git a/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h b/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h
index 3c1321e04a0de9af05693b0c78a7252be5b33303..0e63717b7f1a080563235e9edc4e8442f2d5dcc3 100644
--- a/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h
+++ b/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h
@@ -82,7 +82,9 @@ public:
   bool IsValidSensorModel() const;
 
   /** Deburst metadata if possible and return lines to keep in image file */
-  bool Deburst(std::vector<std::pair<unsigned long, unsigned long> > & lines);
+  bool Deburst(std::vector<std::pair<unsigned long, unsigned long> > & lines,
+	       std::pair<unsigned long,unsigned long> & samples, bool onlyValidSample=false);
+
 
   /** Transform world point (lat,lon,hgt) to input image point
   (col,row) and YZ frame */
diff --git a/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx b/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx
index 5e351bea4b17591fcb9a55966878836dabf46c2e..8e2dd04c56017d1d9da73819cc4f578cd88648b4 100644
--- a/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx
+++ b/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx
@@ -89,11 +89,13 @@ bool SarSensorModelAdapter::IsValidSensorModel() const
   return m_SensorModel.get() != nullptr;
 }
 
-bool SarSensorModelAdapter::Deburst(std::vector<std::pair<unsigned long, unsigned long> > & lines)
+bool SarSensorModelAdapter::Deburst(std::vector<std::pair<unsigned long, unsigned long> > & lines,
+				      std::pair<unsigned long,unsigned long> & samples, 
+				      bool onlyValidSample)
 {
   if(m_SensorModel.get() != nullptr)
     {
-    return m_SensorModel->deburst(lines);
+      return m_SensorModel->deburst(lines, samples, onlyValidSample);
     }
   
   return false;
diff --git a/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx b/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx
index 0858e7e7146997530a067cb32929850e749e06f9..849f91de97313dabacb4533fcd18354c23c7e567 100644
--- a/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx
+++ b/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx
@@ -60,7 +60,10 @@ private:
                           "Note that the output sensor model is updated accordingly. This deburst"
                           " operation is the perfect preprocessing step to orthorectify S1 IW SLC"
                           " product with OTB [2] without suffering from artifacts caused by"
-                          " bursts separation.");
+                          " bursts separation.\n"
+
+			   "Two modes are available for the output image : with all samples and"
+			  "with only valid samples ");
     
     SetDocLimitations("Only Sentinel1 IW SLC products are supported for now. Processing of"
                       " other Sentinel1 modes or TerrasarX images will result in no changes in"
@@ -80,6 +83,9 @@ private:
     AddParameter(ParameterType_OutputImage,  "out", "Output Image");
     SetParameterDescription("out", "Deburst image, with updated geom file that can be further used by Orthorectification application. If the input image is a raw Sentinel1 product, uint16 output type should be used (encoding of S1 product). Otherwise, output type should match type of input image.");
 
+    AddParameter(ParameterType_Bool, "onlyvalidsamples", "Select the modes for output image");
+    SetParameterDescription("onlyvalidsamples", "If true, the selected mode is with only valid samples.");
+
     AddRAMParameter();
 
     SetDocExampleParameterValue("in","s1_iw_slc.tif");
@@ -100,6 +106,12 @@ private:
     m_DeburstFilter = DeburstFilterType::New();
     m_DeburstFilter->SetInput(in);
 
+    if (IsParameterEnabled("onlyvalidsamples"))
+      {
+	m_DeburstFilter->SetOnlyValidSample(true);
+      }
+     
+
     // Set the output image
     SetParameterOutputImage("out", m_DeburstFilter->GetOutput());
   }
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.h b/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.h
index 6b771c9dbfa6052d49104cc93303a85d3572a800..5489259e10fd06dfdf67a5a0620c9f174a6c0527 100644
--- a/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.h
+++ b/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.h
@@ -62,8 +62,11 @@ public:
   typedef typename ImageType::RegionType         RegionType;
   typedef typename ImageType::PointType          PointType;
 
-  typedef std::pair<unsigned long, unsigned long> LinesRecordType;
-  typedef std::vector<LinesRecordType>            LinesRecordVectorType;
+  typedef std::pair<unsigned long, unsigned long> RecordType;
+  typedef std::vector<RecordType>                 LinesRecordVectorType;
+	
+  // Setter
+  itkSetMacro(OnlyValidSample, bool);
   
 protected:
   // Constructor
@@ -81,6 +84,9 @@ protected:
   // Actual processing
   virtual void ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId) override;
 
+  void ThreadedGenerateDataWithAllSamples(const RegionType& outputRegionForThread, itk::ThreadIdType threadId);
+  void ThreadedGenerateDataWithOnlyValidSamples(const RegionType& outputRegionForThread, itk::ThreadIdType threadId);
+
   RegionType OutputRegionToInputRegion(const RegionType& outputRegion) const;
   
 private:
@@ -89,7 +95,12 @@ private:
 
   // Vector of line records
   LinesRecordVectorType m_LinesRecord;
-  
+
+  // Pair for sample valid selection
+  RecordType m_SamplesRecord;
+
+  bool m_OnlyValidSample;
+ 
 };
 
 } // End namespace otb
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.hxx b/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.hxx
index d9de620dba6c6643f22426cb45f4ca74bed45232..e15425f09236a28391fdb72105a316d6caa09c3a 100644
--- a/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.hxx
+++ b/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.hxx
@@ -27,12 +27,14 @@
 #include "otbImageKeywordlist.h"
 #include "itkImageScanlineIterator.h"
 #include "itkImageScanlineConstIterator.h"
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
 
 namespace otb
 {
 // Constructor
 template <class TImage> SarDeburstImageFilter<TImage>::SarDeburstImageFilter()
-  : m_LinesRecord()
+  : m_LinesRecord(), m_SamplesRecord(), m_OnlyValidSample(false)
 {}
 
 // Needs to be re-implemented since size of output is modified
@@ -66,7 +68,7 @@ SarDeburstImageFilter<TImage>::GenerateOutputInformation()
     itkExceptionMacro(<<"Input image does not contain a valid SAR sensor model.");
   
   // Try to call the deburst function
-  bool deburstOk = sarSensorModel->Deburst(m_LinesRecord);
+  bool deburstOk = sarSensorModel->Deburst(m_LinesRecord, m_SamplesRecord, m_OnlyValidSample);
 
   if(!deburstOk || m_LinesRecord.empty())
     itkExceptionMacro(<<"Could not deburst SAR sensor model from input image");
@@ -83,9 +85,6 @@ SarDeburstImageFilter<TImage>::GenerateOutputInformation()
   if(!saveOk)
     itkExceptionMacro(<<"Could not export deburst SAR sensor model to keyword list");
 
-  // Set new keyword list to output image
-  outputPtr->SetImageKeywordList(newKwl);
-
   // Now, filter the LinesRecord so as to account for possible
   // extracts on input image
   long firstInputLine = static_cast<long>(origin[1]-0.5);
@@ -111,7 +110,7 @@ SarDeburstImageFilter<TImage>::GenerateOutputInformation()
     // If record is inside input image region
     if((long)it->first<=lastInputLine && (long)it->second>=firstInputLine)
       {
-      LinesRecordType filteredRecord = *it;
+      RecordType filteredRecord = *it;
       filteredRecord.first = std::max((long)filteredRecord.first,firstInputLine);
       filteredRecord.second = std::min((long)filteredRecord.second,lastInputLine);
       filteredRecords.push_back(filteredRecord);
@@ -134,10 +133,21 @@ SarDeburstImageFilter<TImage>::GenerateOutputInformation()
     deburstSize[1]+=it->second-it->first+1;
     }
 
+  if (m_OnlyValidSample)
+    {
+      deburstSize[0] = m_SamplesRecord.second - m_SamplesRecord.first + 1;
+    }
+  
   // Set largest possible region
   typename ImageType::RegionType outputLargestPossibleRegion = largestPossibleRegion;
   largestPossibleRegion.SetSize(deburstSize);
   outputPtr->SetLargestPossibleRegion(largestPossibleRegion);
+
+  newKwl.AddKey("support_data_number_samples", std::to_string(deburstSize[0]));
+  newKwl.AddKey("support_data_number_lines", std::to_string(deburstSize[1]));
+  
+  // Set new keyword list to output image
+  outputPtr->SetImageKeywordList(newKwl);
 }
 
 template<class TImage>
@@ -172,6 +182,12 @@ SarDeburstImageFilter<TImage>::OutputRegionToInputRegion(const RegionType& outpu
   typename RegionType::SizeType size = inputRegion.GetSize();
   typename RegionType::IndexType index = inputRegion.GetIndex();
   
+  if (m_OnlyValidSample)
+    {
+      index[0]+= m_SamplesRecord.first;
+      //size[0]+= m_SamplesRecord.first;
+    }
+  
   index[1]=inputUpperLeftLine;
   size[1]=inputLowerLeftLine-inputUpperLeftLine+1;
 
@@ -194,7 +210,26 @@ template <class TImage> void SarDeburstImageFilter<TImage>::GenerateInputRequest
 }
 
 // Actual processing
-template <class TImage> void SarDeburstImageFilter<TImage>::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType itkNotUsed(threadId))
+template <class TImage> 
+void 
+SarDeburstImageFilter<TImage>::ThreadedGenerateData(const RegionType& outputRegionForThread, 
+						    itk::ThreadIdType itkNotUsed(threadId))
+{
+  if (m_OnlyValidSample)
+    {
+      this->ThreadedGenerateDataWithOnlyValidSamples(outputRegionForThread, 0);
+    }
+  else
+    {
+      this->ThreadedGenerateDataWithAllSamples(outputRegionForThread, 0);
+    }
+}
+
+// Actual processing with all samples
+template <class TImage> 
+void 
+SarDeburstImageFilter<TImage>::ThreadedGenerateDataWithAllSamples(const RegionType& outputRegionForThread, 
+								  itk::ThreadIdType itkNotUsed(threadId))
 {
   // Compute corresponding input region
   RegionType inputRegionForThread = OutputRegionToInputRegion(outputRegionForThread);
@@ -239,6 +274,59 @@ template <class TImage> void SarDeburstImageFilter<TImage>::ThreadedGenerateData
     }  
 }
 
+// Actual processing with only valid samples
+template <class TImage> 
+void 
+SarDeburstImageFilter<TImage>::ThreadedGenerateDataWithOnlyValidSamples(const RegionType& outputRegionForThread, 
+									itk::ThreadIdType itkNotUsed(threadId))
+{
+  // Compute corresponding input region
+  RegionType inputRegionForThread = OutputRegionToInputRegion(outputRegionForThread);
+  
+  itk::ImageRegionConstIterator<ImageType> inputIt(this->GetInput(),inputRegionForThread);
+  itk::ImageRegionIterator<ImageType> outputIt(this->GetOutput(),outputRegionForThread);
+
+  inputIt.GoToBegin();
+  outputIt.GoToBegin();
+
+  while(!inputIt.IsAtEnd()&&!outputIt.IsAtEnd())
+    {
+      typename ImageType::IndexType currentInputIndex = inputIt.GetIndex();
+      PointType currentInputPoint;
+      this->GetInput()->TransformIndexToPhysicalPoint(currentInputIndex,currentInputPoint);
+
+      bool lineToKeep = false;
+      bool sampleToKeep = false;
+
+      for(LinesRecordVectorType::const_iterator it  = m_LinesRecord.begin();
+	  it!=m_LinesRecord.end();++it)
+	{
+	  if(currentInputPoint[1]-0.5>=it->first && currentInputPoint[1]-0.5<=it->second)
+	    {
+	      lineToKeep = true;
+	      break;
+	    }
+	}
+
+      if (currentInputIndex[0] >= static_cast<int>(m_SamplesRecord.first) && 
+	  currentInputIndex[0] <= static_cast<int>(m_SamplesRecord.second))
+	{
+	  sampleToKeep = true;
+	} 
+
+      if(lineToKeep && sampleToKeep)
+	{
+	  outputIt.Set(inputIt.Get());
+
+	  ++outputIt;
+	}
+    
+
+      ++inputIt;
+    }  
+}
+
+
 } // End namespace otb
 
 #endif
diff --git a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
index 7bbc7f2df4e4939f9b66d123886abce9bef52da8..c3f6731c11f6c59effec84e1c101a476cc33c752 100644
--- a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
@@ -288,12 +288,19 @@ public:
     * Note that the deburst operation has no effect if theBurstRecords
     * contains a single burst. Otherwise it will merge burst together
     * into a single burst, and update GCPs accordingly.
+    * Two modes are available for the output image : with all samples and
+    * with only valid samples. A pair of samples specifies first and last samples
     * \return true if the deburst operation succeeded. No changes is
     * made to the object if the operation fails.
     * \param lines A container for the lines ranges to keep in the
     * deburst image.
+    * \param samples A container for the samples to keep in the
+    * deburst image.
+    * \param onlyValidSample If true, the selected mode is with only valid sample.
     */
-   bool deburst(std::vector<std::pair<unsigned long,unsigned long> >& lines);
+   bool deburst(std::vector<std::pair<unsigned long,unsigned long> >& lines, 
+		std::pair<unsigned long,unsigned long> & samples, bool onlyValidSample=false);
+   
 
    /**
     * This is a helper function to convert image line to deburst image
@@ -453,6 +460,11 @@ protected:
    double                                      theRangeTimeOffset; // Offset in seconds, computed
    bool                                        theRightLookingFlag;
    
+   TimeType                                    theFirstLineTime;
+   TimeType                                    theLastLineTime;
+
+   bool redaptMedataAfterDeburst;
+   
    static const double C;
 
    static const unsigned int thePluginVersion; // version of the SarSensorModel plugin
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
index 31c046fe6baed47cf66876f07021e43d2c7a5fd5..505bc70c2c1bd3bf0f6539be0949f39953d09f9a 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
@@ -139,7 +139,8 @@ namespace ossimplugins
       theBistaticCorrectionNeeded(false),
       theAzimuthTimeOffset(seconds(0)),
       theRangeTimeOffset(0.),
-      theRightLookingFlag(true)
+      theRightLookingFlag(true),
+      redaptMedataAfterDeburst(false)
       {}
 
    ossimSarSensorModel::GCPRecordType const&
@@ -1359,6 +1360,14 @@ bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeT
 
      add(kwl, HEADER_PREFIX, "version", thePluginVersion);
 
+     if (redaptMedataAfterDeburst)
+       {
+	 add(kwl, SUPPORT_DATA_PREFIX, "first_line_time", theFirstLineTime);
+	 add(kwl, SUPPORT_DATA_PREFIX, "last_line_time", theLastLineTime);
+	 add(kwl, HEADER_PREFIX, "first_line_time", theFirstLineTime);
+	 add(kwl, HEADER_PREFIX, "last_line_time", theLastLineTime);
+       }
+
      return ossimSensorModel::saveState(kwl, prefix);
    }
 
@@ -1425,7 +1434,8 @@ bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeT
       return false;
    }
 
-bool ossimSarSensorModel::deburst(std::vector<std::pair<unsigned long, unsigned long> >& lines)
+bool ossimSarSensorModel::deburst(std::vector<std::pair<unsigned long, unsigned long> >& lines, 
+				  std::pair<unsigned long,unsigned long> & samples, bool onlyValidSample)
 {
   if(theBurstRecords.empty())
     return false;
@@ -1452,6 +1462,8 @@ bool ossimSarSensorModel::deburst(std::vector<std::pair<unsigned long, unsigned
   TimeType deburstAzimuthStartTime = it->azimuthStartTime;
 
   unsigned long deburstEndLine = 0;
+
+  samples = std::make_pair(it->startSample, it->endSample);
   
   for(; next!= itend ;++it,++next)
     {
@@ -1466,17 +1478,44 @@ bool ossimSarSensorModel::deburst(std::vector<std::pair<unsigned long, unsigned
       
     unsigned long currentStop = it->endLine-halfLineOverlapEnd;
 
-    deburstEndLine+=currentStop-currentStart;
+    deburstEndLine+= currentStop - currentStart + 1; // +1 because currentStart/Stop are both valids
+
     
     lines.push_back(std::make_pair(currentStart,currentStop));
 
-    currentStart = next->startLine+halfLineOverlapBegin;    
+    currentStart = next->startLine+halfLineOverlapBegin;
+
+     if (onlyValidSample)
+      {
+	// Find the first and last valid sampleburst
+	if (it->startSample > samples.first)
+	  {
+	    samples.first = it->startSample;
+	  }
+	if (it->endSample < samples.second)
+	  {
+	    samples.second = it->endSample;
+	  }
+      }
     }
 
   TimeType deburstAzimuthStopTime = it->azimuthStopTime;
   deburstEndLine+=it->endLine-currentStart;
 
   lines.push_back(std::make_pair(currentStart,it->endLine));
+
+  if (onlyValidSample)
+    {
+      if (it->startSample > samples.first)
+	{
+	  samples.first = it->startSample;
+	}
+      if (it->endSample < samples.second)
+	{
+	  samples.second = it->endSample;
+	}
+    }
+
   
   // Now, update other metadata accordingly
 
@@ -1489,6 +1528,13 @@ bool ossimSarSensorModel::deburst(std::vector<std::pair<unsigned long, unsigned
   deburstBurst.azimuthStartTime = deburstAzimuthStartTime;
   deburstBurst.endLine = deburstEndLine;
   deburstBurst.azimuthStopTime = deburstAzimuthStopTime;
+
+  if (onlyValidSample)
+    {
+      deburstBurst.startSample = 0;
+      deburstBurst.endSample = samples.second - samples.first;
+    }
+
   
   theBurstRecords.push_back(deburstBurst);
 
@@ -1501,21 +1547,50 @@ bool ossimSarSensorModel::deburst(std::vector<std::pair<unsigned long, unsigned
       unsigned long newLine=0;
 
       unsigned long gcpLine = std::floor(currentGCP.imPt.y+0.5);
+      unsigned long gcpSample = std::floor(currentGCP.imPt.x+0.5);
+
 
       // Be careful about fractional part of GCPs
-      double fractional = currentGCP.imPt.y - gcpLine;
-      
-      bool deburstOk = imageLineToDeburstLine(lines,gcpLine,newLine);
+      double fractionalLines = currentGCP.imPt.y - gcpLine;
+      double fractionalSamples = currentGCP.imPt.x - gcpSample;
 
-      if(deburstOk)
+      bool linesOk = imageLineToDeburstLine(lines,gcpLine,newLine);
+
+      // Gcp into valid samples
+      bool samplesOk = true;
+      unsigned long newSample = gcpSample;
+      
+      if (onlyValidSample)
+	{
+	  samplesOk = false;
+	  if (gcpSample >= samples.first && gcpSample <= samples.second)
+	    {
+	      samplesOk = true;
+	      newSample -= samples.first; // Offset with first valid sample
+	    } 
+	}
+
+      if(linesOk && samplesOk)
         {
-        currentGCP.imPt.y = newLine+fractional;
-        deburstGCPs.push_back(currentGCP);
+	  currentGCP.imPt.y = newLine + fractionalLines;
+	  currentGCP.imPt.x = newSample + fractionalSamples;
+	  
+	  deburstGCPs.push_back(currentGCP);
         }        
       }
 
   theGCPRecords.swap(deburstGCPs);
 
+
+  // Adapt general metadata : theNearRangeTime, first_time_line, last_time_line
+  redaptMedataAfterDeburst = false;
+  theFirstLineTime = deburstBurst.azimuthStartTime;
+  theLastLineTime = deburstBurst.azimuthStopTime;
+  
+  if (onlyValidSample)
+    theNearRangeTime += samples.first*(1/theRangeSamplingRate); 
+
+
   return true;
 }