ATLAS Offline Software
Loading...
Searching...
No Matches
TrigGenericAlgsConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
4from AthenaConfiguration.ComponentFactory import CompFactory
5from TrigPartialEventBuilding.TrigPartialEventBuildingConfig import getRegSelTools
6from AthenaCommon.Logging import logging
7_log = logging.getLogger( __name__ )
8
9
10def TimeBurnerCfg(flags, name="TimeBurner", **kwargs):
11 return CompFactory.TimeBurner(name, **kwargs)
12
13def TimeBurnerHypoToolGen(flags, chainDict):
14 # Dummy HypoTool (it is not even called by TimeBurner)
15 return CompFactory.TrigGenericHypoTool(chainDict['chainName'],
16 PassString = "")
17
19 return CompFactory.EndOfEventROIConfirmerAlg(name)
20
21def EndOfEventFilterAlgCfg(name, chainName):
22 return CompFactory.EndOfEventFilterAlg(name, ChainName=chainName)
23
24def TrigEventInfoRecorderAlgCfg(flags, name, trigEventInfoKey, decoratePFlowInfo, decorateEMTopoInfo, renounceAll=False, primaryVertexInputName="HLT_IDVertex_FS", RhoKey_PFlow = 'HLT_Kt4EMPFlowEventShape', RhoKey_EMTopo = 'HLT_Kt4EMTopoEventShape'):
25 acc = ComponentAccumulator()
26 alg = CompFactory.TrigEventInfoRecorderAlg(name,
27 trigEventInfoKey = trigEventInfoKey,
28 decoratePFlowInfo = decoratePFlowInfo,
29 decorateEMTopoInfo = decorateEMTopoInfo,
30 renounceAll = renounceAll,
31 primaryVertexInputName = primaryVertexInputName,
32 RhoKey_PFlow = RhoKey_PFlow,
33 RhoKey_EMTopo = RhoKey_EMTopo,
34 )
35 acc.addEventAlgo(alg, primary=True)
36 return acc
37
38
40 from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool
41 mon = GenericMonitoringTool(flags, 'MonTool')
42
43 maxBC = 6 # fixed plotting half-range ±6 (CTP limit is 15)
44 nbin = 2*maxBC + 1
45 # 1-D delta BC histogram
46 mon.defineHistogram(
47 'BeforeAfterFlag', # ← variable list, positional
48 path = 'EXPERT',
49 type = 'TH1F',
50 title = 'L1 correlation; delta BC (relative to L1A); Events',
51 xbins = nbin,
52 xmin = -maxBC-0.5,
53 xmax = maxBC+0.5)
54
55 mon.defineHistogram(
56 'BeforeAfterFlag,otherType',
57 path = 'EXPERT',
58 type = 'TH2F',
59 title = 'delta BC vs Other-BC type; delta BC (relative to L1A); Other-BC type',
60 xbins = nbin, xmin = -maxBC-0.5, xmax = maxBC+0.5,
61 ybins = 8, ymin = -0.5, ymax = 7.5)
62
63 # 2-D type matrix (same as before – just remove var=)
64 mon.defineHistogram(
65 'l1Accept,otherType',
66 path = 'EXPERT',
67 type = 'TH2F',
68 title = 'Type matrix ; L1A type ; Other-BC type',
69 xbins = 8, xmin = -0.5, xmax = 7.5,
70 ybins = 8, ymin = -0.5, ymax = 7.5)
71
72 mon.defineHistogram(
73 'BeforeAfterFlag,l1Accept',
74 path = 'EXPERT',
75 type = 'TH2F',
76 title = 'delta BC vs L1A type; delta BC (relative); L1A type',
77 xbins = nbin, xmin = -maxBC-0.5, xmax = maxBC+0.5,
78 ybins = 8, ymin = -0.5, ymax = 7.5)
79
80 # BeforeOffset: Distance in BCs to the first earlier fired BC
81 mon.defineHistogram(
82 'BeforeOffset',
83 path = 'EXPERT',
84 type = 'TH1F',
85 title = 'Offset of earlier BC trigger relative to L1A; delta BC before; Events',
86 xbins = maxBC,
87 xmin = -0.5,
88 xmax = maxBC + 0.5
89 )
90
91 # AfterOffset: Distance in BCs to the first later fired BC
92 mon.defineHistogram(
93 'AfterOffset',
94 path = 'EXPERT',
95 type = 'TH1F',
96 title = 'Offset of later BC trigger relative to L1A; delta BC after; Events',
97 xbins = maxBC,
98 xmin = -0.5,
99 xmax = maxBC + 0.5
100 )
101
102 # OtherTypeBefore: Trigger type (1–7) of the earlier BC
103 mon.defineHistogram(
104 'OtherTypeBefore',
105 path = 'EXPERT',
106 type = 'TH1F',
107 title = 'Trigger type of the earlier neighbor BC; Type code; Events',
108 xbins = 8,
109 xmin = -0.5,
110 xmax = 7.5
111 )
112
113 # OtherTypeAfter: Trigger type (1–7) of the later BC
114 mon.defineHistogram(
115 'OtherTypeAfter',
116 path = 'EXPERT',
117 type = 'TH1F',
118 title = 'Trigger type of the later neighbor BC; Type code; Events',
119 xbins = 8,
120 xmin = -0.5,
121 xmax = 7.5
122 )
123
124 # Correlation between early/late BC types
125 mon.defineHistogram(
126 'OtherTypeBefore,OtherTypeAfter',
127 path = 'EXPERT',
128 type = 'TH2F',
129 title = 'Trigger type before vs after; Earlier BC type; Later BC type',
130 xbins = 8, xmin = -0.5, xmax = 7.5,
131 ybins = 8, ymin = -0.5, ymax = 7.5
132 )
133
134 # Time structure of symmetric/asymmetric cases
135 mon.defineHistogram(
136 'BeforeOffset,AfterOffset',
137 path = 'EXPERT',
138 type = 'TH2F',
139 title = 'Offset before vs after; delta BC before; delta BC after',
140 xbins = maxBC, xmin = -0.5, xmax = maxBC + 0.5,
141 ybins = maxBC, ymin = -0.5, ymax = maxBC + 0.5
142 )
143
144 # delta BC × CTPID occupancy maps (TBP)
145 mon.defineHistogram(
146 'DeltaBCAll,CTPIDAll;MistimeMap_TBP',
147 path='EXPERT', type='TH2F',
148 title='TBP occupancy vs delta BC and CTPID;delta BC (relative to L1A);CTPID',
149 xbins=2*maxBC+1, xmin=-maxBC-0.5, xmax=maxBC+0.5,
150 ybins=512, ymin=-0.5, ymax=511.5
151 )
152
153 # TAP
154 mon.defineHistogram(
155 'DeltaBCAll_TAP,CTPIDAll_TAP;MistimeMap_TAP',
156 path='EXPERT', type='TH2F',
157 title='TAP occupancy vs delta BC and CTPID;delta BC (relative to L1A);CTPID',
158 xbins=2*maxBC+1, xmin=-maxBC-0.5, xmax=maxBC+0.5,
159 ybins=512, ymin=-0.5, ymax=511.5
160 )
161
162 # 512×512 pair maps: CTPID(BC=0) vs CTPID(BC=±1, ±2)
163 mon.defineHistogram(
164 'CTPID0tbp_m2,CTPIDtbp_m2;PairMap_TBP_DeltaBCm2',
165 path='EXPERT', type='TH2F',
166 title='TBP: CTPID at BC 0 vs CTPID at BC=-2;CTPID at BC=0;CTPID at BC=-2',
167 xbins=512, xmin=-0.5, xmax=511.5,
168 ybins=512, ymin=-0.5, ymax=511.5
169 )
170 mon.defineHistogram(
171 'CTPID0tbp_m1,CTPIDtbp_m1;PairMap_TBP_DeltaBCm1',
172 path='EXPERT', type='TH2F',
173 title='TBP: CTPID at BC 0 vs CTPID at BC=-1;CTPID at BC=0;CTPID at BC=-1',
174 xbins=512, xmin=-0.5, xmax=511.5,
175 ybins=512, ymin=-0.5, ymax=511.5
176 )
177 mon.defineHistogram(
178 'CTPID0tbp_p1,CTPIDtbp_p1;PairMap_TBP_DeltaBCp1',
179 path='EXPERT', type='TH2F',
180 title='TBP: CTPID at BC 0 vs CTPID at BC=+1;CTPID at BC=0;CTPID at BC=+1',
181 xbins=512, xmin=-0.5, xmax=511.5,
182 ybins=512, ymin=-0.5, ymax=511.5
183 )
184 mon.defineHistogram(
185 'CTPID0tbp_p2,CTPIDtbp_p2;PairMap_TBP_DeltaBCp2',
186 path='EXPERT', type='TH2F',
187 title='TBP: CTPID at BC 0 vs CTPID at BC=+2;CTPID at BC=0;CTPID at BC=+2',
188 xbins=512, xmin=-0.5, xmax=511.5,
189 ybins=512, ymin=-0.5, ymax=511.5
190 )
191 # 512×512 TAP pair maps
192 mon.defineHistogram(
193 'CTPID0tap_m2,CTPIDtap_m2;PairMap_TAP_DeltaBCm2',
194 path='EXPERT', type='TH2F',
195 title='TAP: CTPID at BC 0 vs CTPID at BC=-2;CTPID at BC=0;CTPID at BC=-2',
196 xbins=512, xmin=-0.5, xmax=511.5, ybins=512, ymin=-0.5, ymax=511.5
197 )
198 mon.defineHistogram(
199 'CTPID0tap_m1,CTPIDtap_m1;PairMap_TAP_DeltaBCm1',
200 path='EXPERT', type='TH2F',
201 title='TAP: CTPID at BC 0 vs CTPID at BC=-1;CTPID at BC=0;CTPID at BC=-1',
202 xbins=512, xmin=-0.5, xmax=511.5, ybins=512, ymin=-0.5, ymax=511.5
203 )
204 mon.defineHistogram(
205 'CTPID0tap_p1,CTPIDtap_p1;PairMap_TAP_DeltaBCp1',
206 path='EXPERT', type='TH2F',
207 title='TAP: CTPID at BC 0 vs CTPID at BC=+1;CTPID at BC=0;CTPID at BC=+1',
208 xbins=512, xmin=-0.5, xmax=511.5, ybins=512, ymin=-0.5, ymax=511.5
209 )
210 mon.defineHistogram(
211 'CTPID0tap_p2,CTPIDtap_p2;PairMap_TAP_DeltaBCp2',
212 path='EXPERT', type='TH2F',
213 title='TAP: CTPID at BC 0 vs CTPID at BC=+2;CTPID at BC=0;CTPID at BC=+2',
214 xbins=512, xmin=-0.5, xmax=511.5, ybins=512, ymin=-0.5, ymax=511.5
215 )
216
217
218 return mon
219
220def L1CorrelationAlgCfg(flags, name='L1CorrelationAlg', **kw):
221 """
222 Factory for L1CorrelationAlg.
223
224 The C++ algorithm scans the full recorded window per event (from l1a_idx).
225 We book monitoring histograms with a fixed range (no job option).
226 """
227
228 # Build and attach the monitoring tool
229 kw.setdefault('MonTool', L1CorrelationMonitoringCfg(flags))
230
231 return CompFactory.L1CorrelationAlg(name, **kw)
232
233
234def ROBPrefetchingAlgCfg(flags, name, regSelDets=[], **kwargs):
235 acc = ComponentAccumulator()
236 alg = CompFactory.ROBPrefetchingAlg(name, **kwargs)
237 alg.RegionSelectorTools = acc.popToolsAndMerge(getRegSelTools(flags, regSelDets))
238 acc.addEventAlgo(alg, primary=True)
239
240 return acc
241
242def ROBPrefetchingAlgCfg_Si(flags, nameSuffix, **kwargs):
243 return ROBPrefetchingAlgCfg(flags, 'ROBPrefetchingAlg_Si_'+nameSuffix, ['Pixel', 'SCT'], **kwargs)
244
245def ROBPrefetchingAlgCfg_Calo(flags, nameSuffix, **kwargs):
246 return ROBPrefetchingAlgCfg(flags, 'ROBPrefetchingAlg_Calo_'+nameSuffix, ['TTEM', 'TTHEC', 'FCALEM', 'FCALHAD', 'TILE'], **kwargs)
247
248def ROBPrefetchingAlgCfg_Muon(flags, nameSuffix, **kwargs):
249 return ROBPrefetchingAlgCfg(flags, 'ROBPrefetchingAlg_Muon_'+nameSuffix, ['MDT', 'RPC', 'TGC', 'CSC', 'MM', 'sTGC'], **kwargs)
250
252 from TrigConfHLTUtils.HLTUtils import string2hash
253 from AthenaCommon.CFElements import getSequenceChildren, isSequence
254 from collections import defaultdict
255 def sequenceAlgs(seq):
256 algs = []
257 for alg in getSequenceChildren(seq):
258 if isSequence(alg):
259 algs.extend(sequenceAlgs(alg))
260 elif alg.getName().startswith('IMEmpty'):
261 # skip empty probe step in tag&probe chains
262 continue
263 else:
264 algs.append(alg.getName())
265
266 return algs
267
268 def firstNonEmptyStepAlgs(CF_list):
269 algsMap = defaultdict(list) # {chainLegName, algsInFirstNonEmptyStep}
270 firstSequence = []
271
272 for cfseq_per_step in CF_list:
273 for cfseq in cfseq_per_step: # all the steps with same step number
274 step = cfseq.sequenceCA.step
275 foundFirstSequence = False
276 for ileg, menuSeq in enumerate(step.sequences):
277 seqA = sequenceAlgs(menuSeq.sequence.Alg)
278 if seqA: # found not empty sequence in this step
279 for stepD, chain in zip(cfseq.stepDicts, cfseq.chains): # loop over chains
280 if chain in firstSequence:
281 continue
282 legName = stepD[ileg]['chainName']
283 if legName not in algsMap: # add only the first time
284 algsMap[legName] = seqA
285 firstSequence.append(chain)
286 foundFirstSequence = True
287
288 if foundFirstSequence:
289 break
290
291 return algsMap
292
293 detGroupIdentifierAlgs = {
294 'Si' : ['PixelRawDataProvider','SCTRawDataProvider'],
295 'Calo' : ['HLTCaloCellMaker','FastCaloL2EgammaAlg'],
296 'Muon' : ['RpcRawDataProvider','TgcRawDataProvider','MdtRawDataProvider','sTgcRawDataProvider','MMRawDataProvider']
297 }
298
299 def algsToDetGroup(algs):
300 groups = []
301 for group,idAlgs in detGroupIdentifierAlgs.items():
302 if any([ida in algName for algName in algs for ida in idAlgs]):
303 groups.append(group)
304 if len(groups)>1:
305 raise RuntimeError(f'Multiple detector groups: {groups:s} matched to the list of algs: {algs:s}')
306 return groups[0] if groups else None
307
308 chainFilterMap = { # {DetGroup, list of chain leg hashes}
309 'Si': [],
310 'Calo': [],
311 'Muon': []
312 }
313
314
315 algsMap = firstNonEmptyStepAlgs(CF_list)
316 for legName,algs in algsMap.items():
317 det = algsToDetGroup(algs)
318 if not det:
319 continue
320 _log.debug("%s initialRoI will prefetch %s", legName, det)
321 chainFilterMap[det].append(string2hash(legName))
322 return chainFilterMap
323
324# Legacy searches for the algs through the top level sequence
326 from AthenaCommon.AlgSequence import AlgSequence
327 from AthenaCommon.CFElements import findSubSequence, findAlgorithm
328 chainFilterMap = getChainsForPrefetching(chains)
329
330 hltBeginSeq = findSubSequence(AlgSequence(), 'HLTBeginSeq')
331 for det,chainFilter in chainFilterMap.items():
332 prefetchAlg = findAlgorithm(hltBeginSeq, f'ROBPrefetchingAlg_{det}_initialRoI')
333 if not chainFilter:
334 # Empty filter means unconditional prefetching
335 # - prevent this by adding a non-existent hash to the list which effectively disables the prefetching alg
336 _log.info('No chains matched to %s - forcing ChainFilter=[0] to disable this alg\'s prefetching', prefetchAlg.getName())
337 chainFilter = [0]
338
339 prefetchAlg.ChainFilter = chainFilter
340
341# In CA we have no access to the HLTBeginSeq in here
342# Instead generate the prefetching alg configs and append the ChainFilter,
343# to be merged into the global config.
344def prefetchingInitialRoIConfig(flags, CFseq_list):
345 chainFilterMap = getChainsForPrefetching(CFseq_list)
346 configurators = {
347 'Si': ROBPrefetchingAlgCfg_Si,
348 'Calo': ROBPrefetchingAlgCfg_Calo,
349 'Muon': ROBPrefetchingAlgCfg_Muon,
350 }
351
352 prefetchCfg = ComponentAccumulator()
353
354 for det,chainFilter in chainFilterMap.items():
355 if not chainFilter:
356 # Empty filter means unconditional prefetching
357 # - prevent this by adding a non-existent hash to the list which effectively disables the prefetching alg
358 _log.info('No chains matched to ROBPrefetchingAlg_%s_initialRoI - forcing ChainFilter=[0] to disable this alg\'s prefetching', det)
359 chainFilter = [0]
360 prefetchAlg = configurators[det](flags, 'initialRoI', ChainFilter=chainFilter)
361 prefetchCfg.merge(prefetchAlg)
362
363 return prefetchCfg
364
365
TrigEventInfoRecorderAlgCfg(flags, name, trigEventInfoKey, decoratePFlowInfo, decorateEMTopoInfo, renounceAll=False, primaryVertexInputName="HLT_IDVertex_FS", RhoKey_PFlow='HLT_Kt4EMPFlowEventShape', RhoKey_EMTopo='HLT_Kt4EMTopoEventShape')
ROBPrefetchingAlgCfg_Si(flags, nameSuffix, **kwargs)
ROBPrefetchingAlgCfg_Muon(flags, nameSuffix, **kwargs)
prefetchingInitialRoIConfig(flags, CFseq_list)
L1CorrelationAlgCfg(flags, name='L1CorrelationAlg', **kw)
ROBPrefetchingAlgCfg_Calo(flags, nameSuffix, **kwargs)
TimeBurnerCfg(flags, name="TimeBurner", **kwargs)
ROBPrefetchingAlgCfg(flags, name, regSelDets=[], **kwargs)