ATLAS Offline Software
Loading...
Searching...
No Matches
PFCfg.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2from AthenaConfiguration.ComponentFactory import CompFactory
3from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
4from AthenaConfiguration.Enums import LHCPeriod
5
6def PFTrackSelectorAlgCfg(inputFlags,algName,useCaching=True):
7 PFTrackSelectorFactory=CompFactory.PFTrackSelector
8 PFTrackSelector=PFTrackSelectorFactory(algName)
9
10 result = ComponentAccumulator()
11
12 from TrackToCalo.TrackToCaloConfig import ParticleCaloExtensionToolCfg
13 pcExtensionTool = result.popToolsAndMerge(ParticleCaloExtensionToolCfg(inputFlags))
14
15 eflowTrackCaloExtensionTool=CompFactory.eflowTrackCaloExtensionTool
16 TrackCaloExtensionTool=eflowTrackCaloExtensionTool(TrackCaloExtensionTool=pcExtensionTool)
17 if (not useCaching):
18 TrackCaloExtensionTool.PFParticleCache = ""
19
20 PFTrackSelector.trackExtrapolatorTool = TrackCaloExtensionTool
21
22 from InDetTrackSelectionTool.InDetTrackSelectionToolConfig import (
23 PFTrackSelectionToolCfg)
24 PFTrackSelector.trackSelectionTool = result.popToolsAndMerge(PFTrackSelectionToolCfg(inputFlags))
25
26 # P->T conversion extra dependencies
27 if inputFlags.Detector.GeometryITk:
28 PFTrackSelector.ExtraInputs = {
29 ("InDetDD::SiDetectorElementCollection", "ConditionStore+ITkPixelDetectorElementCollection"),
30 ("InDetDD::SiDetectorElementCollection", "ConditionStore+ITkStripDetectorElementCollection"),
31 }
32 else:
33 PFTrackSelector.ExtraInputs = {
34 ("InDetDD::SiDetectorElementCollection", "ConditionStore+PixelDetectorElementCollection"),
35 ("InDetDD::SiDetectorElementCollection", "ConditionStore+SCT_DetectorElementCollection"),
36 ("InDetDD::TRT_DetElementContainer", "ConditionStore+TRT_DetElementContainer"),
37 }
38
39 result.addEventAlgo (PFTrackSelector, primary=True)
40
41 return result
42
43def getPFClusterSelectorTool(inputFlags,clustersin,calclustersin,algName):
44
45 PFClusterSelectorToolFactory = CompFactory.PFClusterSelectorTool
46 PFClusterSelectorTool = PFClusterSelectorToolFactory(algName)
47 if clustersin is not None:
48 PFClusterSelectorTool.clustersName = clustersin
49 if calclustersin is not None:
50 PFClusterSelectorTool.calClustersName = calclustersin
51
52 if inputFlags.PF.useTruthCheating:
53 if inputFlags.PF.useTrackClusterTruthMatching:
54 PFClusterSelectorTool.CaloClusterReadDecorHandleKey_NLeadingTruthParticles = "CaloTopoClusters." + inputFlags.Calo.TopoCluster.CalibrationHitDecorationName
55
56 if inputFlags.PF.useTopoTowers:
57 PFClusterSelectorTool.clustersName="CaloTopoSignal"
58 PFClusterSelectorTool.calClustersName="CaloCalTopoSignal"
59
60 return PFClusterSelectorTool
61
62def getPFTrackClusterMatchingTool(inputFlags,matchCut,distanceType,clusterPositionType,name):
63 PFTrackClusterMatchingTool = CompFactory.PFTrackClusterMatchingTool
64 MatchingTool = PFTrackClusterMatchingTool(name)
65 MatchingTool.ClusterPositionType = clusterPositionType
66 MatchingTool.DistanceType = distanceType
67 MatchingTool.MatchCut = matchCut*matchCut
68 return MatchingTool
69
70
71def getPFCellLevelSubtractionTool(inputFlags,toolName):
72 PFCellLevelSubtractionToolFactory = CompFactory.PFSubtractionTool
73 PFCellLevelSubtractionTool = PFCellLevelSubtractionToolFactory(toolName,useNNEnergy = inputFlags.PF.useMLEOverP)
74
75 if inputFlags.GeoModel.Run <= LHCPeriod.Run3:
76 eflowCellEOverPTool_Run2_mc20_JetETMiss = CompFactory.eflowCellEOverPTool_Run2_mc20_JetETMiss
77 PFCellLevelSubtractionTool.eflowCellEOverPTool = eflowCellEOverPTool_Run2_mc20_JetETMiss()
78 else:
79 if inputFlags.PF.useLegacyEOverPRun4:
80 eflowCellEOverPTool_mc12_HLLHC = CompFactory.eflowCellEOverPTool_mc12_HLLHC
81 PFCellLevelSubtractionTool.eflowCellEOverPTool = eflowCellEOverPTool_mc12_HLLHC ()
82 else:
83 PFCellEOverPTool = CompFactory.PFCellEOverPTool
84 PFCellLevelSubtractionTool.eflowCellEOverPTool = PFCellEOverPTool("PFCellEOverPTool", referenceFileLocation = inputFlags.PF.EOverP_CellOrdering_ReferenceLocation)
85 #this should always be false for any reference derived, except eflowCellEOverPTool_mc12_HLLHC.h or eflowCellEOverPTool_Run2_mc20_JetETMiss.h
86 PFCellLevelSubtractionTool.useLegacyEBinIndex=False
87
88 if(inputFlags.PF.EOverPMode):
89 PFCellLevelSubtractionTool.CalcEOverP = True
90 PFCellLevelSubtractionTool.nClusterMatchesToUse = -1
91 else:
92 PFCellLevelSubtractionTool.nClusterMatchesToUse = 1
93
94 if(inputFlags.PF.EOverPMode):
95 PFCellLevelSubtractionTool.PFTrackClusterMatchingTool = getPFTrackClusterMatchingTool(inputFlags,0.2,"EtaPhiSquareDistance","PlainEtaPhi","CalObjBldMatchingTool")
96 else:
97 PFCellLevelSubtractionTool.PFTrackClusterMatchingTool = getPFTrackClusterMatchingTool(inputFlags,1.64,"EtaPhiSquareSignificance","GeomCenterEtaPhi","CalObjBldMatchingTool")
98
99 PFCellLevelSubtractionTool.PFTrackClusterMatchingTool_015 = getPFTrackClusterMatchingTool(inputFlags,0.15,"EtaPhiSquareDistance","PlainEtaPhi","MatchingTool_Pull_015")
100 PFCellLevelSubtractionTool.PFTrackClusterMatchingTool_02 = getPFTrackClusterMatchingTool(inputFlags,0.2,"EtaPhiSquareDistance","PlainEtaPhi","MatchingTool_Pull_02")
101
102 if inputFlags.PF.useMLEOverP:
103 PFEnergyPredictorTool = CompFactory.PFEnergyPredictorTool("PFCellLevelEnergyPredcictorTool",ModelPath = inputFlags.PF.EOverP_NN_Model)
104 PFCellLevelSubtractionTool.NNEnergyPredictorTool = PFEnergyPredictorTool
105 PFCellLevelSubtractionTool.addCPData = inputFlags.PF.addCPData
106
107 if inputFlags.PF.useTruthCheating:
108 if inputFlags.PF.useTrackClusterTruthMatching:
109 PFCellLevelSubtractionTool.CaloClusterReadDecorHandleKey_NLeadingTruthParticles = "CaloTopoClusters." + inputFlags.Calo.TopoCluster.CalibrationHitDecorationName
110 PFCellLevelSubtractionTool.useTrackClusterTruthMatching=True
111
112 if inputFlags.PF.useTruthForChargedShowerSubtraction:
113 PFCellLevelSubtractionTool.useTruthForChargedShowerSubtraction = True
114 PFCellLevelSubtractionTool.PFSimulateTruthShowerTool = CompFactory.PFSimulateTruthShowerTool("PFSimulateTruthShowerTool")
115
116 return PFCellLevelSubtractionTool
117
118def getPFRecoverSplitShowersTool(inputFlags,toolName):
119 PFRecoverSplitShowersToolFactory = CompFactory.PFSubtractionTool
120 PFRecoverSplitShowersTool = PFRecoverSplitShowersToolFactory(toolName,useNNEnergy = inputFlags.PF.useMLEOverP)
121
122 if inputFlags.GeoModel.Run <= LHCPeriod.Run3:
123 eflowCellEOverPTool_Run2_mc20_JetETMiss = CompFactory.eflowCellEOverPTool_Run2_mc20_JetETMiss
124 PFRecoverSplitShowersTool.eflowCellEOverPTool = eflowCellEOverPTool_Run2_mc20_JetETMiss("eflowCellEOverPTool_Run2_mc20_JetETMiss_Recover")
125 else:
126 if inputFlags.PF.useLegacyEOverPRun4:
127 eflowCellEOverPTool_mc12_HLLHC = CompFactory.eflowCellEOverPTool_mc12_HLLHC
128 PFRecoverSplitShowersTool.eflowCellEOverPTool = eflowCellEOverPTool_mc12_HLLHC ()
129 else:
130 PFCellEOverPTool = CompFactory.PFCellEOverPTool
131 PFRecoverSplitShowersTool.eflowCellEOverPTool = PFCellEOverPTool("PFCellEOverPTool_Recover", referenceFileLocation = inputFlags.PF.EOverP_CellOrdering_ReferenceLocation)
132 #this should always be false for any reference derived, except eflowCellEOverPTool_mc12_HLLHC.h or eflowCellEOverPTool_Run2_mc20_JetETMiss.h
133 PFRecoverSplitShowersTool.useLegacyEBinIndex=False
134
135 PFRecoverSplitShowersTool.RecoverSplitShowers = True
136
137 if inputFlags.PF.useMLEOverP:
138 PFEnergyPredictorTool = CompFactory.PFEnergyPredictorTool("PFRecoverSplitShowersEnergyPredcictorTool",ModelPath = inputFlags.PF.EOverP_NN_Model)
139 PFRecoverSplitShowersTool.NNEnergyPredictorTool = PFEnergyPredictorTool
140
141 return PFRecoverSplitShowersTool
142
143def getPFMomentCalculatorTool(inputFlags, momentsToCalculateList):
144 result=ComponentAccumulator()
145 PFMomentCalculatorToolFactory = CompFactory.PFMomentCalculatorTool
146 PFMomentCalculatorTool = PFMomentCalculatorToolFactory("PFMomentCalculatorTool")
147
148 from CaloRec.CaloTopoClusterConfig import getTopoMoments
149 PFClusterMomentsMaker = result.popToolsAndMerge(getTopoMoments(inputFlags))
150 if (len(momentsToCalculateList) > 0):
151 PFClusterMomentsMaker.MomentsNames = momentsToCalculateList
152 PFMomentCalculatorTool.CaloClusterMomentsMaker = PFClusterMomentsMaker
153
154 PFClusterCollectionTool = CompFactory.PFClusterCollectionTool
155 PFMomentCalculatorTool.PFClusterCollectionTool = PFClusterCollectionTool("PFClusterCollectionTool")
156
157 if(inputFlags.PF.useCalibHitTruthClusterMoments):
158 PFMomentCalculatorTool.UseCalibHitTruth=True
159 from CaloRec.CaloTopoClusterConfig import getTopoCalibMoments
160 PFMomentCalculatorTool.CaloCalibClusterMomentsMaker2 = getTopoCalibMoments(inputFlags)
161
162 result.setPrivateTools(PFMomentCalculatorTool)
163 return result
164
165def getPFLCCalibTool(inputFlags):
166 PFLCCalibTool = CompFactory.PFLCCalibTool
167 PFLCCalibTool = PFLCCalibTool("PFLCCalibTool")
168
169 PFClusterCollectionTool = CompFactory.PFClusterCollectionTool
170 PFLCCalibTool.eflowRecClusterCollectionTool = PFClusterCollectionTool("PFClusterCollectionTool_LCCalib")
171 PFLCCalibTool.UseLocalWeight = False
172
173 from CaloRec.CaloTopoClusterConfig import getTopoClusterLocalCalibTools
174 lcCalibToolList = getTopoClusterLocalCalibTools(inputFlags)
175
176 PFLCCalibTool.CaloClusterLocalCalib=lcCalibToolList[0]
177 PFLCCalibTool.CaloClusterLocalCalibOOCC=lcCalibToolList[1]
178 PFLCCalibTool.CaloClusterLocalCalibOOCCPi0=lcCalibToolList[2]
179 PFLCCalibTool.CaloClusterLocalCalibDM=lcCalibToolList[3]
180
181 return PFLCCalibTool
182
183def getChargedFlowElementCreatorAlgorithm(inputFlags,chargedFlowElementOutputName,nameSuffix="",eflowCaloObjectContainerName="eflowCaloObjects"):
184 FlowElementChargedCreatorAlgorithmFactory = CompFactory.PFChargedFlowElementCreatorAlgorithm
185 FlowElementChargedCreatorAlgorithm = FlowElementChargedCreatorAlgorithmFactory("PFChargedFlowElementCreatorAlgorithm"+nameSuffix)
186 FlowElementChargedCreatorAlgorithm.eflowCaloObjectContainerName = eflowCaloObjectContainerName
187 if chargedFlowElementOutputName:
188 FlowElementChargedCreatorAlgorithm.FlowElementOutputName=chargedFlowElementOutputName
189 if(inputFlags.PF.EOverPMode):
190 FlowElementChargedCreatorAlgorithm.FlowElementOutputName="EOverPChargedParticleFlowObjects"
191 FlowElementChargedCreatorAlgorithm.EOverPMode = True
192 if inputFlags.PF.addCPData:
193 FlowElementChargedCreatorAlgorithm.addCPData = True
194
195 return FlowElementChargedCreatorAlgorithm
196
197def getNeutralFlowElementCreatorAlgorithm(inputFlags,neutralFlowElementOutputName,nameSuffix="",eflowCaloObjectContainerName="eflowCaloObjects"):
198 FlowElementNeutralCreatorAlgorithmFactory = CompFactory.PFNeutralFlowElementCreatorAlgorithm
199 FlowElementNeutralCreatorAlgorithm = FlowElementNeutralCreatorAlgorithmFactory("PFNeutralFlowElementCreatorAlgorithm"+nameSuffix)
200 FlowElementNeutralCreatorAlgorithm.eflowCaloObjectContainerName = eflowCaloObjectContainerName
201 if neutralFlowElementOutputName:
202 FlowElementNeutralCreatorAlgorithm.FlowElementOutputName=neutralFlowElementOutputName
203 if(inputFlags.PF.EOverPMode):
204 FlowElementNeutralCreatorAlgorithm.FlowElementOutputName="EOverPNeutralParticleFlowObjects"
205 if(inputFlags.PF.useCalibHitTruthClusterMoments and inputFlags.PF.addClusterMoments):
206 FlowElementNeutralCreatorAlgorithm.UseCalibHitTruth=True
207 if inputFlags.PF.addCPData:
208 FlowElementNeutralCreatorAlgorithm.addCPData = True
209
210 return FlowElementNeutralCreatorAlgorithm
211
212def getLCNeutralFlowElementCreatorAlgorithm(inputFlags,neutralFlowElementOutputName):
213 LCFlowElementNeutralCreatorAlgorithmFactory = CompFactory.PFLCNeutralFlowElementCreatorAlgorithm
214 LCFlowElementNeutralCreatorAlgorithm = LCFlowElementNeutralCreatorAlgorithmFactory("PFLCNeutralFlowElementCreatorAlgorithm")
215 if neutralFlowElementOutputName:
216 LCFlowElementNeutralCreatorAlgorithm.FELCOutputName=neutralFlowElementOutputName
217 if(inputFlags.PF.EOverPMode):
218 LCFlowElementNeutralCreatorAlgorithm.FEInputContainerName="EOverPNeutralParticleFlowObjects"
219 LCFlowElementNeutralCreatorAlgorithm.FELCOutputName="EOverPLCNeutralParticleFlowObjects"
220
221 return LCFlowElementNeutralCreatorAlgorithm
222
223# Factory function to create the ML-based neutral flow element creator algorithm
224def getPFOClusterMLCorrectionAlgorithmCfg(inputFlags, inputNameBase = "JetETMiss", outputNameBase = "JetETMissClusterMLCorrected"):
225 alg = CompFactory.PFOClusterMLCorrectionAlgorithm("PFOClusterMLCorrectionAlgorithm")
226 suffix = "ParticleFlowObjects"
227 alg.NeutralPFlowInputContainer = inputNameBase + "Neutral" + suffix
228 alg.ChargedPFlowInputContainer = inputNameBase + "Charged" + suffix
229 alg.NeutralPFlowOutputContainer = outputNameBase + "Neutral" + suffix
230 alg.ChargedPFlowOutputContainer = outputNameBase + "Charged" + suffix
231
232 return alg
233
234def getNeutralPFOClusterMLCorrectionToolCfg(inputFlags, toolName="NeutralPFOClusterMLCorrectionTool", clusterMLCorrectedEnergyDecorationKey="clusterE_ML"):
235 if toolName == "NeutralPFOClusterMLCorrectionTool":
236 tool = CompFactory.NeutralPFOClusterMLCorrectionTool(toolName)
237 tool.ClusterMLCorrectedEnergyDecorationKey = clusterMLCorrectedEnergyDecorationKey
238 else:
239 raise ValueError(f"Unknown tool name: {toolName}")
240
241 ca = ComponentAccumulator()
242 ca.setPrivateTools(tool)
243 return ca
244
245
246
247def getEGamFlowElementAssocAlgorithm(inputFlags, algName="", **kwargs):
248
249 kwargs.setdefault("neutral_FE_cont_name", "")
250 kwargs.setdefault("charged_FE_cont_name", "")
251 kwargs.setdefault("doTCC", False)
252 kwargs.setdefault("useGlobal", False)
253
254 PFEGamFlowElementLinkerAlgorithmFactory=CompFactory.PFEGamFlowElementAssoc
255 if not algName:
256 algName = "PFEGamFlowElementAssoc"
257 PFEGamFlowElementLinkerAlgorithm=PFEGamFlowElementLinkerAlgorithmFactory(algName)
258
259 #set an an alternate name if needed
260 #this uses some gaudi core magic, namely that you can change the name of the handle as it is a callable attribute, despite the attribute not being explicitly listed in the header
261 #for a key of type SG::WriteDecorHandle<xAOD::SomeCont>someKey{this,"SpecificContainerName","myContainerName","other-labels"}
262 #setting algorithm.SpecificContainerName="myNewContainerName" changes parameter "myContainerName"
263 #(also applies to ReadHandles)
264 if kwargs['neutral_FE_cont_name']:
265 PFEGamFlowElementLinkerAlgorithm.JetEtMissNeutralFlowElementContainer = kwargs['neutral_FE_cont_name']
266
267 if kwargs['charged_FE_cont_name']:
268 PFEGamFlowElementLinkerAlgorithm.JetEtMissChargedFlowElementContainer = kwargs['charged_FE_cont_name']
269
270 if kwargs['doTCC']:
271 # ReadHandles to change
272 PFEGamFlowElementLinkerAlgorithm.JetEtMissNeutralFlowElementContainer="TrackCaloClustersNeutral"
273 PFEGamFlowElementLinkerAlgorithm.JetEtMissChargedFlowElementContainer="TrackCaloClustersCharged"
274
275 #Now to change the writeHandles
276 # first the Electron -> FE links
277 EL_NFE_Link=str(PFEGamFlowElementLinkerAlgorithm.ElectronNeutralFEDecorKey)
278 PFEGamFlowElementLinkerAlgorithm.ElectronNeutralFEDecorKey=EL_NFE_Link.replace("FELinks","TCCLinks")
279 EL_CFE_Link=str(PFEGamFlowElementLinkerAlgorithm.ElectronChargedFEDecorKey)
280 PFEGamFlowElementLinkerAlgorithm.ElectronChargedFEDecorKey=EL_CFE_Link.replace("FELinks","TCCLinks")
281 #then the converse case (FE -> Electron)
282
283 PFEGamFlowElementLinkerAlgorithm.ChargedFEElectronDecorKey="TCC_ElectronLinks"
284 PFEGamFlowElementLinkerAlgorithm.NeutralFEElectronDecorKey="TCC_ElectronLinks"
285
286
287 # first the Photon -> FE links
288 PH_NFE_Link=str(PFEGamFlowElementLinkerAlgorithm.PhotonNeutralFEDecorKey)
289 PFEGamFlowElementLinkerAlgorithm.PhotonNeutralFEDecorKey=PH_NFE_Link.replace("FELinks","TCCLinks")
290 PH_CFE_Link=str(PFEGamFlowElementLinkerAlgorithm.PhotonChargedFEDecorKey)
291 PFEGamFlowElementLinkerAlgorithm.PhotonChargedFEDecorKey=PH_CFE_Link.replace("FELinks","TCCLinks")
292 #then the converse case (FE -> Photons)
293
294 PFEGamFlowElementLinkerAlgorithm.ChargedFEPhotonDecorKey="TCC_PhotonLinks"
295 PFEGamFlowElementLinkerAlgorithm.NeutralFEPhotonDecorKey="TCC_PhotonLinks"
296
297 if kwargs['useGlobal']:
298 # ReadHandles to change
299 PFEGamFlowElementLinkerAlgorithm.JetEtMissNeutralFlowElementContainer="GlobalNeutralParticleFlowObjects"
300 PFEGamFlowElementLinkerAlgorithm.JetEtMissChargedFlowElementContainer="GlobalChargedParticleFlowObjects"
301
302 #Now to change the writeHandles
303 # first the Electron -> FE links
304 EL_NFE_Link=str(PFEGamFlowElementLinkerAlgorithm.ElectronNeutralFEDecorKey)
305 PFEGamFlowElementLinkerAlgorithm.ElectronNeutralFEDecorKey=EL_NFE_Link.replace("FELinks","GlobalFELinks")
306 EL_CFE_Link=str(PFEGamFlowElementLinkerAlgorithm.ElectronChargedFEDecorKey)
307 PFEGamFlowElementLinkerAlgorithm.ElectronChargedFEDecorKey=EL_CFE_Link.replace("FELinks","GlobalFELinks")
308 #then the converse case (FE -> Electron)
309
310 PFEGamFlowElementLinkerAlgorithm.ChargedFEElectronDecorKey="GlobalFE_ElectronLinks"
311 PFEGamFlowElementLinkerAlgorithm.NeutralFEElectronDecorKey="GlobalFE_ElectronLinks"
312
313
314 # first the Photon -> FE links
315 PH_NFE_Link=str(PFEGamFlowElementLinkerAlgorithm.PhotonNeutralFEDecorKey)
316 PFEGamFlowElementLinkerAlgorithm.PhotonNeutralFEDecorKey=PH_NFE_Link.replace("FELinks","GlobalFELinks")
317 PH_CFE_Link=str(PFEGamFlowElementLinkerAlgorithm.PhotonChargedFEDecorKey)
318 PFEGamFlowElementLinkerAlgorithm.PhotonChargedFEDecorKey=PH_CFE_Link.replace("FELinks","GlobalFELinks")
319 #then the converse case (FE -> Photons)
320
321 PFEGamFlowElementLinkerAlgorithm.ChargedFEPhotonDecorKey="TCC_PhotonLinks"
322 PFEGamFlowElementLinkerAlgorithm.NeutralFEPhotonDecorKey="TCC_PhotonLinks"
323
324
325
326 return PFEGamFlowElementLinkerAlgorithm
327
328def getMuonFlowElementAssocAlgorithm(inputFlags, algName="", **kwargs):
329
330 kwargs.setdefault("neutral_FE_cont_name", "")
331 kwargs.setdefault("charged_FE_cont_name", "")
332 kwargs.setdefault("LinkNeutralFEClusters", True)
333 kwargs.setdefault("doTCC", False)
334 kwargs.setdefault("useGlobal", False)
335
336 useMuonTopoClusters = False
337 from AthenaConfiguration.Enums import ProductionStep
338 # set 'useMuonTopoClusters=True' if running on AOD, as do not have calorimeter cells for CaloCalTopoCluster
339 # Assumes that in production workflows this only happens in "Derivation" or if DQ environment is AOD
340 if inputFlags.Common.ProductionStep in [ProductionStep.Derivation] or inputFlags.DQ.Environment == "AOD":
341 useMuonTopoClusters = True
342
343
344 PFMuonFlowElementLinkerAlgorithmFactory=CompFactory.PFMuonFlowElementAssoc
345 if not algName:
346 algName="PFMuonFlowElementAssoc"
347 PFMuonFlowElementLinkerAlgorithm=PFMuonFlowElementLinkerAlgorithmFactory(algName)
348
349 #set an an alternate name if needed
350 #this uses some gaudi core magic, namely that you can change the name of the handle as it is a callable attribute, despite the attribute not being explicitly listed in the header as such
351 #for a key of type SG::WriteDecorHandle<xAOD::SomeCont>someKey{this,"SpecificContainerName","myContainerName","other-labels"}
352 #setting algorithm.SpecificContainerName="myNewContainerName" changes parameter "myContainerName" to "myNewContainerName"
353 if kwargs['neutral_FE_cont_name']:
354 #update the readhandle
355 PFMuonFlowElementLinkerAlgorithm.JetEtMissNeutralFlowElementContainer = kwargs['neutral_FE_cont_name']
356 #update the write handle for the link
357
358 if kwargs['charged_FE_cont_name']:
359 PFMuonFlowElementLinkerAlgorithm.JetEtMissChargedFlowElementContainer = kwargs['charged_FE_cont_name']
360
361 PFMuonFlowElementLinkerAlgorithm.LinkNeutralFEClusters = kwargs['LinkNeutralFEClusters']
362 PFMuonFlowElementLinkerAlgorithm.useMuonTopoClusters = useMuonTopoClusters
363
364 #prototype on AOD with the linkers already defined - so need to rename the output links to something besides their default name.
365
366 #Track Calo cluster (TCC) specific configuration. Input is differently named FE container, and in the AOD step specifically
367 if kwargs['doTCC']:
368 #input containers are TrackCaloClustersCharged and TrackCaloClustersNeutral, so rename them
369 #service_key="StoreGateSvc+"
370 service_key=""
371 PFMuonFlowElementLinkerAlgorithm.MuonContainer=service_key+"Muons"
372 PFMuonFlowElementLinkerAlgorithm.JetEtMissChargedFlowElementContainer=service_key+"TrackCaloClustersCharged"
373 PFMuonFlowElementLinkerAlgorithm.JetEtMissNeutralFlowElementContainer=service_key+"TrackCaloClustersNeutral"
374
375 #Output
376 #rename the FE_MuonLinks as TCC_MuonLinks
377 #rename output containers
378 PFMuonFlowElementLinkerAlgorithm.MuonContainer_chargedFELinks="chargedTCCLinks"
379 PFMuonFlowElementLinkerAlgorithm.MuonContainer_neutralFELinks="neutralTCCLinks"
380 PFMuonFlowElementLinkerAlgorithm.JetETMissNeutralFlowElementContainer_FE_MuonLinks="TCC_MuonLinks"
381 PFMuonFlowElementLinkerAlgorithm.JetETMissChargedFlowElements_FE_MuonLinks="TCC_MuonLinks"
382 PFMuonFlowElementLinkerAlgorithm.FlowElementContainer_ChargedFE_ennergy_matched_muon="TCC_efrac_matched_muon"
383 # several variables relating to Neutral Flow Elements/TCCs to Muons for debug. perhaps at some point these should be removed by default
384 PFMuonFlowElementLinkerAlgorithm.FlowElementContainer_nMatchedMuons="TCC_nMatchedMuons"
385 PFMuonFlowElementLinkerAlgorithm.FlowElementContainer_FE_efrac_matched_muon="TCC_efrac_matched_muon"
386
387 PFMuonFlowElementLinkerAlgorithm.MuonContainer_muon_efrac_matched_FE="muon_efrac_matched_TCC"
388 # this is because the algorithm adds this debug container which we don't need
389 PFMuonFlowElementLinkerAlgorithm.MuonContainer_ClusterInfo_deltaR="deltaR_muon_clus_TCCalg"
390
391 if kwargs['useGlobal']:
392 PFMuonFlowElementLinkerAlgorithm.JetEtMissChargedFlowElementContainer="GlobalChargedParticleFlowObjects"
393 PFMuonFlowElementLinkerAlgorithm.JetEtMissNeutralFlowElementContainer="GlobalNeutralParticleFlowObjects"
394
395 PFMuonFlowElementLinkerAlgorithm.MuonContainer_chargedFELinks="chargedGlobalFELinks"
396 PFMuonFlowElementLinkerAlgorithm.MuonContainer_neutralFELinks="neutralGlobalFELinks"
397
398 PFMuonFlowElementLinkerAlgorithm.JetETMissNeutralFlowElementContainer_FE_MuonLinks="GlobalFE_MuonLinks"
399 PFMuonFlowElementLinkerAlgorithm.JetETMissChargedFlowElements_FE_MuonLinks="GlobalFE_MuonLinks"
400 PFMuonFlowElementLinkerAlgorithm.FlowElementContainer_ChargedFE_ennergy_matched_muon="GlobalFE_efrac_matched_muon"
401
402 PFMuonFlowElementLinkerAlgorithm.FlowElementContainer_nMatchedMuons="GlobalFE_nMatchedMuons"
403 PFMuonFlowElementLinkerAlgorithm.FlowElementContainer_FE_efrac_matched_muon="GlobalFE_efrac_matched_muon"
404
405 PFMuonFlowElementLinkerAlgorithm.MuonContainer_muon_efrac_matched_FE="muon_efrac_matched_GlobalFE"
406 # this is because the algorithm adds this debug container which we don't need
407 PFMuonFlowElementLinkerAlgorithm.MuonContainer_ClusterInfo_deltaR="deltaR_muon_clus_GlobalFEalg"
408
409 if kwargs['LinkNeutralFEClusters'] and not useMuonTopoClusters:
410 # We dereference links to cells, so make sure we have the
411 # dependency.
412 PFMuonFlowElementLinkerAlgorithm.ExtraInputs.add(('CaloCellContainer', inputFlags.Egamma.Keys.Input.CaloCells))
413
414 if kwargs['LinkNeutralFEClusters']:
415 if kwargs['doTCC']:
416 # since the cells are deleted on AOD, if you try to run the link between NFE and Muon on AOD, it will crash. Terminate to catch this.
417 # This is a known bug to rectify soon
418 from AthenaCommon.Logging import logging
419 msg=logging.getLogger("PFCfg.py::getMuonFlowElementAssocAlgorithm")
420 msg.error("Neutral FE from AOD configured to be linked with Muon. This link will fail due to missing CaloCells in the AOD")
421 msg.info("Terminating job")
422 exit(0)
423
424
425 return PFMuonFlowElementLinkerAlgorithm
426
427def getTauFlowElementAssocAlgorithm(inputFlags, algName="", **kwargs):
428
429 kwargs.setdefault("neutral_FE_cont_name", "")
430 kwargs.setdefault("charged_FE_cont_name", "")
431 kwargs.setdefault("doTCC", False)
432 kwargs.setdefault("useGlobal", False)
433
434 PFTauFlowElementLinkerAlgorithmFactory=CompFactory.PFTauFlowElementAssoc
435 if not algName:
436 algName = "PFTauFlowElementAssoc"
437
438 PFTauFlowElementLinkerAlgorithm=PFTauFlowElementLinkerAlgorithmFactory(algName)
439
440 #set an an alternate name if needed
441 #this uses some gaudi core magic, namely that you can change the name of the handle as it is a callable attribute, despite the attribute not being explicitly listed in the header
442 #for a key of type SG::WriteDecorHandle<xAOD::SomeCont>someKey{this,"SpecificContainerName","myContainerName","other-labels"}
443 #setting algorithm.SpecificContainerName="myNewContainerName" changes parameter "myContainerName"
444 #(also applies to ReadHandles)
445 if kwargs['neutral_FE_cont_name']:
446 PFTauFlowElementLinkerAlgorithm.JetETMissNeutralFlowElementContainer = kwargs['neutral_FE_cont_name']
447
448 if kwargs['charged_FE_cont_name']:
449 PFTauFlowElementLinkerAlgorithm.JetETMissChargedFlowElementContainer = kwargs['charged_FE_cont_name']
450
451 if kwargs['doTCC']:
452 PFTauFlowElementLinkerAlgorithm.JetETMissNeutralFlowElementContainer="TrackCaloClustersNeutral"
453 PFTauFlowElementLinkerAlgorithm.JetETMissChargedFlowElementContainer="TrackCaloClustersCharged"
454
455 PFTauFlowElementLinkerAlgorithm.TauNeutralFEDecorKey="neutralTCCLinks"
456 PFTauFlowElementLinkerAlgorithm.TauChargedFEDecorKey="chargedTCCLinks"
457
458 PFTauFlowElementLinkerAlgorithm.NeutralFETauDecorKey="TCC_TauLinks"
459 PFTauFlowElementLinkerAlgorithm.ChargedFETauDecorKey="TCC_TauLinks"
460
461 #This allows to set the links on the global particle flow containers created by JetPFlowSelectionAlg in JetRecTools
462 if kwargs['useGlobal']:
463 PFTauFlowElementLinkerAlgorithm.JetETMissNeutralFlowElementContainer="GlobalNeutralParticleFlowObjects"
464 PFTauFlowElementLinkerAlgorithm.JetETMissChargedFlowElementContainer="GlobalChargedParticleFlowObjects"
465
466 PFTauFlowElementLinkerAlgorithm.TauNeutralFEDecorKey="neutralGlobalFELinks"
467 PFTauFlowElementLinkerAlgorithm.TauChargedFEDecorKey="chargedGlobalFELinks"
468
469 PFTauFlowElementLinkerAlgorithm.NeutralFETauDecorKey="GlobalFE_TauLinks"
470 PFTauFlowElementLinkerAlgorithm.ChargedFETauDecorKey="GlobalFE_TauLinks"
471
472 return PFTauFlowElementLinkerAlgorithm
473
474def getOfflinePFAlgorithm(inputFlags):
475 result=ComponentAccumulator()
476
477 PFAlgorithm=CompFactory.PFAlgorithm
478 PFAlgorithm = PFAlgorithm("PFAlgorithm")
479
480
481 if inputFlags.HeavyIon.Egamma.doSubtractedClusters:
482 PFAlgorithm.PFClusterSelectorTool = getPFClusterSelectorTool(inputFlags,inputFlags.HeavyIon.Egamma.UncalibCaloTopoCluster,inputFlags.HeavyIon.Egamma.CaloTopoCluster,"PFClusterSelectorTool")
483 else:
484 topoClustersName="CaloTopoClusters"
485 PFAlgorithm.PFClusterSelectorTool = getPFClusterSelectorTool(inputFlags,topoClustersName,"CaloCalTopoClusters","PFClusterSelectorTool")
486
487 PFAlgorithm.SubtractionToolList = [getPFCellLevelSubtractionTool(inputFlags,"PFCellLevelSubtractionTool")]
488
489 if(False is inputFlags.PF.EOverPMode and False is inputFlags.PF.useTruthCheating):
490 PFAlgorithm.SubtractionToolList += [getPFRecoverSplitShowersTool(inputFlags,"PFRecoverSplitShowersTool")]
491
492 PFMomentCalculatorTools=result.popToolsAndMerge(getPFMomentCalculatorTool(inputFlags,[]))
493 PFAlgorithm.BaseToolList = [PFMomentCalculatorTools]
494 PFAlgorithm.BaseToolList += [getPFLCCalibTool(inputFlags)]
495 if inputFlags.PF.EOverPMode:
496 PFAlgorithm.BaseToolList += [CompFactory.PFRadialEnergyCalculatorTool()]
497
498 result.addEventAlgo(PFAlgorithm)
499 return result
500
501def PFGlobalFlowElementLinkingCfg(inputFlags, **kwargs):
502 result=ComponentAccumulator()
503
504 kwargs.setdefault("useGlobal", True)
505
506 result.addEventAlgo(getTauFlowElementAssocAlgorithm(inputFlags, algName="PFTauGlobalFlowElementAssoc", **kwargs))
507 result.addEventAlgo(getMuonFlowElementAssocAlgorithm(inputFlags, algName="PFMuonGlobalFlowElementAssoc", **kwargs))
508 result.addEventAlgo(getEGamFlowElementAssocAlgorithm(inputFlags, algName="PFEGamGlobalFlowElementAssoc", **kwargs))
509 return result
if(febId1==febId2)
Class to store reference e/p mean and widths, as well as reference energy density radial profile fit ...
Inherits from IPFClusterCollectionTool and AthAlgTool.
This tool can either use a series of CaloClusterProcessor to calibrate the modified xAOD::CaloCluster...
This is the tool, which inherits from AthAlgTool, which clients can use for track-cluster matching.
Class to store reference e/p mean and widths, as well as reference energy density radial profile fit ...
Inherits from eflowTrackExtrapolatorBaseAlgTool and AthAlgTool.
getEGamFlowElementAssocAlgorithm(inputFlags, algName="", **kwargs)
Definition PFCfg.py:247
getNeutralPFOClusterMLCorrectionToolCfg(inputFlags, toolName="NeutralPFOClusterMLCorrectionTool", clusterMLCorrectedEnergyDecorationKey="clusterE_ML")
Definition PFCfg.py:234
getTauFlowElementAssocAlgorithm(inputFlags, algName="", **kwargs)
Definition PFCfg.py:427
getPFRecoverSplitShowersTool(inputFlags, toolName)
Definition PFCfg.py:118
getPFCellLevelSubtractionTool(inputFlags, toolName)
Definition PFCfg.py:71
PFTrackSelectorAlgCfg(inputFlags, algName, useCaching=True)
Definition PFCfg.py:6
getPFLCCalibTool(inputFlags)
Definition PFCfg.py:165
getPFTrackClusterMatchingTool(inputFlags, matchCut, distanceType, clusterPositionType, name)
Definition PFCfg.py:62
getLCNeutralFlowElementCreatorAlgorithm(inputFlags, neutralFlowElementOutputName)
Definition PFCfg.py:212
getPFOClusterMLCorrectionAlgorithmCfg(inputFlags, inputNameBase="JetETMiss", outputNameBase="JetETMissClusterMLCorrected")
Definition PFCfg.py:224
getPFClusterSelectorTool(inputFlags, clustersin, calclustersin, algName)
Definition PFCfg.py:43
getMuonFlowElementAssocAlgorithm(inputFlags, algName="", **kwargs)
Definition PFCfg.py:328
getNeutralFlowElementCreatorAlgorithm(inputFlags, neutralFlowElementOutputName, nameSuffix="", eflowCaloObjectContainerName="eflowCaloObjects")
Definition PFCfg.py:197
PFGlobalFlowElementLinkingCfg(inputFlags, **kwargs)
Definition PFCfg.py:501
getChargedFlowElementCreatorAlgorithm(inputFlags, chargedFlowElementOutputName, nameSuffix="", eflowCaloObjectContainerName="eflowCaloObjects")
Definition PFCfg.py:183
getOfflinePFAlgorithm(inputFlags)
Definition PFCfg.py:474
getPFMomentCalculatorTool(inputFlags, momentsToCalculateList)
Definition PFCfg.py:143