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.

478 lines
9.8 KiB

  1. #include "TH1D.h"
  2. #include "TH2D.h"
  3. #include "THStack.h"
  4. #include "TGraph.h"
  5. #include "TTree.h"
  6. #include "TChain.h"
  7. #include "TFile.h"
  8. #include "TCanvas.h"
  9. #include "TROOT.h"
  10. #include "TStyle.h"
  11. #include "TColor.h"
  12. #include "TLorentzVector.h"
  13. #include "TRandom3.h"
  14. #include "TLorentzVector.h"
  15. #include "TString.h"
  16. #include "RooDataHist.h"
  17. #include "RooRealVar.h"
  18. #include "RooPlot.h"
  19. #include "RooGaussian.h"
  20. #include "RooExponential.h"
  21. #include "RooRealConstant.h"
  22. #include "RooAddPdf.h"
  23. #include "RooFitResult.h"
  24. #include "RooProduct.h"
  25. #include "RooCrystalBall.h"
  26. #include "RooBreitWigner.h"
  27. #include "RooArgSet.h"
  28. #include "RooFFTConvPdf.h"
  29. #include "RooNovosibirsk.h"
  30. #include <string>
  31. #include <iostream>
  32. #include <cmath>
  33. #include <vector>
  34. template <typename T>
  35. class Cut
  36. {
  37. public:
  38. virtual bool Check(T y) = 0;
  39. virtual std::string ToString() = 0;
  40. };
  41. template <typename T>
  42. class LT : public Cut<T>
  43. {
  44. private:
  45. T value;
  46. public:
  47. LT(T val) : value{val}
  48. {
  49. }
  50. bool Check(T y)
  51. {
  52. return y < value;
  53. }
  54. std::string ToString()
  55. {
  56. return TString::Format("(x < %s)", std::to_string(value).c_str()).Data();
  57. }
  58. };
  59. template <typename T>
  60. class GT : public Cut<T>
  61. {
  62. private:
  63. T value;
  64. public:
  65. GT(T val) : value{val} {}
  66. bool Check(T y)
  67. {
  68. return y > value;
  69. }
  70. std::string ToString()
  71. {
  72. return TString::Format("(x > %s)", std::to_string(value).c_str()).Data();
  73. }
  74. };
  75. template <typename T>
  76. class EQ : public Cut<T>
  77. {
  78. private:
  79. T value;
  80. public:
  81. EQ(T val) : value{val} {}
  82. bool Check(T y)
  83. {
  84. return y == value;
  85. }
  86. std::string ToString()
  87. {
  88. return TString::Format("(x == %s)", std::to_string(value).c_str()).Data();
  89. }
  90. };
  91. template <typename T>
  92. class BT : public Cut<T>
  93. {
  94. private:
  95. T low;
  96. T up;
  97. public:
  98. BT(T lower, T upper) : low{lower}, up{upper} {}
  99. bool Check(T y)
  100. {
  101. return low < y && y < up;
  102. }
  103. std::string ToString()
  104. {
  105. return TString::Format("(x in [%s, %s])", std::to_string(low).c_str(), std::to_string(up).c_str()).Data();
  106. }
  107. };
  108. template <typename T>
  109. class Variable
  110. {
  111. private:
  112. const char *name;
  113. std::vector<Cut<T> *> cuts;
  114. T value;
  115. public:
  116. Variable()
  117. {
  118. }
  119. Variable(const char *name, std::vector<Cut<T> *> cuts)
  120. {
  121. this->name = name;
  122. this->cuts = cuts;
  123. }
  124. T *GetValuePtr()
  125. {
  126. return &value;
  127. }
  128. T GetValue() const
  129. {
  130. return value;
  131. }
  132. bool CheckCuts() const
  133. {
  134. for (int i = 0; i < cuts.size(); i++)
  135. {
  136. if (!cuts[i]->Check(value))
  137. {
  138. return false;
  139. }
  140. }
  141. return true;
  142. }
  143. };
  144. class VariableCollection
  145. {
  146. private:
  147. std::map<std::string, Variable<Double_t>> doubles;
  148. std::map<std::string, Variable<Float_t>> floats;
  149. std::map<std::string, Variable<Int_t>> ints;
  150. std::map<std::string, Variable<Bool_t>> bools;
  151. std::vector<std::vector<std::string>> trigger_cuts;
  152. TLorentzVector ComputeFourMomentum(const char *name, bool do_mass_sub, double subbed_mass)
  153. {
  154. std::string pxname = TString::Format("%s_PX", name).Data();
  155. std::string pyname = TString::Format("%s_PY", name).Data();
  156. std::string pzname = TString::Format("%s_PZ", name).Data();
  157. std::string ename = TString::Format("%s_ENERGY", name).Data();
  158. auto itx = floats.find(pxname);
  159. if (itx == floats.end())
  160. {
  161. return TLorentzVector{};
  162. }
  163. auto ity = floats.find(pyname);
  164. if (ity == floats.end())
  165. {
  166. return TLorentzVector{};
  167. }
  168. auto itz = floats.find(pzname);
  169. if (itz == floats.end())
  170. {
  171. return TLorentzVector{};
  172. }
  173. TVector3 momentum(itx->second.GetValue(), ity->second.GetValue(), itz->second.GetValue());
  174. double energy = 0;
  175. if (do_mass_sub)
  176. {
  177. energy = TMath::Sqrt(TMath::Sq(subbed_mass) + momentum.Mag2());
  178. }
  179. else
  180. {
  181. auto ite = floats.find(ename);
  182. if (ite == floats.end())
  183. {
  184. return TLorentzVector{};
  185. }
  186. energy = ite->second.GetValue();
  187. }
  188. return TLorentzVector(momentum, energy);
  189. }
  190. public:
  191. VariableCollection()
  192. {
  193. doubles = std::map<std::string, Variable<Double_t>>{};
  194. floats = std::map<std::string, Variable<Float_t>>{};
  195. ints = std::map<std::string, Variable<Int_t>>{};
  196. bools = std::map<std::string, Variable<Bool_t>>{};
  197. trigger_cuts = std::vector<std::vector<std::string>>{};
  198. }
  199. void Connect(TChain *chain)
  200. {
  201. for (auto &[key, var] : doubles)
  202. {
  203. chain->SetBranchAddress(key.c_str(), var.GetValuePtr());
  204. }
  205. for (auto &[key, var] : floats)
  206. {
  207. chain->SetBranchAddress(key.c_str(), var.GetValuePtr());
  208. }
  209. for (auto &[key, var] : ints)
  210. {
  211. chain->SetBranchAddress(key.c_str(), var.GetValuePtr());
  212. }
  213. for (auto &[key, var] : bools)
  214. {
  215. chain->SetBranchAddress(key.c_str(), var.GetValuePtr());
  216. }
  217. }
  218. void AddDouble(const char *name, const std::vector<Cut<Double_t> *> &cuts)
  219. {
  220. doubles[name] = Variable<Double_t>(name, cuts);
  221. }
  222. void AddFloat(const char *name, const std::vector<Cut<Float_t> *> &cuts)
  223. {
  224. floats[name] = Variable<Float_t>(name, cuts);
  225. }
  226. void AddInt(const char *name, const std::vector<Cut<Int_t> *> &cuts)
  227. {
  228. ints[name] = Variable<Int_t>(name, cuts);
  229. }
  230. void AddBool(const char *name, const std::vector<Cut<Bool_t> *> &cuts)
  231. {
  232. bools[name] = Variable<Bool_t>(name, cuts);
  233. }
  234. void AddTriggerCut(const std::vector<std::string> &triggers_list)
  235. {
  236. for (const auto &trig : triggers_list)
  237. {
  238. bools[trig.c_str()] = Variable<Bool_t>(trig.c_str(), {});
  239. }
  240. trigger_cuts.push_back(triggers_list);
  241. }
  242. void AddFourMomentumFor(const char *name)
  243. {
  244. std::string pxname = TString::Format("%s_PX", name).Data();
  245. std::string pyname = TString::Format("%s_PY", name).Data();
  246. std::string pzname = TString::Format("%s_PZ", name).Data();
  247. std::string ename = TString::Format("%s_ENERGY", name).Data();
  248. floats[pxname] = Variable<Float_t>(pxname.c_str(), {});
  249. floats[pyname] = Variable<Float_t>(pyname.c_str(), {});
  250. floats[pzname] = Variable<Float_t>(pzname.c_str(), {});
  251. floats[ename] = Variable<Float_t>(ename.c_str(), {});
  252. }
  253. Double_t GetDouble(const char *name) const
  254. {
  255. auto it = doubles.find(name);
  256. if (it != doubles.end())
  257. {
  258. return it->second.GetValue();
  259. }
  260. return 0;
  261. }
  262. Float_t GetFloat(const char *name) const
  263. {
  264. auto it = floats.find(name);
  265. if (it != floats.end())
  266. {
  267. return it->second.GetValue();
  268. }
  269. return 0;
  270. }
  271. Int_t GetInt(const char *name) const
  272. {
  273. auto it = ints.find(name);
  274. if (it != ints.end())
  275. {
  276. return it->second.GetValue();
  277. }
  278. return 0;
  279. }
  280. Bool_t GetBool(const char *name) const
  281. {
  282. auto it = bools.find(name);
  283. if (it != bools.end())
  284. {
  285. return it->second.GetValue();
  286. }
  287. return 0;
  288. }
  289. TLorentzVector GetFourMomentum(const char *name)
  290. {
  291. return ComputeFourMomentum(name, false, 0.);
  292. }
  293. TLorentzVector GetFourMomentumWithMassSub(const char *name, double subbed_mass)
  294. {
  295. return ComputeFourMomentum(name, true, subbed_mass);
  296. }
  297. bool CheckCuts() const
  298. {
  299. for (const auto &[key, var] : doubles)
  300. {
  301. if (!var.CheckCuts())
  302. {
  303. return false;
  304. }
  305. }
  306. for (const auto &[key, var] : floats)
  307. {
  308. if (!var.CheckCuts())
  309. {
  310. return false;
  311. }
  312. }
  313. for (const auto &[key, var] : ints)
  314. {
  315. if (!var.CheckCuts())
  316. {
  317. return false;
  318. }
  319. }
  320. for (const auto &[key, var] : bools)
  321. {
  322. if (!var.CheckCuts())
  323. {
  324. return false;
  325. }
  326. }
  327. for (const auto &triggers : trigger_cuts)
  328. {
  329. bool cut_okay = false;
  330. for (const auto &trigger : triggers)
  331. {
  332. cut_okay = cut_okay | this->GetBool(trigger.c_str());
  333. }
  334. if (!cut_okay)
  335. {
  336. return false;
  337. }
  338. }
  339. return true;
  340. }
  341. void PrintValues() const
  342. {
  343. for (const auto &[key, var] : doubles)
  344. {
  345. std::cout << key << ": " << var.GetValue() << std::endl;
  346. }
  347. for (const auto &[key, var] : floats)
  348. {
  349. std::cout << key << ": " << var.GetValue() << std::endl;
  350. }
  351. for (const auto &[key, var] : ints)
  352. {
  353. std::cout << key << ": " << var.GetValue() << std::endl;
  354. }
  355. for (const auto &[key, var] : bools)
  356. {
  357. std::cout << key << ": " << var.GetValue() << std::endl;
  358. }
  359. }
  360. };
  361. void BuToHpMuMu()
  362. {
  363. TChain *data_chain = new TChain("BuToHpMuMu/DecayTree");
  364. data_chain->Add("/auto/data/pfeiffer/inclusive_detached_dilepton/data_samples/spruce_magdown_2023_v0r1_tuple_90000000_2023_v0r0p6288631.root");
  365. data_chain->Add("/auto/data/pfeiffer/inclusive_detached_dilepton/data_samples/spruce_magdown_2023_v0_tuple_90000000_v0r0p6288631.root");
  366. VariableCollection col{};
  367. col.AddFourMomentumFor("L1");
  368. col.AddFourMomentumFor("L2");
  369. col.AddFourMomentumFor("Hp");
  370. col.AddTriggerCut({"Hlt2_InclDetDiMuonDecision", "Hlt2_InclDetDiMuon_3BodyDecision", "Hlt2_InclDetDiMuon_4BodyDecision"});
  371. col.AddTriggerCut({"Hlt1TrackMVADecision", "Hlt1TwoTrackMVADecision"});
  372. col.Connect(data_chain);
  373. const Double_t MASS_HIST_MIN = 5100.;
  374. const Double_t MASS_HIST_MAX = 6000.;
  375. const int N_BINS = 70;
  376. TH1D *h1_B_M = new TH1D("h1_B_M", "B Mass", N_BINS, MASS_HIST_MIN, MASS_HIST_MAX);
  377. unsigned int entries = data_chain->GetEntries();
  378. for (unsigned int i = 0; i < entries; i++)
  379. {
  380. data_chain->GetEntry(i);
  381. if (col.CheckCuts())
  382. {
  383. auto l1_4v = col.GetFourMomentum("L1");
  384. auto l2_4v = col.GetFourMomentum("L2");
  385. auto K_4v = col.GetFourMomentumWithMassSub("Hp", 493.677);
  386. h1_B_M->Fill((l1_4v + l2_4v + K_4v).M());
  387. }
  388. if ((i + 1) % 10000 == 0 || i + 1 == entries)
  389. {
  390. std::cout << "["
  391. << "BuToHpMuMu"
  392. << "] Processed event: " << i + 1 << " (" << TString::Format("%.2f", ((double)(i + 1) / (double)entries) * 100.) << "%)" << std::endl;
  393. }
  394. }
  395. TCanvas *c1 = new TCanvas("c1", "c1", 0, 0, 800, 600);
  396. h1_B_M->Draw();
  397. c1->Draw();
  398. return 0;
  399. }
  400. int do_all() {
  401. BuToHpMuMu();
  402. return 0;
  403. }