forked from sagittaeri/htt
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplot-ranking
More file actions
executable file
·164 lines (152 loc) · 6.46 KB
/
plot-ranking
File metadata and controls
executable file
·164 lines (152 loc) · 6.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env python
# python imports
import pickle
import os
import logging
# ROOT/rootpy imports
from rootpy.plotting import Canvas, Pad, Legend, Graph, Hist, get_style, set_style
from rootpy.plotting.utils import draw
from rootpy.plotting.style.atlas.labels import ATLAS_label
from rootpy.utils.path import mkdir_p
from rootpy import ROOT
from ROOT import TLine, TGaxis, TLatex
# local imports
from statstools.plotting import get_data, print_np
log = logging.getLogger(os.path.basename(__file__))
# set the style
style = get_style('ATLAS', shape='square')
style.SetPadLeftMargin(0.09)
style.SetPadBottomMargin(0.4)
style.SetPadRightMargin(0.03)
style.SetTitleYOffset(0.8)
style.SetHatchesLineWidth(2)
style.SetHatchesSpacing(0.5)
# remove ticks on top X axis
style.SetPadTickX(0)
set_style(style)
# guide lines
line = TLine()
line.SetLineStyle(7)
line.SetLineWidth(2)
solid_line = TLine()
solid_line.SetLineWidth(1)
if not os.getenv('MVA_NO_BATCH', False):
ROOT.gROOT.SetBatch(True)
def plot_ranking(name, file, outdir):
# make the ranking plot
data = get_data(file)
n_points = len(data)
c = Canvas(width=1024, height=1448)
c.margin = (0, 0, 0, 0)
pad1 = Pad(0, 0, 1, 1)
pad1.margin = (0.3, 0.05, 0.09, 0.09)
pad1.Draw()
# inset for NormFactors
#pad2 = Pad(0.63, 0.1, 0.94, 0.22, 0)
xaxis, yaxis = pad1.axes(xlimits=(-2, 2), ylimits=(-0.5 - 2, n_points + 2 - 0.5))
xaxis.title = '(#theta_{fit} - #theta_{0}) / #Delta#theta'
yaxis.SetTickLength(0)
yaxis.SetLabelOffset(999)
# rank by postfit impact on mu
ranking = []
for np, info in data.items():
prefit_low, prefit_nom, prefit_high = info['poi_prefit']
postfit_low, postfit_nom, postfit_high = info['poi_postfit']
prefit_impact_low = (prefit_nom - prefit_low) / prefit_nom
prefit_impact_high = (prefit_high - prefit_nom) / prefit_nom
postfit_impact_low = (postfit_nom - postfit_low) / postfit_nom
postfit_impact_high = (postfit_high - postfit_nom) / postfit_nom
# for ranking use full width of postfit impact
postfit_impact = (max(postfit_high, postfit_low, postfit_nom) -
min(postfit_high, postfit_low, postfit_nom)) / postfit_nom
ranking.append((np, postfit_impact,
(prefit_impact_low, prefit_impact_high),
(postfit_impact_low, postfit_impact_high)))
# sort by postfit impact
ranking.sort(key=lambda item: abs(item[1]))
# make pull graph
pulls = Graph(n_points, drawstyle='P', linewidth=2, markersize=1,
legendstyle='LP',
title="postfit value and #pm1#sigma uncertainty")
pulls_1sigma = pulls.Clone(drawstyle='2', linewidth=0, markersize=0,
fillcolor='yellow', fillstyle='solid',
legendstyle='F',
title="#pm1#sigma prefit uncertainty")
prefit_graph = pulls_1sigma.Clone(fillstyle='\\', color='blue', linewidth=2,
legendstyle='F',
title="#pm1#sigma prefit impact on #hat{#mu}")
postfit_graph = pulls_1sigma.Clone(fillstyle='/', color='red', linewidth=2,
legendstyle='F',
title="#pm1#sigma postfit impact on #hat{#mu}")
for i, (np, impact, prefit, postfit) in enumerate(ranking):
info = data[np]
low, mid, high = info['np']
pulls_1sigma.SetPoint(i, mid, i)
pulls_1sigma.SetPointError(i, 1, 1, 0.5, 0.5)
err_up = high - mid
err_dn = mid - low
pulls.SetPoint(i, mid, i)
pulls.SetPointError(i, err_dn, err_up, 0, 0)
log.info('{0} pull: {1} < {2} < {3}'.format(np, err_dn, mid, err_up))
prefit_graph.SetPoint(i, 0, i)
postfit_graph.SetPoint(i, 0, i)
prefit_impact_low, prefit_impact_high = prefit
postfit_impact_low, postfit_impact_high = postfit
prefit_graph.SetPointError(i, prefit_impact_low * 4, prefit_impact_high * 4, 0.5, 0)
postfit_graph.SetPointError(i, postfit_impact_low * 4, postfit_impact_high * 4, 0, 0.5)
nuis_name = TLatex()
nuis_name.SetTextAlign(32)
nuis_name.SetTextSize(12)
with pad1:
# mu axis
mu_axis = TGaxis(-2, n_points + 2 - 0.5, 2, n_points + 2 - 0.5, -0.5, 0.5, 510, '-')
mu_axis.SetTitle('#Delta#hat{#mu}/#hat{#mu}')
mu_axis.SetLabelFont(xaxis.GetLabelFont())
mu_axis.SetTitleFont(xaxis.GetTitleFont())
mu_axis.SetLabelSize(xaxis.GetLabelSize())
mu_axis.SetTitleSize(xaxis.GetTitleSize())
mu_axis.SetLabelOffset(-0.005) # HACK
mu_axis.SetTitleOffset(xaxis.GetTitleOffset())
mu_axis.Draw()
# draw 1sigma pull graph
pulls_1sigma.Draw('SAME')
# impact graphs
prefit_graph.Draw('SAME')
postfit_graph.Draw('SAME')
# draw guide lines
line.DrawLine(1, -0.5 - 2, 1, n_points + 2 - 0.5)
line.DrawLine(-1, -0.5 - 2, -1, n_points + 2 - 0.5)
line.DrawLine(0, -0.5 - 2, 0, n_points + 2 - 0.5)
for i in xrange(n_points):
solid_line.DrawLine(-2, i - 0.5, 2, i - 0.5)
nuis_name.DrawLatex(-2.1, i, print_np(ranking[i][0]))
solid_line.DrawLine(-2, i + 0.5, 2, i + 0.5)
pulls.Draw('SAME')
ATLAS_label(0.03, 1. - pad1.GetTopMargin(), text="Internal", sqrts=None, pad=pad1, sep=0.1,
textsize=30)
mu_legend = Legend((prefit_graph, postfit_graph), pad=pad1,
topmargin=-pad1.GetTopMargin(),
leftmargin=0,
entryheight=0.018,
margin=0.1)
theta_legend = Legend((pulls, pulls_1sigma), pad=pad1,
topmargin=0.85,
leftmargin=0,
entryheight=0.018,
margin=0.1)
mu_legend.Draw()
theta_legend.Draw()
c.SaveAs(os.path.join(outdir, '{0}.png'.format(name)))
c.SaveAs(os.path.join(outdir, '{0}.eps'.format(name)))
if __name__ == '__main__':
from rootpy.extern.argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('--name', default='ranking')
parser.add_argument('file')
args = parser.parse_args()
input = os.path.splitext(args.file)[0]
pulls = input + '_pulls.pickle'
plots = input + '_plots'
if not os.path.exists(plots):
mkdir_p(plots)
plot_ranking(args.name, pulls, plots)