Skip to content

Commit c122ce8

Browse files
authored
[PWGHF] Cut variation: demote efficiency vector non-monotonicity to warning; fix bug and format (#18447)
1 parent a5132d2 commit c122ce8

2 files changed

Lines changed: 124 additions & 65 deletions

File tree

‎PWGHF/D2H/Macros/compute_fraction_cutvar.py‎

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
import numpy as np # pylint: disable=import-error
1717
import ROOT # pylint: disable=import-error
1818

19-
sys.path.insert(0, '..')
19+
sys.path.insert(0, "..")
2020
from cut_variation import CutVarMinimiser, MinimisationStatus
2121
from style_formatter import set_object_style
2222

2323
# pylint: disable=no-member,too-many-locals,too-many-statements
2424

25+
2526
class PlotType(IntEnum):
2627
Rawy = 0
2728
Eff = auto()
@@ -31,6 +32,7 @@ class PlotType(IntEnum):
3132
RelUnc = auto()
3233
N = auto()
3334

35+
3436
class ObjectToSave(IntEnum):
3537
Canvas = 0
3638
RawYield = auto()
@@ -44,6 +46,7 @@ class ObjectToSave(IntEnum):
4446
MinimisationStatus = auto()
4547
N = auto()
4648

49+
4750
def main(config):
4851
"""
4952
Main function
@@ -65,7 +68,7 @@ def main(config):
6568
hist_rawy_name = cfg["rawyields"]["histoname"]
6669
hist_rawy.append(infile_rawy.Get(hist_rawy_name))
6770
if not isinstance(hist_rawy[-1], ROOT.TH1):
68-
sys.exit(f"\33[31mFatal error: Histogram with raw yield \"{hist_rawy_name}\" is absent. Exit.\33[0m")
71+
sys.exit(f'\33[31mFatal error: Histogram with raw yield "{hist_rawy_name}" is absent. Exit.\33[0m')
6972
hist_rawy[-1].SetDirectory(0)
7073
infile_rawy.Close()
7174

@@ -75,14 +78,22 @@ def main(config):
7578
hist_effp.append(infile_eff.Get(hist_effp_name))
7679
hist_effnp.append(infile_eff.Get(hist_effnp_name))
7780
if not isinstance(hist_effp[-1], ROOT.TH1):
78-
sys.exit(f"\33[31mFatal error: Histogram with efficiency for prompt \"{hist_effp_name}\" is absent. Exit.\33[0m")
81+
sys.exit(
82+
f'\33[31mFatal error: Histogram with efficiency for prompt "{hist_effp_name}" is absent. Exit.\33[0m'
83+
)
7984
if not isinstance(hist_effnp[-1], ROOT.TH1):
80-
sys.exit(f"\33[31mFatal error: Histogram with efficiency for nonprompt \"{hist_effnp}\" is absent. Exit.\33[0m")
85+
sys.exit(
86+
f'\33[31mFatal error: Histogram with efficiency for nonprompt "{hist_effnp}" is absent. Exit.\33[0m'
87+
)
8188
hist_effp[-1].SetDirectory(0)
8289
hist_effnp[-1].SetDirectory(0)
8390
for i_bin in range(1, hist_effp[-1].GetNbinsX() + 1):
84-
hist_effp[-1].SetBinContent(i_bin, hist_effp[-1].GetBinContent(i_bin) + effp_shift_nsigma*hist_effp[-1].GetBinError(i_bin))
85-
hist_effnp[-1].SetBinContent(i_bin, hist_effnp[-1].GetBinContent(i_bin) + effnp_shift_nsigma*hist_effnp[-1].GetBinError(i_bin))
91+
hist_effp[-1].SetBinContent(
92+
i_bin, hist_effp[-1].GetBinContent(i_bin) + effp_shift_nsigma * hist_effp[-1].GetBinError(i_bin)
93+
)
94+
hist_effnp[-1].SetBinContent(
95+
i_bin, hist_effnp[-1].GetBinContent(i_bin) + effnp_shift_nsigma * hist_effnp[-1].GetBinError(i_bin)
96+
)
8697
if zero_eff_unc:
8798
hist_effp[-1].SetBinError(i_bin, 0.0)
8899
hist_effnp[-1].SetBinError(i_bin, 0.0)
@@ -92,7 +103,9 @@ def main(config):
92103
if not isinstance(pt_bin_to_process, int):
93104
sys.exit("\33[31mFatal error: pt_bin_to_process must be an integer value. Exit.")
94105
if (pt_bin_to_process != -1 and pt_bin_to_process < 1) or pt_bin_to_process > hist_rawy[0].GetNbinsX():
95-
sys.exit("\33[31mFatal error: pt_bin_to_process must be a positive value up to number of bins in raw yield histogram. Exit.")
106+
sys.exit(
107+
"\33[31mFatal error: pt_bin_to_process must be a positive value up to number of bins in raw yield histogram. Exit."
108+
)
96109

97110
is_draw_title = [False] * PlotType.N
98111
is_draw_title[PlotType.Rawy] = cfg.get("is_draw_title", {}).get("rawy", True)
@@ -117,22 +130,32 @@ def main(config):
117130
is_save_to_root_file[ObjectToSave.Efficiency] = cfg.get("is_save_to_root_file", {}).get("efficiency", True)
118131
is_save_to_root_file[ObjectToSave.Fraction] = cfg.get("is_save_to_root_file", {}).get("fraction", True)
119132
is_save_to_root_file[ObjectToSave.CorrectedYield] = cfg.get("is_save_to_root_file", {}).get("corrected_yield", True)
120-
is_save_to_root_file[ObjectToSave.CorrelationMatrix] = cfg.get("is_save_to_root_file", {}).get("correlation_matrix", True)
133+
is_save_to_root_file[ObjectToSave.CorrelationMatrix] = cfg.get("is_save_to_root_file", {}).get(
134+
"correlation_matrix", True
135+
)
121136
is_save_to_root_file[ObjectToSave.Covariance] = cfg.get("is_save_to_root_file", {}).get("covariance", True)
122-
is_save_to_root_file[ObjectToSave.CorrectedFraction] = cfg.get("is_save_to_root_file", {}).get("corrected_fraction", True)
123-
is_save_to_root_file[ObjectToSave.MinimisationStatus] = cfg.get("is_save_to_root_file", {}).get("minimisation_status", True)
137+
is_save_to_root_file[ObjectToSave.CorrectedFraction] = cfg.get("is_save_to_root_file", {}).get(
138+
"corrected_fraction", True
139+
)
140+
is_save_to_root_file[ObjectToSave.MinimisationStatus] = cfg.get("is_save_to_root_file", {}).get(
141+
"minimisation_status", True
142+
)
124143

125144
if cfg["central_efficiency"]["computerawfrac"]:
126145
infile_name = os.path.join(cfg["central_efficiency"]["inputdir"], cfg["central_efficiency"]["inputfile"])
127146
infile_central_eff = ROOT.TFile.Open(infile_name)
128147
hist_central_effp_name = cfg["central_efficiency"]["histonames"]["prompt"]
129148
hist_central_effp = infile_central_eff.Get(hist_central_effp_name)
130149
if not isinstance(hist_central_effp[-1], ROOT.TH1):
131-
sys.exit(f"\33[31mFatal error: Histogram with central efficiency for prompt \"{hist_central_effp_name}\" is absent. Exit.\33[0m")
150+
sys.exit(
151+
f'\33[31mFatal error: Histogram with central efficiency for prompt "{hist_central_effp_name}" is absent. Exit.\33[0m'
152+
)
132153
hist_central_effnp_name = cfg["central_efficiency"]["histonames"]["nonprompt"]
133154
hist_central_effnp = infile_central_eff.Get(hist_central_effnp_name)
134155
if not isinstance(hist_central_effnp[-1], ROOT.TH1):
135-
sys.exit(f"\33[31mFatal error: Histogram with central efficiency for nonprompt \"{hist_central_effnp_name}\" is absent. Exit.\33[0m")
156+
sys.exit(
157+
f'\33[31mFatal error: Histogram with central efficiency for nonprompt "{hist_central_effnp_name}" is absent. Exit.\33[0m'
158+
)
136159
hist_central_effp.SetDirectory(0)
137160
hist_central_effnp.SetDirectory(0)
138161
infile_central_eff.Close()
@@ -150,8 +173,18 @@ def main(config):
150173
hist_corrfrac_prompt = hist_rawy[0].Clone("hCorrFracPrompt")
151174
hist_corrfrac_nonprompt = hist_rawy[0].Clone("hCorrFracNonPrompt")
152175
hist_minimisation_status = hist_rawy[0].Clone("hMinimizationStatus")
153-
hist_red_chi2 = hist_rawy[0].Clone("hChi2OverNdf")
154-
for histo in hist_corry_prompt, hist_corry_nonprompt, hist_covariance_pnp, hist_covariance_pp, hist_covariance_npnp, hist_corrfrac_prompt, hist_corrfrac_nonprompt, hist_minimisation_status, hist_red_chi2:
176+
hist_red_chi2 = hist_rawy[0].Clone("hChi2OverNdf")
177+
for histo in (
178+
hist_corry_prompt,
179+
hist_corry_nonprompt,
180+
hist_covariance_pnp,
181+
hist_covariance_pp,
182+
hist_covariance_npnp,
183+
hist_corrfrac_prompt,
184+
hist_corrfrac_nonprompt,
185+
hist_minimisation_status,
186+
hist_red_chi2,
187+
):
155188
histo.Reset()
156189
hist_corry_prompt.GetYaxis().SetTitle("corrected yields prompt")
157190
hist_corry_nonprompt.GetYaxis().SetTitle("corrected yields non-prompt")
@@ -164,7 +197,7 @@ def main(config):
164197
hist_red_chi2.GetYaxis().SetTitle("#chi^{2}/ndf")
165198
hist_minimisation_status_title = ""
166199
for min_status in MinimisationStatus:
167-
hist_minimisation_status_title += (str(min_status.value) + " = " + min_status.name + ", ")
200+
hist_minimisation_status_title += str(min_status.value) + " = " + min_status.name + ", "
168201
hist_minimisation_status_title = hist_minimisation_status_title[:-2]
169202
hist_minimisation_status.SetTitle(hist_minimisation_status_title)
170203
set_object_style(
@@ -221,17 +254,17 @@ def main(config):
221254
if pt_bin_to_process != -1:
222255
pt_bin_to_process_name_suffix = "_bin_" + str(pt_bin_to_process)
223256

224-
output_name_template = cfg['output']['file'].replace(".root", "") + pt_bin_to_process_name_suffix + ".root"
257+
output_name_template = cfg["output"]["file"].replace(".root", "") + pt_bin_to_process_name_suffix + ".root"
225258
output = ROOT.TFile(os.path.join(cfg["output"]["directory"], output_name_template), "recreate")
226259
n_sets = len(hist_rawy)
227260
pt_axis_title = hist_rawy[0].GetXaxis().GetTitle()
228261
for ipt in range(hist_rawy[0].GetNbinsX()):
229-
if pt_bin_to_process !=-1 and ipt+1 != pt_bin_to_process:
262+
if pt_bin_to_process != -1 and ipt + 1 != pt_bin_to_process:
230263
continue
231264
all_vectors_monotonous = MinimisationStatus.Success
232265
pt_min = hist_rawy[0].GetXaxis().GetBinLowEdge(ipt + 1)
233266
pt_max = hist_rawy[0].GetXaxis().GetBinUpEdge(ipt + 1)
234-
print(f"\n\nINFO: processing pt range {ipt+1} from {pt_min} to {pt_max} {pt_axis_title}")
267+
print(f"\n\nINFO: processing pt range {ipt + 1} from {pt_min} to {pt_max} {pt_axis_title}")
235268

236269
rawy, effp, effnp, unc_rawy, unc_effp, unc_effnp = (np.zeros(n_sets) for _ in range(6))
237270
for iset, (hrawy, heffp, heffnp) in enumerate(zip(hist_rawy, hist_effp, hist_effnp)):
@@ -245,16 +278,24 @@ def main(config):
245278
if cfg["minimisation"]["correlated"]:
246279
if not (np.all(rawy[1:] > rawy[:-1]) or np.all(rawy[1:] < rawy[:-1])):
247280
all_vectors_monotonous = MinimisationStatus.MonotonyViolation
248-
print("\0\33[33mWARNING! main(): the raw yield vector is not monotonous. Check the input for stability.\0\33[0m")
281+
print(
282+
"\0\33[33m\nWARNING! main(): the raw yield vector is not monotonous. Check the input for stability.\n\0\33[0m"
283+
)
249284
print(f"raw yield vector elements = {rawy}\n")
250285
if not (np.all(unc_rawy[1:] > unc_rawy[:-1]) or np.all(unc_rawy[1:] < unc_rawy[:-1])):
251286
all_vectors_monotonous = MinimisationStatus.MonotonyViolation
252-
print("\0\33[33mWARNING! main(): the raw yield uncertainties vector is not monotonous. Check the input for stability.\0\33[0m")
287+
print(
288+
"\0\33[33m\nWARNING! main(): the raw yield uncertainties vector is not monotonous. Check the input for stability.\n\0\33[0m"
289+
)
253290
print(f"raw yield uncertainties vector elements = {unc_rawy}\n")
254291
if not (np.all(effp[1:] > effp[:-1]) or np.all(effp[1:] < effp[:-1])):
255-
sys.exit("\33[31mFatal error: the prompt efficiency vector is not monotonous. Check the input. Exit.\33[0m")
292+
all_vectors_monotonous = MinimisationStatus.MonotonyViolation
293+
print("\0\33[33m\nWARNING! the prompt efficiency vector is not monotonous. Check the input.\0\33[0m")
294+
print(f"prompt efficiency vector elements = {effp}\n")
256295
if not (np.all(effnp[1:] > effnp[:-1]) or np.all(effnp[1:] < effnp[:-1])):
257-
sys.exit("\33[31mFatal error: the nonprompt efficiency vector is not monotonous. Check the input. Exit.\33[0m")
296+
all_vectors_monotonous = MinimisationStatus.MonotonyViolation
297+
print("\0\33[33m\nWARNING! the nonprompt efficiency vector is not monotonous. Check the input.\0\33[0m")
298+
print(f"nonprompt efficiency vector elements = {effnp}\n")
258299

259300
minimiser = CutVarMinimiser(rawy, effp, effnp, unc_rawy, unc_effp, unc_effnp)
260301
status = minimiser.minimise_system(cfg["minimisation"]["correlated"])
@@ -290,62 +331,66 @@ def main(config):
290331
hist_frac_raw_nonprompt.SetBinContent(ipt + 1, raw_frac_nonprompt[0])
291332
hist_frac_raw_nonprompt.SetBinError(ipt + 1, raw_frac_nonprompt[1])
292333

293-
hist_bin_title = f"bin # {ipt+1}; {pt_axis_title}#in ({pt_min}; {pt_max})"
334+
hist_bin_title = f"bin # {ipt + 1}; {pt_axis_title}#in ({pt_min}; {pt_max})"
294335

295336
hist_bin_title_rawy = hist_bin_title if is_draw_title[PlotType.Rawy] else ""
296337
canv_rawy, histos_rawy, _leg_r = minimiser.plot_result(f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_rawy)
297338
output.cd()
298339
if is_save_to_root_file[ObjectToSave.Canvas]:
299340
canv_rawy.Write()
300341
if is_save_to_root_file[ObjectToSave.RawYield]:
301-
for _, hist in histos_rawy.values():
342+
for hist in histos_rawy.values():
302343
hist.Write()
303344
if is_save_canvas_as_macro[PlotType.Rawy]:
304-
canv_rawy.SaveAs(f"canv_rawy_{ipt+1}.C")
345+
canv_rawy.SaveAs(f"canv_rawy_{ipt + 1}.C")
305346

306347
hist_bin_title_unc = hist_bin_title if is_draw_title[PlotType.Unc] else ""
307-
canv_unc, histos_unc, _leg_unc = minimiser.plot_uncertainties(f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_unc)
348+
canv_unc, histos_unc, _leg_unc = minimiser.plot_uncertainties(
349+
f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_unc
350+
)
308351
output.cd()
309352
if is_save_to_root_file[ObjectToSave.Canvas]:
310353
canv_unc.Write()
311354
if is_save_to_root_file[ObjectToSave.Uncertainty]:
312-
for _, hist in histos_unc.values():
355+
for hist in histos_unc.values():
313356
hist.Write()
314357
if is_save_canvas_as_macro[PlotType.Unc]:
315-
canv_unc.SaveAs(f"canv_unc_{ipt+1}.C")
358+
canv_unc.SaveAs(f"canv_unc_{ipt + 1}.C")
316359

317360
hist_bin_title_rel_unc = hist_bin_title if is_draw_title[PlotType.RelUnc] else ""
318-
canv_rel_unc, histos_rel_unc, _leg_rel_unc = minimiser.plot_relative_uncertainties(f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_rel_unc)
361+
canv_rel_unc, histos_rel_unc, _leg_rel_unc = minimiser.plot_relative_uncertainties(
362+
f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_rel_unc
363+
)
319364
output.cd()
320365
if is_save_to_root_file[ObjectToSave.Canvas]:
321366
canv_rel_unc.Write()
322367
if is_save_to_root_file[ObjectToSave.Uncertainty]:
323-
for _, hist in histos_rel_unc.values():
368+
for hist in histos_rel_unc.values():
324369
hist.Write()
325370
if is_save_canvas_as_macro[PlotType.RelUnc]:
326-
canv_rel_unc.SaveAs(f"canv_rel_unc_{ipt+1}.C")
371+
canv_rel_unc.SaveAs(f"canv_rel_unc_{ipt + 1}.C")
327372

328373
hist_bin_title_eff = hist_bin_title if is_draw_title[PlotType.Eff] else ""
329374
canv_eff, histos_eff, _leg_e = minimiser.plot_efficiencies(f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_eff)
330375
output.cd()
331376
if is_save_to_root_file[ObjectToSave.Canvas]:
332377
canv_eff.Write()
333378
if is_save_to_root_file[ObjectToSave.Efficiency]:
334-
for _, hist in histos_eff.values():
379+
for hist in histos_eff.values():
335380
hist.Write()
336381
if is_save_canvas_as_macro[PlotType.Eff]:
337-
canv_eff.SaveAs(f"canv_eff_{ipt+1}.C")
382+
canv_eff.SaveAs(f"canv_eff_{ipt + 1}.C")
338383

339384
hist_bin_title_frac = hist_bin_title if is_draw_title[PlotType.Frac] else ""
340385
canv_frac, histos_frac, _leg_f = minimiser.plot_fractions(f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_frac)
341386
output.cd()
342387
if is_save_to_root_file[ObjectToSave.Canvas]:
343388
canv_frac.Write()
344389
if is_save_to_root_file[ObjectToSave.Fraction]:
345-
for _, hist in histos_frac.values():
390+
for hist in histos_frac.values():
346391
hist.Write()
347392
if is_save_canvas_as_macro[PlotType.Frac]:
348-
canv_frac.SaveAs(f"canv_frac_{ipt+1}.C")
393+
canv_frac.SaveAs(f"canv_frac_{ipt + 1}.C")
349394

350395
hist_bin_title_cov = hist_bin_title if is_draw_title[PlotType.Cov] else ""
351396
canv_cov, histo_cov = minimiser.plot_cov_matrix(True, f"_pt_{pt_min}_to_{pt_max}", hist_bin_title_cov)
@@ -355,7 +400,7 @@ def main(config):
355400
if is_save_to_root_file[ObjectToSave.CorrelationMatrix]:
356401
histo_cov.Write()
357402
if is_save_canvas_as_macro[PlotType.Cov]:
358-
canv_cov.SaveAs(f"canv_cov_{ipt+1}.C")
403+
canv_cov.SaveAs(f"canv_cov_{ipt + 1}.C")
359404
else:
360405
print(f"Minimization for pT {pt_min}, {pt_max} not successful")
361406
hist_minimisation_status.SetBinContent(ipt + 1, MinimisationStatus.Fail)
@@ -377,7 +422,7 @@ def main(config):
377422
canv_combined.cd(4)
378423
canv_cov.DrawClonePad()
379424

380-
output_name_template = output_name_template.replace('.root', '.pdf')
425+
output_name_template = output_name_template.replace(".root", ".pdf")
381426

382427
output_name_rawy_pdf = f"Distr_{output_name_template}"
383428
output_name_eff_pdf = f"Eff_{output_name_template}"

0 commit comments

Comments
 (0)