7 ROOT.gROOT.SetBatch(
True)
10 return numpy.nan_to_num(numpy.subtract(numpy.multiply(N, numpy.log(mu)), mu))
13 muhat_uncapped = numpy.divide(numpy.subtract(obs,b), s)
14 muhat_low_cap = numpy.maximum(muhat_uncapped, 0.)
15 muhat_high_cap = numpy.minimum(muhat_uncapped, mu)
16 muhat_capped = numpy.maximum(muhat_high_cap, 0.)
20 bot_low_cap =
LogPoissonLike(obs, numpy.add(b, numpy.multiply(s, muhat_low_cap)))
21 bot_high_cap =
LogPoissonLike(obs, numpy.add(b, numpy.multiply(s, muhat_high_cap)))
22 bot_capped =
LogPoissonLike(obs, numpy.add(b, numpy.multiply(s, muhat_capped)))
24 numpy.multiply(-2., numpy.subtract(top, bot_standard)),
25 numpy.multiply(-2., numpy.subtract(top, bot_uncapped)),
26 numpy.multiply(-2., numpy.subtract(top, bot_low_cap)),
27 numpy.multiply(-2., numpy.subtract(top, bot_high_cap)),
28 numpy.multiply(-2., numpy.subtract(top, bot_capped)))
36 if i == 0:
return "raw_num" 37 elif i == 1:
return "standard" 38 elif i == 2:
return "no_cap" 39 elif i == 3:
return "low_cap" 40 elif i == 4:
return "high_cap" 41 elif i == 5:
return "both_capped" 42 else:
return "UNKNOWN" 46 r = background + signal
47 return math.ceil(r+5.*math.sqrt(r))
49 return 2*ROOT.RooStats.NumberCountingUtils.BinomialWithTauExpZ(signal, background, 10000.)**2 + 4
52 if i == 0:
return max(0., math.floor(background-5.*math.sqrt(background)))
53 elif i == 1:
return -
GetXmax(i, background, signal)
56 def PlotQ(i, q_0_bonly, q_0_splusb, q_1_bonly, q_1_splusb, background, signal):
58 xmax =
GetXmax(i, background, signal)
59 xmin =
GetXmin(i, background, signal)
60 h_0_bonly = ROOT.TH1D(
"q_0_bonly",
";q;Toys", nbins, xmin, xmax)
61 h_0_splusb = ROOT.TH1D(
"q_0_splusb",
";q;Toys", nbins, xmin, xmax)
62 h_1_bonly = ROOT.TH1D(
"q_1_bonly",
";q;Toys", nbins, xmin, xmax)
63 h_1_splusb = ROOT.TH1D(
"q_1_splusb",
";q;Toys", nbins, xmin, xmax)
65 for q
in q_0_bonly: h_0_bonly.Fill(q)
66 for q
in q_0_splusb: h_0_splusb.Fill(q)
67 for q
in q_1_bonly: h_1_bonly.Fill(q)
68 for q
in q_1_splusb: h_1_splusb.Fill(q)
70 Style(h_0_bonly, ROOT.kBlack, 1)
71 Style(h_0_splusb, ROOT.kBlack, 2)
72 Style(h_1_bonly, ROOT.kRed, 1)
73 Style(h_1_splusb, ROOT.kRed, 2)
75 h_dumb = ROOT.TH1D(
"q",
";q;Toys", 1, xmin, xmax)
77 h_dumb.SetMaximum(len(q_0_bonly))
78 h_dumb.SetStats(
False)
79 h_dumb.GetYaxis().SetTitleOffset(1.25)
81 l = ROOT.TLegend(0.1, 0.915, 0.9, 0.995)
84 l.AddEntry(h_0_bonly,
"q_{0}^{B}",
"l")
85 l.AddEntry(h_0_splusb,
"q_{0}^{S+B}",
"l")
86 l.AddEntry(h_1_bonly,
"q_{1}^{B}",
"l")
87 l.AddEntry(h_1_splusb,
"q_{1}^{S+B}",
"l")
90 c.SetMargin(0.1, 0.05, 0.1, 0.1)
93 h_0_bonly.Draw(
"hist same")
94 h_1_bonly.Draw(
"hist same")
95 h_0_splusb.Draw(
"hist same")
96 h_1_splusb.Draw(
"hist same")
99 c.Print(
"plots/one_bin_test_stat_q_"+
GetName(i)+
"_b_"+str(background)+
"_s_"+str(signal)+
"_toys_"+str(len(q_0_bonly))+
".pdf")
102 h_0 = ROOT.TH1D(
"",
";N_{obs};q(N_{obs})", len(n)-1, n)
103 h_1 = ROOT.TH1D(
"",
";N_{obs};q(N_{obs})", len(n)-1, n)
104 for bin
in range(1, len(n)+1):
105 h_0.SetBinContent(bin, q_0[bin-1])
106 h_1.SetBinContent(bin, q_1[bin-1])
107 h_0.SetBinError(bin, 0.)
108 h_1.SetBinError(bin, 0.)
110 Style(h_0, ROOT.kBlack, 1)
111 Style(h_1, ROOT.kRed, 1)
115 q_min = min(h_0.GetBinContent(h_0.GetMinimumBin()),
116 h_1.GetBinContent(h_1.GetMinimumBin()))
117 q_max = max(h_0.GetBinContent(h_0.GetMaximumBin()),
118 h_1.GetBinContent(h_1.GetMaximumBin()))
119 h_0.SetMinimum(q_min)
120 h_0.SetMaximum(q_max)
121 h_1.SetMinimum(q_min)
122 h_1.SetMaximum(q_max)
127 h_1.Draw(
"hist l same")
129 l = ROOT.TLegend(0.1, 0.915, 0.9, 0.995)
132 l.AddEntry(h_0,
"q_{0}",
"l")
133 l.AddEntry(h_1,
"q_{1}",
"l")
136 c.Print(
"plots/one_bin_test_stat_q_vs_n_"+
GetName(i)+
"_b_"+str(background)+
"_s_"+str(signal)+
".pdf")
140 xmax =
GetXmax(i, background, signal)
141 xmin =
GetXmin(i, background, signal)
142 h_bonly = ROOT.TH1D(
"",
";q_{"+str(mu)+
"};Toys", nbins, xmin, xmax)
143 h_splusb = ROOT.TH1D(
"",
";q_{"+str(mu)+
"};Toys", nbins, xmin, xmax)
145 for q
in q_bonly: h_bonly.Fill(q)
146 for q
in q_splusb: h_splusb.Fill(q)
148 Style(h_bonly, ROOT.kBlack, 1)
149 Style(h_splusb, ROOT.kBlack, 2)
151 h_dumb = ROOT.TH1D(
"",
";q_{"+str(mu)+
"};Toys", 1, xmin, xmax)
152 h_dumb.SetMinimum(1.)
153 h_dumb.SetMaximum(len(q_bonly))
154 h_dumb.SetStats(
False)
155 h_dumb.GetYaxis().SetTitleOffset(1.25)
156 h_dumb.SetFillStyle(0)
157 h_dumb.SetFillColor(0)
158 h_dumb.SetLineStyle(0)
159 h_dumb.SetLineColor(0)
160 h_dumb.SetLineWidth(0)
161 h_dumb.SetMarkerStyle(0)
162 h_dumb.SetMarkerColor(0)
163 h_dumb.SetMarkerSize(0)
165 q_example =
GetQs(mu, signal, background, background)[i]
166 clb = numpy.mean(numpy.greater_equal(q_bonly, q_example))
167 clsb = numpy.mean(numpy.greater_equal(q_splusb, q_example))
169 clb = numpy.mean(numpy.less_equal(q_bonly, q_example))
170 clsb = numpy.mean(numpy.less_equal(q_splusb, q_example))
173 line = ROOT.TLine(q_example, 1., q_example, len(q_bonly))
174 line.SetLineColor(ROOT.kGreen)
179 c.SetMargin(0.1, 0.05, 0.1, 0.2)
183 h_bonly.Draw(
"hist same")
184 h_splusb.Draw(
"hist same")
187 l = ROOT.TLegend(0.1, 0.83, 0.9, 0.995)
191 l.AddEntry(h_dumb,
"r="+str(round(mu,3)),
"l")
193 l.AddEntry(h_splusb,
"q_{"+str(round(mu,3))+
"}^{rS+B} (CL_{S+B}="+str(round(clsb,3))+
")",
"l")
195 l.AddEntry(h_splusb,
"N^{rS+B} (CL_{S+B}="+str(round(clsb,3))+
")",
"l")
196 l.AddEntry(h_dumb,
"CL_{S}="+str(round(cls,3)),
"l")
198 l.AddEntry(h_bonly,
"q_{"+str(round(mu,3))+
"}^{B} (CL_{B}="+str(round(clb,3))+
")",
"l")
200 l.AddEntry(h_bonly,
"N^{B} (CL_{B}="+str(round(clb,3))+
")",
"l")
203 c.Print(
"plots/one_bin_test_stat_cls_scan_"+
GetName(i)+
"_mu_"+str(mu)+
"_b_"+str(background)+
"_s_"+str(signal)+
"_toys_"+str(len(q_bonly))+
".pdf")
206 backgrounds = numpy.random.poisson(background, num_toys)
207 splusb = numpy.random.poisson(signal+background, num_toys)
209 q_0_bonly =
GetQs(0., signal, background, backgrounds)
210 q_0_splusb =
GetQs(0., signal, background, splusb)
211 q_1_bonly =
GetQs(1., signal, background, backgrounds)
212 q_1_splusb =
GetQs(1., signal, background, splusb)
213 q_2_bonly =
GetQs(2., signal, background, backgrounds)
214 q_2_splusb =
GetQs(2., signal, background, splusb)
215 q_3_bonly =
GetQs(3., signal, background, backgrounds)
216 q_3_splusb =
GetQs(3., signal, background, splusb)
218 nmin =
GetXmin(0, background, signal)
219 nmax =
GetXmax(0, background, signal)
220 n = numpy.linspace(nmin, nmax, 100)
222 q_0 =
GetQs(0., signal, background, n)
223 q_1 =
GetQs(1., signal, background, n)
225 for i
in range(0, 6):
226 PlotQ(i, q_0_bonly[i], q_0_splusb[i], q_1_bonly[i], q_1_splusb[i], background, signal)
227 PlotQVsN(i, n, q_0[i], q_1[i], background, signal)
228 for mu
in [0., 0.25, 0.5, 0.654511, 0.75, 1.]:
230 if mu == 1.: obs = splusb
231 elif mu != 0.: obs = numpy.random.poisson(background+mu*signal, num_toys)
232 q_bonly =
GetQs(mu, signal, background, backgrounds)
233 q_splusb =
GetQs(mu, signal, background, obs)
234 for i
in range(0, 6):
237 if __name__ ==
"__main__":
238 parser = argparse.ArgumentParser(description=
"Plots distributions of test statistics for a single bin counting experiment",
239 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
240 parser.add_argument(
"background", type=float, help=
"True background rate")
241 parser.add_argument(
"signal", type=float, help=
"True signal rate")
242 parser.add_argument(
"--num_toys", type=int, default=100000, help=
"Number of toys to throw when plotting distributions.")
243 args = parser.parse_args()
def LogPoissonLike(N, mu)
def OneBinTestStatistic(background, signal, num_toys)
def ScanSigStrength(i, mu, q_bonly, q_splusb, background, signal)
def PlotQ(i, q_0_bonly, q_0_splusb, q_1_bonly, q_1_splusb, background, signal)
def Style(h, color, style)
def GetXmin(i, background, signal)
def GetXmax(i, background, signal)
def PlotQVsN(i, n, q_0, q_1, background, signal)