From ea53b86767b0084fbe08a3eef9590d3de74fad0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Traizet?= <traizetc@cesbio.cnes.fr>
Date: Wed, 21 Jun 2017 09:42:51 +0200
Subject: [PATCH] DR is now based on Machine Learning Models, it is now
 possible to reduce de dimension of the pca model (it has to be changed in
 PCAModel.txx for now

---
 app/cbDimensionalityReductionVector.cxx       | 20 +++++------
 include/AutoencoderModel.h                    | 29 ++++++++++------
 include/AutoencoderModel.txx                  |  4 +--
 include/DimensionalityReductionModelFactory.h |  6 ++--
 .../DimensionalityReductionModelFactory.txx   | 24 ++++++++------
 include/ImageDimensionalityReductionFilter.h  |  5 +--
 include/PCAModel.h                            | 33 ++++++++++++-------
 include/PCAModel.txx                          |  9 +++--
 include/cbLearningApplicationBaseDR.h         | 16 ++++-----
 include/cbLearningApplicationBaseDR.txx       |  8 ++---
 10 files changed, 93 insertions(+), 61 deletions(-)

diff --git a/app/cbDimensionalityReductionVector.cxx b/app/cbDimensionalityReductionVector.cxx
index 90927c56c4..25ac852bd4 100644
--- a/app/cbDimensionalityReductionVector.cxx
+++ b/app/cbDimensionalityReductionVector.cxx
@@ -27,7 +27,7 @@
 #include "itkListSample.h"
 #include "otbShiftScaleSampleListFilter.h"
 #include "DimensionalityReductionModelFactory.h"
-#include "DimensionalityReductionModel.h"
+//#include "DimensionalityReductionModel.h"
 #include <time.h>
 
 namespace otb
@@ -57,16 +57,16 @@ class CbDimensionalityReductionVector : public Application
 		
 		/** Filters typedef */
 		
-		typedef double ValueType;
-		typedef DimensionalityReductionModel<ValueType,ValueType> DimensionalityReductionModelType;
-		typedef DimensionalityReductionModelFactory<ValueType, ValueType> DimensionalityReductionModelFactoryType;
-		typedef DimensionalityReductionModelType::Pointer ModelPointerType;
+		typedef double 															ValueType;
+		typedef itk::VariableLengthVector<ValueType> 							InputSampleType;
+		typedef itk::Statistics::ListSample<InputSampleType> 					ListSampleType;
+		typedef MachineLearningModel<itk::VariableLengthVector<ValueType>, itk::VariableLengthVector<ValueType>>	DimensionalityReductionModelType;
+		typedef DimensionalityReductionModelFactory<ValueType,ValueType> 		DimensionalityReductionModelFactoryType;
+		typedef DimensionalityReductionModelType::Pointer 						ModelPointerType;
 		
 		/** Statistics Filters typedef */
-		typedef itk::VariableLengthVector<ValueType> MeasurementType;
-		typedef otb::StatisticsXMLFileReader<MeasurementType> StatisticsReader;
-		typedef itk::VariableLengthVector<ValueType> InputSampleType;
-		typedef itk::Statistics::ListSample<InputSampleType> ListSampleType;
+		typedef itk::VariableLengthVector<ValueType> 										MeasurementType;
+		typedef otb::StatisticsXMLFileReader<MeasurementType> 								StatisticsReader;
 		typedef otb::Statistics::ShiftScaleSampleListFilter<ListSampleType, ListSampleType> ShiftScaleFilterType;
 		~CbDimensionalityReductionVector() ITK_OVERRIDE
 		{
@@ -211,7 +211,7 @@ class CbDimensionalityReductionVector : public Application
 			
 			
 			/** Read the model */
-			
+			std::cout << "create the fact ?" << std::endl;
 			m_Model = DimensionalityReductionModelFactoryType::CreateDimensionalityReductionModel(GetParameterString("model"),
 			DimensionalityReductionModelFactoryType::ReadMode);
 			if (m_Model.IsNull())
diff --git a/include/AutoencoderModel.h b/include/AutoencoderModel.h
index 3fd4c44748..e9dd9d2b66 100644
--- a/include/AutoencoderModel.h
+++ b/include/AutoencoderModel.h
@@ -6,23 +6,31 @@
 namespace otb
 {
 template <class TInputValue, class AutoencoderType>
-class ITK_EXPORT AutoencoderModel: public  DimensionalityReductionModel<TInputValue,TInputValue>   
+class ITK_EXPORT AutoencoderModel: public  MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>>   
 {
 
 public:
 	
 	typedef AutoencoderModel Self;
-	typedef DimensionalityReductionModel<TInputValue,TInputValue> Superclass;
+	typedef MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>> Superclass;
 	typedef itk::SmartPointer<Self> Pointer;
 	typedef itk::SmartPointer<const Self> ConstPointer;
 
-	typedef typename Superclass::InputValueType InputValueType;
-	typedef typename Superclass::InputSampleType InputSampleType;
-	typedef typename Superclass::InputListSampleType InputListSampleType;
-	typedef typename Superclass::TargetValueType TargetValueType;
-	typedef typename Superclass::TargetSampleType TargetSampleType;
-	typedef typename Superclass::TargetListSampleType TargetListSampleType;
+	typedef typename Superclass::InputValueType 			InputValueType;
+	typedef typename Superclass::InputSampleType 			InputSampleType;
+	typedef typename Superclass::InputListSampleType 		InputListSampleType;
+	typedef typename InputListSampleType::Pointer 			ListSamplePointerType;
+	typedef typename Superclass::TargetValueType 			TargetValueType;
+	typedef typename Superclass::TargetSampleType 			TargetSampleType;
+	typedef typename Superclass::TargetListSampleType 		TargetListSampleType;
+
+	/// Confidence map related typedefs
 	
+	typedef typename Superclass::ConfidenceValueType  				ConfidenceValueType;
+	typedef typename Superclass::ConfidenceSampleType 				ConfidenceSampleType;
+	typedef typename Superclass::ConfidenceListSampleType      		ConfidenceListSampleType;
+
+
 	itkNewMacro(Self);
 	itkTypeMacro(AutoencoderModel, DimensionalityReductionModel);
 
@@ -59,8 +67,9 @@ protected:
 	AutoencoderModel();	
 	~AutoencoderModel() ITK_OVERRIDE;
  
-	virtual TargetSampleType DoPredict(const InputSampleType& input) const ITK_OVERRIDE;
-	virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *) const ITK_OVERRIDE;
+	virtual TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType * quality = ITK_NULLPTR) const;
+
+	virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *, ConfidenceListSampleType * quality = ITK_NULLPTR) const;
   
 private:
 	
diff --git a/include/AutoencoderModel.txx b/include/AutoencoderModel.txx
index a23adb9ba2..3060d8fb30 100644
--- a/include/AutoencoderModel.txx
+++ b/include/AutoencoderModel.txx
@@ -171,7 +171,7 @@ void AutoencoderModel<TInputValue,AutoencoderType>::Load(const std::string & fil
 
 template <class TInputValue, class AutoencoderType>
 typename AutoencoderModel<TInputValue,AutoencoderType>::TargetSampleType
-AutoencoderModel<TInputValue,AutoencoderType>::DoPredict(const InputSampleType & value) const
+AutoencoderModel<TInputValue,AutoencoderType>::DoPredict(const InputSampleType & value, ConfidenceValueType * quality) const
 {  
 	shark::RealVector samples(value.Size());
 	for(size_t i = 0; i < value.Size();i++)
@@ -200,7 +200,7 @@ AutoencoderModel<TInputValue,AutoencoderType>::DoPredict(const InputSampleType &
 
 template <class TInputValue, class AutoencoderType>
 void AutoencoderModel<TInputValue,AutoencoderType>
-::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets) const
+::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets, ConfidenceListSampleType * quality) const
 {
 	std::vector<shark::RealVector> features;
 	Shark::ListSampleRangeToSharkVector(input, features,startIndex,size);
diff --git a/include/DimensionalityReductionModelFactory.h b/include/DimensionalityReductionModelFactory.h
index 791199b5e8..16fa0f416d 100644
--- a/include/DimensionalityReductionModelFactory.h
+++ b/include/DimensionalityReductionModelFactory.h
@@ -18,9 +18,11 @@
 #ifndef DimensionalityReductionModelFactory_h
 #define DimensionalityReductionModelFactory_h
 
-#include "DimensionalityReductionModel.h"
+//#include "DimensionalityReductionModel.h"
 #include "otbMachineLearningModelFactoryBase.h"
  
+#include "otbMachineLearningModel.h" 
+
 namespace otb
 {
 /** \class MachineLearningModelFactory
@@ -44,7 +46,7 @@ public:
   itkTypeMacro(DimensionalityReductionModelFactory, itk::Object);
 
   /** Convenient typedefs. */
-  typedef otb::DimensionalityReductionModel<TInputValue,TOutputValue> DimensionalityReductionModelType;
+  typedef otb::MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>> DimensionalityReductionModelType;
   typedef typename DimensionalityReductionModelType::Pointer DimensionalityReductionModelTypePointer;
 
   /** Mode in which the files is intended to be used */
diff --git a/include/DimensionalityReductionModelFactory.txx b/include/DimensionalityReductionModelFactory.txx
index a546978fb7..ac8f40c680 100644
--- a/include/DimensionalityReductionModelFactory.txx
+++ b/include/DimensionalityReductionModelFactory.txx
@@ -22,25 +22,25 @@
 #include "otbConfigure.h"
 
 #include "SOMModelFactory.h"
-/*
+
 #ifdef OTB_USE_SHARK
 #include "AutoencoderModelFactory.h"
 #include "PCAModelFactory.h"
 #endif
-*/
+
 #include "itkMutexLockHolder.h"
 
 
 namespace otb
 {
-/*	
+
 template <class TInputValue, class TTargetValue>
 using AutoencoderModelFactory = AutoencoderModelFactoryBase<TInputValue, TTargetValue, shark::Autoencoder<shark::TanhNeuron, shark::LinearNeuron>>  ;
 
 
 template <class TInputValue, class TTargetValue>
 using TiedAutoencoderModelFactory = AutoencoderModelFactoryBase<TInputValue, TTargetValue, shark::TiedAutoencoder< shark::TanhNeuron, shark::LinearNeuron>>  ;
-*/
+
 
 template <class TInputValue, class TTargetValue>
 using SOM2DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 2>  ;
@@ -56,7 +56,7 @@ using SOM5DModelFactory = SOMModelFactory<TInputValue, TTargetValue, 5>  ;
 
 
 template <class TInputValue, class TOutputValue>
-typename DimensionalityReductionModel<TInputValue,TOutputValue>::Pointer
+typename MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>>::Pointer
 DimensionalityReductionModelFactory<TInputValue,TOutputValue>
 ::CreateDimensionalityReductionModel(const std::string& path, FileModeType mode)
 {
@@ -65,26 +65,30 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
   std::list<DimensionalityReductionModelTypePointer> possibleDimensionalityReductionModel;
   std::list<LightObject::Pointer> allobjects =
     itk::ObjectFactoryBase::CreateAllInstance("DimensionalityReductionModel");
+ 
   for(std::list<LightObject::Pointer>::iterator i = allobjects.begin();
       i != allobjects.end(); ++i)
     {
-    DimensionalityReductionModel<TInputValue,TOutputValue> * io = dynamic_cast<DimensionalityReductionModel<TInputValue,TOutputValue>*>(i->GetPointer());
+    MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>> * io = dynamic_cast<MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TOutputValue>>*>(i->GetPointer());
     if(io)
       {
       possibleDimensionalityReductionModel.push_back(io);
       }
     else
       {
+	
       std::cerr << "Error DimensionalityReductionModel Factory did not return an DimensionalityReductionModel: "
                 << (*i)->GetNameOfClass()
                 << std::endl;
       }
     }
+  
 for(typename std::list<DimensionalityReductionModelTypePointer>::iterator k = possibleDimensionalityReductionModel.begin();
       k != possibleDimensionalityReductionModel.end(); ++k)
     {
       if( mode == ReadMode )
       {
+		
       if((*k)->CanReadFile(path))
         {
         return *k;
@@ -115,13 +119,13 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
   RegisterFactory(SOM3DModelFactory<TInputValue,TOutputValue>::New());
   RegisterFactory(SOM4DModelFactory<TInputValue,TOutputValue>::New());
   RegisterFactory(SOM5DModelFactory<TInputValue,TOutputValue>::New());
-  /*
+  
 #ifdef OTB_USE_SHARK
   RegisterFactory(PCAModelFactory<TInputValue,TOutputValue>::New());
   RegisterFactory(AutoencoderModelFactory<TInputValue,TOutputValue>::New());
   RegisterFactory(TiedAutoencoderModelFactory<TInputValue,TOutputValue>::New());
 #endif
-  */
+  
 }
 
 template <class TInputValue, class TOutputValue>
@@ -182,7 +186,7 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
       itk::ObjectFactoryBase::UnRegisterFactory(som2dFactory);
       continue;
       }
-      /*
+      
 #ifdef OTB_USE_SHARK
 	
 	// Autoencoder
@@ -211,7 +215,7 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
       continue;
       }
 #endif
-*/
+
     }
 
 }
diff --git a/include/ImageDimensionalityReductionFilter.h b/include/ImageDimensionalityReductionFilter.h
index e550b1944d..008c57d2a4 100644
--- a/include/ImageDimensionalityReductionFilter.h
+++ b/include/ImageDimensionalityReductionFilter.h
@@ -19,7 +19,8 @@
 #define ImageDimensionalityReduction_h
 
 #include "itkImageToImageFilter.h"
-#include "DimensionalityReductionModel.h"
+//#include "DimensionalityReductionModel.h"
+#include "otbMachineLearningModel.h"
 #include "otbImage.h"
 
 namespace otb
@@ -66,7 +67,7 @@ public:
   typedef typename OutputImageType::RegionType OutputImageRegionType;
   typedef typename OutputImageType::InternalPixelType  LabelType;
 
-  typedef DimensionalityReductionModel<ValueType, LabelType> ModelType;
+  typedef MachineLearningModel<itk::VariableLengthVector<ValueType>, itk::VariableLengthVector<LabelType>> ModelType;
   typedef typename ModelType::Pointer                ModelPointerType;
 
   typedef otb::Image<double>                    ConfidenceImageType;
diff --git a/include/PCAModel.h b/include/PCAModel.h
index 45693dfc8a..d5557eb169 100644
--- a/include/PCAModel.h
+++ b/include/PCAModel.h
@@ -7,29 +7,39 @@
 namespace otb
 {
 template <class TInputValue>
-class ITK_EXPORT PCAModel: public  DimensionalityReductionModel<TInputValue,TInputValue>   
+class ITK_EXPORT PCAModel: public  MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>>    
 {
 
 public:
 	
 	typedef PCAModel Self;
-	typedef DimensionalityReductionModel<TInputValue,TInputValue> Superclass;
+	typedef MachineLearningModel<itk::VariableLengthVector< TInputValue> , itk::VariableLengthVector< TInputValue>> Superclass;
 	typedef itk::SmartPointer<Self> Pointer;
 	typedef itk::SmartPointer<const Self> ConstPointer;
 
-	typedef typename Superclass::InputValueType InputValueType;
-	typedef typename Superclass::InputSampleType InputSampleType;
-	typedef typename Superclass::InputListSampleType InputListSampleType;
-	typedef typename Superclass::TargetValueType TargetValueType;
-	typedef typename Superclass::TargetSampleType TargetSampleType;
-	typedef typename Superclass::TargetListSampleType TargetListSampleType;
+	typedef typename Superclass::InputValueType 			InputValueType;
+	typedef typename Superclass::InputSampleType 			InputSampleType;
+	typedef typename Superclass::InputListSampleType 		InputListSampleType;
+	typedef typename InputListSampleType::Pointer 			ListSamplePointerType;
+	typedef typename Superclass::TargetValueType 			TargetValueType;
+	typedef typename Superclass::TargetSampleType 			TargetSampleType;
+	typedef typename Superclass::TargetListSampleType 		TargetListSampleType;
+
+	/// Confidence map related typedefs
 	
+	typedef typename Superclass::ConfidenceValueType  				ConfidenceValueType;
+	typedef typename Superclass::ConfidenceSampleType 				ConfidenceSampleType;
+	typedef typename Superclass::ConfidenceListSampleType      		ConfidenceListSampleType;
+
+
 	itkNewMacro(Self);
 	itkTypeMacro(PCAModel, DimensionalityReductionModel);
 
 	unsigned int GetDimension() {return m_Dimension;}; 
 	itkSetMacro(Dimension,unsigned int);
 	
+	itkSetMacro(Do_resize_flag,bool);
+	
 	bool CanReadFile(const std::string & filename);
 	bool CanWriteFile(const std::string & filename);
 
@@ -44,15 +54,16 @@ protected:
 	PCAModel();	
 	~PCAModel() ITK_OVERRIDE;
  
-	virtual TargetSampleType DoPredict(const InputSampleType& input) const ITK_OVERRIDE;
-	virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *) const ITK_OVERRIDE;
+	virtual TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType * quality = ITK_NULLPTR) const;
+
+	virtual void DoPredictBatch(const InputListSampleType *, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType *, ConfidenceListSampleType * quality = ITK_NULLPTR) const ITK_OVERRIDE;
   
 private:
 	shark::LinearModel<> m_encoder;
 	shark::LinearModel<> m_decoder;
 	shark::PCA m_pca;
 	unsigned int m_Dimension;
-
+	bool m_Do_resize_flag;
 };
 } // end namespace otb
 
diff --git a/include/PCAModel.txx b/include/PCAModel.txx
index 8f48040388..9cda11ec90 100644
--- a/include/PCAModel.txx
+++ b/include/PCAModel.txx
@@ -40,6 +40,7 @@ void PCAModel<TInputValue>::Train()
 	shark::Data<shark::RealVector> inputSamples = shark::createDataFromRange( features );
 	m_pca.setData(inputSamples);
 	m_pca.encoder(m_encoder, m_Dimension);
+	std::cout << m_encoder.matrix() << std::endl;
 	m_pca.decoder(m_decoder, m_Dimension);
 	
 }
@@ -94,13 +95,17 @@ void PCAModel<TInputValue>::Load(const std::string & filename, const std::string
 	m_encoder.read(ia);
 	ifs.close();
 	m_Dimension = m_encoder.outputSize();
+	auto eigenvectors = m_encoder.matrix();
+	eigenvectors.resize(2,m_encoder.inputSize());
+	m_encoder.setStructure(eigenvectors, m_encoder.offset() );
+	std::cout << m_encoder.matrix() << std::endl;
 	//this->m_Size = m_NumberOfHiddenNeurons;
 }
 
 
 template <class TInputValue>
 typename PCAModel<TInputValue>::TargetSampleType
-PCAModel<TInputValue>::DoPredict(const InputSampleType & value) const
+PCAModel<TInputValue>::DoPredict(const InputSampleType & value, ConfidenceValueType * quality) const
 {  
 	shark::RealVector samples(value.Size());
 	for(size_t i = 0; i < value.Size();i++)
@@ -126,7 +131,7 @@ PCAModel<TInputValue>::DoPredict(const InputSampleType & value) const
 
 template <class TInputValue>
 void PCAModel<TInputValue>
-::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets) const
+::DoPredictBatch(const InputListSampleType *input, const unsigned int & startIndex, const unsigned int & size, TargetListSampleType * targets, ConfidenceListSampleType * quality) const
 {
 	
 	std::vector<shark::RealVector> features;
diff --git a/include/cbLearningApplicationBaseDR.h b/include/cbLearningApplicationBaseDR.h
index 71c31f40fe..b3bf030786 100644
--- a/include/cbLearningApplicationBaseDR.h
+++ b/include/cbLearningApplicationBaseDR.h
@@ -15,12 +15,12 @@
 #include "DimensionalityReductionModelFactory.h"
 
 #include "SOMModel.h"
-/*
+
 #ifdef OTB_USE_SHARK
 #include "AutoencoderModel.h"
 #include "PCAModel.h"
 #endif
-*/
+
 namespace otb
 {
 namespace Wrapper
@@ -99,7 +99,7 @@ public:
 	typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 5> Map5DType;
 	typedef otb::SOMModel<InputValueType, 5> SOM5DModelType;
 	
-/*
+
 #ifdef OTB_USE_SHARK
 	typedef shark::Autoencoder< shark::TanhNeuron, shark::LinearNeuron> AutoencoderType;
 	typedef otb::AutoencoderModel<InputValueType, AutoencoderType> AutoencoderModelType;
@@ -109,7 +109,7 @@ public:
 	
 	typedef otb::PCAModel<InputValueType> PCAModelType;
 #endif
-  */
+  
 protected:
   cbLearningApplicationBaseDR();
 
@@ -136,7 +136,7 @@ private:
   template <class somchoice>
   void TrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
   void BeforeTrainSOM(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
-/*
+
 #ifdef OTB_USE_SHARK
   void InitAutoencoderParams();
   void InitPCAParams();
@@ -148,7 +148,7 @@ private:
   void TrainPCA(typename ListSampleType::Pointer trainingListSample, std::string modelPath);
   
  
-#endif  */
+#endif  
   //@}
 };
 
@@ -158,11 +158,11 @@ private:
 #ifndef OTB_MANUAL_INSTANTIATION
 #include "cbLearningApplicationBaseDR.txx"
 #include "cbTrainSOM.txx"
-/*
+
 #ifdef OTB_USE_SHARK
 #include "cbTrainAutoencoder.txx"
 #include "cbTrainPCA.txx"
-#endif*/
+#endif
 #endif
 
 #endif
diff --git a/include/cbLearningApplicationBaseDR.txx b/include/cbLearningApplicationBaseDR.txx
index 2befe3e396..a42ad73857 100644
--- a/include/cbLearningApplicationBaseDR.txx
+++ b/include/cbLearningApplicationBaseDR.txx
@@ -50,12 +50,12 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
   
 
   InitSOMParams();
-  /*
+  
 #ifdef OTB_USE_SHARK
   InitAutoencoderParams();
   InitPCAParams();
 #endif
-  */
+  
 }
 
 template <class TInputValue, class TOutputValue>
@@ -80,7 +80,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
 	{
 		BeforeTrainSOM(trainingListSample,modelPath);
 	}
- /*
+ 
  if(modelName == "autoencoder")
     {
     #ifdef OTB_USE_SHARK
@@ -105,7 +105,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
     #else
     otbAppLogFATAL("Module SharkLearning is not installed. You should consider turning OTB_USE_SHARK on during cmake configuration.");
     #endif
-    }*/
+    }
 }
 
 }
-- 
GitLab