ROOT Analysis for the Inclusive Detachted Dilepton Trigger Lines
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

636 lines
23 KiB

6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
6 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
7 months ago
  1. #ifndef BASIC_ANALYSIS
  2. #define BASIC_ANALYSIS
  3. #include <string>
  4. #include <iostream>
  5. #include <cmath>
  6. #include <algorithm>
  7. #include <filesystem>
  8. #include <string_view>
  9. #include "TTree.h"
  10. #include "RooHist.h"
  11. #include "constants.h"
  12. std::pair<double, double> DivWithErr(double x, double dx, double y, double dy) {
  13. double err_x = (1 / y) * dx;
  14. double err_y = - (x / (y*y)) * dy;
  15. return std::make_pair(x / y, TMath::Sqrt((TMath::Sq(err_x) + TMath::Sq(err_y))));
  16. }
  17. std::pair<double, double> MultWithErr(double x, double dx, double y, double dy) {
  18. double err_x = y * dx;
  19. double err_y = - x * dy;
  20. return std::make_pair(x * y, TMath::Sqrt((TMath::Sq(err_x) + TMath::Sq(err_y))));
  21. }
  22. double RoundUp(double x, int n = 0) {
  23. if(std::abs(x) > std::numeric_limits<double>::max() / n) // v * p would overflow
  24. throw std::overflow_error("rounding would overflow");
  25. const double multiplier = std::pow(10.0, n);
  26. return std::ceil(x * multiplier) / multiplier;
  27. }
  28. double RoundDown(double x, int n = 0) {
  29. if(std::abs(x) > std::numeric_limits<double>::max() / n) // v * p would overflow
  30. throw std::overflow_error("rounding would overflow");
  31. const double multiplier = std::pow(10.0, n);
  32. return std::floor(x * multiplier) / multiplier;
  33. }
  34. double Round(double x, int n = 0) {
  35. if(std::abs(x) > std::numeric_limits<double>::max() / n) // v * p would overflow
  36. throw std::overflow_error("rounding would overflow");
  37. const double multiplier = std::pow(10.0, n);
  38. return std::round(x * multiplier) / multiplier;
  39. }
  40. std::string ErrToStr(double val, double err, int n) {
  41. return TString::Format("%.*f #pm %.*f", n, Round(val, n), n, RoundUp(err, n)).Data();
  42. }
  43. std::string ErrToStr(std::pair<double, double> val_err, int n) {
  44. return ErrToStr(val_err.first, val_err.second, n);
  45. }
  46. std::pair<double, double> CalcSignificance(double sig_val, double sig_err, double bkg_val, double bkg_err) {
  47. double significance_val = sig_val / TMath::Sqrt(sig_val + bkg_val);
  48. double err_prop_sig = (sig_val + 2 * bkg_val) / (2 * TMath::Power((sig_val + bkg_val), (3 / 2)));
  49. double err_prop_bkg = -sig_val / (2 * TMath::Power((sig_val + bkg_val), (3 / 2)));
  50. double significance_err = TMath::Sqrt(TMath::Sq(err_prop_sig * sig_err) + TMath::Sq(err_prop_bkg * bkg_err));
  51. return std::make_pair(significance_val, significance_err);
  52. }
  53. class FourVect
  54. {
  55. private:
  56. Float_t px, py, pz, energy;
  57. Float_t *PtrPX()
  58. {
  59. return &px;
  60. }
  61. Float_t *PtrPY()
  62. {
  63. return &py;
  64. }
  65. Float_t *PtrPZ()
  66. {
  67. return &pz;
  68. }
  69. Float_t *PtrEnergy()
  70. {
  71. return &energy;
  72. }
  73. public:
  74. static FourVect *Init(TTree *tree, const char *particle)
  75. {
  76. FourVect *v = new FourVect{};
  77. tree->SetBranchAddress(TString::Format("%s_PX", particle).Data(), v->PtrPX());
  78. tree->SetBranchAddress(TString::Format("%s_PY", particle).Data(), v->PtrPY());
  79. tree->SetBranchAddress(TString::Format("%s_PZ", particle).Data(), v->PtrPZ());
  80. tree->SetBranchAddress(TString::Format("%s_ENERGY", particle).Data(), v->PtrEnergy());
  81. return v;
  82. }
  83. TLorentzVector LorentzVector()
  84. {
  85. return TLorentzVector(px, py, pz, energy);
  86. }
  87. TLorentzVector LorentzVector(double sub_mass)
  88. {
  89. TVector3 momentum(px, py, pz);
  90. float energy = TMath::Sqrt(TMath::Sq(sub_mass) + momentum.Mag2());
  91. return TLorentzVector(momentum, energy);
  92. }
  93. std::string ToString()
  94. {
  95. return TString::Format("(%f, %f, %f, %f)", px, py, pz, energy).Data();
  96. }
  97. };
  98. struct FittedParam
  99. {
  100. std::string title;
  101. std::string name;
  102. double value;
  103. double error;
  104. bool at_limit;
  105. bool constant;
  106. int decimals;
  107. bool print_const;
  108. bool ignore_print;
  109. FittedParam(RooRealVar var, int decimals, bool print_const = false, bool ignore_print = false)
  110. {
  111. this->title = var.GetTitle();
  112. this->name = var.GetName();
  113. double val = var.getVal();
  114. this->value = val;
  115. this->constant = var.isConstant();
  116. this->print_const = print_const;
  117. this->ignore_print = ignore_print;
  118. if (!this->constant)
  119. {
  120. this->error = var.getError();
  121. this->at_limit = ((val == var.getMin()) || (val == var.getMax()));
  122. }
  123. else
  124. {
  125. this->error = 0.;
  126. }
  127. this->decimals = decimals;
  128. }
  129. FittedParam(std::string name, std::string title, double value, double err, int decimals, bool ignore_print = false)
  130. {
  131. this->title = title;
  132. this->name = name;
  133. this->value = value;
  134. this->error = err;
  135. this->decimals = decimals;
  136. this->constant = false;
  137. this->at_limit = false;
  138. this->ignore_print = ignore_print;
  139. }
  140. std::string ToString(bool latex = false) const
  141. {
  142. if (this->constant)
  143. {
  144. return TString::Format("%s = %.*f (c)", this->title.c_str(), this->decimals, this->value).Data();
  145. }
  146. else
  147. {
  148. if (this->error == 0) {
  149. return TString::Format("%s = %.*f", this->title.c_str(), this->decimals, this->value).Data();
  150. }
  151. else {
  152. return TString::Format("%s = %.*f %s %.*f", this->title.c_str(), this->decimals, this->value, (latex ? "\\pm" : "#pm"), this->decimals, this->error).Data();
  153. }
  154. }
  155. }
  156. };
  157. struct ShapeParamters
  158. {
  159. double alpha_left;
  160. double n_left;
  161. double alpha_right;
  162. double n_right;
  163. double sigma_lr;
  164. std::string ToString() {
  165. return TString::Format("aL: %.2f\nnL: %.2f\naR: %.2f\nnR: %.2f\nS: %.2f\n", this->alpha_left, this->n_left, this->alpha_right, this->n_right, this->sigma_lr).Data();
  166. }
  167. };
  168. struct RooFitSummary
  169. {
  170. RooPlot *fit_histogram;
  171. RooPlot *pull_histogram;
  172. std::map<std::string, std::string> pdf_names;
  173. std::pair<double, double> signal_yield;
  174. std::pair<double, double> background_yield;
  175. std::vector<FittedParam> fitted_params;
  176. ShapeParamters shape_parameters;
  177. };
  178. void DrawInDefaultCanvas(TH1 *histogram, const char *folder, double margin_left = 0.1, Option_t *option = "")
  179. {
  180. std::filesystem::create_directory(TString::Format("output_files/analysis/%s", folder).Data());
  181. TString name = TString::Format("%s_canvas", histogram->GetName());
  182. TCanvas *c = new TCanvas(name, histogram->GetName(), 0, 0, 800, 600);
  183. c->SetLeftMargin(margin_left);
  184. histogram->SetStats(0);
  185. histogram->Draw(option);
  186. c->Draw();
  187. c->SaveAs(TString::Format("output_files/analysis/%s/%s.pdf", folder, name.Data()).Data());
  188. }
  189. void DrawInDefaultCanvasStacked(std::vector<TH1D *> histograms, std::vector<Color_t> colors, std::vector<Style_t> fill_style, const char *folder, const char* title, double margin_left = 0.12, Option_t *option = "")
  190. {
  191. std::filesystem::create_directory(TString::Format("output_files/analysis/%s", folder).Data());
  192. TString name = TString::Format("%s_stack_canvas", histograms[0]->GetName());
  193. TCanvas *c = new TCanvas(name, histograms[0]->GetName(), 0, 0, 800, 600);
  194. c->SetLeftMargin(margin_left);
  195. Double_t max = 0;
  196. for (size_t i = 0; i < histograms.size(); i++)
  197. {
  198. if (histograms[i]->GetEntries() > max) {
  199. max = histograms[i]->GetEntries();
  200. }
  201. }
  202. TString stack_name = TString::Format("%s_stack", histograms[0]->GetName());
  203. TString stack_title = TString::Format("%s;%s;#Events normed to 1/%.0f", title, histograms[0]->GetXaxis()->GetTitle(), max);
  204. std::string drwopt_2 = std::string(option).empty() ? "HIST" : TString::Format("%s HIST", option).Data();
  205. auto stack = new THStack(stack_name, stack_title);
  206. for (size_t i = 0; i < histograms.size(); i++)
  207. {
  208. const Double_t scaling_factor = 1.;
  209. auto hist_clone = (TH1 *)histograms[i]->Clone(TString::Format("%s_clone", histograms[i]->GetName()));
  210. hist_clone->Scale(scaling_factor / max);
  211. hist_clone->SetLineColor(colors[i]);
  212. // hist_clone->SetMaximum(scaling_factor + (scaling_factor * 0.05));
  213. // hist_clone->SetMaximum(max + (max * 0.05));
  214. hist_clone->SetMinimum(0.);
  215. hist_clone->SetStats(0);
  216. if (fill_style[i] != 0)
  217. {
  218. hist_clone->SetFillStyle(fill_style[i]);
  219. hist_clone->SetFillColor(colors[i]);
  220. }
  221. if (i > 0)
  222. {
  223. stack->Add(hist_clone, drwopt_2.c_str());
  224. }
  225. else
  226. {
  227. stack->Add(hist_clone, drwopt_2.c_str());
  228. }
  229. }
  230. stack->Draw("NOSTACK");
  231. c->BuildLegend(0.55, 0.70, 0.87, 0.89);
  232. c->Draw();
  233. c->SaveAs(TString::Format("output_files/analysis/%s/%s.pdf", folder, name.Data()).Data());
  234. }
  235. void DrawInDefaultCanvas(RooPlot *rooPlot, const char *folder, double margin_left = 0, Option_t *option = "")
  236. {
  237. std::filesystem::create_directory(TString::Format("output_files/analysis/%s", folder).Data());
  238. TString name = TString::Format("%s_canvas", rooPlot->GetName());
  239. TCanvas *c = new TCanvas(name, rooPlot->GetName(), 0, 0, 800, 600);
  240. c->SetLeftMargin(margin_left);
  241. rooPlot->Draw(option);
  242. c->Draw();
  243. c->SaveAs(TString::Format("output_files/analysis/%s/%s.pdf", folder, name.Data()).Data());
  244. }
  245. void PrintStyles(RooPlot *plt)
  246. {
  247. auto Xaxis = plt->GetXaxis();
  248. auto Yaxis = plt->GetYaxis();
  249. std::cout << "## Styles for plot " << plt->GetName() << std::endl;
  250. std::cout << "## X axis\n"
  251. << "Label Size: " << Xaxis->GetLabelSize() << ",\n"
  252. << "Label Offset: " << Xaxis->GetLabelOffset() << ",\n"
  253. << "Title Size: " << Xaxis->GetTitleSize() << ",\n"
  254. << "Title Offset: " << Xaxis->GetTitleOffset() << "." << std::endl;
  255. std::cout << "## Y axis\n"
  256. << "Label Size: " << Yaxis->GetLabelSize() << ",\n"
  257. << "Label Offset: " << Yaxis->GetLabelOffset() << ",\n"
  258. << "Title Size: " << Yaxis->GetTitleSize() << ",\n"
  259. << "Title Offset: " << Yaxis->GetTitleOffset() << "." << std::endl;
  260. }
  261. void DrawInDefaultCanvas(RooFitSummary fitSummary, const char *folder)
  262. {
  263. std::filesystem::create_directory(TString::Format("output_files/analysis/%s", folder).Data());
  264. TString name = TString::Format("%s_canvas", fitSummary.fit_histogram->GetName());
  265. TCanvas *c = new TCanvas(name, fitSummary.fit_histogram->GetTitle(), 0, 0, 800, 600);
  266. Double_t xlow, ylow, xup, yup;
  267. c->GetPad(0)->GetPadPar(xlow, ylow, xup, yup);
  268. c->Divide(1, 2);
  269. Double_t upPad_ylow = ylow + 0.25 * (yup - ylow);
  270. Double_t dwPad_yup = ylow + 0.25 * (yup - ylow);
  271. TVirtualPad *upPad = c->GetPad(1);
  272. upPad->SetPad(xlow, upPad_ylow, xup, yup);
  273. TVirtualPad *dwPad = c->GetPad(2);
  274. dwPad->SetPad(xlow, ylow, xup, dwPad_yup);
  275. dwPad->SetTopMargin(0);
  276. Double_t upPad_area = (yup - upPad_ylow) * (xup - xlow);
  277. Double_t dwPad_area = (dwPad_yup - ylow) * (xup - xlow);
  278. // std::cout << "### UP AREA: " << upPad_area << " LOW AREA: " << dwPad_area << std::endl;
  279. const Double_t pull_title_size = 0.09;
  280. const Double_t pull_label_size = 0.09;
  281. Double_t fit_title_size = (pull_title_size * dwPad_area) / upPad_area;
  282. Double_t fit_label_size = (pull_label_size * dwPad_area) / upPad_area;
  283. c->cd(1);
  284. auto fit_Xaxis = fitSummary.fit_histogram->GetXaxis();
  285. auto fit_Yaxis = fitSummary.fit_histogram->GetYaxis();
  286. fit_Xaxis->SetLabelOffset(0.02);
  287. fit_Xaxis->SetLabelSize(fit_label_size);
  288. fit_Xaxis->SetTitleOffset(1.4);
  289. fit_Xaxis->SetTitleSize(fit_title_size);
  290. fit_Yaxis->SetLabelOffset(0.01);
  291. fit_Yaxis->SetLabelSize(fit_label_size);
  292. fit_Yaxis->SetTitleSize(fit_title_size);
  293. fit_Yaxis->SetTitleOffset(0);
  294. fitSummary.fit_histogram->Draw();
  295. TLegend *leg1 = new TLegend(0.55, 0.45, 0.87, 0.89);
  296. leg1->SetFillColor(kWhite);
  297. leg1->SetLineColor(kWhite);
  298. for (const auto &[name, title] : fitSummary.pdf_names)
  299. {
  300. leg1->AddEntry(fitSummary.fit_histogram->findObject(name.c_str()), title.c_str(), "LP");
  301. }
  302. for (const auto &par : fitSummary.fitted_params)
  303. {
  304. if ((!par.ignore_print) && ((!par.constant) || par.print_const))
  305. {
  306. leg1->AddEntry((TObject *)0, par.ToString().c_str(), "");
  307. }
  308. }
  309. leg1->Draw();
  310. c->cd(2);
  311. Double_t pull_min = fitSummary.pull_histogram->GetMinimum();
  312. Double_t pull_max = fitSummary.pull_histogram->GetMaximum();
  313. // std::cout << "### (" << fitSummary.pull_histogram->GetName() << ") PULL MIN: " << pull_min << " PULL MAX: " << pull_max << std::endl;
  314. double bound = 0;
  315. if (TMath::Abs(pull_min) > TMath::Abs(pull_max))
  316. {
  317. bound = TMath::Abs(pull_min);
  318. }
  319. else
  320. {
  321. bound = TMath::Abs(pull_max);
  322. }
  323. auto pull_Xaxis = fitSummary.pull_histogram->GetXaxis();
  324. auto pull_Yaxis = fitSummary.pull_histogram->GetYaxis();
  325. pull_Xaxis->SetLabelOffset(0.02);
  326. pull_Xaxis->SetLabelSize(pull_label_size);
  327. pull_Xaxis->SetTitleSize(pull_title_size);
  328. pull_Xaxis->SetTitle("");
  329. pull_Yaxis->SetLabelOffset(0.01);
  330. pull_Yaxis->SetLabelSize(pull_label_size);
  331. pull_Yaxis->SetTitleSize(pull_title_size);
  332. pull_Yaxis->SetTitleOffset(0.45);
  333. pull_Yaxis->SetTitle("Pull Distribution");
  334. fitSummary.pull_histogram->SetTitle("");
  335. fitSummary.pull_histogram->SetMaximum(bound);
  336. fitSummary.pull_histogram->SetMinimum(-bound);
  337. fitSummary.pull_histogram->Draw();
  338. auto line_mid = new TLine(B_MASS_VAR_MIN, 0, B_MASS_VAR_MAX, 0);
  339. line_mid->SetLineColor(kOrange + 4);
  340. line_mid->Draw();
  341. auto line_up = new TLine(B_MASS_VAR_MIN, bound / 2, B_MASS_VAR_MAX, bound / 2);
  342. line_up->SetLineStyle(kDashed);
  343. line_up->SetLineColor(kOrange + 4);
  344. line_up->Draw();
  345. auto line_low = new TLine(B_MASS_VAR_MIN, -bound / 2, B_MASS_VAR_MAX, -bound / 2);
  346. line_low->SetLineStyle(kDashed);
  347. line_low->SetLineColor(kOrange + 4);
  348. line_low->Draw();
  349. c->Draw();
  350. c->SaveAs(TString::Format("output_files/analysis/%s/%s.pdf", folder, name.Data()).Data());
  351. }
  352. void PrintProgress(const char *title, unsigned int total, unsigned int every, unsigned int current)
  353. {
  354. if ((current + 1) % every == 0 || current + 1 == total)
  355. {
  356. std::cout << "["
  357. << title
  358. << "] Processed event: " << current + 1 << " (" << TString::Format("%.2f", ((double)(current + 1) / (double)total) * 100.) << "%)" << std::endl;
  359. }
  360. }
  361. RooPlot *CreateRooFitHistogram(TH1D *hist)
  362. {
  363. RooRealVar roo_var_mass("var_mass", "B Mass Variable", B_MASS_VAR_MIN, B_MASS_VAR_MAX);
  364. roo_var_mass.setRange("fitting_range", B_MASS_FIT_MIN, B_MASS_FIT_MAX);
  365. RooDataHist roohist_B_M("roohist_B_M", "B Mass Histogram", roo_var_mass, RooFit::Import(*hist));
  366. RooPlot *roo_frame_mass = roo_var_mass.frame(RooFit::Title(hist->GetTitle()), RooFit::Name(TString::Format("%s_rplt", hist->GetName())));
  367. roohist_B_M.plotOn(roo_frame_mass, RooFit::Binning(B_MASS_HIST_BINS), RooFit::Name("B Mass Distribution"));
  368. roo_frame_mass->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
  369. return roo_frame_mass;
  370. }
  371. RooFitSummary CreateRooDataSetAndFitCB(TTree *dataSet, TString var_name, TString xAxis, bool hasExpBkg, bool useExtShape, ShapeParamters extShape, bool const_sigma = false, Double_t fit_low = 0, Double_t fit_up = 0)
  372. {
  373. auto suffix_name = [name = dataSet->GetName()](const char *text)
  374. {
  375. return TString::Format("%s_%s", text, name);
  376. };
  377. Double_t fitRangeUp = fit_low == 0 ? B_MASS_FIT_MIN : fit_low;
  378. Double_t fitRangeLow = fit_up == 0 ? B_MASS_FIT_MAX : fit_up;
  379. RooRealVar roo_var_mass(var_name, "B Mass Variable", B_MASS_VAR_MIN, B_MASS_VAR_MAX);
  380. const char *fitting_range_name = "fitting_range";
  381. roo_var_mass.setRange(fitting_range_name, fitRangeUp, fitRangeLow);
  382. const char *draw_range_name = "draw_range";
  383. roo_var_mass.setRange(draw_range_name, B_MASS_VAR_MIN, B_MASS_VAR_MAX);
  384. TString dataset_name = suffix_name("roodataset_B_M");
  385. // RooDataHist roodataset_B_M(hist_name, "B Mass Histogram", roo_var_mass, RooFit::Import(*hist));
  386. RooDataSet roodataset_B_M(dataset_name, "B Mass Data Set", roo_var_mass, RooFit::Import(*dataSet));
  387. RooPlot *roo_frame_mass = roo_var_mass.frame(RooFit::Title(dataSet->GetTitle()), RooFit::Name(TString::Format("%s_rplt", dataSet->GetName())));
  388. roodataset_B_M.plotOn(roo_frame_mass, RooFit::Name(dataset_name));
  389. roo_frame_mass->GetXaxis()->SetTitle(xAxis);
  390. // Crystal Ball for Signal
  391. RooRealVar var_mass_x0(suffix_name("var_mass_x0"), "#mu", 5278., 5170., 5500.);
  392. RooRealVar var_mass_sigmaLR(suffix_name("var_mass_sigmaLR"), "#sigma_{LR}", 16., 5., 40.);
  393. RooRealVar var_mass_alphaL(suffix_name("var_mass_alphaL"), "#alpha_{L}", 2., 0., 4.);
  394. RooRealVar var_mass_nL(suffix_name("var_mass_nL"), "n_{L}", 5., 0., 15.);
  395. RooRealVar var_mass_alphaR(suffix_name("var_mass_alphaR"), "#alpha_{R}", 2., 0., 4.);
  396. RooRealVar var_mass_nR(suffix_name("var_mass_nR"), "n_{R}", 5., 0., 15.);
  397. if (useExtShape)
  398. {
  399. if (extShape.alpha_left != 0.)
  400. {
  401. var_mass_alphaL.setConstant(true);
  402. var_mass_alphaL.setVal(extShape.alpha_left);
  403. }
  404. if (extShape.n_left != 0.)
  405. {
  406. var_mass_nL.setConstant(true);
  407. var_mass_nL.setVal(extShape.n_left);
  408. }
  409. if (extShape.alpha_right != 0.)
  410. {
  411. var_mass_alphaR.setConstant(true);
  412. var_mass_alphaR.setVal(extShape.alpha_right);
  413. }
  414. if (extShape.n_right != 0.)
  415. {
  416. var_mass_nR.setConstant(true);
  417. var_mass_nR.setVal(extShape.n_right);
  418. }
  419. if (extShape.sigma_lr != 0. && const_sigma)
  420. {
  421. var_mass_sigmaLR.setConstant(true);
  422. var_mass_sigmaLR.setVal(extShape.sigma_lr);
  423. }
  424. }
  425. TString signal_name = suffix_name("sig_cb");
  426. RooCrystalBall sig_cb(signal_name, "CB Signal", roo_var_mass, var_mass_x0, var_mass_sigmaLR, var_mass_alphaL, var_mass_nL, var_mass_alphaR, var_mass_nR);
  427. std::vector<FittedParam> fitted_params{};
  428. std::map<std::string, std::string> pdf_names{};
  429. pdf_names[signal_name.Data()] = sig_cb.getTitle().Data();
  430. TString pull_compare_name{};
  431. double sig_val = 0.;
  432. double sig_err = 0.;
  433. double bkg_val = 0.;
  434. double bkg_err = 0.;
  435. if (hasExpBkg)
  436. {
  437. // Exponential for Background
  438. RooRealVar var_mass_bkg_c(suffix_name("var_mass_bkg_c"), "#lambda", -0.0014, -0.004, -0.000);
  439. TString background_name = suffix_name("bgk_exp");
  440. RooExponential bkg_exp(background_name, "Exp Background", roo_var_mass, var_mass_bkg_c);
  441. pdf_names[background_name.Data()] = bkg_exp.getTitle().Data();
  442. RooRealVar var_mass_nsig(suffix_name("nsig"), "N_{Sig}", 0., dataSet->GetEntries());
  443. RooRealVar var_mass_nbkg(suffix_name("nbkg"), "N_{Bkg}", 0., dataSet->GetEntries());
  444. TString fitted_pdf_name = suffix_name("sigplusbkg");
  445. RooAddPdf fitted_pdf(fitted_pdf_name, "Sig + Bkg", RooArgList(sig_cb, bkg_exp), RooArgList(var_mass_nsig, var_mass_nbkg));
  446. pdf_names[fitted_pdf_name.Data()] = fitted_pdf.getTitle().Data();
  447. RooFitResult *fitres = fitted_pdf.fitTo(roodataset_B_M, RooFit::Save(), RooFit::PrintLevel(-1), RooFit::Range(fitting_range_name));
  448. // sigplusbkg.plotOn(roo_frame_mass, RooFit::VisualizeError(*fitres, 1), RooFit::FillColor(kOrange + 1), RooFit::FillStyle(3144));
  449. fitted_pdf.plotOn(roo_frame_mass, RooFit::LineColor(kRed), RooFit::LineStyle(kSolid), RooFit::Range(draw_range_name), RooFit::Name(fitted_pdf_name));
  450. fitted_pdf.plotOn(roo_frame_mass, RooFit::Components(RooArgSet(bkg_exp)), RooFit::LineColor(kBlue - 7), RooFit::LineStyle(kDashed), RooFit::Range(draw_range_name), RooFit::Name(background_name));
  451. fitted_pdf.plotOn(roo_frame_mass, RooFit::Components(RooArgSet(sig_cb)), RooFit::LineColor(kRed - 7), RooFit::LineStyle(kDashed), RooFit::Range(draw_range_name), RooFit::Name(signal_name));
  452. fitted_params.push_back(FittedParam(var_mass_nsig, 0));
  453. fitted_params.push_back(FittedParam(var_mass_nbkg, 0));
  454. double mu_val = var_mass_x0.getVal();
  455. double sigma_val = var_mass_sigmaLR.getVal();
  456. sig_val = var_mass_nsig.getVal();
  457. sig_err = var_mass_nsig.getError();
  458. bkg_val = var_mass_nbkg.getVal();
  459. bkg_err = var_mass_nbkg.getError();
  460. double sig_bkg_sum_val = sig_val + bkg_val;
  461. double sig_bkg_sum_err = TMath::Sqrt(TMath::Sq(sig_err) + TMath::Sq(bkg_err));
  462. const int sigma_space = 2;
  463. double int_lo = mu_val - sigma_space * sigma_val;
  464. double int_up = mu_val + sigma_space * sigma_val;
  465. roo_var_mass.setRange("peak_integral_range", int_lo, int_up);
  466. std::cout << "#### Integral Over: " << int_lo << " -> " << int_up << std::endl;
  467. auto bkg_int = bkg_exp.createIntegral(roo_var_mass, RooFit::NormSet(roo_var_mass), RooFit::Range("peak_integral_range"));
  468. auto bkg_yield_under_sig = std::make_pair(bkg_int->getVal() * sig_bkg_sum_val, bkg_int->getVal() * sig_bkg_sum_err);
  469. fitted_params.push_back(FittedParam("bkg_int_sig", TString::Format("N_{Bkg,%d#sigma}", sigma_space).Data(), bkg_yield_under_sig.first, bkg_yield_under_sig.second, 0));
  470. auto significance = CalcSignificance(sig_val, sig_err, bkg_val, bkg_err);
  471. auto sig_over_bkg_3sig = DivWithErr(sig_val, sig_err, bkg_yield_under_sig.first, bkg_yield_under_sig.second);
  472. auto sig_over_bkg_full = DivWithErr(sig_val, sig_err, bkg_val, bkg_err);
  473. // fitted_params.push_back(FittedParam("significance", "N_{Sig}/#sqrt{N_{Sig} + N_{Bkg}}", significance.first, significance.second, 2));
  474. fitted_params.push_back(FittedParam("sig_over_bkg", "N_{Sig}/N_{Bkg}", sig_over_bkg_full.first, sig_over_bkg_full.second, 2, true));
  475. fitted_params.push_back(FittedParam("sig_over_bkg", TString::Format("N_{Sig}/N_{Bkg,%d#sigma}", sigma_space).Data(), sig_over_bkg_3sig.first, sig_over_bkg_3sig.second, 2, true));
  476. fitted_params.push_back(FittedParam(var_mass_bkg_c, 5));
  477. pull_compare_name = fitted_pdf_name;
  478. }
  479. else
  480. {
  481. RooFitResult *fitres = sig_cb.fitTo(roodataset_B_M, RooFit::Save(), RooFit::PrintLevel(-1), RooFit::Range(fitting_range_name));
  482. // sigplusbkg.plotOn(roo_frame_mass, RooFit::VisualizeError(*fitres, 1), RooFit::FillColor(kOrange + 1), RooFit::FillStyle(3144));
  483. sig_cb.plotOn(roo_frame_mass, RooFit::LineColor(kRed), RooFit::LineStyle(kSolid), RooFit::Range(draw_range_name), RooFit::Name(signal_name));
  484. pull_compare_name = signal_name;
  485. }
  486. fitted_params.push_back(FittedParam(var_mass_x0, 2));
  487. fitted_params.push_back(FittedParam(var_mass_sigmaLR, 2, true));
  488. fitted_params.push_back(FittedParam(var_mass_alphaL, 2));
  489. fitted_params.push_back(FittedParam(var_mass_nL, 2));
  490. fitted_params.push_back(FittedParam(var_mass_alphaR, 2));
  491. fitted_params.push_back(FittedParam(var_mass_nR, 2));
  492. RooPlot *roo_frame_pull = roo_var_mass.frame(RooFit::Title("Pull Distribution"), RooFit::Name(TString::Format("%s_pull_rplt", dataSet->GetName())));
  493. RooHist *pull_hist = roo_frame_mass->pullHist(dataset_name, pull_compare_name);
  494. roo_frame_pull->addPlotable(pull_hist, "P");
  495. // Double_t pull_min = pull_hist->GetMinimum();
  496. // Double_t pull_max = pull_hist->GetMaximum();
  497. // std::cout << "##### (" << pull_hist->GetName() << ") PULL MIN: " << pull_min << " PULL MAX: " << pull_max << std::endl;
  498. return RooFitSummary{
  499. roo_frame_mass,
  500. roo_frame_pull,
  501. pdf_names,
  502. std::make_pair(sig_val, sig_err),
  503. std::make_pair(bkg_val, bkg_err),
  504. fitted_params,
  505. ShapeParamters{
  506. var_mass_alphaL.getVal(),
  507. var_mass_nL.getVal(),
  508. var_mass_alphaR.getVal(),
  509. var_mass_nR.getVal(),
  510. var_mass_sigmaLR.getVal()}};
  511. }
  512. bool InRange(double value, double center, double low_intvl, double up_intvl)
  513. {
  514. return center - low_intvl < value && value < center + up_intvl;
  515. }
  516. bool InRange(double value, double center, double intvl)
  517. {
  518. return InRange(value, center, intvl, intvl);
  519. }
  520. #endif