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 AthenaCommon.Logging
import logging
17 log = logging.getLogger(
'TriggerMenuConfigTest' )
18 log.info(
"Importing %s", __name__)
30 def run(self, config):
31 raise NotImplementedError(
"ConfigVerification subclass must implement run()")
36 super(UniqueChainNames, self).
__init__(
37 description=
"Chain names are unique")
39 def run(self, config):
40 names = config[
"chains"].
keys()
41 counts = Counter(names)
43 in counts.items()
if count > 1]
48 super(ConsecutiveChainCounters, self).
__init__(
49 description=
"Chain counters are consecutive 1..N")
51 def run(self, config):
52 counters = [chain[
"counter"]
for chain
53 in config[
"chains"].
values()]
55 for count
in counters:
56 if count != prev_counter + 1:
63 Verifies that chain names start with the expected prefix, and have their
64 parts in the correct order by type, as well as any trigger level specific
68 _SIGNATURE_TYPE_ORDER = {
70 "e",
"g",
"mu",
"tau",
"j",
"xe",
"ht",
"isotrk",
"fslrt",
"dedxtrk",
"hitdvjet",
"fsvsi",
"distrk",
"dispjet"
73 "EM",
"MU",
"TAU",
"J",
"XE",
"HT"
78 super(StructuredChainNames, self).
__init__(
79 description=
"Chain names are structured in the expected way")
84 def run(self, config):
86 names = config[
"chains"].
keys()
90 names = [item[
"name"]
for item
in config[
"items"].
values()]
98 def FEX_items_in_order(name):
100 Where multiple FEX algorithms are used for the same item type,
101 they should be in alphabetical order.
103 fex_pattern =
r"\d*([egj])({})[A-Z]*\d+s?".
format(
105 fex_items = re.findall(fex_pattern, name)
108 fexes_of_type = [fex
for fex, match_type
in fex_items
109 if match_type == item_type]
110 if not fexes_of_type ==
sorted(fexes_of_type):
118 True if name starts with level prefix, and all signature
119 types are in the correct order, otherwise False.
124 sig_type_pattern = re.compile(
125 r"_\d*[egj]?({})\d+s?".
format(signature_types))
126 def items_in_order(part):
129 sig_type_pattern.findall(part)]
130 rr = indices ==
sorted(indices)
132 log.error(
"[StructuredChainNames::items_in_order] %s NOT SORTED!", indices)
136 def are_signatures_in_order(name_parts):
137 to_check = [
"_".
join(p
for p
in name_parts
if "-" not in p)]
139 topo_parts = [p
for p
in name_parts
if "-" in p]
140 for topo
in topo_parts:
141 to_check.extend(topo.split(
"-"))
142 res =
all(items_in_order(part)
for part
in to_check)
144 for part
in to_check:
145 if not items_in_order(part):
146 log.error(
"[StructuredChainNames::are_signatures_in_order] %s not in order!", part)
150 parts = name.split(
"_")
152 result=
all((len(parts) > 1,
154 are_signatures_in_order(parts[1:])))
156 log.error(
"[StructuredChainNames::_matches_shared_conventions] chain deosn't match convention: parts[0] = %s, value = %s, parts[1:] = %s, signature_types = %s",
163 super(RestrictedCTPIDs, self).
__init__(
164 description=
"Less than 512 CTP items, and no CTP id greater than 512")
167 ctp_ids = {name: item[
"ctpid"]
for
168 name, item
in config[
"items"].
items()}
169 if len(ctp_ids) > 512:
171 "More than 512 CTP items defined")
172 over_max_ids = [name
for name, ctp_id
in ctp_ids.items()
179 super(PartialEventBuildingChecks, self).
__init__(
180 description=
'Config consistency of Partial Event Building')
183 from TriggerMenuMT.HLT.Menu
import EventBuildingInfo
184 eb_identifiers = EventBuildingInfo.getAllEventBuildingIdentifiers()
186 for chain_name, chain_config
in config[
'chains'].
items():
187 peb_identifiers = [idf
for idf
in eb_identifiers
if '_'+idf+
'_' in chain_name]
188 peb_writers = [seq
for seq
in chain_config[
'sequencers']
if 'PEBInfoWriter' in seq]
190 is_peb_chain = (len(peb_identifiers) > 0
or len(peb_writers) > 0)
193 for stream_name
in chain_config[
'streams']:
194 if stream_name
not in config[
'streams']:
196 'Stream {:s} for chain {:s} is not defined in streaming configuration'.
format(
197 stream_name, chain_name))
199 is_feb_stream = config[
'streams'][stream_name][
'forceFullEventBuilding']
201 if is_peb_chain
and is_feb_stream:
203 'PEB chain {:s} streamed to a full-event-building stream {:s} '
204 '(forceFullEventBuilding=True)'.
format(
205 chain_name, stream_name))
207 elif not is_peb_chain
and not is_feb_stream:
209 'Full-event-building chain {:s} streamed to the stream {:s} which allows partial '
210 'event building (forceFullEventBuilding=False)'.
format(
211 chain_name, stream_name))
217 if len(peb_identifiers) != 1:
219 '{:s} has {:d} event building identifiers'.
format(chain_name, len(peb_identifiers)))
221 if len(peb_writers) != 1:
223 '{:s} has {:d} PEBInfoWriter sequences'.
format(chain_name, len(peb_writers)))
225 if peb_identifiers
and peb_writers
and not peb_writers[0].endswith(peb_identifiers[0]):
227 '{:s} PEB sequence name {:s} doesn\'t end with PEB identifier {:s}'.
format(
228 chain_name, peb_writers[0], peb_identifiers[0]))