diff --git a/App/inc/FitSuiteHelper.h b/App/inc/FitSuiteHelper.h index 7000380a897ee34dea4a40310a259fd0ef758e19..c807db9ad6416abc4e1302e4a5d5353678e64529 100644 --- a/App/inc/FitSuiteHelper.h +++ b/App/inc/FitSuiteHelper.h @@ -19,6 +19,18 @@ #include <string> +//- ------------------------------------------------------------------- +//! @class FitSuiteObserverPrint +//! @brief Print fit progress at the end of each FitSuite's iteration +//- ------------------------------------------------------------------- +class FitSuiteObserverPrint : public IObserver +{ +public: + FitSuiteObserverPrint() { } + void update(IObservable *subject); +}; + + //- ------------------------------------------------------------------- //! @class FitSuiteObserverDraw //! @brief Draw fit progress at the end of each FitSuite's iteration @@ -26,10 +38,9 @@ class FitSuiteObserverDraw : public IObserver { public: - FitSuiteObserverDraw(std::string canvas_name) : m_ncall(0), m_canvas_name(canvas_name) {} + FitSuiteObserverDraw( const std::string &canvas_name = std::string("FitSuiteObserverDraw_c1") ) : m_canvas_name(canvas_name) {} void update(IObservable *subject); private: - int m_ncall; //! number of call of given observer std::string m_canvas_name; //! canvas name were to draw }; @@ -42,10 +53,9 @@ private: class FitSuiteObserverWriteTree : public IObserver { public: - FitSuiteObserverWriteTree(std::string file_name) : m_ncall(0), m_file_name(file_name) {} + FitSuiteObserverWriteTree(const std::string &file_name = std::string("fitsuite.root")) : m_file_name(file_name) {} void update(IObservable *subject); private: - int m_ncall; std::string m_file_name; //! canvas name were to draw }; diff --git a/App/inc/IsGISAXSTools.h b/App/inc/IsGISAXSTools.h index 0df776a757277819f48c673fafca2930df1f0167..1015ba0bee3c5a42e89e439f2208773f78e3ca8a 100644 --- a/App/inc/IsGISAXSTools.h +++ b/App/inc/IsGISAXSTools.h @@ -40,7 +40,10 @@ public: static void drawOutputDataDifference1D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string()); //! draw relative difference of two 2D OutputData sets - static void drawOutputDataDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string()); + static void drawOutputDataRelativeDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string()); + + //! draw relative difference of two 2D OutputData sets + static void drawOutputDataChi2Difference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string()); //! write output data (1D or 2D) in ASCII file static void writeOutputDataToFile(const OutputData<double> &output, const std::string &filename, int precision=10); diff --git a/App/inc/ROOTMinimizer.h b/App/inc/ROOTMinimizer.h index 3d7d86717eda6940771cda97cc8c4f92616fad9b..8c2c3ba262c50b41ec47848359c83655ae973adb 100644 --- a/App/inc/ROOTMinimizer.h +++ b/App/inc/ROOTMinimizer.h @@ -41,15 +41,27 @@ public: //! return pointer to created minimizer ROOT::Math::Minimizer *getROOTMinimizer() { return m_root_minimizer; } + //! get number of variables to fit + virtual size_t getNumberOfVariables() const { return m_root_minimizer->NDim(); } + //! return minimum function value - virtual double getMinValue() { return m_root_minimizer->MinValue(); } + virtual double getMinValue() const { return m_root_minimizer->MinValue(); } //! return value of variable corresponding the minimum of the function - virtual double getValueOfVariableAtMinimum(size_t i) { - if(i >= m_root_minimizer->NDim() ) throw OutOfBoundsException("ROOTMinimizer::getVariableAtMinimum() -> Wrong number of the variable"); + virtual double getValueOfVariableAtMinimum(size_t i) const { + if(i >= getNumberOfVariables() ) throw OutOfBoundsException("ROOTMinimizer::getValueOfVariableAtMinimum() -> Wrong number of the variable"); return m_root_minimizer->X()[i]; } + //! return value of variable corresponding the minimum of the function + virtual double getErrorOfVariable(size_t i) const { + if(i >= getNumberOfVariables() ) throw OutOfBoundsException("ROOTMinimizer::getErrorOfVariable() -> Wrong number of the variable"); + return m_root_minimizer->Errors()[i]; + } + + //! printing results + virtual void printResults() const; + private: ROOT::Math::Minimizer *m_root_minimizer; ROOT::Math::Functor *m_fcn; diff --git a/App/inc/TestPerformance.h b/App/inc/TestPerformance.h index 6c78d35a76159164e9ad27bf5870a208a6d33489..a75bbc8cd8f16f9a0cd8e6d467624a4ff443e1f6 100644 --- a/App/inc/TestPerformance.h +++ b/App/inc/TestPerformance.h @@ -56,9 +56,6 @@ private: //! return delimeter between columns std::string get_delimeter() { return std::string(" | "); } - //! adjust string length to requested - std::string adjust_string_length(std::string name, int length); - std::map<std::string, std::string > m_performance_info; //!< holds system information performance_tests_t m_tests; //!< list of tests for performance measurements diff --git a/App/src/FitSuiteHelper.cpp b/App/src/FitSuiteHelper.cpp index 29bd1f5b4ea422456939a742295c3a53b84b1444..a2416de7bfd28abd1d8587d7ddc77f077b0d1d91 100644 --- a/App/src/FitSuiteHelper.cpp +++ b/App/src/FitSuiteHelper.cpp @@ -2,6 +2,7 @@ #include "FitSuiteHelper.h" #include "TreeEventStructure.h" #include "IsGISAXSTools.h" +#include "ROOTMinimizer.h" #include "TCanvas.h" #include "TPaveText.h" @@ -9,36 +10,85 @@ #include "TROOT.h" #include "TFile.h" #include "TTree.h" +#include "Utils.h" +#include <iomanip> /* ************************************************************************* */ -// draw results of fit iteration in ROOT's canvas +// print results of fit iteration /* ************************************************************************* */ -void FitSuiteObserverDraw::update(IObservable *subject) +void FitSuiteObserverPrint::update(IObservable *subject) { FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject); - if( !fitSuite ) throw NullPointerException("FitSuiteObserverDraw::update() -> Error! Can't cast FitSuite"); + if( !fitSuite ) throw NullPointerException("FitSuiteObserverPrint::update() -> Error! Can't cast FitSuite"); - std::cout << "FitObserver: " << " ncall" << m_ncall << " chi2:" << fitSuite->getChiSquaredModule()->getValue(); // printing parameter values - for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { - std::cout << " " << (*it)->getName() << " " << (*it)->getValue(); - // std::cout << *(*it); + std::cout << "FitSuiteObserverPrint::update() -> Info." + << " NumberOfVariables:" << fitSuite->getMinimizer()->getNumberOfVariables() + << " NCall:" << fitSuite->getNCall() + << " Chi2:" << std::scientific << std::setprecision(8) << fitSuite->getChiSquaredModule()->getValue() << std::endl; + + int npar(0); + for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it, ++npar) { + std::cout << " # "<< npar << " "; + std::cout << Utils::AdjustStringLength((*it)->getName(), 30) + << " value:" << std::scientific << std::setprecision(8) << (*it)->getValue() + << std::endl; } - std::cout << std::endl; + + if(fitSuite->isLastIteration()) { + fitSuite->getMinimizer()->printResults(); + } +} + + +/* ************************************************************************* */ +// draw results of fit iteration in ROOT's canvas +/* ************************************************************************* */ +void FitSuiteObserverDraw::update(IObservable *subject) +{ + FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject); + if( !fitSuite ) throw NullPointerException("FitSuiteObserverDraw::update() -> Error! Can't cast FitSuite"); TCanvas *c1 = dynamic_cast<TCanvas *>( gROOT->FindObject(m_canvas_name.c_str()) ); - if(!c1) throw NullPointerException("FitSuiteObserverDraw::update() -> No access to canvas"); - c1->cd(3); + if(!c1) { + std::cout << " FitSuiteObserverDraw::update() -> Info. No canvas with name '" << m_canvas_name << "', creating one" << std::endl; + c1 = new TCanvas(m_canvas_name.c_str(), m_canvas_name.c_str(), 768, 1024); + c1->Divide(2,3); + } + IsGISAXSTools::resetMinimumAndMaximum(); + // drawing real data + c1->cd(1); + gPad->SetLogz(); + gPad->SetLeftMargin(0.12); + gPad->SetRightMargin(0.12); + IsGISAXSTools::drawOutputDataInPad(*fitSuite->getChiSquaredModule()->getRealData(), "CONT4 Z", "Real data"); + // drawing simulated data + c1->cd(2); gPad->SetLogz(); + gPad->SetLeftMargin(0.12); + gPad->SetRightMargin(0.12); IsGISAXSTools::drawOutputDataInPad(*fitSuite->getChiSquaredModule()->getSimulationData(), "CONT4 Z", "current simulated data"); + // simple difference + c1->cd(3); + gPad->SetLogz(); + gPad->SetLeftMargin(0.12); + gPad->SetRightMargin(0.12); + IsGISAXSTools::setMinimum(10.); + IsGISAXSTools::drawOutputDataRelativeDifference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "COLZ", "relative difference"); + // chi2 difference c1->cd(4); - IsGISAXSTools::drawOutputDataDifference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "CONT4 Z", "difference"); - c1->cd(5); + gPad->SetLogz(); + gPad->SetLeftMargin(0.12); + gPad->SetRightMargin(0.12); + IsGISAXSTools::setMinimum(0.0000001); + IsGISAXSTools::setMaximum(1.0); + IsGISAXSTools::drawOutputDataChi2Difference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "COLZ", "relative chi2 difference"); + c1->cd(5); TPaveText *pt = new TPaveText(.05,.1,.95,.8); char str[256]; - sprintf(str,"Iteration %d",m_ncall); + sprintf(str,"Iteration %d", fitSuite->getNCall()); pt->AddText(str); sprintf(str,"chi2 %e",fitSuite->getChiSquaredModule()->getValue()); pt->AddText(str); @@ -49,7 +99,6 @@ void FitSuiteObserverDraw::update(IObservable *subject) } pt->Draw(); - m_ncall++; } @@ -63,7 +112,6 @@ void FitSuiteObserverWriteTree::update(IObservable *subject) FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject); if( !fitSuite ) throw NullPointerException("FitSuiteObserverWriteTree::update() -> Error! Can't cast FitSuite"); - std::cout << "FitObserver: " << " ncall" << m_ncall << " chi2:" << fitSuite->getChiSquaredModule()->getValue(); // printing parameter values for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { std::cout << " " << (*it)->getName() << " " << (*it)->getValue(); @@ -73,7 +121,7 @@ void FitSuiteObserverWriteTree::update(IObservable *subject) // preparing root file for writing // if it is first call the file will be opened in 'recreate' mode, otherwise in 'update' mode TFile *top(0); - if(m_ncall == 0) { + if(fitSuite->getNCall() == 0) { top = new TFile(m_file_name.c_str(),"RECREATE"); } else { top = new TFile(m_file_name.c_str(),"UPDATE"); @@ -82,7 +130,6 @@ void FitSuiteObserverWriteTree::update(IObservable *subject) throw RuntimeErrorException("FitSuiteObserverWriteTree::update() -> Can't open file "+ m_file_name + " for writing"); } - // data object to write in the tree TreeEventFitData *event = new TreeEventFitData(); @@ -107,7 +154,7 @@ void FitSuiteObserverWriteTree::update(IObservable *subject) event->parvalues.push_back( (*it)->getValue() ); event->parnames.push_back( (*it)->getName().c_str() ); } - event->niter = m_ncall; + event->niter = fitSuite->getNCall(); // appending data to the tree tree->Fill(); @@ -115,7 +162,5 @@ void FitSuiteObserverWriteTree::update(IObservable *subject) top->Close(); delete top; // there is no need to delete tree since ROOT file takes care about all objects opened afterwards delete event; - - m_ncall++; } diff --git a/App/src/IsGISAXSTools.cpp b/App/src/IsGISAXSTools.cpp index c58db4b532ca104c6f308dd6c7f17cb59326ce5f..ddedfbf3ebb9e3f517a3a18935ef7b831e226996 100644 --- a/App/src/IsGISAXSTools.cpp +++ b/App/src/IsGISAXSTools.cpp @@ -241,7 +241,7 @@ void IsGISAXSTools::drawOutputDataDifference1D(const OutputData<double> &left, c /* ************************************************************************* */ // draw relative difference of two 2D OutputData sets /* ************************************************************************* */ -void IsGISAXSTools::drawOutputDataDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title) +void IsGISAXSTools::drawOutputDataRelativeDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title) { if(!gPad) { throw NullPointerException("IsGISAXSTools::drawOutputDataDifference2D -> Error! No canvas exists."); @@ -260,6 +260,31 @@ void IsGISAXSTools::drawOutputDataDifference2D(const OutputData<double> &left, c } +/* ************************************************************************* */ +// draw relative chi2 difference of two 2D OutputData sets +/* ************************************************************************* */ +void IsGISAXSTools::drawOutputDataChi2Difference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title) +{ + if(!gPad) { + throw NullPointerException("IsGISAXSTools::drawOutputDataDifference2D -> Error! No canvas exists."); + } + OutputData<double> *left_clone = left.clone(); + OutputData<double> *right_clone = right.clone(); + + *left_clone -= *right_clone; + OutputData<double> *tmp = left_clone->clone(); + + *left_clone *= *tmp; + left_clone->scaleAll(1./left_clone->totalSum()); + + IsGISAXSTools::drawOutputDataInPad(*left_clone, draw_options, histogram_title); + + delete left_clone; + delete right_clone; + delete tmp; +} + + /* ************************************************************************* */ // write output data (1D or 2D) in ASCII file /* ************************************************************************* */ diff --git a/App/src/ROOTMinimizer.cpp b/App/src/ROOTMinimizer.cpp index fc3c092b239db068b0557bd53f63effc2fbd0e5b..0970467a40646da4b980c388b691d9f802c3a414 100644 --- a/App/src/ROOTMinimizer.cpp +++ b/App/src/ROOTMinimizer.cpp @@ -1,6 +1,7 @@ #include "ROOTMinimizer.h" #include "Exceptions.h" - +#include "Utils.h" +#include <iomanip> ROOTMinimizer::ROOTMinimizer(const std::string &minimizer_name, const std::string &algo_type) : m_fcn(0) { @@ -50,3 +51,24 @@ void ROOTMinimizer::setFunction(boost::function<double(const double *)> fcn, int m_root_minimizer->SetFunction(*m_fcn); } + +/* ************************************************************************* */ +// print results +/* ************************************************************************* */ +void ROOTMinimizer::printResults() const +{ + std::cout << "ROOTMinimizer::printResults() -> " + << " NumberOfVariables:" << getNumberOfVariables() + << " NCall:" << m_root_minimizer->NCalls() + << " Chi2:" << std::scientific << std::setprecision(8) << getMinValue() << std::endl; + + for(size_t i=0; i<getNumberOfVariables(); ++i) { + std::cout << " #" << i + << " '" << Utils::AdjustStringLength(m_root_minimizer->VariableName(i), 30) << "' " + << " value:" << getValueOfVariableAtMinimum(i) + << " error:" << getErrorOfVariable(i) << std::endl; + } +// m_root_minimizer->PrintResults(); +} + + diff --git a/App/src/TestFittingModule.cpp b/App/src/TestFittingModule.cpp index 51c3c99bcb61bb6ff11224244583687f6c9467d0..4d1b8b620a6cd2f4ccc6d42e81e1ca5e1b7dbfc4 100644 --- a/App/src/TestFittingModule.cpp +++ b/App/src/TestFittingModule.cpp @@ -25,8 +25,6 @@ #include "TPaveText.h" - - TestFittingModule::TestFittingModule() : mp_exact_data(0) , mp_real_data(0) @@ -49,28 +47,16 @@ TestFittingModule::~TestFittingModule() void TestFittingModule::execute() { - // initializing data initializeSample(); initializeExperiment(); generateRealData(0.1); -// mp_sample->print_structure(); -// ParameterPool *pool = mp_sample->createParameterTree(); -// std::cout << *pool << std::endl; -// return; - // drawing initial data std::string canvas_name("TestFittingModule_c1"); - TCanvas *c1 = new TCanvas(canvas_name.c_str(), "Test of the fitting suite", 768, 1024); - c1->Divide(2,3); - IsGISAXSTools::setMinimum(1.); - // exact data - c1->cd(1); gPad->SetLogz(); + TCanvas *c1 = new TCanvas(canvas_name.c_str(), "Test of the fitting suite", 800, 600); + c1->cd(); gPad->SetLogz(); IsGISAXSTools::drawOutputDataInPad(*mp_exact_data, "CONT4 Z", "exact data"); - // real data - c1->cd(2); gPad->SetLogz(); - IsGISAXSTools::drawOutputDataInPad(*mp_real_data, "CONT4 Z", "real data"); \ // setting fitSuite FitSuite *fitSuite = new FitSuite(); @@ -80,39 +66,40 @@ void TestFittingModule::execute() fitSuite->addFitParameter("*/MultiLayer/Layer0/thickness", 12*Units::nanometer, 2*Units::nanometer, TRange<double>(1.0, 20.0) ); fitSuite->addFitParameter("*/FormFactorCylinder/radius", 2*Units::nanometer, 2*Units::nanometer, TRange<double>(1.0, 20.0) ); - FitSuiteObserverDraw *drawObserver = new FitSuiteObserverDraw(canvas_name); - fitSuite->attachObserver(drawObserver); - FitSuiteObserverWriteTree *writeObserver = new FitSuiteObserverWriteTree("fitsuite.root"); - fitSuite->attachObserver(writeObserver); + fitSuite->attachObserver( new FitSuiteObserverPrint() ); + fitSuite->attachObserver( new FitSuiteObserverDraw() ); + fitSuite->attachObserver( new FitSuiteObserverWriteTree() ); fitSuite->runFit(); - delete drawObserver; - delete writeObserver; - std::cout << "------ RESULTS ---------" << std::endl; - std::cout << "FitSuite > MinValue:" << fitSuite->getMinimizer()->getMinValue() << " " << fitSuite->getMinimizer()->getValueOfVariableAtMinimum(0) << std::endl; - for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { - std::cout << *(*it) << std::endl; - } - // another way to get results - std::cout << "ROOTMinimizer >" << std::endl; - ROOTMinimizer *min = dynamic_cast<ROOTMinimizer *>(fitSuite->getMinimizer()); - std::cout << min->getROOTMinimizer()->MinValue() << " " << min->getROOTMinimizer()->NCalls() << std::endl; - std::cout << min->getROOTMinimizer()->X()[0] << std::endl; - min->getROOTMinimizer()->PrintResults(); - - c1->cd(6); - TPaveText *pt = new TPaveText(.05,.1,.95,.8); - char str[256]; - sprintf(str,"Results"); - pt->AddText(str); - sprintf(str,"chi2 %e",fitSuite->getMinimizer()->getMinValue()); - pt->AddText(str); - for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { - sprintf(str,"%s %f", (*it)->getName().c_str(), (*it)->getValue()); - pt->AddText(str); - } - pt->Draw(); + // FitSuiteObserverWriteTree *writeObserver = new FitSuiteObserverWriteTree("fitsuite.root"); +// delete drawObserver; +// delete writeObserver; + +// std::cout << "------ RESULTS ---------" << std::endl; +// std::cout << "FitSuite > MinValue:" << fitSuite->getMinimizer()->getMinValue() << " " << fitSuite->getMinimizer()->getValueOfVariableAtMinimum(0) << std::endl; +// for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { +// std::cout << *(*it) << std::endl; +// } +// // another way to get results +// std::cout << "ROOTMinimizer >" << std::endl; +// ROOTMinimizer *min = dynamic_cast<ROOTMinimizer *>(fitSuite->getMinimizer()); +// std::cout << min->getROOTMinimizer()->MinValue() << " " << min->getROOTMinimizer()->NCalls() << std::endl; +// std::cout << min->getROOTMinimizer()->X()[0] << std::endl; +// min->getROOTMinimizer()->PrintResults(); + +// c1->cd(6); +// TPaveText *pt = new TPaveText(.05,.1,.95,.8); +// char str[256]; +// sprintf(str,"Results"); +// pt->AddText(str); +// sprintf(str,"chi2 %e",fitSuite->getMinimizer()->getMinValue()); +// pt->AddText(str); +// for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { +// sprintf(str,"%s %f", (*it)->getName().c_str(), (*it)->getValue()); +// pt->AddText(str); +// } +// pt->Draw(); // IsGISAXSTools::drawLogOutputData(*mp_exact_data, "c1_test_fitting", "fitting", "CONT4 Z", "fitting"); diff --git a/App/src/TestIsGISAXS1.cpp b/App/src/TestIsGISAXS1.cpp index 4ed14c531fee23f9281eda511fc1dce8ddaed872..ae6450ba01b621c32fc6e3cd3117f620242ead8a 100644 --- a/App/src/TestIsGISAXS1.cpp +++ b/App/src/TestIsGISAXS1.cpp @@ -53,7 +53,7 @@ void TestIsGISAXS1::finalise() c1->cd(3); IsGISAXSTools::setMinimum(-0.0001); IsGISAXSTools::setMaximum(0.0001); - IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); + IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); // difference c1->cd(4); diff --git a/App/src/TestIsGISAXS10.cpp b/App/src/TestIsGISAXS10.cpp index 89f50ea0bd6f31836338c8971a139bad800e153c..c533ff4cf65339c800e0f23b73cc09a6b413fc3c 100644 --- a/App/src/TestIsGISAXS10.cpp +++ b/App/src/TestIsGISAXS10.cpp @@ -55,7 +55,7 @@ void TestIsGISAXS10::finalise() c1->cd(3); IsGISAXSTools::setMinimum(-0.0001); IsGISAXSTools::setMaximum(0.0001); - IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); + IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); // difference c1->cd(4); diff --git a/App/src/TestIsGISAXS11.cpp b/App/src/TestIsGISAXS11.cpp index c6e229a4900716acee43de3a6c969f51c5e4c7f9..69bfe8352d962a444108b41ebfb6251473280340 100644 --- a/App/src/TestIsGISAXS11.cpp +++ b/App/src/TestIsGISAXS11.cpp @@ -46,7 +46,7 @@ void TestIsGISAXS11::finalise() c1->cd(3); IsGISAXSTools::setMinimum(-0.0001); IsGISAXSTools::setMaximum(0.0001); - IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); + IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); // difference c1->cd(4); diff --git a/App/src/TestIsGISAXS2.cpp b/App/src/TestIsGISAXS2.cpp index 09d7912e4aa9e9d94d4fc71eb54be8703a7533a8..d29c37618f1c28fdef299c68831b559b8e087c81 100644 --- a/App/src/TestIsGISAXS2.cpp +++ b/App/src/TestIsGISAXS2.cpp @@ -62,7 +62,7 @@ void TestIsGISAXS2::finalise() c1->cd(3); IsGISAXSTools::setMinimum(-0.0001); IsGISAXSTools::setMaximum(0.0001); - IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); + IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); // difference c1->cd(4); diff --git a/App/src/TestIsGISAXS3.cpp b/App/src/TestIsGISAXS3.cpp index 7be9e00a4edfe8f4c47f9c22e61958b7471289f0..f272b359928b1412a1c7015b24a8488fffb51f82 100644 --- a/App/src/TestIsGISAXS3.cpp +++ b/App/src/TestIsGISAXS3.cpp @@ -76,7 +76,7 @@ void TestIsGISAXS3::finalise() c1->cd(3); IsGISAXSTools::setMinimum(-0.0001); IsGISAXSTools::setMaximum(0.0001); - IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); + IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); // difference c1->cd(4); diff --git a/App/src/TestIsGISAXS9.cpp b/App/src/TestIsGISAXS9.cpp index 631a638e96144d663a20b9b17fd0054dab6b4d77..ca0dd1b30f0ded742be933ad4935b72d52393c05 100644 --- a/App/src/TestIsGISAXS9.cpp +++ b/App/src/TestIsGISAXS9.cpp @@ -93,7 +93,7 @@ void TestIsGISAXS9::finalise() c1->cd(3); IsGISAXSTools::setMinimum(-0.0001); IsGISAXSTools::setMaximum(0.0001); - IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); + IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map"); // difference c1->cd(4); diff --git a/App/src/TestMesoCrystal1.cpp b/App/src/TestMesoCrystal1.cpp index 957084a2d7b2b87125533c59b5b2bbdccacabdd3..61830b640ee20debfb4da1acb8d540994f8b5c21 100644 --- a/App/src/TestMesoCrystal1.cpp +++ b/App/src/TestMesoCrystal1.cpp @@ -53,10 +53,10 @@ void TestMesoCrystal1::execute() std::cout << (*p_param_pool) << std::endl; experiment.runSimulation(); - double count_before_normalize = experiment.getOutputData()->total(); + double count_before_normalize = experiment.getOutputData()->totalSum(); experiment.normalize(); mp_intensity_output = experiment.getOutputDataClone(); - double total_count = mp_intensity_output->total(); + double total_count = mp_intensity_output->totalSum(); std::cout << "Total count in detector: " << total_count << std::endl; std::cout << "Scattered percentage in detector: " << 100*total_count/experiment.getBeam().getIntensity() << std::endl; std::cout << "Total count in detector before normalize: " << count_before_normalize << std::endl; diff --git a/App/src/TestPerformance.cpp b/App/src/TestPerformance.cpp index 4f03db5edc7fad42c8cc1de74a48ea109538f64a..5ec0a58e05316f9441b58a56ffa87a4aa12aedf9 100644 --- a/App/src/TestPerformance.cpp +++ b/App/src/TestPerformance.cpp @@ -103,11 +103,11 @@ void TestPerformance::write_performance() } file << m_performance_info["datime"] << get_delimeter(); - file << std::left << adjust_string_length(m_performance_info["hostname"],10) << get_delimeter(); - file << std::left << adjust_string_length(m_performance_info["sysinfo"],23) << get_delimeter(); + file << std::left << Utils::AdjustStringLength(m_performance_info["hostname"],10) << get_delimeter(); + file << std::left << Utils::AdjustStringLength(m_performance_info["sysinfo"],23) << get_delimeter(); for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); it++) { std::string test_name = (*it)->m_test->getName(); - file << std::left << adjust_string_length(m_performance_info[test_name],7) << get_delimeter(); + file << std::left << Utils::AdjustStringLength(m_performance_info[test_name],7) << get_delimeter(); } file<<std::endl; @@ -117,18 +117,6 @@ void TestPerformance::write_performance() } -/* ************************************************************************* */ -// adjust length of string -/* ************************************************************************* */ -std::string TestPerformance::adjust_string_length(std::string name, int length) -{ - std::string newstring = name; - newstring.resize(length,' '); - return newstring; -} - - - /* ************************************************************************* */ // fill system information /* ************************************************************************* */ diff --git a/Core/Algorithms/inc/ISquaredFunction.h b/Core/Algorithms/inc/ISquaredFunction.h index 8d36ea8005d5a8165c4380bf82d0f3b1501268fc..fb97e0206e0bb347f3860b181f419aebd26bef1a 100644 --- a/Core/Algorithms/inc/ISquaredFunction.h +++ b/Core/Algorithms/inc/ISquaredFunction.h @@ -42,7 +42,8 @@ inline double DefaultSquaredFunction::calculateSquaredDifference( { double diff_squared = (simulated_value-real_value)*(simulated_value-real_value); if (diff_squared < Numeric::double_epsilon) return 0.0; - double normalization = std::max(std::abs(real_value), 1.0); + //double normalization = std::max(std::abs(real_value), 1.0); + double normalization = 1.0; return diff_squared/normalization; } diff --git a/Core/Algorithms/src/ChiSquaredModule.cpp b/Core/Algorithms/src/ChiSquaredModule.cpp index a7216f32a70e8fea79a0e8ec9d1cf2ee5745d4f9..9a279b07e54f53df7f473e4ce6cd837038aafe22 100644 --- a/Core/Algorithms/src/ChiSquaredModule.cpp +++ b/Core/Algorithms/src/ChiSquaredModule.cpp @@ -1,4 +1,5 @@ #include "ChiSquaredModule.h" +#include <iostream> ChiSquaredModule::ChiSquaredModule(const OutputData<double>& real_data) : mp_simulation_data(0), m_chi2_value(0) diff --git a/Core/Tools/inc/FitSuite.h b/Core/Tools/inc/FitSuite.h index d32224c6f40dcb76f7407b81a672a847a9693219..59bc5a1d8e68017b91fd4685101b717836a9a8f8 100644 --- a/Core/Tools/inc/FitSuite.h +++ b/Core/Tools/inc/FitSuite.h @@ -35,9 +35,13 @@ class FitSuite : public IObservable { public: typedef std::vector<FitMultiParameter *> fitparameters_t; + FitSuite(); virtual ~FitSuite(); + //! clear all and prepare for the next fit + void clear(); + //! set experiment void setExperiment(Experiment *experiment) { m_experiment = experiment; } @@ -71,11 +75,19 @@ public: //! get chi2 module const ChiSquaredModule *getChiSquaredModule() const { return m_chi2_module; } + //! if the last iteration is done + bool isLastIteration() { return m_is_last_iteration; } + + //! get number of call + int getNCall() { return m_n_call; } + private: Experiment *m_experiment; //! experiment with sample description IMinimizer *m_minimizer; //! minimization engine ChiSquaredModule *m_chi2_module; //! module providing chi2 calculations fitparameters_t m_fit_params; //! vector of parameters to minimize + bool m_is_last_iteration; + int m_n_call; }; #endif // FITSUITE_H diff --git a/Core/Tools/inc/IMinimizer.h b/Core/Tools/inc/IMinimizer.h index 622a06331696c5b33e28b098a576b6adc4156fa3..e18240d4a53847c57d64ba92c0606ea537459cde 100644 --- a/Core/Tools/inc/IMinimizer.h +++ b/Core/Tools/inc/IMinimizer.h @@ -38,11 +38,21 @@ public: //! run minimization virtual void minimize() = 0; + //! get number of variables to fit + virtual size_t getNumberOfVariables() const = 0; + //! return minimum function value - virtual double getMinValue() = 0; + virtual double getMinValue() const = 0; + + //! return pointer to the parameters values at the minimum + virtual double getValueOfVariableAtMinimum(size_t i) const = 0; //! return pointer to the parameters values at the minimum - virtual double getValueOfVariableAtMinimum(size_t i) = 0; + virtual double getErrorOfVariable(size_t i) const = 0; + + //! print fit results + virtual void printResults() const = 0; + }; #endif // IMINIMIZER_H diff --git a/Core/Tools/inc/OutputData.h b/Core/Tools/inc/OutputData.h index c421bbb6eb795a64eb95f40ef9e8385ac0c2b011..e200848566e44ca82236b0bc52b34fd7827eded5 100644 --- a/Core/Tools/inc/OutputData.h +++ b/Core/Tools/inc/OutputData.h @@ -136,7 +136,7 @@ public: template <class U> U getCurrentValueOfAxis(std::string axis_name) const; //! get sum of all values in the data structure - T total() const; + T totalSum() const; // --------- // modifiers @@ -183,6 +183,9 @@ const OutputData<double> &operator-=(OutputData<double> &left, const OutputData< //! division-assignment operator for two output data const OutputData<double> &operator/=(OutputData<double> &left, const OutputData<double> &right); +//! multiplication-assignment operator for two output data +const OutputData<double> &operator*=(OutputData<double> &left, const OutputData<double> &right); + //! double the bin size for each dimension OutputData<double> *doubleBinSize(const OutputData<double> &source); @@ -369,7 +372,7 @@ template <class U> inline U OutputData<T>::getCurrentValueOfAxis(std::string axi template<class T> -inline T OutputData<T>::total() const +inline T OutputData<T>::totalSum() const { T total = 0; for (size_t i=0; i<m_data_size; ++i) { diff --git a/Core/Tools/inc/Utils.h b/Core/Tools/inc/Utils.h index 0dcf7681dafdc5df524441c4e454b7393275314a..ca3e752c53c7b51b08162548ae6a89cc630ead3f 100644 --- a/Core/Tools/inc/Utils.h +++ b/Core/Tools/inc/Utils.h @@ -99,64 +99,15 @@ private: }; - -////- ------------------------------------------------------------------- -////! @class StringSampleHelper -////! @brief Definition of StringSampleHelper to build the string representing -////! path in ISample parameter tree -////! -////! See example in ICompositeSample::getParameterTree() -////- ------------------------------------------------------------------- -//class StringSampleHelper -//{ -//public: -// typedef std::vector<StringUsageMap > nstringmap_t; -// typedef nstringmap_t::iterator iterator_t; - -// StringSampleHelper(){} -// ~StringSampleHelper(){} - -// void add(std::string name, int dirlevel) { - -// while(dirlevel > (int)m_stringstack.size()-1) { -// m_stringstack.push_back(StringUsageMap()); -// } - -// while(dirlevel < (int)m_stringstack.size()-1) { -// m_stringstack.pop_back(); -// } - -// m_stringstack[dirlevel].add(name); -// } - -// //! return current path in parameter tree, like /multilayer/interface3/roughness/sigma -// std::string get_path() -// { -// std::string result; -// for(size_t i_level=0; i_level<m_stringstack.size(); i_level++) { -// std::string currentLevelName = m_stringstack[i_level].get_current(); -// StringUsageMap &strUsageMap = m_stringstack[i_level]; -// // if such name has been already used on that level, built the level name using index number -// std::ostringstream os; -// int nOfUsage = strUsageMap[currentLevelName]; -// result += std::string("/") + currentLevelName; -// if(nOfUsage != 1) { -// os<<nOfUsage; -// result += os.str(); -// } -// } -// return result; -// } - -// iterator_t begin() { return m_stringstack.begin(); } -// iterator_t end() { return m_stringstack.end(); } -// size_t size() const { return m_stringstack.size(); } -// StringUsageMap &operator[](size_t i) { return m_stringstack[i]; } -// StringUsageMap const &operator[](size_t i) const { return m_stringstack[i]; } - -//protected: -// std::vector<StringUsageMap > m_stringstack; -//}; +//- ------------------------------------------------------------------- +//! @brief adjust length of the string +//- ------------------------------------------------------------------- +inline std::string AdjustStringLength(std::string name, int length) +{ + std::string newstring = name; + newstring.resize(length,' '); + return newstring; +} } diff --git a/Core/Tools/src/FitSuite.cpp b/Core/Tools/src/FitSuite.cpp index 22518f148fb1dd78ff8f33efa47cdc891463c3a4..5b828416c8095ff3a48d97d4dc057886acfd825a 100644 --- a/Core/Tools/src/FitSuite.cpp +++ b/Core/Tools/src/FitSuite.cpp @@ -7,18 +7,28 @@ #include "ChiSquaredModule.h" -FitSuite::FitSuite() : m_experiment(0), m_minimizer(0), m_chi2_module(0) +FitSuite::FitSuite() : m_experiment(0), m_minimizer(0), m_chi2_module(0), m_is_last_iteration(false), m_n_call(0) { } FitSuite::~FitSuite() +{ + clear(); +} + + +/* ************************************************************************* */ +// clear all and prepare for the next fit +/* ************************************************************************* */ +void FitSuite::clear() { for(fitparameters_t::iterator it = m_fit_params.begin(); it!= m_fit_params.end(); ++it) { delete (*it); } delete m_minimizer; delete m_chi2_module; + m_is_last_iteration = false; } @@ -102,6 +112,7 @@ void FitSuite::runFit() // seting parameters to the optimum values found by the minimizer for(size_t i=0; i<m_fit_params.size(); ++i) m_fit_params[i]->setValue(m_minimizer->getValueOfVariableAtMinimum(i)); + m_is_last_iteration = true; notifyObservers(); } @@ -111,6 +122,10 @@ void FitSuite::runFit() /* ************************************************************************* */ double FitSuite::functionToMinimize(const double *pars_current_values) { + if( m_fit_params.size() != m_minimizer->getNumberOfVariables() ) { + throw RuntimeErrorException("FitSuite::functionToMinimize() -> Error! Wrong number of parameters (probably missed FitSuite's initialization)."); + } + // set fitting parameters to values suggested by the minimizer for(size_t i=0; i<m_fit_params.size(); ++i) m_fit_params[i]->setValue(pars_current_values[i]); @@ -120,9 +135,8 @@ double FitSuite::functionToMinimize(const double *pars_current_values) const OutputData<double> *p_simulated_data = m_experiment->getOutputData(); double chi_squared = m_chi2_module->calculateChiSquared(p_simulated_data); - std::cout << "chi squared = " << chi_squared << std::endl; - notifyObservers(); + m_n_call++; return chi_squared; } diff --git a/Core/Tools/src/OutputData.cpp b/Core/Tools/src/OutputData.cpp index 53dfbf8af35b74e209dbe2540be0f94415b63d56..57f69930c8780ea5d0e5af9e15a2338b9b2e9e28 100644 --- a/Core/Tools/src/OutputData.cpp +++ b/Core/Tools/src/OutputData.cpp @@ -231,6 +231,8 @@ void MultiIndex::clear() /* ************************************************************************* */ const OutputData<double> &operator+=(OutputData<double> &left, const OutputData<double> &right) { + if( &left == &right) throw LogicErrorException("OutputData &operator+=() -> Error. Left And right can't be the same"); + size_t total_size = left.getAllocatedSize(); if (right.getAllocatedSize()!= total_size) { throw LogicErrorException("OutputData<double> &operator+=() -> Error! Cannot add OutputData objects of different size."); @@ -250,6 +252,8 @@ const OutputData<double> &operator+=(OutputData<double> &left, const OutputData< /* ************************************************************************* */ const OutputData<double> &operator-=(OutputData<double> &left, const OutputData<double> &right) { + if( &left == &right) throw LogicErrorException("OutputData &operator-=() -> Error. Left And right can't be the same"); + size_t total_size = left.getAllocatedSize(); if (right.getAllocatedSize()!= total_size) { throw LogicErrorException("OutputData<double> &operator-=() -> Error! Cannot substract OutputData objects of different size."); @@ -269,6 +273,8 @@ const OutputData<double> &operator-=(OutputData<double> &left, const OutputData< /* ************************************************************************* */ const OutputData<double> &operator/=(OutputData<double> &left, const OutputData<double> &right) { + if( &left == &right) throw LogicErrorException("OutputData &operator/=() -> Error. Left And right can't be the same"); + size_t total_size = left.getAllocatedSize(); if (right.getAllocatedSize()!= total_size) { throw LogicErrorException("OutputData<double> &operator/=() -> Error! Cannot substract OutputData objects of different size."); @@ -292,6 +298,28 @@ const OutputData<double> &operator/=(OutputData<double> &left, const OutputData< return left; } +/* ************************************************************************* */ +// multiplication-assignment operator for two output data +/* ************************************************************************* */ +const OutputData<double> &operator*=(OutputData<double> &left, const OutputData<double> &right) +{ + if( &left == &right) throw LogicErrorException("OutputData &operator*=() -> Error. Left And right can't be the same"); + + size_t total_size = left.getAllocatedSize(); + if (right.getAllocatedSize()!= total_size) { + throw LogicErrorException("OutputData<double> &operator/=() -> Error! Cannot substract OutputData objects of different size."); + } + left.resetIndex(); + right.resetIndex(); + while ( right.hasNext() ) { + double xleft = left.currentValue(); + double xright = right.currentValue(); + left.currentValue() = xleft*xright; + left.next(); right.next(); + } + return left; +} + /* ************************************************************************* */ // double the bin size for each dimension /* ************************************************************************* */