ATLAS Offline Software
Loading...
Searching...
No Matches
TrigTauHypoTool.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3from typing import Any
4
5from AthenaCommon.SystemOfUnits import GeV
6from AthenaConfiguration.AthConfigFlags import AthConfigFlags
7
8from .TrigTauHypoMonitoring import getTrigTauPrecisionIDHypoToolMonitoring, getTrigTauPrecisionDiKaonHypoToolMonitoring
9
10from AthenaCommon.Logging import logging
11log = logging.getLogger('TrigHLTTauHypoTool')
12
13#============================================================================================
14# Precision step hypothesis tool
15#============================================================================================
16def TrigTauPrecisionHypoToolFromDict(flags: AthConfigFlags, chainDict: dict[str, Any]):
17 chainPart = chainDict['chainParts'][0]
18
19 from TriggerMenuMT.HLT.Tau.TauConfigurationTools import getChainIDConfigName
20 identification = getChainIDConfigName(chainPart)
21
22 if identification == 'MesonCuts':
23 # Meson cut-based triggers (ATR-22644)
24 return TrigTauPrecisionDiKaonHypoToolFromDict(flags, chainDict)
25 else:
26 # Everything else
27 return TrigTauPrecisionIDHypoToolFromDict(flags, chainDict)
28
29#-----------------------------------------------------------------
30# Standard tau triggers configuration
31#-----------------------------------------------------------------
32class TauCuts:
33 def __init__(self, chain_part: dict[str, Any]):
34 self._chain_part = chain_part
35
36 @property
37 def n_track_max(self) -> int: return 3
38
39 @property
40 def n_iso_track_max(self) -> int: return 999 if self._chain_part['selection'] == 'idperf' else 1
41
42 @property
43 def pt_min(self) -> float: return float(self._chain_part['threshold']) * GeV
44
45 @property
46 def id_wp(self) -> int:
47 sel = self._chain_part['selection']
48
49 if sel == 'perf' or sel == 'idperf': return -1 # disabled
50 elif sel.startswith('veryloose'): return 0
51 elif sel.startswith('loose'): return 1
52 elif sel.startswith('medium'): return 2
53 elif sel.startswith('tight'): return 3
54
55 raise ValueError(f'Invalid selection: {sel}')
56
57def TrigTauPrecisionIDHypoToolFromDict(flags: AthConfigFlags, chainDict: dict[str, Any]):
58 '''TrigTauPrecisionIDHypoTool configuration for the standard Tau triggers'''
59 name = chainDict['chainName']
60 chainPart = chainDict['chainParts'][0]
61 cuts = TauCuts(chainPart)
62
63 # Setup the Hypothesis tool
64 from AthenaConfiguration.ComponentFactory import CompFactory
65 currentHypo = CompFactory.TrigTauPrecisionIDHypoTool(
66 name,
67 PtMin=cuts.pt_min,
68 NTracksMax=cuts.n_track_max,
69 NIsoTracksMax=cuts.n_iso_track_max,
70 IDWP=cuts.id_wp,
71 )
72
73 from TriggerMenuMT.HLT.Tau.TauConfigurationTools import getChainIDConfigName, getChainPrecisionSeqName, useBuiltInTauJetRNNScore, getPrecisionSequenceTauIDs, getTauIDScoreVariables
74
75 id_score_monitoring = {}
76
77 precision_seq_name = getChainPrecisionSeqName(chainPart)
78 identification = getChainIDConfigName(chainPart)
79 if identification in ['perf', 'idperf']:
80 if identification == 'idperf':
81 currentHypo.AcceptAll = True
82
83 # Monitor all the included algorithms
84 used_builtin_rnnscore = False
85 for tau_id in getPrecisionSequenceTauIDs(flags, precision_seq_name):
86 # Skip algs without inference scores
87 if tau_id in ['MesonCuts']: continue
88
89 # We can only have at most one alg. using the built-in TauJet RNN score variables
90 if useBuiltInTauJetRNNScore(tau_id, precision_seq_name):
91 if used_builtin_rnnscore:
92 raise ValueError('Cannot have two TauID algorithms with scores stored in the built-in TauJet RNN score variables')
93 used_builtin_rnnscore = True
94
95 id_score_monitoring[tau_id] = getTauIDScoreVariables(tau_id, precision_seq_name)
96
97 else:
98 if useBuiltInTauJetRNNScore(identification, precision_seq_name):
99 # To support the legacy tracktwoMVA/LLP/LRT chains, only in those cases we store the
100 # ID score and passed WPs in the native TauJet variables
101 currentHypo.IDMethod = 1 # TauJet built-in RNN score
102 else:
103 # Decorator-based triggers
104 currentHypo.IDMethod = 2 # Use decorators
105 currentHypo.IDWPNames = [f'{identification}_{wp}' for wp in getattr(flags.Trigger.Offline.Tau, identification).WPNames]
106
107 # Monitor this algorithm only
108 id_score_monitoring[identification] = getTauIDScoreVariables(identification, precision_seq_name)
109
110 # For any triggers following the tracktwoMVA reconstruction (2023+ DeepSet and GNTau)
111 if chainPart['reconstruction'] == 'tracktwoMVA':
112 currentHypo.TrackPtCut = 1.5*GeV
113 currentHypo.HighPtSelectionLooseIDThr = 200*GeV
114 currentHypo.HighPtSelectionJetThr = 430*GeV
115
116 # Only monitor chains with the 'tauMon:online' groups
117 if 'tauMon:online' in chainDict['monGroups']:
118 currentHypo.MonTool = getTrigTauPrecisionIDHypoToolMonitoring(flags, name, id_score_monitoring.keys())
119
120 # TauID Score monitoring
121 currentHypo.MonitoredIDScores = id_score_monitoring
122
123 return currentHypo
124
125
126#-----------------------------------------------------------------
127# Meson cut-based triggers configuration (ATR-22644 + ATR-23239)
128#-----------------------------------------------------------------
129from collections import namedtuple
130
131DiKaonCuts = namedtuple('DiKaonCuts', 'massTrkSysMin massTrkSysMax massTrkSysKaonMin massTrkSysKaonMax massTrkSysKaonPiMin massTrkSysKaonPiMax targetMassTrkSysKaonPi leadTrkPtMin PtMin EMPOverTrkSysPMax')
132thresholds_dikaon = {
133 ('dikaonmass', 25): DiKaonCuts(0.0*GeV, 1000.0*GeV, 0.987*GeV, 1.060*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 15.0*GeV, 25.0*GeV, 1.5),
134 ('dikaonmass', 35): DiKaonCuts(0.0*GeV, 1000.0*GeV, 0.987*GeV, 1.060*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 25.0*GeV, 35.0*GeV, 1.5),
135
136 ('kaonpi1', 25): DiKaonCuts(0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 0.79*GeV, 0.99*GeV, 0.89*GeV, 15.0*GeV, 25.0*GeV, 1.0),
137 ('kaonpi1', 35): DiKaonCuts(0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 0.79*GeV, 0.99*GeV, 0.89*GeV, 25.0*GeV, 35.0*GeV, 1.0),
138
139 ('kaonpi2', 25): DiKaonCuts(0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 1.8*GeV, 1.93*GeV, 1.865*GeV, 15.0*GeV, 25.0*GeV, 1.0),
140 ('kaonpi2', 35): DiKaonCuts(0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 1.8*GeV, 1.93*GeV, 1.865*GeV, 25.0*GeV, 35.0*GeV, 1.0),
141
142 ('dipion1', 25): DiKaonCuts(0.475*GeV, 1.075*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 15.0*GeV, 25.0*GeV, 1.0),
143 ('dipion2', 25): DiKaonCuts(0.460*GeV, 0.538*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 15.0*GeV, 25.0*GeV, 1.0),
144 ('dipion3', 25): DiKaonCuts(0.279*GeV, 0.648*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 25.0*GeV, 25.0*GeV, 2.2),
145 ('dipion4', 25): DiKaonCuts(0.460*GeV, 1.075*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 1000.0*GeV, 0.0*GeV, 15.0*GeV, 25.0*GeV, 1.0),
146}
147
148SinglePionCuts = namedtuple('SinglePionCuts', 'leadTrkPtMin PtMin NTracksMax NIsoTracksMax dRmaxMax etOverPtLeadTrkMin etOverPtLeadTrkMax')
149thresholds_singlepion = {
150 ('singlepion', 25): SinglePionCuts(30.0*GeV, 25.0*GeV, 1, 0, 0.06, 0.4, 0.85),
151}
152
153def TrigTauPrecisionDiKaonHypoToolFromDict(flags: AthConfigFlags, chainDict: dict[str, Any]):
154 '''TrigTauPrecisionDiKaonHypoTool configuration for the meson cut-based Tau triggers (ATR-22644)'''
155 name = chainDict['chainName']
156 chainPart = chainDict['chainParts'][0]
157
158 # Setup the Hypothesis tool
159 from AthenaConfiguration.ComponentFactory import CompFactory
160 currentHypo = CompFactory.TrigTauPrecisionDiKaonHypoTool(name)
161
162 key = (chainPart['selection'], int(chainPart['threshold']))
163 if key in thresholds_dikaon:
164 thr = thresholds_dikaon[key]
165 currentHypo.PtMin = thr.PtMin
166 currentHypo.leadTrkPtMin = thr.leadTrkPtMin
167 currentHypo.massTrkSysMin = thr.massTrkSysMin
168 currentHypo.massTrkSysMax = thr.massTrkSysMax
169 currentHypo.massTrkSysKaonMin = thr.massTrkSysKaonMin
170 currentHypo.massTrkSysKaonMax = thr.massTrkSysKaonMax
171 currentHypo.massTrkSysKaonPiMin = thr.massTrkSysKaonPiMin
172 currentHypo.massTrkSysKaonPiMax = thr.massTrkSysKaonPiMax
173 currentHypo.targetMassTrkSysKaonPi = thr.targetMassTrkSysKaonPi
174 currentHypo.EMPOverTrkSysPMax = thr.EMPOverTrkSysPMax
175
176 elif key in thresholds_singlepion:
177 thr = thresholds_singlepion[key]
178 currentHypo.PtMin = thr.PtMin
179 currentHypo.NTracksMax = thr.NTracksMax
180 currentHypo.NIsoTracksMax = thr.NIsoTracksMax
181 currentHypo.leadTrkPtMin = thr.leadTrkPtMin
182 currentHypo.dRmaxMax = thr.dRmaxMax
183 currentHypo.etOverPtLeadTrkMin = thr.etOverPtLeadTrkMin
184 currentHypo.etOverPtLeadTrkMax = thr.etOverPtLeadTrkMax
185
186 currentHypo.MonTool = getTrigTauPrecisionDiKaonHypoToolMonitoring(flags, name)
187
188 return currentHypo
189
190
191
192#============================================================================================
193# Tracking step hypothesis tool (without selection)
194#============================================================================================
195def TrigTauTrackingHypoToolFromDict(flags: AthConfigFlags, chainDict: dict[str, Any]):
196 name = chainDict['chainName']
197
198 from AthenaConfiguration.ComponentFactory import CompFactory
199 currentHypo = CompFactory.TrigTauTrackingHypoTool(name)
200
201 return currentHypo
202
203
204
205#============================================================================================
206# CaloMVA step hypothesis tool
207#============================================================================================
208def TrigTauCaloMVAHypoToolFromDict(flags: AthConfigFlags, chainDict: dict[str, Any]):
209 name = chainDict['chainName']
210 threshold = float(chainDict['chainParts'][0]['threshold'])
211
212 from AthenaConfiguration.ComponentFactory import CompFactory
213 currentHypo = CompFactory.TrigTauCaloHypoTool(name)
214 currentHypo.PtMin = threshold * GeV
215
216 return currentHypo
217
__init__(self, dict[str, Any] chain_part)
TrigTauTrackingHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
TrigTauPrecisionIDHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
TrigTauCaloMVAHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
TrigTauPrecisionDiKaonHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
TrigTauPrecisionHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)