4 from AnalysisAlgorithmsConfig.ConfigBlock
import ConfigBlock
5 from AnalysisAlgorithmsConfig.ConfigAccumulator
import DataType
6 from Campaigns.Utils
import Campaign
7 from AthenaCommon.Logging
import logging
11 """the ConfigBlock for the tau four-momentum correction"""
14 super (TauCalibrationConfig, self).__init__ ()
15 self.setBlockName(
'Taus')
17 self.addOption (
'inputContainer',
'TauJets', type=str,
18 info=
"select tau input container, by default set to TauJets")
19 self.addOption (
'containerName', containerName, type=str,
21 info=
"the name of the output container after calibration.")
22 self.addOption (
'postfix',
'', type=str,
23 info=
"a postfix to apply to decorations and algorithm names. "
24 "Typically not needed here since the calibration is common to "
26 self.addOption (
'rerunTruthMatching',
True, type=bool,
27 info=
"whether to rerun truth matching (sets up an instance of "
28 "CP::TauTruthMatchingAlg). The default is True.")
29 self.addOption (
'decorateTruth',
False, type=bool,
30 info=
"decorate truth particle information on the reconstructed one")
35 postfix = self.postfix
36 if postfix !=
'' and postfix[0] !=
'_' :
37 postfix =
'_' + postfix
39 if config.isPhyslite() :
42 config.setSourceName (self.
containerName, self.inputContainer)
45 if self.rerunTruthMatching
and config.dataType()
is not DataType.Data:
46 alg = config.createAlgorithm(
'CP::TauTruthMatchingAlg',
47 'TauTruthMatchingAlg' + postfix )
48 config.addPrivateTool(
'matchingTool',
49 'TauAnalysisTools::TauTruthMatchingTool' )
50 alg.matchingTool.TruthJetContainerName =
'AntiKt4TruthDressedWZJets'
52 alg.preselection = config.getPreselection (self.
containerName,
'')
55 if self.decorateTruth
and config.dataType()
is not DataType.Data:
56 alg = config.createAlgorithm(
'CP::TauTruthDecorationsAlg',
57 'TauTruthDecorationsAlg' + postfix )
59 alg.doubleDecorations = [
'pt_vis',
'eta_vis',
'phi_vis',
'm_vis']
60 alg.floatDecorations = []
61 alg.intDecorations = [
'pdgId']
62 alg.unsignedIntDecorations = [
'classifierParticleOrigin',
'classifierParticleType']
63 alg.charDecorations = [
'IsHadronicTau']
67 for var
in [
'DecayMode',
'ParticleType',
'PartonTruthLabelID'] + alg.doubleDecorations[:] + alg.floatDecorations[:] + alg.intDecorations[:] + alg.unsignedIntDecorations[:] + alg.charDecorations[:]:
68 branchName = alg.prefix + var
69 if 'classifierParticle' in var:
70 branchOutput = alg.prefix + var.replace(
'classifierParticle',
'').lower()
72 branchOutput = branchName
73 config.addOutputVar (self.
containerName, branchName, branchOutput, noSys=
True)
76 alg = config.createAlgorithm(
'CP::TauExtraVariablesAlg',
'TauExtraVariables' + self.
containerName + self.postfix )
80 alg = config.createAlgorithm(
'CP::TauSmearingAlg',
'TauSmearingAlg' + postfix )
81 config.addPrivateTool(
'smearingTool',
'TauAnalysisTools::TauSmearingTool' )
82 alg.smearingTool.useFastSim = config.dataType()
is DataType.FastSim
85 alg.preselection = config.getPreselection (self.
containerName,
'')
88 alg = config.createAlgorithm(
'CP::AsgEnergyDecoratorAlg',
'EnergyDecorator' + self.
containerName + self.postfix )
92 config.addOutputVar (self.
containerName,
'eta',
'eta', noSys=
True)
93 config.addOutputVar (self.
containerName,
'phi',
'phi', noSys=
True)
95 config.addOutputVar (self.
containerName,
'charge',
'charge', noSys=
True)
96 config.addOutputVar (self.
containerName,
'NNDecayMode',
'NNDecayMode', noSys=
True)
97 config.addOutputVar (self.
containerName,
'nTracks',
'nTracks', noSys=
True)
101 """the ConfigBlock for the tau working point
103 This may at some point be split into multiple blocks (16 Mar 22)."""
105 def __init__ (self, containerName='', selectionName='') :
106 super (TauWorkingPointConfig, self).__init__ ()
107 self.addOption (
'containerName', containerName, type=str,
109 info=
"the name of the input container.")
110 self.addOption (
'selectionName', selectionName, type=str,
112 info=
"the name of the tau-jet selection to define (e.g. tight or "
114 self.addOption (
'postfix',
None, type=str,
115 info=
"a postfix to apply to decorations and algorithm names. "
116 "Typically not needed here as selectionName is used internally.")
117 self.addOption (
'quality',
None, type=str,
118 info=
"the ID WP (string) to use. Supported ID WPs: Tight, Medium, "
119 "Loose, VeryLoose, Baseline.")
120 self.addOption (
'use_eVeto',
False, type=bool,
121 info=
"use selection with or without eVeto combined with tauID "
122 "recommendations: set it to True if electron mis-reconstructed as tau is a large background for your analysis")
123 self.addOption (
'useGNTau',
False, type=bool,
124 info=
"use GNTau based ID instead of RNNTau ID "
125 "recommendations: that's new experimental feature and might come default soon")
126 self.addOption (
'noEffSF',
False, type=bool,
127 info=
"disables the calculation of efficiencies and scale factors. "
128 "Experimental! only useful to test a new WP for which scale "
129 "factors are not available. The default is False.")
133 selectionPostfix = self.selectionName
134 if selectionPostfix !=
'' and selectionPostfix[0] !=
'_' :
135 selectionPostfix =
'_' + selectionPostfix
137 postfix = self.postfix
139 postfix = self.selectionName
140 if postfix !=
'' and postfix[0] !=
'_' :
141 postfix =
'_' + postfix
144 nameFormat =
'TauAnalysisAlgorithms/tau_selection_gntau_{}_eleid.conf'
145 if not self.use_eVeto:
146 nameFormat =
'TauAnalysisAlgorithms/tau_selection_gntau_{}_noeleid.conf'
148 nameFormat =
'TauAnalysisAlgorithms/tau_selection_{}_eleid.conf'
149 if not self.use_eVeto:
150 nameFormat =
'TauAnalysisAlgorithms/tau_selection_{}_noeleid.conf'
152 if self.
quality not in [
'Tight',
'Medium',
'Loose',
'VeryLoose',
'Baseline'] :
153 raise ValueError (
"invalid tau quality: \"" + self.
quality +
154 "\", allowed values are Tight, Medium, Loose, " +
155 "VeryLoose, Baseline")
156 inputfile = nameFormat.format(self.
quality.lower())
159 alg = config.createAlgorithm(
'CP::AsgSelectionAlg',
'TauSelectionAlg' + postfix )
160 config.addPrivateTool(
'selectionTool',
'TauAnalysisTools::TauSelectionTool' )
161 alg.selectionTool.ConfigPath = inputfile
162 alg.selectionDecoration =
'selected_tau' + selectionPostfix +
',as_bits'
163 alg.particles = config.readName (self.containerName)
164 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
165 config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration)
169 if config.dataType()
is not DataType.Data
and not self.noEffSF
and not self.useGNTau:
175 alg = config.createAlgorithm(
'CP::TauEfficiencyCorrectionsAlg',
176 'TauEfficiencyCorrectionsAlgReco' + postfix )
177 config.addPrivateTool(
'efficiencyCorrectionsTool',
178 'TauAnalysisTools::TauEfficiencyCorrectionsTool' )
179 alg.efficiencyCorrectionsTool.EfficiencyCorrectionTypes = [0]
180 alg.efficiencyCorrectionsTool.useFastSim = config.dataType()
is DataType.FastSim
181 alg.scaleFactorDecoration =
'tau_Reco_effSF' + selectionPostfix +
'_%SYS%'
182 alg.outOfValidity = 2
183 alg.outOfValidityDeco =
'bad_Reco_eff' + selectionPostfix
184 alg.taus = config.readName (self.containerName)
185 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
186 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
'Reco_effSF' + postfix)
189 if self.
quality not in (
'VeryLoose',
'Baseline'):
191 alg = config.createAlgorithm(
'CP::TauEfficiencyCorrectionsAlg',
192 'TauEfficiencyCorrectionsAlgID' + postfix )
193 config.addPrivateTool(
'efficiencyCorrectionsTool',
194 'TauAnalysisTools::TauEfficiencyCorrectionsTool' )
195 alg.efficiencyCorrectionsTool.EfficiencyCorrectionTypes = [4]
203 raise ValueError (
"invalid tauID: \"" + self.
quality +
"\". Allowed values are loose, medium, tight")
205 alg.efficiencyCorrectionsTool.JetIDLevel = JetIDLevel
206 alg.efficiencyCorrectionsTool.useFastSim = config.dataType()
is DataType.FastSim
207 alg.scaleFactorDecoration =
'tau_ID_effSF' + selectionPostfix +
'_%SYS%'
208 alg.outOfValidity = 2
209 alg.outOfValidityDeco =
'bad_ID_eff' + selectionPostfix
210 alg.taus = config.readName (self.containerName)
211 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
212 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
'ID_effSF' + postfix)
218 alg = config.createAlgorithm(
'CP::TauEfficiencyCorrectionsAlg',
219 'TauEfficiencyCorrectionsAlgEvetoFakeTau' + postfix )
220 config.addPrivateTool(
'efficiencyCorrectionsTool',
221 'TauAnalysisTools::TauEfficiencyCorrectionsTool' )
223 alg.efficiencyCorrectionsTool.EfficiencyCorrectionTypes = [10]
225 alg.efficiencyCorrectionsTool.EleIDLevel = 2
226 alg.efficiencyCorrectionsTool.useFastSim = config.dataType()
is DataType.FastSim
227 alg.scaleFactorDecoration =
'tau_EvetoFakeTau_effSF' + selectionPostfix +
'_%SYS%'
228 alg.outOfValidity = 2
229 alg.outOfValidityDeco =
'bad_EvetoFakeTau_eff' + selectionPostfix
230 alg.taus = config.readName (self.containerName)
231 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
232 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
'EvetoFakeTau_effSF' + postfix)
235 alg = config.createAlgorithm(
'CP::TauEfficiencyCorrectionsAlg',
236 'TauEfficiencyCorrectionsAlgEvetoTrueTau' + postfix )
237 config.addPrivateTool(
'efficiencyCorrectionsTool',
238 'TauAnalysisTools::TauEfficiencyCorrectionsTool' )
240 alg.efficiencyCorrectionsTool.EfficiencyCorrectionTypes = [8]
241 alg.efficiencyCorrectionsTool.useFastSim = config.dataType()
is DataType.FastSim
242 alg.scaleFactorDecoration =
'tau_EvetoTrueTau_effSF' + selectionPostfix +
'_%SYS%'
243 alg.outOfValidity = 2
244 alg.outOfValidityDeco =
'bad_EvetoTrueTau_eff' + selectionPostfix
245 alg.taus = config.readName (self.containerName)
246 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
247 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
'EvetoTrueTau_effSF' + postfix)
251 def __init__ (self, inputTaus = 'TauJets', inputTausMuRM = 'TauJets_MuonRM', outputTaus = 'TauJets_MuonRmCombined', postfix = '') :
252 super (EXPERIMENTAL_TauCombineMuonRemovalConfig, self).__init__ ()
254 'inputTaus', inputTaus, type=str,
256 info=
"the name of the input tau container."
259 'inputTausMuRM', inputTausMuRM, type=str,
261 info=
"the name of the input tau container with muon removal applied."
263 self.addOption (
'postfix', postfix, type=str,
264 info=
"a postfix to apply to decorations and algorithm names. "
265 "Typically not needed here as selectionName is used internally."
268 'outputTaus', outputTaus, type=str,
270 info=
"the name of the output tau container."
275 postfix = self.postfix
276 if postfix !=
'' and postfix[0] !=
'_' :
277 postfix =
'_' + postfix
279 if config.isPhyslite() :
280 raise(RuntimeError(
"Muon removal taus is not available in Physlite mode"))
282 alg = config.createAlgorithm(
'CP::TauCombineMuonRMTausAlg',
'TauCombineMuonRMTausAlg' + postfix )
283 alg.taus = self.inputTaus
284 alg.muonrm_taus = self.inputTausMuRM
285 alg.combined_taus = self.outputTaus
289 inputTausMuRM = 'TauJets_MuonRM',
290 outputTaus = 'TauJets_MuonRmCombined',
292 config = EXPERIMENTAL_TauCombineMuonRemovalConfig (
293 inputTaus = inputTaus,
294 inputTausMuRM = inputTausMuRM,
295 outputTaus = outputTaus,
302 postfix = None, rerunTruthMatching = None):
303 """Create tau calibration analysis algorithms
305 This makes all the algorithms that need to be run first befor
306 all working point specific algorithms and that can be shared
307 between the working points.
310 postfix -- a postfix to apply to decorations and algorithm
311 names. this is mostly used/needed when using this
312 sequence with multiple working points to ensure all
314 rerunTruthMatching -- Whether or not to rerun truth matching
317 config = TauCalibrationConfig (containerName)
318 config.setOptionValue (
'inputContainer', inputContainer)
319 if postfix
is not None :
320 config.setOptionValue (
'postfix', postfix)
321 if rerunTruthMatching
is not None :
322 config.setOptionValue (
'rerunTruthMatching', rerunTruthMatching)
331 """Create tau analysis algorithms for a single working point
334 selectionName -- a postfix to apply to decorations and algorithm
335 names. this is mostly used/needed when using this
336 sequence with multiple working points to ensure all
338 noEffSF -- Disables the calculation of efficiencies and scale factors
341 config = TauWorkingPointConfig (containerName, selectionName)
342 if workingPoint
is not None :
343 splitWP = workingPoint.split (
'.')
344 if len (splitWP) != 1 :
345 raise ValueError (
'working point should be of format "quality", not ' + workingPoint)
346 config.setOptionValue (
'quality', splitWP[0])
347 config.setOptionValue (
'noEffSF', noEffSF)
354 super (TauTriggerAnalysisSFBlock, self).__init__ ()
356 self.addOption (
'triggerChainsPerYear', {}, type=
None,
357 info=
"a dictionary with key (string) the year and value (list of "
358 "strings) the trigger chains. The default is {} (empty dictionary).")
359 self.addOption (
'tauID',
'', type=str,
360 info=
"the tau quality WP (string) to use.")
361 self.addOption (
'containerName',
'', type=str,
362 info=
"the input tau container, with a possible selection, in "
363 "the format container or container.selection.")
366 return dictionary.get(
int(year), dictionary.get(
str(year), []))
370 if config.dataType()
is not DataType.Data:
371 if config.campaign()
is Campaign.MC20a:
372 triggers = self.
get_year_data(self.triggerChainsPerYear, 2015)
373 triggers += self.
get_year_data(self.triggerChainsPerYear, 2016)
376 elif config.campaign()
is Campaign.MC20d:
377 triggers = self.
get_year_data(self.triggerChainsPerYear, 2017)
378 elif config.campaign()
is Campaign.MC20e:
379 triggers = self.
get_year_data(self.triggerChainsPerYear, 2018)
380 elif config.campaign()
in [Campaign.MC21a, Campaign.MC23a]:
381 triggers = self.
get_year_data(self.triggerChainsPerYear, 2022)
382 elif config.campaign()
in [Campaign.MC23c, Campaign.MC23d]:
383 triggers = self.
get_year_data(self.triggerChainsPerYear, 2023)
385 logging.warning(
"unknown campaign, skipping triggers: " +
str(config.campaign()))
388 for trig
in triggers:
389 trig = trig.replace(
"HLT_",
"")
390 alg = config.createAlgorithm(
'CP::TauEfficiencyCorrectionsAlg',
391 'TauTrigEfficiencyCorrectionsAlg' + trig )
392 config.addPrivateTool(
'efficiencyCorrectionsTool',
393 'TauAnalysisTools::TauEfficiencyCorrectionsTool' )
396 alg.efficiencyCorrectionsTool.EfficiencyCorrectionTypes = [12]
397 alg.efficiencyCorrectionsTool.TriggerName =
'HLT_' + trig
403 elif self.
tauID==
"Medium":
405 elif self.
tauID==
"Tight":
408 raise ValueError (
"invalid tauID: \"" + self.
tauID +
"\". Allowed values are loose, medium, tight")
409 alg.efficiencyCorrectionsTool.JetIDLevel = JetIDLevel
410 alg.efficiencyCorrectionsTool.TriggerSFMeasurement =
"combined"
411 alg.efficiencyCorrectionsTool.useFastSim = config.dataType()
is DataType.FastSim
413 alg.scaleFactorDecoration =
'tau_trigEffSF_' + trig +
'_%SYS%'
414 alg.outOfValidity = 2
415 alg.outOfValidityDeco =
'bad_eff_tautrig_' + trig
416 alg.taus = config.readName (self.containerName)
417 alg.preselection = config.getPreselection (self.containerName, self.
tauID)
418 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
'trigEffSF_' + trig)