ATLAS Offline Software
Loading...
Searching...
No Matches
TrigMinBiasEffMonitoring.py
Go to the documentation of this file.
2# Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3#
4
5'''
6@brief configuration for the trigger efficiency monitoring
7'''
8
9from .utils import getMinBiasChains
10from AthenaCommon.Logging import logging
11from AthenaConfiguration.ComponentFactory import CompFactory
12
13log = logging.getLogger('TrigMinBiasEffMonitoring')
14
15
16def _TrigEff(flags, triggerAndRef, algname='HLTMinBiasEffMonitoringAlg'):
17 from AthenaMonitoring import AthMonitorCfgHelper
18 monConfig = AthMonitorCfgHelper(flags, algname)
19
20 alg = monConfig.addAlgorithm(
21 CompFactory.HLTMinBiasEffMonitoringAlg, algname)
22
23 from InDetConfig.InDetTrackSelectionToolConfig import InDetTrackSelectionTool_LoosePrimary_Cfg
24 trkSel = monConfig.resobj.popToolsAndMerge(InDetTrackSelectionTool_LoosePrimary_Cfg(flags))
25 alg.TrackSelectionTool = trkSel
26
27 alg.triggerList = [ el["chain"] for el in triggerAndRef ]
28 alg.refTriggerList = [ el["refchain"] for el in triggerAndRef ]
29
30 length = len(alg.triggerList)
31
32 mainGroup = monConfig.addGroup(alg, 'TrigAll', topPath='HLT/MinBiasMon/Counts/')
33
34 alreadyConfigured = set()
35 for cdef in triggerAndRef:
36 chain = cdef['chain']
37 refchain = cdef['refchain']
38 level = cdef['level']
39 xmin = cdef['xmin']
40 xmax = cdef['xmax']
41 xbins = xmax-xmin
42 effGroup = monConfig.addGroup(alg, chain+refchain, topPath=f'HLT/MinBiasMon/{level}/EffAll/')
43
44 whichcounter='nTrkOffline'
45 # if the chain cuts on higher pt (there is a few predefined chains) use different counter
46 if '_sptrk_pt' in chain:
47 effGroup.defineHistogram(f'EffPassed,leadingTrackPt;{chain}_ref_{refchain}_pt', type='TEfficiency',
48 title=chain+';Leading track pt;Efficiency', xbins=50, xmin=0.0, xmax=10)
49
50 # these chains have such name pattern: HLT_mb_sptrk_pt2_L1MBTS_2
51 whichcounter += '_'+chain.split('_')[3]
52 elif '_excl_' in chain:
53 effGroup.defineHistogram(f'EffPassed,nTrkOffline;{chain}_ref_{refchain}_exclusivity', type='TEfficiency',
54 title=chain+';Offline Good nTrk (low pt);Efficiency', xbins=30, xmin=-0.5, xmax=30-0.5)
55 effGroup.defineHistogram(f'EffPassed,leadingTrackPt;{chain}_ref_{refchain}_pt', type='TEfficiency',
56 title=chain+';Leading track pt;Efficiency', xbins=50, xmin=0.0, xmax=10)
57 # these chains have such form: HLT_mb_excl_1trk5_pt4_L1RD0_FILLED
58 whichcounter += '_'+chain.split('_')[4]
59
60 if '_pusup' in chain or '_hmt_' in chain:
61 whichcounter = 'nTrkOfflineVtx'
62 effGroup.defineHistogram(f'EffPassed,{whichcounter};{chain}_ref_{refchain}', type='TEfficiency',
63 title=f'{chain} ref: {refchain} ;Offline Good nTrk {whichcounter};Efficiency', xbins=xbins, xmin=xmin, xmax=xmax)
64
65
66
67 if chain not in alreadyConfigured:
68 alreadyConfigured.add(chain)
69 # need this protection because we can measure efficiency with several reference trigger, but want counts irrespective of ref. triggers
70 mainGroup.defineHistogram('nTrkOffline_counts_' + chain, type='TH1F',
71 title=chain+';Offline Good nTrk;Events', xbins=xmax-xmin, xmin=xmin, xmax=xmax)
72
73 mainGroup.defineHistogram('TrigCounts', title='Trigger counts;;Event rate',
74 xbins=length, xmin=0, xmax=len(alreadyConfigured), xlabels=list(alreadyConfigured))
75
76 return monConfig.result()
77
78
79def TrigMinBiasEff(flags):
80 from TrigConfigSvc.TriggerConfigAccess import getHLTMonitoringAccess
81 monAccess = getHLTMonitoringAccess(flags)
82
83 mbNames = [name for name, _ in getMinBiasChains(monAccess)]
84 if len(mbNames) == 0:
85 return _TrigEff(flags, [])
86
87 log.info(f'Monitoring {len(mbNames)} MinBias chains')
88 log.debug(mbNames)
89
90 # here we generate config with detailed settings
91 def _c(chain, refchain, level, **kwargs):
92 conf = {"chain": chain, "refchain": refchain, "level": level, "xmin": 0, "xmax": 20}
93 conf.update(kwargs)
94 return conf
95
96 def _isFilled(chain):
97 name, _ = chain
98 return "_EMPTY" not in name and "_UNPAIRED_ISO" not in name
99
100 spTrkChains = getMinBiasChains(monAccess, '(_sptrk_|_sp_|_mbts_)')
101 filledChains = list(filter(_isFilled, spTrkChains))
102 emptyChains = [chain for chain in spTrkChains if "_EMPTY" in chain[0]]
103 unpairedChains = [chain for chain in spTrkChains if "_UNPAIRED_ISO" in chain[0]]
104
105 triggerAndRef = []
106
107 # check all mb_sptrk chains w.r.t. random noalg
108 triggerAndRef += [_c(name, "HLT_noalg_L1RD0_FILLED", level) for name, level in filledChains]
109 triggerAndRef += [_c(name, "HLT_noalg_L1RD0_EMPTY", level) for name, level in emptyChains]
110 triggerAndRef += [_c(name, "HLT_noalg_L1RD0_UNPAIRED_ISO", level) for name, level in unpairedChains]
111
112 # for monitoring in MB stream
113 triggerAndRef += [_c(name, "HLT_noalg_mb_L1RD0_FILLED", level) for name, level in filledChains]
114 triggerAndRef += [_c(name, "HLT_noalg_mb_L1RD0_EMPTY", level) for name, level in emptyChains]
115 triggerAndRef += [_c(name, "HLT_noalg_mb_L1RD0_UNPAIRED_ISO", level) for name, level in unpairedChains]
116
117 # sptrk vs sp
118 triggerAndRef += [_c("HLT_mb_sptrk_L1RD0_FILLED", "HLT_mb_sp_L1RD0_FILLED", 'Shifter')]
119
120 # HMT chains
121 hmtChains = getMinBiasChains(monAccess, '(hmt)')
122 nonPusupChains = [chain for chain in hmtChains if '_pusup' not in chain[0]]
123 if len(nonPusupChains) != 0:
124 # sort by trk threshold
125 def _trk(chain):
126 name, _ = chain
127 part = name.split("_")
128 for el in part:
129 if el.startswith("trk"):
130 return int(el.strip("trk"))
131 raise RuntimeError(f"Chain {name} is not the hmt chain")
132
133 nonPusupChains.sort(key=lambda chain: int(_trk(chain)))
134
135 # monitor first hmt w.r.t sptrk
136 first = nonPusupChains[0]
137 triggerAndRef += [_c(first[0], "HLT_mb_sptrk_L1RD0_FILLED", first[1], xmax=_trk(first) + 30)]
138
139 # group set the ref for each trigger to be one of lower threshold : ordering of chains needs to be reviewed
140 triggerAndRef += [_c(chain[0], "HLT_mb_sptrk_L1RD0_FILLED", chain[1], xmin=_trk(chain) - 20, xmax=_trk(chain) + 50) for chain in nonPusupChains[1:]]
141
142 # pu suppressing trigger should be monitored using trigger of the same threshold w/o pu suppression
143 pusupChains = [chain for chain in hmtChains if '_pusup' in chain[0]]
144
145 def _dropsup(name):
146 s = name.split("_")
147 return "_".join(s[:3] + s[4:])
148
149 triggerAndRef += [_c(chain[0], _dropsup(chain[0]), chain[1], xmin=_trk(chain) - 20, xmax=_trk(chain) + 50) for chain in pusupChains]
150
151 # monitor exclusivity cut
152 exclChains = getMinBiasChains(monAccess, '(excl)')
153 for name, level in exclChains:
154 triggerAndRef.append(_c(name, 'HLT_mb_sptrk_L1RD0_FILLED', level))
155 triggerAndRef.append(_c(name, 'HLT_mb_sp_L1RD0_FILLED', level))
156
157 # monitor noalg MBTS chains
158 noalgMbtsChains = getMinBiasChains(monAccess, '^HLT_noalg_.*(L1MBTS)')
159 triggerAndRef += [_c(name, 'HLT_mb_sptrk_L1RD0_FILLED', level) for name, level in noalgMbtsChains]
160
161 # L1 MBTS
162 mbtsL1Chains = ["L1_MBTS_A", "L1_MBTS_C", "L1_MBTS_1", "L1_MBTS_2", "L1_MBTS_1_1"]
163 triggerAndRef += [_c(chain, 'HLT_mb_sptrk_L1RD0_FILLED', 'Expert') for chain in mbtsL1Chains]
164
165 # L1 transverse energy
166 triggerAndRef += [_c("L1_TE{}".format(i), 'HLT_mb_sptrk_L1RD0_FILLED', 'Expert', xmin=0, xmax=100) for i in [3, 5, 10, 40]]
167
168 # Pair HLT chain with its noalg version
169 def _find_noalg(chain):
170 pos = chain.find('L1')
171 return 'HLT_noalg_' + chain[pos:]
172
173 def _chains_with_noalg_ref():
174 chains = []
175
176 for name, level in filledChains:
177 # Already added
178 if 'L1RD0_FILLED' in name:
179 continue
180
181 noalg = _find_noalg(name)
182 if noalg not in mbNames:
183 continue
184
185 chains.append(_c(name, noalg, level))
186
187 return chains
188
189 triggerAndRef += _chains_with_noalg_ref()
190
191 # HI chains
192 hiChains = getMinBiasChains(monAccess, '(_hi_)')
193
194 # Pair MB+HI chains with MB only reference if it exists
195 def _hi_chain_with_mb_ref():
196 chains = []
197
198 for name, level in hiChains:
199 split = name.split('_hi_')
200 if len(split) != 2:
201 continue
202 mb, hi_l1 = split
203
204 split = hi_l1.split('L1')
205 if len(split) != 2:
206 continue
207 hi, l1 = split
208
209 ref = f'{mb}_L1{l1}'
210 if ref not in mbNames:
211 continue
212
213 chains.append(_c(name, ref, level))
214
215 return chains
216
217 triggerAndRef += _hi_chain_with_mb_ref()
218
219 # Add here all the special cases:
220 # HI Fgap chains
221 triggerAndRef.append(_c('HLT_mb_excl_1trk4_pt1_hi_FgapAC5_L12eEM1_VjTE200', 'HLT_mb_excl_1trk4_pt1_L12eEM1_VjTE200_GAP_AANDC', 'Expert'))
222
223 return _TrigEff(flags, triggerAndRef)
224
225
226if __name__ == '__main__':
227 # Set the Athena configuration flags
228 from AthenaConfiguration.AllConfigFlags import initConfigFlags
229 flags = initConfigFlags()
230 flags.Output.HISTFileName = 'TestMinBiasMonitorOutput.root'
231 flags.fillFromArgs()
232 flags.lock()
233
234 # Initialize configuration object, add accumulator, merge, and run.
235 from AthenaConfiguration.MainServicesConfig import MainServicesCfg
236 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
237 cfg = MainServicesCfg(flags)
238 cfg.merge(PoolReadCfg(flags))
239 cfg.merge(TrigMinBiasEff(flags))
240
241
242 # cfg.getEventAlgo('HLTMinBiasEffMonitoringAlg').OutputLevel = DEBUG # DEBUG
243 cfg.printConfig(withDetails=True) # set True for exhaustive info
244 with open("cfg.pkl", "wb") as f:
245 cfg.store(f)
246
247 cfg.run()
248 # to run:
249 # python -m TrigMinBiasMonitoring.TrigMinBiasEffMonitoring --filesInput=filepath --evtMax=XYZ
STL class.
_TrigEff(flags, triggerAndRef, algname='HLTMinBiasEffMonitoringAlg')