diff --git a/App/App.pro b/App/App.pro index e402ee3bfcb89c8aba98a376bf6d09d54a988019..8b09c1fb114261b6858296ecf1d62f533e33e80d 100644 --- a/App/App.pro +++ b/App/App.pro @@ -16,8 +16,6 @@ SOURCES += \ src/AppOptionsDescription.cpp \ src/CommandLine.cpp \ src/DrawHelper.cpp \ - src/EventFrame.cpp \ - src/FittingHelper.cpp \ src/FunctionalTestFactory.cpp \ src/IFunctionalTest.cpp \ src/IsGISAXSTools.cpp \ @@ -43,7 +41,9 @@ SOURCES += \ src/TestMultiLayerRoughness.cpp \ src/TestPerformance.cpp \ src/TestRootTree.cpp \ - src/TestRoughness.cpp + src/TestRoughness.cpp \ + src/TreeEventStructure.cpp \ + src/FitSuiteHelper.cpp HEADERS += \ inc/App.h \ @@ -51,9 +51,7 @@ HEADERS += \ inc/AppOptionsDescription.h \ inc/CommandLine.h \ inc/DrawHelper.h \ - inc/EventFrame.h \ inc/FunctionalTestFactory.h \ - inc/FittingHelper.h \ inc/IFunctionalTest.h \ inc/IsGISAXSTools.h \ inc/ROOTMinimizer.h \ @@ -77,7 +75,9 @@ HEADERS += \ inc/TestMultiLayerRoughness.h \ inc/TestPerformance.h \ inc/TestRootTree.h \ - inc/TestRoughness.h + inc/TestRoughness.h \ + inc/TreeEventStructure.h \ + inc/FitSuiteHelper.h INCLUDEPATH += ./inc ../Core/Algorithms/inc ../Core/FormFactors/inc ../Core/Geometry/inc ../Core/Samples/inc ../Core/Tools/inc ../Core/PythonAPI/inc DEPENDPATH += ./inc ../Core/Algorithms/inc ../Core/FormFactors/inc ../Core/Geometry/inc ../Core/Samples/inc ../Core/Tools/inc ../Core/PythonAPI/inc diff --git a/App/inc/App.h b/App/inc/App.h index e6244f69a1a236013d57642763b7336aa78dabb6..dee1d9fdea64c5d952db712bca0237ad9570da79 100644 --- a/App/inc/App.h +++ b/App/inc/App.h @@ -16,6 +16,6 @@ #include "ISingleton.h" #include "DrawHelper.h" -#include "EventFrame.h" +#include "TreeEventStructure.h" #endif // APP_H diff --git a/App/inc/AppLinkDef.h b/App/inc/AppLinkDef.h index b297e139e7776c636a28331a0f57e29fb4cf504a..e93d4c2ad0f48604f0cb03fa7cac90b3ba5e5ca4 100644 --- a/App/inc/AppLinkDef.h +++ b/App/inc/AppLinkDef.h @@ -20,7 +20,7 @@ #pragma link C++ class ISingleton<DrawHelper>+; #pragma link C++ class DrawHelper+; - -#pragma link C++ class EventFrame+; +#pragma link C++ class TreeEventOutputData+; +#pragma link C++ class TreeEventFitData+; #endif diff --git a/App/inc/FittingHelper.h b/App/inc/FitSuiteHelper.h similarity index 55% rename from App/inc/FittingHelper.h rename to App/inc/FitSuiteHelper.h index 81a3b2eb809a2074d60c35fcb4ac005af9f3597a..7000380a897ee34dea4a40310a259fd0ef758e19 100644 --- a/App/inc/FittingHelper.h +++ b/App/inc/FitSuiteHelper.h @@ -1,5 +1,5 @@ -#ifndef FITTINGHELPER_H -#define FITTINGHELPER_H +#ifndef FITSUITEHELPER_H +#define FITSUITEHELPER_H // ******************************************************************** // * The BornAgain project * // * Simulation of neutron and x-ray scattering at grazing incidence * @@ -9,7 +9,7 @@ // * eget quam orci. Quisque porta varius dui, quis posuere nibh * // * mollis quis. Mauris commodo rhoncus porttitor. * // ******************************************************************** -//! @file FittingHelper.h +//! @file FitSuiteHelper.h //! @brief Collection of helper classes for fitting from App //! @author Scientific Computing Group at FRM II //! @date 08.10.2012 @@ -18,17 +18,15 @@ #include "IObserver.h" #include <string> -namespace FittingHelper { - //- ------------------------------------------------------------------- -//! @class ObserveAndDraw -//! @brief Draw fit progress at the end of each FitSuite's minimization function call +//! @class FitSuiteObserverDraw +//! @brief Draw fit progress at the end of each FitSuite's iteration //- ------------------------------------------------------------------- -class ObserveAndDraw : public IObserver +class FitSuiteObserverDraw : public IObserver { public: - ObserveAndDraw(std::string canvas_name) : m_ncall(0), m_canvas_name(canvas_name) {} + FitSuiteObserverDraw(std::string canvas_name) : m_ncall(0), m_canvas_name(canvas_name) {} void update(IObservable *subject); private: int m_ncall; //! number of call of given observer @@ -36,7 +34,22 @@ private: }; -} +//- ------------------------------------------------------------------- +//! @class FitSuiteObserverWrite +//! @brief Save results of each fit iteration to the disk in the form of ROOT tree +//! If tree exist, data will be appended to it +//- ------------------------------------------------------------------- +class FitSuiteObserverWriteTree : public IObserver +{ +public: + FitSuiteObserverWriteTree(std::string file_name) : m_ncall(0), m_file_name(file_name) {} + void update(IObservable *subject); +private: + int m_ncall; + std::string m_file_name; //! canvas name were to draw +}; + + -#endif // FITTINGHELPER_H +#endif // FITSUITEHELPER_H diff --git a/App/inc/ROOTMinimizer.h b/App/inc/ROOTMinimizer.h index 94ea46df617b34b8947d33e8bbbd7099408898e6..3d7d86717eda6940771cda97cc8c4f92616fad9b 100644 --- a/App/inc/ROOTMinimizer.h +++ b/App/inc/ROOTMinimizer.h @@ -44,7 +44,7 @@ public: //! return minimum function value virtual double getMinValue() { return m_root_minimizer->MinValue(); } - //! return pointer to the parameters values at the minimum + //! 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"); return m_root_minimizer->X()[i]; diff --git a/App/inc/EventFrame.h b/App/inc/TreeEventStructure.h similarity index 51% rename from App/inc/EventFrame.h rename to App/inc/TreeEventStructure.h index 25f582eedfd7befbcc6cedd07b0211f9086b6980..8782679774af94bc3bb00f4f29cf5d33ad1ddb65 100644 --- a/App/inc/EventFrame.h +++ b/App/inc/TreeEventStructure.h @@ -1,5 +1,5 @@ -#ifndef EVENTFRAME_H -#define EVENTFRAME_H +#ifndef TREEEVENTSTRUCTURE_H +#define TREEEVENTSTRUCTURE_H // ******************************************************************** // * The BornAgain project * // * Simulation of neutron and x-ray scattering at grazing incidence * @@ -9,24 +9,27 @@ // * eget quam orci. Quisque porta varius dui, quis posuere nibh * // * mollis quis. Mauris commodo rhoncus porttitor. * // ******************************************************************** -//! @file EventFrame.h -//! @brief Definition of EventFrame class for writing in root files +//! @file TreeEventStructure.h +//! @brief Collection of classes to write output data in ROOT trees //! @author Scientific Computing Group at FRM II -//! @date 19.07.2012 - +//! @date 09.10.2012 #include "TObject.h" #include <vector> +#include <string> + + //- ------------------------------------------------------------------- -//! @class EventFrame -//! @brief event structure to save in the root file +//! @class TreeEventOutputData +//! @brief Data structure respresenting OutputData and mesocrystal settings +//! for writing/reading in/from the ROOT tree. //- ------------------------------------------------------------------- -class EventFrame +class TreeEventOutputData { public: - EventFrame(); - virtual ~EventFrame(){} + TreeEventOutputData(); + virtual ~TreeEventOutputData() { } void clear(); @@ -49,9 +52,35 @@ public: std::vector<std::vector<double > > valpha_f; // values of alpha_f for the frame std::vector<std::vector<double > > vphi_f; // values of phi_f for the frames - ClassDef(EventFrame,1) + ClassDef(TreeEventOutputData,1) +}; + + +//- ------------------------------------------------------------------- +//! @class TreeEventFitData +//! @brief Represent fit results after each iteration for writing/reading +//! in/from the ROOT tree +//- ------------------------------------------------------------------- +class TreeEventFitData +{ +public: + TreeEventFitData(); + virtual ~TreeEventFitData() { } + void clear(); + + int niter; // number of iteration + std::vector<std::vector<double > > real_data; // real data + std::vector<std::vector<double > > fit_data; // current fit iteration data + std::vector<std::vector<double > > diff; // chi2 difference between real and fit data + std::vector<std::vector<double > > axis0; // values of phi_f (made in 2D for convenient drawing) + std::vector<std::vector<double > > axis1; // values of alpha_f (made in 2D for convenient drawing) + double chi2; // current value of the function to minimize + std::vector<double> parvalues; // vector of minimization parameters + std::vector<std::string> parnames; // names of parameters + + ClassDef(TreeEventFitData,1) }; -#endif // EventFrame_H +#endif // TREEEVENTSTRUCTURE_H diff --git a/App/src/EventFrame.cpp b/App/src/EventFrame.cpp deleted file mode 100644 index e291a06a9b0b09d63ba0cfd5d17f217a2097f48d..0000000000000000000000000000000000000000 --- a/App/src/EventFrame.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "EventFrame.h" - -EventFrame::EventFrame() -{ - clear(); -} - -void EventFrame::clear() -{ - nframe = 0; - alpha_i = 0; - phi_i = 0; - - nphi_f = 0; - phi_f_min = 0; - phi_f_max = 0; - - nalpha_f = 0; - alpha_f_min = 0; - alpha_f_max = 0; - - malpha = 0; - mphi = 0; - npR = 0; - - valpha_f.clear(); - vphi_f.clear(); - vi.clear(); -} diff --git a/App/src/FitSuiteHelper.cpp b/App/src/FitSuiteHelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ae42c0d5233f26a9595eccf0d71022fe79b727ab --- /dev/null +++ b/App/src/FitSuiteHelper.cpp @@ -0,0 +1,114 @@ +#include "FitSuite.h" +#include "FitSuiteHelper.h" +#include "TreeEventStructure.h" +#include "IsGISAXSTools.h" + +#include "TCanvas.h" +#include "TPaveText.h" +#include "ChiSquaredModule.h" +#include "TROOT.h" +#include "TFile.h" +#include "TTree.h" + + +/* ************************************************************************* */ +// 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"); + + 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 << std::endl; + + 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); + gPad->SetLogz(); + IsGISAXSTools::drawOutputDataInPad(*fitSuite->getChiSquaredModule()->getSimulationData(), "CONT4 Z", "current simulated data"); + c1->cd(4); + IsGISAXSTools::drawOutputDataDifference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "CONT4 Z", "difference"); + c1->cd(5); + + TPaveText *pt = new TPaveText(.05,.1,.95,.8); + char str[256]; + sprintf(str,"Iteration %d",m_ncall); + pt->AddText(str); + sprintf(str,"chi2 %e",fitSuite->getChiSquaredModule()->getValue()); + pt->AddText(str); + //pt->AddLine(.0,.5,1.,.5); + 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(); + + m_ncall++; +} + + +/* ************************************************************************* */ +// Save results of each fit iteration to the disk in the form of ROOT tree +/* ************************************************************************* */ +void FitSuiteObserverWriteTree::update(IObservable *subject) +{ + std::string tree_name("FitSuiteTree"); + + FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject); + if( !fitSuite ) throw NullPointerException("FitSuiteObserverWriteTree::update() -> Error! Can't cast FitSuite"); + + // 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) { + top = new TFile(m_file_name.c_str(),"RECREATE"); + } else { + top = new TFile(m_file_name.c_str(),"UPDATE"); + } + if( !top->IsOpen() ) { + throw RuntimeErrorException("FitSuiteObserverWriteTree::update() -> Can't open file "+ m_file_name + " for writing"); + } + + + // data object to write in the tree + TreeEventFitData *event = new TreeEventFitData(); + + // creating new tree + TTree *tree = dynamic_cast<TTree *>(top->Get(tree_name.c_str())); + if( tree == 0) { + // tree doesn't exist due to new file, making new tree + tree = new TTree(tree_name.c_str(),"Oh, my data"); + tree->Branch("Event",&event,16000,2); + } else { + // tree exists, pointing it to the new data + tree->SetBranchAddress("Event", &event); + } + + // filling data object with data from FitSuite + const OutputData<double > *real_data = fitSuite->getChiSquaredModule()->getRealData(); + const OutputData<double > *simu_data = fitSuite->getChiSquaredModule()->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->getChiSquaredModule()->getValue(); + for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { + event->parvalues.push_back( (*it)->getValue() ); + event->parnames.push_back( (*it)->getName().c_str() ); + } + event->niter = m_ncall; + + // appending data to the tree + tree->Fill(); + tree->Write(tree_name.c_str(), TObject::kOverwrite); + 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/FittingHelper.cpp b/App/src/FittingHelper.cpp deleted file mode 100644 index 320daa8cadfbec306d314d94f2caf94a941dc780..0000000000000000000000000000000000000000 --- a/App/src/FittingHelper.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "FittingHelper.h" -#include "FitSuite.h" -#include "IsGISAXSTools.h" - -#include "TCanvas.h" -#include "TPaveText.h" -#include "ChiSquaredModule.h" -#include "TROOT.h" - -void FittingHelper::ObserveAndDraw::update(IObservable *subject) -{ - FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject); - if( !fitSuite ) throw NullPointerException("LocalFitObserver::IObserver() -> 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 << std::endl; - - TCanvas *c1 = dynamic_cast<TCanvas *>( gROOT->FindObject(m_canvas_name.c_str()) ); - if(!c1) throw NullPointerException("LocalFitIbserver::update() -> No access to canvas"); - c1->cd(3); - gPad->SetLogz(); - IsGISAXSTools::drawOutputDataInPad(*fitSuite->getChiSquaredModule()->getSimulationData(), "CONT4 Z", "current simulated data"); - c1->cd(4); - IsGISAXSTools::drawOutputDataDifference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "CONT4 Z", "difference"); - c1->cd(5); - - TPaveText *pt = new TPaveText(.05,.1,.95,.8); - char str[256]; - sprintf(str,"Iteration %d",m_ncall); - pt->AddText(str); - sprintf(str,"chi2 %e",fitSuite->getChiSquaredModule()->getValue()); - pt->AddText(str); - //pt->AddLine(.0,.5,1.,.5); - 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(); - - m_ncall++; -} - - diff --git a/App/src/TestFittingModule.cpp b/App/src/TestFittingModule.cpp index 5068d9771575a2d47ea56f5fecf1b54526b13344..e19dd3e2dbc928fbaff0f4904ce9e21a3558ef87 100644 --- a/App/src/TestFittingModule.cpp +++ b/App/src/TestFittingModule.cpp @@ -12,7 +12,7 @@ #include "FormFactors.h" #include "Exceptions.h" #include "DrawHelper.h" -#include "FittingHelper.h" +#include "FitSuiteHelper.h" #include "IObserver.h" #include "FitSuite.h" @@ -80,10 +80,14 @@ void TestFittingModule::execute() fitSuite->addFitParameter("/MultiLayer/Layer0/thickness", 12*Units::nanometer, 1*Units::nanometer, TRange<double>(1.0, 20.0) ); fitSuite->addFitParameter("*/FormFactorCylinder/radius", 2*Units::nanometer, 1*Units::nanometer, TRange<double>(1.0, 20.0) ); - FittingHelper::ObserveAndDraw *observer = new FittingHelper::ObserveAndDraw(canvas_name); - fitSuite->attachObserver(observer); + FitSuiteObserverDraw *drawObserver = new FitSuiteObserverDraw(canvas_name); + fitSuite->attachObserver(drawObserver); + FitSuiteObserverWriteTree *writeObserver = new FitSuiteObserverWriteTree("fitsuite.root"); + fitSuite->attachObserver(writeObserver); fitSuite->runFit(); + delete drawObserver; + delete writeObserver; std::cout << "------ RESULTS ---------" << std::endl; std::cout << "FitSuite > MinValue:" << fitSuite->getMinimizer()->getMinValue() << " " << fitSuite->getMinimizer()->getValueOfVariableAtMinimum(0) << std::endl; diff --git a/App/src/TestMesoCrystal2.cpp b/App/src/TestMesoCrystal2.cpp index 3e94b822e9f1a568aefd591bc8a16fb0f97db9d0..af309a4ad91e1c23131bdfef323d8df2cb9f427c 100644 --- a/App/src/TestMesoCrystal2.cpp +++ b/App/src/TestMesoCrystal2.cpp @@ -24,7 +24,7 @@ #include "SampleFactory.h" #include "FitMultiParameter.h" #include "TRange.h" -#include "FittingHelper.h" +#include "FitSuiteHelper.h" #include "TCanvas.h" #include "TH2D.h" @@ -83,9 +83,9 @@ void TestMesoCrystal2::execute() fitSuite->setMinimizer( new ROOTMinimizer("Minuit2", "Migrad") ); fitSuite->addFitParameter("/MultiLayer/LayerInterface1/roughness/sigma", 0.1, 0.05, TRange<double>(0.0, 10.0) ); - FittingHelper::ObserveAndDraw *observer = new FittingHelper::ObserveAndDraw(canvas_name); - fitSuite->attachObserver(observer); - + FitSuiteObserverDraw *drawObserver = new FitSuiteObserverDraw(canvas_name); + fitSuite->attachObserver(drawObserver); +\ fitSuite->runFit(); for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) { diff --git a/App/src/TestRootTree.cpp b/App/src/TestRootTree.cpp index a2b7ddea02c4d2be3063fe77211ba20dc0c9bb1d..1b0c907d2cb7ce7171e9e6277dc7e1439a3a5abb 100644 --- a/App/src/TestRootTree.cpp +++ b/App/src/TestRootTree.cpp @@ -16,7 +16,7 @@ #include "TRandom.h" #include "TCanvas.h" #include "IsGISAXSTools.h" -#include "EventFrame.h" +#include "TreeEventStructure.h" #include "TestMesoCrystal1.h" #include <vector> @@ -71,7 +71,7 @@ void TestRootTree::complex_write() // creating new tree TTree *tree = new TTree(tree_name.c_str(),"Oh, my data"); - EventFrame *event = new EventFrame(); + TreeEventOutputData *event = new TreeEventOutputData(); tree->Branch("Event",&event,16000,2); // preparing set of meso parameters to simulate @@ -181,7 +181,8 @@ void TestRootTree::complex_read() throw RuntimeErrorException("TestRootTree::complex_read() -> Can't get tree with name '" + tree_name + "' from root file"); } - EventFrame *event = 0; + TreeEventOutputData *event = 0; + tree->SetBranchAddress("Event", &event); // reading data from the tree diff --git a/App/src/TreeEventStructure.cpp b/App/src/TreeEventStructure.cpp new file mode 100644 index 0000000000000000000000000000000000000000..15fcebc5e99c62ca3a90f310c9d7b7bdc259afe6 --- /dev/null +++ b/App/src/TreeEventStructure.cpp @@ -0,0 +1,57 @@ +#include "TreeEventStructure.h" + + +/* ************************************************************************* */ +// Output data +/* ************************************************************************* */ +TreeEventOutputData::TreeEventOutputData() +{ + clear(); +} + + +void TreeEventOutputData::clear() +{ + nframe = 0; + alpha_i = 0; + phi_i = 0; + + nphi_f = 0; + phi_f_min = 0; + phi_f_max = 0; + + nalpha_f = 0; + alpha_f_min = 0; + alpha_f_max = 0; + + malpha = 0; + mphi = 0; + npR = 0; + + valpha_f.clear(); + vphi_f.clear(); + vi.clear(); +} + + +/* ************************************************************************* */ +// Fit data +/* ************************************************************************* */ +TreeEventFitData::TreeEventFitData() +{ + clear(); +} + +void TreeEventFitData::clear() +{ + niter = 0; + real_data.clear(); + fit_data.clear(); + diff.clear(); + axis0.clear(); + axis1.clear(); + chi2=0; + parvalues.clear(); + parnames.clear(); +} + diff --git a/App/src/main.cpp b/App/src/main.cpp index f7edbe472b3dbe49a33fde3e7a534b095744fa84..3f253b35fdf25e9a58e6318c3a52e3d86bd6cc84 100644 --- a/App/src/main.cpp +++ b/App/src/main.cpp @@ -1,16 +1,18 @@ #include "FunctionalTestFactory.h" #include "DrawHelper.h" -#include "CommandLine.h" -#include "Utils.h" +//#include "CommandLine.h" +//#include "Utils.h" #include <iostream> #include <string> #include "TROOT.h" #include "TApplication.h" #include "ProgramOptions.h" -#include "AppOptionsDescription.h" -#include "Macros.h" -#include "GISASExperiment.h" +//#include "AppOptionsDescription.h" +//#include "Macros.h" +//#include "GISASExperiment.h" + + int main(int argc, char **argv) { diff --git a/Core/Core.pro b/Core/Core.pro index 3d2da50907160d0b96c5dc1d59d61b790db3e588..d42095ce000df524d8687902e709e6339d27d4e0 100644 --- a/Core/Core.pro +++ b/Core/Core.pro @@ -110,7 +110,8 @@ SOURCES += \ PythonAPI/src/PythonListConverter.cpp \ PythonAPI/src/PythonModule.cpp \ PythonAPI/src/PythonPlusplusHelper.cpp \ - PythonAPI/src/PythonOutputData.cpp + PythonAPI/src/PythonOutputData.cpp \ + Tools/src/IObserver.cpp HEADERS += \ Algorithms/inc/Beam.h \ diff --git a/Core/Tools/inc/IObserver.h b/Core/Tools/inc/IObserver.h index 509ee6849ee97c5e03100f51e7367dc50a712895..5d4abff69a503a7015fb3bd8c58ae263bfa90ebf 100644 --- a/Core/Tools/inc/IObserver.h +++ b/Core/Tools/inc/IObserver.h @@ -25,11 +25,16 @@ class IObservable; //- ------------------------------------------------------------------- class IObserver { public: - virtual ~IObserver(){} - //! method which is used by observable object to notify change in status + //! destructor detach observer from observed subject + virtual ~IObserver(); + //! method which is used by observable subject to notify change in status virtual void update (IObservable *subject) = 0; + //! set pointer to observed subject + virtual void setObservedSubject(IObservable *subject); protected: - IObserver(){} + IObserver() : m_observed_subject(0) {} +private: + IObservable *m_observed_subject; }; @@ -44,18 +49,13 @@ public: virtual ~IObservable(){} //! attach observer to the list of observers - virtual void attachObserver(IObserver *obj) { m_observers.push_back(obj); } + virtual void attachObserver(IObserver *obj); //! detach observer from observers list - virtual void detachObserver(IObserver *obj) { m_observers.remove(obj); } + virtual void detachObserver(IObserver *obj); //! notify observers about change in status - virtual void notifyObservers() - { - for(observers_t::iterator it = m_observers.begin(); it!=m_observers.end(); ++it) { - (*it)->update(this); - } - } + virtual void notifyObservers(); protected: IObservable(){} diff --git a/Core/Tools/src/IObserver.cpp b/Core/Tools/src/IObserver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42c874f96cda01f81728499c9c775d96b48cc544 --- /dev/null +++ b/Core/Tools/src/IObserver.cpp @@ -0,0 +1,43 @@ +#include "IObserver.h" + + + +/* ************************************************************************* */ +// Observer +/* ************************************************************************* */ +IObserver::~IObserver() +{ + if(m_observed_subject) m_observed_subject->detachObserver(this); +} + + +void IObserver::setObservedSubject(IObservable *subject) +{ + m_observed_subject = subject; +} + + + +/* ************************************************************************* */ +// Observable +/* ************************************************************************* */ +void IObservable::attachObserver(IObserver *obj) +{ + obj->setObservedSubject(this); + m_observers.push_back(obj); +} + + +void IObservable::detachObserver(IObserver *obj) +{ + m_observers.remove(obj); +} + + +void IObservable::notifyObservers() +{ + for(observers_t::iterator it = m_observers.begin(); it!=m_observers.end(); ++it) { + (*it)->update(this); + } +} + diff --git a/Examples/Analysis/RootMacros/README b/Examples/Analysis/RootMacros/README new file mode 100644 index 0000000000000000000000000000000000000000..d5c6dc996c4333d18c1dd23b8eac05327f8869ed --- /dev/null +++ b/Examples/Analysis/RootMacros/README @@ -0,0 +1,9 @@ +Directory contains exmpales with ROOT analysis macros + +ex01_MesoGif - analysis of the data produced by TestRootTree +ex02_ReadFitData - analysis of the data produced by TestFittingModule + + + +To clean remainings from ROOT session +rm -f */*.so */*.d */*~ diff --git a/Examples/Analysis/MesoData/MesoData.C b/Examples/Analysis/RootMacros/ex01_MesoGif/MesoData.C similarity index 100% rename from Examples/Analysis/MesoData/MesoData.C rename to Examples/Analysis/RootMacros/ex01_MesoGif/MesoData.C diff --git a/Examples/Analysis/MesoData/MesoData.h b/Examples/Analysis/RootMacros/ex01_MesoGif/MesoData.h similarity index 100% rename from Examples/Analysis/MesoData/MesoData.h rename to Examples/Analysis/RootMacros/ex01_MesoGif/MesoData.h diff --git a/Examples/Analysis/MesoData/analysis1.C b/Examples/Analysis/RootMacros/ex01_MesoGif/analysis1.C similarity index 100% rename from Examples/Analysis/MesoData/analysis1.C rename to Examples/Analysis/RootMacros/ex01_MesoGif/analysis1.C diff --git a/Examples/Analysis/MesoData/analysis2.C b/Examples/Analysis/RootMacros/ex01_MesoGif/analysis2.C similarity index 100% rename from Examples/Analysis/MesoData/analysis2.C rename to Examples/Analysis/RootMacros/ex01_MesoGif/analysis2.C diff --git a/Examples/Analysis/RootMacros/ex02_ReadFitData/FitData.C b/Examples/Analysis/RootMacros/ex02_ReadFitData/FitData.C new file mode 100644 index 0000000000000000000000000000000000000000..84e6e5e8fbb413f2cdac35bc12bb151affcd0e0f --- /dev/null +++ b/Examples/Analysis/RootMacros/ex02_ReadFitData/FitData.C @@ -0,0 +1,43 @@ +#define FitData_cxx +#include "FitData.h" +#include <TH2.h> +#include <TStyle.h> +#include <TCanvas.h> + +void FitData::Loop() +{ +// In a ROOT session, you can do: +// Root > .L FitData.C +// Root > FitData t +// Root > t.GetEntry(12); // Fill t data members with entry number 12 +// Root > t.Show(); // Show values of entry 12 +// Root > t.Show(16); // Read and show values of entry 16 +// Root > t.Loop(); // Loop on all entries +// + +// This is the loop skeleton where: +// jentry is the global entry number in the chain +// ientry is the entry number in the current Tree +// Note that the argument to GetEntry must be: +// jentry for TChain::GetEntry +// ientry for TTree::GetEntry and TBranch::GetEntry +// +// To read only selected branches, Insert statements like: +// METHOD1: +// fChain->SetBranchStatus("*",0); // disable all branches +// fChain->SetBranchStatus("branchname",1); // activate branchname +// METHOD2: replace line +// fChain->GetEntry(jentry); //read all branches +//by b_branchname->GetEntry(ientry); //read only this branch + if (fChain == 0) return; + + Long64_t nentries = fChain->GetEntriesFast(); + + Long64_t nbytes = 0, nb = 0; + for (Long64_t jentry=0; jentry<nentries;jentry++) { + Long64_t ientry = LoadTree(jentry); + if (ientry < 0) break; + nb = fChain->GetEntry(jentry); nbytes += nb; + // if (Cut(ientry) < 0) continue; + } +} diff --git a/Examples/Analysis/RootMacros/ex02_ReadFitData/FitData.h b/Examples/Analysis/RootMacros/ex02_ReadFitData/FitData.h new file mode 100644 index 0000000000000000000000000000000000000000..f8875b1b44c67934d1a65d7e00d4f9a0f221b8b8 --- /dev/null +++ b/Examples/Analysis/RootMacros/ex02_ReadFitData/FitData.h @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////// +// This class has been automatically generated on +// Wed Oct 10 15:14:35 2012 by ROOT version 5.34/01 +// from TTree FitSuiteTree/Oh, my data +// found on file: ../../../../fitsuite.root +////////////////////////////////////////////////////////// + +#ifndef FitData_h +#define FitData_h + +#include <TROOT.h> +#include <TChain.h> +#include <TFile.h> + +// Header file for the classes stored in the TTree if any. + +// Fixed size dimensions of array or collections stored in the TTree if any. + +class FitData { +public : + TTree *fChain; //!pointer to the analyzed TTree or TChain + Int_t fCurrent; //!current Tree number in a TChain + + // Declaration of leaf types + //TreeEventFitData *Event; + Int_t niter; + vector<vector<double> > real_data; + vector<vector<double> > fit_data; + vector<vector<double> > diff; + vector<vector<double> > axis0; + vector<vector<double> > axis1; + Double_t chi2; + vector<double> params; + vector<string> parnames; + + // List of branches + TBranch *b_Event_niter; //! + TBranch *b_Event_real_data; //! + TBranch *b_Event_fit_data; //! + TBranch *b_Event_diff; //! + TBranch *b_Event_axis0; //! + TBranch *b_Event_axis1; //! + TBranch *b_Event_chi2; //! + TBranch *b_Event_params; //! + TBranch *b_Event_parnames; //! + + FitData(TTree *tree=0); + virtual ~FitData(); + virtual Int_t Cut(Long64_t entry); + virtual Int_t GetEntry(Long64_t entry); + virtual Long64_t LoadTree(Long64_t entry); + virtual void Init(TTree *tree); + virtual void Loop(); + virtual Bool_t Notify(); + virtual void Show(Long64_t entry = -1); +}; + +#endif + +#ifdef FitData_cxx +FitData::FitData(TTree *tree) : fChain(0) +{ +// if parameter tree is not specified (or zero), connect the file +// used to generate this class and read the Tree. + if (tree == 0) { + TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("../../../../fitsuite.root"); + if (!f || !f->IsOpen()) { + f = new TFile("../../../../fitsuite.root"); + } + f->GetObject("FitSuiteTree",tree); + + } + Init(tree); +} + +FitData::~FitData() +{ + if (!fChain) return; + delete fChain->GetCurrentFile(); +} + +Int_t FitData::GetEntry(Long64_t entry) +{ +// Read contents of entry. + if (!fChain) return 0; + return fChain->GetEntry(entry); +} +Long64_t FitData::LoadTree(Long64_t entry) +{ +// Set the environment to read one entry + if (!fChain) return -5; + Long64_t centry = fChain->LoadTree(entry); + if (centry < 0) return centry; + if (fChain->GetTreeNumber() != fCurrent) { + fCurrent = fChain->GetTreeNumber(); + Notify(); + } + return centry; +} + +void FitData::Init(TTree *tree) +{ + // The Init() function is called when the selector needs to initialize + // a new tree or chain. Typically here the branch addresses and branch + // pointers of the tree will be set. + // It is normally not necessary to make changes to the generated + // code, but the routine can be extended by the user if needed. + // Init() will be called many times when running on PROOF + // (once per file to be processed). + + // Set branch addresses and branch pointers + if (!tree) return; + fChain = tree; + fCurrent = -1; + fChain->SetMakeClass(1); + + fChain->SetBranchAddress("niter", &niter, &b_Event_niter); + fChain->SetBranchAddress("real_data", &real_data, &b_Event_real_data); + fChain->SetBranchAddress("fit_data", &fit_data, &b_Event_fit_data); + fChain->SetBranchAddress("diff", &diff, &b_Event_diff); + fChain->SetBranchAddress("axis0", &axis0, &b_Event_axis0); + fChain->SetBranchAddress("axis1", &axis1, &b_Event_axis1); + fChain->SetBranchAddress("chi2", &chi2, &b_Event_chi2); + fChain->SetBranchAddress("params", ¶ms, &b_Event_params); + fChain->SetBranchAddress("parnames", &parnames, &b_Event_parnames); + Notify(); +} + +Bool_t FitData::Notify() +{ + // The Notify() function is called when a new file is opened. This + // can be either for a new TTree in a TChain or when when a new TTree + // is started when using PROOF. It is normally not necessary to make changes + // to the generated code, but the routine can be extended by the + // user if needed. The return value is currently not used. + + return kTRUE; +} + +void FitData::Show(Long64_t entry) +{ +// Print contents of entry. +// If entry is not specified, print current entry + if (!fChain) return; + fChain->Show(entry); +} +Int_t FitData::Cut(Long64_t entry) +{ +// This function may be called from Loop. +// returns 1 if entry is accepted. +// returns -1 otherwise. + return 1; +} +#endif // #ifdef FitData_cxx diff --git a/Examples/Analysis/RootMacros/ex02_ReadFitData/analyse_fitdata1.C b/Examples/Analysis/RootMacros/ex02_ReadFitData/analyse_fitdata1.C new file mode 100644 index 0000000000000000000000000000000000000000..ac1c306b6dcb08e578738149e7657308be198b94 --- /dev/null +++ b/Examples/Analysis/RootMacros/ex02_ReadFitData/analyse_fitdata1.C @@ -0,0 +1,61 @@ +// Simple drawing of fit data stored in the FitSuiteTree using TTree::Draw() method +// (data produced by FitSuiteObserverWriteTree un TestFittingModule) +// Usage: +// +// Way #1 (script mode) +// > root -l analyse_fitdata1.C +// +// Way #2 (precompiled mode) +// > root -l +// > .L analyse_fitdata1.C++ +// analyse_fitdata1() + +#include <iostream> +#include <string> +#include <vector> +#include "TFile.h" +#include "TTree.h" +#include "TCanvas.h" + +#include "FitData.h" + + +void analyse_fitdata1() +{ + const char *file_name ="../../../../fitsuite.root"; + const char *tree_name = "FitSuiteTree"; + + // opening root file + TFile *top = new TFile(file_name,"READ"); + if( !top->IsOpen() ) { + std::cout << "Can't open file '" << file_name << "'" << std::endl; + return; + } + + // access tree stored in the file + TTree *tree = (TTree *) top->Get(tree_name); + if( !tree ) { + std::cout << "Can't get tree '" << tree_name << "'" << std::endl; + return; + } + + TCanvas *c1 = new TCanvas("c1","c1",1024, 768); + c1->Divide(2,2); + + // loop over tree entries and drawing + for(int i=0; i<tree->GetEntries(); i++){ + // defining criteria for Draw method -> it will draw only data corresponding to the event with given number + char criteria[128]; + sprintf(criteria,"Entry$==%d",i); + c1->cd(1); gPad->SetLogz(); + tree->Draw("real_data:axis1:axis0",criteria,"prof COLZ"); + c1->cd(2); gPad->SetLogz(); + tree->Draw("fit_data:axis1:axis0",criteria,"prof COLZ"); + c1->Update(); + } + + + +} + + diff --git a/Examples/Analysis/RootMacros/ex02_ReadFitData/analyse_fitdata2.C b/Examples/Analysis/RootMacros/ex02_ReadFitData/analyse_fitdata2.C new file mode 100644 index 0000000000000000000000000000000000000000..1456163035643bb9af41f3614545bb8270cabc14 --- /dev/null +++ b/Examples/Analysis/RootMacros/ex02_ReadFitData/analyse_fitdata2.C @@ -0,0 +1,103 @@ +// Simple drawing of fit data stored in the FitSuiteTree (using FitData class) +// (data produced by FitSuiteObserverWriteTree un TestFittingModule) +// Usage: +// +// Way #1 (script mode) +// > root -l analyse_fitdata1.C +// +// Way #2 (precompiled mode) +// > root -l +// > .L analyse_fitdata1.C++ +// analyse_fitdata1() + +#include <iostream> +#include <string> +#include <vector> +#include "TFile.h" +#include "TChain.h" +#include "TCanvas.h" +#include "TH2D.h" +#include "TSystem.h" +#include "TPaveText.h" + +using namespace std; +#include "FitData.C" + + +void analyse_fitdata2() +{ + const char *file_name ="../../../../fitsuite.root"; + const char *tree_name = "FitSuiteTree"; + + TChain *chain = new TChain(tree_name); + chain->Add(file_name); + + FitData *event = new FitData(chain); + + // reading first event + chain->GetEntry(0); + + // finding histogram limits + std::vector<double> axis0; + for(size_t i=0; i<event->axis0.size(); ++i) axis0.push_back(event->axis0[i][0]); + std::vector<double> axis1 = event->axis1[0]; + double dphi = (axis0.back()-axis0.front())/double(axis0.size()-1); + double phi1 = axis0.front() - dphi/2.; + double phi2 = axis0.back() + dphi/2.; + double dalpha = (axis1.back()-axis1.front())/double(axis1.size()-1); + double alpha1 = axis1.front() - dalpha/2.; + double alpha2 = axis1.back() + dalpha/2.; + std::cout << "dphi: " << dphi << " phi1:" << phi1 << " phi2:" << phi2 << std::endl; + std::cout << "dalpha: " << dalpha << " alpha1:" << alpha1 << " alpha2:" << alpha2 << std::endl; + + TH2D *myHisto = new TH2D("myHisto","myHisto", axis0.size(), phi1, phi2, axis0.size(), alpha1, alpha2); + myHisto->SetContour(50); + myHisto->SetTitle(""); + myHisto->SetMinimum(1); + myHisto->SetStats(0); + + TCanvas *c1 = new TCanvas("c1","c1",1024, 768); + c1->Divide(2,2); + // loop over entries + int i_entry(0); + while(chain->GetEntry(i_entry++)){ + for(size_t i=0; i<axis0.size(); i++){ + for(size_t j=0; j<axis1.size(); j++) { + myHisto->Fill(event->axis0[i][j], event->axis1[i][j], event->real_data[i][j]); + } + } + c1->cd(1); gPad->SetLogz(); + myHisto->DrawCopy("colz"); + myHisto->Reset(); + for(size_t i=0; i<axis0.size(); i++){ + for(size_t j=0; j<axis1.size(); j++) { + myHisto->Fill(event->axis0[i][j], event->axis1[i][j], event->fit_data[i][j]); + } + } + c1->cd(2); gPad->SetLogz(); + myHisto->DrawCopy("colz"); + myHisto->Reset(); + + // printing parameters + c1->cd(3); + TPaveText *pt = new TPaveText(.05,.1,.95,.8); + char str[256]; + sprintf(str,"Iteration %d",event->niter); + pt->AddText(str); + sprintf(str,"chi2 %e",event->chi2); + pt->AddText(str); + for(size_t i =0; i<event->params.size(); ++i) { + sprintf(str,"%s %f", event->parnames[i].c_str(), event->params[i]); + pt->AddText(str); + } + pt->Draw(); + + c1->Update(); + gSystem->Sleep(5); // wait a bit for smooth animation + } // loop over recorder events + + + +} + + diff --git a/Examples/Analysis/RootMacros/ex02_ReadFitData/make_class.C b/Examples/Analysis/RootMacros/ex02_ReadFitData/make_class.C new file mode 100644 index 0000000000000000000000000000000000000000..1334911927542d664a73fa2456eb255e33eb3ad8 --- /dev/null +++ b/Examples/Analysis/RootMacros/ex02_ReadFitData/make_class.C @@ -0,0 +1,37 @@ +// Generates classes to read ROOT tree from existing ROOT file +// +// Usage: +// Way 1 (script mode): +// > root -l -q .x make_class.C +// Way 2 (precompiled mode): +// > root -l +// > .L make_class.C++ +// > make_class() + + +#include "TFile.h" +#include "TTree.h" +#include <iostream> + +void make_class(const char *file_name ="../../../../fitsuite.root" + ,const char *tree_name = "FitSuiteTree" + ,const char *class_name = "FitData") +{ + + // open root file + TFile *top = new TFile(file_name,"READ"); + + // access to the tree stored in the file + if( !top->IsOpen() ) { + std::cout << "File is absent " << file_name << std::endl; + return; + } + TTree *tree = (TTree *)top->Get(tree_name); + if( !tree ) { + std::cout << "Tree is absent " << tree_name << std::endl; + return; + } + + // generating class files (*.h, *.C) + tree->MakeClass(class_name); +} diff --git a/Examples/Performance/perf_history.txt b/Examples/Performance/perf_history.txt index 78c703f8950592cf82990598551194ecfdb7f175..721c463396b433a3497c9cd0e6ba57cc916c24c5 100644 --- a/Examples/Performance/perf_history.txt +++ b/Examples/Performance/perf_history.txt @@ -120,3 +120,7 @@ # current status of the art (not possible to trace what was changed) 2012-10-08 17:36:40 | jcnsopc73 | macosx64, 2800 MHz | 270270 | 13.986 | 13.8889 | 4.7619 | 2012-10-08 17:37:28 | jcnsopc73 | macosx64, 2800 MHz | 266667 | 13.986 | 13.986 | 4.7619 | +2012-10-09 14:00:42 | jcnsopc73 | macosx64, 2800 MHz | 266667 | 14.1844 | 13.986 | 4.7619 | + + + diff --git a/Macros/GitUtils/gisasfw_loc.png b/Macros/GitUtils/gisasfw_loc.png index 5cccb7fa5df8baea7f69757132fd19cfd486030a..59831b72b9d474f8d4c73429b2be3d0e5acf99db 100644 Binary files a/Macros/GitUtils/gisasfw_loc.png and b/Macros/GitUtils/gisasfw_loc.png differ