From 4fc6e57a31b6904c1339cbb436fd7152e5d3bbef Mon Sep 17 00:00:00 2001 From: pospelov <pospelov@fz-juelich.de> Date: Tue, 27 Nov 2012 13:21:00 +0100 Subject: [PATCH] Refactoring in FitSuite and Co to link OutputDataNormilizer parameters with fit parameters --- App/inc/TestFittingModule2.h | 3 +- App/src/FitSuiteHelper.cpp | 40 +++++----------- App/src/IsGISAXSTools.cpp | 36 ++++++++------ App/src/TestFittingModule1.cpp | 4 +- App/src/TestFittingModule2.cpp | 20 -------- App/src/TestFittingModule3.cpp | 7 +++ Core/Algorithms/inc/ChiSquaredFrequency.h | 4 +- Core/Algorithms/inc/ChiSquaredModule.h | 4 +- Core/Algorithms/inc/IChiSquaredModule.h | 41 +++++++++------- Core/Algorithms/inc/IOutputDataNormalizer.h | 8 ++-- Core/Algorithms/src/Beam.cpp | 7 ++- Core/Algorithms/src/ChiSquaredFrequency.cpp | 41 ++++++++++++---- Core/Algorithms/src/ChiSquaredModule.cpp | 26 +++++----- Core/Algorithms/src/Detector.cpp | 7 +-- Core/Algorithms/src/Experiment.cpp | 5 +- Core/Algorithms/src/IChiSquaredModule.cpp | 47 ++++++++----------- Core/Algorithms/src/IOutputDataNormalizer.cpp | 23 +++++++++ Core/Tools/inc/FitObject.h | 17 +++++-- Core/Tools/inc/FitSuite.h | 2 +- Core/Tools/inc/FitSuiteObjects.h | 16 +++++-- Core/Tools/inc/FitSuiteParameters.h | 7 +-- Core/Tools/src/FitObject.cpp | 39 +++++++++++++++ Core/Tools/src/FitSuite.cpp | 10 ++-- Core/Tools/src/FitSuiteObjects.cpp | 44 +++++++++++++---- Core/Tools/src/FitSuiteParameters.cpp | 11 +---- 25 files changed, 288 insertions(+), 181 deletions(-) diff --git a/App/inc/TestFittingModule2.h b/App/inc/TestFittingModule2.h index d01861fffe9..343c4d2757e 100644 --- a/App/inc/TestFittingModule2.h +++ b/App/inc/TestFittingModule2.h @@ -27,7 +27,8 @@ class FitSuite; //- ------------------------------------------------------------------- //! @class TestFittingModule2 -//! @brief Testing of fitting module with 5 parameters sample +//! @brief Testing of fitting module with 5 parameters sample using different +//! fit strategies //- ------------------------------------------------------------------- class TestFittingModule2 : public IFunctionalTest { diff --git a/App/src/FitSuiteHelper.cpp b/App/src/FitSuiteHelper.cpp index 13e2a8f6a36..e88ce2234f4 100644 --- a/App/src/FitSuiteHelper.cpp +++ b/App/src/FitSuiteHelper.cpp @@ -112,8 +112,9 @@ void FitSuiteObserverDraw::update(IObservable *subject) enum hist_keys {kReal, kSimul, kDiff, kChi2}; std::vector<OutputData<double > *> data2draw; data2draw.push_back( fitObject->getRealData()->clone() ); - data2draw.push_back( fitObject->getSimulatedData()->clone() ); - data2draw.push_back( getRelativeDifferenceMap(fitObject->getSimulatedData(), fitObject->getRealData() ) ); +// data2draw.push_back( fitObject->getSimulationData()->clone() ); + data2draw.push_back( fitObject->getChiSquaredModule()->getSimulationData()->clone() ); //chi module have normalized simulation + data2draw.push_back( getRelativeDifferenceMap(fitObject->getChiSquaredModule()->getSimulationData(), fitObject->getRealData() ) ); data2draw.push_back( fitObject->getChiSquaredModule()->createChi2DifferenceMap() ); // drawing @@ -175,32 +176,15 @@ void FitSuiteObserverDraw::update(IObservable *subject) /* ************************************************************************* */ TH1 *FitSuiteObserverDraw::get_histogram(const OutputData<double> &data, const std::string &hname) { - TH2D *hist2 = dynamic_cast<TH2D *>(IsGISAXSTools::getOutputDataTH123D( data, hname.c_str())); - if(!hist2) throw LogicErrorException("FitSuiteObserverDraw::get_histogram() -> Error! Can't cast histogram"); - - if( data.getAxis("alpha_f")->getSize() > 1 && data.getAxis("phi_f")->getSize() > 1) { - return hist2; - } - - TH1D *hist1(0); - std::ostringstream ostr; - std::string hname_proj = hname; - if( data.getAxis("alpha_f")->getSize() == 1) { - hname_proj += std::string(" proj_on_phi"); - hist1 = hist2->ProjectionX(hname_proj.c_str()); - ostr << hname_proj << ", alpha_f=" << dynamic_cast<const NamedVector<double >*>(data.getAxis("alpha_f"))->getMin(); - }else if( data.getAxis("phi_f")->getSize() == 1 ) { - hname_proj += std::string(" proj_on_alpha"); - hist1 = hist2->ProjectionY(hname_proj.c_str()); - ostr << hname_proj << ", phi_f=" << dynamic_cast<const NamedVector<double >*>(data.getAxis("phi_f"))->getMin(); - } else { - throw LogicErrorException("FitSuiteObserverDraw::get_histogram() -> Error! Unexpected place"); + if( data.getAxis("alpha_f") && data.getAxis("phi_f") ) { + if( data.getAxis("alpha_f")->getSize() != 1 && data.getAxis("phi_f")->getSize() != 1) + { + return IsGISAXSTools::getOutputDataTH123D( data, hname); + } else if(data.getAxis("alpha_f")->getSize() == 1 || data.getAxis("phi_f")->getSize() == 1){ + return IsGISAXSTools::getOutputDataScanHist(data, hname); + } } - if( !hist1 ) throw LogicErrorException("FitSuiteObserverDraw::get_histogram() -> Error! Can't profile 2D histogram into 1D"); - hist1->SetTitle(ostr.str().c_str()); - delete hist2; - - return hist1; + throw LogicErrorException("FitSuiteObserverDraw::get_histogram()-> Error! Can't handle axis"); } @@ -264,7 +248,7 @@ void FitSuiteObserverWriteTree::update(IObservable *subject) // filling data object with data from FitSuite const OutputData<double > *real_data = fitSuite->getFitObjects()->getRealData(); - const OutputData<double > *simu_data = fitSuite->getFitObjects()->getSimulatedData(); + const OutputData<double > *simu_data = fitSuite->getFitObjects()->getSimulationData(); IsGISAXSTools::exportOutputDataInVectors2D(*real_data, event->real_data, event->axis0, event->axis1); IsGISAXSTools::exportOutputDataInVectors2D(*simu_data, event->fit_data, event->axis0, event->axis1); event->chi2 = fitSuite->getFitObjects()->getChiSquaredModule()->getValue(); diff --git a/App/src/IsGISAXSTools.cpp b/App/src/IsGISAXSTools.cpp index b855568fdd6..ba69fd9e98c 100644 --- a/App/src/IsGISAXSTools.cpp +++ b/App/src/IsGISAXSTools.cpp @@ -150,7 +150,7 @@ TH1 *IsGISAXSTools::getOutputDataTH123D(const OutputData<double>& output, const std::vector<AxisStructure > haxises; haxises.resize(output.getNdimensions()); - // we assume variable bin size and prepare [nbins+1] array of low edges of each bin + // we assume variable bin size and prepare [nbins+1] array of left edges of each bin plus right edge of the last bin for(size_t i_axis=0; i_axis<output.getNdimensions(); ++i_axis) { const NamedVector<double> *axis = reinterpret_cast<const NamedVector<double>*>(output.getAxes()[i_axis]); if( !axis ) throw("IsGISAXSTools::getOutputDataTH123D() -> Error! Can't cast axis"); @@ -186,19 +186,25 @@ TH1 *IsGISAXSTools::getOutputDataTH123D(const OutputData<double>& output, const // } // creation of 1D, 2D or 3D histogram with variable bin size - TH1 *hist; + TH1 *hist(0); + TH1D *hist1(0); + TH2D *hist2(0); + TH3D *hist3(0); if(output.getNdimensions() == 1) { - hist = new TH1D(histo_name.c_str(), histo_name.c_str(), haxises[0].nbins, &haxises[0].xbins[0]); - hist->GetXaxis()->SetTitle( haxises[0].name.c_str() ); + hist1 = new TH1D(histo_name.c_str(), histo_name.c_str(), haxises[0].nbins, &haxises[0].xbins[0]); + hist1->GetXaxis()->SetTitle( haxises[0].name.c_str() ); + hist = hist1; } else if(output.getNdimensions() == 2) { - hist = new TH2D(histo_name.c_str(), histo_name.c_str(), haxises[0].nbins, &haxises[0].xbins[0], haxises[1].nbins, &haxises[1].xbins[0]); - hist->GetXaxis()->SetTitle( haxises[0].name.c_str() ); - hist->GetYaxis()->SetTitle( haxises[1].name.c_str() ); + hist2 = new TH2D(histo_name.c_str(), histo_name.c_str(), haxises[0].nbins, &haxises[0].xbins[0], haxises[1].nbins, &haxises[1].xbins[0]); + hist2->GetXaxis()->SetTitle( haxises[0].name.c_str() ); + hist2->GetYaxis()->SetTitle( haxises[1].name.c_str() ); + hist = hist2; } else if(output.getNdimensions() == 3) { - hist = new TH3D(histo_name.c_str(), histo_name.c_str(), haxises[0].nbins, &haxises[0].xbins[0], haxises[1].nbins, &haxises[1].xbins[0], haxises[1].nbins, &haxises[1].xbins[0]); - hist->GetXaxis()->SetTitle( haxises[0].name.c_str() ); - hist->GetYaxis()->SetTitle( haxises[1].name.c_str() ); - hist->GetZaxis()->SetTitle( haxises[2].name.c_str() ); + hist3 = new TH3D(histo_name.c_str(), histo_name.c_str(), haxises[0].nbins, &haxises[0].xbins[0], haxises[1].nbins, &haxises[1].xbins[0], haxises[1].nbins, &haxises[1].xbins[0]); + hist3->GetXaxis()->SetTitle( haxises[0].name.c_str() ); + hist3->GetYaxis()->SetTitle( haxises[1].name.c_str() ); + hist3->GetZaxis()->SetTitle( haxises[2].name.c_str() ); + hist = hist3; } else { throw LogicErrorException("IsGISAXSTools::getOutputDataTH123D() -> Error! Wrong number of dimensions."); } @@ -211,9 +217,9 @@ TH1 *IsGISAXSTools::getOutputDataTH123D(const OutputData<double>& output, const xyz.push_back(output.getValueOfAxis<double>( haxises[i_axis].name, it.getIndex() ) ); } double value = *it++; - if(output.getNdimensions() == 1) dynamic_cast<TH1D *>(hist)->Fill(xyz[0], value); - if(output.getNdimensions() == 2) dynamic_cast<TH2D *>(hist)->Fill(xyz[0], xyz[1], value); - if(output.getNdimensions() == 3) dynamic_cast<TH3D *>(hist)->Fill(xyz[0], xyz[1], xyz[2], value); + if(hist1) hist1->Fill(xyz[0], value); + if(hist2) hist2->Fill(xyz[0], xyz[1], value); + if(hist3) hist3->Fill(xyz[0], xyz[1], xyz[2], value); } hist->SetContour(50); hist->SetStats(0); @@ -531,7 +537,7 @@ TLine *IsGISAXSTools::getOutputDataScanLine(const OutputData<double> &data) TH1D *IsGISAXSTools::getOutputDataScanHist(const OutputData<double> &data, const std::string &hname) { if(data.getNdimensions() != 2) throw LogicErrorException("IsGISAXSTools::getOutputDataScanHist() -> Error! Number of dimensions should be 2"); - // on of axis should have dimension 1 + // one of axis should have dimension 1 if( (data.getAxis("alpha_f") && data.getAxis("alpha_f")->getSize() != 1) && (data.getAxis("phi_f") && data.getAxis("phi_f")->getSize() != 1)) { std::cout << "IsGISAXSTools::getOutputDataScanHist() -> Info. Can't create 1D histogram from these axes" << std::endl; diff --git a/App/src/TestFittingModule1.cpp b/App/src/TestFittingModule1.cpp index 535ec09ceeb..73afcb3fee2 100644 --- a/App/src/TestFittingModule1.cpp +++ b/App/src/TestFittingModule1.cpp @@ -17,6 +17,7 @@ #include "ResolutionFunction2DSimple.h" #include "AttLimits.h" #include "ISquaredFunction.h" +#include "IOutputDataNormalizer.h" #include "IObserver.h" #include "FitSuite.h" @@ -56,8 +57,6 @@ void TestFittingModule1::execute() // initializing data initializeSample2(); - ParameterPool *pool = mp_sample->createParameterTree(); - std::cout << *pool << std::endl; initializeExperiment(); generateRealData(0.1); @@ -72,6 +71,7 @@ void TestFittingModule1::execute() // setting up fitSuite ChiSquaredModule chiModule; chiModule.setChiSquaredFunction( SquaredFunctionWithSystematicError() ); + chiModule.setOutputDataNormalizer( OutputDataNormalizerScaleAndShift(1e10,0) ); m_fitSuite->addExperimentAndRealData(*mp_experiment, *mp_real_data, chiModule); m_fitSuite->setMinimizer( new ROOTMinimizer("Minuit2", "Migrad") ); diff --git a/App/src/TestFittingModule2.cpp b/App/src/TestFittingModule2.cpp index a0d78bedfb1..5935983d658 100644 --- a/App/src/TestFittingModule2.cpp +++ b/App/src/TestFittingModule2.cpp @@ -59,26 +59,6 @@ TestFittingModule2::~TestFittingModule2() void TestFittingModule2::execute() { -// OutputData<double > *data1 = new OutputData<double>; -// data1->addAxis(std::string("a1"), 0., 10., 100); -// data1->addAxis(std::string("a2"), 0., 10., 100); - -// OutputData<double > *data2 = new OutputData<double>; -// data2->addAxis(std::string("a1"), 0., 10., 100); -// data2->addAxis(std::string("a2"), 0., 10., 99.9999999999999999999); - -// if( data1->hasSameDimensions(*data2) ) { -// std::cout << "Same dimensions " << std::endl; -// } else { -// std::cout << "Not Same dimensions " << std::endl; - -// } -// if( data1->hasSameShape(*data2) ) { -// std::cout << "Same shape " << std::endl; -// } else { -// std::cout << "Not Same shape " << std::endl; -// } - // new sample builder mp_sample_builder = new TestSampleBuilder(); ParameterPool *pool = mp_sample_builder->createParameterTree(); diff --git a/App/src/TestFittingModule3.cpp b/App/src/TestFittingModule3.cpp index 5ed1c7fdfe3..279d19c3dcd 100644 --- a/App/src/TestFittingModule3.cpp +++ b/App/src/TestFittingModule3.cpp @@ -67,6 +67,13 @@ void TestFittingModule3::execute() // m_fitSuite->addFitParameter("*FormFactorPrism3/half_side", 5.0001*Units::nanometer, 1*Units::nanometer, AttLimits::lowerLimited(0.01) ); // m_fitSuite->addFitParameter("*FormFactorPrism3/height", 5.0001*Units::nanometer, 1*Units::nanometer, AttLimits::lowerLimited(0.01) ); + +// // setting up fitSuite +// ChiSquaredModule chiModule; +// chiModule.setChiSquaredFunction( SquaredFunctionWithSystematicError() ); +// m_fitSuite->addExperimentAndRealData(*mp_experiment, *mp_real_data, chiModule); + + // putting scans for(DataScan_t::iterator it=m_data_scans.begin(); it!= m_data_scans.end(); ++it) { m_fitSuite->addExperimentAndRealData(*m_experiment, *(*it)); diff --git a/Core/Algorithms/inc/ChiSquaredFrequency.h b/Core/Algorithms/inc/ChiSquaredFrequency.h index 9b06e07d689..c13a9d9a9da 100644 --- a/Core/Algorithms/inc/ChiSquaredFrequency.h +++ b/Core/Algorithms/inc/ChiSquaredFrequency.h @@ -19,10 +19,10 @@ class ChiSquaredFrequency : public IChiSquaredModule { public: - ChiSquaredFrequency(const OutputData<double> &real_data); + ChiSquaredFrequency(); virtual ~ChiSquaredFrequency(); - virtual double calculateChiSquared(const OutputData<double> *p_simulation_data=0); + virtual double calculateChiSquared(); void setCutoff(double cutoff) { if (cutoff>=0.0 && cutoff<=1.0) m_cutoff = cutoff; diff --git a/Core/Algorithms/inc/ChiSquaredModule.h b/Core/Algorithms/inc/ChiSquaredModule.h index bde6fe13e10..d7b1c1234c6 100644 --- a/Core/Algorithms/inc/ChiSquaredModule.h +++ b/Core/Algorithms/inc/ChiSquaredModule.h @@ -21,16 +21,16 @@ class ChiSquaredModule : public IChiSquaredModule public: ChiSquaredModule(){} ChiSquaredModule(const ChiSquaredModule &other); - ChiSquaredModule(const OutputData<double> &real_data); virtual ~ChiSquaredModule(); virtual ChiSquaredModule *clone() const; //! calculate chi squared volume over experimental and simulated data - virtual double calculateChiSquared(const OutputData<double> *p_simulation_data=0); + virtual double calculateChiSquared(); //! return output data which contains chi^2 values virtual OutputData<double > *createChi2DifferenceMap() const; + private: // disabling assignment operator ChiSquaredModule &operator=(const ChiSquaredModule &); diff --git a/Core/Algorithms/inc/IChiSquaredModule.h b/Core/Algorithms/inc/IChiSquaredModule.h index 5b2269fedb7..088ee069178 100644 --- a/Core/Algorithms/inc/IChiSquaredModule.h +++ b/Core/Algorithms/inc/IChiSquaredModule.h @@ -14,6 +14,7 @@ //! @author Scientific Computing Group at FRM II //! @date Nov 5, 2012 +#include "IParameterized.h" #include "OutputData.h" #include "IFittingDataSelector.h" #include "ISquaredFunction.h" @@ -25,36 +26,42 @@ class IChiSquaredModule { public: IChiSquaredModule(); - IChiSquaredModule(const OutputData<double> &real_data); IChiSquaredModule(const IChiSquaredModule &other); virtual ~IChiSquaredModule(); + //! clone method virtual IChiSquaredModule *clone() const = 0; - void setRealData(const OutputData<double> &real_data); - - void setSimulationData(const OutputData<double> &simulation_data); - - virtual void setFittingDataSelector(const IFittingDataSelector &selector); - - void setChiSquaredFunction(const ISquaredFunction &squared_function); + //! return output data which contains chi^2 values + virtual OutputData<double > *createChi2DifferenceMap() const=0; - virtual double calculateChiSquared(const OutputData<double> *p_simulation_data=0) =0; + //! calculate chi dquared value + virtual double calculateChiSquared() = 0; - //! return real data + //! get real data const OutputData<double> *getRealData() const { return mp_real_data; } - - //! return simulation data + //! get simulated data const OutputData<double> *getSimulationData() const { return mp_simulation_data; } + //! set real and simulated data pair + void setRealAndSimulatedData(const OutputData<double > &real_data, const OutputData<double >&simulation_data); - //! return squared function + //! get squared function const ISquaredFunction *getSquaredFunction() const { return mp_squared_function; } + //! set squared function + void setChiSquaredFunction(const ISquaredFunction &squared_function); - //! return chi2 value (should be called after calculateChiSquared) - virtual double getValue() const { return m_chi2_value; } + //! get fitting data selector + virtual const IFittingDataSelector *getFittingDataSelector() const {return mp_data_selector; } + //! set fitting data selector + virtual void setFittingDataSelector(const IFittingDataSelector &selector); - //! return output data which contains chi^2 values - virtual OutputData<double > *createChi2DifferenceMap() const=0; + //! get data normalizer + virtual const IOutputDataNormalizer *getOutputDataNormalizer() const {return mp_data_normalizer; } + //! set data normalizer + virtual void setOutputDataNormalizer(const IOutputDataNormalizer &data_normalizer); + + //! return last calculated chi squared value + virtual double getValue() const { return m_chi2_value; } protected: // disabling assignment operator diff --git a/Core/Algorithms/inc/IOutputDataNormalizer.h b/Core/Algorithms/inc/IOutputDataNormalizer.h index c823754390b..0221b67879e 100644 --- a/Core/Algorithms/inc/IOutputDataNormalizer.h +++ b/Core/Algorithms/inc/IOutputDataNormalizer.h @@ -28,10 +28,6 @@ public: virtual OutputData<double> *createNormalizedData(const OutputData<double > &data) const=0; -protected: - //! initialize pool parameters, i.e. register some of class members for later access via parameter pool - virtual void init_parameters(){} - }; @@ -40,11 +36,13 @@ class OutputDataNormalizerScaleAndShift : public IOutputDataNormalizer { public: OutputDataNormalizerScaleAndShift(); + OutputDataNormalizerScaleAndShift(double scale, double shift); + OutputDataNormalizerScaleAndShift(const OutputDataNormalizerScaleAndShift &other); virtual ~OutputDataNormalizerScaleAndShift() {} virtual OutputData<double> *createNormalizedData(const OutputData<double > &data) const; - virtual OutputDataNormalizerScaleAndShift *clone() const { return new OutputDataNormalizerScaleAndShift(*this); } + virtual OutputDataNormalizerScaleAndShift *clone() const; protected: //! initialize pool parameters, i.e. register some of class members for later access via parameter pool diff --git a/Core/Algorithms/src/Beam.cpp b/Core/Algorithms/src/Beam.cpp index f55d8560583..fc8d8c3de43 100644 --- a/Core/Algorithms/src/Beam.cpp +++ b/Core/Algorithms/src/Beam.cpp @@ -20,8 +20,11 @@ Beam::Beam(const Beam &other) : IParameterized() Beam &Beam::operator=(const Beam &other) { - Beam tmp(other); - tmp.swapContent(*this); + if( this != &other) + { + Beam tmp(other); + tmp.swapContent(*this); + } return *this; } diff --git a/Core/Algorithms/src/ChiSquaredFrequency.cpp b/Core/Algorithms/src/ChiSquaredFrequency.cpp index c8e96667893..5f0b0284564 100644 --- a/Core/Algorithms/src/ChiSquaredFrequency.cpp +++ b/Core/Algorithms/src/ChiSquaredFrequency.cpp @@ -1,26 +1,47 @@ #include "ChiSquaredFrequency.h" #include "OutputDataFunctions.h" -ChiSquaredFrequency::ChiSquaredFrequency(const OutputData<double>& real_data) -: IChiSquaredModule(real_data) -, mp_real_ft(0) +ChiSquaredFrequency::ChiSquaredFrequency() + : mp_real_ft(0) , mp_simulation_ft(0) , m_cutoff(1.0) { + } + ChiSquaredFrequency::~ChiSquaredFrequency() { delete mp_real_ft; delete mp_simulation_ft; } -double ChiSquaredFrequency::calculateChiSquared( - const OutputData<double>* p_simulation_data) +//double ChiSquaredFrequency::calculateChiSquared( +// const OutputData<double>* p_simulation_data) +//{ +// if (p_simulation_data!=0) { +// setSimulationData(*p_simulation_data); +// } + +// double result = 0.0; +// initWeights(); +// size_t data_size = mp_weights->getAllocatedSize(); +// OutputData<double> *p_difference = createChi2DifferenceMap(); +// OutputData<double>::const_iterator it_weights = mp_weights->begin(); +// OutputData<double>::const_iterator it_diff = p_difference->begin(); +// while(it_diff != p_difference->end()) { +// result += (*it_diff++)*(*it_weights++); +// } +// delete p_difference; +// m_chi2_value = result/data_size; +// return m_chi2_value; +//} + + +double ChiSquaredFrequency::calculateChiSquared() { - if (p_simulation_data!=0) { - setSimulationData(*p_simulation_data); - } + if( !mp_real_data ) throw NullPointerException("ChiSquaredFrequency::calculateChiSquared() -> Error! No real data has been set"); + if( !mp_simulation_data ) throw NullPointerException("ChiSquaredFrequency::calculateChiSquared() -> Error! No simulated data has been set"); double result = 0.0; initWeights(); @@ -33,7 +54,9 @@ double ChiSquaredFrequency::calculateChiSquared( } delete p_difference; m_chi2_value = result/data_size; - return m_chi2_value;} + return m_chi2_value; +} + OutputData<double>* ChiSquaredFrequency::createChi2DifferenceMap() const { diff --git a/Core/Algorithms/src/ChiSquaredModule.cpp b/Core/Algorithms/src/ChiSquaredModule.cpp index d64db56e0e8..ea91a703c64 100644 --- a/Core/Algorithms/src/ChiSquaredModule.cpp +++ b/Core/Algorithms/src/ChiSquaredModule.cpp @@ -6,33 +6,32 @@ ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other) : IChiSquaredM } -ChiSquaredModule::ChiSquaredModule(const OutputData<double>& real_data) - : IChiSquaredModule(real_data) -{ -} - ChiSquaredModule::~ChiSquaredModule() { } + ChiSquaredModule *ChiSquaredModule::clone() const { return new ChiSquaredModule(*this); } -double ChiSquaredModule::calculateChiSquared( - const OutputData<double>* p_simulation_data) +double ChiSquaredModule::calculateChiSquared() { - if (p_simulation_data!=0) { - setSimulationData(*p_simulation_data); - } - if (mp_simulation_data==0) { - throw LogicErrorException("No simulation data present for calculating chi squared."); - } + if( !mp_real_data ) throw NullPointerException("ChiSquaredModule::calculateChiSquared() -> Error! No real data has been set"); + if( !mp_simulation_data ) throw NullPointerException("ChiSquaredModule::calculateChiSquared() -> Error! No simulated data has been set"); + double result = 0.0; size_t data_size = mp_real_data->getAllocatedSize(); initWeights(); + + if(mp_data_normalizer) { + OutputData<double > *normalized_simulation = mp_data_normalizer->createNormalizedData(*mp_simulation_data); + delete mp_simulation_data; + mp_simulation_data = normalized_simulation; + } + OutputData<double> *p_difference = createChi2DifferenceMap(); OutputData<double>::const_iterator it_weights = mp_weights->begin(); OutputData<double>::const_iterator it_diff = p_difference->begin(); @@ -44,6 +43,7 @@ double ChiSquaredModule::calculateChiSquared( return m_chi2_value; } + OutputData<double>* ChiSquaredModule::createChi2DifferenceMap() const { OutputData<double > *p_difference = mp_simulation_data->clone(); diff --git a/Core/Algorithms/src/Detector.cpp b/Core/Algorithms/src/Detector.cpp index 854b1d46cf8..1d1f3bdbcec 100644 --- a/Core/Algorithms/src/Detector.cpp +++ b/Core/Algorithms/src/Detector.cpp @@ -30,12 +30,13 @@ Detector::~Detector() Detector &Detector::operator=(const Detector &other) { - Detector tmp(other); - tmp.swapContent(*this); + if( this != &other) { + Detector tmp(other); + tmp.swapContent(*this); + } return *this; } - void Detector::swapContent(Detector &other) { std::swap(this->m_axes, other.m_axes); diff --git a/Core/Algorithms/src/Experiment.cpp b/Core/Algorithms/src/Experiment.cpp index 59b746b824b..ba868594daf 100644 --- a/Core/Algorithms/src/Experiment.cpp +++ b/Core/Algorithms/src/Experiment.cpp @@ -142,8 +142,9 @@ std::string Experiment::addParametersToExternalPool(std::string path, } // add parameters of the sample (only in the case without sample builder) else if (mp_sample) { - std::string sample_path = new_path + mp_sample->getName(); - mp_sample->addParametersToExternalPool(sample_path, external_pool, -1); +// std::string sample_path = new_path + mp_sample->getName(); +// mp_sample->addParametersToExternalPool(sample_path, external_pool, -1); + mp_sample->addParametersToExternalPool(new_path, external_pool, -1); } return new_path; diff --git a/Core/Algorithms/src/IChiSquaredModule.cpp b/Core/Algorithms/src/IChiSquaredModule.cpp index 3e1ef1a183f..75b213a0b4d 100644 --- a/Core/Algorithms/src/IChiSquaredModule.cpp +++ b/Core/Algorithms/src/IChiSquaredModule.cpp @@ -15,21 +15,6 @@ IChiSquaredModule::IChiSquaredModule() } -IChiSquaredModule::IChiSquaredModule(const OutputData<double>& real_data) - : mp_real_data(0) - , mp_simulation_data(0) - , mp_weights(0) - , mp_squared_function(0) - , mp_data_selector(0) - , mp_data_normalizer(0) - , m_chi2_value(0) -{ - mp_real_data = real_data.clone(); - mp_squared_function = new DefaultSquaredFunction(); - mp_data_selector = new DefaultAllDataSelector(); -} - - IChiSquaredModule::IChiSquaredModule(const IChiSquaredModule &other) : mp_real_data(0) , mp_simulation_data(0) @@ -39,8 +24,8 @@ IChiSquaredModule::IChiSquaredModule(const IChiSquaredModule &other) , mp_data_normalizer(0) , m_chi2_value(0) { - if(other.mp_real_data) mp_real_data = other.mp_real_data->clone(); - if(other.mp_simulation_data) mp_simulation_data = other.mp_simulation_data->clone(); + if(other.mp_real_data) mp_real_data = other.mp_real_data; + if(other.mp_simulation_data) mp_simulation_data = other.mp_simulation_data; if(other.mp_weights) mp_weights = other.mp_weights->clone(); if(other.mp_squared_function) mp_squared_function = other.mp_squared_function->clone(); if(other.mp_data_selector) mp_data_selector = other.mp_data_selector->clone(); @@ -58,35 +43,41 @@ IChiSquaredModule::~IChiSquaredModule() delete mp_data_normalizer; } -void IChiSquaredModule::setRealData(const OutputData<double>& real_data) -{ - delete mp_real_data; - mp_real_data = real_data.clone(); -} -void IChiSquaredModule::setSimulationData( - const OutputData<double>& simulation_data) +void IChiSquaredModule::setRealAndSimulatedData(const OutputData<double > &real_data, const OutputData<double >&simulation_data) { + delete mp_real_data; + mp_real_data=real_data.clone(); delete mp_simulation_data; mp_simulation_data = simulation_data.clone(); } -void IChiSquaredModule::setFittingDataSelector( - const IFittingDataSelector& selector) + +void IChiSquaredModule::setFittingDataSelector(const IFittingDataSelector& selector) { delete mp_data_selector; mp_data_selector = selector.clone(); } -void IChiSquaredModule::setChiSquaredFunction( - const ISquaredFunction& squared_function) + +void IChiSquaredModule::setChiSquaredFunction(const ISquaredFunction& squared_function) { delete mp_squared_function; mp_squared_function = squared_function.clone(); } +void IChiSquaredModule::setOutputDataNormalizer(const IOutputDataNormalizer &data_normalizer) +{ + delete mp_data_normalizer; + mp_data_normalizer = data_normalizer.clone(); +} + + void IChiSquaredModule::initWeights() { delete mp_weights; + if( !mp_real_data ) throw NullPointerException("IChiSquaredModule::initWeights() -> Error! No real data has been set"); + if( !mp_simulation_data ) throw NullPointerException("IChiSquaredModule::initWeights() -> Error! No simulated data has been set"); mp_weights = mp_data_selector->createWeightMap(*mp_real_data, *mp_simulation_data); } + diff --git a/Core/Algorithms/src/IOutputDataNormalizer.cpp b/Core/Algorithms/src/IOutputDataNormalizer.cpp index 8619ed3dd31..52fc5ca5bf6 100644 --- a/Core/Algorithms/src/IOutputDataNormalizer.cpp +++ b/Core/Algorithms/src/IOutputDataNormalizer.cpp @@ -11,6 +11,27 @@ OutputDataNormalizerScaleAndShift::OutputDataNormalizerScaleAndShift() init_parameters(); } +OutputDataNormalizerScaleAndShift::OutputDataNormalizerScaleAndShift(double scale, double shift) + : m_scale(scale) + , m_shift(shift) +{ + setName("Normalizer"); + init_parameters(); +} + +OutputDataNormalizerScaleAndShift::OutputDataNormalizerScaleAndShift(const OutputDataNormalizerScaleAndShift &other) : IOutputDataNormalizer(other) +{ + m_scale = other.m_scale; + m_shift = other.m_shift; + init_parameters(); +} + + +OutputDataNormalizerScaleAndShift *OutputDataNormalizerScaleAndShift::clone() const +{ + return new OutputDataNormalizerScaleAndShift(*this); +} + void OutputDataNormalizerScaleAndShift::init_parameters() { @@ -26,6 +47,7 @@ OutputData<double> *OutputDataNormalizerScaleAndShift::createNormalizedData(cons OutputData<double >::const_iterator cit = std::max_element(data.begin(), data.end()); double max_intensity = (*cit); + std::cout << "QQQ before " << data.totalSum() << std::endl; if(max_intensity) { OutputData<double >::iterator it = normalized_data->begin(); while(it!=normalized_data->end()) { @@ -33,6 +55,7 @@ OutputData<double> *OutputDataNormalizerScaleAndShift::createNormalizedData(cons (*it) = m_scale*(value/max_intensity) + m_shift; ++it; } + std::cout << "QQQ after " << normalized_data->totalSum() << std::endl; } else { std::cout << "OutputDataNormalizerScaleAndShift::createNormalizedData() -> Warning! Zero maximum intensity" << std::endl; } diff --git a/Core/Tools/inc/FitObject.h b/Core/Tools/inc/FitObject.h index 80548e50ff0..054082cd91d 100644 --- a/Core/Tools/inc/FitObject.h +++ b/Core/Tools/inc/FitObject.h @@ -14,17 +14,18 @@ //! @author Scientific Computing Group at FRM II //! @date 21.11.2012 - +#include "IParameterized.h" #include "Experiment.h" #include "OutputData.h" #include "ChiSquaredModule.h" + //- ------------------------------------------------------------------- //! @class FitObject //! @brief Class to hold single experiment description, real data and chi2 module //! Used by FitSuite //- ------------------------------------------------------------------- -class FitObject +class FitObject : public IParameterized { public: FitObject(const Experiment &experiment, const OutputData<double > &real_data, const IChiSquaredModule &chi2_module=ChiSquaredModule()); @@ -42,7 +43,7 @@ public: void setRealData(const OutputData<double > &real_data); //! get simulated data - const OutputData<double > *getSimulatedData() const { return m_experiment->getOutputData(); } + const OutputData<double > *getSimulationData() const { return m_experiment->getOutputData(); } //! get chi2 module const IChiSquaredModule *getChiSquaredModule() const {return m_chi2_module; } @@ -50,6 +51,16 @@ public: //! set chi2 module void setChiSquaredModule(const IChiSquaredModule &chi2_module) { delete m_chi2_module; m_chi2_module = chi2_module.clone(); } + //! calculate chi squared value + double calculateChiSquared(); + + //! add parameters from local pool to external pool and call recursion over direct children + virtual std::string addParametersToExternalPool(std::string path, ParameterPool *external_pool, int copy_number=-1) const; + +protected: + //! initialize pool parameters, i.e. register some of class members for later access via parameter pool + virtual void init_parameters(); + private: FitObject(const FitObject &); FitObject &operator=(const FitObject &); diff --git a/Core/Tools/inc/FitSuite.h b/Core/Tools/inc/FitSuite.h index 878770d191d..49833193e84 100644 --- a/Core/Tools/inc/FitSuite.h +++ b/Core/Tools/inc/FitSuite.h @@ -95,7 +95,7 @@ private: //! check if all prerequisites to run fit fit are filled bool check_prerequisites(); - FitSuiteObjects m_fit_objects; //! kit which contains pairs of <experiment,real_data> to fit + FitSuiteObjects m_fit_objects; //! kit which contains sets of <experiment,real_data,chi_module> to fit FitSuiteParameters m_fit_parameters; //! collection of fit parameters fitstrategies_t m_fit_strategies; //! collection of strategies which are executed before every minimization round IMinimizer *m_minimizer; //! minimization engine diff --git a/Core/Tools/inc/FitSuiteObjects.h b/Core/Tools/inc/FitSuiteObjects.h index 68633005a09..47687b7a6f4 100644 --- a/Core/Tools/inc/FitSuiteObjects.h +++ b/Core/Tools/inc/FitSuiteObjects.h @@ -15,11 +15,11 @@ //! @date 15.11.2012 +#include "IParameterized.h" #include "Experiment.h" #include "OutputData.h" #include "FitObject.h" - #include <vector> @@ -27,12 +27,12 @@ //! @class FitSuiteObjects //! @brief Class containing vector FitObject's (experiment and real data) to fit //- ------------------------------------------------------------------- -class FitSuiteObjects +class FitSuiteObjects : public IParameterized { public: typedef std::vector<FitObject *> FitObjects_t; - FitSuiteObjects(){} + FitSuiteObjects(); virtual ~FitSuiteObjects(){} //! clear all data @@ -63,11 +63,19 @@ public: IChiSquaredModule *getChiSquaredModule(int i_item = 0) { return m_fit_objects[check_index(i_item)]->getChiSquaredModule(); } //! get simulated data - const OutputData<double> * getSimulatedData(int i_item = 0) const { return m_fit_objects[check_index(i_item)]->getSimulatedData(); } + const OutputData<double> * getSimulationData(int i_item = 0) const { return m_fit_objects[check_index(i_item)]->getSimulationData(); } //! get fit object const FitObject *getObject(int i_item = 0) const { return m_fit_objects[check_index(i_item)]; } FitObject *getObject(int i_item = 0) { return m_fit_objects[check_index(i_item)]; } + + //! add parameters from local pool to external pool and call recursion over direct children + virtual std::string addParametersToExternalPool(std::string path, ParameterPool *external_pool, int copy_number=-1) const; + +protected: + //! initialize pool parameters, i.e. register some of class members for later access via parameter pool + virtual void init_parameters(); + private: //! disabled copy constructor and assignment operator FitSuiteObjects &operator=(const FitSuiteObjects &); diff --git a/Core/Tools/inc/FitSuiteParameters.h b/Core/Tools/inc/FitSuiteParameters.h index 68bb87874bb..860fbc5fb93 100644 --- a/Core/Tools/inc/FitSuiteParameters.h +++ b/Core/Tools/inc/FitSuiteParameters.h @@ -18,7 +18,8 @@ #include "FitParameterLinked.h" #include <vector> -class Experiment; +//class Experiment; +class ParameterPool; //- ------------------------------------------------------------------- //! @class FitSuiteParameters @@ -68,8 +69,8 @@ public: const FitParameter *operator[](std::string name) const { return getParameter(name); } FitParameter *operator[](std::string name) { return getParameter(name); } - //! link fit parameters to parameters defined in experiment - void link_to_experiment(const Experiment *experiment); + //! linking fit parameters with pool parameters + void link_to_pool(const ParameterPool *pool); private: //! disabled copy constructor and assignment operator diff --git a/Core/Tools/src/FitObject.cpp b/Core/Tools/src/FitObject.cpp index 140dbdc99fe..ee0335df065 100644 --- a/Core/Tools/src/FitObject.cpp +++ b/Core/Tools/src/FitObject.cpp @@ -10,6 +10,7 @@ FitObject::FitObject(const Experiment &experiment, const OutputData<double > &re , m_real_data(real_data.clone()) , m_chi2_module(chi2_module.clone()) { + setName("FitObject"); if( !m_real_data->hasSameShape(*m_experiment->getOutputData()) ) { std::cout << "FitObject::FitObject() -> Info. Real data and output data in the experiment have different shape. Adjusting experiment's detector." << std::endl; } else { @@ -40,3 +41,41 @@ void FitObject::setRealData(const OutputData<double > &real_data) } } + +/* ************************************************************************* */ +// calculate chi squared value +/* ************************************************************************* */ +double FitObject::calculateChiSquared() +{ + m_chi2_module->setRealAndSimulatedData(*m_real_data, *m_experiment->getOutputData()); + return m_chi2_module->calculateChiSquared(); +} + + +/* ************************************************************************* */ +// add parameters from local pool to external pool +/* ************************************************************************* */ +std::string FitObject::addParametersToExternalPool(std::string path, + ParameterPool* external_pool, int copy_number) const +{ + // add own parameters + std::string new_path = IParameterized::addParametersToExternalPool(path, external_pool, copy_number); + + // add parameters of the experiment + if(m_experiment) m_experiment->addParametersToExternalPool(new_path, external_pool, -1); + + if(m_chi2_module) { + const IOutputDataNormalizer *data_normalizer = m_chi2_module->getOutputDataNormalizer(); + if(data_normalizer) { + data_normalizer->addParametersToExternalPool(new_path, external_pool, -1); + } + } + + return new_path; +} + + +void FitObject::init_parameters() +{ + +} diff --git a/Core/Tools/src/FitSuite.cpp b/Core/Tools/src/FitSuite.cpp index 5c197e2710b..19a77cba18e 100644 --- a/Core/Tools/src/FitSuite.cpp +++ b/Core/Tools/src/FitSuite.cpp @@ -68,10 +68,12 @@ void FitSuite::addFitStrategy(IFitSuiteStrategy *strategy) /* ************************************************************************* */ void FitSuite::link_fit_parameters() { - // loop over all experiments defined - for(size_t i_exp = 0; i_exp<m_fit_objects.size(); ++i_exp) { - m_fit_parameters.link_to_experiment(m_fit_objects.getExperiment(i_exp)); - } + ParameterPool *pool = m_fit_objects.createParameterTree(); + m_fit_parameters.link_to_pool(pool); + std::cout << "XXXXXX FitSuite::link_fit_parameters() -> " << std::endl; + std::cout << *pool << std::endl; + std::cout << "----------------" << std::endl; + delete pool; } diff --git a/Core/Tools/src/FitSuiteObjects.cpp b/Core/Tools/src/FitSuiteObjects.cpp index ca14c32fea5..99916ff302d 100644 --- a/Core/Tools/src/FitSuiteObjects.cpp +++ b/Core/Tools/src/FitSuiteObjects.cpp @@ -2,6 +2,13 @@ +FitSuiteObjects::FitSuiteObjects() +{ + setName("FitSuiteObjects"); + init_parameters(); +} + + /* ************************************************************************* */ // clear all data /* ************************************************************************* */ @@ -39,16 +46,37 @@ void FitSuiteObjects::runSimulation() double FitSuiteObjects::getChiSquaredValue() { double chi_squared(0); - for(size_t i_exp = 0; i_exp<m_fit_objects.size(); ++i_exp) { - const OutputData<double> *simulated_data = getSimulatedData(i_exp); - const OutputData<double> *real_data = getRealData(i_exp); + for(FitObjects_t::iterator it = m_fit_objects.begin(); it!= m_fit_objects.end(); ++it) { + chi_squared += (*it)->calculateChiSquared(); + } + return chi_squared; +} - IChiSquaredModule *chi2_module = getChiSquaredModule(i_exp); - chi2_module->setRealData(*real_data); - double value = chi2_module->calculateChiSquared(simulated_data); - chi_squared += value; +/* ************************************************************************* */ +// add parameters from local pool to external pool +/* ************************************************************************* */ +std::string FitSuiteObjects::addParametersToExternalPool(std::string path, + ParameterPool* external_pool, int copy_number) const +{ + (void)copy_number; + // add own parameters + // so far it is top object in our chain, and its without parameters, lets exclude its name from path + //std::string new_path = IParameterized::addParametersToExternalPool(path, external_pool, copy_number); + std::string new_path = path; + + int ncopy(0); + if(m_fit_objects.size()==1) ncopy=-1; // if we have only one object, lets get rid from copy number + for(FitObjects_t::const_iterator it = m_fit_objects.begin(); it!= m_fit_objects.end(); ++it, ++ncopy) { + (*it)->addParametersToExternalPool(new_path, external_pool, ncopy); } - return chi_squared; + + return new_path; +} + + +void FitSuiteObjects::init_parameters() +{ + } diff --git a/Core/Tools/src/FitSuiteParameters.cpp b/Core/Tools/src/FitSuiteParameters.cpp index b708f11d3e4..404e3afd031 100644 --- a/Core/Tools/src/FitSuiteParameters.cpp +++ b/Core/Tools/src/FitSuiteParameters.cpp @@ -81,15 +81,10 @@ std::vector<double > FitSuiteParameters::getValues() const /* ************************************************************************* */ -// link fit parameters to parameters defined in experiment +// linking fit parameters with pool parameters /* ************************************************************************* */ -void FitSuiteParameters::link_to_experiment(const Experiment *experiment) +void FitSuiteParameters::link_to_pool(const ParameterPool *pool) { - // accessing parameter pool of the sample - ParameterPool *pool = experiment->createParameterTree(); - std::cout << " XXX " << std::endl; - std::cout << *pool << std::endl; - // linking fit parameter with whose pool parameters which match name of fit parameter // going through all fit parameters defined for(parameters_t::iterator it = m_parameters.begin(); it!= m_parameters.end(); ++it) { @@ -97,8 +92,6 @@ void FitSuiteParameters::link_to_experiment(const Experiment *experiment) if( !par ) throw LogicErrorException("FitSuiteParameters::link_to_experiment() -> Error! Can't cast to FitParameterLinked."); par->addMatchedParametersFromPool(pool); } - - delete pool; } -- GitLab