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
54{
56 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: initialized.");
57}
58
60{
61 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: beginRun called.");
62}
63
65{
66 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: event called.");
67}
68
69
70// Plot the resulting fit into the file
71TCanvas* DQMHistAnalysisEcmsMonObjModule::plotArgusFit(RooDataHist* dataE, RooAddPdf& sumB, RooArgusBG& argus, RooGaussian& gauss,
72 RooRealVar& eNow,
73 TString nTag)
74{
75 // switch to the batch mode and store the current setup
76 bool isBatch = gROOT->IsBatch();
77 gROOT->SetBatch(kTRUE);
78
79
80 // --- Plot toy data and composite PDF overlaid ---
81 RooPlot* frame = eNow.frame(40) ;
82 dataE->plotOn(frame) ;
83
84 TString name = (nTag == "B0") ? "B^{0}" : "B^{#pm}";
85 sumB.paramOn(frame, Label(name), Format("TE"), Layout(0.5, 0.8, 0.85));//, Parameters(pars));
86
87
88 sumB.plotOn(frame, Components(argus), LineStyle(kDashed)) ;
89 sumB.plotOn(frame, Components(gauss), LineStyle(kDashed), LineColor(kRed)) ;
90
91 sumB.plotOn(frame);
92
93 frame->GetXaxis()->SetTitleSize(0.0001);
94 frame->GetXaxis()->SetLabelSize(0.0001);
95 frame->SetTitleSize(0.0001);
96 frame->GetYaxis()->SetTitleSize(0.055);
97 frame->GetYaxis()->SetTitleOffset(1.1);
98 frame->GetYaxis()->SetLabelSize(0.05) ;
99
100 frame->SetTitle("");
101
102
103 RooHist* hpull = frame->pullHist() ;
104 hpull->Print();
105 RooPlot* frameRat = eNow.frame(Title("."));
106 frameRat->GetYaxis()->SetTitle("Pull");
107 frameRat->GetYaxis()->CenterTitle();
108 frameRat->GetYaxis()->SetTitleSize(0.13);
109
110 frameRat->GetYaxis()->SetNdivisions(504);
111 frameRat->GetYaxis()->SetLabelSize(0.12);
112 frameRat->GetXaxis()->SetTitleSize(0.12);
113 frameRat->GetXaxis()->SetTitleOffset(1.1);
114 frameRat->GetXaxis()->SetLabelSize(0.12);
115
116 frameRat->GetYaxis()->SetTitleOffset(0.4);
117 frameRat->addPlotable(hpull, "x0 P E1");
118 frameRat->SetMaximum(5.);
119 frameRat->SetMinimum(-5.);
120
121 TCanvas* c1 = new TCanvas(nTag + "_can");
122 TPad* pad = new TPad(nTag + "_pad", "pad", 0, 0.3, 1, 1.0);
123 pad->SetBottomMargin(0.03);
124 pad->SetRightMargin(0.05);
125 pad->SetLeftMargin(0.15);
126 pad->Draw();
127 pad->cd();
128 frame->Draw() ;
129
130
131 TLine* ll = new TLine;
132 double mRev = 10578e-3 / 2; // Optimal collision energy (measured by Roman and Radek)
133 ll->SetLineColor(kGreen);
134 ll->DrawLine(mRev, 0, mRev, frame->GetMaximum());
135
136
137 c1->cd();
138 TPad* padRat = new TPad(nTag + "_padRat", "padRat", 0, 0.00, 1, 0.3);
139 padRat->SetTopMargin(0.04);
140 padRat->SetBottomMargin(0.35);
141 padRat->SetRightMargin(0.05);
142 padRat->SetLeftMargin(0.15);
143 padRat->Draw();
144 padRat->cd();
145 frameRat->Draw() ;
146 c1->Update();
147
148 TLine* l = new TLine(5279.34e-3, 0.0, 5.37, 0.0);
149 l->SetLineColor(kBlue);
150 l->SetLineWidth(3);
151 l->Draw();
152
153 gROOT->SetBatch(isBatch);
154
155 return c1;
156}
157
158
159// Fit the EcmsBB histogram with Gaus+Argus function
160unordered_map<string, double> DQMHistAnalysisEcmsMonObjModule::fitEcmsBB(TH1D* hB0, TH1D* hBp)
161{
162 const double cMBp = EvtGenDatabasePDG::Instance()->GetParticle("B+")->Mass();
163 const double cMB0 = EvtGenDatabasePDG::Instance()->GetParticle("B0")->Mass();
164
165 RooRealVar eNow("eNow", "E^{*}_{B} [GeV]", cMBp, 5.37);
166
167 RooDataHist* dataE0 = new RooDataHist("dataE0hist", "Dataset from histogram", RooArgSet(eNow), hB0);
168 RooDataHist* dataEp = new RooDataHist("dataEphist", "Dataset from histogram", RooArgSet(eNow), hBp);
169
170
171 RooCategory Bcharge("sample", "sample") ;
172 Bcharge.defineType("B0") ;
173 Bcharge.defineType("Bp") ;
174
175 RooDataHist combData("combData", "combined data", eNow, Index(Bcharge), Import("B0", *dataE0), Import("Bp", *dataEp));
176
177
178 // --- Build Gaussian signal PDF ---
179 RooRealVar sigmean("mean", "#mu", 5.29, 5.27, 5.30) ;
180 RooRealVar sigwidth("sigma", "#sigma", 0.00237, 0.0001, 0.030) ;
181
182 RooGaussian gauss("gauss", "gaussian PDF", eNow, sigmean, sigwidth) ;
183
184 // --- Build Argus background PDF ---
185 RooRealVar argpar("Argus_param", "c_{Argus}", -150.7, -300., +50.0) ;
186 RooRealVar endpointBp("EndPointBp", "endPoint parameter", cMBp, 5.27, 5.291) ; //B+ value
187 RooRealVar endpointB0("EndPointB0", "endPoint parameter", cMB0, 5.27, 5.291) ; //B0 value
188 endpointB0.setConstant(kTRUE);
189 endpointBp.setConstant(kTRUE);
190
191
192 //B0 pars
193 RooPolyVar shape2B0("EndPoint2B0", "shape parameter", endpointB0, RooArgSet(RooConst(0.), RooConst(2.)));
194 RooPolyVar eNowDifB0("eNowDifB0", "eNowDifB0", eNow, RooArgSet(shape2B0, RooConst(-1.)));
195 RooArgusBG argusB0("argusB0", "Argus PDF", eNowDifB0, endpointB0, argpar) ;
196
197 //Bp pars
198 RooPolyVar shape2Bp("EndPoint2Bp", "shape parameter", endpointBp, RooArgSet(RooConst(0.), RooConst(2.)));
199 RooPolyVar eNowDifBp("eNowDifBp", "eNowDifBp", eNow, RooArgSet(shape2Bp, RooConst(-1.)));
200 RooArgusBG argusBp("argusBp", "Argus PDF", eNowDifBp, endpointBp, argpar) ;
201
202
203 // --- Construct signal+background PDF ---
204 RooRealVar nsigB0("nsigB0", "N_{sig}^{B^{0}}", 100, 0., 100000) ;
205 RooRealVar nbkgB0("nbkgB0", "N_{bg}", 100, 0., 500000) ;
206
207 RooRealVar nsigBp("nsigBp", "N_{sig}^{B^{#pm}}", 100, 0., 100000) ;
208 RooRealVar nbkgBp("nbkgBp", "N_{bg}", 100, 0., 500000) ;
209
210
211
212 RooAddPdf sumB0("sumB0", "g0+a0", RooArgList(gauss, argusB0), RooArgList(nsigB0, nbkgB0)) ;
213 RooAddPdf sumBp("sumBp", "gP+aP", RooArgList(gauss, argusBp), RooArgList(nsigBp, nbkgBp)) ;
214
215
216 // Construct a simultaneous pdf using category sample as index
217 RooSimultaneous simPdf("simPdf", "simultaneous pdf", Bcharge) ;
218
219
220 // Associate model with the physics state and model_ctl with the control state
221 simPdf.addPdf(sumB0, "B0") ;
222 simPdf.addPdf(sumBp, "Bp") ;
223
224
225 simPdf.fitTo(combData);
226
227 // Plot the results into the Canvas
228 m_canvas = new TCanvas("ecms", "ecms", 1500, 800);
229 TCanvas* c0 = plotArgusFit(dataE0, sumB0, argusB0, gauss, eNow, "B0");
230 TCanvas* cp = plotArgusFit(dataEp, sumBp, argusBp, gauss, eNow, "Bp");
231
232 m_canvas->cd();
233 m_canvas->Divide(2, 1);
234
235 m_canvas->cd(1);
236 for (auto obj : *cp->GetListOfPrimitives()) obj->DrawClone();
237 m_canvas->cd(2);
238 for (auto obj : *c0->GetListOfPrimitives()) obj->DrawClone();
239
240 // Go back to the main cBase canvas
241 m_canvas->cd();
242 m_monObj->addCanvas(m_canvas);
243
244
245 // Delete RooFit objects
246 delete dataE0;
247 delete dataEp;
248
249
250 return {{"EcmsBBcnt", 2 * sigmean.getValV()}, {"EcmsBBcntUnc", 2 * sigmean.getError()},
251 {"EcmsBBspread", 2 * sigwidth.getValV()}, {"EcmsBBspreadUnc", 2 * sigwidth.getError()}, {"EcmsBBnsigB0", nsigB0.getValV()}, {"EcmsBBnsigB0Unc", nsigB0.getError()}, {"EcmsBBnsigBp", nsigBp.getValV()}, {"EcmsBBnsigBpUnc", nsigBp.getError()}};
252}
253
254unordered_map<string, double> DQMHistAnalysisEcmsMonObjModule::parseTitle(const std::string& title)
255{
256 std::regex re(R"(exp\s+(\d+)\s+run\s+(\d+).*?=\s*([\d.]+))");
257 std::smatch m;
258 double exp = 0;
259 double run = 0;
260 double lumi = -1.;
261 if (std::regex_search(title, m, re)) {
262 exp = std::stoi(m[1]);
263 run = std::stoi(m[2]);
264 lumi = std::stod(m[3]);
265 }
266 return {{"exp", exp}, {"run", run}, {"lumi", lumi}};
267}
268
269
271{
272 B2DEBUG(20, "DQMHistAnalysisEcmsMonObj: endRun called.");
273
274 auto* hB0 = (TH1D*)findHist("PhysicsObjectsMiraBelleEcmsBB/hB0");
275 auto* hBp = (TH1D*)findHist("PhysicsObjectsMiraBelleEcmsBB/hBp");
276 if (hB0 == nullptr || hBp == nullptr) return;
277
278 auto res = fitEcmsBB(hB0, hBp);
279
280 auto tit = parseTitle(std::string(hB0->GetTitle()));
281
282 m_monObj->setVariable("EcmsBBcnt", res.at("EcmsBBcnt"), res.at("EcmsBBcntUnc"));
283 m_monObj->setVariable("EcmsBBspread", res.at("EcmsBBspread"), res.at("EcmsBBspreadUnc"));
284 if (tit.at("lumi") > 1.) {
285 m_monObj->setVariable("EcmsBBnsigB0", res.at("EcmsBBnsigB0") / tit.at("lumi"), res.at("EcmsBBnsigB0Unc") / tit.at("lumi"));
286 m_monObj->setVariable("EcmsBBnsigBp", res.at("EcmsBBnsigBp") / tit.at("lumi"), res.at("EcmsBBnsigBpUnc") / tit.at("lumi"));
287 }
288
289 m_monObj->setVariable("EcmsBBcnt_firstExp", tit.at("exp"));
290 m_monObj->setVariable("EcmsBBcnt_firstRun", tit.at("run"));
291
292}
293
295{
296
297 B2DEBUG(20, "terminate called");
298}
299
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.