Skip to content

Commit f06a697

Browse files
authored
[PWGHF] Cut variation - enhance plotting features, minor code cleaning and chore (#11726)
1 parent 1435203 commit f06a697

File tree

3 files changed

+79
-50
lines changed

3 files changed

+79
-50
lines changed

PWGHF/D2H/Macros/compute_fraction_cutvar.py

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import ROOT # pylint: disable=import-error
1717
sys.path.insert(0, '..')
1818
from cut_variation import CutVarMinimiser
19-
from utils.style_formatter import set_object_style
19+
from style_formatter import set_object_style
2020

2121
# pylint: disable=no-member,too-many-locals,too-many-statements
2222

@@ -27,29 +27,45 @@ def main(config):
2727
"""
2828

2929
ROOT.gROOT.SetBatch(True)
30+
ROOT.TH1.AddDirectory(False)
3031

3132
with open(config, encoding="utf8") as fil:
3233
cfg = json.load(fil)
3334

3435
hist_rawy, hist_effp, hist_effnp = ([] for _ in range(3))
3536
for filename_rawy, filename_eff in zip(cfg["rawyields"]["inputfiles"], cfg["efficiencies"]["inputfiles"]):
3637
infile_rawy = ROOT.TFile.Open(os.path.join(cfg["rawyields"]["inputdir"], filename_rawy))
37-
hist_rawy.append(infile_rawy.Get(cfg["rawyields"]["histoname"]))
38+
hist_rawy_name = cfg["rawyields"]["histoname"]
39+
hist_rawy.append(infile_rawy.Get(hist_rawy_name))
40+
if(hist_rawy[-1] is None):
41+
sys.exit(f"Fatal error: Histogram with raw yield \"{hist_rawy_name}\" is absent. Exit.")
3842
hist_rawy[-1].SetDirectory(0)
3943
infile_rawy.Close()
4044

4145
infile_eff = ROOT.TFile.Open(os.path.join(cfg["efficiencies"]["inputdir"], filename_eff))
42-
hist_effp.append(infile_eff.Get(cfg["efficiencies"]["histonames"]["prompt"]))
43-
hist_effnp.append(infile_eff.Get(cfg["efficiencies"]["histonames"]["nonprompt"]))
46+
hist_effp_name = cfg["efficiencies"]["histonames"]["prompt"]
47+
hist_effnp_name = cfg["efficiencies"]["histonames"]["nonprompt"]
48+
hist_effp.append(infile_eff.Get(hist_effp_name))
49+
hist_effnp.append(infile_eff.Get(hist_effnp_name))
50+
if(hist_effp[-1] is None):
51+
sys.exit(f"Fatal error: Histogram with efficiency for prompt \"{hist_effp_name}\" is absent. Exit.")
52+
if(hist_effnp[-1] is None):
53+
sys.exit(f"Fatal error: Histogram with efficiency for nonprompt \"{hist_effnp}\" is absent. Exit.")
4454
hist_effp[-1].SetDirectory(0)
4555
hist_effnp[-1].SetDirectory(0)
4656
infile_eff.Close()
4757

4858
if cfg["central_efficiency"]["computerawfrac"]:
4959
infile_name = os.path.join(cfg["central_efficiency"]["inputdir"], cfg["central_efficiency"]["inputfile"])
5060
infile_central_eff = ROOT.TFile.Open(infile_name)
51-
hist_central_effp = infile_central_eff.Get(cfg["central_efficiency"]["histonames"]["prompt"])
52-
hist_central_effnp = infile_central_eff.Get(cfg["central_efficiency"]["histonames"]["nonprompt"])
61+
hist_central_effp_name = cfg["central_efficiency"]["histonames"]["prompt"]
62+
hist_central_effp = infile_central_eff.Get(hist_central_effp_name)
63+
if(hist_central_effp is None):
64+
sys.exit(f"Fatal error: Histogram with central efficiency for prompt \"{hist_central_effp_name}\" is absent. Exit.")
65+
hist_central_effnp_name = cfg["central_efficiency"]["histonames"]["nonprompt"]
66+
hist_central_effnp = infile_central_eff.Get(hist_central_effnp_name)
67+
if(hist_central_effnp is None):
68+
sys.exit(f"Fatal error: Histogram with central efficiency for nonprompt \"{hist_central_effnp_name}\" is absent. Exit.")
5369
hist_central_effp.SetDirectory(0)
5470
hist_central_effnp.SetDirectory(0)
5571
infile_central_eff.Close()
@@ -115,18 +131,19 @@ def main(config):
115131

116132
output = ROOT.TFile(os.path.join(cfg["output"]["directory"], cfg["output"]["file"]), "recreate")
117133
n_sets = len(hist_rawy)
134+
pt_axis_title = hist_rawy[0].GetXaxis().GetTitle()
118135
for ipt in range(hist_rawy[0].GetNbinsX()):
119136
pt_min = hist_rawy[0].GetXaxis().GetBinLowEdge(ipt + 1)
120137
pt_max = hist_rawy[0].GetXaxis().GetBinUpEdge(ipt + 1)
121138

122139
rawy, effp, effnp, unc_rawy, unc_effp, unc_effnp = (np.zeros(n_sets) for _ in range(6))
123140
for iset, (hrawy, heffp, heffnp) in enumerate(zip(hist_rawy, hist_effp, hist_effnp)):
124-
rawy.itemset(iset, hrawy.GetBinContent(ipt + 1))
125-
effp.itemset(iset, heffp.GetBinContent(ipt + 1))
126-
effnp.itemset(iset, heffnp.GetBinContent(ipt + 1))
127-
unc_rawy.itemset(iset, hrawy.GetBinError(ipt + 1))
128-
unc_effp.itemset(iset, heffp.GetBinError(ipt + 1))
129-
unc_effnp.itemset(iset, heffnp.GetBinError(ipt + 1))
141+
rawy[iset] = hrawy.GetBinContent(ipt + 1)
142+
effp[iset] = heffp.GetBinContent(ipt + 1)
143+
effnp[iset] = heffnp.GetBinContent(ipt + 1)
144+
unc_rawy[iset] = hrawy.GetBinError(ipt + 1)
145+
unc_effp[iset] = heffp.GetBinError(ipt + 1)
146+
unc_effnp[iset] = heffnp.GetBinError(ipt + 1)
130147

131148
minimiser = CutVarMinimiser(rawy, effp, effnp, unc_rawy, unc_effp, unc_effnp)
132149
minimiser.minimise_system(cfg["minimisation"]["correlated"])
@@ -155,30 +172,32 @@ def main(config):
155172
hist_frac_raw_nonprompt.SetBinContent(ipt + 1, raw_frac_nonprompt[0])
156173
hist_frac_raw_nonprompt.SetBinError(ipt + 1, raw_frac_nonprompt[1])
157174

158-
canv_rawy, histos_rawy, leg_r = minimiser.plot_result(f"_pt{pt_min:.0f}_{pt_max:.0f}")
175+
hist_bin_title = f"bin # {ipt+1}; {pt_axis_title}#in ({pt_min}; {pt_max})"
176+
177+
canv_rawy, histos_rawy, leg_r = minimiser.plot_result(f"_pt{pt_min}_{pt_max}", hist_bin_title)
159178
output.cd()
160179
canv_rawy.Write()
161180
for _, hist in histos_rawy.items():
162181
hist.Write()
163182

164-
canv_eff, histos_eff, leg_e = minimiser.plot_efficiencies(f"_pt{pt_min:.0f}_{pt_max:.0f}")
183+
canv_eff, histos_eff, leg_e = minimiser.plot_efficiencies(f"_pt{pt_min}_{pt_max}", hist_bin_title)
165184
output.cd()
166185
canv_eff.Write()
167186
for _, hist in histos_eff.items():
168187
hist.Write()
169188

170-
canv_frac, histos_frac, leg_f = minimiser.plot_fractions(f"_pt{pt_min:.0f}_{pt_max:.0f}")
189+
canv_frac, histos_frac, leg_f = minimiser.plot_fractions(f"_pt{pt_min}_{pt_max}", hist_bin_title)
171190
output.cd()
172191
canv_frac.Write()
173192
for _, hist in histos_frac.items():
174193
hist.Write()
175194

176-
canv_cov, histo_cov = minimiser.plot_cov_matrix(True, f"_pt{pt_min:.0f}_{pt_max:.0f}")
195+
canv_cov, histo_cov = minimiser.plot_cov_matrix(True, f"_pt{pt_min}_{pt_max}", hist_bin_title)
177196
output.cd()
178197
canv_cov.Write()
179198
histo_cov.Write()
180199

181-
canv_combined = ROOT.TCanvas("canv_combined", "", 1000, 1000)
200+
canv_combined = ROOT.TCanvas(f"canv_combined_{ipt}", "", 1000, 1000)
182201
canv_combined.Divide(2, 2)
183202
canv_combined.cd(1)
184203
canv_rawy.DrawClonePad()
@@ -194,23 +213,20 @@ def main(config):
194213
output_name_frac_pdf = f"Frac_{cfg['output']['file'].replace('.root', '.pdf')}"
195214
output_name_covmat_pdf = f"CovMatrix_{cfg['output']['file'].replace('.root', '.pdf')}"
196215
output_name_pdf = f"{cfg['output']['file'].replace('.root', '.pdf')}"
197-
if ipt == 0:
198-
canv_rawy.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_rawy_pdf)}[")
199-
canv_eff.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_eff_pdf)}[")
200-
canv_frac.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_frac_pdf)}[")
201-
canv_cov.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_covmat_pdf)}[")
202-
canv_combined.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_pdf)}[")
203-
canv_rawy.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_rawy_pdf)}")
204-
canv_eff.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_eff_pdf)}")
205-
canv_frac.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_frac_pdf)}")
206-
canv_cov.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_covmat_pdf)}")
207-
canv_combined.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_pdf)}")
208-
if ipt == hist_rawy[0].GetNbinsX() - 1:
209-
canv_rawy.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_rawy_pdf)}]")
210-
canv_eff.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_eff_pdf)}]")
211-
canv_frac.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_frac_pdf)}]")
212-
canv_cov.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_covmat_pdf)}]")
213-
canv_combined.SaveAs(f"{os.path.join(cfg['output']['directory'], output_name_pdf)}]")
216+
217+
if hist_rawy[0].GetNbinsX() == 1:
218+
print_bracket = ""
219+
elif ipt == 0:
220+
print_bracket = "("
221+
elif ipt == hist_rawy[0].GetNbinsX() - 1:
222+
print_bracket = ")"
223+
else:
224+
print_bracket = ""
225+
canv_rawy.Print(f"{os.path.join(cfg['output']['directory'], output_name_rawy_pdf)}{print_bracket}")
226+
canv_eff.Print(f"{os.path.join(cfg['output']['directory'], output_name_eff_pdf)}{print_bracket}")
227+
canv_frac.Print(f"{os.path.join(cfg['output']['directory'], output_name_frac_pdf)}{print_bracket}")
228+
canv_cov.Print(f"{os.path.join(cfg['output']['directory'], output_name_covmat_pdf)}{print_bracket}")
229+
canv_combined.Print(f"{os.path.join(cfg['output']['directory'], output_name_pdf)}{print_bracket}")
214230

215231
output.cd()
216232
hist_corry_prompt.Write()

PWGHF/D2H/Macros/config_cutvar_example.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,4 @@
7070
"directory": ".",
7171
"file": "CutVarDplus_pp13TeV_MB.root"
7272
}
73-
}
73+
}

PWGHF/D2H/Macros/cut_variation.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import numpy as np # pylint: disable=import-error
1313
import ROOT # pylint: disable=import-error
1414
sys.path.insert(0, '..')
15-
from utils.style_formatter import set_global_style, set_object_style
15+
from style_formatter import set_global_style, set_object_style
1616

1717

1818
# pylint: disable=too-many-instance-attributes
@@ -110,9 +110,9 @@ def __initialise_objects(self):
110110
self.unc_frac_nonprompt = np.zeros(shape=self.n_sets)
111111

112112
for i_set, (rawy, effp, effnp) in enumerate(zip(self.raw_yields, self.eff_prompt, self.eff_nonprompt)):
113-
self.m_rawy.itemset(i_set, rawy)
114-
self.m_eff.itemset((i_set, 0), effp)
115-
self.m_eff.itemset((i_set, 1), effnp)
113+
self.m_rawy[i_set] = rawy
114+
self.m_eff[(i_set, 0)] = effp
115+
self.m_eff[(i_set, 1)] = effnp
116116

117117
# pylint: disable=too-many-locals
118118
def minimise_system(self, correlated=True, precision=1.0e-8, max_iterations=100):
@@ -165,7 +165,7 @@ def minimise_system(self, correlated=True, precision=1.0e-8, max_iterations=100)
165165
else:
166166
rho = 0.0
167167
cov_row_col = rho * unc_row * unc_col
168-
self.m_cov_sets.itemset((i_row, i_col), cov_row_col)
168+
self.m_cov_sets[i_row, i_col] = cov_row_col
169169

170170
self.m_cov_sets = np.matrix(self.m_cov_sets)
171171
self.m_weights = np.linalg.inv(np.linalg.cholesky(self.m_cov_sets))
@@ -211,10 +211,10 @@ def minimise_system(self, correlated=True, precision=1.0e-8, max_iterations=100)
211211
+ der_fnp_np**2 * self.m_covariance.item(1, 1)
212212
+ 2 * der_fnp_p * der_fnp_np * self.m_covariance.item(1, 0)
213213
)
214-
self.frac_prompt.itemset(i_set, rawyp / (rawyp + rawynp))
215-
self.frac_nonprompt.itemset(i_set, rawynp / (rawyp + rawynp))
216-
self.unc_frac_prompt.itemset(i_set, unc_fp)
217-
self.unc_frac_nonprompt.itemset(i_set, unc_fnp)
214+
self.frac_prompt[i_set] = rawyp / (rawyp + rawynp)
215+
self.frac_nonprompt[i_set] = rawynp / (rawyp + rawynp)
216+
self.unc_frac_prompt[i_set] = unc_fp
217+
self.unc_frac_nonprompt[i_set] = unc_fnp
218218

219219
def get_red_chi2(self):
220220
"""
@@ -424,7 +424,7 @@ def get_corr_nonprompt_fraction(self):
424424
return self.get_raw_nonprompt_fraction(1.0, 1.0)
425425

426426
# pylint: disable=no-member
427-
def plot_result(self, suffix=""):
427+
def plot_result(self, suffix="", title=""):
428428
"""
429429
Helper function to plot minimisation result as a function of cut set
430430
@@ -528,6 +528,9 @@ def plot_result(self, suffix=""):
528528
hist_raw_yield_prompt.Draw("histsame")
529529
hist_raw_yield_nonprompt.Draw("histsame")
530530
hist_raw_yield_sum.Draw("histsame")
531+
tex = ROOT.TLatex()
532+
tex.SetTextSize(0.04)
533+
tex.DrawLatexNDC(0.05, 0.95, title)
531534
canvas.Modified()
532535
canvas.Update()
533536

@@ -540,7 +543,7 @@ def plot_result(self, suffix=""):
540543

541544
return canvas, histos, leg
542545

543-
def plot_cov_matrix(self, correlated=True, suffix=""):
546+
def plot_cov_matrix(self, correlated=True, suffix="", title=""):
544547
"""
545548
Helper function to plot covariance matrix
546549
@@ -563,6 +566,7 @@ def plot_cov_matrix(self, correlated=True, suffix=""):
563566
padleftmargin=0.14,
564567
padbottommargin=0.12,
565568
padrightmargin=0.12,
569+
padtopmargin = 0.075,
566570
palette=ROOT.kRainBow,
567571
)
568572

@@ -592,12 +596,15 @@ def plot_cov_matrix(self, correlated=True, suffix=""):
592596

593597
canvas = ROOT.TCanvas(f"cCorrMatrixCutSets{suffix}", "", 500, 500)
594598
hist_corr_matrix.Draw("colz")
599+
tex = ROOT.TLatex()
600+
tex.SetTextSize(0.04)
601+
tex.DrawLatexNDC(0.05, 0.95, title)
595602
canvas.Modified()
596603
canvas.Update()
597604

598605
return canvas, hist_corr_matrix
599606

600-
def plot_efficiencies(self, suffix=""):
607+
def plot_efficiencies(self, suffix="", title=""):
601608
"""
602609
Helper function to plot efficiencies as a function of cut set
603610
@@ -616,7 +623,7 @@ def plot_efficiencies(self, suffix=""):
616623
needed otherwise it is destroyed
617624
"""
618625

619-
set_global_style(padleftmargin=0.14, padbottommargin=0.12, titleoffset=1.2)
626+
set_global_style(padleftmargin=0.14, padbottommargin=0.12, titleoffset=1.2, padtopmargin = 0.075)
620627

621628
hist_eff_prompt = ROOT.TH1F(
622629
f"hEffPromptVsCut{suffix}",
@@ -678,12 +685,15 @@ def plot_efficiencies(self, suffix=""):
678685
leg.AddEntry(hist_eff_prompt, "prompt", "pl")
679686
leg.AddEntry(hist_eff_nonprompt, "non-prompt", "pl")
680687
leg.Draw()
688+
tex = ROOT.TLatex()
689+
tex.SetTextSize(0.04)
690+
tex.DrawLatexNDC(0.05, 0.95, title)
681691
canvas.Modified()
682692
canvas.Update()
683693

684694
return canvas, histos, leg
685695

686-
def plot_fractions(self, suffix=""):
696+
def plot_fractions(self, suffix="", title=""):
687697
"""
688698
Helper function to plot fractions as a function of cut set
689699
@@ -702,7 +712,7 @@ def plot_fractions(self, suffix=""):
702712
needed otherwise it is destroyed
703713
"""
704714

705-
set_global_style(padleftmargin=0.14, padbottommargin=0.12, titleoffset=1.2)
715+
set_global_style(padleftmargin=0.14, padbottommargin=0.12, titleoffset=1.2, padtopmargin = 0.075)
706716

707717
hist_f_prompt = ROOT.TH1F(
708718
f"hFracPromptVsCut{suffix}",
@@ -757,6 +767,9 @@ def plot_fractions(self, suffix=""):
757767
leg.AddEntry(hist_f_prompt, "prompt", "pl")
758768
leg.AddEntry(hist_f_nonprompt, "non-prompt", "pl")
759769
leg.Draw()
770+
tex = ROOT.TLatex()
771+
tex.SetTextSize(0.04)
772+
tex.DrawLatexNDC(0.05, 0.95, title)
760773
canvas.Modified()
761774
canvas.Update()
762775

0 commit comments

Comments
 (0)