diff --git a/Modules/Core/Metadata/include/otbImageMetadata.h b/Modules/Core/Metadata/include/otbImageMetadata.h
index e951bab05ea154f68898367efd78843058f3d57d..31e285005ecf57aa63d59b7cdd5323d67f862f55 100644
--- a/Modules/Core/Metadata/include/otbImageMetadata.h
+++ b/Modules/Core/Metadata/include/otbImageMetadata.h
@@ -287,6 +287,10 @@ public:
    *  Returns True if all keywords were parsed correctly.
    */
   bool FromKeywordlists(const KeywordlistVector&);
+
+  /** Setter for numeric keys on each band*/
+  using ImageMetadataBase::Add;
+  void Add(const MDNum&, const MetaDataKey::VariableLengthVectorType);
 };
 
 extern OTBMetadata_EXPORT std::ostream& operator<<(std::ostream& os, const otb::ImageMetadataBase& imd);
diff --git a/Modules/Core/Metadata/src/otbImageMetadata.cxx b/Modules/Core/Metadata/src/otbImageMetadata.cxx
index 1997503e2544f4e44a415b1b12787ff324a80345..f947583b129d0dee3d87a9b20ae14155075fdcd2 100644
--- a/Modules/Core/Metadata/src/otbImageMetadata.cxx
+++ b/Modules/Core/Metadata/src/otbImageMetadata.cxx
@@ -606,6 +606,16 @@ bool ImageMetadata::FromKeywordlists(const KeywordlistVector& kwlVect)
   return all_parsed;
 }
 
+void ImageMetadata::Add(const MDNum& key, const MetaDataKey::VariableLengthVectorType vlv)
+{
+  assert(this->Bands.size() == vlv.Size());
+  const double* vlvIt = vlv.GetDataPointer();
+  for(auto band = this->Bands.begin() ; band != this->Bands.end() ; ++band, ++vlvIt)
+  {
+    band->Add(key, *vlvIt);
+  }
+}
+
 // printing
 std::ostream& operator<<(std::ostream& os, const otb::ImageMetadataBase& imd)
 {
diff --git a/Modules/Core/Metadata/src/otbOpticalImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbOpticalImageMetadataInterface.cxx
index c5863f9fd0bab1dd7574b4ec7d5f92ce4eddcf2e..647ba5c571273887d86e11ff3b3d805afa2776da 100644
--- a/Modules/Core/Metadata/src/otbOpticalImageMetadataInterface.cxx
+++ b/Modules/Core/Metadata/src/otbOpticalImageMetadataInterface.cxx
@@ -98,8 +98,80 @@ void OpticalImageMetadataInterface::PrintSelf(std::ostream& os, itk::Indent inde
 
 bool OpticalImageMetadataInterface::ConvertImageKeywordlistToImageMetadata()
 {
-  // TODO
-  return false;
+  bool result = true;
+  try
+  {
+    this->m_Imd.Add(MDNum::SunElevation, this->GetSunElevation());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::SunAzimuth, this->GetSunAzimuth());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::SatElevation, this->GetSatElevation());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::SatAzimuth, this->GetSatAzimuth());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::PhysicalBias, this->GetPhysicalBias());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::PhysicalGain, this->GetPhysicalGain());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::SolarIrradiance, this->GetSolarIrradiance());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::FirstWavelength, this->GetFirstWavelengths());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  try
+  {
+	  this->m_Imd.Add(MDNum::LastWavelength,  this->GetLastWavelengths());
+  }
+  catch (const itk::ExceptionObject)
+  {
+    result = false;
+  }
+  return result;
 }
 
 } // end namespace otb
diff --git a/Modules/Core/Metadata/test/otbImageMetadataTest.cxx b/Modules/Core/Metadata/test/otbImageMetadataTest.cxx
index 5badd82398d350c1c5701a05d3ef6efbae1338d3..a9039419834f8a1f8068b0e247dc4b9809ca544a 100644
--- a/Modules/Core/Metadata/test/otbImageMetadataTest.cxx
+++ b/Modules/Core/Metadata/test/otbImageMetadataTest.cxx
@@ -39,17 +39,20 @@ void SetUpImageMetadata(otb::ImageMetadata& md, unsigned int nbBands)
   md.Add(MDTime::ProductionDate, mytime);
   md.Add(std::string("Comment"), std::string("Test Extrakeys"));
 
+  MetaDataKey::VariableLengthVectorType PhysicalGain(nbBands);
+
   for(unsigned int bandId = 0 ; bandId < nbBands ; bandId++)
   {
     ImageMetadataBase bmd;
     oss.str("");
     oss << "B" << bandId;
     bmd.Add(MDStr::BandName, oss.str());
-    bmd.Add(MDNum::PhysicalGain , bandId + 2.0);
     bmd.Add(MDNum::PhysicalBias,  bandId + 1.0);
     bmd.Add(MDNum::NoData, -10000.0);
     md.Bands.push_back(bmd);
+    PhysicalGain.SetElement(bandId, bandId + 2.0);
   }
+  md.Add(MDNum::PhysicalGain , PhysicalGain);
 }
 
 void otbMetadataKeyTest(char* argv[])
@@ -202,7 +205,7 @@ void otbImageMetadataAppendTest(char* argv[])
   SetUpImageMetadata(md, 2);
 
   ImageMetadata md2;
-  SetUpImageMetadata(md, 3);
+  SetUpImageMetadata(md2, 3);
 
   md.append(md2);
   outfile << md;