diff --git a/include/DimensionalityReductionModelFactory.txx b/include/DimensionalityReductionModelFactory.txx
index 0c05937d39c7ba448c1f43ec360d10f62fcaea80..585af208aaef19604247d1e48369e65729d3a704 100644
--- a/include/DimensionalityReductionModelFactory.txx
+++ b/include/DimensionalityReductionModelFactory.txx
@@ -21,6 +21,7 @@
 #include "DimensionalityReductionModelFactory.h"
 #include "otbConfigure.h"
 
+#include "SOMModelFactory.h"
 
 #ifdef OTB_USE_SHARK
 #include "AutoencoderModelFactory.h"
@@ -95,15 +96,12 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
 {
   itk::MutexLockHolder<itk::SimpleMutexLock> lockHolder(mutex);
   
+  
 
-#ifdef OTB_USE_SHARK
 
+  RegisterFactory(SOMModelFactory<TInputValue,TOutputValue>::New());
   
- // using AutoencoderModelFactory = AutoencoderModelFactoryBase<TInputValue, TTargetValue, shark::Autoencoder< shark::TanhNeuron, shark::LinearNeuron>>  {};
- 
- 
-  //using TiedAutoencoderModelFactory = public AutoencoderModelFactoryBase<TInputValue, TTargetValue, shark::TiedAutoencoder< shark::TanhNeuron, shark::LinearNeuron>>  {};
-
+#ifdef OTB_USE_SHARK
   RegisterFactory(PCAModelFactory<TInputValue,TOutputValue>::New());
   RegisterFactory(AutoencoderModelFactory<TInputValue,TOutputValue>::New());
   RegisterFactory(TiedAutoencoderModelFactory<TInputValue,TOutputValue>::New());
@@ -136,7 +134,14 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
   for (itFac = factories.begin(); itFac != factories.end() ; ++itFac)
     {
 
-
+	// SOM
+    SOMModelFactory<TInputValue,TOutputValue> *somFactory =
+      dynamic_cast<SOMModelFactory<TInputValue,TOutputValue> *>(*itFac);
+    if (somFactory)
+      {
+      itk::ObjectFactoryBase::UnRegisterFactory(somFactory);
+      continue;
+      }
 #ifdef OTB_USE_SHARK
 	
 	// Autoencoder
@@ -155,7 +160,8 @@ DimensionalityReductionModelFactory<TInputValue,TOutputValue>
       itk::ObjectFactoryBase::UnRegisterFactory(taeFactory);
       continue;
       }
-      
+    
+    // PCA  
     PCAModelFactory<TInputValue,TOutputValue> *pcaFactory =
       dynamic_cast<PCAModelFactory<TInputValue,TOutputValue> *>(*itFac);
     if (pcaFactory)
diff --git a/include/SOMModel.h b/include/SOMModel.h
index 1a469e44369509cf81ccfe97876839222306897e..b7adddd663494f7d01c00a66062931ed5c7dbaac 100644
--- a/include/SOMModel.h
+++ b/include/SOMModel.h
@@ -37,7 +37,7 @@ public:
 	typedef typename Superclass::ConfidenceSampleType ConfidenceSampleType;
 	typedef typename Superclass::ConfidenceListSampleType ConfidenceListSampleType;
 
-	typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 2> MapType;
+	typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 3> MapType;
 	typedef typename MapType::SizeType       SizeType;
 	
 	typedef otb::SOM<InputListSampleType, MapType> EstimatorType;
diff --git a/include/SOMModel.txx b/include/SOMModel.txx
index 78df8415c8470d3fb365030606bb1a60e45f0e8f..5c6be685bae44fbc4525c87f62f03166464720b5 100644
--- a/include/SOMModel.txx
+++ b/include/SOMModel.txx
@@ -14,6 +14,7 @@ namespace otb
 template <class TInputValue>
 SOMModel<TInputValue>::SOMModel()
 {
+	this->m_IsRegressionSupported = true;
 }
 
 
@@ -37,13 +38,6 @@ void SOMModel<TInputValue>::Train()
     estimator->SetBetaEnd(m_BetaEnd);
     estimator->SetMaxWeight(m_MaxWeight);
     //AddProcess(estimator,"Learning");
-    std::cout << "list = " << m_ListSample << std::endl;
-    std::cout << "size = " << m_MapSize << std::endl;
-    std::cout << "neigsize = " << m_NeighborhoodSizeInit << std::endl;
-    std::cout << "n iter = " << m_NumberOfIterations << std::endl;
-    std::cout << "bi = " << m_BetaInit << std::endl;
-    std::cout << "be = " << m_BetaEnd << std::endl;
-    std::cout << "mw = " << m_MaxWeight << std::endl;
     
     estimator->Update();
 	
@@ -54,6 +48,14 @@ void SOMModel<TInputValue>::Train()
 template <class TInputValue>
 bool SOMModel<TInputValue>::CanReadFile(const std::string & filename)
 {
+	try
+	{
+		this->Load(filename);
+	}
+	catch(...)
+	{
+	return false;
+	}
 	return true;
 }
 
@@ -86,7 +88,7 @@ void SOMModel<TInputValue>::Load(const std::string & filename, const std::string
 	auto reader = otb::ImageFileReader<MapType>::New();
 	reader->SetFileName(filename);
 	reader->Update();
-	std::cout <<  reader->GetOutput()->GetImageKeywordlist().GetMetadataByKey("MachineLearningModelType") << '\n';
+	//std::cout <<  reader->GetOutput()->GetImageKeywordlist().GetMetadataByKey("MachineLearningModelType") << '\n';
 	m_SOMMap = reader->GetOutput();
 }
 
@@ -94,7 +96,19 @@ void SOMModel<TInputValue>::Load(const std::string & filename, const std::string
 template <class TInputValue>
 typename SOMModel<TInputValue>::TargetSampleType
 SOMModel<TInputValue>::DoPredict(const InputSampleType & value, ConfidenceValueType *quality) const
-{  
+{ 
+	unsigned int dimension =MapType::ImageDimension;
+    TargetSampleType target;
+    target.SetSize(dimension);
+	
+    auto winner =m_SOMMap->GetWinner(value);
+    
+    
+    for (int i=0; i< dimension ;i++) {
+		target[i] = winner.GetElement(i); 
+	}
+	
+	return target;
 }
 
 } // namespace otb
diff --git a/include/SOMModelFactory.h b/include/SOMModelFactory.h
index 56c0b88c6c3d85414d8f0d95b93f64047d2fbd06..0a3a9dd7a33e8366aa70d37d75a3af568c9a22c5 100644
--- a/include/SOMModelFactory.h
+++ b/include/SOMModelFactory.h
@@ -1,5 +1,5 @@
-#ifndef PCAModelFactory_h
-#define PCAModelFactory_h
+#ifndef SOMModelFactory_h
+#define SOMModelFactory_h
 
 
 #include "itkObjectFactoryBase.h"
@@ -9,11 +9,11 @@ namespace otb
 {
 	
 template <class TInputValue, class TTargetValue>
-class ITK_EXPORT PCAModelFactory : public itk::ObjectFactoryBase
+class ITK_EXPORT SOMModelFactory : public itk::ObjectFactoryBase
 {
 public:
   /** Standard class typedefs. */
-  typedef PCAModelFactory   Self;
+  typedef SOMModelFactory   Self;
   typedef itk::ObjectFactoryBase        Superclass;
   typedef itk::SmartPointer<Self>       Pointer;
   typedef itk::SmartPointer<const Self> ConstPointer;
@@ -26,21 +26,21 @@ public:
   itkFactorylessNewMacro(Self);
 
   /** Run-time type information (and related methods). */
-  itkTypeMacro(PCAModelFactory, itk::ObjectFactoryBase);
+  itkTypeMacro(SOMModelFactory, itk::ObjectFactoryBase);
 
   /** Register one factory of this type  */
   static void RegisterOneFactory(void)
   {
-    Pointer PCAFactory = PCAModelFactory::New();
-    itk::ObjectFactoryBase::RegisterFactory(PCAFactory);
+    Pointer SOMFactory = SOMModelFactory::New();
+    itk::ObjectFactoryBase::RegisterFactory(SOMFactory);
   }
 
 protected:
-  PCAModelFactory();
-  ~PCAModelFactory() ITK_OVERRIDE;
+  SOMModelFactory();
+  ~SOMModelFactory() ITK_OVERRIDE;
 
 private:
-  PCAModelFactory(const Self &); //purposely not implemented
+  SOMModelFactory(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
 
 };
@@ -51,7 +51,7 @@ private:
 
 
 #ifndef OTB_MANUAL_INSTANTIATION
-#include "PCAModelFactory.txx"
+#include "SOMModelFactory.txx"
 #endif
 
 #endif
diff --git a/include/SOMModelFactory.txx b/include/SOMModelFactory.txx
index bfaa4f6f624b12d8351defb1bc52ad9a4d37253e..0df39c43c49d3983060c03f01572a3b5d417e129 100644
--- a/include/SOMModelFactory.txx
+++ b/include/SOMModelFactory.txx
@@ -15,49 +15,49 @@
      PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
-#ifndef PCAFactory_txx
-#define PCAFactory_txx
+#ifndef SOMFactory_txx
+#define SOMFactory_txx
 
 
-#include "PCAModelFactory.h"
+#include "SOMModelFactory.h"
 
 #include "itkCreateObjectFunction.h"
-#include "PCAModel.h"
+#include "SOMModel.h"
 //#include <shark/Algorithms/Trainers/PCA.h>
 #include "itkVersion.h"
 
 namespace otb
 {
 template <class TInputValue, class TOutputValue>
-PCAModelFactory<TInputValue,TOutputValue>::PCAModelFactory()
+SOMModelFactory<TInputValue,TOutputValue>::SOMModelFactory()
 {
 
   std::string classOverride = std::string("DimensionalityReductionModel");
-  std::string subclass = std::string("PCAModel");
+  std::string subclass = std::string("SOMModel");
 
   this->RegisterOverride(classOverride.c_str(),
                          subclass.c_str(),
-                         "Shark PCA ML Model",
+                         "SOM DR Model",
                          1,
                       //   itk::CreateObjectFunction<AutoencoderModel<TInputValue,TOutputValue> >::New());
-						itk::CreateObjectFunction<PCAModel<TInputValue>>::New());
+						itk::CreateObjectFunction<SOMModel<TInputValue>>::New());
 }
 
 template <class TInputValue, class TOutputValue>
-PCAModelFactory<TInputValue,TOutputValue>::~PCAModelFactory()
+SOMModelFactory<TInputValue,TOutputValue>::~SOMModelFactory()
 {
 }
 
 template <class TInputValue, class TOutputValue>
-const char* PCAModelFactory<TInputValue,TOutputValue>::GetITKSourceVersion(void) const
+const char* SOMModelFactory<TInputValue,TOutputValue>::GetITKSourceVersion(void) const
 {
   return ITK_SOURCE_VERSION;
 }
 
 template <class TInputValue, class TOutputValue>
-const char* PCAModelFactory<TInputValue,TOutputValue>::GetDescription() const
+const char* SOMModelFactory<TInputValue,TOutputValue>::GetDescription() const
 {
-  return "PCA model factory";
+  return "SOM model factory";
 }
 
 } // end namespace otb
diff --git a/include/cbLearningApplicationBaseDR.h b/include/cbLearningApplicationBaseDR.h
index 9ef37ef948487c3c2f729d9a0b9e973af8de4d95..5ff2e90442d4630d8aed0d348c8eec70060ba56b 100644
--- a/include/cbLearningApplicationBaseDR.h
+++ b/include/cbLearningApplicationBaseDR.h
@@ -87,7 +87,7 @@ public:
 	  
 	// Dimensionality reduction models
 	
-	typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 2> MapType;
+	typedef SOMMap<itk::VariableLengthVector<TInputValue>,itk::Statistics::EuclideanDistanceMetric<itk::VariableLengthVector<TInputValue>>, 3> MapType;
 	typedef otb::SOM<ListSampleType, MapType> EstimatorType;
 	typedef otb::SOMModel<InputValueType> SOMModelType;
 
diff --git a/include/cbTrainSOM.txx b/include/cbTrainSOM.txx
index 9e2b620dc52349f5a2f16eec97501b44d5998580..4951b177250802a4f097ebd10f897698a5472c6b 100644
--- a/include/cbTrainSOM.txx
+++ b/include/cbTrainSOM.txx
@@ -20,7 +20,14 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
                           "This group of parameters allows setting SOM parameters. "
                           );
   
-  
+	AddParameter(ParameterType_StringList ,  "model.som.s",   "Size");
+    SetParameterDescription("model.som.s", "Size of the SOM map");
+    MandatoryOff("model.som.s");
+    
+	AddParameter(ParameterType_StringList ,  "model.som.n",   "Size Neighborhood");
+    SetParameterDescription("model.som.n", "Size of the initial neighborhood in the SOM map");
+    MandatoryOff("model.som.n");
+    
     AddParameter(ParameterType_Int,  "model.som.sx",   "SizeX");
     SetParameterDescription("model.som.sx", "X size of the SOM map");
     MandatoryOff("model.som.sx");
@@ -52,7 +59,7 @@ cbLearningApplicationBaseDR<TInputValue,TOutputValue>
     AddParameter(ParameterType_Float,  "model.som.iv",   "InitialValue");
     SetParameterDescription("model.som.iv", "Maximum initial neuron weight");
     MandatoryOff("model.som.iv");
-    
+    ;
     SetDefaultParameterInt("model.som.sx", 32);
     SetDefaultParameterInt("model.som.sy", 32);
     SetDefaultParameterInt("model.som.nx", 10);
@@ -70,20 +77,28 @@ void cbLearningApplicationBaseDR<TInputValue,TOutputValue>
 ::TrainSOM(typename ListSampleType::Pointer trainingListSample,std::string modelPath)
 {
 		
+		//std::cout << std::stoi(s[0]) << std::endl;
 		typename SOMModelType::Pointer dimredTrainer = SOMModelType::New();
 		dimredTrainer->SetNumberOfIterations(GetParameterInt("model.som.ni"));
 		dimredTrainer->SetBetaInit(GetParameterFloat("model.som.bi"));
 		dimredTrainer->SetBetaEnd(GetParameterFloat("model.som.bf"));
 		dimredTrainer->SetMaxWeight(GetParameterFloat("model.som.iv"));
+		std::cout << "0" << std::endl;
 		typename EstimatorType::SizeType size;
-        size[0]=GetParameterInt("model.som.sx");
-        size[1]=GetParameterInt("model.som.sy");
+		std::vector<std::basic_string<char>> s= GetParameterStringList("model.som.s");
+		for (int i=0; i<3; i++){ // This will be templated later (the 3)
+			size[i]=std::stoi(s[i]);
+		}
+		
         dimredTrainer->SetMapSize(size);
+        std::cout << "1" << std::endl;
         typename EstimatorType::SizeType radius;
-        radius[0] = GetParameterInt("model.som.nx");
-        radius[1] = GetParameterInt("model.som.ny");
+		std::vector<std::basic_string<char>> n= GetParameterStringList("model.som.n");
+		for (int i=0; i<3; i++){ // This will be templated later (the 3)
+			radius[i]=std::stoi(n[i]);
+		}
+		std::cout << "2" << std::endl;
         dimredTrainer->SetNeighborhoodSizeInit(radius);
-        std::cout << trainingListSample << std::endl;
         dimredTrainer->SetListSample(trainingListSample);
 		dimredTrainer->Train();
 		dimredTrainer->Save(modelPath);