ATLAS Offline Software
TrigTauHypoTool.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 from typing import Any
4 
5 from AthenaCommon.SystemOfUnits import GeV
6 from AthenaConfiguration.AthConfigFlags import AthConfigFlags
7 
8 from .TrigTauHypoMonitoring import getTrigTauPrecisionIDHypoToolMonitoring, getTrigTauPrecisionDiKaonHypoToolMonitoring
9 
10 from AthenaCommon.Logging import logging
11 log = logging.getLogger('TrigHLTTauHypoTool')
12 
13 #============================================================================================
14 # Precision step hypothesis tool
15 #============================================================================================
16 def 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 #-----------------------------------------------------------------
32 class 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 
57 def 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 #-----------------------------------------------------------------
129 from collections import namedtuple
130 
131 DiKaonCuts = namedtuple('DiKaonCuts', 'massTrkSysMin massTrkSysMax massTrkSysKaonMin massTrkSysKaonMax massTrkSysKaonPiMin massTrkSysKaonPiMax targetMassTrkSysKaonPi leadTrkPtMin PtMin EMPOverTrkSysPMax')
132 thresholds_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 
148 SinglePionCuts = namedtuple('SinglePionCuts', 'leadTrkPtMin PtMin NTracksMax NIsoTracksMax dRmaxMax etOverPtLeadTrkMin etOverPtLeadTrkMax')
149 thresholds_singlepion = {
150  ('singlepion', 25): SinglePionCuts(30.0*GeV, 25.0*GeV, 1, 0, 0.06, 0.4, 0.85),
151 }
152 
153 def 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 #============================================================================================
195 def 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 #============================================================================================
208 def 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 
TrigTauHypoTool.TauCuts.n_iso_track_max
int n_iso_track_max(self)
Definition: TrigTauHypoTool.py:40
SystemOfUnits
TrigTauHypoMonitoring.getTrigTauPrecisionIDHypoToolMonitoring
def getTrigTauPrecisionIDHypoToolMonitoring(AthConfigFlags flags, str name, list[str] tau_ids)
Definition: TrigTauHypoMonitoring.py:6
python.HLT.Tau.TauConfigurationTools.useBuiltInTauJetRNNScore
bool useBuiltInTauJetRNNScore(str tau_id, str precision_sequence)
Definition: TauConfigurationTools.py:97
TrigTauHypoTool.TauCuts.pt_min
float pt_min(self)
Definition: TrigTauHypoTool.py:43
TrigTauHypoTool.TauCuts
Definition: TrigTauHypoTool.py:32
TrigTauHypoTool.TauCuts._chain_part
_chain_part
Definition: TrigTauHypoTool.py:34
python.HLT.Tau.TauConfigurationTools.getPrecisionSequenceTauIDs
list[str] getPrecisionSequenceTauIDs(flags, str precision_sequence)
Sequence TauIDs.
Definition: TauConfigurationTools.py:15
TrigTauHypoTool.DiKaonCuts
DiKaonCuts
Definition: TrigTauHypoTool.py:131
python.HLT.Tau.TauConfigurationTools.getChainPrecisionSeqName
str getChainPrecisionSeqName(chainPart)
Definition: TauConfigurationTools.py:82
python.HLT.Tau.TauConfigurationTools.getTauIDScoreVariables
tuple[str, str] getTauIDScoreVariables(str tau_id, str precision_sequence)
Definition: TauConfigurationTools.py:106
TrigTauHypoMonitoring.getTrigTauPrecisionDiKaonHypoToolMonitoring
def getTrigTauPrecisionDiKaonHypoToolMonitoring(AthConfigFlags flags, str name)
Definition: TrigTauHypoMonitoring.py:37
TrigTauHypoTool.TrigTauTrackingHypoToolFromDict
def TrigTauTrackingHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
Definition: TrigTauHypoTool.py:195
TrigTauHypoTool.TauCuts.__init__
def __init__(self, dict[str, Any] chain_part)
Definition: TrigTauHypoTool.py:33
python.HLT.Tau.TauConfigurationTools.getChainIDConfigName
str getChainIDConfigName(chainPart)
Definition: TauConfigurationTools.py:50
TrigTauHypoTool.TauCuts.n_track_max
int n_track_max(self)
Definition: TrigTauHypoTool.py:37
TrigTauHypoTool.TrigTauPrecisionHypoToolFromDict
def TrigTauPrecisionHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
Definition: TrigTauHypoTool.py:16
TrigTauHypoTool.SinglePionCuts
SinglePionCuts
Definition: TrigTauHypoTool.py:148
TrigTauHypoTool.TauCuts.id_wp
int id_wp(self)
Definition: TrigTauHypoTool.py:46
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
TrigTauHypoTool.TrigTauPrecisionIDHypoToolFromDict
def TrigTauPrecisionIDHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
Definition: TrigTauHypoTool.py:57
TrigTauHypoTool.TrigTauPrecisionDiKaonHypoToolFromDict
def TrigTauPrecisionDiKaonHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
Definition: TrigTauHypoTool.py:153
TrigTauHypoTool.TrigTauCaloMVAHypoToolFromDict
def TrigTauCaloMVAHypoToolFromDict(AthConfigFlags flags, dict[str, Any] chainDict)
Definition: TrigTauHypoTool.py:208
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65