diff --git a/app/otbSARMetadataCorrection.cxx b/app/otbSARMetadataCorrection.cxx
index cf6833c6085ca7c033525a461b7132a75aa216f2..f665f58451f20e3061361c63c7b51012333c1148 100644
--- a/app/otbSARMetadataCorrection.cxx
+++ b/app/otbSARMetadataCorrection.cxx
@@ -28,8 +28,12 @@
 #include <fstream>
 #include <complex>
 #include <cmath>
+#include <ctime>
 #include <iosfwd>
 
+#include "otb_tinyxml.h"
+#include "itksys/SystemTools.hxx"
+
 // include ossim
 #if defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic push
@@ -47,11 +51,21 @@
 #endif
 
 
+enum
+{
+  Mode_UserDefined,
+  Mode_GCP,
+  Mode_Orbits
+};
+
+
+
 // Time/Date ossim 
 typedef ossimplugins::time::ModifiedJulianDate TimeType;
 typedef ossimplugins::time::Duration           DurationType;
 
 // Keys for ImageKeywordlist
+// Gcp keys
 const std::string keyAzimuthTime      = "azimuthTime";
 const std::string keySlantRangeTime   = "slant_range_time";
 const std::string keyImPtX            = "im_pt.x";
@@ -62,6 +76,16 @@ const std::string keyWorldPtHgt       = "world_pt.hgt";
 const std::string GCP_PREFIX          = "support_data.geom.gcp";
 const std::string GCP_NUMBER_KEY      = "support_data.geom.gcp.number";
 const std::string SUPPORT_DATA_PREFIX = "support_data.";
+// Orbit keys
+const std::string ORBIT_PREFIX        = "orbitList.orbit";
+const std::string ORBIT_NUMBER_KEY    = "orbitList.nb_orbits";
+const std::string keyTime             = "time";
+const std::string keyPosX             = "x_pos";
+const std::string keyPosY             = "y_pos";
+const std::string keyPosZ             = "z_pos";
+const std::string keyVelX             = "x_vel";
+const std::string keyVelY             = "y_vel";
+const std::string keyVelZ             = "z_vel";
 
 
 ///// Functions to handle metadata //////
@@ -332,6 +356,130 @@ int updateGCPAndKWL(std::vector<double> * vector_hgt, unsigned int gcpcount, otb
   return 0;  
 }
 
+// Selection for fine orbits (choose only orbits that fit with the image)
+int selectOrbits(std::vector<std::string> * vector_time,
+		 const otb::ImageKeywordlist inKWL, int & ind_first, int & ind_last)
+{
+  // Initialize indexes
+  ind_first = 0;
+  ind_last = vector_time->size() - 1;
+
+  // Get time for first and last original orbit states
+  int orbitCount = std::atoi(inKWL.GetMetadataByKey(ORBIT_NUMBER_KEY).c_str());
+  
+  char prefix_first[1024];
+  sprintf(prefix_first, "%s[%d].%s", ORBIT_PREFIX.c_str(), 0, keyTime.c_str());
+  std::string UTC_first = inKWL.GetMetadataByKey(std::string (prefix_first));  
+ 
+  char prefix_last[1024];
+  sprintf(prefix_last, "%s[%d].%s", ORBIT_PREFIX.c_str(), (orbitCount-1), keyTime.c_str());
+  std::string UTC_last = inKWL.GetMetadataByKey(std::string (prefix_last));
+  
+  // Transform string to t_time (in seconds)
+  struct tm tm1;
+  struct tm tm2;
+  strptime(UTC_first.c_str(), "%Y-%m-%dT%H:%M:%SZ", &tm1);
+  strptime(UTC_last.c_str(), "%Y-%m-%dT%H:%M:%SZ", &tm2);
+  time_t t_first = mktime(&tm1);
+  time_t t_last = mktime(&tm2);
+	    
+  // Selection of indexes into vector_time
+  // ind_first = last elt to be inferior to t_first
+  // ind_last = first elt to be superior to t_last
+  for (unsigned int i = 0; i < vector_time->size(); i++) 
+    {
+      struct tm tm;
+      strptime(vector_time->at(i).c_str(), "%Y-%m-%dT%H:%M:%SZ", &tm);
+      time_t t = mktime(&tm);
+
+      if (difftime(t, t_first) > 0 && ind_first == 0)
+	{
+	  if (i !=0)
+	    {
+	      ind_first = i - 1; 
+	    } 
+	}
+      if (difftime(t_last, t) < 0)
+	{
+	  ind_last = i;
+	  
+	  break;
+	}
+    }
+}
+
+
+// Create new Orbits and update outKWL //
+int createOrbitsAndUpdateKWL(std::vector<double *>* vector_posvel, 
+			     std::vector<std::string> * vector_time,
+			     int ind_first, int ind_last,
+			     otb::ImageKeywordlist & outKWL)
+{
+  // Check size (same size for all vectors)
+  unsigned int vecSize = vector_posvel->size();
+  if (vector_time->size() != vecSize)
+    {
+      // retrun 1 => Pb
+      return 1;
+    }
+
+  int orbitCount = std::atoi(outKWL.GetMetadataByKey(ORBIT_NUMBER_KEY).c_str());
+ 
+  if (vecSize < orbitCount)
+    {
+      // Fine orbit are inferior to original => pb
+      return 1;
+    }
+
+  std::string orbitFineCount = std::to_string(ind_last - ind_first + 1);
+  outKWL.AddKey(ORBIT_NUMBER_KEY, orbitFineCount);
+  
+  // Create or update each Orbit state
+  for (unsigned int i = 0; i < std::atoi(orbitFineCount.c_str()); i++) 
+    {
+      // Add the orbit to kwl
+      char prefix[1024];
+      
+      std::stringstream stream;
+ 
+      // time
+      sprintf(prefix, "%s[%d].%s", ORBIT_PREFIX.c_str(), i, keyTime.c_str());
+      outKWL.AddKey(prefix, vector_time->at(ind_first + i));
+      
+      // position
+      sprintf(prefix, "%s[%d].%s", ORBIT_PREFIX.c_str(), i, keyPosX.c_str());
+      stream.str("");
+      stream << std::fixed << std::setprecision(6) << vector_posvel->at(ind_first + i)[0];
+      outKWL.AddKey(prefix, stream.str());
+
+      sprintf(prefix, "%s[%d].%s", ORBIT_PREFIX.c_str(), i, keyPosY.c_str());
+      stream.str("");
+      stream << std::fixed << std::setprecision(6) << vector_posvel->at(ind_first + i)[1];
+      outKWL.AddKey(prefix, stream.str());
+
+      sprintf(prefix, "%s[%d].%s", ORBIT_PREFIX.c_str(), i, keyPosZ.c_str());
+      stream.str("");
+      stream << std::fixed << std::setprecision(6) << vector_posvel->at(ind_first + i)[2];
+      outKWL.AddKey(prefix, stream.str());
+      
+      // velocity
+      sprintf(prefix, "%s[%d].%s", ORBIT_PREFIX.c_str(), i, keyVelX.c_str());
+      stream.str("");
+      stream << std::fixed << std::setprecision(6) << vector_posvel->at(ind_first + i)[3];
+      outKWL.AddKey(prefix, stream.str());
+
+      sprintf(prefix, "%s[%d].%s", ORBIT_PREFIX.c_str(), i, keyVelY.c_str());
+      stream.str("");
+      stream << std::fixed << std::setprecision(6) << vector_posvel->at(ind_first + i)[4];
+      outKWL.AddKey(prefix, stream.str());
+
+      sprintf(prefix, "%s[%d].%s", ORBIT_PREFIX.c_str(), i, keyVelZ.c_str());
+      stream.str("");
+      stream << std::fixed << std::setprecision(6) << vector_posvel->at(ind_first + i)[5];
+      outKWL.AddKey(prefix, stream.str());
+    }
+  return 0;
+}
 
 ///// OTB Application //////
 namespace otb
@@ -374,6 +522,22 @@ private:
     AddParameter(ParameterType_InputImage,  "insar",   "Input SAR image");
     SetParameterDescription("insar", "SAR Image to extract initial metadata.");
 
+    AddParameter(ParameterType_InputFilename, "infineorbits", "Input file to get precise orbits");
+    SetParameterDescription("infineorbits","Input file to get precise orbits.");
+    MandatoryOff("infineorbits");
+
+    // mode selection : gcp (auto) or fine orbits
+    AddParameter(ParameterType_Choice, "mode", "Parameters estimation modes");
+    AddChoice("mode.auto", "User Defined");
+    SetParameterDescription("mode.auto", "This mode allows you to fully modify default values : GCP corrections");
+    AddChoice("mode.gcp", "GCP corrections");
+    SetParameterDescription("mode.gcp",
+                            "This mode allows you to automatically correct GCP into the output geom file");
+    AddChoice("mode.orbits", "Fine orbits");
+    SetParameterDescription("mode.orbits",
+                            "This mode allows you to automatically retrieve the fine orbits and to save into a new geom file");
+    
+
     AddParameter(ParameterType_OutputFilename, "outkwl", "Write the OSSIM keywordlist to a geom file");
     SetParameterDescription("outkwl", "This option allows extracting the OSSIM keywordlist of the image into a geom file.");
     MandatoryOff("outkwl");
@@ -386,145 +550,300 @@ private:
 
   void DoUpdateParameters() override
   {
-    // Nothing to do here : all parameters are independent
+    // Handle inputs following the mode
+    // chose by the user
+    switch (GetParameterInt("mode"))
+      {
+      case Mode_UserDefined:
+	{
+	  EnableParameter("indem");
+	  EnableParameter("outkwl");
+	  DisableParameter("infineorbits");
+
+	  MandatoryOn("indem");
+	  MandatoryOff("outkwl");
+	  MandatoryOff("infineorbits");
+	}
+      break;
+      case Mode_GCP:
+	{
+	  EnableParameter("indem");
+	  EnableParameter("outkwl");
+	  DisableParameter("infineorbits");
+	  
+	  MandatoryOn("indem");
+	  MandatoryOff("outkwl");
+	  MandatoryOff("infineorbits");
+	}
+      break;
+      case Mode_Orbits:
+	{
+	  DisableParameter("indem");
+	  EnableParameter("outkwl");
+	  EnableParameter("infineorbits");
+
+	  MandatoryOff("indem");
+	  MandatoryOn("outkwl");
+	  MandatoryOn("infineorbits");
+	}
+      break;
+      } // switch (GetParameterInt("mode") )
   }
 
   void DoExecute() override
   {  
     std::ostringstream ossOutput;
 
-    // Get inputs 
+    ////// Get inputs and keywordlist ///// 
     ComplexFloatImageType::Pointer SARPtr = GetParameterComplexFloatImage("insar");
-    FloatImageType::Pointer inputDEM =  GetParameterFloatImage("indem");
-
-    // Get Sar keyWordList
-    otb::ImageKeywordlist sar_kwl = SARPtr->GetImageKeywordlist();
-    
+ 
     // Read information
     typedef otb::ImageMetadataInterfaceBase ImageMetadataInterfaceType;
     ImageMetadataInterfaceType::Pointer metadataInterface = ImageMetadataInterfaceFactory::CreateIMI(SARPtr->GetMetaDataDictionary());
   
-
-    // Change insar (???)
-    // SetParameterOutputImage("out", SARPtr); // Compilation error
-    // SARPtr->UpdateOutputInformation(); // Does not write (only for reader)
-
-    ////////// KyWordList (geom) //////////////
     SARPtr->UpdateOutputInformation();
     
     ImageKeywordlist outputKWL = SARPtr->GetImageKeywordlist();
-    
-    // Check with metadataInterface and keyword List
-    int gcpcount = metadataInterface->GetGCPCount();
 
-    if (gcpcount == 0)
+
+    // Get mode to adapt estimation according to user choice
+    bool doGcpCorrection = false;
+    bool doFineOrbits = false;
+
+    switch (GetParameterInt("mode"))
+      {
+      case Mode_UserDefined:
+	{
+	  doGcpCorrection = true;
+	}
+      break;
+      case Mode_GCP:
+	{
+	  doGcpCorrection = true;
+	}
+      break;
+      case Mode_Orbits:
+	{
+	  doFineOrbits = true;
+	}
+      break;
+      } // switch (GetParameterInt("mode") )
+   
+    /////// GCP Correction ///////
+    if (doGcpCorrection)
       {
-	int gcpcount_kwl = std::atoi(outputKWL.GetMetadataByKey(GCP_NUMBER_KEY).c_str());
-	if (gcpcount_kwl > 5)
+	FloatImageType::Pointer inputDEM =  GetParameterFloatImage("indem");
+	// Check with metadataInterface and keyword List
+	int gcpcount = metadataInterface->GetGCPCount();
+
+	if (gcpcount == 0)
 	  {
-	    gcpcount = gcpcount_kwl;
+	    int gcpcount_kwl = std::atoi(outputKWL.GetMetadataByKey(GCP_NUMBER_KEY).c_str());
+	    if (gcpcount_kwl > 5)
+	      {
+		gcpcount = gcpcount_kwl;
+	      }
 	  }
-      }
 
-    std::vector<double *> * vector_lonlat = new std::vector<double *>(); 
-    std::vector<int *>   * vector_colrow = new std::vector<int *>(); 
-    std::vector<int> vector_ind; 
-    std::vector<TimeType>  vector_aziTime;
-    std::vector<double>  vector_ranTime;
+	std::vector<double *> * vector_lonlat = new std::vector<double *>(); 
+	std::vector<int *>   * vector_colrow = new std::vector<int *>(); 
+	std::vector<int> vector_ind; 
+	std::vector<TimeType>  vector_aziTime;
+	std::vector<double>  vector_ranTime;
 
-    // Build the input (vector_lonlat) for GetClosestMNTHeight filter
-    if (gcpcount == 0)
-      {
-	// If no GCP => Retrieve Corners instead
-	// Get latitude and longitude for ur, ul, ll lr and center points
-	try
+	// Build the input (vector_lonlat) for GetClosestMNTHeight filter
+	if (gcpcount == 0)
 	  {
-	    getCorners(metadataInterface->GetImageKeywordlist(), vector_lonlat, 
-		       vector_colrow, vector_ind, vector_aziTime,
-		       vector_ranTime);
+	    // If no GCP => Retrieve Corners instead
+	    // Get latitude and longitude for ur, ul, ll lr and center points
+	    try
+	      {
+		getCorners(metadataInterface->GetImageKeywordlist(), vector_lonlat, 
+			   vector_colrow, vector_ind, vector_aziTime,
+			   vector_ranTime);
+	      }
+	    catch (itk::ExceptionObject& /*err*/)
+	      {
+	      }
 	  }
-	catch (itk::ExceptionObject& /*err*/)
-	  {
+	else
+	  {	
+	    // If GCPs => Retrieve its
+	    // Get latitude and longitude for each of its
+	    getGCP(metadataInterface, gcpcount, outputKWL, vector_lonlat, vector_colrow, vector_ind);
 	  }
-      }
-    else
-      {	
-	// If GCPs => Retrieve its
-	// Get latitude and longitude for each of its
-	getGCP(metadataInterface, gcpcount, outputKWL, vector_lonlat, vector_colrow, vector_ind);
-      }
     
     
-    ///// DEMClosestHgt filter to estimate accurate heights /////
-    DEMClosestHgtFilterType::Pointer filterDEMClosestHgt = DEMClosestHgtFilterType::New();
-    m_Ref.push_back(filterDEMClosestHgt.GetPointer());
+	///// DEMClosestHgt filter to estimate accurate heights /////
+	DEMClosestHgtFilterType::Pointer filterDEMClosestHgt = DEMClosestHgtFilterType::New();
+	m_Ref.push_back(filterDEMClosestHgt.GetPointer());
    
-    // Set inputs : DEM and the vector_LonLat
-    filterDEMClosestHgt->SetInput(inputDEM);
-    filterDEMClosestHgt->SetVectorLonLat(vector_lonlat);
+	// Set inputs : DEM and the vector_LonLat
+	filterDEMClosestHgt->SetInput(inputDEM);
+	filterDEMClosestHgt->SetVectorLonLat(vector_lonlat);
 
-    // Init a vector for hgt
-    std::vector<double> * vector_hgt = new vector<double>();
-    vector_hgt->resize(vector_lonlat->size()); // Same size than lon and lat
+	// Init a vector for hgt
+	std::vector<double> * vector_hgt = new vector<double>();
+	vector_hgt->resize(vector_lonlat->size()); // Same size than lon and lat
     
-    for (unsigned int k = 0; k < vector_lonlat->size(); k++) 
-      {
-	vector_hgt->at(k) = 0;
-      }
+	for (unsigned int k = 0; k < vector_lonlat->size(); k++) 
+	  {
+	    vector_hgt->at(k) = 0;
+	  }
     
-    // Launch our Persistent filter
-    filterDEMClosestHgt->Update();
-    filterDEMClosestHgt->GetDEMHgt(vector_hgt);
+	// Launch our Persistent filter
+	filterDEMClosestHgt->Update();
+	filterDEMClosestHgt->GetDEMHgt(vector_hgt);
 
-    // Add or update GCP into the output KWL (according to the sensor (GCPs already present or not))
-    if (gcpcount == 0)
-      {
-	// Create GPCs with the four corners and center
-	createGCPAndUpdateKWL(vector_lonlat, vector_hgt,
-			      vector_colrow, vector_ind,
-			      vector_aziTime,
-			      vector_ranTime, outputKWL);
-      }
-    else
-      {
-	// Just update heigths
-	updateGCPAndKWL(vector_hgt, gcpcount, outputKWL);
-      }
+	// Add or update GCP into the output KWL (according to the sensor (GCPs already present or not))
+	if (gcpcount == 0)
+	  {
+	    // Create GPCs with the four corners and center
+	    createGCPAndUpdateKWL(vector_lonlat, vector_hgt,
+				  vector_colrow, vector_ind,
+				  vector_aziTime,
+				  vector_ranTime, outputKWL);
+	  }
+	else
+	  {
+	    // Just update heigths
+	    updateGCPAndKWL(vector_hgt, gcpcount, outputKWL);
+	  }
     
     
-    // Display image information in  the dedicated logger
-    otbAppLogINFO(<< ossOutput.str());
+	// Display image information in  the dedicated logger
+	otbAppLogINFO(<< ossOutput.str());
 
-    // Free Memory
-    for (unsigned int itab = 0; itab < vector_lonlat->size(); itab++) 
-      {
-	delete vector_lonlat->at(itab);
-	vector_lonlat->at(itab) = 0;
-      }
-    vector_lonlat->clear();
-    delete vector_lonlat;
-    vector_lonlat = 0;
+	// Free Memory
+	for (unsigned int itab = 0; itab < vector_lonlat->size(); itab++) 
+	  {
+	    delete vector_lonlat->at(itab);
+	    vector_lonlat->at(itab) = 0;
+	  }
+	vector_lonlat->clear();
+	delete vector_lonlat;
+	vector_lonlat = 0;
 
-    vector_hgt->clear();
-    delete vector_hgt;
-    vector_hgt = 0;
+	vector_hgt->clear();
+	delete vector_hgt;
+	vector_hgt = 0;
 
     
-    for (unsigned int itab = 0; itab < vector_colrow->size(); itab++) 
-      {
-	delete vector_colrow->at(itab);
-	vector_colrow->at(itab) = 0;
+	for (unsigned int itab = 0; itab < vector_colrow->size(); itab++) 
+	  {
+	    delete vector_colrow->at(itab);
+	    vector_colrow->at(itab) = 0;
+	  }
+	vector_colrow->clear();
+	delete vector_colrow;
+	vector_colrow = 0;
+
+	vector_ind.clear();
+	vector_aziTime.clear();
+	vector_ranTime.clear();
       }
-    vector_colrow->clear();
-    delete vector_colrow;
-    vector_colrow = 0;
 
-    vector_ind.clear();
-    vector_aziTime.clear();
-    vector_ranTime.clear();
+    /////// Fine orbits ///////
+    if (doFineOrbits)
+      {
+	double ullat = std::atof(outputKWL.GetMetadataByKey("ul_lat").c_str());
+
+	// Add into SAR Image keyword list, the precise metadata
+	std::string inFile = GetParameterString("infineorbits");
+	
+
+	// Check that the right extension is given : expected .EOF */
+	std::string extension = itksys::SystemTools::GetFilenameLastExtension(inFile);
+	if (itksys::SystemTools::LowerCase(extension) != ".eof")
+	  {
+	    itkExceptionMacro(<< extension << " is a wrong Extension FileName : Expected .EOF");
+	  }
+
+	// Open the xml file
+	TiXmlDocument doc(inFile.c_str());
+	if (!doc.LoadFile())
+	  {
+	    itkExceptionMacro(<< "Can't open file " << inFile);
+	  }
+
+	TiXmlHandle   hDoc(&doc);
+
+	// Get root node
+	TiXmlElement* root = hDoc.FirstChildElement("Earth_Explorer_File").ToElement();
+
+	if (root)
+	  {
+	    // Init vectors 
+	    std::vector<double *> * vector_posvel = new std::vector<double *>(); 
+	    std::vector<std::string> * vector_time = new std::vector<std::string>();
+
+	    // Get Data_Block
+	    TiXmlElement* dataBlock = root->FirstChildElement("Data_Block");
+	    
+	    // Retrieve the number of orbits
+	    int count = std::atoi(dataBlock->FirstChildElement("List_of_OSVs")->Attribute("count"));
+
+	    int count_loop = 0;
+	    
+	    // Iterate through the tree to get all the orbits
+	    // Fill vectors with its 
+	    for (TiXmlElement* currentOrb = dataBlock->FirstChildElement("List_of_OSVs")->FirstChildElement(); 
+		 currentOrb != nullptr; currentOrb = currentOrb->NextSiblingElement())
+	      {
+		double * posvel = new double[6];
+		
+		std::string UTCTime = std::string(currentOrb->FirstChildElement("UTC")->GetText());
+		UTCTime = UTCTime.substr(UTCTime.find("=")+1, UTCTime.length());
+		
+		posvel[0] = std::atof(currentOrb->FirstChildElement("X")->GetText());
+		posvel[1] = std::atof(currentOrb->FirstChildElement("Y")->GetText());
+		posvel[2] = std::atof(currentOrb->FirstChildElement("Z")->GetText());
+		posvel[3] = std::atof(currentOrb->FirstChildElement("VX")->GetText());
+		posvel[4] = std::atof(currentOrb->FirstChildElement("VY")->GetText());
+		posvel[5] = std::atof(currentOrb->FirstChildElement("VZ")->GetText());
+
+		vector_posvel->push_back(posvel);
+		vector_time->push_back(std::string(UTCTime));
+
+		++count_loop;
+	      }
+
+	    int ind_first, ind_last;
+	    selectOrbits(vector_time, outputKWL, ind_first, ind_last);
 
+    
+	    // Check coherency between the number of orbits
+	    if (count != count_loop)
+	      {
+		itkExceptionMacro(<< "Problem of coherency into EOF file");
+	      }
+
+
+	    int ret = createOrbitsAndUpdateKWL(vector_posvel, vector_time, ind_first,
+					       ind_last, outputKWL);
+
+	    if (ret == 1)
+	      {
+		itkExceptionMacro(<< "Problem during orbits update");
+	      }
+
+	    // Free Memory
+	    for (unsigned int itab = 0; itab < vector_posvel->size(); itab++) 
+	      {
+		delete vector_posvel->at(itab);
+		vector_posvel->at(itab) = 0;
+	      }
+	    vector_posvel->clear();
+	    delete vector_posvel;
+	    vector_posvel = 0;
+	    
+	    vector_time->clear();
+	    delete vector_time;
+	    vector_time = 0;
+	  }
+      }
 
-    // Write output keywordlist with correct gcp (correction on heigth)
+    /////// Write output keywordlist with correct gcp (correction on heigth) ///////
     if (IsParameterEnabled("outkwl") && HasValue("outkwl"))
       {
 	WriteGeometry(outputKWL, GetParameterString("outkwl"));
diff --git a/json_schemas/schema_MultiSlc.json b/json_schemas/schema_MultiSlc.json
index 67d27d8a45306414419c4f22de3428fc5e2d881b..8138ec13041a7326e00f8e9083dbec9973d6fd5f 100644
--- a/json_schemas/schema_MultiSlc.json
+++ b/json_schemas/schema_MultiSlc.json
@@ -22,13 +22,14 @@
 				"End_Date", "Input_Path"],
 		    "additionalProperties": false,
 		    "properties": {"SRTM_Shapefile": {"type": "string"}, 
-				  "SRTM_Path": {"type": "string"},
-				  "Geoid": {"type": "string"},
-				  "Master_Image": {"type": "string"},
-				  "Start_Date": {"type": "string"},
-				  "End_Date": {"type": "string"},
-				  "Exclude": {"type": "string", "default": "-9999"},
-				  "Input_Path": {"type": "string"}}
+				   "SRTM_Path": {"type": "string"},
+				   "EOF_Path": {"type": "string"},
+				   "Geoid": {"type": "string"},
+				   "Master_Image": {"type": "string"},
+				   "Start_Date": {"type": "string"},
+				   "End_Date": {"type": "string"},
+				   "Exclude": {"type": "string", "default": "-9999"},
+				   "Input_Path": {"type": "string"}}
 		}, 
 		"out": 
 		{
diff --git a/json_schemas/schema_MultiSlc_IW.json b/json_schemas/schema_MultiSlc_IW.json
index cad9e7759b7f62cd1c2b401f685b4ec24a37b522..b74d7b7d03011fe24ffad14c2fde7f5187cc5513 100644
--- a/json_schemas/schema_MultiSlc_IW.json
+++ b/json_schemas/schema_MultiSlc_IW.json
@@ -21,13 +21,14 @@
 				"End_Date", "Input_Path"],
 		    "additionalProperties": false,
 		    "properties": {"SRTM_Shapefile": {"type": "string"}, 
-				  "SRTM_Path": {"type": "string"},
-				  "Geoid": {"type": "string"},
-				  "Master_Image": {"type": "string"},
-				  "Start_Date": {"type": "string"},
-				  "End_Date": {"type": "string"},
-				  "Exclude": {"type": "string", "default": "-9999"},
-				  "Input_Path": {"type": "string"}}
+				   "SRTM_Path": {"type": "string"},
+				   "Geoid": {"type": "string"},
+				   "EOF_Path": {"type": "string"},
+				   "Master_Image": {"type": "string"},
+				   "Start_Date": {"type": "string"},
+				   "End_Date": {"type": "string"},
+				   "Exclude": {"type": "string", "default": "-9999"},
+				   "Input_Path": {"type": "string"}}
 		}, 
 		"out": 
 		{
diff --git a/json_schemas/schema_S1IW.json b/json_schemas/schema_S1IW.json
index 137e8464d1ce473cb576edb57676936f2ac4f407..f8c9911633b55dd57fd265cb7f215c337b57ecab 100644
--- a/json_schemas/schema_S1IW.json
+++ b/json_schemas/schema_S1IW.json
@@ -21,7 +21,8 @@
 		    "additionalProperties": false,
 		    "properties": {"Master_Image_Path": {"type": "string"}, 
 				  "Slave_Image_Path": {"type": "string"},
-				  "DEM_Path": {"type": "string"}}
+				  "DEM_Path": {"type": "string"},
+				  "EOF_Path": {"type": "string"}}
 		}, 
 		"out": 
 		{
diff --git a/json_schemas/schema_S1SM.json b/json_schemas/schema_S1SM.json
index c18077fa860a20ad7c1ce91edd95c7ebec70575e..c69614c415fceb224b544bceb16f0b746a5cd17e 100644
--- a/json_schemas/schema_S1SM.json
+++ b/json_schemas/schema_S1SM.json
@@ -22,7 +22,8 @@
 		    "additionalProperties": false,
 		    "properties": {"Master_Image_Path": {"type": "string"}, 
 				  "Slave_Image_Path": {"type": "string"},
-				  "DEM_Path": {"type": "string"}}
+				  "DEM_Path": {"type": "string"},
+				  "EOF_Path": {"type": "string"}}
 		}, 
 		"out": 
 		{
diff --git a/python_src/SAR_MultiSlc.py b/python_src/SAR_MultiSlc.py
index e79d633f0d4c23b03e6620b08ad2d8db9e07b72e..a111fa0b0efe2ceedd114c636befd9034b7e76db 100644
--- a/python_src/SAR_MultiSlc.py
+++ b/python_src/SAR_MultiSlc.py
@@ -92,6 +92,10 @@ if __name__ == "__main__":
     hgts_path = dict_Global['in']['SRTM_Path']
     geoid_path = dict_Global['in']['Geoid']
 
+    eof_Path = None
+    if 'EOF_Path' in dict_Global['in']:
+        eof_Path = dict_Global['in']['EOF_Path']
+
     output_dir = dict_Global['out']['Output_Path']
 
     if not os.path.exists(output_dir):
@@ -234,6 +238,12 @@ if __name__ == "__main__":
     func_utils.check_ifExist(hgts_path)
     func_utils.check_ifExist(master_Image)
 
+    # Check eof path 
+    if eof_Path :
+        if not os.path.exists(eof_Path) :
+            func_utils.log(logging.CRITICAL, "Error, {path} does not exist. Check its path.".format(path=eof_Path))
+            quit()
+
     # ====== Check roi format (if roi)
     if roi :
         func_utils.check_roiFormat(roi)
@@ -408,6 +418,66 @@ if __name__ == "__main__":
 
             slave_Image = "HDF5:" + slave_Image + "://S01/SBI"
 
+        # Find eof files for each image if not cosmo
+        # Then, create the "fine" geom (with precise orbits) 
+        # Eventually, assign an extended filename if EOF file correspond to the image
+        if satellite != "cosmo" :
+            if eof_Path :
+                list_ofEOF = func_utils.get_AllFilesWithExt(eof_Path, ".EOF")
+
+
+                # master 
+                if counter <= 1 :
+                    start_master = dictKWLMaster['support_data.first_line_time']
+                    end_master = dictKWLMaster['support_data.last_line_time']
+
+                    # Get a eof file 
+                    eof_file = func_utils.select_EofWithDate(start_master, end_master, list_ofEOF)
+
+                    if (eof_file) :
+                        # Create the new geom file into dedicated repository
+                        extendedGeom_Path = os.path.join(master_data_dir, "extended_geom")
+                        if not os.path.exists(extendedGeom_Path):
+                            os.makedirs(extendedGeom_Path)
+
+                        # Call SARMetadataCorrection
+                        diapOTBApp.metadataCorrection(mode="orbits", insar=master_Image, indem=None, 
+                                                      infineorbits=os.path.join(eof_Path, eof_file),
+                                                      outPath=os.path.join(extendedGeom_Path, 
+                                                                           "extended_master.geom"))
+
+
+                        # Assign new geom file with extended filename
+                        master_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                                "extended_master.geom")
+
+
+                # slave 
+                dictKWLSlave = func_utils.getImageKWL(slave_Image)
+                start_slave = dictKWLSlave['support_data.first_line_time']
+                end_slave = dictKWLSlave['support_data.last_line_time']
+
+                # Get a eof file 
+                eof_file = func_utils.select_EofWithDate(start_slave, end_slave, list_ofEOF)
+
+                if (eof_file) :
+                    # Create the new geom file into dedicated repository
+                    extendedGeom_Path = os.path.join(output_dir, "extended_geom")
+                    if not os.path.exists(extendedGeom_Path):
+                        os.makedirs(extendedGeom_Path)
+
+                    # Call SARMetadataCorrection
+                    diapOTBApp.metadataCorrection(mode="orbits", insar=slave_Image, indem=None, 
+                                                  infineorbits=os.path.join(eof_Path, eof_file),
+                                                  outPath=os.path.join(extendedGeom_Path, 
+                                                                       "extended_slave.geom"))
+
+                    # Assign new geom file with extended filename
+                    slave_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                           "extended_slave.geom")
+
+
+
         func_utils.log(logging.INFO, "########### Input Images for the current execution ############## ")
         func_utils.log(logging.INFO, "Nb iteration : {param} with : ".format(param=counter))
         func_utils.log(logging.INFO, "master_Image : {param}".format(param=master_Image))
diff --git a/python_src/SAR_MultiSlc_IW.py b/python_src/SAR_MultiSlc_IW.py
index 03965645ef96069b1174219b180019ca66e4eeed..c5460fc3b040c32630cf53880351ed7167311c8c 100644
--- a/python_src/SAR_MultiSlc_IW.py
+++ b/python_src/SAR_MultiSlc_IW.py
@@ -95,6 +95,10 @@ if __name__ == "__main__":
     hgts_path = dict_Global['in']['SRTM_Path']
     geoid_path = dict_Global['in']['Geoid']
 
+    eof_Path = None
+    if 'EOF_Path' in dict_Global['in']:
+        eof_Path = dict_Global['in']['EOF_Path']
+
     output_dir = dict_Global['out']['Output_Path']
 
     if not os.path.exists(output_dir):
@@ -225,6 +229,12 @@ if __name__ == "__main__":
     func_utils.check_ifExist(hgts_path)
     func_utils.check_ifExist(master_Image)
     
+    # Check eof path 
+    if eof_Path :
+        if not os.path.exists(eof_Path) :
+            func_utils.log(logging.CRITICAL, "Error, {path} does not exist. Check its path.".format(path=eof_Path))
+            quit()
+
     # ====== Check roi format (if roi)
     if roi :
         func_utils.check_roiFormat(roi)
@@ -325,6 +335,72 @@ if __name__ == "__main__":
             os.makedirs(master_data_dir)
 
 
+        # ==============================================
+        # Retrieving informations about master and slave
+        # ==============================================    
+        dictKWLMaster = func_utils.getImageKWL(master_Image)
+        dictKWLSlave = func_utils.getImageKWL(slave_Image)
+
+
+        # Find eof files for each image if not cosmo
+        # Then, create the "fine" geom (with precise orbits) 
+        # Eventually, assign an extended filename if EOF file correspond to the image
+        if eof_Path :
+            list_ofEOF = func_utils.get_AllFilesWithExt(eof_Path, ".EOF")
+
+
+            # master 
+            if counter <= 1 :
+                start_master = dictKWLMaster['support_data.first_line_time']
+                end_master = dictKWLMaster['support_data.last_line_time']
+
+                # Get a eof file 
+                eof_file = func_utils.select_EofWithDate(start_master, end_master, list_ofEOF)
+
+                if (eof_file) :
+                    # Create the new geom file into dedicated repository
+                    extendedGeom_Path = os.path.join(master_data_dir, "extended_geom")
+                    if not os.path.exists(extendedGeom_Path):
+                        os.makedirs(extendedGeom_Path)
+
+                    # Call SARMetadataCorrection
+                    diapOTBApp.metadataCorrection(mode="orbits", insar=master_Image, indem=None, 
+                                                  infineorbits=os.path.join(eof_Path, eof_file),
+                                                  outPath=os.path.join(extendedGeom_Path, 
+                                                                       "extended_master.geom"))
+
+
+                    # Assign new geom file with extended filename
+                    master_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                            "extended_master.geom")
+
+
+            # slave 
+            start_slave = dictKWLSlave['support_data.first_line_time']
+            end_slave = dictKWLSlave['support_data.last_line_time']
+
+            # Get a eof file 
+            eof_file = func_utils.select_EofWithDate(start_slave, end_slave, list_ofEOF)
+
+            if (eof_file) :
+                # Create the new geom file into dedicated repository
+                extendedGeom_Path = os.path.join(output_dir, "extended_geom")
+                if not os.path.exists(extendedGeom_Path):
+                    os.makedirs(extendedGeom_Path)
+
+                # Call SARMetadataCorrection
+                diapOTBApp.metadataCorrection(mode="orbits", insar=slave_Image, indem=None, 
+                                              infineorbits=os.path.join(eof_Path, eof_file),
+                                              outPath=os.path.join(extendedGeom_Path, 
+                                                                   "extended_slave.geom"))
+
+                # Assign new geom file with extended filename
+                slave_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                       "extended_slave.geom")
+
+
+
+
         func_utils.log(logging.INFO, "########### Input Images for the current execution ############## ")
         func_utils.log(logging.INFO, "Nb iteration : {param} with : ".format(param=counter))
         func_utils.log(logging.INFO, "master_Image : {param}".format(param=master_Image))
@@ -334,12 +410,6 @@ if __name__ == "__main__":
         func_utils.printOnStd("\n master_Image : {param} : \n".format(param=master_Image))
         func_utils.printOnStd("\n slave_Image : {param} : \n".format(param=slave_Image))
 
-        # ==============================================
-        # Retrieving informations about master and slave
-        # ==============================================    
-        dictKWLMaster = func_utils.getImageKWL(master_Image)
-        dictKWLSlave = func_utils.getImageKWL(slave_Image)
-
 
         # ===== Check header version
         if int(dictKWLMaster['header.version']) < 3 or int(dictKWLSlave['header.version']) < 3 :
diff --git a/python_src/diapOTB.py b/python_src/diapOTB.py
index cb207b18fe9d43cb670f6883f3049ec0c09f17b2..b97e8c36b87b0a27c0a2e3376274141a70861a69 100644
--- a/python_src/diapOTB.py
+++ b/python_src/diapOTB.py
@@ -47,6 +47,7 @@ from processings import DInSar
 from processings import Metadata_Correction
 from processings import Post_Processing
 
+import utils.DiapOTB_applications as diapOTBApp
 from utils import func_utils
 
 # Main
@@ -75,8 +76,12 @@ if __name__ == "__main__":
     master_Image = dict_Global['in']['Master_Image_Path']
     slave_Image =  dict_Global['in']['Slave_Image_Path']
     dem =  dict_Global['in']['DEM_Path']
-    output_dir = dict_Global['out']['output_dir']
+    eof_Path = None
+    if 'EOF_Path' in dict_Global['in']:
+        eof_Path = dict_Global['in']['EOF_Path']
 
+    output_dir = dict_Global['out']['output_dir']
+   
     satellite = "default"
     mode = "default"
 
@@ -162,6 +167,13 @@ if __name__ == "__main__":
         print("The output directory exists. Some files can be overwritten")
 
 
+    # Check eof path 
+    if eof_Path :
+        if not os.path.exists(eof_Path) :
+            func_utils.log(logging.CRITICAL, "Error, {path} does not exist. Check its path.".format(path=eof_Path))
+            quit()
+
+
     # Init file handler (all normaly print on std is redirected into info.log) 
     # To use previous print on std, use printOnStd
     func_utils.init_fileLog(output_dir) 
@@ -296,6 +308,67 @@ if __name__ == "__main__":
     func_utils.printOnStd("\n Beginning of DiapOTB processing (S1 SM or Cosmo mode) \n")
     func_utils.log(logging.INFO, "############ Beginning of DiapOTB processing (S1 SM or Cosmo mode) ##############")
 
+
+    # Find eof files for each image if not cosmo
+    # Then, create the "fine" geom (with precise orbits) 
+    # Eventually, assign an extended filename if EOF file correspond to the image
+    if satellite != "cosmo" :
+        if eof_Path :
+            list_ofEOF = func_utils.get_AllFilesWithExt(eof_Path, ".EOF")
+            
+
+            # master 
+            start_master = dictKWLMaster['support_data.first_line_time']
+            end_master = dictKWLMaster['support_data.last_line_time']
+
+            # Get a eof file 
+            eof_file = func_utils.select_EofWithDate(start_master, end_master, list_ofEOF)
+           
+            if (eof_file) :
+                # Create the new geom file into dedicated repository
+                extendedGeom_Path = os.path.join(output_dir, "extended_geom")
+                if not os.path.exists(extendedGeom_Path):
+                    os.makedirs(extendedGeom_Path)
+
+                # Call SARMetadataCorrection
+                diapOTBApp.metadataCorrection(mode="orbits", insar=master_Image, indem=None, 
+                                              infineorbits=os.path.join(eof_Path, eof_file),
+                                              outPath=os.path.join(extendedGeom_Path, 
+                                                                   "extended_master.geom"))
+
+
+                # Assign new geom file with extended filename
+                master_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                        "extended_master.geom")
+
+
+            # slave 
+            dictKWLSlave = func_utils.getImageKWL(slave_Image)
+            start_slave = dictKWLSlave['support_data.first_line_time']
+            end_slave = dictKWLSlave['support_data.last_line_time']
+            
+            # Get a eof file 
+            eof_file = func_utils.select_EofWithDate(start_slave, end_slave, list_ofEOF)
+            
+            if (eof_file) :
+                # Create the new geom file into dedicated repository
+                extendedGeom_Path = os.path.join(output_dir, "extended_geom")
+                if not os.path.exists(extendedGeom_Path):
+                    os.makedirs(extendedGeom_Path)
+
+                # Call SARMetadataCorrection
+                diapOTBApp.metadataCorrection(mode="orbits", insar=slave_Image, indem=None, 
+                                              infineorbits=os.path.join(eof_Path, eof_file),
+                                              outPath=os.path.join(extendedGeom_Path, 
+                                                                   "extended_slave.geom"))
+
+                # Assign new geom file with extended filename
+                slave_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                       "extended_slave.geom")
+
+            
+            
+
     ####################### Pre Processing Chain ##########################
     # Master
     func_utils.printOnStd("\n Master Pre_Processing chain \n")
diff --git a/python_src/diapOTB_S1IW.py b/python_src/diapOTB_S1IW.py
index 29655d8413b84b8337afa8f25423bcef95db5d9d..b77c1b454681d6bee1cabfd64ced4680bd1d2965 100644
--- a/python_src/diapOTB_S1IW.py
+++ b/python_src/diapOTB_S1IW.py
@@ -46,6 +46,7 @@ from processings import Ground
 from processings import DInSar
 from processings import Post_Processing
 
+import utils.DiapOTB_applications as diapOTBApp
 from utils import func_utils
 
 # Main
@@ -74,6 +75,10 @@ if __name__ == "__main__":
     master_Image = dict_Global['in']['Master_Image_Path']
     slave_Image =  dict_Global['in']['Slave_Image_Path']
     dem =  dict_Global['in']['DEM_Path']
+    eof_Path = None
+    if 'EOF_Path' in dict_Global['in']:
+        eof_Path = dict_Global['in']['EOF_Path']
+
     output_dir = dict_Global['out']['output_dir']
     
     # Pre_Processing
@@ -150,6 +155,12 @@ if __name__ == "__main__":
     else :
         print("The output directory exists. Some files can be overwritten")
 
+    # Check eof path 
+    if eof_Path :
+        if not os.path.exists(eof_Path) :
+            func_utils.log(logging.CRITICAL, "Error, {path} does not exist. Check its path.".format(path=eof_Path))
+            quit()
+        
     
     # Init file handler (all normaly print on std is redirected into info.log) 
     # To use previous print on std, use printOnStd
@@ -257,6 +268,65 @@ if __name__ == "__main__":
 
     func_utils.printOnStd("\n Beginning of DiapOTB processing (S1 IW mode) \n")
     func_utils.log(logging.INFO, "############ Beginning of DiapOTB processing (S1 IW mode) ##############")
+
+    # Find eof files for each image if not cosmo
+    # Then, create the "fine" geom (with precise orbits) 
+    # Eventually, assign an extended filename if EOF file correspond to the image
+    if eof_Path :
+        list_ofEOF = func_utils.get_AllFilesWithExt(eof_Path, ".EOF")
+
+
+        # master 
+        start_master = dictKWLMaster['support_data.first_line_time']
+        end_master = dictKWLMaster['support_data.last_line_time']
+
+        # Get a eof file 
+        eof_file = func_utils.select_EofWithDate(start_master, end_master, list_ofEOF)
+
+        if (eof_file) :
+            # Create the new geom file into dedicated repository
+            extendedGeom_Path = os.path.join(output_dir, "extended_geom")
+            if not os.path.exists(extendedGeom_Path):
+                os.makedirs(extendedGeom_Path)
+
+            # Call SARMetadataCorrection
+            diapOTBApp.metadataCorrection(mode="orbits", insar=master_Image, indem=None, 
+                                          infineorbits=os.path.join(eof_Path, eof_file),
+                                          outPath=os.path.join(extendedGeom_Path, 
+                                                               "extended_master.geom"))
+
+
+            # Assign new geom file with extended filename
+            master_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                    "extended_master.geom")
+
+
+        # slave 
+        dictKWLSlave = func_utils.getImageKWL(slave_Image)
+        start_slave = dictKWLSlave['support_data.first_line_time']
+        end_slave = dictKWLSlave['support_data.last_line_time']
+
+        # Get a eof file 
+        eof_file = func_utils.select_EofWithDate(start_slave, end_slave, list_ofEOF)
+
+        if (eof_file) :
+            # Create the new geom file into dedicated repository
+            extendedGeom_Path = os.path.join(output_dir, "extended_geom")
+            if not os.path.exists(extendedGeom_Path):
+                os.makedirs(extendedGeom_Path)
+
+            # Call SARMetadataCorrection
+            diapOTBApp.metadataCorrection(mode="orbits", insar=slave_Image, indem=None, 
+                                          infineorbits=os.path.join(eof_Path, eof_file),
+                                          outPath=os.path.join(extendedGeom_Path, 
+                                                               "extended_slave.geom"))
+
+            # Assign new geom file with extended filename
+            slave_Image += "?geom=" + os.path.join(extendedGeom_Path, 
+                                                   "extended_slave.geom")
+
+            
+
                         
     ####################### Pre Processing Chain ##########################
     # Master
diff --git a/python_src/utils/DiapOTB_applications.py b/python_src/utils/DiapOTB_applications.py
index 1cb94c504032511eafe7f569aaf8138a8ca0f9b5..ae7ab0c6400fe933dc1d028b2eb7f649b848c2a7 100644
--- a/python_src/utils/DiapOTB_applications.py
+++ b/python_src/utils/DiapOTB_applications.py
@@ -654,6 +654,52 @@ def topographicPhase(ingrid, insarslave, incartmeanmaster, gridsteprange, gridst
     appTopoPhase.ExecuteAndWriteOutput()
 
 
+def metadataCorrection(mode, insar, indem, infineorbits,
+                       outPath, ram="4000"):
+    """
+        Launch SARMetadataCorrection application (from DiapOTB).
+
+        This application correct some metadata such as gcp or orbit states. 
+        Two kinds of uses are possible according to the input mode : 
+        _ GCPs correction thanks to input DEM
+        _ Fine orbits correction (with input EOF file)
+    
+    
+        :param mode: String to indicate selected mode (gcp or orbits).     
+        :param insar: Input SAR image.
+        :param indem: Input DEM to extract height data.
+        :param infineorbits: Input file to get precise orbits.
+        :param outPath: Output geom file.
+    
+        :type mode: string
+        :type insar: string
+        :type idem: string
+        :type infineorbits: string
+        :type outPath: string
+
+        :return: None
+    """
+    appMetatadataCorrection = otb.Registry.CreateApplication("SARMetadataCorrection")
+
+    # Check mode (must be gcp or orbits)
+    if mode != "gcp" and mode != "orbits" :
+        print("Wrong selected modes for SARMetadataCorrection application")
+        return 1
+
+    
+    appMetatadataCorrection.SetParameterString("mode", mode) # Check if really string
+    appMetatadataCorrection.SetParameterString("insar", insar)
+    
+    if mode == "gcp" :
+        appMetatadataCorrection.SetParameterString("indem", indem)
+    else :
+        appMetatadataCorrection.SetParameterString("infineorbits", infineorbits)
+
+    appMetatadataCorrection.SetParameterString("outkwl", outPath)
+    appMetatadataCorrection.SetParameterString("ram", ram)
+    appMetatadataCorrection.ExecuteAndWriteOutput()
+
+
 def phaseFiltering(withComplex, inForFiltering, mlran, mlazi, step, sizetiles, alpha, 
                    outPath, ram="4000"):
     """
diff --git a/python_src/utils/func_utils.py b/python_src/utils/func_utils.py
index fa6d0e6e2237d9c34fd824300418d584f33ee939..c42e55272835ebb9a378ff36c9745ae2543806af 100644
--- a/python_src/utils/func_utils.py
+++ b/python_src/utils/func_utils.py
@@ -39,6 +39,7 @@ import argparse
 import re
 import xml.etree.ElementTree as ET
 import datetime
+import time
 import gdal
 import ogr
 
@@ -201,7 +202,7 @@ def getImageKWL(Img):
     keyword = ReadImageInfo.GetParameterString("keyword")
     keywordlist = ReadImageInfo.GetParameterString("keyword").split("\n")
     keywordlist = filter(None, keywordlist)
-    dictKWL = { i.split(':')[0] : re.sub(r"[\n\t\s]*", "", i.split(':')[1]) for i in keywordlist }
+    dictKWL = { i.split(':')[0] : re.sub(r"[\n\t\s]*", "", "".join(i.split(':')[1:])) for i in keywordlist }
     
     return dictKWL
 
@@ -354,6 +355,42 @@ def get_Tiff_WithDates(start, end, exclude, TiffList, ext=""):
                 date_list.append(i)
     return date_list
 
+def select_EofWithDate(start, end, eofList) :
+    """
+        Select into the input list, the file that correspond to dates
+    """
+    time_start = time.mktime(time.strptime(start,
+                                          "%Y-%m-%dT%H%M%S.%f"))
+
+    time_end = time.mktime(time.strptime(end,
+                                        "%Y-%m-%dT%H%M%S.%f"))
+    
+
+    for i_eof in eofList:
+        # Without extension
+        i_eof = i_eof.split(".EOF")[0]
+
+        start_eofDate = i_eof.split('_')[-2]
+        start_eofDate = start_eofDate.split("V")[1]
+        end_eofDate = i_eof.split('_')[-1] 
+
+        # Save date format
+        time_start_eofDate = time.mktime(time.strptime(start_eofDate,
+                                                       "%Y%m%dT%H%M%S"))
+
+        time_end_eofDate = time.mktime(time.strptime(end_eofDate,
+                                                     "%Y%m%dT%H%M%S"))
+    
+
+        # Compare dates and return eof file if eof file contains the current image dates
+        if time_start >= time_start_eofDate and time_end <= time_end_eofDate :
+            return i_eof + ".EOF"
+
+        
+    # if none of files contains wanted dates : return None
+    return None
+        
+
 def get_relative_orbit(manifest):
     """
         Get from manifest file, the orbit number
diff --git a/python_src/utils/getEOFFromESA.py b/python_src/utils/getEOFFromESA.py
new file mode 100644
index 0000000000000000000000000000000000000000..4bd436e3cc8f489071e4749ebb143f4991e01595
--- /dev/null
+++ b/python_src/utils/getEOFFromESA.py
@@ -0,0 +1,266 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import re
+import os
+import time
+import requests
+import shutil
+import argparse
+import datetime
+import xml.etree.ElementTree
+
+def searchForSafe(input_dir) :
+    """
+    Search for Safe repository into input_dir
+
+    :input_dir: (str) input directory
+    :returns: (iterable) list of SAFE repository
+    """ 
+    list_SAFE = []
+    for root, dirs, files in os.walk(input_dir):
+        for i in (i for i in dirs): 
+            if i.endswith(".SAFE"):
+                list_SAFE.append(i)
+    
+    return list_SAFE
+
+# Get url for orbits files
+def get_url_orbs(orbs_type, sensor, year, month, day, 
+                 url="https://aux.sentinel1.eo.esa.int/",
+                 orb_list=None):
+    """
+    Get the set of available orbs from url
+
+    :orbs_type: (str) either POEROB or RESORB
+    :sensor: (str) seither S1A or S1B
+    :year: (str) year
+    :month: (str|int) month (as a 2 digit number)
+    :day: (str) day as a two digit number in the month
+    :url: (str) url where to gather the data
+    :returns: (iterable) list of urls of the EOF files
+    """
+    url = url.strip('/')
+    month = "{:02d}".format(int(month))
+    day = "{:02d}".format(int(day))
+    
+    # Pattern to find EOF file into response
+    pattern = "".join(['"', sensor, '_.*?_', orbs_type, '_.*?.EOF"'])
+
+    html_list = []
+    orb_list_tmp = []
+
+    tacquisition0 = datetime.datetime(int(year), int(month), int(day))
+    
+    list_of_days_tosearch = []
+    # Fetch POEORB if orb_type is POEORB or None (ie, first try with Precises orbits)
+    # This kind of orbit is restitued around 21 days later
+    if orbs_type == 'POEORB' or orbs_type is None:
+        list_of_days_tosearch = [21, 20, 22, 19, 23]
+    # Fetch RESORB if orbs_type is RESORB 
+    # This kind of orbit is restitued around 3 hours later (day before to day after safe name)
+    if orbs_type == "RESORB":
+        list_of_days_tosearch = [0, 1, 2]
+
+    if url.startswith("https"):
+        for day in list_of_days_tosearch :
+            
+            tacquisition = tacquisition0 + datetime.timedelta(days=day)
+
+            # Build the url wtih "ESA format"
+            url_orb = "{}/{}/{}/{}/{}/".format(url, orbs_type, tacquisition.year, 
+                                               "{:02d}".format(tacquisition.month), 
+                                               "{:02d}".format(tacquisition.day))
+
+        
+            try:
+                # Make the get request with verify = False to avoid ssl issues
+                response = requests.get(url_orb, verify=False)
+                
+                if response.status_code != 200 and response.status_code != 201: 
+                    print("problem with the url {} ".format(url_orb))
+                    continue
+
+                orb_list_tmp += list(set([url_orb + "/" + x.strip().strip('"').strip()
+                                     for x in re.findall(pattern, response.text)]))
+                    
+
+            except Exception as e:
+                print("exception for url {} ".format(e))
+                return []
+
+    else:
+        raise RuntimeError("malformed url or too recent date, should start by https://")   
+
+        
+    # Add result into orb_list or return orb_list_tmp
+    orb_list += orb_list_tmp
+    
+
+
+# Get contents of orbit files on disk
+def get_orb_content_ondisk(orb_list, output_dir) :
+    """
+    Retrieve on disk the set of selected orbs
+
+    :orb_list: (list) list or url (to get orbit files)
+    :output_dir: (str) output directory (on disk) to put orbit files
+    :returns: () 
+    """
+    for orb in orb_list:
+        try:
+            # Get the content of eof_file
+            response = requests.get(orb, verify=False, stream=True)
+
+            if response.status_code != 200 and response.status_code != 201: 
+                print("problem with the url {} ".format(orb))
+                continue
+
+            # Copy the content on disk
+            with open(os.path.join(output_dir, os.path.basename(orb)), 'wb') as out_file:
+                shutil.copyfileobj(response.raw, out_file)
+
+            del response
+        except Exception as e:
+            print("exception for url {} ".format(e))
+
+
+###################
+###### Main #######
+###################
+if __name__ == "__main__":
+    
+    ###### Get the main argument : indir and outdir ######
+    # Check arguments
+    parser = argparse.ArgumentParser()
+    parser.add_argument("indir", help="input directory to search SAFE repository")
+    parser.add_argument("outdir", help="output directory to store EOF files")
+    parser.add_argument("--type", "-t", type=str, choices=['POEORB', 'RESORB'],
+                        default='POEORB',
+                        help=("The type of data request. If set should be either POEORB or RESORB; "
+                              "if not set test first POEORB and backoff to RESORB else"))
+    args = parser.parse_args()
+
+    # Check input and output directory (if exist)
+    if not os.path.exists(args.indir):
+        print(args.indir + " does not exists")
+        quit()
+
+    if not os.path.exists(args.outdir):
+        print(args.outdir + " does not exists")
+        quit()
+
+    # Require a check of user for connexion parameters (proxy, ...)
+    response = input("Check all your parameters for internet connexion (proxy, ssl ...), before continuing. \
+    \nReady to continue (yes/no) :")
+
+    if response != "yes" :
+        print("Set all your parameters for internet connexion to relaunch this script")
+        quit()
+
+    list_InSAFE = searchForSafe(args.indir)
+
+    if len(list_InSAFE) == 0 :
+        print("None SAFE repository was found into {}".format(args.indir))
+        quit()
+
+        
+    # For each SAFE found, retrieve URLs of EOF files (with date correspondance)
+    orb_list = []
+
+    for safeDir in list_InSAFE:
+        
+        # Tmp lists
+        orb_list_firstSelect = []
+        orb_list_secondSelect = []
+
+        # patterns for SAFE names
+        pattern_date = "".join(['\d{8}', "T", '\d{6}'])
+        pattern_sensor = "".join(["S1."])
+        pattern_orbit = "".join(["_", '\d{6}', "_"])
+        dates = ""
+        sensor = ""
+        orbit_number = ""
+
+        try :
+            dates = re.findall(pattern_date, safeDir)
+            sensor = re.findall(pattern_sensor, safeDir)
+            orbit_number = int(re.findall(pattern_orbit, safeDir)[0][1:-1])
+        except Exception as e:
+            print("Safe name does not match with usual pattern and causes an exception : \
+            {}".format(e))
+            # Next safe
+            continue
+
+        if len(dates) == 2 and len(sensor) == 1 :
+            # First selection for S1A and S1B sensor at corresponding dates
+            get_url_orbs(args.type, sensor[0], dates[0][0:4], dates[0][4:6], 
+                         dates[0][6:8], orb_list=orb_list_firstSelect)
+            
+
+            # Second selection with times
+            time_start = time.mktime(time.strptime(dates[0],
+                                                   "%Y%m%dT%H%M%S"))
+
+            time_end = time.mktime(time.strptime(dates[1],
+                                                 "%Y%m%dT%H%M%S"))
+            
+            for orb in orb_list_firstSelect:
+                eof_file = orb.split('/')[-1]
+                
+                # Without extension
+                i_eof = eof_file.split(".EOF")[0]
+
+                start_eofDate = i_eof.split('_')[-2]
+                start_eofDate = start_eofDate.split("V")[1]
+                end_eofDate = i_eof.split('_')[-1] 
+                
+                # Save date format
+                time_start_eofDate = time.mktime(time.strptime(start_eofDate,
+                                                               "%Y%m%dT%H%M%S"))
+
+                time_end_eofDate = time.mktime(time.strptime(end_eofDate,
+                                                             "%Y%m%dT%H%M%S"))
+
+                # Compare dates and return eof file if eof file contains the current image dates
+                if time_end > time_start_eofDate and time_start <= time_end_eofDate :
+                    orb_list_secondSelect.append(orb)
+                    
+
+            # Last selection/check with orbit (Keep ????)
+            for orb in orb_list_secondSelect:
+                try:
+                    # Make the get request with verify = False to avoid ssl issues
+                    response = requests.get(orb, verify=False)
+                                        
+                    if response.status_code != 200 and response.status_code != 201: 
+                        print("problem with the url {} ".format(url_orb))
+                        continue
+
+                    tree = xml.etree.ElementTree.fromstring(response.text)
+                    
+                    Absolute_Orbit_Elt = tree.findall("Data_Block/List_of_OSVs/OSV/Absolute_Orbit")
+
+                    orbitNumbers = list(set([int(x.text)
+                                             for x in Absolute_Orbit_Elt]))
+
+                    if (orbit_number in orbitNumbers) :
+                        orb_list.append(orb)
+                    
+
+                except Exception as e:
+                    print("Exception {}".format(e))
+                    quit()
+
+        else :
+            print("Wrong SAFE format for  {}".format(args.indir))
+            # Next Safe
+            continue
+        
+
+    print("Selected orbit files (Ready to be retrieved on disk) : ")
+    print(orb_list)
+    
+    # Get selection into output_dir
+    get_orb_content_ondisk(orb_list, args.outdir)
+