yields.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #!/usr/bin/env python
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from filval.result_set import ResultSet
  5. from filval.histogram_utils import hist, hist_add, hist_normalize
  6. from filval.plotter import (decl_plot, render_plots, hist_plot, hist_plot_stack, Plot, generate_dashboard)
  7. @decl_plot
  8. def plot_yield_grid(rss):
  9. r"""## Event Yield
  10. The event yield for the eight signal regions defined in AN-17-115. Data is normalized
  11. to the Moriond 2018 integrated luminosity ($35.9\textrm{fb}^{-1}$). Code for the histogram generation is
  12. here: <https://github.com/cfangmeier/FTAnalysis/blob/master/studies/tau/Yield.C>
  13. """
  14. _, ((ax_tttt, ax_ttw), (ax_ttz, ax_tth)) = plt.subplots(2, 2)
  15. ft, ttw, ttz, tth = map(lambda rs: hist(rs.SRs), rss)
  16. # ft, ttw = map(lambda rs: hist(rs.SRs), rss[:2])
  17. plt.sca(ax_tttt)
  18. an = ((0.47, 0.33, 0.18, 0.78, 0.49, 0.52, 0.33, 0.49),
  19. (0, 0, 0, 0, 0, 0, 0, 0), [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5])
  20. hist_plot(ft, title='TTTT', stats=False, label='Mock')
  21. hist_plot(an, title='TTTT', stats=False, label='AN')
  22. plt.sca(ax_ttw)
  23. an = ([2.29663, 0.508494, 0.161166, 1.03811, 0.256401, 0.127582, 0.181522, 0.141659],
  24. [0, 0, 0, 0, 0, 0, 0, 0], [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5])
  25. hist_plot(ttw, title='TTW', stats=False, label='Mock')
  26. hist_plot(an, title='TTW', stats=False, label='AN')
  27. plt.legend()
  28. plt.sca(ax_ttz)
  29. an = ([0.974751, 0.269195, 1e-06, 0.395831, 0.0264703, 0.06816, 0.8804, 0.274265],
  30. [0, 0, 0, 0, 0, 0, 0, 0], [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5])
  31. hist_plot(ttz, title='TTZ', stats=False, label='Mock')
  32. hist_plot(an, title='TTZ', stats=False, label='AN')
  33. plt.xlabel('Signal Region')
  34. plt.sca(ax_tth)
  35. an = ([1.13826, 0.361824, 0.162123, 0.683917, 0.137608, 0.0632719, 0.554491, 0.197864],
  36. [0, 0, 0, 0, 0, 0, 0, 0], [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5])
  37. hist_plot(tth, title='TTH', stats=False, label='Mock')
  38. hist_plot(an, title='TTH', stats=False, label='AN')
  39. plt.xlabel('Signal Region')
  40. @decl_plot
  41. def plot_yield_stack(rss):
  42. r"""## Event Yield - Stacked
  43. The event yield for the eight signal regions defined in AN-17-115. Data is normalized
  44. to the Moriond 2018 integrated luminosity ($35.9\textrm{fb}^{-1}$). Code for the histogram generation is
  45. here: <https://github.com/cfangmeier/FTAnalysis/blob/master/studies/tau/Yield.C>
  46. """
  47. ft, ttw, ttz, tth = map(lambda rs: hist(rs.SRs), rss)
  48. hist_plot_stack([ttw, ttz, tth], labels=['TTW', 'TTZ', 'TTH'])
  49. ft = ft[0]*10, ft[1], ft[2]
  50. hist_plot(ft, label='TTTT (x10)', stats=False, color='k')
  51. plt.ylim((0, 60))
  52. plt.xlabel('Signal Region')
  53. plt.legend()
  54. @decl_plot
  55. def plot_lep_multi(rss, use_mc_reweight, dataset):
  56. _, (ax_els, ax_mus, ax_taus) = plt.subplots(3, 1)
  57. if use_mc_reweight:
  58. els = list(map(lambda rs: hist_normalize(hist(rs.nEls_mc)), rss))
  59. mus = list(map(lambda rs: hist_normalize(hist(rs.nMus_mc)), rss))
  60. taus = list(map(lambda rs: hist_normalize(hist(rs.nTaus_mc)), rss))
  61. else:
  62. els = list(map(lambda rs: hist_normalize(hist(rs.nEls)), rss))
  63. mus = list(map(lambda rs: hist_normalize(hist(rs.nMus)), rss))
  64. taus = list(map(lambda rs: hist_normalize(hist(rs.nTaus)), rss))
  65. def _plot(ax, procs):
  66. plt.sca(ax)
  67. ft, ttw, ttz, tth = procs
  68. h = {'TTTT': ft,
  69. 'TTW': ttw,
  70. 'TTZ': ttz,
  71. 'TTH': tth}[dataset]
  72. hist_plot(h, stats=False, label=dataset)
  73. _plot(ax_els, els)
  74. plt.xlabel('\\# Good Electrons')
  75. plt.legend()
  76. _plot(ax_mus, mus)
  77. plt.xlabel('\\# Good Muons')
  78. _plot(ax_taus, taus)
  79. plt.xlabel('\\# Good Taus')
  80. @decl_plot
  81. def plot_sig_strength(rss):
  82. r""" The signal strength of the TTTT signal defined as
  83. $\frac{S}{\sqrt{S+B}}$
  84. """
  85. ft, ttw, ttz, tth = map(lambda rs: hist(rs.SRs), rss)
  86. bg = hist_add(ttw, ttz, tth)
  87. strength = ft[0] / np.sqrt(ft[0] + bg[0])
  88. hist_plot((strength, ft[1], ft[2]), stats=False)
  89. @decl_plot
  90. def plot_event_obs(rss, dataset):
  91. r"""
  92. """
  93. _, ((ax_ht, ax_met), (ax_njet, ax_nbjet)) = plt.subplots(2, 2)
  94. # ft, ttw, ttz, tth = map(lambda rs: hist(rs.SRs), rss)
  95. ft, ttw, ttz, tth = rss
  96. rs = {'TTTT': ft,
  97. 'TTW': ttw,
  98. 'TTZ': ttz,
  99. 'TTH': tth}[dataset]
  100. def _plot(ax, obs):
  101. plt.sca(ax)
  102. h = {'MET': rs.met,
  103. 'HT': rs.ht,
  104. 'NJET': rs.njet,
  105. 'NBJET': rs.nbjet}[obs]
  106. hist_plot(hist(h), stats=False, label=dataset, xlabel=obs)
  107. _plot(ax_ht, 'HT')
  108. _plot(ax_met, 'MET')
  109. _plot(ax_njet, 'NJET')
  110. _plot(ax_nbjet, 'NBJET')
  111. @decl_plot
  112. def plot_tau_purity(rss):
  113. _, ((ax_ft, ax_ttw), (ax_ttz, ax_tth)) = plt.subplots(2, 2)
  114. ft, ttw, ttz, tth = list(map(lambda rs: hist(rs.tau_purity_v_pt), rss))
  115. def _plot(ax, dataset):
  116. plt.sca(ax)
  117. h = {'TTTT': ft,
  118. 'TTW': ttw,
  119. 'TTZ': ttz,
  120. 'TTH': tth}[dataset]
  121. hist_plot(h, stats=False, label=dataset)
  122. plt.text(200, 0.05, dataset)
  123. plt.xlabel(r"$P_T$(GeV)")
  124. _plot(ax_ft, 'TTTT')
  125. _plot(ax_ttw, 'TTW')
  126. _plot(ax_ttz, 'TTZ')
  127. _plot(ax_tth, 'TTH')
  128. if __name__ == '__main__':
  129. # First create a ResultSet object which loads all of the objects from output.root
  130. # into memory and makes them available as attributes
  131. rss = (ResultSet("ft", 'data/yield_ft.root'),
  132. ResultSet("ttw", 'data/yield_ttw.root'),
  133. ResultSet("ttz", 'data/yield_ttz.root'),
  134. ResultSet("tth", 'data/yield_tth.root'))
  135. rss_notau = (ResultSet("ft_notau", 'data/yield_ft_notau.root'),
  136. ResultSet("ttw_notau", 'data/yield_ttw_notau.root'),
  137. ResultSet("ttz_notau", 'data/yield_ttz_notau.root'),
  138. ResultSet("tth_notau", 'data/yield_tth_notau.root'))
  139. # Next, declare all of the (sub)plots that will be assembled into full
  140. # figures later
  141. yield_tau = (plot_yield_grid, (rss,), {})
  142. yield_notau = (plot_yield_grid, (rss_notau,), {})
  143. yield_tau_stack = (plot_yield_stack, (rss,), {})
  144. yield_notau_stack = (plot_yield_stack, (rss_notau,), {})
  145. sig_strength_tau = (plot_sig_strength, (rss,), {})
  146. sig_strength_notau = (plot_sig_strength, (rss_notau,), {})
  147. ft_lep_multi = (plot_lep_multi, (rss, True, 'TTTT'), {})
  148. ttw_lep_multi = (plot_lep_multi, (rss, True, 'TTW'), {})
  149. ttz_lep_multi = (plot_lep_multi, (rss, True, 'TTZ'), {})
  150. tth_lep_multi = (plot_lep_multi, (rss, True, 'TTH'), {})
  151. ft_event_obs = (plot_event_obs, (rss, 'TTTT'), {})
  152. ttw_event_obs = (plot_event_obs, (rss, 'TTW'), {})
  153. ttz_event_obs = (plot_event_obs, (rss, 'TTZ'), {})
  154. tth_event_obs = (plot_event_obs, (rss, 'TTH'), {})
  155. tau_purity = (plot_tau_purity, (rss,), {})
  156. # Now assemble the plots into figures.
  157. plots = [
  158. Plot([[yield_tau]],
  159. 'Yield With Tau'),
  160. Plot([[yield_notau]],
  161. 'Yield Without Tau'),
  162. Plot([[yield_tau_stack]],
  163. 'Yield With Tau Stacked'),
  164. Plot([[yield_notau_stack]],
  165. 'Yield Without Tau Stacked'),
  166. Plot([[yield_tau_stack],
  167. [yield_notau_stack]],
  168. 'Event Yield, top: with tau, bottom: no tau'),
  169. Plot([[sig_strength_tau],
  170. [sig_strength_notau]],
  171. 'Signal Strength'),
  172. Plot([[ft_lep_multi]],
  173. 'Lepton Multiplicity - TTTT'),
  174. Plot([[ttw_lep_multi]],
  175. 'Lepton Multiplicity - TTW'),
  176. Plot([[ttz_lep_multi]],
  177. 'Lepton Multiplicity - TTZ'),
  178. Plot([[tth_lep_multi]],
  179. 'Lepton Multiplicity - TTH'),
  180. Plot([[ft_event_obs]],
  181. 'TTTT - Event Observables'),
  182. Plot([[ttw_event_obs]],
  183. 'TTW - Event Observables'),
  184. Plot([[ttz_event_obs]],
  185. 'TTZ - Event Observables'),
  186. Plot([[tth_event_obs]],
  187. 'TTH - Event Observables'),
  188. Plot([[tau_purity]],
  189. 'Tau Purity'),
  190. ]
  191. # Finally, render and save the plots and generate the html+bootstrap
  192. # dashboard to view them
  193. render_plots(plots, to_disk=False)
  194. generate_dashboard(plots, 'TTTT Yields', output='yield2.html', source_file=__file__)