ATLAS Offline Software
Loading...
Searching...
No Matches
ElectronChainConfiguration.py
Go to the documentation of this file.
1#Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3from AthenaCommon.Logging import logging
4logging.getLogger().info("Importing %s",__name__)
5log = logging.getLogger(__name__)
6
7from ..Config.ChainConfigurationBase import ChainConfigurationBase
8from ..CommonSequences.CaloSequences import fastCaloSequenceGenCfg
9from ..CommonSequences.CaloSequences_FWD import fastCalo_FWDSequenceGenCfg
10from ..Electron.FastElectronMenuSequences import fastElectronSequenceGenCfg, fastElectron_LRTSequenceGenCfg
11from ..Electron.FastTrackingMenuSequences import fastTrackingSequenceGenCfg, fastTracking_LRTSequenceGenCfg
12from ..Electron.PrecisionCaloMenuSequences import precisionCaloSequenceGenCfg, precisionCalo_LRTSequenceGenCfg
13from ..Electron.PrecisionElectronMenuSequences import precisionElectronSequenceGenCfg, precisionElectron_LRTSequenceGenCfg
14from ..Electron.PrecisionElectronMenuSequences_GSF import precisionElectron_GSFSequenceGenCfg, precisionElectron_GSF_LRTSequenceGenCfg
15from TrigBphysHypo.TrigMultiTrkComboHypoConfig import NoMuonDiElecPrecisionGSFComboHypoCfg, DiElecPrecisionGSFComboHypoCfg, TrigMultiTrkComboHypoToolFromDict
16from ..Electron.PrecisionTrackingMenuSequences import precisionTrackingSequenceGenCfg, precisionTracking_LRTSequenceGenCfg
17from ..Electron.PrecisionTracks_GSFRefittedMenuSequences import precisionTracks_GSFRefittedSequenceGenCfg, precisionTracks_GSFRefitted_LRTSequenceGenCfg
18
19from AthenaConfiguration.ComponentFactory import CompFactory
20
21from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool
22
23
24
25def _diElectronMassComboHypoToolFromDict(flags, chainDict, mass_range):
26 name = chainDict['chainName']
27 monTool = GenericMonitoringTool(flags, "MonTool_"+name,
28 HistPath = 'EgammaMassHypo/'+name)
29 monTool.defineHistogram('DphiOfProcessed', type='TH1F', path='EXPERT', title="PrecisionCalo Hypo entries per Phi;Phi", xbins=128, xmin=-3.2, xmax=3.2)
30 monTool.defineHistogram('MassOfProcessed', type='TH1F', path='EXPERT', title="Mass in accepted combinations [MeV]", xbins=75, xmin=0, xmax=150000)
31 monTool.defineHistogram('DphiOfAccepted', type='TH1F', path='EXPERT', title="PrecisionCalo Hypo entries per Phi;Phi", xbins=128, xmin=-3.2, xmax=3.2)
32 monTool.defineHistogram('MassOfAccepted', type='TH1F', path='EXPERT', title="Mass in accepted combinations [MeV]", xbins=75, xmin=0, xmax=150000)
33
34 tool = CompFactory.TrigEgammaTopoHypoTool(name,
35 AcceptAll = False,
36 ApplyMassCut = True,
37 LowerMassEgammaClusterCut = mass_range[0],
38 UpperMassEgammaClusterCut = mass_range[1],
39 MonTool = monTool)
40 return tool
41
42
44 return _diElectronMassComboHypoToolFromDict(flags, chainDict, (50000, 130000))
45
47 return _diElectronMassComboHypoToolFromDict(flags, chainDict, (1000, 5000))
48
50 return _diElectronMassComboHypoToolFromDict(flags, chainDict, (90000, 1400000))
51
52
53#----------------------------------------------------------------
54# Class to configure chain
55#----------------------------------------------------------------
56class ElectronChainConfiguration(ChainConfigurationBase):
57
58 def __init__(self, chainDict):
59 ChainConfigurationBase.__init__(self,chainDict)
60 self.chainDict = chainDict
61
62
63 # ----------------------
64 # Prepare the sequence
65 # ----------------------
66 def prepareSequence(self):
67 # This function prepares the list of step names from which assembleChainImpl would make the chain assembly from.
68
69 # --------------------
70 # define here the names of the steps and obtain the chainStep configuration
71 # --------------------
72
73 stepNames = [] # This will contain the name of the steps we will want to configure
74
75 # Step1
76 # Put first fast Calo. Two possible variants now:
77 # getFastCalo
78 # getFastCalo_fwd
79 # But first, we need to check whether this is a chain that will run smth at fast or precision. So if no L2IDAlg or IDinfo defined, just return this here
80
81 if not self.chainPart['IDinfo'] and not self.chainPart['L2IDAlg'] and not self.chainPart['isoInfo'] and not self.chainPart['addInfo']:
82 return stepNames
83
84 if "fwd" in self.chainPart['addInfo']:
85 stepNames += ['getFastCalo_fwd']
86
87 # Actually, if its fwd and etcut we will stop here (for now)
88 if "etcut" in self.chainPart['addInfo']:
89 return stepNames
90 else:
91 stepNames += ['getFastCalo']
92
93 # Step2
94 # Now lets do Fast Electron. Possible Flavours:
95 # getFastTracking
96 # getFastTracking_lrt
97
98 if self.chainPart['lrtInfo']:
99 stepNames += ['getFastTracking_lrt']
100 else:
101 stepNames += ['getFastTracking']
102
103
104 # Step3
105 # Now lets do Fast Electron. Possible Flavours:
106 # getFastElectron
107 # getFastElectron_lrt
108
109 if self.chainPart['lrtInfo']:
110 stepNames += ['getFastElectron_lrt']
111 else:
112 stepNames += ['getFastElectron']
113
114
115 # Step4
116 # After Fast Electron we have to build PrecisionCalo for electorns. Current available variantas are:
117 # getPrecisionCaloElectron
118 # getPrecisionCaloElectron_lrt
119 # Now, we will add this if there is any IDInfo (i.e. any of dnn* or lh* in the chain name). Otherwise we wont run precision steps
120
121 if not self.chainPart['IDinfo'] and not self.chainPart['isoInfo'] and not self.chainPart['addInfo']:
122 log.debug("No IDInfo, no isoInfo and no addInfo. Returning here up to fastElectron")
123 return stepNames
124
125 if self.chainPart['lrtInfo']:
126 stepNames += ['getPrecisionCaloElectron_lrt']
127 else:
128 stepNames += ['getPrecisionCaloElectron']
129
130 # If its an etcut chain, we will not run precision Tracking Electron. Just precision Calo. So returning here if its an etcut chain unless its an etcut_idperf chaiin:
131
132 if 'etcut' in self.chainPart['addInfo'] and 'idperf' not in self.chainPart['idperfInfo']:
133 log.debug("This is an etcut chain. Returning here")
134 return stepNames
135
136 # Step5
137 # After precisionCalo Electron we have to do precision tracking next. Current available variantas are:
138 # getPrecisionTracking
139 # getPrecisionTracking_lrt
140
141 if self.chainPart['lrtInfo']:
142 stepNames += ['getPrecisionTracking_lrt']
143 else:
144 stepNames += ['getPrecisionTracking']
145
146 # Step6
147 # Now if a chain is configured to do gsf refitting we need to add another tracking step for the GSF refitting:
148 # getPrecisionTrack_GSFRefitted
149 # getPrecisionTrack_GSFRefitted_lrt
150
151 if "" in self.chainPart['gsfInfo'] and 'nogsf' not in self.chainPart['gsfInfo']:
152 if self.chainPart['lrtInfo']:
153 stepNames += ['getPrecisionTrack_GSFRefitted_lrt']
154 else:
155 stepNames += ['getPrecisionTrack_GSFRefitted']
156 # if its nogsf, then we need to add an addtional empty step to keep aligned the gsf chains (with the additional refitting)
157 else:
158 if 'idperf' not in self.chainPart['idperfInfo']:
159 # Only add an empty refiting step if its not an idperf - nonGSF. Otherwise the last step will be an empty step and that doesnt work
160 stepNames += ['getEmptyRefitStep']
161
162
163
164 # If its an idperf chain, we will not run precision Electron. Just precision Calo and Precision Tracking so returning here if its an etcut chain
165 if 'idperf' in self.chainPart['idperfInfo']:
166 log.debug("This is an idperf chain. Returning here")
167 return stepNames
168
169
170 # Step7
171 # and Finally! once we have precision tracking adn precision calo, we can build our electrons!. Current available variantas are:
172 # getPrecisionElectron
173 # getPrecisionGSFElectron
174 # getPrecisionElectron_lrt
175
176 if "nogsf" in self.chainPart['gsfInfo']:
177 if self.chainPart['lrtInfo']:
178 stepNames += ['getPrecisionElectron_lrt']
179 else:
180 stepNames += ['getPrecisionElectron']
181
182 else:
183 if self.chainPart['lrtInfo']:
184 stepNames += ['getPrecisionGSFElectron_lrt']
185 else:
186 stepNames += ['getPrecisionGSFElectron']
187
188 log.debug("Returning chain with all steps in the sequence")
189 return stepNames
190
191 # ----------------------
192 # Assemble the chain depending on information from chainName
193 # ----------------------
194 def assembleChainImpl(self, flags):
195 chainSteps = []
196 log.debug("Assembling chain for %s", self.chainName)
197
198 # This will contain the name of the steps we will want to configure
199 steps = self.prepareSequence()
200
201
202 # This is it, lets print the list of stepNames
203 log.debug("stepNames: %s", steps)
204 for step in steps:
205 log.debug('Adding electron trigger step %s', step)
206 is_probe_leg = self.chainPart['tnpInfo']=='probe'
207 chainstep = getattr(self, step)(flags, is_probe_leg=is_probe_leg)
208 chainSteps+=[chainstep]
209
210 myChain = self.buildChain(chainSteps)
211
212 return myChain
213
214 # -------------------------------
215 # Configuration of electron steps
216 # -------------------------------
217
218 def getFastCalo(self, flags, is_probe_leg=False):
219 stepName = "FastCalo_electron"
220 return self.getStep(flags, stepName,[fastCaloSequenceGenCfg], name='Electron', is_probe_leg=is_probe_leg)
221
222 def getFastTracking(self, flags, is_probe_leg=False):
223 stepName = "fast_tracking"
224 return self.getStep(flags, stepName,[ fastTrackingSequenceGenCfg],is_probe_leg=is_probe_leg)
225
226 def getFastTracking_lrt(self, flags, is_probe_leg=False):
227 stepName = "fast_tracking_lrt"
228 return self.getStep(flags, stepName,[ fastTracking_LRTSequenceGenCfg],is_probe_leg=is_probe_leg)
229
230 def getFastElectron(self, flags, is_probe_leg=False):
231 if self.chainPart['idperfInfo']:
232 stepName = "fast_electron_empty"
233 return self.getEmptyStep(stepName)
234 else:
235 stepName = "fast_electron"
236 return self.getStep(flags, stepName,[fastElectronSequenceGenCfg],is_probe_leg=is_probe_leg)
237
238 def getFastElectron_lrt(self, flags, is_probe_leg=False):
239 if self.chainPart['idperfInfo']:
240 stepName = "fast_electron_lrt_empty"
241 return self.getEmptyStep(stepName)
242 else:
243 stepName = "fast_electron_lrt"
244 return self.getStep(flags, stepName,[fastElectron_LRTSequenceGenCfg],is_probe_leg=is_probe_leg)
245
246 def getPrecisionCaloElectron(self, flags, is_probe_leg=False):
247 if self.chainPart['extra'] == 'ion':
248 stepName = 'precisionCalo_ion_electron'
249 return self.getStep(flags, stepName, [precisionCaloSequenceGenCfg], ion=True, is_probe_leg=is_probe_leg)
250
251 stepName = "precisionCalo_electron"
252 return self.getStep(flags, stepName,[precisionCaloSequenceGenCfg], is_probe_leg=is_probe_leg)
253
254 def getPrecisionCaloElectron_lrt(self, flags, is_probe_leg=False):
255 stepName = "precisionCalo_electron_lrt"
256 return self.getStep(flags, stepName,[precisionCalo_LRTSequenceGenCfg],is_probe_leg=is_probe_leg)
257
258 def getPrecisionTracking(self, flags, is_probe_leg=False):
259 if self.chainPart['extra'] == 'ion':
260 stepName = 'precisionTracking_ion_electron'
261 return self.getStep(flags, stepName, [precisionTrackingSequenceGenCfg], ion=True, is_probe_leg=is_probe_leg)
262
263 stepName = "precisionTracking_electron"
264 return self.getStep(flags, stepName,[precisionTrackingSequenceGenCfg], is_probe_leg=is_probe_leg)
265
266 def getPrecisionTracking_lrt(self, flags, is_probe_leg=False):
267 stepName = "precisionTracking_electron_lrt"
268 return self.getStep(flags, stepName,[precisionTracking_LRTSequenceGenCfg],is_probe_leg=is_probe_leg)
269
270 def getPrecisionTrack_GSFRefitted(self, flags, is_probe_leg=False):
271 stepName = "PrecisionTrack_GSFRefitted_electron"
272 return self.getStep(flags, stepName,[precisionTracks_GSFRefittedSequenceGenCfg], is_probe_leg=is_probe_leg)
273
274 def getPrecisionTrack_GSFRefitted_lrt(self, flags, is_probe_leg=False):
275 stepName = "PrecisionTrack_GSFRefitted_electron_lrt"
276 return self.getStep(flags, stepName,[precisionTracks_GSFRefitted_LRTSequenceGenCfg], is_probe_leg=is_probe_leg)
277
278 def getPrecisionElectron(self, flags, is_probe_leg=False):
279
280 isocut = self.chainPart['isoInfo']
281 log.debug(' isolation cut = %s', isocut)
282
283 if "Zee" in self.chainDict['topo']:
284 stepName = "precision_electron_Zee"+str(isocut)
285 return self.getStep(flags, stepName,sequenceCfgArray=[precisionElectronSequenceGenCfg], comboTools=[diElectronZeeMassComboHypoToolFromDict], is_probe_leg=is_probe_leg)
286 elif "Jpsiee" in self.chainDict['topo']:
287 stepName = "precision_topoelectron_Jpsiee"+str(isocut)
288 return self.getStep(flags, stepName,sequenceCfgArray=[precisionElectronSequenceGenCfg], comboTools=[diElectronJpsieeMassComboHypoToolFromDict], is_probe_leg=is_probe_leg)
289 elif "Heg" in self.chainDict['topo']:
290 stepName = "precision_electron_Heg"+str(isocut)
291 return self.getStep(flags, stepName,sequenceCfgArray=[precisionElectronSequenceGenCfg], comboTools=[diEgammaHegMassComboHypoToolFromDict], is_probe_leg=is_probe_leg)
292 elif self.chainPart['extra'] == 'ion':
293 stepName = "precision_ion_electron" + str(isocut)
294 return self.getStep(flags, stepName,[precisionElectronSequenceGenCfg], ion=True, is_probe_leg=is_probe_leg)
295 else:
296 stepName = "precision_electron_nominal"+str(isocut)
297 return self.getStep(flags, stepName,[ precisionElectronSequenceGenCfg ], is_probe_leg=is_probe_leg)
298
299 def getPrecisionGSFElectron(self, flags, is_probe_leg=False):
300
301 isocut = self.chainPart['isoInfo']
302 log.debug(' isolation cut = %s', isocut)
303
304 if "Zee" in self.chainDict['topo']:
305 stepName = "precision_topoelectron_Zee_GSF"+str(isocut)
306 return self.getStep(flags, stepName,sequenceCfgArray=[precisionElectron_GSFSequenceGenCfg], comboTools=[diElectronZeeMassComboHypoToolFromDict], is_probe_leg=is_probe_leg)
307 elif "Jpsiee" in self.chainDict['topo']:
308 stepName = "precision_topoelectron_Jpsiee_GSF"+str(isocut)
309 return self.getStep(flags, stepName,sequenceCfgArray=[precisionElectron_GSFSequenceGenCfg], comboTools=[diElectronJpsieeMassComboHypoToolFromDict], is_probe_leg=is_probe_leg)
310 elif "bBeeM6000" in self.chainDict['topo']:
311 signatures = self.chainDict['signatures']
312 if signatures.count(signatures[0]) == len(signatures):
313 stepName = "noMuon_precision_electron_bBee_GSF"+str(isocut)
314 return self.getStep(flags, stepName,sequenceCfgArray=[precisionElectron_GSFSequenceGenCfg], comboHypoCfg=NoMuonDiElecPrecisionGSFComboHypoCfg, comboTools=[TrigMultiTrkComboHypoToolFromDict], is_probe_leg=is_probe_leg)
315 else:
316 stepName = "precision_electron_bBee_GSF"+str(isocut)
317 return self.getStep(flags, stepName,sequenceCfgArray=[precisionElectron_GSFSequenceGenCfg], comboHypoCfg=DiElecPrecisionGSFComboHypoCfg, comboTools=[TrigMultiTrkComboHypoToolFromDict], is_probe_leg=is_probe_leg)
318 else:
319 stepName = "precision_electron_GSF"+str(isocut)
320 return self.getStep(flags, stepName,[precisionElectron_GSFSequenceGenCfg], is_probe_leg=is_probe_leg)
321
322 def getPrecisionGSFElectron_lrt(self, flags, is_probe_leg=False):
323
324 isocut = self.chainPart['isoInfo']
325 log.debug(' isolation cut = %s', isocut)
326 stepName = "precision_electron_LRTGSF"+str(isocut)
327 return self.getStep(flags, stepName,[precisionElectron_GSF_LRTSequenceGenCfg], is_probe_leg=is_probe_leg)
328
329 def getPrecisionElectron_lrt(self, flags, is_probe_leg=False):
330
331 isocut = self.chainPart['isoInfo']
332 log.debug(' isolation cut = %s', isocut)
333 stepName = "precision_electron_lrt"+str(isocut)
334 return self.getStep(flags, stepName,[ precisionElectron_LRTSequenceGenCfg],is_probe_leg=is_probe_leg)
335
336 def getFastCalo_fwd(self, flags, is_probe_leg=False):
337 stepName = "FastCalo_FWD_electron"
338 return self.getStep(flags, stepName, [fastCalo_FWDSequenceGenCfg], name='Electron', is_probe_leg=is_probe_leg)
339
340 def getEmptyRefitStep(self, flags, is_probe_leg=False):
341 return self.getEmptyStep('nonGSFEmptyRefit')
342
343
_diElectronMassComboHypoToolFromDict(flags, chainDict, mass_range)