Skip to content

Commit 8408830

Browse files
committed
add F plots
1 parent 7f03d5c commit 8408830

File tree

5 files changed

+177
-32
lines changed

5 files changed

+177
-32
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ cd higgstocharm
4646
# Must chose --data or --MC, other options get printed
4747
# python new_Hxx.py --data --unblind --year 2017 --templates n2nano/templates_nskim17_CC.root -o Test17
4848
python new_Hxx.py --data --unblind --year 2017 -t tau/templates_new17_CC.root -o Test17 --degs 0,0 --fast 1
49+
python new_Hxx.py --data --unblind --year 2016 -t temps/templates_preapp16_CC.root --mut temps/templatesmuCR_preapp16_CC.root -o Test16 --degs 0,1
4950
```
5051

5152
## Fitting
5253

5354
### Building workspace commands
5455
```
5556
bash build.sh
56-
text2workspace.py -P HiggsAnalysis.CombinedLimit.PhysicsModel:multiSignalModel --PO verbose --PO 'map=.*/*hcc*:r[1,-500,500]' --PO 'map=.*/zcc:z[1,-5,5]' model_combined.txt
57+
# text2workspace.py -P HiggsAnalysis.CombinedLimit.PhysicsModel:multiSignalModel --PO verbose --PO 'map=.*/*hcc*:r[1,-500,500]' --PO 'map=.*/zcc:z[1,-5,5]' model_combined.txt
5758
# text2workspace.py -P HiggsAnalysis.CombinedLimit.PhysicsModel:multiSignalModel --PO verbose --PO 'map=.*/*hcc*:r[1,-500,500]' model_combined.txt
5859
# text2workspace.py -P HiggsAnalysis.CombinedLimit.PhysicsModel:multiSignalModel --PO verbose --PO 'map=.*/zcc:r[1,-5,5]' model_combined.txt
5960

config_Hxx.py

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -60,42 +60,54 @@ def _get(s):
6060

6161

6262
# SFs
63-
def ddxSF(pbin, flav):
64-
# ptbins = np.array([450, 500, 550, 600, 675, 800, 1200])
65-
_SFdict = {
66-
'cc': {
67-
"SF": [0.899, 1.152, 0.692],
68-
"up": [0.254, 0.428, 0.309],
69-
"down": [0.254, 0.426, 0.278],
70-
}
71-
}
72-
if flav not in ['bb', 'cc', 'qq']:
73-
raise ValueError("``flav`` has be one of ['bb', 'cc', 'qq'].")
74-
if pbin in [0, 1, 2]:
75-
return _SFdict[flav]['SF'][0], _SFdict[flav]['up'][0], _SFdict[flav]['down'][0]
76-
elif pbin in [3, 4]:
77-
return _SFdict[flav]['SF'][1], _SFdict[flav]['up'][1], _SFdict[flav]['down'][1]
78-
elif pbin in [5]:
79-
return _SFdict[flav]['SF'][2], _SFdict[flav]['up'][2], _SFdict[flav]['down'][2]
80-
else:
81-
raise RuntimeError()
63+
# def ddxSF(pbin, flav):
64+
# # ptbins = np.array([450, 500, 550, 600, 675, 800, 1200])
65+
# _SFdict = {
66+
# 'cc': {
67+
# "SF": [0.899, 1.152, 0.692],
68+
# "up": [0.254, 0.428, 0.309],
69+
# "down": [0.254, 0.426, 0.278],
70+
# }
71+
# }
72+
# if flav not in ['bb', 'cc', 'qq']:
73+
# raise ValueError("``flav`` has be one of ['bb', 'cc', 'qq'].")
74+
# if pbin in [0, 1, 2]:
75+
# return _SFdict[flav]['SF'][0], _SFdict[flav]['up'][0], _SFdict[flav]['down'][0]
76+
# elif pbin in [3, 4]:
77+
# return _SFdict[flav]['SF'][1], _SFdict[flav]['up'][1], _SFdict[flav]['down'][1]
78+
# elif pbin in [5]:
79+
# return _SFdict[flav]['SF'][2], _SFdict[flav]['up'][2], _SFdict[flav]['down'][2]
80+
# else:
81+
# raise RuntimeError()
8282

8383
def ddxSF(pbin, flav, year=2017):
8484
# ptbins = np.array([450, 500, 550, 600, 675, 800, 1200])
8585
_SFdict = {
86-
'cc': {
87-
"SF": [0.899, 1.152, 0.692],
88-
"up": [0.254, 0.428, 0.309],
89-
"down": [0.254, 0.426, 0.278],
90-
}
86+
2016: {
87+
'cc': {
88+
"SF": [0.77],
89+
"up": [0.15],
90+
"down": [0.15],
91+
}
92+
},
93+
2017: {
94+
'cc': {
95+
"SF": [1.24],
96+
"up": [0.2],
97+
"down": [0.2],
98+
}
99+
},
100+
2018: {
101+
'cc': {
102+
"SF": [0.94],
103+
"up": [0.15],
104+
"down": [0.15],
105+
}
106+
},
91107
}
92108
if flav not in ['bb', 'cc', 'qq']:
93109
raise ValueError("``flav`` has be one of ['bb', 'cc', 'qq'].")
94-
if pbin in [0, 1, 2]:
95-
return _SFdict[flav]['SF'][0], _SFdict[flav]['up'][0], _SFdict[flav]['down'][0]
96-
elif pbin in [3, 4]:
97-
return _SFdict[flav]['SF'][1], _SFdict[flav]['up'][1], _SFdict[flav]['down'][1]
98-
elif pbin in [5]:
99-
return _SFdict[flav]['SF'][2], _SFdict[flav]['up'][2], _SFdict[flav]['down'][2]
110+
if pbin in [0, 1, 2, 3, 4, 5]:
111+
return _SFdict[year][flav]['SF'][0], _SFdict[year][flav]['up'][0], _SFdict[year][flav]['down'][0]
100112
else:
101113
raise RuntimeError()

gofer.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,21 @@
1818
parser.add_argument('--collect', action='store_true', help='')
1919
parser.add_argument('--plot', action='store_true', help='')
2020
parser.add_argument('--year', type=str, default=None, help="Year to display on plots.")
21+
parser.add_argument('-p', '--param', type=str, choices=['bern', 'cheby', 'exp'], default='bern',
22+
help="Parametrization")
2123
args = parser.parse_args()
2224

2325
dname = args.dname
2426
print("X", dname)
2527
start = time.time()
2628

29+
if args.param == 'cheby':
30+
basis = ' --basis Bernstein,Chebyshev'
31+
elif args.param == 'exp':
32+
basis = ' --basis Bernstein,Bernstein --transform '
33+
else:
34+
basis = " "
35+
2736
if args.make:
2837
# Made workspaces
2938
for pt in range(0, 4):
@@ -33,13 +42,15 @@
3342
"python new_Hxx.py --MC --year {year} --templates tau/templates_ref{yearshort}_CC.root -o {dname}{p}{r} --degs {p},{r} "
3443
" --justZ True --muCR False --MCTF False --muCR False --systs False --scale False --smear False --unblind "
3544
.format(year=args.year, yearshort=args.year[-2:], dname=dname, p=str(pt), r=str(rho))
45+
+ basis
3646
)
3747
else:
3848
os.system(
3949
"python new_Hxx.py --data --year {year} --templates reft/templates_ref{yearshort}_CC.root -o {dname}{p}{r} --degs {p},{r} "
4050
"--mutemplates reft/templatesmuCR_ref{yearshort}_CC.root --muCR True"
4151
.format(year=args.year, yearshort=args.year[-2:], dname=dname, p=str(pt), r=str(rho))
4252
+ (" --unblind " if not args.blind else "")
53+
+ basis
4354
)
4455

4556
N = 3
@@ -112,7 +123,8 @@
112123
for pt in range(0, 3):
113124
for rho in range(0, 3):
114125
print("X", pt, rho)
115-
os.system("python fplots.py {}{}{} --year {} --out {}".format(dname, str(pt), str(rho), args.year, 'plots_{}'.format(dname)))
126+
# os.system("python fplots.py {}{}{} --year {} --out {}".format(dname, str(pt), str(rho), args.year, 'plots_{}'.format(dname)))
127+
os.system("python plot_ftest.py {}{}{} --year {} -d {}".format(dname, str(pt), str(rho), args.year, 'plots_{}'.format(dname)))
116128

117129
print("Done")
118130
end = time.time()

plot.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ def str2bool(v):
610610
if not args.run_all: continue
611611
cat_name = 'shapes_{}/ptbin{}{}{};1'.format(shape_type, i, region,
612612
args.year)
613+
print([cat_name])
613614
try:
614615
cat = f[cat_name]
615616
except Exception:

plot_ftest.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import os
2+
import sys
3+
import time
4+
import argparse
5+
import json
6+
7+
import ROOT as r
8+
import os
9+
import numpy as np
10+
import matplotlib
11+
matplotlib.use("Agg")
12+
import matplotlib.pyplot as plt
13+
import matplotlib.transforms as transforms
14+
import mplhep as hep
15+
16+
plt.style.use(hep.style.ROOT)
17+
18+
BASE = os.getcwd()
19+
20+
def get_vals(fname):
21+
rfile = r.TFile.Open(fname)
22+
rtree = rfile.Get("limit")
23+
vals = []
24+
for i in range(rtree.GetEntries()):
25+
rtree.GetEntry(i)
26+
mu = rtree.limit
27+
vals.append(mu)
28+
return vals
29+
30+
def fval(lambda1, lambda2, p1, p2, nbins):
31+
32+
numerator = -2.0 * np.log(np.array(lambda1) / np.array(lambda2)) / (p2 - p1)
33+
denominator = -2.0 * np.log(np.array(lambda2)) / (nbins - p2)
34+
35+
return numerator / denominator
36+
37+
def fplot(dname, ref, alt, year=2017, savename='fplotX', nbins=130):
38+
ref_pt, ref_rho = ref
39+
alt_pt, alt_rho = alt
40+
p1 = (ref_pt + 1) * (ref_rho + 1)
41+
p2 = (alt_pt + 1) * (alt_rho + 1)
42+
43+
alt = get_vals('{dname}/bkgtest_{ref_pt}-{ref_rho}_{alt_pt}-{alt_rho}/gofsalt.root'
44+
.format(dname=dname, ref_pt=ref_pt, ref_rho=ref_rho, alt_pt=alt_pt, alt_rho=alt_rho))
45+
base = get_vals('{dname}/bkgtest_{ref_pt}-{ref_rho}_{alt_pt}-{alt_rho}/gofsbase.root'
46+
.format(dname=dname, ref_pt=ref_pt, ref_rho=ref_rho, alt_pt=alt_pt, alt_rho=alt_rho))
47+
if len(alt) != len(base):
48+
raise ValueError("Number of toys for base and ref does not match.")
49+
fvals = fval(base, alt, 2, 3, nbins)
50+
f_data = fval(get_vals('{dname}/bkgtest_{ref_pt}-{ref_rho}_{alt_pt}-{alt_rho}/refbase.root'
51+
.format(dname=dname, ref_pt=ref_pt, ref_rho=ref_rho, alt_pt=alt_pt, alt_rho=alt_rho)),
52+
get_vals('{dname}/bkgtest_{ref_pt}-{ref_rho}_{alt_pt}-{alt_rho}/refalt.root'
53+
.format(dname=dname, ref_pt=ref_pt, ref_rho=ref_rho, alt_pt=alt_pt, alt_rho=alt_rho)),
54+
2, 3, nbins)[0]
55+
56+
from scipy.stats import f
57+
x_lim = max(np.percentile(fvals, 90), f_data*1.2)
58+
x = np.linspace(0, x_lim, 200)
59+
bins = np.linspace(0, x_lim, 30)
60+
width = bins[1] - bins[0]
61+
62+
fig, ax = plt.subplots()
63+
trans = transforms.blended_transform_factory(ax.transData, ax.transAxes)
64+
ax.plot(x, len(base) * width * f.pdf(x, p2 - p1, nbins - p2), color='red', label='F-dist, ndf({},{})'.format(p2-p1, nbins-p2))
65+
ax.hist(fvals, bins, facecolor='none', edgecolor='black', histtype='stepfilled', lw=2,
66+
label="Toys, N = {}".format(len(fvals)))
67+
ax.hist(fvals[fvals > f_data], bins, facecolor='steelblue', edgecolor='gray', histtype='stepfilled', alpha=0.3,
68+
label='p-value = {}'.format(round(float(len(fvals[fvals > f_data]))/len(fvals), 3)));
69+
ax.annotate("", xy=(f_data, 0), xycoords=trans,
70+
xytext=(f_data, 0.25), textcoords=trans,
71+
arrowprops=dict(lw='4', color='b', arrowstyle="->,head_length=1.5,head_width=0.5"),
72+
)
73+
ax.plot([], [], color='blue', lw=2, label="Observed = {:.3f}".format(f_data))
74+
75+
title = "TF({},{}) x TF({},{})".format(ref_pt, ref_rho, alt_pt, alt_rho)
76+
ax.legend(title=title)
77+
hep.cms.label(data=True, year=year, ax=ax)
78+
ax.set_xlim(0, x_lim)
79+
80+
fig.savefig('{}.pdf'.format(savename), dpi=300, transparent=True, bbox_inches='tight')
81+
fig.savefig('{}.png'.format(savename), dpi=300, transparent=True, bbox_inches='tight')
82+
83+
if __name__ == "__main__":
84+
parser = argparse.ArgumentParser(description='Make plots for ftest/gof files.')
85+
parser.add_argument('dname', nargs='?', default=os.getcwd())
86+
parser.add_argument("--degs",
87+
type=str,
88+
default=None,
89+
help="Polynomial degrees in the shape 'pt,rho' e.g. '2,2'")
90+
parser.add_argument('-d', '--savedir', type=str, default=None, help="Plots out")
91+
parser.add_argument('--year', type=str, default=None, help="Year to display on plots.")
92+
args = parser.parse_args()
93+
94+
configs = json.load(open(os.path.join(BASE, args.dname, "config.json")))
95+
if args.year is None:
96+
args.year = str(configs['year'])
97+
if args.degs is None:
98+
args.degs = str(configs['degs'])
99+
ref_pt, ref_rho = tuple([int(s) for s in args.degs.split(',')])
100+
nbins = int(configs['NBINS']) + int(configs['NBINSMU'])
101+
102+
sname = "{}_{}_{}".format(os.path.join(args.savedir, args.dname),
103+
str(ref_pt) + str(ref_rho),
104+
str(ref_pt + 1) + str(ref_rho),
105+
)
106+
fplot(os.path.join(BASE, args.dname),
107+
(ref_pt, ref_rho), (ref_pt + 1, ref_rho), args.year, sname)
108+
sname = "{}_{}_{}".format(os.path.join(args.savedir, args.dname),
109+
str(ref_pt) + str(ref_rho),
110+
str(ref_pt) + str(ref_rho + 1),
111+
)
112+
fplot(os.path.join(BASE, args.dname),
113+
(ref_pt, ref_rho), (ref_pt, ref_rho + 1), args.year, sname)
114+
sname = "{}_{}_{}".format(os.path.join(args.savedir, args.dname),
115+
str(ref_pt) + str(ref_rho),
116+
str(ref_pt + 1) + str(ref_rho + 1),
117+
)
118+
fplot(os.path.join(BASE, args.dname),
119+
(ref_pt, ref_rho), (ref_pt + 1, ref_rho + 1), args.year, sname)

0 commit comments

Comments
 (0)