yields.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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_fake_taus(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_fakes_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. _plot(ax_ft, 'TTTT')
  123. _plot(ax_ttw, 'TTW')
  124. _plot(ax_ttz, 'TTZ')
  125. _plot(ax_tth, 'TTH')
  126. if __name__ == '__main__':
  127. # First create a ResultSet object which loads all of the objects from output.root
  128. # into memory and makes them available as attributes
  129. rss = (ResultSet("ft", 'data/yield_ft.root'),
  130. ResultSet("ttw", 'data/yield_ttw.root'),
  131. ResultSet("ttz", 'data/yield_ttz.root'),
  132. ResultSet("tth", 'data/yield_tth.root'))
  133. rss_notau = (ResultSet("ft_notau", 'data/yield_ft_notau.root'),
  134. ResultSet("ttw_notau", 'data/yield_ttw_notau.root'),
  135. ResultSet("ttz_notau", 'data/yield_ttz_notau.root'),
  136. ResultSet("tth_notau", 'data/yield_tth_notau.root'))
  137. # Next, declare all of the (sub)plots that will be assembled into full
  138. # figures later
  139. yield_tau = (plot_yield_grid, (rss,), {})
  140. yield_notau = (plot_yield_grid, (rss_notau,), {})
  141. yield_tau_stack = (plot_yield_stack, (rss,), {})
  142. yield_notau_stack = (plot_yield_stack, (rss_notau,), {})
  143. sig_strength_tau = (plot_sig_strength, (rss,), {})
  144. sig_strength_notau = (plot_sig_strength, (rss_notau,), {})
  145. ft_lep_multi = (plot_lep_multi, (rss, True, 'TTTT'), {})
  146. ttw_lep_multi = (plot_lep_multi, (rss, True, 'TTW'), {})
  147. ttz_lep_multi = (plot_lep_multi, (rss, True, 'TTZ'), {})
  148. tth_lep_multi = (plot_lep_multi, (rss, True, 'TTH'), {})
  149. ft_event_obs = (plot_event_obs, (rss, 'TTTT'), {})
  150. ttw_event_obs = (plot_event_obs, (rss, 'TTW'), {})
  151. ttz_event_obs = (plot_event_obs, (rss, 'TTZ'), {})
  152. tth_event_obs = (plot_event_obs, (rss, 'TTH'), {})
  153. fake_taus = (plot_fake_taus, (rss,), {})
  154. # Now assemble the plots into figures.
  155. plots = [
  156. Plot([[yield_tau]],
  157. 'Yield With Tau'),
  158. Plot([[yield_notau]],
  159. 'Yield Without Tau'),
  160. Plot([[yield_tau_stack]],
  161. 'Yield With Tau Stacked'),
  162. Plot([[yield_notau_stack]],
  163. 'Yield Without Tau Stacked'),
  164. Plot([[yield_tau_stack],
  165. [yield_notau_stack]],
  166. 'Event Yield, top: with tau, bottom: no tau'),
  167. Plot([[sig_strength_tau],
  168. [sig_strength_notau]],
  169. 'Signal Strength'),
  170. Plot([[ft_lep_multi]],
  171. 'Lepton Multiplicity - TTTT'),
  172. Plot([[ttw_lep_multi]],
  173. 'Lepton Multiplicity - TTW'),
  174. Plot([[ttz_lep_multi]],
  175. 'Lepton Multiplicity - TTZ'),
  176. Plot([[tth_lep_multi]],
  177. 'Lepton Multiplicity - TTH'),
  178. Plot([[ft_event_obs]],
  179. 'TTTT - Event Observables'),
  180. Plot([[ttw_event_obs]],
  181. 'TTW - Event Observables'),
  182. Plot([[ttz_event_obs]],
  183. 'TTZ - Event Observables'),
  184. Plot([[tth_event_obs]],
  185. 'TTH - Event Observables'),
  186. Plot([[fake_taus]],
  187. 'Hadronic Tau fake-rate'),
  188. ]
  189. # Finally, render and save the plots and generate the html+bootstrap
  190. # dashboard to view them
  191. render_plots(plots, to_disk=False)
  192. generate_dashboard(plots, 'TTTT Yields', output='yield2.html', source_file=__file__)