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