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.

464 lines
16 KiB

10 months ago
  1. # flake8: noqa
  2. import argparse
  3. from ROOT import TMultiGraph, TLatex, TCanvas, TFile, TGaxis
  4. from ROOT import kGreen, kBlue, kBlack, kAzure, kOrange, kMagenta, kCyan
  5. from ROOT import gROOT, gStyle, gPad
  6. from ROOT import TEfficiency
  7. from array import array
  8. gROOT.SetBatch(True)
  9. def getEfficiencyHistoNames():
  10. return ["p", "pt", "phi", "eta", "nPV"]
  11. def getTrackers(trackers):
  12. return trackers
  13. def getOriginFolders():
  14. basedict = {
  15. "Velo": {},
  16. "Upstream": {},
  17. "Forward": {},
  18. "Match": {},
  19. "BestLong": {},
  20. }
  21. basedict["Velo"]["folder"] = "VeloTrackChecker/"
  22. basedict["Upstream"]["folder"] = "UpstreamTrackChecker/"
  23. basedict["Forward"]["folder"] = "ForwardTrackChecker/"
  24. basedict["Match"]["folder"] = "MatchTrackChecker/"
  25. basedict["BestLong"]["folder"] = "BestLongTrackChecker/"
  26. return basedict
  27. def getTrackNames():
  28. basedict = {
  29. "Velo": {},
  30. "Upstream": {},
  31. "Forward": {},
  32. "Match": {},
  33. "BestLong": {},
  34. }
  35. basedict["Velo"] = "Velo"
  36. basedict["Upstream"] = "VeloUT"
  37. basedict["Forward"] = "Forward"
  38. basedict["Match"] = "Match"
  39. basedict["BestLong"] = "BestLong"
  40. return basedict
  41. def get_colors():
  42. return [kBlack, kAzure, kGreen + 3, kMagenta + 2, kOrange, kCyan + 2]
  43. def get_markers():
  44. return [20, 24, 21, 22, 23, 25]
  45. def get_fillstyles():
  46. return [1003, 1002, 3002, 3325, 3144, 3244, 3444]
  47. def getGhostHistoNames():
  48. basedict = {
  49. "Velo": {},
  50. "Upstream": {},
  51. "Forward": {},
  52. "Match": {},
  53. "BestLong": {},
  54. }
  55. basedict["Velo"] = ["eta", "nPV"]
  56. basedict["Upstream"] = ["eta", "p", "pt", "nPV"]
  57. basedict["Forward"] = ["eta", "p", "pt", "nPV"]
  58. basedict["Match"] = basedict["Forward"]
  59. basedict["BestLong"] = basedict["Forward"]
  60. return basedict
  61. def argument_parser():
  62. parser = argparse.ArgumentParser(description="location of the tuple file")
  63. parser.add_argument(
  64. "--filename",
  65. type=str,
  66. default=["data/resolutions_and_effs_Bs2PhiPhi_MD_default.root"],
  67. nargs="+",
  68. help="input files, including path",
  69. )
  70. parser.add_argument(
  71. "--outfile",
  72. type=str,
  73. default="data/efficiency_plots.root",
  74. help="output file",
  75. )
  76. parser.add_argument(
  77. "--trackers",
  78. type=str,
  79. nargs="+",
  80. default=["Forward", "Match", "BestLong"],
  81. help="Trackers to plot.",
  82. )
  83. parser.add_argument(
  84. "--label",
  85. nargs="+",
  86. default=["EffChecker"],
  87. help="label for files",
  88. )
  89. parser.add_argument(
  90. "--savepdf",
  91. action="store_true",
  92. help="save plots in pdf format",
  93. )
  94. parser.add_argument(
  95. "--plot-electrons",
  96. action="store_true",
  97. help="plot electrons")
  98. parser.add_argument(
  99. "--plot-electrons-only",
  100. action="store_true",
  101. help="plot only electrons",
  102. )
  103. return parser
  104. def get_files(tf, filename, label):
  105. for i, f in enumerate(filename):
  106. tf[label[i]] = TFile(f, "read")
  107. return tf
  108. def get_nicer_var_string(var: str):
  109. nice_vars = dict(pt="p_{T}", eta="#eta", phi="#phi")
  110. try:
  111. return nice_vars[var]
  112. except KeyError:
  113. return var
  114. def get_eff(eff, hist, tf, histoName, label, var):
  115. eff = {}
  116. hist = {}
  117. var = get_nicer_var_string(var)
  118. for i, lab in enumerate(label):
  119. numeratorName = histoName + "_reconstructed"
  120. numerator = tf[lab].Get(numeratorName)
  121. denominatorName = histoName + "_reconstructible"
  122. denominator = tf[lab].Get(denominatorName)
  123. if numerator.GetEntries() == 0 or denominator.GetEntries() == 0:
  124. continue
  125. teff = TEfficiency(numerator, denominator)
  126. teff.SetStatisticOption(7)
  127. eff[lab] = teff.CreateGraph()
  128. eff[lab].SetName(lab)
  129. eff[lab].SetTitle(lab + " not e^{-}")
  130. if histoName.find("strange") != -1:
  131. eff[lab].SetTitle(lab + " from stranges")
  132. if histoName.find("electron") != -1:
  133. eff[lab].SetTitle(lab + " e^{-}")
  134. hist[lab] = denominator.Clone()
  135. hist[lab].SetName("h_numerator_notElectrons")
  136. hist[lab].SetTitle(var + " distribution, not e^{-}")
  137. if histoName.find("strange") != -1:
  138. hist[lab].SetTitle(var + " distribution, stranges")
  139. if histoName.find("electron") != -1:
  140. hist[lab].SetTitle(var + " distribution, e^{-}")
  141. return eff, hist
  142. def get_ghost(eff, hist, tf, histoName, label):
  143. ghost = {}
  144. for i, lab in enumerate(label):
  145. numeratorName = histoName + "_Ghosts"
  146. denominatorName = histoName + "_Total"
  147. numerator = tf[lab].Get(numeratorName)
  148. denominator = tf[lab].Get(denominatorName)
  149. print("Numerator = " + numeratorName)
  150. print("Denominator = " + denominatorName)
  151. teff = TEfficiency(numerator, denominator)
  152. teff.SetStatisticOption(7)
  153. ghost[lab] = teff.CreateGraph()
  154. print(lab)
  155. ghost[lab].SetName(lab)
  156. return ghost
  157. def PrCheckerEfficiency(
  158. filename,
  159. outfile,
  160. label,
  161. trackers,
  162. savepdf,
  163. plot_electrons,
  164. plot_electrons_only,
  165. ):
  166. from utils.LHCbStyle import setLHCbStyle, set_style
  167. from utils.ConfigHistos import (
  168. efficiencyHistoDict,
  169. ghostHistoDict,
  170. categoriesDict,
  171. getCuts,
  172. )
  173. from utils.Legend import place_legend
  174. setLHCbStyle()
  175. markers = get_markers()
  176. colors = get_colors()
  177. styles = get_fillstyles()
  178. tf = {}
  179. tf = get_files(tf, filename, label)
  180. outputfile = TFile(outfile, "recreate")
  181. latex = TLatex()
  182. latex.SetNDC()
  183. latex.SetTextSize(0.05)
  184. efficiencyHistoDict = efficiencyHistoDict()
  185. efficiencyHistos = getEfficiencyHistoNames()
  186. ghostHistos = getGhostHistoNames()
  187. ghostHistoDict = ghostHistoDict()
  188. categories = categoriesDict()
  189. cuts = getCuts()
  190. trackers = getTrackers(trackers)
  191. folders = getOriginFolders()
  192. # names = getTrackNames()
  193. for tracker in trackers:
  194. outputfile.cd()
  195. trackerDir = outputfile.mkdir(tracker)
  196. trackerDir.cd()
  197. for cut in cuts[tracker]:
  198. cutDir = trackerDir.mkdir(cut)
  199. cutDir.cd()
  200. folder = folders[tracker]["folder"]
  201. print(folder)
  202. histoBaseName = "Track/" + folder + tracker + "/" + cut + "_"
  203. # calculate efficiency
  204. for histo in efficiencyHistos:
  205. canvastitle = (
  206. "efficiency_" + histo + ", " + categories[tracker][cut]["title"]
  207. )
  208. # get efficiency for not electrons category
  209. histoName = histoBaseName + "" + efficiencyHistoDict[histo]["variable"]
  210. print("not electrons: " + histoName)
  211. eff = {}
  212. hist_den = {}
  213. eff, hist_den = get_eff(eff, hist_den, tf, histoName, label, histo)
  214. if categories[tracker][cut]["plotElectrons"] and plot_electrons:
  215. histoNameElec = (
  216. "Track/"
  217. + folder
  218. + tracker
  219. + "/"
  220. + categories[tracker][cut]["Electrons"]
  221. )
  222. histoName_e = (
  223. histoNameElec + "_" + efficiencyHistoDict[histo]["variable"]
  224. )
  225. print("electrons: " + histoName_e)
  226. eff_elec = {}
  227. hist_elec = {}
  228. eff_elec, hist_elec = get_eff(
  229. eff_elec,
  230. hist_elec,
  231. tf,
  232. histoName_e,
  233. label,
  234. histo,
  235. )
  236. name = "efficiency_" + histo
  237. canvas = TCanvas(name, canvastitle)
  238. canvas.SetRightMargin(0.1)
  239. mg = TMultiGraph()
  240. for i, lab in enumerate(label):
  241. if not plot_electrons_only:
  242. mg.Add(eff[lab])
  243. set_style(eff[lab], colors[i], markers[i], styles[i])
  244. if categories[tracker][cut]["plotElectrons"] and plot_electrons:
  245. mg.Add(eff_elec[lab])
  246. set_style(eff_elec[lab], kBlue - 7, markers[i + 1], styles[i])
  247. mg.Draw("AP")
  248. mg.GetYaxis().SetRangeUser(0, 1.05)
  249. xtitle = efficiencyHistoDict[histo]["xTitle"]
  250. unit_l = xtitle.split("[")
  251. if "]" in unit_l[-1]:
  252. unit = unit_l[-1].replace("]", "")
  253. else:
  254. unit = ""
  255. print(unit)
  256. mg.GetXaxis().SetTitle(xtitle)
  257. mg.GetXaxis().SetTitleSize(0.06)
  258. mg.GetYaxis().SetTitle(
  259. "Efficiency of Long Tracks",
  260. ) # (" + str(round(hist_den[label[0]].GetBinWidth(1), 2)) + f"{unit})"+"^{-1}")
  261. mg.GetYaxis().SetTitleSize(0.06)
  262. mg.GetYaxis().SetTitleOffset(1.1)
  263. mg.GetXaxis().SetRangeUser(*efficiencyHistoDict[histo]["range"])
  264. mg.GetXaxis().SetNdivisions(10, 5, 0)
  265. mygray = 18
  266. myblue = kBlue - 9
  267. for i, lab in enumerate(label):
  268. rightmax = 1.05 * hist_den[lab].GetMaximum()
  269. scale = gPad.GetUymax() / rightmax
  270. hist_den[lab].Scale(scale)
  271. if categories[tracker][cut]["plotElectrons"] and plot_electrons:
  272. rightmax = 1.05 * hist_elec[lab].GetMaximum()
  273. scale = gPad.GetUymax() / rightmax
  274. hist_elec[lab].Scale(scale)
  275. if i == 0:
  276. if not plot_electrons_only:
  277. set_style(hist_den[lab], mygray, markers[i], styles[i])
  278. gStyle.SetPalette(2, array("i", [mygray - 1, myblue + 1]))
  279. hist_den[lab].Draw("HIST PLC SAME")
  280. if categories[tracker][cut]["plotElectrons"] and plot_electrons:
  281. set_style(hist_elec[lab], myblue, markers[i], styles[i])
  282. hist_elec[lab].SetFillColorAlpha(myblue, 0.35)
  283. hist_elec[lab].Draw("HIST PLC SAME")
  284. else:
  285. print(
  286. "No distribution plotted for other labels.",
  287. "Can be added by uncommenting the code below this print statement.",
  288. )
  289. # set_style(hist_den[lab], mygray, markers[i], styles[i])
  290. # gStyle.SetPalette(2, array("i", [mygray - 1, myblue + 1]))
  291. # hist_den[lab].Draw("HIST PLC SAME")
  292. if histo == "p":
  293. pos = [0.53, 0.4, 1.01, 0.71]
  294. elif histo == "pt":
  295. pos = [0.5, 0.4, 0.98, 0.71]
  296. else:
  297. pos = [0.4, 0.37, 0.88, 0.68]
  298. legend = place_legend(
  299. canvas, *pos, header="LHCb Simulation", option="LPE"
  300. )
  301. for le in legend.GetListOfPrimitives():
  302. if "distribution" in le.GetLabel():
  303. le.SetOption("LF")
  304. legend.SetTextFont(132)
  305. legend.SetTextSize(0.045)
  306. legend.Draw()
  307. for lab in label:
  308. if not plot_electrons_only:
  309. eff[lab].Draw("P SAME")
  310. if categories[tracker][cut]["plotElectrons"] and plot_electrons:
  311. eff_elec[lab].Draw("P SAME")
  312. cutName = categories[tracker][cut]["title"]
  313. latex.DrawLatex(legend.GetX1() + 0.01, legend.GetY1() - 0.05, cutName)
  314. low = 0
  315. high = 1.05
  316. gPad.Update()
  317. axis = TGaxis(
  318. gPad.GetUxmax(),
  319. gPad.GetUymin(),
  320. gPad.GetUxmax(),
  321. gPad.GetUymax(),
  322. low,
  323. high,
  324. 510,
  325. "+U",
  326. )
  327. axis.SetTitleFont(132)
  328. axis.SetTitleSize(0.06)
  329. axis.SetTitleOffset(0.55)
  330. axis.SetTitle(
  331. "# Tracks " + get_nicer_var_string(histo) + " distribution [a.u.]",
  332. )
  333. axis.SetLabelSize(0)
  334. axis.Draw()
  335. canvas.RedrawAxis()
  336. if savepdf:
  337. filestypes = ["pdf"] # , "png", "eps", "C", "ps", "tex"]
  338. for ftype in filestypes:
  339. if not plot_electrons_only:
  340. canvasName = tracker + "_" + cut + "_" + histo + "." + ftype
  341. else:
  342. canvasName = (
  343. tracker + "Electrons_" + cut + "_" + histo + "." + ftype
  344. )
  345. canvas.SaveAs("checks/" + canvasName)
  346. # canvas.SetRightMargin(0.05)
  347. canvas.Write()
  348. # calculate ghost rate
  349. histoBaseName = "Track/" + folder + tracker + "/"
  350. for histo in ghostHistos[tracker]:
  351. trackerDir.cd()
  352. title = "ghost_rate_vs_" + histo
  353. gPad.SetTicks()
  354. histoName = histoBaseName + ghostHistoDict[histo]["variable"]
  355. ghost = {}
  356. hist_den = {}
  357. ghost = get_ghost(ghost, hist_den, tf, histoName, label)
  358. canvas = TCanvas(title, title)
  359. mg = TMultiGraph()
  360. for i, lab in enumerate(label):
  361. mg.Add(ghost[lab])
  362. set_style(ghost[lab], colors[i], markers[i], styles[i])
  363. xtitle = ghostHistoDict[histo]["xTitle"]
  364. mg.GetXaxis().SetTitle(xtitle)
  365. mg.GetYaxis().SetTitle("Fraction of fake tracks")
  366. mg.Draw("ap")
  367. mg.GetXaxis().SetTitleSize(0.06)
  368. mg.GetYaxis().SetTitleSize(0.06)
  369. mg.GetYaxis().SetTitleOffset(1.1)
  370. mg.GetXaxis().SetRangeUser(*efficiencyHistoDict[histo]["range"])
  371. mg.GetXaxis().SetNdivisions(10, 5, 0)
  372. # for lab in label:
  373. # ghost[lab].Draw("P SAME")
  374. if histo == "p":
  375. pos = [0.53, 0.4, 1.01, 0.71]
  376. elif histo == "pt":
  377. pos = [0.5, 0.4, 0.98, 0.71]
  378. elif histo == "eta":
  379. pos = [0.35, 0.6, 0.85, 0.9]
  380. else:
  381. pos = [0.4, 0.37, 0.88, 0.68]
  382. legend = place_legend(canvas, *pos, header="LHCb Simulation", option="LPE")
  383. legend.SetTextFont(132)
  384. legend.SetTextSize(0.045)
  385. legend.Draw()
  386. # if histo != "nPV":
  387. # latex.DrawLatex(0.7, 0.85, "LHCb simulation")
  388. # else:
  389. # latex.DrawLatex(0.2, 0.85, "LHCb simulation")
  390. # mg.GetYaxis().SetRangeUser(0, 0.4)
  391. if histo == "eta":
  392. mg.GetYaxis().SetRangeUser(0, 0.4)
  393. # track_name = names[tracker] + " tracks"
  394. # latex.DrawLatex(0.7, 0.75, track_name)
  395. # canvas.PlaceLegend()
  396. if savepdf:
  397. filestypes = ["pdf"] # , "png", "eps", "C", "ps", "tex"]
  398. for ftype in filestypes:
  399. canvas.SaveAs(
  400. "checks/" + tracker + "ghost_rate_" + histo + "." + ftype,
  401. )
  402. canvas.Write()
  403. outputfile.Write()
  404. outputfile.Close()
  405. if __name__ == "__main__":
  406. parser = argument_parser()
  407. args = parser.parse_args()
  408. PrCheckerEfficiency(**vars(args))