ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
PhysicsAnalysis
PATJobTransforms
scripts
physvalPostProcessing.py
Go to the documentation of this file.
1
#!/usr/bin/env python3
2
3
# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4
5
import
ROOT
6
import
os
7
import
argparse
8
import
logging
9
import
PATJobTransforms.physvalPostProcessingTools
as
physvalPostProcessingTools
10
from
PATJobTransforms.physvalPostProcessingTools
import
(
11
ConfigManager,
12
EfficiencyComputation,
13
ProjectionComputation,
14
RebinningOperation,
15
HistogramAdjustment,
16
HistogramAddition,
17
HistogramBlackList,
18
ResolutionComputation,
19
ROCCurveComputation,
20
expand_fragments
21
)
22
23
logging.basicConfig(level=logging.INFO)
24
25
from
AthenaCommon.Utils.unixtools
import
find_datafile
26
27
try
:
28
electron_config = find_datafile(
"PATJobTransforms/physvalPostProcessingElectronConfig.yaml"
)
29
photon_config = find_datafile(
"PATJobTransforms/physvalPostProcessingPhotonConfig.yaml"
)
30
btag_config = find_datafile(
"PATJobTransforms/physvalPostProcessingBTagConfig.yaml"
)
31
except
(ImportError, FileNotFoundError)
as
e:
32
print
(f
"Error: {e}. Attempting fallback paths."
)
33
electron_config = find_datafile(
"../share/physvalPostProcessingElectronConfig.yaml"
)
34
photon_config = find_datafile(
"../share/physvalPostProcessingPhotonConfig.yaml"
)
35
btag_config = find_datafile(
"../share/physvalPostProcessingBTagConfig.yaml"
)
36
except
Exception
as
e:
37
print
(f
"Unexpected error: {e}. Please ensure the configuration files are available at the correct paths."
)
38
raise
39
40
def
create_output_file
(input_file, output_file):
41
try
:
42
ROOT.TFile.Cp(input_file, output_file)
43
output_root = ROOT.TFile.Open(output_file,
"UPDATE"
)
44
if
not
output_root
or
output_root.IsZombie():
45
logging.error(f
"Could not open {output_file}"
)
46
return
None
47
# logging.info(f"Opened {output_file} file for updating.")
48
return
output_root
49
except
Exception
as
e:
50
logging.error(f
"Failed to create output file: {e}"
)
51
return
None
52
53
OPERATION_KEYS = (
"rebinning"
,
"resolutions"
,
"projections"
,
"efficiencies"
,
"adding_histograms"
,
54
"adjustments"
,
"roc_curves"
,
"blacklist"
,
"rebinning_later"
)
55
56
def
process_domain
(root_file, domain_config, domain):
57
logging.info(f
"For domain: '{domain}'"
)
58
59
operations = {key: expand_fragments(domain_config.get(key, []), root_file)
for
key
in
OPERATION_KEYS}
60
templated = any(
"for_each"
in
fragment
for
fragments
in
domain_config.values()
for
fragment
in
fragments)
61
if
templated
and
not
any(operations.values()):
62
logging.error(f
"No histogram of domain '{domain}' matched any for_each pattern"
)
63
64
for
rebin
in
operations[
"rebinning"
]: RebinningOperation.from_yaml(rebin)(root_file)
65
actions = []
66
for
res
in
operations[
"resolutions"
]: actions.append(
lambda
res=res: ResolutionComputation.from_yaml(res)(root_file))
67
for
proj
in
operations[
"projections"
]: actions.append(
lambda
proj=proj: ProjectionComputation.from_yaml(proj)(root_file))
68
for
eff
in
operations[
"efficiencies"
]: actions.append(
lambda
eff=eff: EfficiencyComputation.from_yaml(eff)(root_file))
69
for
add
in
operations[
"adding_histograms"
]: actions.append(
lambda
add=add: HistogramAddition.from_yaml(add)(root_file))
70
for
adj
in
operations[
"adjustments"
]: actions.append(
lambda
adj=adj: HistogramAdjustment.from_yaml(adj)(root_file))
71
for
roc
in
operations[
"roc_curves"
]: actions.append(
lambda
roc=roc: ROCCurveComputation.from_yaml(roc)(root_file))
72
for
action
in
actions: action()
73
for
list
in
operations[
"blacklist"
]: HistogramBlackList.from_yaml(list)(root_file)
74
75
for
rebin
in
operations[
"rebinning_later"
]: RebinningOperation.from_yaml(rebin)(root_file)
76
77
logging.info(f
"Finished post processing for domain: '{domain}'"
)
78
79
def
main
():
80
parser = argparse.ArgumentParser(description=
"NTUPLE PHYSVAL Histogram Post-processing Tool"
)
81
parser.add_argument(
"files"
, nargs=
"*"
, help=
"Input ROOT file and optionally output file name"
)
82
parser.add_argument(
"--domain"
, type=str, help=
"Specific domain to process (e.g., Electron, Photon, BTag)"
)
83
parser.add_argument(
"--crash_on_error"
, action=
"store_true"
, help=
"Crash on first error instead of just warning"
)
84
args = parser.parse_args()
85
86
physvalPostProcessingTools.crash_on_error = args.crash_on_error
87
88
if
len(args.files) == 1:
89
input_file = args.files[0]
90
output_file = os.path.splitext(input_file)[0] +
"_after_post_process.root"
91
elif
len(args.files) == 2:
92
input_file, output_file = args.files
93
else
:
94
logging.error(
"You must provide 1 or 2 positional arguments: <input_file> [output_file]"
)
95
exit(1)
96
97
config_manager = ConfigManager()
98
config_manager.add_configuration(
"Electron"
, electron_config)
99
config_manager.add_configuration(
"Photon"
, photon_config)
100
config_manager.add_configuration(
"BTag"
, btag_config)
101
102
logging.info(f
"Input: {input_file}"
)
103
logging.info(f
"Output: {output_file}"
)
104
105
root_file =
create_output_file
(input_file, output_file)
106
if
not
root_file:
107
exit(1)
108
109
logging.info(
"Post Processing started..."
)
110
if
args.domain:
111
process_domain
(root_file, config_manager.get_config(args.domain), args.domain)
# Processing specified domain
112
else
:
113
for
domain, domain_config
in
config_manager.get_all_configs():
114
process_domain
(root_file, domain_config, domain)
# Processing all domains
115
116
try
:
117
root_file.Close()
118
logging.info(f
"Postprocessing complete. Output saved to: {output_file}"
)
119
except
Exception
as
e:
120
logging.error(f
"Failed to close ROOT file: {e}"
)
121
exit(1)
122
123
if
__name__ ==
"__main__"
:
124
main
()
print
void print(char *figname, TCanvas *c1)
Definition
TRTCalib_StrawStatusPlots.cxx:26
physvalPostProcessing.main
main()
Definition
physvalPostProcessing.py:79
physvalPostProcessing.create_output_file
create_output_file(input_file, output_file)
Definition
physvalPostProcessing.py:40
physvalPostProcessing.process_domain
process_domain(root_file, domain_config, domain)
Definition
physvalPostProcessing.py:56
Generated on
for ATLAS Offline Software by
1.17.0