ATLAS Offline Software
TrigMinBiasEffMonitoring.py
Go to the documentation of this file.
1 #
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 
9 from .utils import getMinBiasChains
10 from AthenaCommon.Logging import logging
11 from AthenaConfiguration.ComponentFactory import CompFactory
12 
13 log = logging.getLogger('TrigMinBiasEffMonitoring')
14 
15 
16 def _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 
79 def 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 
226 if __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
vtune_athena.format
format
Definition: vtune_athena.py:14
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.TriggerConfigAccess.getHLTMonitoringAccess
HLTMonitoringAccess getHLTMonitoringAccess(flags=None)
Definition: TriggerConfigAccess.py:256
python.InDetTrackSelectionToolConfig.InDetTrackSelectionTool_LoosePrimary_Cfg
def InDetTrackSelectionTool_LoosePrimary_Cfg(flags, name="InDetTrackSelectionTool_LoosePrimary", **kwargs)
Configs based on CutLevel LoosePrimary #####.
Definition: InDetTrackSelectionToolConfig.py:49
TrigMinBiasEffMonitoring.TrigMinBiasEff
def TrigMinBiasEff(flags)
Definition: TrigMinBiasEffMonitoring.py:79
covarianceTool.filter
filter
Definition: covarianceTool.py:514
python.MainServicesConfig.MainServicesCfg
def MainServicesCfg(flags, LoopMgr='AthenaEventLoopMgr')
Definition: MainServicesConfig.py:256
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
Trk::open
@ open
Definition: BinningType.h:40
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
utils.getMinBiasChains
def getMinBiasChains(monAccess, wildcard='')
Definition: Trigger/TrigMonitoring/TrigMinBiasMonitoring/python/utils.py:7
TrigMinBiasEffMonitoring._TrigEff
def _TrigEff(flags, triggerAndRef, algname='HLTMinBiasEffMonitoringAlg')
Definition: TrigMinBiasEffMonitoring.py:16
python.PoolReadConfig.PoolReadCfg
def PoolReadCfg(flags)
Definition: PoolReadConfig.py:69