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.

308 lines
11 KiB

7 months ago
  1. #include <string>
  2. #include <iostream>
  3. #include <cmath>
  4. #include <algorithm>
  5. #include <filesystem>
  6. #include <string_view>
  7. #include "TH1D.h"
  8. #include "TH2D.h"
  9. #include "THStack.h"
  10. #include "TGraph.h"
  11. #include "TTree.h"
  12. #include "TChain.h"
  13. #include "TFile.h"
  14. #include "TCanvas.h"
  15. #include "TROOT.h"
  16. #include "TStyle.h"
  17. #include "TColor.h"
  18. #include "TLorentzVector.h"
  19. #include "TRandom3.h"
  20. #include "TLegend.h"
  21. #include "RooDataHist.h"
  22. #include "RooRealVar.h"
  23. #include "RooPlot.h"
  24. #include "RooGaussian.h"
  25. #include "RooExponential.h"
  26. #include "RooRealConstant.h"
  27. #include "RooAddPdf.h"
  28. #include "RooFitResult.h"
  29. #include "RooProduct.h"
  30. #include "RooCrystalBall.h"
  31. #include "RooBreitWigner.h"
  32. #include "RooArgSet.h"
  33. #include "RooFFTConvPdf.h"
  34. #include "RooNovosibirsk.h"
  35. #include "constants.h"
  36. #include "basic_analysis.h"
  37. #include "hlt1_decision_analysis.h"
  38. #include "bdt_classification.h"
  39. // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Inclusive :: B0 To Hp Hm Mu Mu %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  40. int new_analysis_b02hphmmumu()
  41. {
  42. const char *analysis_name = "B0ToHpHmMuMu";
  43. const char *data_tree_name = "B0ToHpHmMuMu";
  44. const char *sim_tree_name = "B0ToHpHmMuMu_noPID";
  45. const char *end_state_mass_literal = "m(#pi^{+}_{(#rightarrow K^{+})}#pi^{-}_{(#rightarrow K^{-})}#mu^{+}#mu^{-})";
  46. const bool retrain_bdt = true;
  47. TChain *data_chain = new TChain(TString::Format("%s/DecayTree", data_tree_name));
  48. // data_chain->Add("/auto/data/pfeiffer/inclusive_detached_dilepton/data_samples/spruce_magdown_2023_v0_tuple_90000000_v0r0p6288631.root");
  49. data_chain->Add("/auto/data/pfeiffer/inclusive_detached_dilepton/data_samples/spruce_magdown_2023_v0r1_tuple_90000000_2023_v0r0p6288631.root");
  50. Double_t Hp_PID_K, Hm_PID_K;
  51. data_chain->SetBranchAddress("Hp_PID_K", &Hp_PID_K);
  52. data_chain->SetBranchAddress("Hm_PID_K", &Hm_PID_K);
  53. FourVect *l14v_data = FourVect::Init(data_chain, "L1");
  54. FourVect *l24v_data = FourVect::Init(data_chain, "L2");
  55. FourVect *hp4v_data = FourVect::Init(data_chain, "Hp");
  56. FourVect *hm4v_data = FourVect::Init(data_chain, "Hm");
  57. TChain *sim_chain = new TChain(TString::Format("%s/DecayTree", sim_tree_name));
  58. sim_chain->Add("/auto/data/pfeiffer/inclusive_detached_dilepton/MC/rd_btoxll_simulation_fullstream_v0r0p6671378_B0ToKpPimMuMu_11144002_magdown.root");
  59. FourVect *l14v_sim = FourVect::Init(sim_chain, "L1");
  60. FourVect *l24v_sim = FourVect::Init(sim_chain, "L2");
  61. FourVect *hp4v_sim = FourVect::Init(sim_chain, "Hp");
  62. FourVect *hm4v_sim = FourVect::Init(sim_chain, "Hm");
  63. Int_t B_BKGCAT, L1_TRUEID, L2_TRUEID, Hp_TRUEID, Hm_TRUEID;
  64. sim_chain->SetBranchAddress("L1_TRUEID", &L1_TRUEID);
  65. sim_chain->SetBranchAddress("L2_TRUEID", &L2_TRUEID);
  66. sim_chain->SetBranchAddress("Hp_TRUEID", &Hp_TRUEID);
  67. sim_chain->SetBranchAddress("Hm_TRUEID", &Hm_TRUEID);
  68. sim_chain->SetBranchAddress("B0_BKGCAT", &B_BKGCAT);
  69. TH1D *h1_B_Mass_jpsi = new TH1D("h1_B_Mass_jpsi", TString::Format("B Mass, J/#psi Mode (%s)", analysis_name), B_MASS_HIST_BINS, B_MASS_VAR_MIN, B_MASS_VAR_MAX);
  70. TH1D *h1_B_Mass_psi2s = new TH1D("h1_B_Mass_psi2s", TString::Format("B Mass, #psi(2S) Mode (%s)", analysis_name), B_MASS_HIST_BINS, B_MASS_VAR_MIN, B_MASS_VAR_MAX);
  71. TH1D *h1_B_Mass_sim = new TH1D("h1_B_Mass_sim", TString::Format("B Mass, Simualted (%s_noPID)", analysis_name), B_MASS_HIST_BINS, B_MASS_VAR_MIN, B_MASS_VAR_MAX);
  72. TH2D *h2_Hlt1_flags_B_Mass = new TH2D("h2_Hlt1_flags_B_Mass", "Hlt1 Decision vs B Mass", 50, 5100, 5400, 13, 1., 14.);
  73. TH2D *h2_Hlt1_flags_excl_B_Mass = new TH2D("h2_Hlt1_flags_excl_B_Mass", "Excl Hlt1 Decision vs B Mass", 50, 5100, 5400, 13, 1., 14.);
  74. TH1D *h1_bdt_probs = new TH1D("h1_bdt_probs", "BDT Probabilities", 100, -1, 1);
  75. h1_B_Mass_jpsi->GetXaxis()->SetTitle(end_state_mass_literal);
  76. h1_B_Mass_psi2s->GetXaxis()->SetTitle(end_state_mass_literal);
  77. h2_Hlt1_flags_B_Mass->GetXaxis()->SetTitle(end_state_mass_literal);
  78. h2_Hlt1_flags_excl_B_Mass->GetXaxis()->SetTitle(end_state_mass_literal);
  79. ConnectHlt1Decisions(data_chain, h2_Hlt1_flags_B_Mass, h2_Hlt1_flags_excl_B_Mass);
  80. auto hlt1_decision_histos = CreateHlt1DecisionHistos(analysis_name);
  81. std::map<std::string, int> exclusive_hits{};
  82. std::vector<TV *> vars{
  83. TV::Float("B0_PT", "B0_PT"),
  84. TV::Float("B0_BPVFDCHI2", "B0_BPVFDCHI2"),
  85. TV::Float("B0_BPVDIRA", "B0_BPVDIRA"),
  86. TV::Float("Jpsi_BPVIPCHI2", "Jpsi_BPVIPCHI2"),
  87. // TV::Float("Jpsi_BPVDIRA", "Jpsi_BPVDIRA"),
  88. TV::Float("Jpsi_PT", "Jpsi_PT"),
  89. TV::Float("Hp_BPVIPCHI2", "Hp_BPVIPCHI2"),
  90. TV::Float("Hp_PT", "Hp_PT"),
  91. TV::Float("Hm_BPVIPCHI2", "Hm_BPVIPCHI2"),
  92. TV::Float("Hm_PT", "Hm_PT"),
  93. // TV::Double("Kplus_PID_K", "K_PID_K"),
  94. TV::Double("Hp_PROBNN_K", "Hp_PROBNN_K"),
  95. TV::Double("Hm_PROBNN_K", "Hm_PROBNN_K"),
  96. TV::Float("L1_BPVIPCHI2", "L1_BPVIPCHI2"),
  97. TV::Float("L2_BPVIPCHI2", "L2_BPVIPCHI2"),
  98. };
  99. TTree *sig_tree = new TTree("TreeS", "tree containing signal data");
  100. TTree *bkg_tree = new TTree("TreeB", "tree containing background data");
  101. ConnectVarsToData(vars, data_chain, sim_chain, sig_tree, bkg_tree);
  102. unsigned int data_entries = data_chain->GetEntries();
  103. unsigned int sim_entries = 100000; // sim_chain->GetEntries();
  104. unsigned int bkg_events = 0;
  105. if (retrain_bdt)
  106. {
  107. std::cout << "# Starting with BDT retrain." << std::endl;
  108. for (unsigned int i = 0; i < data_entries; i++)
  109. {
  110. data_chain->GetEntry(i);
  111. TLorentzVector reconstructed_Kstar{};
  112. bool found_k_star = false;
  113. if (Hp_PID_K > 0 && Hm_PID_K < 0)
  114. {
  115. reconstructed_Kstar = hp4v_data->LorentzVector(K_MASS) + hm4v_data->LorentzVector();
  116. found_k_star = true;
  117. }
  118. else if (Hm_PID_K > 0 && Hp_PID_K < 0)
  119. {
  120. reconstructed_Kstar = hp4v_data->LorentzVector() + hm4v_data->LorentzVector(K_MASS);
  121. found_k_star = true;
  122. }
  123. if (found_k_star)
  124. {
  125. Double_t reconstructed_B_Mass = (reconstructed_Kstar + l14v_data->LorentzVector() + l24v_data->LorentzVector()).M();
  126. if (std::all_of(vars.begin(), vars.end(), [](TV *v)
  127. { return v->IsDataFinite(); }))
  128. {
  129. if (reconstructed_B_Mass > 5500.)
  130. {
  131. bkg_tree->Fill();
  132. bkg_events++;
  133. }
  134. }
  135. }
  136. PrintProgress(TString::Format("%s BKG Collection", analysis_name), data_entries, 10000, i);
  137. }
  138. }
  139. else
  140. {
  141. std::cout << "# Starting without BDT retrain." << std::endl;
  142. }
  143. for (unsigned int i = 0; i < sim_entries; i++)
  144. {
  145. sim_chain->GetEntry(i);
  146. if (B_BKGCAT == 30 && TMath::Abs(L1_TRUEID) == PID_MUON && L2_TRUEID == -L1_TRUEID)
  147. {
  148. TLorentzVector reconstructed_Kstar{};
  149. bool found_k_star = false;
  150. if (TMath::Abs(Hp_TRUEID) == PID_KAON && TMath::Abs(Hm_TRUEID) == PID_PION)
  151. {
  152. reconstructed_Kstar = hp4v_sim->LorentzVector(K_MASS) + hm4v_sim->LorentzVector();
  153. found_k_star = true;
  154. }
  155. else if (TMath::Abs(Hp_TRUEID) == PID_PION && TMath::Abs(Hm_TRUEID) == PID_KAON)
  156. {
  157. reconstructed_Kstar = hp4v_sim->LorentzVector() + hm4v_sim->LorentzVector(K_MASS);
  158. found_k_star = true;
  159. }
  160. if (found_k_star)
  161. {
  162. Double_t reconstructed_B_Mass = (reconstructed_Kstar + l14v_sim->LorentzVector() + l24v_sim->LorentzVector()).M();
  163. if (std::all_of(vars.begin(), vars.end(), [](TV *v)
  164. { return v->IsMCFinite(); }))
  165. {
  166. if (retrain_bdt)
  167. {
  168. sig_tree->Fill();
  169. }
  170. h1_B_Mass_sim->Fill(reconstructed_B_Mass);
  171. }
  172. }
  173. }
  174. PrintProgress(TString::Format("%s SIG Collection", analysis_name), sim_entries, 10000, i);
  175. }
  176. if (retrain_bdt)
  177. {
  178. TrainBDT(vars, analysis_name, sig_tree, bkg_tree);
  179. std::cout << "# Finished BDT retrain." << std::endl;
  180. }
  181. std::cout << "# Starting evaluation of data." << std::endl;
  182. Float_t *train_vars = new Float_t[vars.size()];
  183. auto reader = SetupReader(vars, train_vars, analysis_name);
  184. const double mva_cut_value = -0.12;
  185. for (unsigned int i = 0; i < data_entries; i++)
  186. {
  187. data_chain->GetEntry(i);
  188. TLorentzVector dimuon = l14v_data->LorentzVector() + l24v_data->LorentzVector();
  189. TLorentzVector reconstructed_Kstar{};
  190. bool found_k_star = false;
  191. if (Hp_PID_K > 0 && Hm_PID_K < 0)
  192. {
  193. reconstructed_Kstar = hp4v_data->LorentzVector(K_MASS) + hm4v_data->LorentzVector();
  194. found_k_star = true;
  195. }
  196. else if (Hm_PID_K > 0 && Hp_PID_K < 0)
  197. {
  198. reconstructed_Kstar = hp4v_data->LorentzVector() + hm4v_data->LorentzVector(K_MASS);
  199. found_k_star = true;
  200. }
  201. if (found_k_star)
  202. {
  203. Double_t reconstructed_B_Mass = (reconstructed_Kstar + dimuon).M();
  204. if (std::all_of(vars.begin(), vars.end(), [](TV *v)
  205. { return v->IsDataFinite(); }))
  206. {
  207. for (size_t j = 0; j < vars.size(); j++)
  208. {
  209. if (vars[j]->IsDouble())
  210. {
  211. train_vars[j] = vars[j]->GetDataDouble();
  212. }
  213. else if (vars[j]->IsFloat())
  214. {
  215. train_vars[j] = vars[j]->GetDataFloat();
  216. }
  217. }
  218. }
  219. if (TMath::Abs(dimuon.M() - JPSI_MASS) < 100.)
  220. {
  221. CheckHlt1Decisioins(h2_Hlt1_flags_B_Mass, h2_Hlt1_flags_excl_B_Mass, exclusive_hits, reconstructed_B_Mass);
  222. FillHlt1DecisionHistos(hlt1_decision_histos, reconstructed_B_Mass);
  223. }
  224. double mva_response = reader->EvaluateMVA("BDT");
  225. h1_bdt_probs->Fill(mva_response);
  226. if (mva_response > mva_cut_value)
  227. {
  228. if (TMath::Abs(reconstructed_Kstar.M() - KSTAR_MASS) < 100.)
  229. {
  230. if (TMath::Abs(dimuon.M() - JPSI_MASS) < 100.)
  231. {
  232. h1_B_Mass_jpsi->Fill(reconstructed_B_Mass);
  233. }
  234. else if (TMath::Abs(dimuon.M() - PSI2S_MASS) < 100.)
  235. {
  236. h1_B_Mass_psi2s->Fill(reconstructed_B_Mass);
  237. }
  238. }
  239. }
  240. }
  241. PrintProgress(TString::Format("%s BDT Evaluation", analysis_name), data_entries, 10000, i);
  242. }
  243. std::cout << "# Exclusive Hits" << std::endl;
  244. for (const auto &[line, hits] : exclusive_hits)
  245. {
  246. std::cout << line << ": " << hits << std::endl;
  247. }
  248. // DrawInDefaultCanvas(h2_Hlt1_flags_B_Mass, analysis_name, 0.16, "COLZ");
  249. // DrawInDefaultCanvas(h2_Hlt1_flags_excl_B_Mass, analysis_name, 0.16, "COLZ");
  250. DrawInDefaultCanvas(h1_B_Mass_jpsi, analysis_name, 0.1);
  251. DrawInDefaultCanvas(h1_B_Mass_psi2s, analysis_name, 0.1);
  252. auto roofit_hist_sim = CreateRooFitHistogramAndFitCB(h1_B_Mass_sim, false, false, ShapeParamters{});
  253. auto roofit_hist_jpsi_fitsum = CreateRooFitHistogramAndFitCB(h1_B_Mass_jpsi, true, true, roofit_hist_sim.shape_parameters);
  254. auto roofit_hist_psi2s_fitsum = CreateRooFitHistogramAndFitCB(h1_B_Mass_psi2s, true, true, roofit_hist_sim.shape_parameters);
  255. DrawInDefaultCanvas(roofit_hist_jpsi_fitsum, analysis_name);
  256. DrawInDefaultCanvas(roofit_hist_psi2s_fitsum, analysis_name);
  257. DrawInDefaultCanvas(roofit_hist_sim, analysis_name);
  258. // DrawHlt1DecisionHistos(analysis_name, hlt1_decision_histos);
  259. DrawBDTProbs(h1_bdt_probs, mva_cut_value, analysis_name);
  260. return 0;
  261. }