4 Tests to verify generated menus are valid.
6 Ported from TrigConfStorage/ConfigurationCheck.cxx and
7 HLT/Config/Utility/HLTMenuConfig.py, see [ATR-19830].
9 Designed to be used by the `verify_menu_config.py` script.
14 from collections
import Counter
16 from TriggerMenuMT.HLT.Menu.SignatureDicts
import getListOfSignatureStrings
18 from AthenaCommon.Logging
import logging
19 log = logging.getLogger(
'TriggerMenuConfigTest' )
20 log.info(
"Importing %s", __name__)
32 def run(self, config):
33 raise NotImplementedError(
"ConfigVerification subclass must implement run()")
38 super(UniqueChainNames, self).
__init__(
39 description=
"Chain names are unique")
41 def run(self, config):
42 names = config[
"chains"].
keys()
43 counts = Counter(names)
45 in counts.items()
if count > 1]
50 super(ConsecutiveChainCounters, self).
__init__(
51 description=
"Chain counters are consecutive 1..N")
53 def run(self, config):
54 counters = [chain[
"counter"]
for chain
55 in config[
"chains"].
values()]
57 for count
in counters:
58 if count != prev_counter + 1:
65 Verifies that chain names start with the expected prefix, and have their
66 parts in the correct order by type, as well as any trigger level specific
70 _SIGNATURE_TYPE_ORDER = {
74 "EM",
"MU",
"TAU",
"J",
"XE",
"HT"
79 super(StructuredChainNames, self).
__init__(
80 description=
"Chain names are structured in the expected way")
85 def run(self, config):
87 names = config[
"chains"].
keys()
91 names = [item[
"name"]
for item
in config[
"items"].
values()]
99 def FEX_items_in_order(name):
101 Where multiple FEX algorithms are used for the same item type,
102 they should be in alphabetical order.
104 fex_pattern =
r"\d*([egj])({})[A-Z]*\d+s?".
format(
106 fex_items = re.findall(fex_pattern, name)
109 fexes_of_type = [fex
for fex, match_type
in fex_items
110 if match_type == item_type]
111 if not fexes_of_type ==
sorted(fexes_of_type):
119 True if name starts with level prefix, and all signature
120 types are in the correct order, otherwise False.
125 sig_type_pattern = re.compile(
126 r"_\d*[egj]?({})\d+s?".
format(signature_types))
133 def items_in_order(part):
136 sig_type_pattern.findall(part)]
157 rr = indices ==
sorted(indices)
159 log.error(
"[StructuredChainNames::items_in_order] %s NOT SORTED!", indices)
163 def are_signatures_in_order(name_parts):
165 to_check = [
"".
join(f
"_{p}" for p
in name_parts
if "-" not in p)]
168 topo_parts = [p
for p
in name_parts
if "-" in p]
169 for topo
in topo_parts:
170 to_check.extend(topo.split(
"-"))
171 res =
all(items_in_order(part)
for part
in to_check)
173 for part
in to_check:
174 if not items_in_order(part):
175 log.error(
"[StructuredChainNames::are_signatures_in_order] %s not in order!", part)
179 parts = name.split(
"_")
181 result=
all((len(parts) > 1,
183 are_signatures_in_order(parts[1:])))
185 log.error(
"[StructuredChainNames::_matches_shared_conventions] chain deosn't match convention: parts[0] = %s, value = %s, parts[1:] = %s, signature_types = %s",
193 super(RestrictedCTPIDs, self).
__init__(
194 description=
"Less than 512 CTP items, and no CTP id greater than 512")
197 ctp_ids = {name: item[
"ctpid"]
for
198 name, item
in config[
"items"].
items()}
199 if len(ctp_ids) > 512:
201 "More than 512 CTP items defined")
202 over_max_ids = [name
for name, ctp_id
in ctp_ids.items()
209 super(PartialEventBuildingChecks, self).
__init__(
210 description=
'Config consistency of Partial Event Building')
213 from TriggerMenuMT.HLT.Menu
import EventBuildingInfo
214 eb_identifiers = EventBuildingInfo.getAllEventBuildingIdentifiers()
216 for chain_name, chain_config
in config[
'chains'].
items():
217 peb_identifiers = [idf
for idf
in eb_identifiers
if '_'+idf+
'_' in chain_name]
218 peb_writers = [seq
for seq
in chain_config[
'sequencers']
if 'PEBInfoWriter' in seq]
220 is_peb_chain = (len(peb_identifiers) > 0
or len(peb_writers) > 0)
223 for stream_name
in chain_config[
'streams']:
224 if stream_name
not in config[
'streams']:
226 'Stream {:s} for chain {:s} is not defined in streaming configuration'.
format(
227 stream_name, chain_name))
229 is_feb_stream = config[
'streams'][stream_name][
'forceFullEventBuilding']
231 if is_peb_chain
and is_feb_stream:
233 'PEB chain {:s} streamed to a full-event-building stream {:s} '
234 '(forceFullEventBuilding=True)'.
format(
235 chain_name, stream_name))
237 elif not is_peb_chain
and not is_feb_stream:
239 'Full-event-building chain {:s} streamed to the stream {:s} which allows partial '
240 'event building (forceFullEventBuilding=False)'.
format(
241 chain_name, stream_name))
247 if len(peb_identifiers) != 1:
249 '{:s} has {:d} event building identifiers'.
format(chain_name, len(peb_identifiers)))
251 if len(peb_writers) != 1:
253 '{:s} has {:d} PEBInfoWriter sequences'.
format(chain_name, len(peb_writers)))
255 if peb_identifiers
and peb_writers
and not peb_writers[0].endswith(peb_identifiers[0]):
257 '{:s} PEB sequence name {:s} doesn\'t end with PEB identifier {:s}'.
format(
258 chain_name, peb_writers[0], peb_identifiers[0]))