From a9b4ab417548659505993da2a857b19fa662ef3d Mon Sep 17 00:00:00 2001
From: Julien Osman <julien.osman@csgroup.eu>
Date: Thu, 9 Jul 2020 10:33:01 +0200
Subject: [PATCH] ENH: Read Noise and Calibration LUTS

---
 ...TvImageMetadataInterfaceTest_Sentinel1.txt |  1 +
 .../Metadata/include/otbGeometryMetadata.h    | 20 +++--
 .../otbSentinel1ImageMetadataInterface.h      |  3 +
 .../otbSentinel1ImageMetadataInterface.cxx    | 78 ++++++++++++++++---
 4 files changed, 84 insertions(+), 18 deletions(-)

diff --git a/Data/Baseline/OTB/Files/ioTvImageMetadataInterfaceTest_Sentinel1.txt b/Data/Baseline/OTB/Files/ioTvImageMetadataInterfaceTest_Sentinel1.txt
index 21ee9e581e..3e8156b2b7 100644
--- a/Data/Baseline/OTB/Files/ioTvImageMetadataInterfaceTest_Sentinel1.txt
+++ b/Data/Baseline/OTB/Files/ioTvImageMetadataInterfaceTest_Sentinel1.txt
@@ -13,6 +13,7 @@ DataType 11
 OrbitNumber 6447
 LineSpacing 4.08568
 PixelSpacing 3.19483
+AcquisitionDate 2015-06-19T19:50:43.223221Z
 ProductionDate 2015-06-20T01:51:06.838854Z
 AcquisitionStartTime 2015-06-19T19:50:43.223221Z
 AcquisitionStopTime 2015-06-19T19:51:01.921994Z
diff --git a/Modules/Core/Metadata/include/otbGeometryMetadata.h b/Modules/Core/Metadata/include/otbGeometryMetadata.h
index ec00f42fbc..bd69ba3e98 100644
--- a/Modules/Core/Metadata/include/otbGeometryMetadata.h
+++ b/Modules/Core/Metadata/include/otbGeometryMetadata.h
@@ -81,13 +81,12 @@ struct OTBMetadata_EXPORT OTB_azimuthFmRate
 
 struct OTBMetadata_EXPORT OTB_calibrationVector
 {
-  MetaData::Time azimuthTime;
   int line;
-  std::vector<int> pixel;
-  std::vector<double> sigmaNought;
-  std::vector<double> betaNought;
-  std::vector<double> gamma;
-  std::vector<double> dn;
+  MetaData::Time azimuthTime;
+  MetaData::LUT1D sigmaNought;
+  MetaData::LUT1D betaNought;
+  MetaData::LUT1D gamma;
+  MetaData::LUT1D dn;
 };
 
 struct OTBMetadata_EXPORT OTB_dopplerCentroid
@@ -98,6 +97,13 @@ struct OTBMetadata_EXPORT OTB_dopplerCentroid
   double slantRangeTime;
 };
 
+struct OTBMetadata_EXPORT OTB_SARNoise
+{
+  int line;
+  MetaData::Time azimuthTime;
+  MetaData::LUT1D noiseLut;
+};
+
 namespace Projection
 {
 
@@ -204,6 +210,8 @@ struct OTBMetadata_EXPORT SARParam
   MetaData::Time stopTime;
 
   std::vector<OTB_dopplerCentroid> dopplerCentroid;
+
+  std::vector<OTB_SARNoise> noiseVector;
 };
 
 } // end namespace Projection
diff --git a/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h b/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
index ff9b70ce1b..74a2740ce5 100644
--- a/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
+++ b/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
@@ -97,6 +97,9 @@ public:
 
   std::vector<OTB_calibrationVector> GetCalibrationVector(XMLMetadataSupplier) const;
 
+  /* fetch the noise LUTs */
+  std::vector<OTB_SARNoise> GetNoiseVector(XMLMetadataSupplier) const;
+
   void Parse(const MetadataSupplierInterface *) override;
 
 protected:
diff --git a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
index 3863cc35b0..f43fe7ea3c 100644
--- a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
+++ b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
@@ -382,24 +382,70 @@ std::vector<OTB_calibrationVector> Sentinel1ImageMetadataInterface::GetCalibrati
     oss.str("");
     oss << listId;
     std::string path_root = "calibration.calibrationVectorList.calibrationVector_" + oss.str();
+
     OTB_calibrationVector calVect;
     std::istringstream(xmlMS.GetAs<std::string>(path_root + ".azimuthTime")) >> calVect.azimuthTime;
     calVect.line = xmlMS.GetAs<int>((path_root + ".line").c_str());
-    calVect.pixel = xmlMS.GetAsVector<int>((path_root + ".pixel").c_str(),
-    		' ', xmlMS.GetAs<int>((path_root + ".pixel.count").c_str()));
-    calVect.sigmaNought = xmlMS.GetAsVector<double>((path_root + ".sigmaNought").c_str(),
-    		' ', xmlMS.GetAs<int>((path_root + ".sigmaNought.count").c_str()));
-    calVect.betaNought = xmlMS.GetAsVector<double>((path_root + ".betaNought").c_str(),
-    		' ', xmlMS.GetAs<int>((path_root + ".betaNought.count").c_str()));
-    calVect.gamma = xmlMS.GetAsVector<double>((path_root + ".gamma").c_str(),
-    		' ', xmlMS.GetAs<int>((path_root + ".gamma.count").c_str()));
-    calVect.dn = xmlMS.GetAsVector<double>((path_root + ".dn").c_str(),
-    		' ', xmlMS.GetAs<int>((path_root + ".dn.count").c_str()));
+
+    // Same axe for all LUTs
+    MetaData::LUTAxis ax1;
+    ax1.Size = xmlMS.GetAs<int>((path_root + ".pixel.count").c_str());
+    ax1.Values = xmlMS.GetAsVector<double>((path_root + ".pixel").c_str(), ' ', ax1.Size);
+
+    MetaData::LUT1D sigmaNoughtLut;
+    sigmaNoughtLut.Axis[0] = ax1;
+    sigmaNoughtLut.Array = xmlMS.GetAsVector<double>((path_root + ".sigmaNought").c_str(),
+     		' ', xmlMS.GetAs<int>((path_root + ".sigmaNought.count").c_str()));
+    calVect.sigmaNought = sigmaNoughtLut;
+
+    MetaData::LUT1D betaNoughtLut;
+    betaNoughtLut.Axis[0] = ax1;
+    betaNoughtLut.Array = xmlMS.GetAsVector<double>((path_root + ".betaNought").c_str(),
+     		' ', xmlMS.GetAs<int>((path_root + ".betaNought.count").c_str()));
+    calVect.betaNought = betaNoughtLut;
+
+    MetaData::LUT1D gammaLut;
+    gammaLut.Axis[0] = ax1;
+    gammaLut.Array = xmlMS.GetAsVector<double>((path_root + ".gamma").c_str(),
+     		' ', xmlMS.GetAs<int>((path_root + ".gamma.count").c_str()));
+    calVect.gamma = gammaLut;
+
+    MetaData::LUT1D dnLut;
+    dnLut.Axis[0] = ax1;
+    dnLut.Array = xmlMS.GetAsVector<double>((path_root + ".dn").c_str(),
+     		' ', xmlMS.GetAs<int>((path_root + ".dn.count").c_str()));
+    calVect.dn = dnLut;
+
     calibrationVector.push_back(calVect);
   }
   return calibrationVector;
 }
 
+std::vector<OTB_SARNoise> Sentinel1ImageMetadataInterface::GetNoiseVector(XMLMetadataSupplier xmlMS) const
+{
+  std::vector<OTB_SARNoise> noiseVector;
+  int listCount = xmlMS.GetAs<double>("noise.noiseVectorList.count");
+  std::ostringstream oss;
+  for (int listId = 1 ; listId <= listCount ; ++listId)
+  {
+    oss.str("");
+    oss << listId;
+    std::string path_root = "noise.noiseVectorList.noiseVector_" + oss.str();
+    OTB_SARNoise noiseVect;
+    std::istringstream(xmlMS.GetAs<std::string>(path_root + ".azimuthTime")) >> noiseVect.azimuthTime;
+    MetaData::LUT1D noiseLut;
+    MetaData::LUTAxis ax1;
+    ax1.Size = xmlMS.GetAs<int>((path_root + ".pixel.count").c_str());
+    ax1.Values = xmlMS.GetAsVector<double>((path_root + ".pixel").c_str(), ' ', ax1.Size);
+    noiseLut.Axis[0] = ax1;
+    noiseLut.Array = xmlMS.GetAsVector<double>((path_root + ".noiseLut").c_str(),
+    		' ', xmlMS.GetAs<int>((path_root + ".noiseLut.count").c_str()));
+    noiseVect.noiseLut = noiseLut;
+    noiseVector.push_back(noiseVect);
+  }
+  return noiseVector;
+}
+
 void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface *mds)
 {
   assert(mds);
@@ -427,8 +473,9 @@ void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface *mds
   {
     XMLMetadataSupplier ManifestMS = XMLMetadataSupplier(ManifestFilePath);
     m_Imd.Add(MDTime::ProductionDate,
-    		ManifestMS.GetFirstAs<MetaData::Time>(
-    				"xfdu:XFDU.metadataSection.metadataObject_#.metadataWrap.xmlData.safe:processing.start"));
+    		ManifestMS.GetFirstAs<MetaData::Time>("xfdu:XFDU.metadataSection.metadataObject_#.metadataWrap.xmlData.safe:processing.start"));
+    m_Imd.Add(MDTime::AcquisitionDate,
+    		ManifestMS.GetFirstAs<MetaData::Time>("xfdu:XFDU.metadataSection.metadataObject_#.metadataWrap.xmlData.safe:acquisitionPeriod.safe:startTime"));
   }
 
   // Band metadata
@@ -457,6 +504,13 @@ void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface *mds
       sarParam.calibrationVectors = this->GetCalibrationVector(CalibrationMS);
       std::istringstream(CalibrationMS.GetAs<std::string>("calibration.adsHeader.startTime")) >> sarParam.startTime;
       std::istringstream(CalibrationMS.GetAs<std::string>("calibration.adsHeader.stopTime")) >> sarParam.stopTime;
+
+      // Noise file
+      std::string NoiseFilePath = itksys::SystemTools::GetFilenamePath(AnnotationFilePath)
+                                              + "/calibration/noise-"
+                                              + itksys::SystemTools::GetFilenameName(AnnotationFilePath);
+      XMLMetadataSupplier NoiseMS = XMLMetadataSupplier(NoiseFilePath);
+      sarParam.noiseVector = this->GetNoiseVector(NoiseMS);
     }
     m_Imd.Bands[bandId].Add(MDGeom::SAR, sarParam);
   }
-- 
GitLab