Belle II Software development
DQMHistAnalysisEcmsMonObj.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9// Own header.
10#include <dqm/analysis/modules/DQMHistAnalysisEcmsMonObj.h>
11#include <framework/particledb/EvtGenDatabasePDG.h>
12#include <string>
13#include <unordered_map>
14#include <regex>
15
16#include <TROOT.h>
17#include <TRandom.h>
18#include <TH1D.h>
19#include <TLine.h>
20
21#include <RooFitResult.h>
22#include <RooRealVar.h>
23#include <RooDataSet.h>
24#include <RooGaussian.h>
25#include <RooPlot.h>
26#include <RooHist.h>
27#include <RooAddPdf.h>
28#include <RooPolyVar.h>
29#include <RooArgusBG.h>
30#include <RooSimultaneous.h>
31#include <RooCategory.h>
32#include <RooArgSet.h>
33#include <RooConstVar.h>
34
35
36using namespace std;
37using namespace Belle2;
38using namespace RooFit;
39
40//-----------------------------------------------------------------
41// Register module
42//-----------------------------------------------------------------
43
44REG_MODULE(DQMHistAnalysisEcmsMonObj);
45
48{
49 setDescription("Module to monitor Ecms information.");
50 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: Constructor done.");
51}
52
56
58{
60 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: initialized.");
61}
62
64{
65 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: beginRun called.");
66}
67
69{
70 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: event called.");
71}
72
73
74// Plot the resulting fit into the file
75TCanvas* DQMHistAnalysisEcmsMonObjModule::plotArgusFit(RooDataHist* dataE, RooAddPdf& sumB, RooArgusBG& argus, RooGaussian& gauss,
76 RooRealVar& eNow,
77 TString nTag)
78{
79 // switch to the batch mode and store the current setup
80 bool isBatch = gROOT->IsBatch();
81 gROOT->SetBatch(kTRUE);
82
83
84 // --- Plot toy data and composite PDF overlaid ---
85 RooPlot* frame = eNow.frame(40) ;
86 dataE->plotOn(frame) ;
87
88 TString name = (nTag == "B0") ? "B^{0}" : "B^{#pm}";
89 sumB.paramOn(frame, Label(name), Format("TE"), Layout(0.5, 0.8, 0.85));//, Parameters(pars));
90
91
92 sumB.plotOn(frame, Components(argus), LineStyle(kDashed)) ;
93 sumB.plotOn(frame, Components(gauss), LineStyle(kDashed), LineColor(kRed)) ;
94
95 sumB.plotOn(frame);
96
97 frame->GetXaxis()->SetTitleSize(0.0001);
98 frame->GetXaxis()->SetLabelSize(0.0001);
99 frame->SetTitleSize(0.0001);
100 frame->GetYaxis()->SetTitleSize(0.055);
101 frame->GetYaxis()->SetTitleOffset(1.1);
102 frame->GetYaxis()->SetLabelSize(0.05) ;
103
104 frame->SetTitle("");
105
106
107 RooHist* hpull = frame->pullHist() ;
108 hpull->Print();
109 RooPlot* frameRat = eNow.frame(Title("."));
110 frameRat->GetYaxis()->SetTitle("Pull");
111 frameRat->GetYaxis()->CenterTitle();
112 frameRat->GetYaxis()->SetTitleSize(0.13);
113
114 frameRat->GetYaxis()->SetNdivisions(504);
115 frameRat->GetYaxis()->SetLabelSize(0.12);
116 frameRat->GetXaxis()->SetTitleSize(0.12);
117 frameRat->GetXaxis()->SetTitleOffset(1.1);
118 frameRat->GetXaxis()->SetLabelSize(0.12);
119
120 frameRat->GetYaxis()->SetTitleOffset(0.4);
121 frameRat->addPlotable(hpull, "x0 P E1");
122 frameRat->SetMaximum(5.);
123 frameRat->SetMinimum(-5.);
124
125 TCanvas* c1 = new TCanvas(nTag + "_can");
126 TPad* pad = new TPad(nTag + "_pad", "pad", 0, 0.3, 1, 1.0);
127 pad->SetBottomMargin(0.03);
128 pad->SetRightMargin(0.05);
129 pad->SetLeftMargin(0.15);
130 pad->Draw();
131 pad->cd();
132 frame->Draw() ;
133
134
135 TLine* ll = new TLine;
136 double mRev = 10578e-3 / 2; // Optimal collision energy (measured by Roman and Radek)
137 ll->SetLineColor(kGreen);
138 ll->DrawLine(mRev, 0, mRev, frame->GetMaximum());
139
140
141 c1->cd();
142 TPad* padRat = new TPad(nTag + "_padRat", "padRat", 0, 0.00, 1, 0.3);
143 padRat->SetTopMargin(0.04);
144 padRat->SetBottomMargin(0.35);
145 padRat->SetRightMargin(0.05);
146 padRat->SetLeftMargin(0.15);
147 padRat->Draw();
148 padRat->cd();
149 frameRat->Draw() ;
150 c1->Update();
151
152 TLine* l = new TLine(5279.34e-3, 0.0, 5.37, 0.0);
153 l->SetLineColor(kBlue);
154 l->SetLineWidth(3);
155 l->Draw();
156
157 gROOT->SetBatch(isBatch);
158
159 return c1;
160}
161
162
163// Fit the EcmsBB histogram with Gaus+Argus function
164unordered_map<string, double> DQMHistAnalysisEcmsMonObjModule::fitEcmsBB(TH1D* hB0, TH1D* hBp)
165{
166 const double cMBp = EvtGenDatabasePDG::Instance()->GetParticle("B+")->Mass();
167 const double cMB0 = EvtGenDatabasePDG::Instance()->GetParticle("B0")->Mass();
168
169 RooRealVar eNow("eNow", "E^{*}_{B} [GeV]", cMBp, 5.37);
170
171 RooDataHist* dataE0 = new RooDataHist("dataE0hist", "Dataset from histogram", RooArgSet(eNow), hB0);
172 RooDataHist* dataEp = new RooDataHist("dataEphist", "Dataset from histogram", RooArgSet(eNow), hBp);
173
174
175 RooCategory Bcharge("sample", "sample") ;
176 Bcharge.defineType("B0") ;
177 Bcharge.defineType("Bp") ;
178
179 RooDataHist combData("combData", "combined data", eNow, Index(Bcharge), Import("B0", *dataE0), Import("Bp", *dataEp));
180
181
182 // --- Build Gaussian signal PDF ---
183 RooRealVar sigmean("mean", "#mu", 5.29, 5.27, 5.30) ;
184 RooRealVar sigwidth("sigma", "#sigma", 0.00237, 0.0001, 0.030) ;
185
186 RooGaussian gauss("gauss", "gaussian PDF", eNow, sigmean, sigwidth) ;
187
188 // --- Build Argus background PDF ---
189 RooRealVar argpar("Argus_param", "c_{Argus}", -150.7, -300., +50.0) ;
190 RooRealVar endpointBp("EndPointBp", "endPoint parameter", cMBp, 5.27, 5.291) ; //B+ value
191 RooRealVar endpointB0("EndPointB0", "endPoint parameter", cMB0, 5.27, 5.291) ; //B0 value
192 endpointB0.setConstant(kTRUE);
193 endpointBp.setConstant(kTRUE);
194
195
196 //B0 pars
197 RooPolyVar shape2B0("EndPoint2B0", "shape parameter", endpointB0, RooArgSet(RooConst(0.), RooConst(2.)));
198 RooPolyVar eNowDifB0("eNowDifB0", "eNowDifB0", eNow, RooArgSet(shape2B0, RooConst(-1.)));
199 RooArgusBG argusB0("argusB0", "Argus PDF", eNowDifB0, endpointB0, argpar) ;
200
201 //Bp pars
202 RooPolyVar shape2Bp("EndPoint2Bp", "shape parameter", endpointBp, RooArgSet(RooConst(0.), RooConst(2.)));
203 RooPolyVar eNowDifBp("eNowDifBp", "eNowDifBp", eNow, RooArgSet(shape2Bp, RooConst(-1.)));
204 RooArgusBG argusBp("argusBp", "Argus PDF", eNowDifBp, endpointBp, argpar) ;
205
206
207 // --- Construct signal+background PDF ---
208 RooRealVar nsigB0("nsigB0", "N_{sig}^{B^{0}}", 100, 0., 100000) ;
209 RooRealVar nbkgB0("nbkgB0", "N_{bg}", 100, 0., 500000) ;
210
211 RooRealVar nsigBp("nsigBp", "N_{sig}^{B^{#pm}}", 100, 0., 100000) ;
212 RooRealVar nbkgBp("nbkgBp", "N_{bg}", 100, 0., 500000) ;
213
214
215
216 RooAddPdf sumB0("sumB0", "g0+a0", RooArgList(gauss, argusB0), RooArgList(nsigB0, nbkgB0)) ;
217 RooAddPdf sumBp("sumBp", "gP+aP", RooArgList(gauss, argusBp), RooArgList(nsigBp, nbkgBp)) ;
218
219
220 // Construct a simultaneous pdf using category sample as index
221 RooSimultaneous simPdf("simPdf", "simultaneous pdf", Bcharge) ;
222
223
224 // Associate model with the physics state and model_ctl with the control state
225 simPdf.addPdf(sumB0, "B0") ;
226 simPdf.addPdf(sumBp, "Bp") ;
227
228
229 simPdf.fitTo(combData);
230
231 // Plot the results into the Canvas
232 m_canvas = new TCanvas("ecms", "ecms", 1500, 800);
233 TCanvas* c0 = plotArgusFit(dataE0, sumB0, argusB0, gauss, eNow, "B0");
234 TCanvas* cp = plotArgusFit(dataEp, sumBp, argusBp, gauss, eNow, "Bp");
235
236 m_canvas->cd();
237 m_canvas->Divide(2, 1);
238
239 m_canvas->cd(1);
240 for (auto obj : *cp->GetListOfPrimitives()) obj->DrawClone();
241 m_canvas->cd(2);
242 for (auto obj : *c0->GetListOfPrimitives()) obj->DrawClone();
243
244 // Go back to the main cBase canvas
245 m_canvas->cd();
246 m_monObj->addCanvas(m_canvas);
247
248
249 // Delete RooFit objects
250 delete dataE0;
251 delete dataEp;
252
253
254 return {{"EcmsBBcnt", 2 * sigmean.getValV()}, {"EcmsBBcntUnc", 2 * sigmean.getError()},
255 {"EcmsBBspread", 2 * sigwidth.getValV()}, {"EcmsBBspreadUnc", 2 * sigwidth.getError()}, {"EcmsBBnsigB0", nsigB0.getValV()}, {"EcmsBBnsigB0Unc", nsigB0.getError()}, {"EcmsBBnsigBp", nsigBp.getValV()}, {"EcmsBBnsigBpUnc", nsigBp.getError()}};
256}
257
258unordered_map<string, double> DQMHistAnalysisEcmsMonObjModule::parseTitle(const std::string& title)
259{
260 std::regex re(R"(exp\s+(\d+)\s+run\s+(\d+).*?=\s*([\d.]+))");
261 std::smatch m;
262 double exp = 0;
263 double run = 0;
264 double lumi = -1.;
265 if (std::regex_search(title, m, re)) {
266 exp = std::stoi(m[1]);
267 run = std::stoi(m[2]);
268 lumi = std::stod(m[3]);
269 }
270 return {{"exp", exp}, {"run", run}, {"lumi", lumi}};
271}
272
273
275{
276 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: endRun called.");
277
278 auto* hB0 = (TH1D*)findHist("PhysicsObjectsMiraBelleEcmsBB/hB0");
279 auto* hBp = (TH1D*)findHist("PhysicsObjectsMiraBelleEcmsBB/hBp");
280 if (hB0 == nullptr || hBp == nullptr) return;
281
282 auto res = fitEcmsBB(hB0, hBp);
283
284 auto tit = parseTitle(std::string(hB0->GetTitle()));
285
286 m_monObj->setVariable("EcmsBBcnt", res.at("EcmsBBcnt"), res.at("EcmsBBcntUnc"));
287 m_monObj->setVariable("EcmsBBspread", res.at("EcmsBBspread"), res.at("EcmsBBspreadUnc"));
288 if (tit.at("lumi") > 1.) {
289 m_monObj->setVariable("EcmsBBnsigB0", res.at("EcmsBBnsigB0") / tit.at("lumi"), res.at("EcmsBBnsigB0Unc") / tit.at("lumi"));
290 m_monObj->setVariable("EcmsBBnsigBp", res.at("EcmsBBnsigBp") / tit.at("lumi"), res.at("EcmsBBnsigBpUnc") / tit.at("lumi"));
291 }
292
293 m_monObj->setVariable("EcmsBBcnt_firstExp", tit.at("exp"));
294 m_monObj->setVariable("EcmsBBcnt_firstRun", tit.at("run"));
295
296}
297
299{
300
301 B2DEBUG(20, "terminate called");
302}
303
void initialize() override final
Initialize the Module.
TCanvas * plotArgusFit(RooDataHist *dataE0, RooAddPdf &sumB0, RooArgusBG &argus, RooGaussian &gauss, RooRealVar &eNow, TString nTag="")
Plot the fit and return TCanvas with the plot.
std::unordered_map< std::string, double > fitEcmsBB(TH1D *hB0, TH1D *hBp)
Fit the histograms and return the fitted parameters.
TCanvas * m_canvas
Canvas to keep plots of the fit.
MonitoringObject * m_monObj
monitoring object
void terminate() override final
Termination action.
void event() override final
This method is called for each event.
void endRun() override final
End-of-run action.
std::unordered_map< std::string, double > parseTitle(const std::string &title)
Reads first exp.run number and integrated lumi from merged histogram title.
void beginRun() override final
Called when entering a new run.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
DQMHistAnalysisModule()
Constructor / Destructor.
static EvtGenDatabasePDG * Instance()
Instance method that loads the EvtGen table.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.