// Standard #include #include using namespace std; // ROOT #include "TH1.h" #include "TCanvas.h" #include "TMath.h" #include "TRandom.h" #include "TThread.h" #include "Math/WrappedTF1.h" #include "Math/WrappedMultiTF1.h" #include "Fit/BinData.h" #include "Fit/UnBinData.h" #include "HFitInterface.h" #include "Fit/Fitter.h" /******************************************************************************/ class ParallelFitter { public: /// Default constructor ParallelFitter() { m_NThreads = 4; } /// Default destructor ~ParallelFitter() {}; /// Analyze what eveer needs to be analyzed... bool Analyze(); //! In this function the parallel calibration happens bool CalibrateParallel(unsigned int ThreadID); private: //! Input: some histograms vector m_Histograms; //! Output: Mean of the fitted Gaussian vector m_Means; //! Output: Sigma of the fitted Gaussian vector m_Sigmas; //! Number of threads unsigned int m_NThreads; //! Storing the threads: vector m_Threads; //! Storing a flag that the thread is running vector m_ThreadIsInitialized; //! Storing a flag that the thread is finished vector m_ThreadIsFinished; //! ID of the next item to be processed unsigned int m_ThreadNextItem; }; /****************************************************************************** * This function encapsulates the information transfered into the thread */ class ThreadCaller { public: //! Standard constructor ThreadCaller(ParallelFitter* M, unsigned int ThreadID) { m_Fitter = M; m_ThreadID = ThreadID; } //! Return the calling class ParallelFitter* GetThreadCaller() { return m_Fitter; } //! Return the thread ID unsigned int GetThreadID() { return m_ThreadID; } private: //! Store the calling class for retrieval ParallelFitter* m_Fitter; //! ID of the worker thread unsigned int m_ThreadID; }; /****************************************************************************** * Thread entry point for the parallel calibration */ void CallParallelCalibrationThread(void* Address) { ParallelFitter* P = ((ThreadCaller*) Address)->GetThreadCaller(); P->CalibrateParallel(((ThreadCaller*) Address)->GetThreadID()); } /****************************************************************************** * The fit function - Gaus */ class Gaus : public ROOT::Math::IParamFunction { public: void SetParameters(const double *p) { std::copy(p,p+NPar(),fp);} const double* Parameters() const { return fp; } ROOT::Math::IGenFunction * Clone() const { Gaus* g = new Gaus(); g->SetParameters(fp); return g; }; unsigned int NPar() const { return 4; } private: double DoEvalPar(double x, const double* par) const { double fitval = par[0]; double arg = 0; if (par[3] != 0) arg = (x - par[2])/par[3]; fitval += par[1]*TMath::Exp(-0.5*arg*arg); return fitval; } double fp[4]; }; /****************************************************************************** * Do whatever analysis is necessary */ bool ParallelFitter::Analyze() { int Bins = 10000; // Create the list of histograms: unsigned int Histograms = 1000; for (unsigned int h = 0; h < Histograms; ++h) { TH1D* Hist = new TH1D("", "Hist", 100, -10, 10); for (int i = 0; i < Bins; ++i) { Hist->Fill(gRandom->Gaus(0, 1)); } m_Histograms.push_back(Hist); m_Sigmas.push_back(-999); m_Means.push_back(-999); } m_ThreadNextItem = 0; m_Threads.resize(m_NThreads); m_ThreadIsInitialized.resize(m_NThreads); m_ThreadIsFinished.resize(m_NThreads); if (m_NThreads > 1) { // Start threads for (unsigned int t = 0; t < m_NThreads; ++t) { TString Name = "Calibration thread #"; Name += t; cout<<"Creating thread: "<Run(); TThread::Sleep(0, 100000000); // Wait until thread is initialized: while (m_ThreadIsInitialized[t] == false && m_ThreadIsFinished[t] == false) { // Sleep for a while... TThread::Sleep(0, 10000000); } cout<Kill(); m_Threads[t] = 0; } cout<<"All threads have finished..."<Fill(m_Means[i]); } TCanvas* C = new TCanvas(); C->cd(); Means->Draw(); C->Update(); return true; } /****************************************************************************** * Perform the parallel calibration */ bool ParallelFitter::CalibrateParallel(unsigned int ThreadID) { cout<<"Calibrate parallel for thread #"<= m_Histograms.size()) break; cout<<"Thread "<