ATLAS Offline Software
TrigGenericAlgsConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
4 from AthenaConfiguration.ComponentFactory import CompFactory
5 from TrigPartialEventBuilding.TrigPartialEventBuildingConfig import getRegSelTools
6 from AthenaCommon.Logging import logging
7 _log = logging.getLogger( __name__ )
8 
9 
10 def TimeBurnerCfg(flags, name="TimeBurner", **kwargs):
11  return CompFactory.TimeBurner(name, **kwargs)
12 
13 def 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 
21 def EndOfEventFilterAlgCfg(name, chainName):
22  return CompFactory.EndOfEventFilterAlg(name, ChainName=chainName)
23 
24 def 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 
220 def 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 
234 def 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 
242 def ROBPrefetchingAlgCfg_Si(flags, nameSuffix, **kwargs):
243  return ROBPrefetchingAlgCfg(flags, 'ROBPrefetchingAlg_Si_'+nameSuffix, ['Pixel', 'SCT'], **kwargs)
244 
245 def ROBPrefetchingAlgCfg_Calo(flags, nameSuffix, **kwargs):
246  return ROBPrefetchingAlgCfg(flags, 'ROBPrefetchingAlg_Calo_'+nameSuffix, ['TTEM', 'TTHEC', 'FCALEM', 'FCALHAD', 'TILE'], **kwargs)
247 
248 def 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.
344 def 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 
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
python.TrigGenericAlgsConfig.ROBPrefetchingAlgCfg_Muon
def ROBPrefetchingAlgCfg_Muon(flags, nameSuffix, **kwargs)
Definition: TrigGenericAlgsConfig.py:248
python.AlgSequence.AlgSequence
AlgSequence
Definition: PhysicsAnalysis/D3PDTools/AnaAlgorithm/python/AlgSequence.py:7
python.TrigGenericAlgsConfig.L1CorrelationMonitoringCfg
def L1CorrelationMonitoringCfg(flags)
Definition: TrigGenericAlgsConfig.py:39
TrigPartialEventBuildingConfig.getRegSelTools
def getRegSelTools(flags, detNames)
Definition: TrigPartialEventBuildingConfig.py:14
GenericMonitoringTool
Definition: GenericMonitoringTool.h:51
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.TrigGenericAlgsConfig.ROBPrefetchingAlgCfg_Calo
def ROBPrefetchingAlgCfg_Calo(flags, nameSuffix, **kwargs)
Definition: TrigGenericAlgsConfig.py:245
python.TrigGenericAlgsConfig.getChainsForPrefetching
def getChainsForPrefetching(CF_list)
Definition: TrigGenericAlgsConfig.py:251
python.TrigGenericAlgsConfig.configurePrefetchingInitialRoI
def configurePrefetchingInitialRoI(flags, chains)
Definition: TrigGenericAlgsConfig.py:325
python.TrigGenericAlgsConfig.ROBPrefetchingAlgCfg
def ROBPrefetchingAlgCfg(flags, name, regSelDets=[], **kwargs)
Definition: TrigGenericAlgsConfig.py:234
python.TrigGenericAlgsConfig.TimeBurnerHypoToolGen
def TimeBurnerHypoToolGen(flags, chainDict)
Definition: TrigGenericAlgsConfig.py:13
python.TrigGenericAlgsConfig.TrigEventInfoRecorderAlgCfg
def TrigEventInfoRecorderAlgCfg(flags, name, trigEventInfoKey, decoratePFlowInfo, decorateEMTopoInfo, renounceAll=False, primaryVertexInputName="HLT_IDVertex_FS", RhoKey_PFlow='HLT_Kt4EMPFlowEventShape', RhoKey_EMTopo='HLT_Kt4EMTopoEventShape')
Definition: TrigGenericAlgsConfig.py:24
python.TrigGenericAlgsConfig.ROBPrefetchingAlgCfg_Si
def ROBPrefetchingAlgCfg_Si(flags, nameSuffix, **kwargs)
Definition: TrigGenericAlgsConfig.py:242
python.TrigGenericAlgsConfig.L1CorrelationAlgCfg
def L1CorrelationAlgCfg(flags, name='L1CorrelationAlg', **kw)
Definition: TrigGenericAlgsConfig.py:220
python.TrigGenericAlgsConfig.prefetchingInitialRoIConfig
def prefetchingInitialRoIConfig(flags, CFseq_list)
Definition: TrigGenericAlgsConfig.py:344
HLTUtils.string2hash
def string2hash(string)
Definition: HLTUtils.py:5
python.CFElements.isSequence
def isSequence(obj)
Definition: CFElements.py:74
python.CFElements.findSubSequence
def findSubSequence(start, nameToLookFor)
Definition: CFElements.py:78
python.TrigGenericAlgsConfig.EndOfEventROIConfirmerAlgCfg
def EndOfEventROIConfirmerAlgCfg(name)
Definition: TrigGenericAlgsConfig.py:18
python.CFElements.findAlgorithm
def findAlgorithm(startSequence, nameToLookFor, depth=1000000)
Definition: CFElements.py:123
python.CFElements.getSequenceChildren
def getSequenceChildren(comp)
Definition: CFElements.py:48
python.TrigGenericAlgsConfig.TimeBurnerCfg
def TimeBurnerCfg(flags, name="TimeBurner", **kwargs)
Definition: TrigGenericAlgsConfig.py:10
python.TrigGenericAlgsConfig.EndOfEventFilterAlgCfg
def EndOfEventFilterAlgCfg(name, chainName)
Definition: TrigGenericAlgsConfig.py:21