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.

500 lines
17 KiB

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