ATLAS Offline Software
Loading...
Searching...
No Matches
TrigEgammaFastCaloHypoTool.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3from AthenaCommon.Logging import logging
4from AthenaCommon.SystemOfUnits import GeV
5from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool
6from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
7from AthenaConfiguration.ComponentFactory import CompFactory
8
9
10def same( val , tool):
11 return [val]*( len( tool.EtaBins ) - 1 )
12
13
14#
15# For electrons
16#
17def electronRingerFastCaloHypoConfig(flags, name, sequenceOut):
18 # make the Hypo
19 theFastCaloHypo = CompFactory.TrigEgammaFastCaloHypoAlg(name)
20 theFastCaloHypo.CaloClusters = sequenceOut
21 theFastCaloHypo.PidNames = ["tight", "medium", "loose", "vloose"]
22 theFastCaloHypo.RingerNNSelectorTools = createTrigEgammaFastCaloElectronSelectors(flags)
23
24 monTool = GenericMonitoringTool(flags, "MonTool_"+name, HistPath = 'FastCaloL2EgammaHypo/'+name)
25 monTool.defineHistogram('TIME_exec', type='TH1F', path='EXPERT', title="Fast Calo Hypo Algtime; time [ us ] ; Nruns", xbins=80, xmin=0.0, xmax=8000.0)
26 monTool.defineHistogram('TIME_NN_exec', type='TH1F', path='EXPERT', title="Fast Calo Hypo NN Algtime; time [ us ] ; Nruns", xbins=50, xmin=0.0, xmax=50)
27
28 theFastCaloHypo.MonTool=monTool
29 return theFastCaloHypo
30
31#
32# For photons
33#
34def photonRingerFastCaloHypoConfig(flags, name, sequenceOut):
35 # make the Hypo
36 theFastCaloHypo = CompFactory.TrigEgammaFastCaloHypoAlg(name)
37 theFastCaloHypo.CaloClusters = sequenceOut
38 theFastCaloHypo.PidNames = ["tight", "medium", "loose"]
39 theFastCaloHypo.RingerNNSelectorTools = createTrigEgammaFastCaloPhotonSelectors(flags)
40
41 monTool = GenericMonitoringTool(flags, "MonTool_"+name, HistPath = 'FastCaloL2EgammaHypo/'+name)
42 monTool.defineHistogram('TIME_exec', type='TH1F', path='EXPERT', title="Fast Calo Hypo Algtime; time [ us ] ; Nruns", xbins=80, xmin=0.0, xmax=8000.0)
43 monTool.defineHistogram('TIME_NN_exec', type='TH1F', path='EXPERT', title="Fast Calo Hypo NN Algtime; time [ us ] ; Nruns", xbins=50, xmin=0.0, xmax=50)
44
45 theFastCaloHypo.MonTool=monTool
46 return theFastCaloHypo
47
48
49
50def createTrigEgammaFastCaloHypoAlg(flags, name, sequenceOut):
51 if 'Electron' in name:
52 return electronRingerFastCaloHypoConfig(flags, name, sequenceOut)
53 elif 'Photon' in name:
54 return photonRingerFastCaloHypoConfig(flags, name, sequenceOut)
55
56
57def TrigEgammaFastCaloHypoAlgCfg(flags, name, CaloClusters):
58 acc = ComponentAccumulator()
59 acc.addEventAlgo(createTrigEgammaFastCaloHypoAlg(flags, name=name, sequenceOut=CaloClusters))
60 return acc
61
62#
63# For photons only
64# NOTE: For future, ringer will be applied at the fast photon step
65#
66def createTrigEgammaFastCaloHypoAlg_noringer(flags, name, sequenceOut):
67
68 # make the Hypo
69 theFastCaloHypo = CompFactory.TrigEgammaFastCaloHypoAlg(name)
70 theFastCaloHypo.CaloClusters = sequenceOut
71
72 # Just for electrons
73 theFastCaloHypo.PidNames = []
74 theFastCaloHypo.RingerNNSelectorTools = []
75
76
77 monTool = GenericMonitoringTool(flags, "MonTool_"+name,
78 HistPath = 'FastCaloL2EgammaHypo/'+name)
79 monTool.defineHistogram('TIME_exec', type='TH1F', path='EXPERT', title="Fast Calo Hypo Algtime; time [ us ] ; Nruns", xbins=80, xmin=0.0, xmax=8000.0)
80 monTool.defineHistogram('TIME_NN_exec', type='TH1F', path='EXPERT', title="Fast Calo Hypo NN Algtime; time [ us ] ; Nruns", xbins=20, xmin=0.0, xmax=1000.0)
81
82 theFastCaloHypo.MonTool=monTool
83 return theFastCaloHypo
84
85
86
87def treatPidName(pidname):
88 if 'tight' in pidname:
89 return 'tight'
90 elif 'medium' in pidname:
91 return 'medium'
92 # this should be before loose to works
93 elif 'vloose' in pidname:
94 return 'vloose'
95 else:
96 return 'loose'
97
98#
99# For electron and photons
100#
102
103 __operation_points = [ 'tight' ,
104 'medium' ,
105 'loose' ,
106 'vloose' ,
107 'lhtight' ,
108 'lhmedium' ,
109 'lhloose' ,
110 'lhvloose' ,
111 'dnntight' ,
112 'dnnmedium',
113 'dnnloose' ,
114 'dnnvloose',
115 ]
116
117
118 def __init__(self, flags, name, monGroups, cpart, tool=None):
119
120 self.__log = logging.getLogger('TrigEgammaFastCaloHypoTool')
121 self.__name = name
122 self.__cand = cpart['trigType']
123 self.__threshold = float(cpart['threshold'])
124 self.__sel = 'ion' if 'ion' in cpart['extra'] else (cpart['addInfo'][0] if cpart['addInfo'] else cpart['IDinfo'])
125 self.__gsfinfo = cpart['gsfInfo'] if cpart['trigType']=='e' and cpart['gsfInfo'] else ''
126 self.__idperfinfo = cpart['idperfInfo'] if cpart['trigType']=='e' and cpart['idperfInfo'] else ''
127 # self.__noringerinfo = cpart['L2IDAlg'] if cpart['trigType']=='e' else ''
128 self.__noringerinfo = cpart['L2IDAlg']
129 self.__monGroups = monGroups
130 self.__calibThreshold = flags.Trigger.egamma.CalibrationETThreshold
131
132 if not tool:
133 tool = CompFactory.TrigEgammaFastCaloHypoTool( name )
134
135 tool.AcceptAll = False
136 tool.UseRinger = False
137 tool.EtaBins = [0.0, 0.6, 0.8, 1.15, 1.37, 1.52, 1.81, 2.01, 2.37, 2.47]
138 tool.ETthr = same( self.__threshold*GeV, tool )
139 tool.dETACLUSTERthr = 0.1
140 tool.dPHICLUSTERthr = 0.1
141 tool.F1thr = same( 0.005 , tool)
142 tool.ET2thr = same( 90.0*GeV, tool )
143 tool.HADET2thr = same( 999.0 , tool)
144 tool.HADETthr = same( 0.058 , tool)
145 tool.WETA2thr = same( 99999. , tool)
146 tool.WSTOTthr = same( 99999. , tool)
147 tool.F3thr = same( 99999. , tool)
148 tool.CARCOREthr = same( -9999. , tool)
149 tool.CAERATIOthr = same( -9999. , tool)
150 tool.PidName = ""
151
152 self.__tool = tool
153
154 self.__log.debug( 'Chain :%s' , self.__name )
155 self.__log.debug( 'Signature :%s' , self.__cand )
156 self.__log.debug( 'Threshold :%s' , self.__threshold )
157 self.__log.debug( 'Pidname :%s' , self.__sel )
158 self.__log.debug( 'noringerinfo :%s', self.__noringerinfo )
159
160
161 def chain(self):
162 return self.__name
163
164 def pidname( self ):
165 return self.__sel
166
167 def etthr(self):
168 return self.__threshold
169
170 def isElectron(self):
171 return 'e' in self.__cand
172
173 def isPhoton(self):
174 return 'g' in self.__cand
175
176 def noringerinfo(self):
177 return self.__noringerinfo
178
179 def gsfinfo(self):
180 return self.__gsfinfo
181
182 def idperfinfo(self):
183 return self.__idperfinfo
184
185 def tool(self):
186 return self.__tool
187
188
189 def nocut(self):
190
191 self.__log.debug( 'Configure nocut' )
192 self.tool().AcceptAll = True
193 self.tool().UseRinger = False
194 self.tool().ETthr = same( self.etthr()*GeV , self.tool())
195 self.tool().dETACLUSTERthr = 9999.
196 self.tool().dPHICLUSTERthr = 9999.
197 self.tool().F1thr = same( 0.0 , self.tool())
198 self.tool().HADETthr = same( 9999. , self.tool())
199 self.tool().CARCOREthr = same( -9999. , self.tool())
200 self.tool().CAERATIOthr = same( -9999. , self.tool())
201
202
203 def etcut(self):
204
205 self.__log.debug( 'Configure etcut or nopid' )
206 self.tool().UseRinger = False
207 self.tool().ETthr = same( ( self.etthr() - self.__calibThreshold )*GeV, self.tool() )
208 self.tool().dETACLUSTERthr = 9999.
209 self.tool().dPHICLUSTERthr = 9999.
210 self.tool().F1thr = same( 0.0 ,self.tool())
211 self.tool().HADETthr = same( 9999. ,self.tool())
212 self.tool().CARCOREthr = same( -9999. ,self.tool())
213 self.tool().CAERATIOthr = same( -9999. ,self.tool())
214
215
216 def noringer(self):
217
218 self.__log.debug( 'Configure noringer' )
219 from TrigEgammaHypo.TrigEgammaFastCutDefs import TrigFastCaloElectronCutMaps
220 self.tool().UseRinger = False
221 self.tool().ETthr = same( ( self.etthr() - self.__calibThreshold )*GeV , self.tool())
222 self.tool().HADETthr = TrigFastCaloElectronCutMaps( self.etthr() ).MapsHADETthr[self.pidname()]
223 self.tool().CARCOREthr = TrigFastCaloElectronCutMaps( self.etthr() ).MapsCARCOREthr[self.pidname()]
224 self.tool().CAERATIOthr = TrigFastCaloElectronCutMaps( self.etthr() ).MapsCAERATIOthr[self.pidname()]
225
226
227 def nominal(self):
228
229 self.__log.debug( 'Configure ringer' )
230 self.tool().UseRinger = True
231 self.tool().EtCut = (self.etthr()-self.__calibThreshold)*GeV
232 if not self.pidname() in self.__operation_points:
233 self.__log.fatal("Bad selection name: %s" % self.pidname())
234 self.tool().PidName = treatPidName(self.pidname())
235
236
237 #
238 # compile the chain
239 #
240 def compile(self, flags):
241
242 if self.pidname() in ('etcut', 'ion', 'nopid'):
243 self.etcut()
244
245 elif self.pidname() in self.__operation_points and 'noringer' in self.noringerinfo() and self.isElectron():
246 self.noringer()
247
248 elif self.pidname() in self.__operation_points and 'noringer' not in self.noringerinfo() and self.isElectron():
249 self.nominal()
250
251 elif self.pidname() in self.__operation_points and self.isPhoton() and 'noringer' in self.noringerinfo():
252 self.etcut()
253 elif self.pidname() in self.__operation_points and self.isPhoton() and 'noringer' not in self.noringerinfo():
254 self.nominal()
255
256 elif self.etthr()==0:
257 self.nocut()
258
259 if hasattr(self.tool(), "MonTool"):
260
261 doValidationMonitoring = flags.Trigger.doValidationMonitoring # True to monitor all chains for validation purposes
262 monGroups = self.__monGroups
263
264 if (any('egammaMon:online' in group for group in monGroups) or doValidationMonitoring):
265 self.addMonitoring(flags)
266
267
268 #
269 # Add monitoring tool
270 #
271 def addMonitoring(self, flags):
272
273 if self.tool().UseRinger:
274 monTool = GenericMonitoringTool(flags, 'MonTool'+self.__name)
275 monTool.defineHistogram('Eta', type='TH1F', path='EXPERT',title="#eta of Clusters; #eta; number of RoIs", xbins=50,xmin=-2.5,xmax=2.5)
276 monTool.defineHistogram('Phi',type='TH1F', path='EXPERT',title="#phi of Clusters; #phi; number of RoIs", xbins=64,xmin=-3.2,xmax=3.2)
277 monTool.defineHistogram('Et',type='TH1F', path='EXPERT',title="E_{T} of Clusters; E_{T} [MeV]; number of RoIs", xbins=60,xmin=0,xmax=5e4)
278 monTool.defineHistogram('NNOutput',type='TH1F', path='EXPERT',title="NN Output; NN; Count", xbins=17,xmin=-8,xmax=+8)
279
280 monTool.HistPath= 'FastCaloL2EgammaHypo/'+self.__name
281 self.tool().MonTool=monTool
282
283 else:
284
285 monTool = GenericMonitoringTool(flags, "MonTool_"+self.__name,
286 HistPath = 'FastCaloL2EgammaHypo/'+self.__name)
287 monTool.defineHistogram('dEta', type='TH1F', path='EXPERT', title="L2Calo Hypo #Delta#eta_{L2 L1}; #Delta#eta_{L2 L1}",
288 xbins=80, xmin=-0.01, xmax=0.01)
289 monTool.defineHistogram('dPhi', type='TH1F', path='EXPERT', title="L2Calo Hypo #Delta#phi_{L2 L1}; #Delta#phi_{L2 L1}",
290 xbins=80, xmin=-0.01, xmax=0.01)
291 monTool.defineHistogram('Et_em', type='TH1F', path='EXPERT', title="L2Calo Hypo cluster E_{T}^{EM};E_{T}^{EM} [MeV]",
292 xbins=50, xmin=-2000, xmax=100000)
293 monTool.defineHistogram('Eta', type='TH1F', path='EXPERT', title="L2Calo Hypo entries per Eta;Eta", xbins=100, xmin=-2.5, xmax=2.5)
294 monTool.defineHistogram('Phi', type='TH1F', path='EXPERT', title="L2Calo Hypo entries per Phi;Phi", xbins=128, xmin=-3.2, xmax=3.2)
295
296 cuts=['Input','has one TrigEMCluster', '#Delta #eta L2-L1', '#Delta #phi L2-L1','eta','rCore',
297 'eRatio','E_{T}^{EM}', 'E_{T}^{Had}','f_{1}','Weta2','Wstot','F3']
298
299 monTool.defineHistogram('CutCounter', type='TH1I', path='EXPERT', title="L2Calo Hypo Passed Cuts;Cut",
300 xbins=13, xmin=-1.5, xmax=12.5, opt="kCumulative", xlabels=cuts)
301
302 if flags.Trigger.doValidationMonitoring:
303 monTool.defineHistogram('Et_had', type='TH1F', path='EXPERT', title="L2Calo Hypo E_{T}^{had} in first layer;E_{T}^{had} [MeV]",
304 xbins=50, xmin=-2000, xmax=100000)
305 monTool.defineHistogram('RCore', type='TH1F', path='EXPERT', title="L2Calo Hypo R_{core};E^{3x7}/E^{7x7} in sampling 2",
306 xbins=48, xmin=-0.1, xmax=1.1)
307 monTool.defineHistogram('Eratio', type='TH1F', path='EXPERT',
308 title="L2Calo Hypo E_{ratio};E^{max1}-E^{max2}/E^{max1}+E^{max2} in sampling 1 (excl.crack)",
309 xbins=64, xmin=-0.1, xmax=1.5)
310 monTool.defineHistogram('EtaBin', type='TH1I', path='EXPERT', title="L2Calo Hypo entries per Eta bin;Eta bin no.",
311 xbins=11, xmin=-0.5, xmax=10.5)
312 monTool.defineHistogram('F1', type='TH1F', path='EXPERT', title="L2Calo Hypo f_{1};f_{1}", xbins=34, xmin=-0.5, xmax=1.2)
313 monTool.defineHistogram('Weta2', type='TH1F', path='EXPERT', title="L2Calo Hypo Weta2; E Width in sampling 2",
314 xbins=96, xmin=-0.1, xmax=0.61)
315 monTool.defineHistogram('Wstot', type='TH1F', path='EXPERT', title="L2Calo Hypo Wstot; E Width in sampling 1",
316 xbins=48, xmin=-0.1, xmax=11.)
317 monTool.defineHistogram('F3', type='TH1F', path='EXPERT', title="L2Calo Hypo F3; E3/(E0+E1+E2+E3)",
318 xbins=96, xmin=-0.1, xmax=1.1)
319
320
321 self.tool().MonTool = monTool
322
323
324
325def _IncTool(flags, name, monGroups, cpart, tool=None):
326 config = TrigEgammaFastCaloHypoToolConfig(flags, name, monGroups, cpart, tool=tool )
327 config.compile(flags)
328 return config.tool()
329
330
331def TrigEgammaFastCaloHypoToolFromDict(flags, chainDict , tool=None):
332 """ Use menu decoded chain dictionary to configure the tool """
333 cparts = [i for i in chainDict['chainParts'] if ((i['signature']=='Electron') or (i['signature']=='Photon'))]
334 return _IncTool( flags, chainDict['chainName'], chainDict['monGroups'], cparts[0], tool=tool)
335
336
337
338def createTrigEgammaFastCaloElectronSelectors(flags, ConfigFilePath=None):
339
340 if not ConfigFilePath:
341 ConfigFilePath = flags.Trigger.egamma.ringerVersion
342
343
344 SelectorNames = {
345 'tight' : 'AsgElectronFastCaloRingerTightSelectorTool',
346 'medium' : 'AsgElectronFastCaloRingerMediumSelectorTool',
347 'loose' : 'AsgElectronFastCaloRingerLooseSelectorTool',
348 'vloose' : 'AsgElectronFastCaloRingerVeryLooseSelectorTool',
349 }
350
351
352 ToolConfigFile = {
353 'tight' :['ElectronRingerTightTriggerConfig.conf' ],
354 'medium' :['ElectronRingerMediumTriggerConfig.conf' ],
355 'loose' :['ElectronRingerLooseTriggerConfig.conf' ],
356 'vloose' :['ElectronRingerVeryLooseTriggerConfig.conf'],
357 }
358
359 selectors = []
360
361 for pidname , name in SelectorNames.items():
362 SelectorTool=CompFactory.Ringer.AsgRingerSelectorTool(name)
363 SelectorTool.ConfigFiles = [ (ConfigFilePath+'/'+path) for path in ToolConfigFile[pidname] ]
364 selectors.append(SelectorTool)
365 return selectors
366
367
368
369def createTrigEgammaFastCaloPhotonSelectors(flags, ConfigFilePath=None):
370
371 if not ConfigFilePath:
372 ConfigFilePath = flags.Trigger.egamma.photonRingerVersion
373
374
375 SelectorNames = {
376 'tight' : 'AsgPhotonFastCaloRingerTightSelectorTool',
377 'medium' : 'AsgPhotonFastCaloRingerMediumSelectorTool',
378 'loose' : 'AsgPhotonFastCaloRingerLooseSelectorTool',
379 }
380
381
382 ToolConfigFile = {
383 'tight' :['PhotonRingerTightTriggerConfig.conf' ],
384 'medium' :['PhotonRingerMediumTriggerConfig.conf' ],
385 'loose' :['PhotonRingerLooseTriggerConfig.conf' ],
386 }
387
388 selectors = []
389
390 for pidname , name in SelectorNames.items():
391 SelectorTool=CompFactory.Ringer.AsgRingerSelectorTool(name)
392 SelectorTool.UseTansigOutput = True # FIXME: Should be removed in the next round
393 SelectorTool.ConfigFiles = [ (ConfigFilePath+'/'+path) for path in ToolConfigFile[pidname] ]
394 selectors.append(SelectorTool)
395 return selectors
const bool debug
_IncTool(flags, name, monGroups, cpart, tool=None)
photonRingerFastCaloHypoConfig(flags, name, sequenceOut)
TrigEgammaFastCaloHypoAlgCfg(flags, name, CaloClusters)
createTrigEgammaFastCaloHypoAlg_noringer(flags, name, sequenceOut)
electronRingerFastCaloHypoConfig(flags, name, sequenceOut)
createTrigEgammaFastCaloHypoAlg(flags, name, sequenceOut)
createTrigEgammaFastCaloElectronSelectors(flags, ConfigFilePath=None)
createTrigEgammaFastCaloPhotonSelectors(flags, ConfigFilePath=None)
TrigEgammaFastCaloHypoToolFromDict(flags, chainDict, tool=None)