ATLAS Offline Software
Loading...
Searching...
No Matches
DiTauAnalysisConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3# AnaAlgorithm import(s):
4from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
5from AnalysisAlgorithmsConfig.ConfigSequence import groupBlocks
6from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
7
8
9class DiTauCalibrationConfig (ConfigBlock):
10 """the ConfigBlock for the tau four-momentum correction"""
11
12 def __init__ (self) :
13 super().__init__()
14 self.setBlockName('DiTaus')
15 self.addOption ('inputContainer', '', type=str,
16 info="the name of the input ditau-jet container.")
17 self.addOption ('containerName', '', type=str,
18 noneAction='error',
19 info="the name of the output container after calibration.",
20 meta={'role':'container'})
21 self.addOption ('postfix', '', type=str,
22 info="a postfix to apply to decorations and algorithm names. "
23 "Typically not needed here since the calibration is common to "
24 "all ditau-jets.")
25 self.addOption ('quality', None, type=str,
26 info="the ID WP to use. Supported ID WPs: `Tight`, `Medium`,`Loose`,`NoID`.",
27 meta={'choices':(['Tight','Medium','Loose','NoID'],1)})
28 self.addOption ('rerunTruthMatching', True, type=bool,
29 info="whether to rerun truth matching (sets up an instance of "
30 "`CP::DiTauTruthMatchingAlg`).")
31 self.addOption ('decorateTruth', False, type=bool,
32 info="decorate the truth particle information on the reconstructed one.")
33 self.addOption ('decorateExtraVariables', True, type=bool,
34 info="decorate extra variables for the reconstructed ditau-jet.")
35
36 def instanceName (self) :
37 """Return the instance name for this block"""
38 return self.containerName + self.postfix
39
40 def makeAlgs (self, config) :
41
42 postfix = self.postfix
43 if postfix != '' and postfix[0] != '_' :
44 postfix = '_' + postfix
45
46 inputContainer = "DiTauJets"
48 inputContainer = self.inputContainer
49 config.setSourceName (self.containerName, inputContainer)
50
51 # Set up the tau truth matching algorithm:
52 if self.rerunTruthMatching and config.dataType() is not DataType.Data:
53 alg = config.createAlgorithm( 'CP::DiTauTruthMatchingAlg',
54 'DiTauTruthMatchingAlg' )
55 config.addPrivateTool( 'matchingTool',
56 'TauAnalysisTools::DiTauTruthMatchingTool' )
57 alg.taus = config.readName (self.containerName)
58 alg.preselection = config.getPreselection (self.containerName, '')
59
60
61 # decorate truth tau information on the reconstructed object:
62 if self.decorateTruth and self.rerunTruthMatching and config.dataType() is not DataType.Data:
63 # in the case of the ditau, the DiTauTruthMatchingTool decorates directly the reco ditau with truth information.
64 # So information can be written directly out without any additional algorithm
65 config.addOutputVar (self.containerName, 'TruthVisLeadPt', 'TruthVisLeadPt', noSys=True)
66 config.addOutputVar (self.containerName, 'TruthVisLeadEta', 'TruthVisLeadEta', noSys=True)
67 config.addOutputVar (self.containerName, 'TruthVisLeadPhi', 'TruthVisLeadPhi', noSys=True)
68 config.addOutputVar (self.containerName, 'TruthVisLeadM', 'TruthVisLeadM', noSys=True)
69 config.addOutputVar (self.containerName, 'TruthLeadPdgID', 'TruthLeadPdgID', noSys=True)
70 config.addOutputVar (self.containerName, 'TruthVisSubleadPt', 'TruthVisSubleadPt', noSys=True)
71 config.addOutputVar (self.containerName, 'TruthVisSubleadEta', 'TruthVisSubleadEta', noSys=True)
72 config.addOutputVar (self.containerName, 'TruthVisSubleadPhi', 'TruthVisSubleadPhi', noSys=True)
73 config.addOutputVar (self.containerName, 'TruthVisSubleadM', 'TruthVisSubleadM', noSys=True)
74 config.addOutputVar (self.containerName, 'TruthSubleadPdgID', 'TruthSubleadPdgID', noSys=True)
75 config.addOutputVar (self.containerName, 'TruthVisDeltaR', 'TruthVisDeltaR', noSys=True)
76 config.addOutputVar (self.containerName, 'TruthVisMass', 'TruthVisMass', noSys=True)
77 config.addOutputVar (self.containerName, 'IsTruthMatched', 'IsTruthMatched', noSys=True)
78 config.addOutputVar (self.containerName, 'IsTruthHadronic', 'IsTruthHadronic', noSys=True)
79
80 # Decorate extra variables
82 alg = config.createAlgorithm( 'CP::DiTauExtraVariablesAlg',
83 'DiTauExtraVariablesAlg',
84 reentrant=True )
85 alg.ditaus = config.readName (self.containerName)
86 config.addOutputVar (self.containerName, 'omniScore', 'omniScore', noSys=True)
87 config.addOutputVar (self.containerName, 'nSubjets', 'nSubjets', noSys=True)
88 config.addOutputVar (self.containerName, 'leadSubjetPt', 'leadSubjetPt', noSys=True)
89 config.addOutputVar (self.containerName, 'leadSubjetEta', 'leadSubjetEta', noSys=True)
90 config.addOutputVar (self.containerName, 'leadSubjetPhi', 'leadSubjetPhi', noSys=True)
91 config.addOutputVar (self.containerName, 'leadSubjetE', 'leadSubjetE', noSys=True)
92 config.addOutputVar (self.containerName, 'leadSubjetNTracks', 'leadSubjetNTracks', noSys=True)
93 config.addOutputVar (self.containerName, 'leadSubjetCharge', 'leadSubjetCharge', noSys=True)
94 config.addOutputVar (self.containerName, 'subleadSubjetPt', 'subleadSubjetPt', noSys=True)
95 config.addOutputVar (self.containerName, 'subleadSubjetEta', 'subleadSubjetEta', noSys=True)
96 config.addOutputVar (self.containerName, 'subleadSubjetPhi', 'subleadSubjetPhi', noSys=True)
97 config.addOutputVar (self.containerName, 'subleadSubjetE', 'subleadSubjetE', noSys=True)
98 config.addOutputVar (self.containerName, 'subleadSubjetNTracks', 'subleadSubjetNTracks', noSys=True)
99 config.addOutputVar (self.containerName, 'subleadSubjetCharge', 'subleadSubjetCharge', noSys=True)
100
101 # Set up the tau 4-momentum smearing algorithm:
102 alg = config.createAlgorithm( 'CP::DiTauSmearingAlg', 'DiTauSmearingAlg' )
103 config.addPrivateTool( 'smearingTool', 'TauAnalysisTools::DiTauSmearingTool' )
104 alg.taus = config.readName (self.containerName)
105 alg.tausOut = config.copyName (self.containerName)
106 alg.preselection = config.getPreselection (self.containerName, '')
107
108 # Save base kinematic ditau variables in output
109 config.addOutputVar (self.containerName, 'pt', 'pt')
110 config.addOutputVar (self.containerName, 'eta', 'eta', noSys=True)
111 config.addOutputVar (self.containerName, 'phi', 'phi', noSys=True)
112 config.addOutputVar (self.containerName, 'm', 'm', noSys=True)
113
114
115
117 """the ConfigBlock for the tau working point selection"""
118
119 def __init__ (self) :
120 super().__init__()
121 self.setBlockName('DiTauWorkingPointSelection')
122 self.addOption ('containerName', '', type=str,
123 noneAction='error',
124 info="the name of the input container.",
125 meta={'role':'containerRef'})
126 self.addOption ('selectionName', '', type=str,
127 noneAction='error',
128 info="the name of the ditau-jet selection to define (e.g. `tight` or "
129 "`loose`).",
130 meta={'role':'selection'})
131 self.addOption ('postfix', None, type=str,
132 info="a postfix to apply to decorations and algorithm names. "
133 "Typically not needed here as `selectionName` is used internally.")
134 self.addOption ('quality', None, type=str,
135 info="the ID WP to use for high-pt ditau-jets (ignored for `DiTauJetsLowPt` containers). "
136 "Supported ID WPs: `Tight`, `Medium`, `Loose`, `NoID`.",
137 meta={'choices':(['Tight','Medium','Loose','NoID'],1)})
138 self.addOption ('addSelectionToPreselection', True, type=bool,
139 info="whether to retain only ditau-jets satisfying the working point "
140 "requirements.")
141
142 def instanceName (self) :
143 """Return the instance name for this block"""
144 if self.postfix is not None:
145 return self.containerName + '_' + self.selectionName + self.postfix
146 else:
147 return self.containerName + '_' + self.selectionName
148
149 def makeAlgs (self, config) :
150
151 selectionPostfix = self.selectionName
152 if selectionPostfix != '' and selectionPostfix[0] != '_' :
153 selectionPostfix = '_' + selectionPostfix
154
155 postfix = self.postfix
156 if postfix is None :
157 postfix = self.selectionName
158 if postfix != '' and postfix[0] != '_' :
159 postfix = '_' + postfix
160
161 if "DiTauJetsLowPt" in self.containerName:
162 inputfile = 'TauAnalysisAlgorithms/ditau_selection_lowpt.conf'
163 else:
164 if self.quality not in ['Tight', 'Medium', 'Loose', 'NoID'] :
165 raise ValueError (f"invalid ditau quality: \"{self.quality}\", allowed values are Tight, Medium, Loose, NoID")
166 if self.quality == 'NoID':
167 inputfile = 'TauAnalysisAlgorithms/ditau_selection_highpt.conf'
168 else:
169 inputfile = 'TauAnalysisAlgorithms/ditau_selection_highpt_'+self.quality.lower()+'.conf'
170
171 # Set up the algorithm selecting taus:
172 alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'DiTauSelectionAlg' )
173 config.addPrivateTool( 'selectionTool', 'TauAnalysisTools::DiTauSelectionTool' )
174 alg.selectionTool.ConfigPath = inputfile
175 alg.selectionDecoration = 'selected_ditau' + selectionPostfix + ',as_char'
176 alg.particles = config.readName (self.containerName)
177 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
178 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
179 preselection=self.addSelectionToPreselection)
180
181
183 """the ConfigBlock for the tau working point efficiency computation"""
184
185 def __init__ (self) :
186 super().__init__()
187 self.setBlockName('DiTauWorkingPointEfficiency')
188 self.addDependency('DiTauWorkingPointSelection', required=True)
189 self.addDependency('EventSelection', required=False)
190 self.addDependency('EventSelectionMerger', required=False)
191 self.addOption ('containerName', '', type=str,
192 noneAction='error',
193 info="the name of the input container.",
194 meta={'role':'containerRef'})
195 self.addOption ('selectionName', '', type=str,
196 noneAction='error',
197 info="the name of the ditau-jet selection to define (e.g. `tight` or "
198 "`loose`).",
199 meta={'role':'selection'})
200 self.addOption ('postfix', None, type=str,
201 info="a postfix to apply to decorations and algorithm names. "
202 "Typically not needed here as `selectionName` is used internally.")
203
204 def instanceName (self) :
205 """Return the instance name for this block"""
206 if self.postfix is not None:
207 return self.containerName + '_' + self.selectionName + self.postfix
208 else:
209 return self.containerName + '_' + self.selectionName
210
211 def makeAlgs (self, config) :
212
213 selectionPostfix = self.selectionName
214 if selectionPostfix != '' and selectionPostfix[0] != '_' :
215 selectionPostfix = '_' + selectionPostfix
216
217 postfix = self.postfix
218 if postfix is None :
219 postfix = self.selectionName
220 if postfix != '' and postfix[0] != '_' :
221 postfix = '_' + postfix
222
223
224 # keep this commented out until TauCP won't provide official recommendations
225 # Set up the algorithm calculating the efficiency scale factors for the
226 # taus:
227 #if config.dataType() is not DataType.Data:
228 # alg = config.createAlgorithm( 'CP::DiTauEfficiencyCorrectionsAlg',
229 # 'DiTauEfficiencyCorrectionsAlg' )
230 # config.addPrivateTool( 'efficiencyCorrectionsTool',
231 # 'TauAnalysisTools::DiTauEfficiencyCorrectionsTool' )
232 # alg.efficiencyCorrectionsTool.JetIDLevel = IDLevel
233 # alg.scaleFactorDecoration = 'tau_effSF' + postfix + '_%SYS%'
234 # # alg.outOfValidity = 2 #silent
235 # # alg.outOfValidityDeco = "bad_eff"
236 # alg.taus = config.readName (self.containerName)
237 # alg.preselection = config.getPreselection (self.containerName, self.selectionName)
238 # config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
239 # 'effSF' + postfix)
240
241
242@groupBlocks