From cd26e7670d3b6bb5953603ff41ca1c87c5b813e5 Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Wed, 30 Sep 2015 13:04:12 +0200
Subject: [PATCH] First working version of Gradient minimizers with new
 FitElement.

---
 Core/Algorithms/inc/DetectorMask.h            |  7 ++--
 Core/Algorithms/src/DetectorMask.cpp          | 33 +++++++------------
 Core/Geometry/src/Line.cpp                    |  2 --
 .../fitting/ex05_FitWithMasks/FitWithMasks.py |  2 ++
 Fit/FitKernel/inc/FitObject.h                 |  2 +-
 Fit/FitKernel/inc/FitSuite.h                  |  2 +-
 Fit/FitKernel/src/FitObject.cpp               |  7 ++++
 Fit/FitKernel/src/FitSuite.cpp                |  3 +-
 Fit/FitKernel/src/FitSuiteObjects.cpp         | 27 +++++++++++----
 Fit/PythonAPI/src/FitSuite.pypp.cpp           |  2 +-
 Tests/UnitTests/TestCore/DetectorMaskTest.h   |  3 ++
 11 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/Core/Algorithms/inc/DetectorMask.h b/Core/Algorithms/inc/DetectorMask.h
index da71b92ee57..e440af9e9ad 100644
--- a/Core/Algorithms/inc/DetectorMask.h
+++ b/Core/Algorithms/inc/DetectorMask.h
@@ -55,14 +55,13 @@ public:
     //! returns true if has masks
     bool hasMasks() const;
 
-//    void print() const;
-private:
-    //! swap function
-//    void swapContent(DetectorMask &other);
+    int getNumberOfMaskedChannels() const;
 
+private:
     SafePointerVector<Geometry::IShape2D> m_shapes;
     std::vector<bool> m_mask_of_shape;
     OutputData<bool> m_mask_data;
+    int m_number_of_masked_channels;
 };
 
 #endif
diff --git a/Core/Algorithms/src/DetectorMask.cpp b/Core/Algorithms/src/DetectorMask.cpp
index f0707411214..67b099a2a2b 100644
--- a/Core/Algorithms/src/DetectorMask.cpp
+++ b/Core/Algorithms/src/DetectorMask.cpp
@@ -22,6 +22,7 @@
 // InfinitePlane, Line, VerticalLine, HorizontalLine
 
 DetectorMask::DetectorMask()
+    : m_number_of_masked_channels(0)
 {
 
 }
@@ -29,6 +30,7 @@ DetectorMask::DetectorMask()
 DetectorMask::DetectorMask(const DetectorMask &other)
     : m_shapes(other.m_shapes)
     , m_mask_of_shape(other.m_mask_of_shape)
+    , m_number_of_masked_channels(other.m_number_of_masked_channels)
 {
     m_mask_data.copyFrom(other.m_mask_data);
 }
@@ -39,6 +41,7 @@ DetectorMask &DetectorMask::operator=(const DetectorMask &other)
         m_shapes = other.m_shapes;
         m_mask_of_shape = other.m_mask_of_shape;
         m_mask_data.copyFrom(other.m_mask_data);
+        m_number_of_masked_channels = other.m_number_of_masked_channels;
 //        DetectorMask tmp(other);
 //        tmp.swapContent(*this);
     }
@@ -50,6 +53,7 @@ void DetectorMask::addMask(const Geometry::IShape2D &shape, bool mask_value)
     m_shapes.push_back(shape.clone());
     m_mask_of_shape.push_back(mask_value);
     m_mask_data.clear();
+    m_number_of_masked_channels = 0;
 }
 
 void DetectorMask::initMaskData(const Detector &detector)
@@ -65,18 +69,22 @@ void DetectorMask::initMaskData(const Detector &detector)
 
     if(!m_shapes.size()) return;
 
+    m_number_of_masked_channels = 0;
     for(size_t index=0; index<m_mask_data.getAllocatedSize(); ++index) {
         Bin1D binx = m_mask_data.getAxisBin(index, BornAgain::X_AXIS_INDEX);
         Bin1D biny = m_mask_data.getAxisBin(index, BornAgain::Y_AXIS_INDEX);
         // setting mask to the data starting from last shape added
+        bool is_masked(false);
         for(size_t i_shape=m_shapes.size(); i_shape>0; --i_shape) {
             const Geometry::IShape2D *shape = m_shapes[i_shape-1];
             if(shape->contains(binx, biny)) {
+                if(m_mask_of_shape[i_shape-1]) is_masked = true;
                 m_mask_data[index] = m_mask_of_shape[i_shape-1];
                 // if given index is covered by the shape, stop looking further
                 break;
             }
         }
+        if(is_masked) ++m_number_of_masked_channels;
     }
 }
 
@@ -105,24 +113,7 @@ bool DetectorMask::hasMasks() const
     return (m_shapes.size() ? true : false);
 }
 
-//void DetectorMask::print() const
-//{
-//    std::cout << "DetectorMask::print() " << m_shapes.size() << " " << m_mask_of_shape.size() << m_mask_data.getAllocatedSize() << std::endl;
-//    assert(m_shapes.size() == m_mask_of_shape.size());
-//    for(size_t i=0; i<m_shapes.size(); ++i) {
-//        std::cout << (*m_shapes[i]) << " " << m_mask_of_shape[i] << std::endl;
-//    }
-//    int nmasked(0);
-//    for(size_t i=0; i<m_mask_data.getAllocatedSize(); ++i) {
-//        if(m_mask_data[i]) nmasked++;
-//    }
-//    std::cout << " nmasked:" << nmasked << std::endl;
-
-//}
-
-//void DetectorMask::swapContent(DetectorMask &other)
-//{
-//    std::swap(this->m_shapes, other.m_shapes);
-//    std::swap(this->m_mask_of_shape, other.m_mask_of_shape);
-//    this->m_mask_data.copyFrom(other.m_mask_data);
-//}
+int DetectorMask::getNumberOfMaskedChannels() const
+{
+    return m_number_of_masked_channels;
+}
diff --git a/Core/Geometry/src/Line.cpp b/Core/Geometry/src/Line.cpp
index 718daed86c0..452e4d836a1 100644
--- a/Core/Geometry/src/Line.cpp
+++ b/Core/Geometry/src/Line.cpp
@@ -50,8 +50,6 @@ bool Line::contains(double x, double y) const
 
     double d = distance(p, line);
 
-    std::cout << "Line: " << d << std::endl;
-
     return (d<Numeric::double_epsilon ? true : false);
 }
 
diff --git a/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks.py b/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks.py
index 043574f2b5b..0317763b725 100644
--- a/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks.py
+++ b/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks.py
@@ -132,6 +132,8 @@ def run_fitting():
     real_data = create_real_data()
 
     fit_suite = FitSuite()
+    # fit_suite.setMinimizer("GSLLMA")
+    fit_suite.setMinimizer("Minuit2", "Fumili")
 
     # Here we are settings masks to the detector plane to simulate image which looks like a Pac-Man
     # from ancient arcade game
diff --git a/Fit/FitKernel/inc/FitObject.h b/Fit/FitKernel/inc/FitObject.h
index 237dac2b2fb..1b1512044ce 100644
--- a/Fit/FitKernel/inc/FitObject.h
+++ b/Fit/FitKernel/inc/FitObject.h
@@ -77,7 +77,7 @@ class BA_CORE_API_ FitObject : public IParameterized
     double getWeight() const { return m_weight; }
 
     //! Returns size of data
-    size_t getSizeOfData() const { return m_real_data->getAllocatedSize(); }
+    size_t getSizeOfData() const;
 
     std::vector<FitElement> calculateFitElements();
 
diff --git a/Fit/FitKernel/inc/FitSuite.h b/Fit/FitKernel/inc/FitSuite.h
index c99407d2451..190e4214ad5 100644
--- a/Fit/FitKernel/inc/FitSuite.h
+++ b/Fit/FitKernel/inc/FitSuite.h
@@ -60,7 +60,7 @@ class BA_CORE_API_ FitSuite : public IObservable
     //! Sets minimizer
     void setMinimizer(IMinimizer *minimizer);
 
-    void setMinimizer(std::string& minimizer, const std::string& algorithm = std::string(), const std::string& options=std::string());
+    void setMinimizer(const std::string& minimizer, const std::string& algorithm = std::string(), const std::string& options=std::string());
 
     //! Returns minimizer
     IMinimizer *getMinimizer() { return m_minimizer; }
diff --git a/Fit/FitKernel/src/FitObject.cpp b/Fit/FitKernel/src/FitObject.cpp
index 6635fbc3c5e..2f9aeefe8fb 100644
--- a/Fit/FitKernel/src/FitObject.cpp
+++ b/Fit/FitKernel/src/FitObject.cpp
@@ -100,6 +100,13 @@ std::string FitObject::addParametersToExternalPool(
     return new_path;
 }
 
+size_t FitObject::getSizeOfData() const
+{
+    size_t result = m_real_data->getAllocatedSize() - m_simulation->getInstrument().getDetector()->getDetectorMask()->getNumberOfMaskedChannels();
+    std::cout << "OOO " << result << std::endl;
+    return result;
+}
+
 std::vector<FitElement> FitObject::calculateFitElements()
 {
     std::vector<FitElement> result;
diff --git a/Fit/FitKernel/src/FitSuite.cpp b/Fit/FitKernel/src/FitSuite.cpp
index a81eab0bb9f..39411366ee9 100644
--- a/Fit/FitKernel/src/FitSuite.cpp
+++ b/Fit/FitKernel/src/FitSuite.cpp
@@ -85,7 +85,7 @@ void FitSuite::setMinimizer(IMinimizer *minimizer)
     }
 }
 
-void FitSuite::setMinimizer(std::string &minimizer, const std::string &algorithm, const std::string &options)
+void FitSuite::setMinimizer(const std::string &minimizer, const std::string &algorithm, const std::string &options)
 {
     setMinimizer(MinimizerFactory::createMinimizer(minimizer, algorithm, options));
 }
@@ -142,6 +142,7 @@ void FitSuite::minimize()
     IMinimizer::function_chi2_t fun_chi2 = boost::bind(&FitSuiteChiSquaredFunction::evaluate, &m_function_chi2, _1);
     m_minimizer->setChiSquaredFunction( fun_chi2, m_fit_parameters.size());
 
+    std::cout << "m_fit_objects.getSizeOfDataSet() " << m_fit_objects.getSizeOfDataSet() << std::endl;
     IMinimizer::function_gradient_t fun_gradient = boost::bind(&FitSuiteGradientFunction::evaluate, &m_function_gradient, _1, _2, _3);
     m_minimizer->setGradientFunction( fun_gradient, m_fit_parameters.size(), m_fit_objects.getSizeOfDataSet() );
 
diff --git a/Fit/FitKernel/src/FitSuiteObjects.cpp b/Fit/FitKernel/src/FitSuiteObjects.cpp
index a83234d7213..f714af88cf8 100644
--- a/Fit/FitKernel/src/FitSuiteObjects.cpp
+++ b/Fit/FitKernel/src/FitSuiteObjects.cpp
@@ -39,6 +39,10 @@ void FitSuiteObjects::add(
     const IChiSquaredModule& chi2_module, double weight)
 {
     m_total_weight += weight;
+
+//    std::cout << (real_data.getAllocatedSize() - simulation.getInstrument().getDetector()->getDetectorMask()->getNumberOfMaskedChannels()) << std::endl;
+//    assert(0);
+
     m_fit_objects.push_back(
         new FitObject(simulation, real_data, chi2_module, weight));
 }
@@ -74,6 +78,10 @@ size_t FitSuiteObjects::getSizeOfDataSet() const
             m_fit_objects.begin(); it!= m_fit_objects.end(); ++it) {
         result += (*it)->getSizeOfData();
     }
+    std::cout << "XXX " << result << std::endl;
+    if(result == 0) {
+        throw LogicErrorException("Panic, zero dataset size");
+    }
     return result;
 }
 
@@ -138,13 +146,18 @@ double FitSuiteObjects::calculateChiSquaredValueNew()
 
 double FitSuiteObjects::getResidualValue(size_t global_index)
 {
-    size_t index(0);
-    const FitObject *fitObject =
-        getObjectForGlobalDataIndex(global_index, index);
-    double residual =
-        fitObject->getChiSquaredModule()->getResidualValue(index) *
-        (fitObject->getWeight()/m_total_weight);
-    return residual;
+    if(global_index >= getSizeOfDataSet()) {
+        throw LogicErrorException(" FitSuiteObjects::getResidualValue() -> Error. Wrong size of dataset");
+    }
+//    size_t index(0);
+//    const FitObject *fitObject =
+//        getObjectForGlobalDataIndex(global_index, index);
+//    double residual =
+//        fitObject->getChiSquaredModule()->getResidualValue(index) *
+//        (fitObject->getWeight()/m_total_weight);
+//    return residual;
+    std::cout << "residual: " << global_index << " " << m_fit_elements[global_index].getResidual() << std::endl;
+    return m_fit_elements[global_index].getResidual();
 }
 
 //! Returns maximum intensity in simulated data over all fit objects defined
diff --git a/Fit/PythonAPI/src/FitSuite.pypp.cpp b/Fit/PythonAPI/src/FitSuite.pypp.cpp
index 1784eb3e9a3..56c64dbf6b6 100644
--- a/Fit/PythonAPI/src/FitSuite.pypp.cpp
+++ b/Fit/PythonAPI/src/FitSuite.pypp.cpp
@@ -350,7 +350,7 @@ void register_FitSuite_class(){
         }
         { //::FitSuite::setMinimizer
         
-            typedef void ( ::FitSuite::*setMinimizer_function_type)( ::std::string &,::std::string const &,::std::string const & ) ;
+            typedef void ( ::FitSuite::*setMinimizer_function_type)( ::std::string const &,::std::string const &,::std::string const & ) ;
             
             FitSuite_exposer.def( 
                 "setMinimizer"
diff --git a/Tests/UnitTests/TestCore/DetectorMaskTest.h b/Tests/UnitTests/TestCore/DetectorMaskTest.h
index 2d9e133b0b7..7d10e0881eb 100644
--- a/Tests/UnitTests/TestCore/DetectorMaskTest.h
+++ b/Tests/UnitTests/TestCore/DetectorMaskTest.h
@@ -64,6 +64,8 @@ TEST_F(DetectorMaskTest, AddMask)
         }
     }
 
+    EXPECT_EQ(detectorMask.getNumberOfMaskedChannels(), 32);
+
     // adding second mask of same size which discard previous one
     detectorMask.addMask(polygon, false);
     detectorMask.initMaskData(detector);
@@ -71,6 +73,7 @@ TEST_F(DetectorMaskTest, AddMask)
     for(size_t index=0; index<detectorMask.getMaskData()->getAllocatedSize(); ++index) {
         EXPECT_FALSE(detectorMask.getMask(index));
     }
+    EXPECT_EQ(detectorMask.getNumberOfMaskedChannels(), 0);
 
     // adding third mask
     x = boost::assign::list_of(5.0)(5.0)(8.0)(8.0)(5.0);
-- 
GitLab