yields.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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
  6. from filval.plotter import (decl_plot, render_plots, hist_plot, hist_plot_stack, Plot)
  7. def generate_dashboard(plots, output='dashboard.htm'):
  8. from jinja2 import Environment, PackageLoader, select_autoescape
  9. from os.path import join
  10. from urllib.parse import quote
  11. env = Environment(
  12. loader=PackageLoader('plots', 'templates'),
  13. autoescape=select_autoescape(['htm', 'html', 'xml']),
  14. )
  15. env.globals.update({'quote': quote,
  16. 'enumerate': enumerate,
  17. 'zip': zip,
  18. })
  19. def render_to_file(template_name, **kwargs):
  20. with open(join('output', output), 'w') as tempout:
  21. template = env.get_template(template_name)
  22. tempout.write(template.render(**kwargs))
  23. def get_by_n(objs, n=2):
  24. objs = list(objs)
  25. while objs:
  26. yield objs[:n]
  27. objs = objs[n:]
  28. render_to_file('dashboard.htm', plots=get_by_n(plots, 3),
  29. outdir="figures/")
  30. @decl_plot
  31. def plot_yield_grid(rss):
  32. r"""## Event Yield
  33. The event yield for the eight signal regions defined in AN-17-115. Data is normalized
  34. to the Moriond 2018 integrated luminosity ($35.9\textrm{fb}^{-1}$). Code for the histogram generation is
  35. here: <https://github.com/cfangmeier/FTAnalysis/blob/master/studies/tau/Yield.C>
  36. """
  37. _, ((ax_tttt, ax_ttw), (ax_ttz, ax_tth)) = plt.subplots(2, 2)
  38. ft, ttw, ttz, tth = map(lambda rs: hist(rs.SRs), rss)
  39. plt.sca(ax_tttt)
  40. hist_plot(ft, title='TTTT', stats=False)
  41. plt.sca(ax_ttw)
  42. hist_plot(ttw, title='TTW', stats=False)
  43. plt.sca(ax_ttz)
  44. hist_plot(ttz, title='TTZ', stats=False)
  45. plt.sca(ax_tth)
  46. hist_plot(tth, title='TTH', stats=False)
  47. plt.xlabel('Signal Region')
  48. @decl_plot
  49. def plot_yield_stack(rss):
  50. r"""## Event Yield - Stacked
  51. The event yield for the eight signal regions defined in AN-17-115. Data is normalized
  52. to the Moriond 2018 integrated luminosity ($35.9\textrm{fb}^{-1}$). Code for the histogram generation is
  53. here: <https://github.com/cfangmeier/FTAnalysis/blob/master/studies/tau/Yield.C>
  54. """
  55. ft, ttw, ttz, tth = map(lambda rs: hist(rs.SRs), rss)
  56. hist_plot_stack([ttw, ttz, tth], labels=['TTW', 'TTZ', 'TTH'])
  57. ft = ft[0]*10, ft[1], ft[2]
  58. hist_plot(ft, label='TTTT (x10)', stats=False, color='k')
  59. plt.ylim((0, 160))
  60. plt.xlabel('Signal Region')
  61. plt.legend()
  62. @decl_plot
  63. def plot_sig_strength(rss):
  64. r""" The signal strength of the TTTT signal defined as
  65. $\frac{S}{\sqrt{S+B}}$
  66. """
  67. ft, ttw, ttz, tth = map(lambda rs: hist(rs.SRs), rss)
  68. bg = hist_add(ttw, ttz, tth)
  69. strength = ft[0] / np.sqrt(ft[0] + bg[0])
  70. hist_plot((strength, ft[1], ft[2]), stats=False)
  71. if __name__ == '__main__':
  72. # First create a ResultSet object which loads all of the objects from output.root
  73. # into memory and makes them available as attributes
  74. # if len(sys.argv) != 2:
  75. # raise ValueError("please supply root file")
  76. rss = (ResultSet("ft", 'data/yield_ft.root'),
  77. ResultSet("ttw", 'data/yield_ttw.root'),
  78. ResultSet("ttz", 'data/yield_ttz.root'),
  79. ResultSet("tth", 'data/yield_tth.root'))
  80. rss_notau = (ResultSet("ft_notau", 'data/yield_ft_notau.root'),
  81. ResultSet("ttw_notau", 'data/yield_ttw_notau.root'),
  82. ResultSet("ttz_notau", 'data/yield_ttz_notau.root'),
  83. ResultSet("tth_notau", 'data/yield_tth_notau.root'))
  84. # Next, declare all of the (sub)plots that will be assembled into full
  85. # figures later
  86. yield_tau = (plot_yield_grid, (rss,), {})
  87. yield_notau = (plot_yield_grid, (rss_notau,), {})
  88. yield_tau_stack = (plot_yield_stack, (rss,), {})
  89. yield_notau_stack = (plot_yield_stack, (rss_notau,), {})
  90. sig_strength_tau = (plot_sig_strength, (rss,), {})
  91. sig_strength_notau = (plot_sig_strength, (rss_notau,), {})
  92. # Now assemble the plots into figures.
  93. plots = [
  94. Plot([[yield_tau]],
  95. 'Yield With Tau'),
  96. Plot([[yield_notau]],
  97. 'Yield Without Tau'),
  98. # Plot([[yield_tau_stack]],
  99. # 'Yield With Tau Stacked'),
  100. # Plot([[yield_notau_stack]],
  101. # 'Yield Without Tau Stacked'),
  102. Plot([[yield_tau_stack],
  103. [yield_notau_stack]],
  104. 'Event Yield, top: with tau, bottom, no tau'),
  105. Plot([[sig_strength_tau],
  106. [sig_strength_notau]],
  107. 'Signal Strength')
  108. ]
  109. # Finally, render and save the plots and generate the html+bootstrap
  110. # dashboard to view them
  111. render_plots(plots, to_disk=False)
  112. generate_dashboard(plots, output='yield.html')