ATLAS Offline Software
Loading...
Searching...
No Matches
JetMenuSequencesConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2#
3
4from enum import Enum
5from TriggerMenuMT.HLT.Config.MenuComponents import MenuSequence, SelectionCA, InEventRecoCA
6from AthenaConfiguration.ComponentFactory import CompFactory
7from AthenaConfiguration.AccumulatorCache import AccumulatorCache
8from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
9
10from ..CommonSequences.FullScanDefs import trkFSRoI, fs_towers
11from ..Config.MenuComponents import parOR
12from .JetRecoCommon import jetDefToString, jetCalibFromJetDef
13from TrigEDMConfig.TriggerEDM import recordable
14
15# Hypo tool generators
16from TrigHLTJetHypo.TrigJetHypoToolConfig import trigJetHypoToolFromDict
17from .JetPresel import caloPreselJetHypoToolFromDict, roiPreselJetHypoToolFromDict
18from TrigCaloRec.TrigCaloRecConfig import jetmetTopoClusteringCfg, jetmetTopoClusteringCfg_LC, HICaloTowerCfg
19from AthenaConfiguration.AthConfigFlags import AthConfigFlags
20from TrigGenericAlgs.TrigGenericAlgsConfig import TrigEventInfoRecorderAlgCfg
21
22from AthenaCommon.Logging import logging
23logging.getLogger().info("Importing %s",__name__)
24log = logging.getLogger(__name__)
25
26
28
29# For step 1, starting from the basic calo reco and topoclustering
30# Used for calo-only chains and preselection for tracking
32 from TrigT2CaloCommon.CaloDef import clusterFSInputMaker
33 InputMakerAlg = clusterFSInputMaker()
34 return InputMakerAlg
35
36# For later steps, where calo reco should not be run
37# The same instance of an algorithm cannot be run in different steps
38# Used for chains that use tracking
39def getTrackingInputMaker(flags : AthConfigFlags, trkopt : str):
40 if trkopt=="ftf":
41 log.debug( "jet FS tracking: useDynamicRoiZWidth: %s", flags.Trigger.InDetTracking.fullScan.useDynamicRoiZWidth )
42
43 roiUpdater = None
44 if flags.Trigger.InDetTracking.fullScan.useDynamicRoiZWidth:
45 roiUpdater = CompFactory.RoiUpdaterTool( useBeamSpot=True )
46
47 log.info( roiUpdater )
48
49 InputMakerAlg = CompFactory.InputMakerForRoI(
50 "IM_Jet_TrackingStep",
51 mergeUsingFeature = False,
52 RoITool = CompFactory.ViewCreatorFSROITool(
53 name="RoiTool_FS",
54 RoiUpdater=roiUpdater,
55 RoisWriteHandleKey=recordable( flags.Trigger.InDetTracking.fullScan.roi )
56 ),
57 RoIs = trkFSRoI,
58 )
59 else:
60 InputMakerAlg = CompFactory.InputMakerForRoI(
61 "IM_Jet_TrackingStep",
62 mergeUsingFeature = False,
63 RoITool = CompFactory.ViewCreatorInitialROITool(),
64 RoIs = trkFSRoI,
65 )
66
67 elif trkopt=="roiftf":
68 InputMakerAlg = CompFactory.EventViewCreatorAlgorithm(
69 "IMJetRoIFTF",
70 mergeUsingFeature = False,
71 RoITool = CompFactory.ViewCreatorJetSuperROITool(
72 'ViewCreatorJetSuperRoI',
73 RoisWriteHandleKey = recordable( flags.Trigger.InDetTracking.jetSuper.roi ),
74 RoIEtaWidth = flags.Trigger.InDetTracking.jetSuper.etaHalfWidth,
75 RoIPhiWidth = flags.Trigger.InDetTracking.jetSuper.phiHalfWidth,
76 RoIZWidth = flags.Trigger.InDetTracking.jetSuper.zedHalfWidth,
77 ),
78 Views = "JetSuperRoIViews",
79 InViewRoIs = "InViewRoIs",
80 RequireParentView = False,
81 ViewFallThrough = True,
82 )
83 else:
84 raise RuntimeError(f"Unrecognised trkopt '{trkopt}' provided, choices are ['ftf','roiftf']")
85 return InputMakerAlg
86
87
89
90# Functions defining the MenuSequence that will be placed into ChainSteps
91# Generate a menu sequence given a set of jet sequences to schedule.
92# The hypo may be set up as a preselection hypo, in which case it will
93# record a single DecisionObject, instead of one per jet.
94# A hypo may alternatively be configured to passThrough, such that
95# the hypo will not retrieve any jets and simply pass.
96#
97# In these functions, we:
98# - First generate the data dependencies for the full jet reco sequence.
99# These come in the form of a dict of JetDefinitions, which are
100# used to define inter-step data dependencies (cluster collections etc).
101# The JetDef is accompanied by a final jet collection name, which is
102# filtered into a vew container to accelerate the hypo
103# - Then pass the JetDefinitions into the configurator functions,
104# which return ComponentAccumulator.
105# - When ChainSteps are created by JetChainConfiguration.getStep,
106# the MenuSequence generators will be wrapped in a deferred call
107# so that when constructing the full HLT menu, we don't regenerate
108# identical sequence configurations repeatedly.
109
110class JetHypoAlgType(Enum):
111 STANDARD = 0
112 CALOPRESEL = 1
113 ROIPRESEL = 2
114 PASSTHROUGH = 3
115
116def jetSelectionCfg(flags, jetDefStr, jetsIn, hypoType=JetHypoAlgType.STANDARD):
117 """constructs CA with hypo alg given arguments """
118 if hypoType==JetHypoAlgType.PASSTHROUGH:
119 hyponame = f"TrigStreamerHypoAlg_{jetDefStr}_passthrough"
120 hypo = CompFactory.TrigStreamerHypoAlg(hyponame)
121 else:
122 assert jetsIn is not None
123 if hypoType==JetHypoAlgType.CALOPRESEL:
124 hyponame = f"TrigJetHypoAlg_{jetDefStr}_calopresel"
125 hypo = CompFactory.TrigJetHypoAlg(hyponame, Jets=jetsIn, DoPresel=True)
126 elif hypoType==JetHypoAlgType.ROIPRESEL:
127 hyponame = f"TrigJetHypoAlg_{jetDefStr}_roipresel"
128 hypo = CompFactory.TrigJetHypoAlg(hyponame, Jets=jetsIn, DoPresel=True)
129 else:
130 hyponame = f"TrigJetHypoAlg_{jetDefStr}"
131 hypo = CompFactory.TrigJetHypoAlg(hyponame, Jets=jetsIn)
132 ca = ComponentAccumulator()
133 ca.addEventAlgo(hypo)
134 return ca
135
136def selName(recoSequenceName, hypoType=JetHypoAlgType.STANDARD):
137 """Construct selection (the name passed to SelectionCA) given reco sequence and hypo type"""
138 selname = recoSequenceName.replace('RecoSequence','MenuSequence')
139 if hypoType==JetHypoAlgType.PASSTHROUGH:
140 selname += "_passthrough"
141 else:
142 if hypoType==JetHypoAlgType.CALOPRESEL:
143 selname += "_calopresel"
144 elif hypoType==JetHypoAlgType.ROIPRESEL:
145 selname += "_roipresel"
146 return selname
147
148
149def hypoToolGenerator(hypoType):
150 """returns function (that in turn returns hypo tool) for menu sequence"""
151 def trigStreamerHypoTool(flags, chainDict):
152 return CompFactory.TrigStreamerHypoTool(chainDict["chainName"])
153 return {
154 JetHypoAlgType.STANDARD: trigJetHypoToolFromDict,
155 JetHypoAlgType.PASSTHROUGH: trigStreamerHypoTool,
156 JetHypoAlgType.CALOPRESEL: caloPreselJetHypoToolFromDict,
157 JetHypoAlgType.ROIPRESEL: roiPreselJetHypoToolFromDict,
158 }[hypoType]
159
160
161
162
164
165# For the preselection step before running tracking (step 1)
166# We set RoIs='' (recognised as seedless) instead of caloFSRoI (output of caloInputMater()) to
167# cut data dependency to InputMaker and allow full scan CaloCell+Clustering to be
168# shared with EGamma (ATR-24722)
169@AccumulatorCache
170def jetCaloPreselMenuSequenceGenCfg(flags, **jetDefDict):
171 jetsOut, jetDef = jetDefDict['final']
172 jetDefStr = jetDefToString(jetDef)
173 reco = InEventRecoCA(f"jetSeqCaloPresel_{jetDefStr}_RecoSequence", inputMaker=getCaloInputMaker())
174
175 if 'LC' in jetDef.inputdef.label:
176 reco.mergeReco(jetmetTopoClusteringCfg_LC(flags, RoIs=''))
177 else:
178 reco.mergeReco(jetmetTopoClusteringCfg(flags, RoIs=''))
179
180 from .JetRecoSequencesConfig import JetRecoCfg
181 jetreco = JetRecoCfg(flags, **jetDefDict)
182 reco.mergeReco(jetreco)
183
184 log.debug("Generating jet preselection menu sequence for reco %s",jetDef.fullname())
185 selAcc = SelectionCA(selName(reco.name, hypoType=JetHypoAlgType.CALOPRESEL))
186 selAcc.mergeReco(reco)
187 selAcc.mergeHypo(jetSelectionCfg(flags, jetDefStr=jetDefStr, jetsIn=jetsOut, hypoType=JetHypoAlgType.CALOPRESEL))
188
189 return MenuSequence(flags, selAcc, HypoToolGen=hypoToolGenerator(hypoType=JetHypoAlgType.CALOPRESEL))
190
191# A null preselection, which will only run the cluster making (step 1)
192# We set RoIs='' for same reason as described for jetCaloPreselMenuSequence
193@AccumulatorCache
194def jetCaloRecoMenuSequenceGenCfg(flags, clusterCalib):
195 reco = InEventRecoCA(f"jetSeqCaloReco_{clusterCalib}_RecoSequence", inputMaker=getCaloInputMaker())
196
197 if clusterCalib=='lcw':
198 reco.mergeReco(jetmetTopoClusteringCfg_LC(flags, RoIs=''))
199 else:
200 reco.mergeReco(jetmetTopoClusteringCfg(flags, RoIs=''))
201
202 selAcc = SelectionCA(selName(reco.name, hypoType=JetHypoAlgType.PASSTHROUGH))
203 selAcc.mergeReco(reco)
204 selAcc.mergeHypo(jetSelectionCfg(flags, jetDefStr="caloreco", jetsIn=None, hypoType=JetHypoAlgType.PASSTHROUGH))
205
206 return MenuSequence(flags, selAcc, HypoToolGen=hypoToolGenerator(hypoType=JetHypoAlgType.PASSTHROUGH))
207
208
209# A full hypo selecting only on calo jets (step 1)
210# Passing isPerf = True disables the hypo
211# We set RoIs='' for same reason as described for jetCaloPreselMenuSequence
212@AccumulatorCache
213def jetCaloHypoMenuSequenceGenCfg(flags, isPerf, **jetDefDict):
214 jetsOut, jetDef = jetDefDict['final']
215 jetDefStr = jetDefToString(jetDef)
216 reco = InEventRecoCA(f"jetSeqCaloHypo_{jetDefStr}{'_perf' if isPerf else ''}_RecoSequence", inputMaker=getCaloInputMaker())
217
218 if 'LC' in jetDef.inputdef.label:
219 reco.mergeReco(jetmetTopoClusteringCfg_LC(flags, RoIs=''))
220 else:
221 reco.mergeReco(jetmetTopoClusteringCfg(flags, RoIs=''))
222
223 from .JetRecoSequencesConfig import JetRecoCfg
224 jetreco = JetRecoCfg(flags, **jetDefDict)
225 reco.mergeReco(jetreco)
226 log.debug("Generating jet calo hypo menu sequence for reco %s",jetDef.fullname())
227
228 hypoType = JetHypoAlgType.PASSTHROUGH if isPerf else JetHypoAlgType.STANDARD
229 selAcc = SelectionCA(selName(reco.name, hypoType=hypoType))
230 selAcc.mergeReco(reco)
231 selAcc.mergeHypo(jetSelectionCfg(flags, jetDefStr=jetDefStr, jetsIn=jetsOut, hypoType=hypoType))
232
233 return MenuSequence(flags, selAcc, HypoToolGen=hypoToolGenerator(hypoType))
234
235
236# A full hypo selecting only on heavy ion calo jets (step 1)
237# Passing isPerf = True disables the hypo
238# We set RoIs='' for same reason as described for jetCaloPreselMenuSequence
239@AccumulatorCache
240def jetHICaloHypoMenuSequenceGenCfg(flags, isPerf, **jetRecoDict):
241 reco = InEventRecoCA(f"jetSeqHICaloHypo_{jetRecoDict['jetDefStr']}{'_perf' if isPerf else ''}_RecoSequence", inputMaker=getCaloInputMaker())
242
243 reco.mergeReco( HICaloTowerCfg(flags) )
244
245 from .JetHIConfig import jetHIRecoSequenceCA
246 jetreco, jetsOut, jetDef = jetHIRecoSequenceCA(flags, clustersKey="HLT_HICaloClustersFS",towerKey = fs_towers, **jetRecoDict)
247 reco.mergeReco(jetreco)
248 log.debug("Generating jet HI calo hypo menu sequence for reco %s",jetDef.fullname())
249 hypoType = JetHypoAlgType.PASSTHROUGH if isPerf else JetHypoAlgType.STANDARD
250 selAcc = SelectionCA(selName(reco.name, hypoType=hypoType))
251 selAcc.mergeReco(reco)
252 selAcc.mergeHypo(jetSelectionCfg(flags, jetDefStr=jetRecoDict['jetDefStr'], jetsIn=jetsOut, hypoType=hypoType))
253
254 return MenuSequence(flags, selAcc, HypoToolGen=hypoToolGenerator(hypoType))
255
256
257# A full hypo selecting on jets with FS track reco (step 2)
258# To combine either with a presel or a passthrough sequence
259@AccumulatorCache
260def jetFSTrackingHypoMenuSequenceGenCfg(flags, isPerf, **jetDefDict):
261 jetsOut, jetDef = jetDefDict['final']
262 jetDefStr = jetDefToString(jetDef)
263 trkopt = jetDef.context
264 reco = InEventRecoCA(f"jetFSTrackingHypo_{jetDefStr}{'_perf' if isPerf else ''}_RecoSequence", inputMaker=getTrackingInputMaker(flags,trkopt))
265
266 assert trkopt != "notrk"
267 from .JetTrackingConfig import JetFSTrackingCfg
268 trk_acc = JetFSTrackingCfg(flags, trkopt, trkFSRoI)
269 reco.mergeReco(trk_acc)
270
271 from .JetRecoSequencesConfig import JetRecoCfg
272 jetreco = JetRecoCfg(flags, **jetDefDict)
273 reco.mergeReco(jetreco)
274 log.debug("Generating jet tracking hypo menu sequence for reco %s",jetDef.fullname())
275
276 if 'PFlow' in jetDef.basename and jetDef.basename.startswith('AntiKt4') and 'sub' in jetCalibFromJetDef(jetDef):
277 pvKey = flags.Trigger.InDetTracking.fullScan.vertex_jet
278 trig_evt_info_key = recordable("HLT_TCEventInfo_jet")
279
280 # Can encapsulate in another CA if necessary but only this instance
281 # currently needed
282 reco.mergeReco(
283 TrigEventInfoRecorderAlgCfg(
284 flags,
285 name="TrigEventInfoRecorderAlg_jet",
286 decoratePFlowInfo=True,
287 decorateEMTopoInfo=False,
288 trigEventInfoKey=trig_evt_info_key, primaryVertexInputName=pvKey,
289 RhoKey_EMTopo='HLT_Kt4EMTopoEventShape', RhoKey_PFlow='HLT_Kt4EMPFlowEventShape'
290 )
291 )
292
293 hypoType = JetHypoAlgType.PASSTHROUGH if isPerf else JetHypoAlgType.STANDARD
294 selAcc = SelectionCA(selName(reco.name, hypoType=hypoType))
295 selAcc.mergeReco(reco)
296 selAcc.mergeHypo(jetSelectionCfg(flags, jetDefStr=jetDefStr, jetsIn=jetsOut, hypoType=hypoType))
297
298 return MenuSequence(flags, selAcc, HypoToolGen=hypoToolGenerator(hypoType))
299
300
301# A full hypo selecting on jets with RoI track reco (step 2)
302# Needs to be preceded by a presel sequence, and be provided
303# with the input jets from which to define RoIs
304# Presel jets to be reused, which makes ghost association impossible
305# Substitute DR association decorator
306@AccumulatorCache
307def jetRoITrackJetTagSelCfg(flags, preselJetDef, isPresel=True):
308 # Seems odd, but we have to combine event and view execution here
309 # where InViewRecoCA will do all in view
310 jetDefStr = jetDefToString(preselJetDef)+'_roiftf'
311 trkopt = 'roiftf'
312 reco = InEventRecoCA(
313 f"jetRoITrackJetTagHypo_{jetDefStr}_RecoSequence",
314 inputMaker=getTrackingInputMaker(flags,trkopt)
315 )
316
317 # Add to top-level serial sequence after IM
318 from TrigGenericAlgs.TrigGenericAlgsConfig import ROBPrefetchingAlgCfg_Si
319 reco.mergeReco(ROBPrefetchingAlgCfg_Si(flags, nameSuffix=reco.inputMaker().name))
320
321 # Decorate EventInfo with online beamspot info in global context -- avoid multiple executes
322 from ..Bjet.BjetFlavourTaggingConfig import OnlineBeamspotAugmenterCfg
323 reco.mergeReco(OnlineBeamspotAugmenterCfg(flags))
324
325 # Add to top-level serial sequence to ensure it is ready for in-view reco
326 from .JetRecoSequencesConfig import (
327 FastFtaggedJetCopyAlgCfg, JetRoITrackJetTagSequenceCfg, JetViewAlgCfg, formatFilteredJetsName, JET_DEFAULT_VIEW_PT_MIN_GEV
328 )
329 ftagjet_acc, ftaggedJetDef = FastFtaggedJetCopyAlgCfg(flags,preselJetDef)
330 ftaggedJetName = recordable(ftaggedJetDef.fullname())
331 reco.mergeReco(ftagjet_acc)
332
333 track_acc = JetRoITrackJetTagSequenceCfg(
334 flags,
335 ftaggedJetName,
336 trkopt,
337 RoIs=reco.inputMaker().InViewRoIs)
338 # Explicitly add the sequence here that is to run in the super-RoI view
339 seqname = f"JetRoITrackJetTag_{trkopt}_RecoSequence"
340 reco.addSequence(parOR(seqname),primary=True)
341 verifier = CompFactory.AthViews.ViewDataVerifier("roiftf_ftag_ViewDataVerifier")
342 verifier.DataObjects = [
343 ('SG::AuxElement',f'EventInfo.{dec}')
344 for dec in ['onlineBeamPosSigmaXY','onlineBeamPosX','onlineBeamPosY','onlineBeamPosZ']
345 ]
346 reco.addEventAlgo(verifier,seqname)
347 reco.merge(track_acc,seqname)
348 reco.inputMaker().ViewNodeName = seqname
349
350 # Run the JetViewAlg sequence to filter out low pT jets
351 # Have to run it outside of JetRoITrackJetTagSequence (which runs in EventView), so that hypo recognises the filtered jets.
352 jetview_Acc = JetViewAlgCfg(flags,jetDef=ftaggedJetDef)
353 filtered_jetsIn = formatFilteredJetsName(ftaggedJetName,JET_DEFAULT_VIEW_PT_MIN_GEV)
354 reco.merge(jetview_Acc)
355
356 # Needs track-to-jet association here, maybe with dR decorator
357 hypoType = JetHypoAlgType.ROIPRESEL if isPresel else JetHypoAlgType.STANDARD
358 selAcc = SelectionCA(selName(reco.name, hypoType=hypoType))
359 selAcc.mergeReco(reco)
360 selAcc.mergeHypo(jetSelectionCfg(flags, jetDefStr=jetDefStr, jetsIn=filtered_jetsIn, hypoType=hypoType))
361 return selAcc, hypoType
362
363def jetRoITrackJetTagHypoMenuSequenceGenCfg(flags, jetDef, isPresel=True):
364 selAcc, hypoType = jetRoITrackJetTagSelCfg(flags, jetDef, isPresel)
365 return MenuSequence(flags, selAcc, HypoToolGen=hypoToolGenerator(hypoType))
366
jetFSTrackingHypoMenuSequenceGenCfg(flags, isPerf, **jetDefDict)
selName(recoSequenceName, hypoType=JetHypoAlgType.STANDARD)
jetRoITrackJetTagHypoMenuSequenceGenCfg(flags, jetDef, isPresel=True)
jetHICaloHypoMenuSequenceGenCfg(flags, isPerf, **jetRecoDict)
jetSelectionCfg(flags, jetDefStr, jetsIn, hypoType=JetHypoAlgType.STANDARD)
jetCaloPreselMenuSequenceGenCfg(flags, **jetDefDict)
— Menu Sequence getters —
jetRoITrackJetTagSelCfg(flags, preselJetDef, isPresel=True)
jetCaloHypoMenuSequenceGenCfg(flags, isPerf, **jetDefDict)
getTrackingInputMaker(AthConfigFlags flags, str trkopt)