23#include <Math/Functor.h>
24#include <Math/SpecFuncMathCore.h>
25#include <Math/DistFunc.h>
28#include <RooRealVar.h>
29#include <RooDataSet.h>
30#include <RooGaussian.h>
34#include <RooPolyVar.h>
35#include <RooArgusBG.h>
36#include <RooSimultaneous.h>
37#include <RooCategory.h>
39#include <RooConstVar.h>
40#include <RooFitResult.h>
42#include <framework/particledb/EvtGenDatabasePDG.h>
47#include <reconstruction/calibration/BeamSpotBoostInvMass/InvariantMassBhadStandAlone.h>
48#include <reconstruction/calibration/BeamSpotBoostInvMass/Splitter.h>
49#include <reconstruction/calibration/BeamSpotBoostInvMass/tools.h>
51#include <InvariantMassBhadStandAlone.h>
60namespace Belle2::InvariantMassBhadCalib {
65 std::vector<Event> getEvents(TTree* tr)
68 std::vector<Event> events;
69 events.reserve(tr->GetEntries());
73 tr->SetBranchAddress(
"run", &evt.run);
74 tr->SetBranchAddress(
"exp", &evt.exp);
75 tr->SetBranchAddress(
"event", &evt.evtNo);
76 tr->SetBranchAddress(
"time", &evt.t);
79 std::vector<double>* pBcms =
new std::vector<double>;
80 std::vector<double>* mB =
new std::vector<double>;
81 std::vector<int>* pdg =
new std::vector<int>;
82 std::vector<int>* mode =
new std::vector<int>;
83 std::vector<double>* Kpid =
new std::vector<double>;
84 std::vector<double>* R2 =
new std::vector<double>;
85 std::vector<double>* mD =
new std::vector<double>;
86 std::vector<double>* dmDstar =
new std::vector<double>;
90 tr->SetBranchAddress(
"pBcms", &pBcms);
91 tr->SetBranchAddress(
"mB", &mB);
92 tr->SetBranchAddress(
"pdg", &pdg);
93 tr->SetBranchAddress(
"mode", &mode);
94 tr->SetBranchAddress(
"Kpid", &Kpid);
95 tr->SetBranchAddress(
"R2", &R2);
96 tr->SetBranchAddress(
"mD", &mD);
97 tr->SetBranchAddress(
"dmDstar", &dmDstar);
102 for (
int i = 0; i < tr->GetEntries(); ++i) {
105 int nCand = mode->size();
106 evt.cand.resize(nCand);
108 for (
int j = 0; j < nCand; ++j) {
109 evt.cand[j].pBcms = pBcms->at(j);
110 evt.cand[j].mB = mB->at(j);
111 evt.cand[j].pdg = pdg->at(j);
112 evt.cand[j].mode = mode->at(j);
113 evt.cand[j].Kpid = Kpid->at(j);
114 evt.cand[j].R2 = R2->at(j);
115 evt.cand[j].mD = mD->at(j);
116 evt.cand[j].dmDstar = dmDstar->at(j);
118 evt.cand[j].isSig =
true;
123 events.push_back(evt);
127 sort(events.begin(), events.end(), [](Event e1, Event e2) {return e1.t < e2.t;});
135 void plotArgusFit(RooDataSet* dataE0, RooAddPdf& sumB0, RooArgusBG& argus, RooGaussian& gauss, RooRealVar& eNow,
139 bool isBatch = gROOT->IsBatch();
140 gROOT->SetBatch(kTRUE);
142 using namespace RooFit ;
145 RooPlot* mbcframe = eNow.frame(40) ;
146 dataE0->plotOn(mbcframe) ;
148 sumB0.paramOn(mbcframe, Parameters(*dataE0->get()));
151 sumB0.plotOn(mbcframe, Components(argus), LineStyle(kDashed)) ;
152 sumB0.plotOn(mbcframe, Components(gauss), LineStyle(kDashed), LineColor(kRed)) ;
154 sumB0.plotOn(mbcframe);
156 mbcframe->GetXaxis()->SetTitleSize(0.0001);
157 mbcframe->GetXaxis()->SetLabelSize(0.0001);
158 mbcframe->SetTitleSize(0.0001);
159 mbcframe->GetYaxis()->SetTitleSize(0.06);
160 mbcframe->GetYaxis()->SetTitleOffset(0.7);
161 mbcframe->GetYaxis()->SetLabelSize(0.06) ;
163 mbcframe->SetTitle(
"");
166 RooHist* hpull = mbcframe->pullHist() ;
168 RooPlot* frame3 = eNow.frame(Title(
".")) ;
169 frame3->GetYaxis()->SetTitle(
"Pull") ;
170 frame3->GetYaxis()->SetTitleSize(0.13) ;
172 frame3->GetYaxis()->SetNdivisions(504) ;
173 frame3->GetYaxis()->SetLabelSize(0.15) ;
174 frame3->GetXaxis()->SetTitleSize(0.15) ;
175 frame3->GetXaxis()->SetLabelSize(0.15) ;
177 frame3->GetYaxis()->SetTitleOffset(0.3) ;
178 frame3->addPlotable(hpull,
"x0 P E1") ;
179 frame3->SetMaximum(5.);
180 frame3->SetMinimum(-5.);
183 TCanvas* c1 =
new TCanvas(
rn()) ;
184 TPad* pad1 =
new TPad(
"pad1",
"pad1", 0, 0.3, 1, 1.0);
190 TLine* ll =
new TLine;
191 double mRev = 10579.4e-3 / 2;
192 ll->SetLineColor(kGreen);
193 ll->DrawLine(mRev, 0, mRev, mbcframe->GetMaximum());
197 TPad* pad2 =
new TPad(
"pad2",
"pad2", 0, 0.00, 1, 0.3);
198 pad2->SetTopMargin(0.05);
199 pad2->SetBottomMargin(0.35);
205 TLine* l =
new TLine(5279.34e-3, 0.0, 5.37, 0.0);
206 l->SetLineColor(kBlue);
211 if (fName !=
"") c1->SaveAs(fName);
223 gROOT->SetBatch(isBatch);
228 std::map<TString, std::pair<double, double>> argusFit(
const std::vector<Event>& evts,
229 std::vector<std::pair<double, double>> limits)
235 using namespace RooFit;
237 RooRealVar eNow(
"eNow",
"E^{*}_{B} [GeV]", cMBp, 5.37);
240 RooDataSet* dataE0 =
new RooDataSet(
"dataE0",
"dataE0", RooArgSet(eNow));
241 RooDataSet* dataEp =
new RooDataSet(
"dataEp",
"dataEp", RooArgSet(eNow));
244 TH1D* hDeltaE =
new TH1D(
rn(),
"", 30, -0.05, 0.05);
245 TH1D* hMD =
new TH1D(
rn(),
"", 30, 1.7, 1.9);
246 TH1D* hMB =
new TH1D(
rn(),
"", 30, -0.15, 0.15);
254 for (
auto event : evts) {
255 for (
auto cand : event.cand) {
257 double p = cand.pBcms;
258 double mInv = cand.mB;
265 if (1.830 < cand.mD && cand.mD < 1.894)
266 if (abs(mInv - mB) < 0.05)
268 if ((cand.dmDstar < -10) || (0.143 < cand.dmDstar && cand.dmDstar < 0.147)) {
269 double eBC =
sqrt(p * p + pow(mB, 2));
270 if (eBC > 5.37)
continue;
272 for (
unsigned i = 0; i < limits.size(); ++i) {
273 if (limits[i].first <= event.t && event.t < limits[i].second) {
274 if (abs(cand.pdg) == 511) {
276 dataE0->add(RooArgSet(eNow));
279 dataEp->add(RooArgSet(eNow));
284 hDeltaE->Fill(eBC - cmsE0 / 2);
286 hMB->Fill(mInv - mB);
293 RooCategory Bcharge(
"sample",
"sample") ;
294 Bcharge.defineType(
"B0") ;
295 Bcharge.defineType(
"Bp") ;
297 RooDataSet combData(
"combData",
"combined data", eNow, Index(Bcharge), Import(
"B0", *dataE0), Import(
"Bp", *dataEp)) ;
301 RooRealVar sigmean(
"Mean",
"B^{#pm} mass", 5.29, 5.27, 5.30) ;
302 RooRealVar sigwidth(
"#sigma",
"B^{#pm} width", 0.00237, 0.0001, 0.030) ;
306 RooPolyVar sigmeanNow(
"sigmeanNow",
"shape parameter", sigmean, RooArgSet(RooConst(0.000), RooConst(1.)));
307 RooGaussian gauss(
"gauss",
"gaussian PDF", eNow, sigmeanNow, sigwidth) ;
310 RooRealVar argpar(
"Argus_param",
"argus shape parameter", -150.7, -300., +50.0) ;
311 RooRealVar endpointBp(
"EndPointBp",
"endPoint parameter", cMBp, 5.27, 5.291) ;
312 RooRealVar endpointB0(
"EndPointB0",
"endPoint parameter", cMB0, 5.27, 5.291) ;
313 endpointB0.setConstant(kTRUE);
314 endpointBp.setConstant(kTRUE);
318 RooPolyVar shape2B0(
"EndPoint2B0",
"shape parameter", endpointB0, RooArgSet(RooConst(0.), RooConst(2.)));
319 RooPolyVar eNowDifB0(
"eNowDifB0",
"eNowDifB0", eNow, RooArgSet(shape2B0, RooConst(-1.)));
320 RooArgusBG argusB0(
"argusB0",
"Argus PDF", eNowDifB0, endpointB0, argpar) ;
323 RooPolyVar shape2Bp(
"EndPoint2Bp",
"shape parameter", endpointBp, RooArgSet(RooConst(0.), RooConst(2.)));
324 RooPolyVar eNowDifBp(
"eNowDifBp",
"eNowDifBp", eNow, RooArgSet(shape2Bp, RooConst(-1.)));
325 RooArgusBG argusBp(
"argusBp",
"Argus PDF", eNowDifBp, endpointBp, argpar) ;
329 RooRealVar nsigB0(
"nsigB0",
"#signal events", 100, 0., 100000) ;
330 RooRealVar nbkgB0(
"nbkgB0",
"#background events", 100, 0., 500000) ;
332 RooRealVar nsigBp(
"nsigBp",
"#signal events", 100, 0., 100000) ;
333 RooRealVar nbkgBp(
"nbkgBp",
"#background events", 100, 0., 500000) ;
337 RooAddPdf sumB0(
"sumB0",
"g0+a0", RooArgList(gauss, argusB0), RooArgList(nsigB0, nbkgB0)) ;
338 RooAddPdf sumBp(
"sumBp",
"gP+aP", RooArgList(gauss, argusBp), RooArgList(nsigBp, nbkgBp)) ;
342 RooSimultaneous simPdf(
"simPdf",
"simultaneous pdf", Bcharge) ;
345 simPdf.addPdf(sumB0,
"B0") ;
346 simPdf.addPdf(sumBp,
"Bp") ;
348 simPdf.fitTo(combData);
351 std::map<TString, std::pair<double, double>> resMap;
352 resMap[
"sigmean"] = {sigmean.getValV(), sigmean.getError()};
353 resMap[
"sigwidth"] = {sigwidth.getValV(), sigwidth.getError()};
354 resMap[
"argpar"] = {argpar.getValV(), argpar.getError()};
356 std::filesystem::create_directories(
"plotsHadBonly");
358 plotArgusFit(dataE0, sumB0, argusB0, gauss, eNow, Form(
"plotsHadBonly/B0Single_%d.pdf",
int(round(limits[0].first))));
359 plotArgusFit(dataEp, sumBp, argusBp, gauss, eNow, Form(
"plotsHadBonly/BpSingle_%d.pdf",
int(round(limits[0].first))));
380 std::map<TString, std::pair<double, double>> argusFitConstrained(
const std::vector<Event>& evts,
381 std::vector<std::pair<double, double>> limits,
382 std::vector<std::pair<double, double>> mumuVals, std::vector<double> startPars)
385 for (
auto& el : mumuVals) {
391 const double meanInit = startPars[0] / 2;
392 const double sigmaInit = startPars[2] / 2;
393 const double argparInit = startPars[4];
395 double s = 0, sw = 0;
396 for (
auto p : mumuVals) {
397 s += p.first / pow(p.second, 2);
398 sw += 1. / pow(p.second, 2);
400 const double mumuMean = s / sw;
401 const double shiftInit = meanInit - mumuMean;
407 using namespace RooFit;
409 RooRealVar eNow(
"eNow",
"E^{*}_{B} [GeV]", cMBp, 5.37);
411 std::vector<RooDataSet*> dataE0(limits.size());
412 std::vector<RooDataSet*> dataEp(limits.size());
414 for (
unsigned i = 0; i < limits.size(); ++i) {
415 dataE0[i] =
new RooDataSet(Form(
"dataE0_%u", i), Form(
"dataE0_%u", i), RooArgSet(eNow));
416 dataEp[i] =
new RooDataSet(Form(
"dataEp_%u", i), Form(
"dataEp_%u", i), RooArgSet(eNow));
420 TH1D* hDeltaE =
new TH1D(
rn(),
"", 30, -0.05, 0.05);
421 TH1D* hMD =
new TH1D(
rn(),
"", 30, 1.7, 1.9);
422 TH1D* hMB =
new TH1D(
rn(),
"", 30, -0.15, 0.15);
429 for (
auto event : evts) {
430 for (
auto cand : event.cand) {
432 double p = cand.pBcms;
433 double mInv = cand.mB;
440 if (1.830 < cand.mD && cand.mD < 1.894)
441 if (abs(mInv - mB) < 0.05)
443 if ((cand.dmDstar < -10) || (0.143 < cand.dmDstar && cand.dmDstar < 0.147)) {
444 double eBC =
sqrt(p * p + pow(mB, 2));
445 if (eBC > 5.37)
continue;
447 for (
unsigned i = 0; i < limits.size(); ++i) {
448 if (limits[i].first <= event.t && event.t < limits[i].second) {
449 if (abs(cand.pdg) == 511) {
451 dataE0[i]->add(RooArgSet(eNow));
454 dataEp[i]->add(RooArgSet(eNow));
459 hDeltaE->Fill(eBC - cmsE0 / 2);
461 hMB->Fill(mInv - mB);
468 RooCategory Bcharge(
"sample",
"sample") ;
469 for (
unsigned i = 0; i < limits.size(); ++i) {
470 Bcharge.defineType(Form(
"B0_%u", i));
471 Bcharge.defineType(Form(
"Bp_%u", i));
474 RooDataSet* combData =
nullptr;
476 std::map<std::string, RooDataSet*> dataSetMap;
477 for (
unsigned i = 0; i < limits.size(); ++i) {
478 dataSetMap[Form(
"B0_%u", i)] = dataE0[i];
479 dataSetMap[Form(
"Bp_%u", i)] = dataEp[i];
481 combData =
new RooDataSet(
"combData",
"combined data", eNow, Index(Bcharge), Import(dataSetMap));
486 RooRealVar sigwidth(
"#sigma",
"width of B-meson energy in CMS", sigmaInit, 0.0001, 0.030) ;
488 std::vector<RooRealVar*> sigmean(limits.size());
489 std::vector<RooGaussian*> gauss(limits.size());
493 for (
unsigned i = 0; i < limits.size(); ++i) {
494 sigmean[i] =
new RooRealVar(Form(
"Mean_%u", i),
"mean B-meson energy in CMS", meanInit, 5.27, 5.30) ;
495 gauss[i] =
new RooGaussian(Form(
"gauss_%u", i),
"gaussian PDF", eNow, *sigmean[i], sigwidth) ;
501 RooRealVar argpar(
"Argus_param",
"argus shape parameter", argparInit, -300., +50.0) ;
502 RooRealVar endpointBp(
"EndPointBp",
"endPoint parameter", cMBp, 5.27, 5.291) ;
503 RooRealVar endpointB0(
"EndPointB0",
"endPoint parameter", cMB0, 5.27, 5.291) ;
504 endpointB0.setConstant(kTRUE);
505 endpointBp.setConstant(kTRUE);
508 RooRealVar zero(
"zero",
"", 0);
509 RooRealVar two(
"two",
"", 2);
510 RooRealVar minus(
"minus",
"", -1);
513 RooPolyVar shape2B0(
"EndPoint2B0",
"shape parameter", endpointB0, RooArgSet(zero, two));
514 RooPolyVar eNowDifB0(
"eNowDifB0",
"eNowDifB0", eNow, RooArgSet(shape2B0, minus));
515 RooArgusBG argusB0(
"argusB0",
"Argus PDF", eNowDifB0, endpointB0, argpar) ;
518 RooPolyVar shape2Bp(
"EndPoint2Bp",
"shape parameter", endpointBp, RooArgSet(zero, two));
519 RooPolyVar eNowDifBp(
"eNowDifBp",
"eNowDifBp", eNow, RooArgSet(shape2Bp, minus));
520 RooArgusBG argusBp(
"argusBp",
"Argus PDF", eNowDifBp, endpointBp, argpar) ;
523 std::vector<RooRealVar*> nsigB0(limits.size());
524 std::vector<RooRealVar*> nbkgB0(limits.size());
526 std::vector<RooRealVar*> nsigBp(limits.size());
527 std::vector<RooRealVar*> nbkgBp(limits.size());
529 std::vector<RooAddPdf*> sumB0(limits.size());
530 std::vector<RooAddPdf*> sumBp(limits.size());
534 for (
unsigned i = 0; i < limits.size(); ++i) {
535 nsigB0[i] =
new RooRealVar(Form(
"nsigB0_%u", i),
"#signal events", 100, 0., 100000);
536 nbkgB0[i] =
new RooRealVar(Form(
"nbkgB0_%u", i),
"#background events", 100, 0., 500000) ;
538 nsigBp[i] =
new RooRealVar(Form(
"nsigBp_%u", i),
"#signal events", 100, 0., 100000) ;
539 nbkgBp[i] =
new RooRealVar(Form(
"nbkgBp_%u", i),
"#background events", 100, 0., 500000) ;
541 sumB0[i] =
new RooAddPdf(Form(
"sumB0_%u", i),
"g0+a0", RooArgList(*gauss[i], argusB0), RooArgList(*nsigB0[i], *nbkgB0[i]));
542 sumBp[i] =
new RooAddPdf(Form(
"sumBp_%u", i),
"gP+aP", RooArgList(*gauss[i], argusBp), RooArgList(*nsigBp[i], *nbkgBp[i]));
548 RooSimultaneous simPdf(
"simPdf",
"simultaneous pdf", Bcharge) ;
551 for (
unsigned i = 0; i < limits.size(); ++i) {
552 simPdf.addPdf(*sumB0[i], Form(
"B0_%u", i));
553 simPdf.addPdf(*sumBp[i], Form(
"Bp_%u", i));
556 RooRealVar shift(
"shift",
"shift to mumu", shiftInit, -30e-3, 30e-3);
558 std::vector<RooGaussian*> fconstraint(limits.size());
559 std::vector<RooPolyVar*> shiftNow(limits.size());
561 for (
unsigned i = 0; i < limits.size(); ++i) {
562 shiftNow[i] =
new RooPolyVar(Form(
"shiftNow_%u", i),
"shiftShift", shift, RooArgSet(RooConst(mumuVals[i].first), RooConst(1.)));
564 fconstraint[i] =
new RooGaussian(Form(
"fconstraint_%u", i),
"fconstraint", *sigmean[i], *shiftNow[i],
565 RooConst(mumuVals[i].second / 1.)) ;
569 RooArgSet constraintSet;
570 for (
auto& c : fconstraint) {
571 constraintSet.add(*c);
573 simPdf.fitTo(*combData, ExternalConstraints(constraintSet));
576 std::map<TString, std::pair<double, double>> resMap;
577 for (
unsigned i = 0; i < limits.size(); ++i) {
578 resMap[Form(
"sigmean_%u", i)] = {sigmean[i]->getValV(), sigmean[i]->getError()};
579 resMap[Form(
"pull_%u", i)] = { (sigmean[i]->getValV() - shift.getValV() - mumuVals[i].first) / mumuVals[i].second, 0};
582 resMap[
"sigwidth"] = {sigwidth.getValV(), sigwidth.getError()};
583 resMap[
"argpar"] = {argpar.getValV(), argpar.getError()};
584 resMap[
"shift"] = {shift.getValV(), shift.getError()};
587 namespace fs = std::filesystem;
588 fs::create_directories(
"plotsHadB");
590 for (
unsigned i = 0; i < limits.size(); ++i) {
591 plotArgusFit(dataE0[i], *sumB0[i], argusB0, *gauss[i], eNow, Form(
"plotsHadB/B0_%d_%u.pdf",
int(round(limits[0].first)), i));
592 plotArgusFit(dataEp[i], *sumBp[i], argusBp, *gauss[i], eNow, Form(
"plotsHadB/Bp_%d_%u.pdf",
int(round(limits[0].first)), i));
597 for (
unsigned i = 0; i < limits.size(); ++i) {
612 delete fconstraint[i];
630 std::vector<std::vector<double>> doBhadFit(
const std::vector<Event>& evts, std::vector<std::pair<double, double>> limits,
631 std::vector<std::pair<double, double>> mumuVals,
const std::vector<double>& startPars)
634 auto r = argusFitConstrained(evts, limits, mumuVals, startPars);
635 assert(limits.size() == mumuVals.size());
637 std::vector<std::vector<double>> result(limits.size());
640 for (
unsigned i = 0; i < limits.size(); ++i) {
641 std::string n = Form(
"sigmean_%u", i);
642 std::string np = Form(
"pull_%u", i);
645 result[i] = {2 * r.at(n).first, 2 * r.at(n).second, 2 * r.at(
"sigwidth").first, 2 * r.at(
"sigwidth").second, 2 * r.at(
"shift").first, 2 * r.at(
"shift").second, r.at(np).first};
653 std::vector<double> doBhadOnlyFit(
const std::vector<Event>& evts,
const std::vector<std::pair<double, double>>& limits)
656 auto r = argusFit(evts, limits);
658 return {2 * r.at(
"sigmean").first, 2 * r.at(
"sigmean").second, 2 * r.at(
"sigwidth").first, 2 * r.at(
"sigwidth").second, r.at(
"argpar").first};
static EvtGenDatabasePDG * Instance()
Instance method that loads the EvtGen table.
double sqrt(double a)
sqrt for double
TString rn()
Get random string.