eff_plots.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. #!/usr/bin/env python
  2. from itertools import product
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. from uproot import open as root_open
  6. from matplottery.utils import Hist1D, Hist2D, to_html_table
  7. from matplottery.plotter import set_defaults, plot_2d
  8. import matplotboard as mpb
  9. matching_cuts = {
  10. 'new-extra-narrow': [
  11. dict(
  12. dPhiMaxHighEt=0.025,
  13. dPhiMaxHighEtThres=20.0,
  14. dPhiMaxLowEtGrad=-0.002,
  15. dRzMaxHighEt=9999.0,
  16. dRzMaxHighEtThres=0.0,
  17. dRzMaxLowEtGrad=0.0,
  18. ),
  19. dict(
  20. dPhiMaxHighEt=0.0015,
  21. dPhiMaxHighEtThres=0.0,
  22. dPhiMaxLowEtGrad=0.0,
  23. dRzMaxHighEt=0.025,
  24. dRzMaxHighEtThres=30.0,
  25. dRzMaxLowEtGrad=-0.002,
  26. ),
  27. dict(
  28. dPhiMaxHighEt=0.0015,
  29. dPhiMaxHighEtThres=0.0,
  30. dPhiMaxLowEtGrad=0.0,
  31. dRzMaxHighEt=0.025,
  32. dRzMaxHighEtThres=30.0,
  33. dRzMaxLowEtGrad=-0.002,
  34. )
  35. ],
  36. 'new-default': [
  37. dict(
  38. dPhiMaxHighEt=0.05,
  39. dPhiMaxHighEtThres=20.0,
  40. dPhiMaxLowEtGrad=-0.002,
  41. dRzMaxHighEt=9999.0,
  42. dRzMaxHighEtThres=0.0,
  43. dRzMaxLowEtGrad=0.0,
  44. ),
  45. dict(
  46. dPhiMaxHighEt=0.003,
  47. dPhiMaxHighEtThres=0.0,
  48. dPhiMaxLowEtGrad=0.0,
  49. dRzMaxHighEt=0.05,
  50. dRzMaxHighEtThres=30.0,
  51. dRzMaxLowEtGrad=-0.002,
  52. ),
  53. dict(
  54. dPhiMaxHighEt=0.003,
  55. dPhiMaxHighEtThres=0.0,
  56. dPhiMaxLowEtGrad=0.0,
  57. dRzMaxHighEt=0.05,
  58. dRzMaxHighEtThres=30.0,
  59. dRzMaxLowEtGrad=-0.002,
  60. )
  61. ],
  62. 'new-wide': [
  63. dict(
  64. dPhiMaxHighEt=0.10,
  65. dPhiMaxHighEtThres=20.0,
  66. dPhiMaxLowEtGrad=-0.002,
  67. dRzMaxHighEt=9999.0,
  68. dRzMaxHighEtThres=0.0,
  69. dRzMaxLowEtGrad=0.0,
  70. ),
  71. dict(
  72. dPhiMaxHighEt=0.006,
  73. dPhiMaxHighEtThres=0.0,
  74. dPhiMaxLowEtGrad=0.0,
  75. dRzMaxHighEt=0.10,
  76. dRzMaxHighEtThres=30.0,
  77. dRzMaxLowEtGrad=-0.002,
  78. ),
  79. dict(
  80. dPhiMaxHighEt=0.006,
  81. dPhiMaxHighEtThres=0.0,
  82. dPhiMaxLowEtGrad=0.0,
  83. dRzMaxHighEt=0.10,
  84. dRzMaxHighEtThres=30.0,
  85. dRzMaxLowEtGrad=-0.002,
  86. )
  87. ],
  88. 'new-extra-wide': [
  89. dict(
  90. dPhiMaxHighEt=0.15,
  91. dPhiMaxHighEtThres=20.0,
  92. dPhiMaxLowEtGrad=-0.002,
  93. dRzMaxHighEt=9999.0,
  94. dRzMaxHighEtThres=0.0,
  95. dRzMaxLowEtGrad=0.0,
  96. ),
  97. dict(
  98. dPhiMaxHighEt=0.009,
  99. dPhiMaxHighEtThres=0.0,
  100. dPhiMaxLowEtGrad=0.0,
  101. dRzMaxHighEt=0.15,
  102. dRzMaxHighEtThres=30.0,
  103. dRzMaxLowEtGrad=-0.002,
  104. ),
  105. dict(
  106. dPhiMaxHighEt=0.009,
  107. dPhiMaxHighEtThres=0.0,
  108. dPhiMaxLowEtGrad=0.0,
  109. dRzMaxHighEt=0.15,
  110. dRzMaxHighEtThres=30.0,
  111. dRzMaxLowEtGrad=-0.002,
  112. )
  113. ],
  114. }
  115. samples = None
  116. def load_samples():
  117. global samples
  118. if samples is None:
  119. print("loading samples")
  120. samples = {(proc, wp): root_open(f'../hists/{proc}-{wp}.root') for proc, wp in product(procs, wps)}
  121. return samples
  122. def calc_window(et, eta, hit, variable, cut_sel):
  123. idx = min(hit-1, 2)
  124. cuts = matching_cuts[cut_sel][idx]
  125. if 'etaBins' in cuts:
  126. for eta_idx, bin_high in enumerate(cuts['etaBins']):
  127. if eta < bin_high:
  128. high_et = cuts[f'{variable}MaxHighEt'][eta_idx]
  129. high_et_thres = cuts[f'{variable}MaxHighEtThres'][eta_idx]
  130. low_et_grad = cuts[f'{variable}MaxLowEtGrad'][eta_idx]
  131. break
  132. else: # highest bin
  133. high_et = cuts[f'{variable}MaxHighEt'][-1]
  134. high_et_thres = cuts[f'{variable}MaxHighEtThres'][-1]
  135. low_et_grad = cuts[f'{variable}MaxLowEtGrad'][-1]
  136. else:
  137. high_et = cuts[f'{variable}MaxHighEt']
  138. high_et_thres = cuts[f'{variable}MaxHighEtThres']
  139. low_et_grad = cuts[f'{variable}MaxLowEtGrad']
  140. return high_et + min(0, et-high_et_thres)*low_et_grad
  141. def hist_integral_ratio(num, den):
  142. num_int = num.get_integral()
  143. den_int = den.get_integral()
  144. ratio = num_int / den_int
  145. error = np.sqrt(den_int) / den_int # TODO: Check this definition of error
  146. return ratio, error
  147. def center_text(x, y, txt, **kwargs):
  148. plt.text(x, y, txt,
  149. horizontalalignment='center', verticalalignment='center',
  150. transform=plt.gca().transAxes, size=24, **kwargs)
  151. def hist_plot(h: Hist1D, *args, include_errors=False, line_width=1, **kwargs):
  152. """ Plots a 1D ROOT histogram object using matplotlib """
  153. counts = h.get_counts()
  154. edges = h.get_edges()
  155. left, right = edges[:-1], edges[1:]
  156. x = np.array([left, right]).T.flatten()
  157. y = np.array([counts, counts]).T.flatten()
  158. plt.plot(x, y, *args, linewidth=line_width, **kwargs)
  159. if include_errors:
  160. plt.errorbar(h.get_bin_centers(), h.counts, yerr=h.errors,
  161. color='k', marker=None, linestyle='None',
  162. barsabove=True, elinewidth=.7, capsize=1)
  163. def hist2d_percent_contour(h: Hist1D, percent: float, axis: str):
  164. values = h.counts
  165. try:
  166. axis = axis.lower()
  167. axis_idx = {'x': 1, 'y': 0}[axis]
  168. except KeyError:
  169. raise ValueError('axis must be \'x\' or \'y\'')
  170. if percent < 0 or percent > 1:
  171. raise ValueError('percent must be in [0,1]')
  172. with np.warnings.catch_warnings():
  173. np.warnings.filterwarnings('ignore', 'invalid value encountered in true_divide')
  174. values = values / np.sum(values, axis=axis_idx, keepdims=True)
  175. np.nan_to_num(values, copy=False)
  176. values = np.cumsum(values, axis=axis_idx)
  177. idxs = np.argmax(values > percent, axis=axis_idx)
  178. x_centers, y_centers = h.get_bin_centers()
  179. if axis == 'x':
  180. return x_centers[idxs], y_centers
  181. else:
  182. return x_centers, y_centers[idxs]
  183. @mpb.decl_fig
  184. def plot_residuals(sample, layer, hit, variable, subdet):
  185. load_samples()
  186. proc, wp = sample
  187. track_matched = samples[sample][f'{variable}_{subdet}_L{layer}_H{hit}_v_Et_TrackMatched']
  188. # no_match = samples[sample][f'{variable}_{subdet}_L{layer}_H{hit}_v_Et_NoMatch']
  189. h_real = Hist2D(track_matched)
  190. # h_fake = Hist2D(no_match)
  191. def do_plot(h):
  192. plot_2d(h, cmap='viridis')
  193. xs, ys = hist2d_percent_contour(h, .90, 'x')
  194. plt.plot(xs, ys, color='green', label='90\% contour')
  195. xs, ys = hist2d_percent_contour(h, .995, 'x')
  196. plt.plot(xs, ys, color='darkgreen', label='99.5\% contour')
  197. ets = h.edges[1]
  198. cuts = [calc_window(et, 0, hit, variable, wp) for et in ets]
  199. plt.plot(cuts, ets, color='red', label='Cut Value')
  200. plt.xlabel({'dPhi': r'$\delta \phi$ (rads)',
  201. 'dRz': r'$\delta R/z$ (cm)'}[variable])
  202. # plt.sca(plt.subplot(1, 2, 1))
  203. do_plot(h_real)
  204. plt.title('Truth-Matched Seeds')
  205. plt.ylabel('$E_T$ (GeV)')
  206. # plt.sca(plt.subplot(1, 2, 2))
  207. # do_plot(h_fake)
  208. # plt.title('Not Truth-Matched Seeds')
  209. plt.legend(loc='upper right')
  210. @mpb.decl_fig
  211. def plot_residuals_eta(sample, hit, variable):
  212. load_samples()
  213. h = Hist2D(samples[sample][f'{variable}_residuals_v_eta_H{hit}'])
  214. plot_2d(h)
  215. xs, ys = hist2d_percent_contour(h, .90, 'x')
  216. plt.plot(xs, ys, color='green', label='90\% contour')
  217. xs, ys = hist2d_percent_contour(h, .995, 'x')
  218. plt.plot(xs, ys, color='darkgreen', label='99.5\% contour')
  219. plt.xlabel({'dPhi': r'$\delta \phi$ (rads)',
  220. 'dRz': r'$\delta R/z$ (cm)'}[variable])
  221. plt.ylabel(r'$|\eta|$')
  222. @mpb.decl_fig
  223. def plot_hit_vs_layer(sample, region):
  224. load_samples()
  225. h = Hist2D(samples[sample][f'hit_vs_layer_{region}'])
  226. plot_2d(h, colz_fmt='2.0f')
  227. plt.xlabel('Layer #')
  228. plt.ylabel('Hit #')
  229. @mpb.decl_fig
  230. def plot_roc_curve(pfx, ext=''):
  231. load_samples()
  232. def get_num_den(sample, basename):
  233. num = Hist1D(sample[f'{basename}_num'])
  234. den = Hist1D(sample[f'{basename}_den'])
  235. return hist_integral_ratio(num, den)
  236. rows = []
  237. for (proc, wp), sample in samples.items():
  238. sample_name = f'{proc}-{wp}'
  239. eff, eff_err = get_num_den(sample, f'{pfx}_eff_v_phi{ext}')
  240. pur, pur_err = get_num_den(sample, f'{pfx}_pur_v_phi{ext}')
  241. rows.append([wp,
  242. rf'${eff*100:0.2f}\pm{eff_err*100:0.2f}\%$',
  243. rf'${pur*100:0.2f}\pm{pur_err*100:0.2f}\%$'])
  244. plt.errorbar([pur], [eff], xerr=[pur_err], yerr=[eff_err],
  245. label=sample_name, marker='o', color=color(proc, wp))
  246. center_text(0.3, 0.3, r'$p_T>20$ and $|\eta|<2.4$')
  247. plt.axis('equal')
  248. plt.xlim((0.5, 1.02))
  249. plt.ylim((0.5, 1.02))
  250. plt.xlabel('Purity')
  251. plt.ylabel('Efficiency')
  252. plt.grid()
  253. plt.legend(loc='lower right')
  254. col_labels = ['Sample', 'Working Point', 'Efficiency', 'Purity']
  255. row_labels = [r'$Z \rightarrow ee$', '', '', r'$t\bar{t}$', '', '']
  256. return to_html_table(rows, col_labels, row_labels, 'table-condensed')
  257. @mpb.decl_fig
  258. def plot_kinematic_eff(pref, ext='', xlim=(None, None), ylim=(None, None), norm=None, label_pfx='', incl_sel=True):
  259. load_samples()
  260. ax_pt = plt.subplot(221)
  261. ax_eta = plt.subplot(222)
  262. ax_phi = plt.subplot(223)
  263. errors = True
  264. for (proc, wp), sample in samples.items():
  265. sample_name = f'{proc}-{wp}'
  266. l = sample_name
  267. c = color(proc, wp)
  268. def do_plot(ax, name):
  269. plt.sca(ax)
  270. h = Hist1D(sample[name], no_overflow=True)
  271. if norm:
  272. h = h / (norm*h.get_integral())
  273. hist_plot(h, include_errors=errors, label=l, color=c)
  274. do_plot(ax_pt, f'{pref}_v_pt{ext}')
  275. do_plot(ax_eta, f'{pref}_v_eta{ext}')
  276. do_plot(ax_phi, f'{pref}_v_phi{ext}')
  277. plt.sca(ax_pt)
  278. if not incl_sel: center_text(0.5, 0.15, r'$|\eta|<2.4$')
  279. plt.xlabel(fr"{label_pfx} $p_T$")
  280. plt.ylim(ylim)
  281. plt.xlim(xlim)
  282. plt.sca(ax_eta)
  283. if not incl_sel: center_text(0.5, 0.15, r'$p_T>20$')
  284. plt.xlabel(fr"{label_pfx} $\eta$")
  285. plt.ylim(ylim)
  286. plt.xlim(xlim)
  287. plt.sca(ax_phi)
  288. if not incl_sel: center_text(0.5, 0.15, r'$p_T>20$ and $|\eta|<2.4$')
  289. plt.xlabel(fr"{label_pfx} $\phi$")
  290. plt.ylim(ylim)
  291. plt.xlim(xlim)
  292. plt.tight_layout()
  293. plt.legend(loc='upper left', bbox_to_anchor=(0.6, 0.45), bbox_transform=plt.gcf().transFigure)
  294. @mpb.decl_fig
  295. def plot_ecal_rel_res():
  296. load_samples()
  297. for sample_name, sample in samples.items():
  298. h = Hist1D(sample['ecal_energy_resolution'])
  299. h = h / h.get_integral()
  300. hist_plot(h, label=sample_name)
  301. plt.xlabel(r"ECAL $E_T$ relative error")
  302. plt.legend()
  303. @mpb.decl_fig
  304. def plot_res_contour(proc, hit_number, var, layers, ext='_TrackMatched'):
  305. load_samples()
  306. _, axs = plt.subplots(1, 2, sharey=True)
  307. def do_plot(ax, sample):
  308. plt.sca(ax)
  309. wp = sample[1]
  310. plt.title(wp)
  311. h = None
  312. for subdet, layer in layers:
  313. h = Hist2D(samples[sample][f'{var}_{subdet}_L{layer}_H{hit_number}_v_Et{ext}'])
  314. xs, ys = hist2d_percent_contour(h, .99, 'x')
  315. plt.plot(xs, ys, label=f'{subdet} - L{layer}')
  316. ets = h.edges[1]
  317. cuts = [calc_window(et, 0, hit_number, var, wp) for et in ets]
  318. plt.plot(cuts, ets, color='k', label='Cut Value')
  319. for ax, wp in zip(axs, ['new-default', 'new-wide']):
  320. do_plot(ax, (proc, wp))
  321. plt.sca(axs[-1])
  322. plt.legend(loc='upper right')
  323. @mpb.decl_fig
  324. def simple_dist(hist_name, rebin=(), norm=1, xlabel="", ylabel="", xlim=None, ylim=None, line_width=1):
  325. load_samples()
  326. for (proc, wp), sample in samples.items():
  327. sample_name = f'{proc}-{wp}'
  328. h = Hist1D(sample[hist_name])
  329. if rebin:
  330. h.rebin(*rebin)
  331. mean = np.sum(h.get_counts() * h.get_bin_centers()) / h.get_integral()
  332. if norm is not None:
  333. h = h * (norm / h.get_integral())
  334. hist_plot(h, label=f'{sample_name} ($\\mu={mean:.2f}$)',
  335. color=color(proc, wp), line_width=line_width)
  336. if xlim:
  337. plt.xlim(xlim)
  338. if ylim:
  339. plt.ylim(ylim)
  340. plt.xlabel(xlabel)
  341. plt.ylabel(ylabel)
  342. plt.legend()
  343. @mpb.decl_fig
  344. def simple_dist2d(hist_name, proc, wp, xlabel="", ylabel="", xlim=None, ylim=None, norm=None):
  345. load_samples()
  346. sample = samples[(proc, wp)]
  347. # sample_name = f'{proc}-{wp}'
  348. h = Hist2D(sample[hist_name])
  349. if norm is not None:
  350. h = h * (norm / h.get_integral())
  351. plot_2d(h, colz_fmt='g')
  352. if xlim:
  353. plt.xlim(xlim)
  354. if ylim:
  355. plt.ylim(ylim)
  356. plt.xlabel(xlabel)
  357. plt.ylabel(ylabel)
  358. def all_cut_plots(refresh=True, publish=False):
  359. figures = {
  360. 'tracking_roc_curve': (plot_roc_curve, ('tracking',)),
  361. 'tracking_roc_curve_dR': (plot_roc_curve, ('tracking',), {'ext': '_dR'}),
  362. 'seeding_roc_curve': (plot_roc_curve, ('seed',)),
  363. 'number_of_seeds': (simple_dist, ('n_seeds',),
  364. dict(xlabel='Number of Seeds', rebin=(50, -0.5, 200.5))),
  365. 'number_of_good_seeds': (simple_dist, ('n_good_seeds',),
  366. dict(xlabel='Number of Good Seeds', rebin=(50, -0.5, 200.5))),
  367. 'number_of_scls': (simple_dist, ('n_scl',),
  368. dict(xlabel='Number of Super-Clusters', xlim=(-0.5, 25.5))),
  369. 'number_of_good_scls': (simple_dist, ('n_good_scl',),
  370. dict(xlabel='Number of Super-Clusters', xlim=(-0.5, 25.5))),
  371. 'number_of_sim_els': (simple_dist, ('n_good_sim',),
  372. dict(xlabel='Number of prompt(ish) electrons', xlim=(-0.5, 20.5))),
  373. 'number_of_gsf_tracks': (simple_dist, ('n_gsf_track',),
  374. dict(xlabel='Number of reco electrons', xlim=(-0.5, 20.5))),
  375. 'number_of_matched': (simple_dist, ('n_matched',),
  376. dict(xlabel='Number of matched electrons', xlim=(-0.5, 10.5), line_width=4)),
  377. 'number_of_merged': (simple_dist, ('n_merged',),
  378. dict(xlabel='Number of merged electrons', xlim=(-0.5, 10.5), line_width=4)),
  379. 'number_of_lost': (simple_dist, ('n_lost',),
  380. dict(xlabel='Number of lost electrons', xlim=(-0.5, 10.5), line_width=4)),
  381. 'number_of_split': (simple_dist, ('n_split',),
  382. dict(xlabel='Number of split electrons', xlim=(-0.5, 10.5), line_width=4)),
  383. 'number_of_faked': (simple_dist, ('n_faked',),
  384. dict(xlabel='Number of faked electrons', xlim=(-0.5, 10.5), line_width=4)),
  385. 'number_of_flipped': (simple_dist, ('n_flipped',),
  386. dict(xlabel='Number of flipped electrons', xlim=(-0.5, 10.5), line_width=4)),
  387. 'matched_dR': (simple_dist, ('matched_dR',),
  388. dict(xlabel='dR between sim and reco')),
  389. 'matched_dpT': (simple_dist, ('matched_dpT',),
  390. dict(xlabel='dpT between sim and reco')),
  391. 'number_of_matched_dR': (simple_dist, ('n_matched_dR',),
  392. dict(xlabel='Number of matched electrons - dR Matched', xlim=(-0.5, 10.5),
  393. line_width=4)),
  394. 'number_of_merged_dR': (simple_dist, ('n_merged_dR',),
  395. dict(xlabel='Number of merged electrons - dR Matched', xlim=(-0.5, 10.5),
  396. line_width=4)),
  397. 'number_of_lost_dR': (simple_dist, ('n_lost_dR',),
  398. dict(xlabel='Number of lost electrons - dR Matched', xlim=(-0.5, 10.5),
  399. line_width=4)),
  400. 'number_of_split_dR': (simple_dist, ('n_split_dR',),
  401. dict(xlabel='Number of split electrons - dR Matched', xlim=(-0.5, 10.5),
  402. line_width=4)),
  403. 'number_of_faked_dR': (simple_dist, ('n_faked_dR',),
  404. dict(xlabel='Number of faked electrons - dR Matched', xlim=(-0.5, 10.5),
  405. line_width=4)),
  406. 'number_of_flipped_dR': (simple_dist, ('n_flipped_dR',),
  407. dict(xlabel='Number of flipped electrons - dR Matched', xlim=(-0.5, 10.5),
  408. line_width=4)),
  409. 'matched_dR_dR': (simple_dist, ('matched_dR_dR',),
  410. dict(xlabel='dR between sim and reco - dR Matched')),
  411. 'matched_dpT_dR': (simple_dist, ('matched_dpT_dR',),
  412. dict(xlabel='dpT between sim and reco - dR Matched')),
  413. 'sim_pt': (simple_dist, ('sim_pt',),
  414. dict(xlabel='Sim Track $p_T$', xlim=(0, None))),
  415. 'sim_eta': (simple_dist, ('sim_eta',),
  416. dict(xlabel='Sim Track $eta$', rebin=(20, -3, 3))),
  417. 'sim_phi': (simple_dist, ('sim_phi',),
  418. dict(xlabel='Sim Track $phi$', rebin=(20, -3.14, 3.14), ylim=(0, None))),
  419. 'reco_pt': (simple_dist, ('reco_pt',),
  420. dict(xlabel='Reco Track $p_T$', xlim=(0, None))),
  421. 'reco_eta': (simple_dist, ('reco_eta',),
  422. dict(xlabel='Reco Track $eta$', rebin=(20, -3, 3))),
  423. 'reco_phi': (simple_dist, ('reco_phi',),
  424. dict(xlabel='Reco Track $phi$', rebin=(20, -3.14, 3.14), ylim=(0, None))),
  425. 'tm_corr': (simple_dist2d, ('tm_corr', 'zee', 'old-default'),
  426. dict(xlabel='Seed Matched', ylabel='Track Matched', norm=1)),
  427. 'ecal_rel_res': plot_ecal_rel_res,
  428. 'hit_v_layer_BPIX_new-default_zee': (plot_hit_vs_layer, (('zee', 'new-default'), 'barrel')),
  429. 'hit_v_layer_FPIX_new-default_zee': (plot_hit_vs_layer, (('zee', 'new-default'), 'forward')),
  430. 'hit_v_layer_BPIX_new-default_tt': (plot_hit_vs_layer, (('tt', 'new-default'), 'barrel')),
  431. 'hit_v_layer_FPIX_new-default_tt': (plot_hit_vs_layer, (('tt', 'new-default'), 'forward')),
  432. 'hit_v_layer_BPIX_new-wide_zee': (plot_hit_vs_layer, (('zee', 'new-wide'), 'barrel')),
  433. 'hit_v_layer_FPIX_new-wide_zee': (plot_hit_vs_layer, (('zee', 'new-wide'), 'forward')),
  434. 'hit_v_layer_BPIX_new-wide_tt': (plot_hit_vs_layer, (('tt', 'new-wide'), 'barrel')),
  435. 'hit_v_layer_FPIX_new-wide_tt': (plot_hit_vs_layer, (('tt', 'new-wide'), 'forward')),
  436. 'good_sim_kinem': (plot_kinematic_eff, ('good_sim',),
  437. dict(norm=1, ylim=(0, None))),
  438. 'gsf_track_kinem': (plot_kinematic_eff, ('gsf_track',),
  439. dict(norm=1, ylim=(0, None))),
  440. 'seed_kinem': (plot_kinematic_eff, ('seed',),
  441. dict(norm=1, ylim=(0, None))),
  442. 'scl_kinem': (plot_kinematic_eff, ('scl',),
  443. dict(norm=1, ylim=(0, None))),
  444. }
  445. def add_num_den(key, func, args, kwargs):
  446. figures[key] = (func, args, dict(**kwargs, ylim=(0, 1.1)))
  447. base_ext = kwargs.get('ext', '')
  448. kwargs_ = kwargs.copy()
  449. kwargs_['ext'] = base_ext+'_num'
  450. figures[key+'_num'] = (func, args, kwargs_)
  451. kwargs_ = kwargs.copy()
  452. kwargs_['ext'] = base_ext+'_den'
  453. figures[key+'_den'] = (func, args, kwargs_)
  454. add_num_den('tracking_eff', plot_kinematic_eff, ('tracking_eff',), dict(incl_sel=False))
  455. add_num_den('tracking_pur', plot_kinematic_eff, ('tracking_pur',), dict(incl_sel=False))
  456. add_num_den('tracking_eff_dR', plot_kinematic_eff, ('tracking_eff',), dict(ext='_dR', incl_sel=False))
  457. add_num_den('tracking_pur_dR', plot_kinematic_eff, ('tracking_pur',), dict(ext='_dR', incl_sel=False))
  458. add_num_den('seeding_eff', plot_kinematic_eff, ('seed_eff',), dict(incl_sel=False))
  459. add_num_den('seeding_pur', plot_kinematic_eff, ('seed_pur',), dict(incl_sel=False))
  460. add_num_den('fake_rate_incl', plot_kinematic_eff, ('fake_rate_incl',), {})
  461. add_num_den('partial_fake_rate_incl', plot_kinematic_eff, ('partial_fake_rate_incl',), {})
  462. add_num_den('full_fake_rate_incl', plot_kinematic_eff, ('full_fake_rate_incl',), {})
  463. add_num_den('clean_fake_rate_incl', plot_kinematic_eff, ('clean_fake_rate_incl',), {})
  464. add_num_den('fake_rate', plot_kinematic_eff, ('fake_rate',), dict(incl_sel=False))
  465. add_num_den('partial_fake_rate', plot_kinematic_eff, ('partial_fake_rate',), dict(incl_sel=False))
  466. add_num_den('full_fake_rate', plot_kinematic_eff, ('full_fake_rate',), dict(incl_sel=False))
  467. add_num_den('clean_fake_rate', plot_kinematic_eff, ('clean_fake_rate',), dict(incl_sel=False))
  468. hit_layers = [(1, 1), (1, 2), (2, 2), (2, 3), (3, 3), (3, 4)]
  469. for proc, wp, (hit, layer), var, subdet in product(['zee', 'tt'], ['new-default', 'new-wide'],
  470. hit_layers,
  471. ['dPhi', 'dRz'], ['BPIX', 'FPIX']):
  472. figures.update({
  473. f'res_{subdet}_L{layer}_H{hit}_{var}_{proc}_{wp}':
  474. (plot_residuals, ((proc, wp), layer, hit, var, subdet))})
  475. rel_layers = {1: [('BPIX', 1), ('BPIX', 2), ('FPIX', 1), ('FPIX', 2)],
  476. 2: [('BPIX', 2), ('BPIX', 3), ('FPIX', 2), ('FPIX', 3)],
  477. 3: [('BPIX', 3), ('BPIX', 4), ('FPIX', 3)], }
  478. for proc, hit, var in product(['zee', 'tt'], [1, 2, 3], ['dPhi', 'dRz']):
  479. figures.update({
  480. f'resall_H{hit}_{var}_{proc}': (plot_res_contour, (proc, hit, var, rel_layers[hit]))})
  481. for proc, wp, hit, var in product(['zee', 'tt'], ['new-default', 'new-wide'], [1, 2, 3], ['dPhi', 'dRz']):
  482. figures.update({
  483. f'res_v_eta_H{hit}_{var}_{proc}_{wp}': (plot_residuals_eta, ((proc, wp), hit, var))})
  484. mpb.render(figures, refresh=refresh)
  485. mpb.generate_report(figures, 'Electron Seeding Studies',
  486. output=f'hists.html',
  487. source=__file__)
  488. mpb.generate_report(figures, 'Update',
  489. output='report.html',
  490. body='../docs/reports/report_2018_05_30.md')
  491. if publish:
  492. mpb.publish()
  493. def color(proc, wp):
  494. from matplotlib.colors import XKCD_COLORS
  495. def f(name):
  496. return XKCD_COLORS['xkcd:'+name]
  497. return {
  498. ('zee', 'new-extra-narrow'): f('kelly green'),
  499. ('tt', 'new-extra-narrow'): f('grey green'),
  500. ('zee', 'new-default'): f('red'),
  501. ('tt', 'new-default'): f('pink'),
  502. ('zee', 'new-wide'): f('strong blue'),
  503. ('tt', 'new-wide'): f('bright blue'),
  504. ('zee', 'new-extra-wide'): f('indigo'),
  505. ('tt', 'new-extra-wide'): f('bright purple'),
  506. ('zee', 'old-default'): f('black'),
  507. ('tt', 'old-default'): f('blue grey'),
  508. }[(proc, wp)]
  509. if __name__ == '__main__':
  510. set_defaults()
  511. mpb.configure(output_dir='seeding_studies',
  512. multiprocess=True,
  513. publish_remote="caleb@fangmeier.tech",
  514. publish_dir="/var/www/eg",
  515. publish_url="eg.fangmeier.tech/",
  516. )
  517. procs = {
  518. 'zee': r'$Z\rightarrow e^+e_-}$',
  519. 'tt': r'$t\bar{t}$'
  520. }
  521. wps = {
  522. 'new-default': 'HLT Settings',
  523. 'new-wide': 'Wide Settings',
  524. 'old-default': 'Old Seeding',
  525. }
  526. all_cut_plots(refresh=True, publish=True)