ATLAS Offline Software
Loading...
Searching...
No Matches
CheckL1HLTConsistency.py
Go to the documentation of this file.
1# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2
3from AthenaCommon.Logging import logging
4log = logging.getLogger(__name__)
5import re
6
7
8def getL1TopoAlgMaps(lvl1access):
9 """
10 Returns tuple of L1Topo algorithm to board and item map: (alg_to_board, alg_to_item)
11
12 alg_to_board: Map between L1 algorithm name and board (Topo2, Topo3 or LegacyTopo,
13 items coming from other boards will not be listed in the map)
14 alg_to_item: Map between L1 item name and topo algorithm
15 """
16
17 lvl1items = lvl1access.items(includeKeys=["name"])
18 lvl1items_full = lvl1access.items()
19
20 l1topo_alg_to_board = {}
21 l1topo_alg_to_item = {}
22 connectors = ['Topo2El','Topo3El','LegacyTopoMerged']
23
24 for l1item in lvl1items:
25 # Split string of AND/OR-ed items
26 # e.g. ((AFP_NSA[x1] & AFP_FSA[x1]) | (AFP_NSC[x1] & AFP_FSC[x1])) & EM7[x1]
27 l1item_def_list = re.split("[&|]+", lvl1items_full[l1item]['definition'])
28 for l1item_def_aux in l1item_def_list:
29 # Strip brackets/whitespace and take name before multiplicity
30 l1item_def = l1item_def_aux.strip('() ').split('[')[0]
31
32 # fill alg_to_board
33 for connect in connectors:
34 for v in lvl1access.connector(connect)['triggerlines']:
35 if l1item_def==v['name']:
36 l1topo_alg_to_board[l1item_def] = connect
37
38 # fill alg_to_item (we stop once we found 'TOPO' item)
39 if 'TOPO' not in l1topo_alg_to_item.get(l1item,''):
40 l1topo_alg_to_item[l1item] = l1item_def
41
42 log.debug("L1Topo alg to board map: %s",l1topo_alg_to_board)
43 log.debug("L1Topo alg to item map: %s",l1topo_alg_to_item)
44 return (l1topo_alg_to_board, l1topo_alg_to_item)
45
46
47#this function checks each threshold within each chain to make sure that it is defined in the L1Menu
49 from TrigConfIO.L1TriggerConfigAccess import L1MenuAccess
50 from TrigConfigSvc.TrigConfigSvcCfg import getL1MenuFileName
51 lvl1name = getL1MenuFileName(flags)
52 lvl1access = L1MenuAccess(lvl1name)
53 lvl1thtypes = lvl1access.thresholdTypes()
54 lvl1items = lvl1access.items(includeKeys=["name"])
55 lvl1items_full = lvl1access.items()
56 from TriggerMenuMT.HLT.Config.Utility.HLTMenuConfig import HLTMenuConfig
57
58 allUsedItems = []
59 allUnusedItems = []
60 chainsWithWrongLabel = {}
61
62 l1topo_alg_to_board, l1topo_alg_to_item = getL1TopoAlgMaps(lvl1access)
63
64 missing_L1_items = []
65 for chain in HLTMenuConfig.dictsList():
66 log.debug('[checkL1HLTConsistency] Checking the l1thresholds in the chain %s', chain["chainName"])
67# #don't check the noalg chains (they don't do anything in the HLT anyway)
68# if 'HLT_noalg_' in chain["chainName"]:
69# continue
70
71 is_missing=False
72 l1item_vec = chain['L1item'].split(',')
73 for l1item in l1item_vec:
74 if l1item == "":
75 log.debug('[checkL1HLTConsistency] chain %s in L1Menu %s: L1item not set...', chain["chainName"], lvl1name)
76 continue
77 if l1item not in lvl1items:
78 log.error('[checkL1HLTConsistency] chain %s: L1item: %s, not found in the items list of the L1Menu %s', chain["chainName"], chain["L1item"], lvl1name)
79 missing_L1_items.append(l1item)
80 is_missing=True
81 else:
82 if l1item not in allUsedItems:
83 allUsedItems.append(l1item)
84
85 # Avoid crashing on lookups
86 if is_missing:
87 continue
88
89 # Find L1 Threshold information for current chain
90 l1thr_vec = []
91 for p in chain['chainParts']:
92 #now check that the thresholds of the chain are listed in the L1Menu.thresholds field
93 th = p['L1threshold'][5:] if p['L1threshold'].startswith("PROBE") else p['L1threshold']
94 l1thr_vec.append(th)
95 if ('TAU' in th) and th[0] not in ['e','j','c']: #legacy TAU
96 th = th.replace('TAU','HA')
97 thFoundInL1Menu = False
98 l1type = "NOTFOUND"
99 if th == 'FSNOSEED':
100 log.debug('[checkL1HLTConsistency] \t %s in L1thresholds', th)
101 continue
102 for thtype in lvl1thtypes:
103 l1thresholds = lvl1access.thresholds(thtype)
104 if th in l1thresholds:
105 thFoundInL1Menu = True
106 l1type = thtype
107 break
108 if thFoundInL1Menu:
109 log.debug('[checkL1HLTConsistency] \t %s in L1HLTConsistency[%s]', th, l1type)
110 else:
111 log.error('[checkL1HLTConsistency] chain %s: L1Threshold %s not found in the L1thresholds of the L1Menu %s', chain["chainName"], th, lvl1name)
112 raise Exception("Please fix the menu or the chain.")
113
114 # check that L1 seeds and L1 item are all either legacy or phase1
115 legacyItem = False
116 noCaloItemL1 = True
117 noCaloItemHLT = True
118 foundPhase1CaloSeed = False
119 foundLegacyCaloSeed = False
120 for item in l1item_vec:
121 if item=='':
122 continue
123 if 'legacy' in lvl1items_full[item]:
124 if lvl1items_full[item]['legacy']:
125 legacyItem = True
126 noCaloItemL1 = False
127 else:
128 items = item[2:].split('_')
129 for it in items:
130 if any(substring in it for substring in ['e','c','j','g']): # find phase1 calo inputs in L1Topo decision triggers
131 noCaloItemL1 = False
132
133 # Don't check topo assignments for multi-seeded triggers
134 if len(l1item_vec)==1:
135 errormsg = ""
136 if l1topo_alg_to_item[item] in l1topo_alg_to_board:
137 if not any('Topo' in g for g in chain['groups']):
138 errormsg = f"Chain has item {item} ({l1topo_alg_to_board[l1topo_alg_to_item[item]]}) but has no topo group"
139
140 # Possibilities for wrong assignment:
141 # - Item comes from topo board but has no topo group
142 # - Chain has topo label but L1 item does not come from topo board
143 # - Chain has wrong topo label (Topo2 when it should be Topo3 for example)
144 for group in chain['groups']:
145 if 'Topo' in group:
146 if l1topo_alg_to_item[item] in l1topo_alg_to_board:
147 if group in l1topo_alg_to_board[l1topo_alg_to_item[item]]:
148 log.debug("Chain correctly assigned topo board")
149 else:
150 errormsg = f"Chain should be labelled with topo board {l1topo_alg_to_board[l1topo_alg_to_item[item]]}"
151 elif l1topo_alg_to_item[item] not in l1topo_alg_to_board:
152 errormsg = f"Chain does not come from topo board but has Topo group {group}"
153
154 if errormsg:
155 chainsWithWrongLabel.update({chain['chainName']: (chain['groups'], errormsg)})
156
157 for th in l1thr_vec:
158 if th=='FSNOSEED':
159 continue
160 if th[:1] in ['e','c','j','g']:
161 foundPhase1CaloSeed = True
162 noCaloItemHLT = False
163 if th[:1] in ['E','T','J','X']:
164 foundLegacyCaloSeed = True
165 noCaloItemHLT = False
166
167 mixedCaloSeed = False
168 if legacyItem and foundPhase1CaloSeed: # chain with L1 legacy item, cannot have phase1 seed
169 mixedCaloSeed = True
170 if not legacyItem:
171 if not noCaloItemL1: # chain with L1 phase1 item, cannot have legacy seed
172 if foundLegacyCaloSeed:
173 mixedCaloSeed = True
174 else:
175 if foundLegacyCaloSeed and foundPhase1CaloSeed: # chain without L1 calo items, cannot have both legacy and phase1 seeds
176 mixedCaloSeed = True
177 if mixedCaloSeed:
178 log.warning('[checkL1HLTConsistency] chain %s contains a mix of legacy and phase1 calo thresholds! L1 items: [%s] (legacy item = %s), L1 seeds: [%s] (foundPhase1CaloSeed = %s, foundLegacyCaloSeed = %s)', chain["chainName"], ",".join(l1item_vec), legacyItem, ",".join(l1thr_vec), foundPhase1CaloSeed, foundLegacyCaloSeed )
179 # log.error('[checkL1HLTConsistency] chain %s contains a mix of legacy and phase1 calo thresholds! L1 items: [%s] (legacy item = %s), L1 seeds: [%s] (foundPhase1CaloSeed = %s, foundLegacyCaloSeed = %s)', chain["chainName"], ",".join(l1item_vec), legacyItem, ",".join(l1thr_vec), foundPhase1CaloSeed, foundLegacyCaloSeed )
180 # raise Exception("Please fix the chain.")
181
182 # check legacy and phase1 chains have the correct groups
183 wrongLabel = False
184 rightLabel = False
185 log.debug("Checking chain %s: noCaloItemL1 %s, noCaloItemHLT %s , legacyItem %s", chain['chainName'], noCaloItemL1, noCaloItemHLT, legacyItem )
186
187 log.debug(chain['groups'])
188 for group in chain['groups']:
189 log.debug("Checking group %s: find 'Legacy' %s, find 'PhaseI' %s", group, str(group.find('Legacy')), str(group.find('PhaseI')) )
190
191 if noCaloItemL1 and noCaloItemHLT:
192 if group.find('Legacy')>-1 or group.find('PhaseI')>-1 :
193 wrongLabel = True # chains without calo inputs should not have legacy or phase1 label
194 if group.find('Legacy')<0 and group.find('PhaseI')<0 :
195 rightLabel = True
196 else:
197 if legacyItem: # chain with L1 legacy seed
198 if group.find('Legacy')>-1 :
199 rightLabel = True
200 if group.find('PhaseI')>-1 :
201 wrongLabel = True
202 else:
203 if not noCaloItemL1: # chain with L1 phase1 item
204 if group.find('PhaseI')>-1 :
205 rightLabel = True
206 if group.find('Legacy')>-1 :
207 wrongLabel = True
208 if noCaloItemL1 and not noCaloItemHLT: # chain with HLT legacy or phase1 seed
209 if foundPhase1CaloSeed and group.find('Legacy')>-1 :
210 wrongLabel = True
211 if foundPhase1CaloSeed and group.find('PhaseI')>-1 :
212 rightLabel = True
213 if foundLegacyCaloSeed and group.find('PhaseI')>-1 :
214 wrongLabel = True
215 if foundLegacyCaloSeed and group.find('Legacy')>-1 :
216 rightLabel = True
217 if wrongLabel or not rightLabel:
218 errormsg = 'Incorrect L1Calo version label -- check Legacy/Phase-I assignment'
219 chainsWithWrongLabel.update({chain['chainName']: (chain['groups'],errormsg)})
220
221 if missing_L1_items:
222 log.error('[checkL1HLTConsistency] Missing L1 items:')
223 for i in missing_L1_items:
224 log.error(f' {i}')
225 raise Exception("Please fix the menu or the chains.")
226
227 if len(chainsWithWrongLabel) and ('Physics' in lvl1name) and not ('HI' in lvl1name) and not ('lowMu' in lvl1name): # apply this check only for the Physics menu, for now; don't apply for HI menu
228 log.error('These chains have the wrong groups for l1menu %s:',lvl1name)
229 for key, (groups, errormsg) in chainsWithWrongLabel.items():
230 log.error('%s: %s\n --> %s', key, ",".join(groups), errormsg)
231 raise Exception("Please fix these chains.")
232
233 # check for unused L1 items
234 for item in lvl1items:
235 if item not in allUsedItems:
236 allUnusedItems.append(item)
237 if len(allUnusedItems)==0:
238 log.info('[checkL1HLTConsistency] All items in L1 menu are used')
239 else:
240 log.info('[checkL1HLTConsistency] %i items in L1 menu are not used: %s', len(allUnusedItems), ",".join(allUnusedItems))
241 log.info('[checkL1HLTConsistency] checkL1HLTConsistency completed succesfully')
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177