16 #include <Eigen/Dense>
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>
33 #include <RooAddPdf.h>
34 #include <RooPolyVar.h>
35 #include <RooArgusBG.h>
36 #include <RooSimultaneous.h>
37 #include <RooCategory.h>
38 #include <RooArgSet.h>
39 #include <RooConstVar.h>
41 #include <framework/particledb/EvtGenDatabasePDG.h>
46 #include <tracking/calibration/InvariantMassBhadStandAlone.h>
47 #include <tracking/calibration/Splitter.h>
48 #include <tracking/calibration/tools.h>
50 #include <InvariantMassBhadStandAlone.h>
55 using Eigen::MatrixXd;
56 using Eigen::VectorXd;
61 namespace Belle2::InvariantMassBhadCalib {
66 vector<Event> getEvents(TTree* tr)
70 events.reserve(tr->GetEntries());
74 tr->SetBranchAddress(
"run", &evt.run);
75 tr->SetBranchAddress(
"exp", &evt.exp);
76 tr->SetBranchAddress(
"event", &evt.evtNo);
77 tr->SetBranchAddress(
"time", &evt.t);
80 vector<double>* pBcms =
new vector<double>;
81 vector<double>* mB =
new vector<double>;
82 vector<int>* pdg =
new vector<int>;
83 vector<int>* mode =
new vector<int>;
84 vector<double>* Kpid =
new vector<double>;
85 vector<double>* R2 =
new vector<double>;
86 vector<double>* mD =
new vector<double>;
87 vector<double>* dmDstar =
new vector<double>;
91 tr->SetBranchAddress(
"pBcms", &pBcms);
92 tr->SetBranchAddress(
"mB", &mB);
93 tr->SetBranchAddress(
"pdg", &pdg);
94 tr->SetBranchAddress(
"mode", &mode);
95 tr->SetBranchAddress(
"Kpid", &Kpid);
96 tr->SetBranchAddress(
"R2", &R2);
97 tr->SetBranchAddress(
"mD", &mD);
98 tr->SetBranchAddress(
"dmDstar", &dmDstar);
103 for (
int i = 0; i < tr->GetEntries(); ++i) {
106 int nCand = mode->size();
107 evt.cand.resize(nCand);
109 for (
int j = 0; j < nCand; ++j) {
110 evt.cand[j].pBcms = pBcms->at(j);
111 evt.cand[j].mB = mB->at(j);
112 evt.cand[j].pdg = pdg->at(j);
113 evt.cand[j].mode = mode->at(j);
114 evt.cand[j].Kpid = Kpid->at(j);
115 evt.cand[j].R2 = R2->at(j);
116 evt.cand[j].mD = mD->at(j);
117 evt.cand[j].dmDstar = dmDstar->at(j);
119 evt.cand[j].isSig =
true;
124 events.push_back(evt);
128 sort(events.begin(), events.end(), [](Event e1, Event e2) {return e1.t < e2.t;});
136 void plotArgusFit(RooDataSet* dataE0, RooAddPdf& sumB0, RooArgusBG& argus, RooGaussian& gauss, RooRealVar& eNow,
140 bool isBatch = gROOT->IsBatch();
141 gROOT->SetBatch(kTRUE);
143 using namespace RooFit ;
146 RooPlot* mbcframe = eNow.frame(40) ;
147 dataE0->plotOn(mbcframe) ;
149 sumB0.paramOn(mbcframe, dataE0);
152 sumB0.plotOn(mbcframe, Components(argus), LineStyle(kDashed)) ;
153 sumB0.plotOn(mbcframe, Components(gauss), LineStyle(kDashed), LineColor(kRed)) ;
155 sumB0.plotOn(mbcframe);
157 mbcframe->GetXaxis()->SetTitleSize(0.0001);
158 mbcframe->GetXaxis()->SetLabelSize(0.0001);
159 mbcframe->SetTitleSize(0.0001);
160 mbcframe->GetYaxis()->SetTitleSize(0.06);
161 mbcframe->GetYaxis()->SetTitleOffset(0.7);
162 mbcframe->GetYaxis()->SetLabelSize(0.06) ;
164 mbcframe->SetTitle(
"");
167 RooHist* hpull = mbcframe->pullHist() ;
169 RooPlot* frame3 = eNow.frame(Title(
".")) ;
170 frame3->GetYaxis()->SetTitle(
"Pull") ;
171 frame3->GetYaxis()->SetTitleSize(0.13) ;
173 frame3->GetYaxis()->SetNdivisions(504) ;
174 frame3->GetYaxis()->SetLabelSize(0.15) ;
175 frame3->GetXaxis()->SetTitleSize(0.15) ;
176 frame3->GetXaxis()->SetLabelSize(0.15) ;
178 frame3->GetYaxis()->SetTitleOffset(0.3) ;
179 frame3->addPlotable(hpull,
"x0 P E1") ;
180 frame3->SetMaximum(5.);
181 frame3->SetMinimum(-5.);
184 TCanvas* c1 =
new TCanvas(
rn()) ;
185 TPad* pad1 =
new TPad(
"pad1",
"pad1", 0, 0.3, 1, 1.0);
191 TLine* ll =
new TLine;
192 double mRev = 10579.4e-3 / 2;
193 ll->SetLineColor(kGreen);
194 ll->DrawLine(mRev, 0, mRev, mbcframe->GetMaximum());
198 TPad* pad2 =
new TPad(
"pad2",
"pad2", 0, 0.00, 1, 0.3);
199 pad2->SetTopMargin(0.05);
200 pad2->SetBottomMargin(0.35);
206 TLine* l =
new TLine(5279.34e-3, 0.0, 5.37, 0.0);
207 l->SetLineColor(kBlue);
212 if (fName !=
"") c1->SaveAs(fName);
224 gROOT->SetBatch(isBatch);
229 map<TString, pair<double, double>> argusFit(
const vector<Event>& evts, vector<pair<double, double>> limits)
232 const double cMBp = EvtGenDatabasePDG::Instance()->GetParticle(
"B+")->Mass();
233 const double cMB0 = EvtGenDatabasePDG::Instance()->GetParticle(
"B0")->Mass();
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);
250 B2ASSERT(
"Assert the existence of the Y4S particle data", EvtGenDatabasePDG::Instance()->GetParticle(
"Upsilon(4S)"));
252 const double cmsE0 = EvtGenDatabasePDG::Instance()->GetParticle(
"Upsilon(4S)")->Mass();
254 int nCand = 0, nEv = 0;
256 for (
auto event : evts) {
258 for (
auto cand : event.cand) {
260 double p = cand.pBcms;
261 double mInv = cand.mB;
264 double mB = EvtGenDatabasePDG::Instance()->GetParticle(abs(cand.pdg))->Mass();
268 if (1.830 < cand.mD && cand.mD < 1.894)
269 if (abs(mInv - mB) < 0.05)
271 if ((cand.dmDstar < -10) || (0.143 < cand.dmDstar && cand.dmDstar < 0.147)) {
272 double eBC = sqrt(p * p + pow(mB, 2));
273 if (eBC > 5.37)
continue;
275 for (
unsigned i = 0; i < limits.size(); ++i) {
276 if (limits[i].first <= event.t && event.t < limits[i].second) {
277 if (abs(cand.pdg) == 511) {
279 dataE0->add(RooArgSet(eNow));
282 dataEp->add(RooArgSet(eNow));
285 if (iCand == 0) ++nEv;
289 hDeltaE->Fill(eBC - cmsE0 / 2);
291 hMB->Fill(mInv - mB);
299 RooCategory Bcharge(
"sample",
"sample") ;
300 Bcharge.defineType(
"B0") ;
301 Bcharge.defineType(
"Bp") ;
303 RooDataSet combData(
"combData",
"combined data", eNow, Index(Bcharge), Import(
"B0", *dataE0), Import(
"Bp", *dataEp)) ;
307 RooRealVar sigmean(
"Mean",
"B^{#pm} mass", 5.29, 5.27, 5.30) ;
308 RooRealVar sigwidth(
"#sigma",
"B^{#pm} width", 0.00237, 0.0001, 0.030) ;
312 RooPolyVar sigmeanNow(
"sigmeanNow",
"shape parameter", sigmean, RooArgSet(RooConst(0.000), RooConst(1.)));
313 RooGaussian gauss(
"gauss",
"gaussian PDF", eNow, sigmeanNow, sigwidth) ;
316 RooRealVar argpar(
"Argus_param",
"argus shape parameter", -150.7, -300., +50.0) ;
317 RooRealVar endpointBp(
"EndPointBp",
"endPoint parameter", cMBp, 5.27, 5.291) ;
318 RooRealVar endpointB0(
"EndPointB0",
"endPoint parameter", cMB0, 5.27, 5.291) ;
319 endpointB0.setConstant(kTRUE);
320 endpointBp.setConstant(kTRUE);
324 RooPolyVar shape2B0(
"EndPoint2B0",
"shape parameter", endpointB0, RooArgSet(RooConst(0.), RooConst(2.)));
325 RooPolyVar eNowDifB0(
"eNowDifB0",
"eNowDifB0", eNow, RooArgSet(shape2B0, RooConst(-1.)));
326 RooArgusBG argusB0(
"argusB0",
"Argus PDF", eNowDifB0, endpointB0, argpar) ;
329 RooPolyVar shape2Bp(
"EndPoint2Bp",
"shape parameter", endpointBp, RooArgSet(RooConst(0.), RooConst(2.)));
330 RooPolyVar eNowDifBp(
"eNowDifBp",
"eNowDifBp", eNow, RooArgSet(shape2Bp, RooConst(-1.)));
331 RooArgusBG argusBp(
"argusBp",
"Argus PDF", eNowDifBp, endpointBp, argpar) ;
335 RooRealVar nsigB0(
"nsigB0",
"#signal events", 100, 0., 100000) ;
336 RooRealVar nbkgB0(
"nbkgB0",
"#background events", 100, 0., 500000) ;
338 RooRealVar nsigBp(
"nsigBp",
"#signal events", 100, 0., 100000) ;
339 RooRealVar nbkgBp(
"nbkgBp",
"#background events", 100, 0., 500000) ;
343 RooAddPdf sumB0(
"sumB0",
"g0+a0", RooArgList(gauss, argusB0), RooArgList(nsigB0, nbkgB0)) ;
344 RooAddPdf sumBp(
"sumBp",
"gP+aP", RooArgList(gauss, argusBp), RooArgList(nsigBp, nbkgBp)) ;
348 RooSimultaneous simPdf(
"simPdf",
"simultaneous pdf", Bcharge) ;
351 simPdf.addPdf(sumB0,
"B0") ;
352 simPdf.addPdf(sumBp,
"Bp") ;
354 simPdf.fitTo(combData);
357 map<TString, pair<double, double>> resMap;
358 resMap[
"sigmean"] = {sigmean.getValV(), sigmean.getError()};
359 resMap[
"sigwidth"] = {sigwidth.getValV(), sigwidth.getError()};
360 resMap[
"argpar"] = {argpar.getValV(), argpar.getError()};
362 filesystem::create_directories(
"plotsHadBonly");
364 plotArgusFit(dataE0, sumB0, argusB0, gauss, eNow, Form(
"plotsHadBonly/B0Single_%d.pdf",
int(round(limits[0].first))));
365 plotArgusFit(dataEp, sumBp, argusBp, gauss, eNow, Form(
"plotsHadBonly/BpSingle_%d.pdf",
int(round(limits[0].first))));
386 map<TString, pair<double, double>> argusFitConstrained(
const vector<Event>& evts, vector<pair<double, double>> limits,
387 vector<pair<double, double>> mumuVals, vector<double> startPars)
390 for (
auto& el : mumuVals) {
396 const double meanInit = startPars[0] / 2;
397 const double sigmaInit = startPars[2] / 2;
398 const double argparInit = startPars[4];
400 double s = 0, sw = 0;
401 for (
auto p : mumuVals) {
402 s += p.first / pow(p.second, 2);
403 sw += 1. / pow(p.second, 2);
405 const double mumuMean = s / sw;
406 const double shiftInit = meanInit - mumuMean;
409 const double cMBp = EvtGenDatabasePDG::Instance()->GetParticle(
"B+")->Mass();
410 const double cMB0 = EvtGenDatabasePDG::Instance()->GetParticle(
"B0")->Mass();
412 using namespace RooFit;
414 RooRealVar eNow(
"eNow",
"E^{*}_{B} [GeV]", cMBp, 5.37);
416 vector<RooDataSet*> dataE0(limits.size());
417 vector<RooDataSet*> dataEp(limits.size());
419 for (
unsigned i = 0; i < limits.size(); ++i) {
420 dataE0[i] =
new RooDataSet(Form(
"dataE0_%u", i), Form(
"dataE0_%u", i), RooArgSet(eNow));
421 dataEp[i] =
new RooDataSet(Form(
"dataEp_%u", i), Form(
"dataEp_%u", i), RooArgSet(eNow));
425 TH1D* hDeltaE =
new TH1D(
rn(),
"", 30, -0.05, 0.05);
426 TH1D* hMD =
new TH1D(
rn(),
"", 30, 1.7, 1.9);
427 TH1D* hMB =
new TH1D(
rn(),
"", 30, -0.15, 0.15);
430 B2ASSERT(
"Assert the existence of the Y4S particle data", EvtGenDatabasePDG::Instance()->GetParticle(
"Upsilon(4S)"));
432 const double cmsE0 = EvtGenDatabasePDG::Instance()->GetParticle(
"Upsilon(4S)")->Mass();
434 int nCand = 0, nEv = 0;
436 for (
auto event : evts) {
438 for (
auto cand : event.cand) {
440 double p = cand.pBcms;
441 double mInv = cand.mB;
444 double mB = EvtGenDatabasePDG::Instance()->GetParticle(abs(cand.pdg))->Mass();
448 if (1.830 < cand.mD && cand.mD < 1.894)
449 if (abs(mInv - mB) < 0.05)
451 if ((cand.dmDstar < -10) || (0.143 < cand.dmDstar && cand.dmDstar < 0.147)) {
452 double eBC = sqrt(p * p + pow(mB, 2));
453 if (eBC > 5.37)
continue;
455 for (
unsigned i = 0; i < limits.size(); ++i) {
456 if (limits[i].first <= event.t && event.t < limits[i].second) {
457 if (abs(cand.pdg) == 511) {
459 dataE0[i]->add(RooArgSet(eNow));
462 dataEp[i]->add(RooArgSet(eNow));
465 if (iCand == 0) ++nEv;
469 hDeltaE->Fill(eBC - cmsE0 / 2);
471 hMB->Fill(mInv - mB);
479 RooCategory Bcharge(
"sample",
"sample") ;
480 for (
unsigned i = 0; i < limits.size(); ++i) {
481 Bcharge.defineType(Form(
"B0_%u", i));
482 Bcharge.defineType(Form(
"Bp_%u", i));
485 RooDataSet* combData =
nullptr;
487 map<string, RooDataSet*> dataSetMap;
488 for (
unsigned i = 0; i < limits.size(); ++i) {
489 dataSetMap[Form(
"B0_%u", i)] = dataE0[i];
490 dataSetMap[Form(
"Bp_%u", i)] = dataEp[i];
492 combData =
new RooDataSet(
"combData",
"combined data", eNow, Index(Bcharge), Import(dataSetMap));
497 RooRealVar sigwidth(
"#sigma",
"width of B-meson energy in CMS", sigmaInit, 0.0001, 0.030) ;
499 vector<RooRealVar*> sigmean(limits.size());
500 vector<RooGaussian*> gauss(limits.size());
504 for (
unsigned i = 0; i < limits.size(); ++i) {
505 sigmean[i] =
new RooRealVar(Form(
"Mean_%u", i),
"mean B-meson energy in CMS", meanInit, 5.27, 5.30) ;
506 gauss[i] =
new RooGaussian(Form(
"gauss_%u", i),
"gaussian PDF", eNow, *sigmean[i], sigwidth) ;
512 RooRealVar argpar(
"Argus_param",
"argus shape parameter", argparInit, -300., +50.0) ;
513 RooRealVar endpointBp(
"EndPointBp",
"endPoint parameter", cMBp, 5.27, 5.291) ;
514 RooRealVar endpointB0(
"EndPointB0",
"endPoint parameter", cMB0, 5.27, 5.291) ;
515 endpointB0.setConstant(kTRUE);
516 endpointBp.setConstant(kTRUE);
519 RooRealVar zero(
"zero",
"", 0);
520 RooRealVar two(
"two",
"", 2);
521 RooRealVar minus(
"minus",
"", -1);
524 RooPolyVar shape2B0(
"EndPoint2B0",
"shape parameter", endpointB0, RooArgSet(zero, two));
525 RooPolyVar eNowDifB0(
"eNowDifB0",
"eNowDifB0", eNow, RooArgSet(shape2B0, minus));
526 RooArgusBG argusB0(
"argusB0",
"Argus PDF", eNowDifB0, endpointB0, argpar) ;
529 RooPolyVar shape2Bp(
"EndPoint2Bp",
"shape parameter", endpointBp, RooArgSet(zero, two));
530 RooPolyVar eNowDifBp(
"eNowDifBp",
"eNowDifBp", eNow, RooArgSet(shape2Bp, minus));
531 RooArgusBG argusBp(
"argusBp",
"Argus PDF", eNowDifBp, endpointBp, argpar) ;
534 vector<RooRealVar*> nsigB0(limits.size());
535 vector<RooRealVar*> nbkgB0(limits.size());
537 vector<RooRealVar*> nsigBp(limits.size());
538 vector<RooRealVar*> nbkgBp(limits.size());
540 vector<RooAddPdf*> sumB0(limits.size());
541 vector<RooAddPdf*> sumBp(limits.size());
545 for (
unsigned i = 0; i < limits.size(); ++i) {
546 nsigB0[i] =
new RooRealVar(Form(
"nsigB0_%u", i),
"#signal events", 100, 0., 100000);
547 nbkgB0[i] =
new RooRealVar(Form(
"nbkgB0_%u", i),
"#background events", 100, 0., 500000) ;
549 nsigBp[i] =
new RooRealVar(Form(
"nsigBp_%u", i),
"#signal events", 100, 0., 100000) ;
550 nbkgBp[i] =
new RooRealVar(Form(
"nbkgBp_%u", i),
"#background events", 100, 0., 500000) ;
552 sumB0[i] =
new RooAddPdf(Form(
"sumB0_%u", i),
"g0+a0", RooArgList(*gauss[i], argusB0), RooArgList(*nsigB0[i], *nbkgB0[i]));
553 sumBp[i] =
new RooAddPdf(Form(
"sumBp_%u", i),
"gP+aP", RooArgList(*gauss[i], argusBp), RooArgList(*nsigBp[i], *nbkgBp[i]));
559 RooSimultaneous simPdf(
"simPdf",
"simultaneous pdf", Bcharge) ;
562 for (
unsigned i = 0; i < limits.size(); ++i) {
563 simPdf.addPdf(*sumB0[i], Form(
"B0_%u", i));
564 simPdf.addPdf(*sumBp[i], Form(
"Bp_%u", i));
567 RooRealVar shift(
"shift",
"shift to mumu", shiftInit, -30e-3, 30e-3);
569 vector<RooGaussian*> fconstraint(limits.size());
570 vector<RooPolyVar*> shiftNow(limits.size());
572 for (
unsigned i = 0; i < limits.size(); ++i) {
573 shiftNow[i] =
new RooPolyVar(Form(
"shiftNow_%u", i),
"shiftShift", shift, RooArgSet(RooConst(mumuVals[i].first), RooConst(1.)));
575 fconstraint[i] =
new RooGaussian(Form(
"fconstraint_%u", i),
"fconstraint", *sigmean[i], *shiftNow[i],
576 RooConst(mumuVals[i].second / 1.)) ;
580 RooArgSet constraintSet;
581 for (
auto& c : fconstraint) {
582 constraintSet.add(*c);
584 simPdf.fitTo(*combData, ExternalConstraints(constraintSet));
587 map<TString, pair<double, double>> resMap;
588 for (
unsigned i = 0; i < limits.size(); ++i) {
589 resMap[Form(
"sigmean_%u", i)] = {sigmean[i]->getValV(), sigmean[i]->getError()};
590 resMap[Form(
"pull_%u", i)] = { (sigmean[i]->getValV() - shift.getValV() - mumuVals[i].first) / mumuVals[i].second, 0};
593 resMap[
"sigwidth"] = {sigwidth.getValV(), sigwidth.getError()};
594 resMap[
"argpar"] = {argpar.getValV(), argpar.getError()};
595 resMap[
"shift"] = {shift.getValV(), shift.getError()};
598 namespace fs = std::filesystem;
599 fs::create_directories(
"plotsHadB");
601 for (
unsigned i = 0; i < limits.size(); ++i) {
602 plotArgusFit(dataE0[i], *sumB0[i], argusB0, *gauss[i], eNow, Form(
"plotsHadB/B0_%d_%u.pdf",
int(round(limits[0].first)), i));
603 plotArgusFit(dataEp[i], *sumBp[i], argusBp, *gauss[i], eNow, Form(
"plotsHadB/Bp_%d_%u.pdf",
int(round(limits[0].first)), i));
608 for (
unsigned i = 0; i < limits.size(); ++i) {
623 delete fconstraint[i];
641 vector<vector<double>> doBhadFit(
const vector<Event>& evts, vector<pair<double, double>> limits,
642 vector<pair<double, double>> mumuVals,
const vector<double>& startPars)
645 auto r = argusFitConstrained(evts, limits, mumuVals, startPars);
646 assert(limits.size() == mumuVals.size());
648 vector<vector<double>> result(limits.size());
651 for (
unsigned i = 0; i < limits.size(); ++i) {
652 string n = Form(
"sigmean_%u", i);
653 string np = Form(
"pull_%u", i);
656 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};
664 vector<double> doBhadOnlyFit(
const vector<Event>& evts,
const vector<pair<double, double>>& limits)
667 auto r = argusFit(evts, limits);
669 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};
TString rn()
Get random string.