Skip to content

Commit 52dfb62

Browse files
committed
Compare script for crosssec: ratio on the same canvas
1 parent ef90ca1 commit 52dfb62

File tree

1 file changed

+174
-51
lines changed

1 file changed

+174
-51
lines changed

PWGHF/D2H/Macros/compare_fractions.py

Lines changed: 174 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010
import json
1111
import math
1212
import os
13+
from array import array
1314

1415
from ROOT import ( # pylint: disable=import-error,no-name-in-module
1516
TCanvas,
1617
TFile,
1718
TGraphErrors,
19+
TH1F,
1820
TLegend,
1921
TPaveText,
2022
TLine,
23+
TPad,
2124
gROOT,
2225
gStyle,
2326
kAzure,
@@ -66,14 +69,40 @@ def get_legend(x_1, y_1, x_2, y_2, num_hists):
6669
leg.SetFillStyle(0)
6770
return leg
6871

69-
def prepare_canvas(cname):
70-
canv = TCanvas(cname, "")
71-
canv.SetCanvasSize(900, 600)
72-
canv.SetTickx()
73-
canv.SetTicky()
74-
canv.SetLeftMargin(0.15)
75-
canv.SetBottomMargin(0.15)
76-
return canv
72+
def prepare_canvas(cname, logy):
73+
canv = TCanvas(cname, "", 443, 100, 700, 700)
74+
canv.Range(0, 0, 1, 1)
75+
#canv.SetTickx()
76+
#canv.SetTicky()
77+
#canv.SetLeftMargin(0.15)
78+
#canv.SetBottomMargin(0.15)
79+
80+
canv_top = TPad(f"{cname}_top", "", 0.01, 0.3, 0.99, 0.99)
81+
if logy:
82+
canv_top.SetLogy()
83+
canv_top.SetLeftMargin(0.13)
84+
canv_top.SetRightMargin(0.05)
85+
canv_top.SetBottomMargin(0.1)
86+
canv_top.SetTopMargin(0.05)
87+
88+
canv.Modified()
89+
canv.cd()
90+
canvr = TPad(f"{cname}_ratio", "", 0.01, 0.01, 0.99, 0.365)
91+
canvr.SetBottomMargin(0.25)
92+
canvr.SetLeftMargin(0.13)
93+
canvr.SetRightMargin(0.05)
94+
95+
for canvas in (canv, canv_top, canvr):
96+
canvas.SetFillColor(0)
97+
canvas.SetBorderMode(0)
98+
canvas.SetBorderSize(2)
99+
canvas.SetFrameBorderMode(0)
100+
canvas.SetGridy()
101+
canvr.Draw()
102+
canv_top.cd()
103+
canv_top.Draw()
104+
105+
return canv, canv_top, canvr
77106

78107

79108
def save_canvas(canv, cfg, filename):
@@ -158,14 +187,14 @@ def get_graph_systematics(hist, label, color, cfg):
158187
graph_syst = fin.Get(cfg["hists"][label]["systematics"][1])
159188
else:
160189
graph_syst = TGraphErrors()
190+
graph_syst.SetName(f"graph_{label}_syst")
161191
for binn in range(hist.GetNbinsX()):
162192
syst_err = combine_syst_errors(cfg["hists"][label]["systematics"][binn],
163193
hist.GetBinContent(binn + 1))
164194
print(f"Syst error {label} bin {binn + 1} {syst_err}")
165195
x_point = hist.GetBinCenter(binn + 1)
166196
y_point = hist.GetBinContent(binn + 1)
167-
x_width = hist.GetBinWidth(binn + 1) / 2.0
168-
x_width /= 2.0 # We want syst boxes to be of half-bin width
197+
x_width = hist.GetBinWidth(binn + 1) / 4.0
169198
if y_point != 0:
170199
graph_syst.SetPoint(binn, x_point, y_point)
171200
graph_syst.SetPointError(binn, x_width, syst_err)
@@ -187,11 +216,7 @@ def get_hist_model(label, color, style, cfg):
187216
return hist
188217

189218

190-
def plot_compare(cfg):
191-
canv = prepare_canvas(f'c_{cfg["histoname"]}')
192-
if cfg.get("log_scale", False):
193-
canv.SetLogy()
194-
219+
def plot_compare(cfg, canv_main, canv):
195220
maxy = 0.
196221
miny = 1000000.
197222

@@ -217,13 +242,20 @@ def plot_compare(cfg):
217242

218243
hists = {}
219244
graphs_syst = []
245+
central_graph = None
220246
for ind, (label, color) in enumerate(zip(cfg["hists"], COLORS)):
221247
hist = get_hist_for_label(label, color, cfg)
222248
print(label)
223249
miny, maxy = get_hist_limits(hist, None, miny, maxy)
224250

225251
canv.cd()
226252
draw_opt = "same" if ind != 0 or len(hists_models) > 0 else ""
253+
for axis in (hist.GetXaxis(), hist.GetYaxis()):
254+
axis.SetLabelFont(42)
255+
axis.SetLabelSize(0.05)
256+
axis.SetTitleSize(0.058)
257+
axis.SetTitleOffset(1.05)
258+
axis.SetTitleFont(42)
227259
hist.Draw(draw_opt)
228260
leg.AddEntry(hist, label, "p")
229261

@@ -235,8 +267,10 @@ def plot_compare(cfg):
235267
miny, maxy = get_hist_limits(hist, graph_syst, miny, maxy)
236268
graph_syst.Draw("sameE2")
237269
graphs_syst.append(graph_syst)
270+
if label == cfg["default"]:
271+
central_graph = graph_syst
238272

239-
margin = 0.1
273+
margin = 1.0
240274
#k = 1.0 - 2 * margin
241275
#rangey = maxy - miny
242276
#miny = miny - margin / k * rangey
@@ -245,7 +279,8 @@ def plot_compare(cfg):
245279
#miny = min(miny - margin * miny, 0)
246280
miny = miny - margin * miny
247281
if miny <= 0:
248-
miny = 0.1
282+
miny = 0.006
283+
maxy = 4000
249284
print(f"Recalculated hist maxy: {maxy + margin * maxy} miny: {miny}")
250285
for hist_models in hists_models:
251286
hist_models.GetYaxis().SetRangeUser(miny, maxy + margin * maxy)
@@ -263,48 +298,124 @@ def plot_compare(cfg):
263298
alice_text = get_alice_text(cfg["alice_text"])
264299
alice_text.Draw("same")
265300

266-
return canv, hists, graphs_syst, hists_models, leg, leg_models, alice_text
267-
268-
269-
def plot_ratio(cfg, hists):
270-
canvr = prepare_canvas(f'c_ratio_{cfg["histoname"]}')
271-
#legr = get_legend(0.32, 0.15, 0.82, 0.31, len(cfg["hists"]))
301+
canv_main.cd()
302+
canv.Draw()
303+
canv_main.Draw()
304+
305+
return canv_main, canv, hists, graphs_syst, hists_models, leg, leg_models, alice_text, central_graph
306+
307+
308+
def get_average(hist, graph_syst):
309+
width_combined = hist.GetBinWidth(hist.GetNbinsX() -1) + hist.GetBinWidth(hist.GetNbinsX())
310+
val = ((hist.GetBinContent(hist.GetNbinsX() - 1) * hist.GetBinWidth(hist.GetNbinsX() - 1) +\
311+
hist.GetBinContent(hist.GetNbinsX()) * hist.GetBinWidth(hist.GetNbinsX())) /\
312+
width_combined)
313+
err = math.sqrt((hist.GetBinError(hist.GetNbinsX() - 1) *\
314+
hist.GetBinWidth(hist.GetNbinsX() - 1) /\
315+
width_combined) **2 +\
316+
(hist.GetBinError(hist.GetNbinsX()) *\
317+
hist.GetBinWidth(hist.GetNbinsX()) /\
318+
width_combined) ** 2)
319+
syst_err = math.sqrt((graph_syst.GetErrorYlow(hist.GetNbinsX() - 2) *\
320+
hist.GetBinWidth(hist.GetNbinsX() - 1) /\
321+
width_combined) **2 +\
322+
(graph_syst.GetErrorYlow(hist.GetNbinsX() - 1) *\
323+
hist.GetBinWidth(hist.GetNbinsX()) /\
324+
width_combined) ** 2)
325+
return val, err, syst_err
326+
327+
328+
def hist_for_ratio(hist, graph, central_hist):
329+
hist2 = TH1F(hist.GetName(), "", central_hist.GetNbinsX(),
330+
array('d', central_hist.GetXaxis().GetXbins()))
331+
graph2 = TGraphErrors()
332+
for binn in range(central_hist.GetNbinsX() - 1):
333+
hist2.SetBinContent(binn + 1, hist.GetBinContent(binn + 1))
334+
hist2.SetBinError(binn + 1, hist.GetBinError(binn + 1))
335+
graph2.SetPoint(binn, graph.GetPointX(binn), graph.GetPointY(binn))
336+
graph2.SetPointError(binn, graph.GetErrorX(binn), graph.GetErrorY(binn))
337+
val, err, syst_err = get_average(hist, graph)
338+
hist2.SetBinContent(hist2.GetNbinsX(), val)
339+
hist2.SetBinError(hist2.GetNbinsX(), err)
340+
graph2.SetPoint(hist2.GetNbinsX() - 1, hist2.GetBinCenter(hist2.GetNbinsX()), val)
341+
graph2.SetPointError(hist2.GetNbinsX() - 1, hist2.GetBinWidth(hist2.GetNbinsX()) / 4.0, syst_err)
342+
return hist2, graph2
343+
344+
345+
def divide_syst_error(val, val1, val2, err1, err2, hist, binn):
346+
return val * math.sqrt((err1 / val1) **2 + (err2 / val2) **2)
347+
348+
349+
def plot_ratio(cfg, hists, graphs_syst, central_graph, canv, canvr):
272350
legr = get_legend(*cfg["legend_ratio"], len(cfg["hists"]))
273351

274352
histsr = []
275-
miny = 0.85
276-
maxy = 1.15
353+
graphsr = []
354+
miny = 0.45
355+
maxy = 1.55
277356
maxx = 0.0
278357
central_hist = hists[cfg["default"]]
279-
for ind, (label, color) in enumerate(zip(hists, COLORS)):
280-
print(f"central hist bins: {central_hist.GetNbinsX()} {label} bins: {hists[label].GetNbinsX()}")
281-
if label != cfg["default"] and hists[label].GetNbinsX() == central_hist.GetNbinsX():
282-
#histr = hists[label].Clone()
358+
for ind, (label, graph, color) in enumerate(zip(hists, graphs_syst, COLORS)):
359+
print(f"central hist bins: {central_hist.GetNbinsX()} "\
360+
f"{label} bins: {hists[label].GetNbinsX()}")
361+
if label != cfg["default"]: #and hists[label].GetNbinsX() == central_hist.GetNbinsX():
362+
print("Doing ratio")
363+
hist_ratio, graph_ratio = hist_for_ratio(hists[label], graph, central_hist)
283364
histr = central_hist.Clone()
365+
graphr = central_graph.Clone()
284366
for binn in range(1, central_hist.GetNbinsX() + 1):
285-
histr.SetBinContent(binn, hists[label].GetBinContent(binn))
286-
histr.SetBinError(binn, hists[label].GetBinError(binn))
287-
print(f"Central hist bin {binn} {central_hist.GetBinContent(binn)} {label} hist bin: {hists[label].GetBinContent(binn)}")
288-
histr.SetName(f"h_ratio_{label}")
289-
histr.SetMarkerColor(color)
290-
histr.SetLineColor(color)
291-
367+
histr.SetBinContent(binn, hist_ratio.GetBinContent(binn))
368+
histr.SetBinError(binn, hist_ratio.GetBinError(binn))
369+
print(f"Central hist bin {binn} [{central_hist.GetXaxis().GetBinLowEdge(binn)}, "\
370+
f"{central_hist.GetXaxis().GetBinLowEdge(binn + 1)}): {central_hist.GetBinContent(binn)} "\
371+
f"{label} hist bin [{hist_ratio.GetXaxis().GetBinLowEdge(binn)}, "\
372+
f"{hist_ratio.GetXaxis().GetBinLowEdge(binn + 1)}): {hist_ratio.GetBinContent(binn)}")
292373
histr.Divide(central_hist)
293-
#histr.SetBinContent(histr.GetNbinsX(), 0.0)
294-
#histr.SetBinError(histr.GetNbinsX(), 0.0)
295-
#histr.SetBinContent(1, 0.0)
296-
#histr.SetBinError(1, 0.0)
297-
#miny, maxy = get_hist_limits(histr, None, miny, maxy)
298-
#for binn in range(histr.GetNbinsX()):
299-
# print(f"ratio bin {binn + 1}: {histr.GetBinContent(binn + 1)}")
374+
for binn in range(2, central_hist.GetNbinsX() + 1):
375+
x_err = histr.GetBinWidth(binn) / 4.0
376+
y_low = divide_syst_error(histr.GetBinContent(binn),
377+
hist_ratio.GetBinContent(binn),
378+
central_hist.GetBinContent(binn),
379+
central_graph.GetErrorYlow(binn - 1),
380+
graph_ratio.GetErrorYlow(binn - 1), histr, binn)
381+
y_high = divide_syst_error(histr.GetBinContent(binn),
382+
hist_ratio.GetBinContent(binn),
383+
central_hist.GetBinContent(binn),
384+
central_graph.GetErrorYhigh(binn - 1),
385+
graph_ratio.GetErrorYhigh(binn - 1), histr, binn)
386+
graphr.SetPoint(binn - 1, histr.GetBinCenter(binn), histr.GetBinContent(binn))
387+
graphr.SetPointError(binn - 1, x_err, x_err, y_low, y_high)
388+
print(f"Central graph bin {binn-1} low {central_graph.GetErrorYlow(binn-1)} "\
389+
f"{label} low: {graph_ratio.GetErrorYlow(binn-1)} "\
390+
f"up {central_graph.GetErrorYhigh(binn-1)} {label} up: {graph_ratio.GetErrorYhigh(binn-1)}")
391+
histr.SetName(f"h_ratio_{label}")
392+
graphr.SetName(f"g_ratio_{label}")
393+
for fig in (histr, graphr):
394+
fig.SetMarkerColor(color)
395+
fig.SetLineColor(color)
396+
fig.SetLineWidth(2)
397+
fig.SetMarkerStyle(1)
398+
fig.SetMarkerSize(1)
399+
for binn in range(histr.GetNbinsX()):
400+
print(f"ratio bin {binn + 1}: {histr.GetBinContent(binn + 1)}")
300401
print(f"maxy {maxy} miny {miny}")
301-
draw_opt = "same" if ind != 0 else ""
302-
histr.GetYaxis().SetTitle("Ratio")
402+
canvr.cd()
403+
draw_opt = "samePE1" if ind != 0 else "PE1"
303404
histr.SetMaximum(maxy)
304405
histr.SetMinimum(miny)
406+
for axis in (histr.GetXaxis(), histr.GetYaxis()):
407+
axis.SetLabelFont(42)
408+
axis.SetLabelSize(0.1)
409+
axis.SetTitleSize(0.12)
410+
axis.SetTitleOffset(0.95)
411+
axis.SetTitleFont(42)
412+
histr.GetYaxis().SetTitleOffset(0.5)
413+
histr.GetYaxis().SetTitle("Ratio")
305414
histr.Draw(draw_opt)
415+
graphr.Draw("sameE2")
306416
legr.AddEntry(histr, label, "p")
307417
histsr.append(histr)
418+
graphsr.append(graphr)
308419
maxx = max(maxx, histr.GetBinLowEdge(histr.GetNbinsX() + 1))
309420

310421
line = TLine(0.0, 1.0, maxx, 1.0)
@@ -313,9 +424,12 @@ def plot_ratio(cfg, hists):
313424
line.SetLineStyle(kDashed)
314425
line.Draw()
315426

316-
legr.Draw()
427+
#legr.Draw()
428+
canv.cd()
429+
canvr.Draw()
430+
canv.Draw()
317431

318-
return canvr, histsr, legr, line
432+
return canv, canvr, histsr, graphsr, legr, line
319433

320434

321435
def calc_systematics(cfg, hists):
@@ -351,6 +465,7 @@ def main():
351465
gROOT.SetBatch(True)
352466

353467
gStyle.SetOptStat(0)
468+
gStyle.SetOptTitle(0)
354469
gStyle.SetFrameLineWidth(2)
355470

356471
parser = argparse.ArgumentParser(description="Arguments to pass")
@@ -363,26 +478,34 @@ def main():
363478
with TFile(os.path.join(cfg["output"]["outdir"],
364479
f'{cfg["output"]["file"]}.root'), "recreate") as output:
365480

366-
canv, hists, graphs_syst, hists_models, leg, leg_models, alice_text = plot_compare(cfg) # pylint: disable=unused-variable
481+
canv, canv_top, canvr = prepare_canvas(f'c_{cfg["histoname"]}', cfg.get("log_scale", False))
482+
canv, canv_top, hists, graphs_syst, hists_models, leg, leg_models, alice_text, central_graph = plot_compare(cfg, canv, canv_top) # pylint: disable=unused-variable
367483
output.cd()
368-
canv.Write()
369-
save_canvas(canv, cfg, cfg["output"]["file"])
484+
canv_top.Write()
485+
save_canvas(canv_top, cfg, f'{cfg["output"]["file"]}_top')
370486
for _, hist in hists.items():
371487
hist.Write()
372488
for graph in graphs_syst:
373489
graph.Write()
374490
for hist in hists_models:
375491
hist.Write()
376492

377-
canvr, histr, legr, line = plot_ratio(cfg, hists)
493+
canv, canvr, histr, graphr, legr, line = plot_ratio(cfg, hists, graphs_syst, central_graph, canv, canvr)
378494
output.cd()
495+
canv.Write()
496+
save_canvas(canv, cfg, f'{cfg["output"]["file"]}')
379497
canvr.Write()
380498
save_canvas(canvr, cfg, f'{cfg["output"]["file"]}_ratio')
381499
for hist in histr:
382500
hist.Write()
501+
for graph in graphr:
502+
graph.Write()
383503

384504
calc_systematics(cfg, hists)
385505

506+
canv_top.Delete()
507+
canvr.Delete()
508+
386509

387510
if __name__ == "__main__":
388511
main()

0 commit comments

Comments
 (0)