ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Trigger
TrigValidation
TrigValTools
python
TrigValSteering
ExecStep.py
Go to the documentation of this file.
1
#
2
# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3
#
4
5
'''
6
Definitions of exec steps (main job) in Trigger ART tests
7
'''
8
9
import
os
10
import
re
11
12
from
TrigValTools.TrigValSteering.Step
import
Step
13
from
TrigValTools.TrigValSteering.Input
import
is_input_defined, get_input
14
15
16
class
ExecStep
(Step):
17
'''
18
Step executing the main job of a Trigger ART test. This can be either
19
athena or athenaEF or a transform. There can be several ExecSteps in
20
one Test.
21
'''
22
23
def
__init__
(self, name=None):
24
super(ExecStep, self).
__init__
(name)
25
self.
input
=
None
26
self.
input_object
=
None
27
self.
job_options
=
None
28
self.
flags
= []
29
self.
threads
=
None
30
self.
concurrent_events
=
None
31
self.
forks
=
None
32
self.
max_events
=
None
33
self.
skip_events
=
None
34
self.
use_pickle
=
False
35
self.
imf
=
True
36
self.
perfmon
=
True
37
self.
fpe_auditor
=
True
38
self.
costmon
=
False
39
self.
malloc
=
False
40
self.
prmon
=
True
41
self.
config_only
=
False
42
self.
auto_report_result
=
True
43
self.
required
=
True
44
self.
depends_on_previous
=
True
45
46
def
construct_name
(self):
47
if
self.
name
and
self.
type
==
'other'
:
48
return
self.
name
49
name = self.
type
if
self.
type
else
self.
executable
50
if
self.
name
:
51
name +=
'.'
+self.
name
52
return
name
53
54
def
get_log_file_name
(self):
55
if
self.
log_file_name
is
not
None
:
56
return
self.
log_file_name
57
else
:
58
return
self.
construct_name
()+
'.log'
59
60
def
configure
(self, test):
61
# Construct the name
62
self.
name
= self.
construct_name
()
63
self.
log_file_name
= self.
name
+
'.log'
64
self.log.
debug
(
'Configuring step %s'
, self.
name
)
65
66
# Parse configuration
67
self.
configure_type
()
68
self.
configure_input
()
69
self.
configure_job_options
()
70
self.
configure_args
(test)
71
72
super(ExecStep, self).
configure
(test)
73
74
def
configure_type
(self):
75
self.log.
debug
(
'Configuring type for step %s'
, self.
name
)
76
# Check if type or executable is specified
77
if
self.
type
is
None
and
self.
executable
is
None
:
78
self.misconfig_abort(
'Cannot configure a step without specified type or executable'
)
79
80
# Configure executable from type
81
known_types = [
'athena'
,
'athenaEF'
,
'Reco_tf'
,
'Trig_reco_tf'
,
'Derivation_tf'
]
82
if
self.
type
in
known_types:
83
if
self.
executable
is
not
None
:
84
self.log.warning(
'type=%s was specified, so executable=%s '
85
'will be ignored and deduced automatically '
86
'from type'
, self.
type
, self.
executable
)
87
self.
executable
=
'{}.py'
.format(self.
type
)
88
elif
self.
type
==
'other'
or
self.
type
is
None
:
89
self.
type
=
'other'
90
else
:
91
self.misconfig_abort(
'Cannot determine type of this step'
)
92
93
if
self.
executable
.endswith(
'_tf.py'
):
94
def
del_env(varname):
95
if
varname
in
os.environ:
96
del os.environ[varname]
97
98
# Ensure no log duplication for transforms
99
os.environ[
'TRF_NOECHO'
] =
'1'
100
del_env(
'TRF_ECHO'
)
101
102
# We don't use the Reco_tf auto-configuration for MP/MT transforms,
103
# instead we pass our parameters of choice to athenaopts
104
del_env(
'ATHENA_NPROC_NUM'
)
105
del_env(
'ATHENA_CORE_NUMBER'
)
106
107
def
_is_good_file
(self, path):
108
if
os.path.isfile(path):
109
return
True
110
from
ROOT
import
TFile
111
with
TFile.Open(path,
"READ"
)
as
f:
112
if
not
f.IsOpen()
or
f.IsZombie():
113
return
False
114
return
True
115
def
configure_input
(self):
116
self.log.
debug
(
'Configuring input for step %s'
, self.
name
)
117
if
self.
input
is
None
:
118
self.misconfig_abort(
119
'Input not provided for this step. To configure'
120
'a step without input, use an empty string'
)
121
122
# Step with no input
123
if
len(self.
input
) == 0:
124
return
125
126
# Try to interpret input as keyword
127
if
is_input_defined(self.
input
):
128
self.
input_object
= get_input(self.
input
)
129
if
self.
input_object
is
None
:
130
self.misconfig_abort(
'Failed to load input with keyword %s'
, self.
input
)
131
return
132
133
# Try to interpret explicit paths
134
input_paths = self.
input
.
split
(
','
)
135
for
path
in
input_paths:
136
if
not
self.
_is_good_file
(path):
137
self.misconfig_abort(f
"The provided input does not exist: {path}"
)
138
self.log.
debug
(
'Using explicit input: %s'
, self.
input
)
139
140
def
configure_job_options
(self):
141
'''Check job options configuration'''
142
self.log.
debug
(
'Configuring job options for step %s'
, self.
name
)
143
if
self.
type
==
'other'
:
144
self.log.
debug
(
'Skipping job options check for step.type=other'
)
145
return
146
if
self.
use_pickle
:
147
self.log.
debug
(
'Skipping job options check for step running from a pickle file'
)
148
return
149
150
if
self.
type
.endswith(
'_tf'
):
151
if
self.
job_options
is
None
:
152
return
153
else
:
154
self.misconfig_abort(
'Transform %s does not accept job options'
, self.
type
)
155
elif
self.
job_options
is
None
or
len(self.
job_options
) == 0:
156
self.misconfig_abort(
'Job options not provided for this step'
)
157
158
def
add_trf_precommand
(self, precommand):
159
'''Add preExec to transform command'''
160
161
if
self.
type
in
[
'Reco_tf'
,
'Trig_reco_tf'
,
'Derivation_tf'
]:
162
if
'inputBS_RDOFile'
in
self.
args
:
163
precommand =
'BSRDOtoRAW:'
+ precommand
164
elif
'outputRDO_TRIGFile'
in
self.
args
or
'doRDO_TRIG'
in
self.
args
:
165
precommand =
'RDOtoRDOTrigger:'
+ precommand
166
else
:
167
self.log.
debug
(
'Skip adding precommand %s to step %s because it is a transform which '
168
'does not run Trigger'
, precommand, self.
name
)
169
return
170
171
# match --preExec, --preExec= ignoring spaces
172
m = re.search(
r'--preExec\s*=?\s*'
, self.
args
)
173
if
m
is
None
:
174
self.
args
+= f
' --preExec "{precommand}" '
175
else
:
176
# Insert new preExec. It is important to not use the '=' sign so we
177
# can chain multiple preExecs.
178
self.
args
= self.
args
[:m.span()[0]] + f
' --preExec "{precommand}" '
+ self.
args
[m.span()[1]:]
179
180
def
configure_args
(self, test):
181
self.log.
debug
(
'Configuring args for step %s'
, self.
name
)
182
if
self.
args
is
None
:
183
self.
args
=
''
184
athenaopts =
''
185
186
# Disable prmon for Reco_tf because it is already started inside the transform
187
if
self.
type
==
'Reco_tf'
or
self.
type
==
'Derivation_tf'
:
188
self.
prmon
=
False
189
190
# Disable perfmon for multi-fork jobs as it cannot deal well with them
191
if
self.
forks
and
self.
forks
> 1
and
self.
perfmon
:
192
self.log.
debug
(
'Disabling perfmon because forks=%d > 1'
, self.
forks
)
193
self.
perfmon
=
False
194
# Disable perfmon for transforms (Reco_tf enables it itself, Trig_reco_tf would need special handling
195
# depending on whether it runs athena or athenaEF)
196
if
self.
type
.endswith(
'_tf'
)
and
self.
perfmon
:
197
self.log.
debug
(
'Disabling perfmon for the transform step type %s'
, self.
type
)
198
self.
perfmon
=
False
199
200
# Append imf/perfmon
201
if
self.
type
!=
'other'
:
202
if
self.
imf
:
203
athenaopts +=
' --imf'
204
if
self.
perfmon
:
205
if
self.
type
==
'athenaEF'
:
206
athenaopts +=
' --perfmon'
207
elif
self.
type
==
'athena'
:
208
athenaopts +=
' --perfmon=fastmonmt'
209
if
self.
malloc
:
210
athenaopts +=
" --stdcmalloc "
211
212
# Enable CostMonitoring/FPEAuditor
213
if
self.
type
!=
'other'
:
214
if
self.
costmon
:
215
self.
flags
.append(
'Trigger.CostMonitoring.monitorAllEvents=True'
)
216
if
self.
fpe_auditor
:
217
self.
flags
.append(
'Exec.FPE=1'
)
218
219
# Run config-only if requested
220
if
self.
config_only
:
221
222
if
self.
type
==
'athenaEF'
or
(self.
type
==
"other"
and
self.
executable
==
"athenaEF.py"
) :
223
athenaopts +=
' --dump-config-exit'
224
225
elif
self.
type
==
'athena'
or
self.
type
==
'Reco_tf'
or
self.
type
==
'Derivation_tf'
or
(self.
type
==
"other"
and
self.
executable
==
"athena.py"
) :
226
athenaopts +=
' --config-only='
+ self.
name
+
'.pkl'
227
228
# No current support if it isn't clear exactly what's being run
229
# This includes Trig_reco_tf and 'other' where the executable is not known
230
else
:
231
self.misconfig_abort(
'Cannot determine what config-only option is needed. Consider adding the appropriate flag to "args" instead.'
)
232
233
# Default threads/concurrent_events/forks
234
if
test.package_name ==
'TrigP1Test'
and
self.
type
==
'athenaEF'
:
235
if
self.
threads
is
None
:
236
self.
threads
= 1
237
if
self.
concurrent_events
is
None
:
238
self.
concurrent_events
= 1
239
240
# Append threads/concurrent_events/forks
241
if
self.
threads
is
not
None
:
242
athenaopts +=
' --threads={}'
.format(self.
threads
)
243
if
self.
concurrent_events
is
not
None
:
244
athenaopts +=
' --concurrent-events={}'
.format(
245
self.
concurrent_events
)
246
if
self.
forks
is
not
None
and
self.
type
!=
'athenaEF'
:
247
athenaopts +=
' --nprocs={}'
.format(self.
forks
)
248
249
# Append athenaopts
250
athenaopts = athenaopts.strip()
251
if
self.
type
.endswith(
'_tf'
):
252
self.
args
+=
' --athenaopts="{}"'
.format(athenaopts)
253
else
:
254
self.
args
+=
' '
+athenaopts
255
256
# Default max events
257
if
self.
max_events
is
None
:
258
if
test.art_type ==
'build'
:
259
if
test.package_name ==
'TrigP1Test'
:
260
self.
max_events
= 80
261
else
:
262
self.
max_events
= 20
263
else
:
264
self.
max_events
= 1000
265
266
# Set prmon interval based on max events
267
if
self.
prmon
:
268
if
self.
max_events
<= 100:
269
self.
prmon_interval
= 5
270
else
:
271
self.
prmon_interval
= 10
272
273
# Append max/skip events
274
if
self.
type
==
'athena'
:
275
self.
args
+=
' --evtMax={}'
.format(self.
max_events
)
276
elif
self.
type
==
'athenaEF'
:
277
self.
args
+=
' --number-of-events={}'
.format(self.
max_events
)
278
elif
self.
type
.endswith(
'_tf'
):
279
self.
args
+=
' --maxEvents={}'
.format(self.
max_events
)
280
if
self.
skip_events
is
not
None
:
281
if
self.
type
==
'athena'
:
282
self.
args
+=
' --skipEvents={}'
.format(self.
skip_events
)
283
elif
self.
type
==
'athenaEF'
:
284
self.
args
+=
' --skip-events={}'
.format(self.
skip_events
)
285
elif
self.
type
.endswith(
'_tf'
):
286
self.
args
+=
' --skipEvents={}'
.format(self.
skip_events
)
287
288
# Append input
289
if
len(self.
input
) > 0:
290
if
self.
input_object
is
not
None
:
291
if
self.
type
==
'athenaEF'
:
292
input_str =
' --file='
.join(self.
input_object
.paths)
293
else
:
294
input_str =
','
.join(self.
input_object
.paths)
295
else
:
296
input_str = self.
input
297
if
self.
type
==
'athena'
:
298
self.
args
+=
' --filesInput={}'
.format(input_str)
299
elif
self.
type
==
'athenaEF'
:
300
self.
args
+=
''
.join([f
" --file={inputFile}"
for
inputFile
in
input_str.split(
','
)])
301
elif
self.
type
.endswith(
'_tf'
):
302
if
self.
input_object
is
None
:
303
self.misconfig_abort(
304
'Cannot build inputXYZFile string for transform '
305
' from explicit input path. Use input=\'\' and '
306
'specify the input explicitly in args'
)
307
if
self.
type
==
'Trig_reco_tf'
and
'--prodSysBSRDO True'
in
self.
args
:
308
self.
args
+=
' --inputBS_RDOFile={}'
.format(input_str)
309
else
:
310
self.
args
+=
' --input{}File={}'
.format(
311
self.
input_object
.format, input_str)
312
313
314
# Append job options
315
if
self.
job_options
is
not
None
:
316
self.
args
+=
' '
+self.
job_options
317
318
# Append flags
319
if
self.
flags
:
320
if
not
isinstance(self.
flags
, (list, tuple)):
321
self.misconfig_abort(
'Wrong type for flags. Expected list or tuple.'
)
322
323
if
self.
type
.endswith(
'_tf'
):
# for transform, set flags as pre-exec
324
if
self.
type
==
'Trig_reco_tf'
:
325
# No 'flags.' prefix for the trigger transform
326
self.
add_trf_precommand
(
' '
.join(f
'{flag}'
for
flag
in
self.
flags
))
327
else
:
328
self.
add_trf_precommand
(
';'
.join(f
'flags.{flag}'
for
flag
in
self.
flags
))
329
else
:
# athena(HLT)
330
self.
args
+=
' '
+
' '
.join(self.
flags
)
331
332
# Strip extra whitespace
333
self.
args
= self.
args
.
strip
()
SiliconTech::strip
@ strip
Definition
FPGATrackSimTypes.h:25
debug
const bool debug
Definition
MakeUncertaintyPlots.cxx:53
python.TrigValSteering.ExecStep.ExecStep
Definition
ExecStep.py:16
python.TrigValSteering.ExecStep.ExecStep.name
name
Definition
ExecStep.py:50
python.TrigValSteering.ExecStep.ExecStep.executable
str executable
Definition
ExecStep.py:86
python.TrigValSteering.ExecStep.ExecStep.use_pickle
bool use_pickle
Definition
ExecStep.py:34
python.TrigValSteering.ExecStep.ExecStep.config_only
bool config_only
Definition
ExecStep.py:41
python.TrigValSteering.ExecStep.ExecStep.input_object
input_object
Definition
ExecStep.py:26
python.TrigValSteering.ExecStep.ExecStep.max_events
int max_events
Definition
ExecStep.py:32
python.TrigValSteering.ExecStep.ExecStep.configure_input
configure_input(self)
Definition
ExecStep.py:115
python.TrigValSteering.ExecStep.ExecStep.depends_on_previous
bool depends_on_previous
Definition
ExecStep.py:44
python.TrigValSteering.ExecStep.ExecStep.input
input
Definition
ExecStep.py:25
python.TrigValSteering.ExecStep.ExecStep.perfmon
bool perfmon
Definition
ExecStep.py:36
python.TrigValSteering.ExecStep.ExecStep.fpe_auditor
bool fpe_auditor
Definition
ExecStep.py:37
python.TrigValSteering.ExecStep.ExecStep.prmon
bool prmon
Definition
ExecStep.py:40
python.TrigValSteering.ExecStep.ExecStep._is_good_file
_is_good_file(self, path)
Definition
ExecStep.py:107
python.TrigValSteering.ExecStep.ExecStep.skip_events
skip_events
Definition
ExecStep.py:33
python.TrigValSteering.ExecStep.ExecStep.get_log_file_name
get_log_file_name(self)
Definition
ExecStep.py:54
python.TrigValSteering.ExecStep.ExecStep.threads
int threads
Definition
ExecStep.py:29
python.TrigValSteering.ExecStep.ExecStep.costmon
bool costmon
Definition
ExecStep.py:38
python.TrigValSteering.ExecStep.ExecStep.malloc
bool malloc
Definition
ExecStep.py:39
python.TrigValSteering.ExecStep.ExecStep.args
str args
Definition
ExecStep.py:162
python.TrigValSteering.ExecStep.ExecStep.construct_name
construct_name(self)
Definition
ExecStep.py:46
python.TrigValSteering.ExecStep.ExecStep.concurrent_events
int concurrent_events
Definition
ExecStep.py:30
python.TrigValSteering.ExecStep.ExecStep.prmon_interval
int prmon_interval
Definition
ExecStep.py:269
python.TrigValSteering.ExecStep.ExecStep.flags
list flags
Definition
ExecStep.py:28
python.TrigValSteering.ExecStep.ExecStep.forks
forks
Definition
ExecStep.py:31
python.TrigValSteering.ExecStep.ExecStep.log_file_name
str log_file_name
Definition
ExecStep.py:63
python.TrigValSteering.ExecStep.ExecStep.configure_args
configure_args(self, test)
Definition
ExecStep.py:180
python.TrigValSteering.ExecStep.ExecStep.job_options
job_options
Definition
ExecStep.py:27
python.TrigValSteering.ExecStep.ExecStep.configure_job_options
configure_job_options(self)
Definition
ExecStep.py:140
python.TrigValSteering.ExecStep.ExecStep.__init__
__init__(self, name=None)
Definition
ExecStep.py:23
python.TrigValSteering.ExecStep.ExecStep.configure_type
configure_type(self)
Definition
ExecStep.py:74
python.TrigValSteering.ExecStep.ExecStep.type
str type
Definition
ExecStep.py:47
python.TrigValSteering.ExecStep.ExecStep.auto_report_result
bool auto_report_result
Definition
ExecStep.py:42
python.TrigValSteering.ExecStep.ExecStep.required
bool required
Definition
ExecStep.py:43
python.TrigValSteering.ExecStep.ExecStep.configure
configure(self, test)
Definition
ExecStep.py:60
python.TrigValSteering.ExecStep.ExecStep.imf
bool imf
Definition
ExecStep.py:35
python.TrigValSteering.ExecStep.ExecStep.add_trf_precommand
add_trf_precommand(self, precommand)
Definition
ExecStep.py:158
split
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition
hcg.cxx:179
Generated on
for ATLAS Offline Software by
1.17.0