ATLAS Offline Software
Loading...
Searching...
No Matches
PhysicsAnalysis
Algorithms
TruthPartonLevelAnalysisAlgorithms
python
PartonHistoryConfig.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3
from
AnalysisAlgorithmsConfig.ConfigBlock
import
ConfigBlock
4
5
6
# ---------------------------------------------------------------------------
7
# Helpers
8
# ---------------------------------------------------------------------------
9
10
KINEMATIC_VARS = (
"pt"
,
"eta"
,
"phi"
,
"m"
)
11
INT_SUFFIXES = frozenset((
"pdgId"
,
"IsOnShell"
,
"origin"
))
12
VECTOR_PREFIXES = (
"MC_b_"
,
"MC_bbar_"
,
"MC_c_"
,
"MC_cbar_"
)
13
VECTOR_HISTORIES = frozenset((
"Ttbarbbbar"
,
"Ttbarccbar"
))
14
15
def
_get_aux_type
(branch: str, prefix: str) -> str:
16
# Handle specific cases where vectors are returned for each particle type
17
# In those cases, only external particles can be vectors, there is still
18
# a single particle allowed in named positions within decay chains
19
is_vector = prefix
in
VECTOR_HISTORIES
and
branch.startswith(VECTOR_PREFIXES)
and
"_from_"
not
in
branch
20
21
if
is_vector:
22
return
"vector_int"
if
any(branch.endswith(s)
for
s
in
INT_SUFFIXES)
else
"vector_float"
23
else
:
24
return
"int"
if
any(branch.endswith(s)
for
s
in
INT_SUFFIXES)
else
"float"
25
26
def
_make_particle_branches
(
27
prefix: str,
28
*,
29
include_pdgid: bool =
True
,
30
stages: tuple =
None
,
31
extra: tuple = (),
32
) -> list:
33
"""Generate standard kinematic branch names for a particle.
34
35
Parameters
36
----------
37
prefix:
38
Particle label as it appears in the branch name, e.g. ``"t"`` ->
39
``MC_t_beforeFSR_pt``. When the prefix already encodes the FSR stage
40
(e.g. ``"W_beforeFSR_from_t"``), pass ``stages=()``.
41
include_pdgid:
42
Append ``pdgId`` after the kinematic variables for each stage.
43
stages:
44
FSR stage tokens to iterate over. Defaults to
45
``("beforeFSR", "afterFSR")``. Pass ``()`` when the FSR stage is
46
already embedded in prefix — branches become ``MC_{prefix}_{var}``.
47
extra:
48
Additional branch suffixes appended verbatim, e.g. ``("IsOnShell",)``.
49
"""
50
if
stages
is
None
:
51
stages = (
"beforeFSR"
,
"afterFSR"
)
52
result = []
53
if
stages:
54
for
stage
in
stages:
55
for
var
in
KINEMATIC_VARS:
56
result.append(f
"MC_{prefix}_{stage}_{var}"
)
57
if
include_pdgid:
58
result.append(f
"MC_{prefix}_{stage}_pdgId"
)
59
else
:
60
for
var
in
KINEMATIC_VARS:
61
result.append(f
"MC_{prefix}_{var}"
)
62
if
include_pdgid:
63
result.append(f
"MC_{prefix}_pdgId"
)
64
for
suffix
in
extra:
65
result.append(f
"MC_{prefix}_{suffix}"
)
66
return
result
67
68
69
def
_replace_in_list
(string_list: list[str], old: str, new: str) -> list[str]:
70
return
[item.replace(old, new)
for
item
in
string_list]
71
72
73
# ---------------------------------------------------------------------------
74
# Per-particle branch lists
75
# ---------------------------------------------------------------------------
76
77
78
def
_t_branches
(suffix: str =
"t"
) -> list:
79
"""Branches for a top quark and its full decay chain.
80
81
Sub-particles carry the FSR stage in their prefix so we pass ``stages=()``
82
to avoid appending a spurious stage token to the variable name.
83
For tbar, the b-quark is named 'bbar'.
84
"""
85
b_name =
"bbar"
if
suffix ==
"tbar"
else
"b"
86
sub_particles = (
"W"
, b_name,
"Wdecay1"
,
"Wdecay2"
)
87
result =
_make_particle_branches
(suffix)
88
for
particle
in
sub_particles:
89
for
stage
in
(
"beforeFSR"
,
"afterFSR"
):
90
result +=
_make_particle_branches
(
91
f
"{particle}_{stage}_from_{suffix}"
, stages=()
92
)
93
return
result
94
95
96
BRANCHES: dict[str, list[str]] = {
97
"t"
:
_t_branches
(
"t"
),
98
"tbar"
:
_t_branches
(
"tbar"
),
99
"ttbar"
: (
100
_make_particle_branches
(
"ttbar"
, include_pdgid=
False
)
101
+
_make_particle_branches
(
"ttbar_fromDecay"
, include_pdgid=
False
)
102
),
103
"b"
:
_make_particle_branches
(
"b"
),
104
"bbar"
:
_make_particle_branches
(
"bbar"
),
105
"c"
:
_make_particle_branches
(
"c"
),
106
"cbar"
:
_make_particle_branches
(
"cbar"
),
107
"Z"
: (
108
_make_particle_branches
(
"Z"
, extra=(
"IsOnShell"
,))
109
+
_make_particle_branches
(
"Zdecay1"
)
110
+
_make_particle_branches
(
"Zdecay2"
)
111
),
112
"Z_extended"
: (
113
_make_particle_branches
(
"Z"
, extra=(
"IsOnShell"
,))
114
+
_make_particle_branches
(
"Zdecay1"
)
115
+
_make_particle_branches
(
"Zdecay1_decay1"
)
116
+
_make_particle_branches
(
"Zdecay1_decay2"
)
117
+
_make_particle_branches
(
"Zdecay1_decay3"
)
118
+
_make_particle_branches
(
"Zdecay2"
)
119
+
_make_particle_branches
(
"Zdecay2_decay1"
)
120
+
_make_particle_branches
(
"Zdecay2_decay2"
)
121
+
_make_particle_branches
(
"Zdecay2_decay3"
)
122
),
123
"W"
: (
124
_make_particle_branches
(
"W"
, extra=(
"IsOnShell"
,))
125
+
_make_particle_branches
(
"Wdecay1"
)
126
+
_make_particle_branches
(
"Wdecay2"
)
127
),
128
"Photon"
: [
129
"MC_gamma_m"
,
130
"MC_gamma_pt"
,
131
"MC_gamma_eta"
,
132
"MC_gamma_phi"
,
133
"MC_gamma_origin"
,
134
"MC_gamma_pdgId"
,
135
],
136
"Higgs"
: (
137
_make_particle_branches
(
"H"
)
138
+
_make_particle_branches
(
"Hdecay1"
)
139
+
_make_particle_branches
(
"Hdecay2"
)
140
+
_make_particle_branches
(
"Hdecay1_decay1"
)
141
+
_make_particle_branches
(
"Hdecay1_decay2"
)
142
+
_make_particle_branches
(
"Hdecay2_decay1"
)
143
+
_make_particle_branches
(
"Hdecay2_decay2"
)
144
),
145
}
146
147
_TTBAR = BRANCHES[
"t"
] + BRANCHES[
"tbar"
] + BRANCHES[
"ttbar"
]
148
149
TRUTH_BRANCHES: dict[str, list[str]] = {
150
"Ttbar"
: _TTBAR,
151
"Ttbarbbbar"
: _TTBAR + BRANCHES[
"b"
] + BRANCHES[
"bbar"
],
152
"Ttbarccbar"
: _TTBAR + BRANCHES[
"c"
] + BRANCHES[
"cbar"
],
153
"Ttz"
: _TTBAR + BRANCHES[
"Z"
],
154
"Ttw"
: _TTBAR + BRANCHES[
"W"
],
155
"Tth"
: _TTBAR + BRANCHES[
"Higgs"
],
156
"Ttgamma"
: _TTBAR + BRANCHES[
"Photon"
],
157
"Tzq"
: BRANCHES[
"t"
] + BRANCHES[
"Z"
] + BRANCHES[
"b"
],
158
"Thq"
: BRANCHES[
"t"
] + BRANCHES[
"Higgs"
] + BRANCHES[
"b"
] + BRANCHES[
"W"
],
159
"Tqgamma"
: BRANCHES[
"t"
] + BRANCHES[
"Photon"
] + BRANCHES[
"b"
],
160
"Wtb"
: BRANCHES[
"t"
] + BRANCHES[
"W"
] + BRANCHES[
"b"
],
161
"FourTop"
: (
162
_replace_in_list
(BRANCHES[
"t"
],
"t_"
,
"t1_"
)
163
+
_replace_in_list
(BRANCHES[
"t"
],
"t_"
,
"t2_"
)
164
+
_replace_in_list
(BRANCHES[
"tbar"
],
"tbar_"
,
"tbar1_"
)
165
+
_replace_in_list
(BRANCHES[
"tbar"
],
"tbar_"
,
"tbar2_"
)
166
),
167
"HWW"
: BRANCHES[
"Higgs"
],
168
"WW_nonresonant"
: (
169
_replace_in_list
(BRANCHES[
"W"
],
"W"
,
"W1"
)
170
+
_replace_in_list
(BRANCHES[
"W"
],
"W"
,
"W2"
)
171
),
172
"HWW_nonresonant"
: BRANCHES[
"Higgs"
],
173
"HZZ"
: BRANCHES[
"Higgs"
],
174
"Zb"
: BRANCHES[
"Z"
] + BRANCHES[
"b"
] + BRANCHES[
"bbar"
],
175
"Ztautau"
: BRANCHES[
"Z_extended"
],
176
}
177
178
# ---------------------------------------------------------------------------
179
# Config block
180
# ---------------------------------------------------------------------------
181
182
183
class
PartonHistoryBlock
(ConfigBlock):
184
"""ConfigBlock for truth/parton-level resonant histories."""
185
186
def
__init__
(self):
187
super().
__init__
()
188
self.addOption(
189
"history"
,
190
None
,
191
type=str,
192
required=
True
,
193
info=
"parton-level interpretation of the MC truth record. Possible values:"
194
+
", "
.join(sorted(TRUTH_BRANCHES))
195
+
"."
,
196
)
197
# Always skip on data
198
self.setOptionValue(
"skipOnData"
,
True
)
199
200
def
makeAlgs
(self, config):
201
if
self.history
not
in
TRUTH_BRANCHES:
202
valid =
", "
.join(sorted(TRUTH_BRANCHES))
203
raise
ValueError(
204
f
"Unknown parton history '{self.history}'. Valid options: {valid}"
205
)
206
207
alg = config.createAlgorithm(
208
"CP::RunPartonHistoryAlg"
, f
"PartonHistory{self.history}"
209
)
210
alg.partonScheme = self.history
211
212
for
branch
in
TRUTH_BRANCHES[self.history]:
213
config.addOutputVar(
214
"EventInfo"
,
215
f
"{self.history}_{branch}"
,
216
f
"{self.history}_{branch}"
,
217
noSys=
True
,
218
auxType=
_get_aux_type
(branch, self.history),
219
)
PartonHistoryConfig.PartonHistoryBlock
Definition
PartonHistoryConfig.py:183
PartonHistoryConfig.PartonHistoryBlock.makeAlgs
makeAlgs(self, config)
Definition
PartonHistoryConfig.py:200
PartonHistoryConfig.PartonHistoryBlock.__init__
__init__(self)
Definition
PartonHistoryConfig.py:186
PartonHistoryConfig._make_particle_branches
list _make_particle_branches(str prefix, *, bool include_pdgid=True, tuple stages=None, tuple extra=())
Definition
PartonHistoryConfig.py:32
PartonHistoryConfig._replace_in_list
list[str] _replace_in_list(list[str] string_list, str old, str new)
Definition
PartonHistoryConfig.py:69
PartonHistoryConfig._t_branches
list _t_branches(str suffix="t")
Definition
PartonHistoryConfig.py:78
PartonHistoryConfig._get_aux_type
str _get_aux_type(str branch, str prefix)
Definition
PartonHistoryConfig.py:15
Generated on
for ATLAS Offline Software by
1.16.1