ATLAS Offline Software
DiTauAnalysisConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 # AnaAlgorithm import(s):
4 from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
5 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
6 
7 
8 class DiTauCalibrationConfig (ConfigBlock):
9  """the ConfigBlock for the tau four-momentum correction"""
10 
11  def __init__ (self) :
12  super (DiTauCalibrationConfig, self).__init__ ()
13  self.setBlockName('DiTaus')
14  self.addOption ('inputContainer', '', type=str,
15  info="select ditau input container, by default set to DiTauJets")
16  self.addOption ('containerName', '', type=str,
17  noneAction='error',
18  info="the name of the output container after calibration.")
19  self.addOption ('postfix', '', type=str,
20  info="a postfix to apply to decorations and algorithm names. "
21  "Typically not needed here since the calibration is common to "
22  "all ditaus.")
23  self.addOption ('rerunTruthMatching', True, type=bool,
24  info="whether to rerun truth matching (sets up an instance of "
25  "CP::DiTauTruthMatchingAlg). The default is True.")
26  self.addOption ('decorateTruth', False, type=bool,
27  info="decorate truth particle information on the reconstructed one")
28  self.addOption ('decorateExtraVariables', True, type=bool,
29  info="decorate extra variables for the reconstructed ditau")
30 
31  def instanceName (self) :
32  """Return the instance name for this block"""
33  return self.containerName + self.postfix
34 
35  def makeAlgs (self, config) :
36 
37  postfix = self.postfix
38  if postfix != '' and postfix[0] != '_' :
39  postfix = '_' + postfix
40 
41  inputContainer = "DiTauJets"
42  if self.inputContainer:
43  inputContainer = self.inputContainer
44  config.setSourceName (self.containerName, inputContainer)
45 
46  # Set up the tau truth matching algorithm:
47  if self.rerunTruthMatching and config.dataType() is not DataType.Data:
48  alg = config.createAlgorithm( 'CP::DiTauTruthMatchingAlg',
49  'DiTauTruthMatchingAlg' )
50  config.addPrivateTool( 'matchingTool',
51  'TauAnalysisTools::DiTauTruthMatchingTool' )
52  alg.taus = config.readName (self.containerName)
53  alg.preselection = config.getPreselection (self.containerName, '')
54 
55 
56  # decorate truth tau information on the reconstructed object:
57  if self.decorateTruth and self.rerunTruthMatching and config.dataType() is not DataType.Data:
58  # in the case of the ditau, the DiTauTruthMatchingTool decorates directly the reco ditau with truth information.
59  # So information can be written directly out without any additional algorithm
60  config.addOutputVar (self.containerName, 'TruthVisLeadPt', 'TruthVisLeadPt', noSys=True)
61  config.addOutputVar (self.containerName, 'TruthVisLeadEta', 'TruthVisLeadEta', noSys=True)
62  config.addOutputVar (self.containerName, 'TruthVisLeadPhi', 'TruthVisLeadPhi', noSys=True)
63  config.addOutputVar (self.containerName, 'TruthVisLeadM', 'TruthVisLeadM', noSys=True)
64  config.addOutputVar (self.containerName, 'TruthLeadPdgID', 'TruthLeadPdgID', noSys=True)
65  config.addOutputVar (self.containerName, 'TruthVisSubleadPt', 'TruthVisSubleadPt', noSys=True)
66  config.addOutputVar (self.containerName, 'TruthVisSubleadEta', 'TruthVisSubleadEta', noSys=True)
67  config.addOutputVar (self.containerName, 'TruthVisSubleadPhi', 'TruthVisSubleadPhi', noSys=True)
68  config.addOutputVar (self.containerName, 'TruthVisSubleadM', 'TruthVisSubleadM', noSys=True)
69  config.addOutputVar (self.containerName, 'TruthSubleadPdgID', 'TruthSubleadPdgID', noSys=True)
70  config.addOutputVar (self.containerName, 'TruthVisDeltaR', 'TruthVisDeltaR', noSys=True)
71  config.addOutputVar (self.containerName, 'TruthVisMass', 'TruthVisMass', noSys=True)
72  config.addOutputVar (self.containerName, 'IsTruthMatched', 'IsTruthMatched', noSys=True)
73  config.addOutputVar (self.containerName, 'IsTruthHadronic', 'IsTruthHadronic', noSys=True)
74 
75  # Decorate extra variables
76  if self.decorateExtraVariables:
77  alg = config.createAlgorithm( 'CP::DiTauExtraVariablesAlg',
78  'DiTauExtraVariablesAlg',
79  reentrant=True )
80  alg.ditaus = config.readName (self.containerName)
81  config.addOutputVar (self.containerName, 'leadSubjetPt', 'leadSubjetPt', noSys=True)
82  config.addOutputVar (self.containerName, 'leadSubjetEta', 'leadSubjetEta', noSys=True)
83  config.addOutputVar (self.containerName, 'leadSubjetPhi', 'leadSubjetPhi', noSys=True)
84  config.addOutputVar (self.containerName, 'leadSubjetE', 'leadSubjetE', noSys=True)
85  config.addOutputVar (self.containerName, 'subleadSubjetPt', 'subleadSubjetPt', noSys=True)
86  config.addOutputVar (self.containerName, 'subleadSubjetEta', 'subleadSubjetEta', noSys=True)
87  config.addOutputVar (self.containerName, 'subleadSubjetPhi', 'subleadSubjetPhi', noSys=True)
88  config.addOutputVar (self.containerName, 'subleadSubjetE', 'subleadSubjetE', noSys=True)
89 
90  # Set up the tau 4-momentum smearing algorithm:
91  alg = config.createAlgorithm( 'CP::DiTauSmearingAlg', 'DiTauSmearingAlg' )
92  config.addPrivateTool( 'smearingTool', 'TauAnalysisTools::DiTauSmearingTool' )
93  alg.taus = config.readName (self.containerName)
94  alg.tausOut = config.copyName (self.containerName)
95  alg.preselection = config.getPreselection (self.containerName, '')
96 
97  # Save base kinematic ditau variables in output
98  config.addOutputVar (self.containerName, 'pt', 'pt')
99  config.addOutputVar (self.containerName, 'eta', 'eta', noSys=True)
100  config.addOutputVar (self.containerName, 'phi', 'phi', noSys=True)
101  config.addOutputVar (self.containerName, 'm', 'm', noSys=True)
102 
103 
104 
105 class DiTauWorkingPointConfig (ConfigBlock) :
106  """the ConfigBlock for the tau working point
107 
108  This may at some point be split into multiple blocks (16 Mar 22)."""
109 
110  def __init__ (self) :
111  super (DiTauWorkingPointConfig, self).__init__ ()
112  self.addOption ('containerName', '', type=str,
113  noneAction='error',
114  info="the name of the input container.")
115  self.addOption ('selectionName', '', type=str,
116  noneAction='error',
117  info="the name of the tau-jet selection to define (e.g. tight or "
118  "loose).")
119  self.addOption ('postfix', None, type=str,
120  info="a postfix to apply to decorations and algorithm names. "
121  "Typically not needed here as selectionName is used internally.")
122  self.addOption ('quality', None, type=str,
123  info="the ID WP (string) to use. Supported ID WPs: Tight, Medium, "
124  "Loose, VeryLoose, Baseline, BaselineForFakes.")
125  self.addOption ('addSelectionToPreselection', True, type=bool,
126  info="whether to retain only ditau-jets satisfying the working point "
127  "requirements. The default is True.")
128 
129  def instanceName (self) :
130  """Return the instance name for this block"""
131  if self.postfix is not None:
132  return self.containerName + '_' + self.selectionName + self.postfix
133  else:
134  return self.containerName + '_' + self.selectionName
135 
136  def makeAlgs (self, config) :
137 
138  selectionPostfix = self.selectionName
139  if selectionPostfix != '' and selectionPostfix[0] != '_' :
140  selectionPostfix = '_' + selectionPostfix
141 
142  postfix = self.postfix
143  if postfix is None :
144  postfix = self.selectionName
145  if postfix != '' and postfix[0] != '_' :
146  postfix = '_' + postfix
147 
148  # using enum value from: https://gitlab.cern.ch/atlas/athena/blob/21.2/PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h
149  # the dictionary is missing in Athena, so hard-coding values here
150  if self.quality == 'Tight' :
151  IDLevel = 4 # ROOT.TauAnalysisTools.JETIDBDTTIGHT
152  elif self.quality == 'Medium' :
153  IDLevel = 3 # ROOT.TauAnalysisTools.JETIDBDTMEDIUM
154  elif self.quality == 'Loose' :
155  IDLevel = 2 # ROOT.TauAnalysisTools.JETIDBDTLOOSE
156  else :
157  raise ValueError ("invalid tau quality: \"" + self.quality +
158  "\", allowed values are Tight, Medium, Loose")
159 
160  inputfile = 'TauAnalysisAlgorithms/ditau_selection_highpt.conf'
161  if "DiTauJetsLowPt" in self.containerName:
162  inputfile = 'TauAnalysisAlgorithms/ditau_selection_lowpt.conf'
163 
164  # Set up the algorithm selecting taus:
165  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'DiTauSelectionAlg' )
166  config.addPrivateTool( 'selectionTool', 'TauAnalysisTools::DiTauSelectionTool' )
167  alg.selectionTool.ConfigPath = inputfile
168  alg.selectionDecoration = 'selected_ditau' + selectionPostfix + ',as_char'
169  alg.particles = config.readName (self.containerName)
170  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
171  config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
172  preselection=self.addSelectionToPreselection)
173 
174 
175  # Set up the algorithm calculating the efficiency scale factors for the
176  # taus:
177  if config.dataType() is not DataType.Data:
178  alg = config.createAlgorithm( 'CP::DiTauEfficiencyCorrectionsAlg',
179  'DiTauEfficiencyCorrectionsAlg' )
180  config.addPrivateTool( 'efficiencyCorrectionsTool',
181  'TauAnalysisTools::DiTauEfficiencyCorrectionsTool' )
182  alg.efficiencyCorrectionsTool.JetIDLevel = IDLevel
183  alg.scaleFactorDecoration = 'tau_effSF' + postfix + '_%SYS%'
184  # alg.outOfValidity = 2 #silent
185  # alg.outOfValidityDeco = "bad_eff"
186  alg.taus = config.readName (self.containerName)
187  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
188  config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
189  'effSF' + postfix)
190 
python.DiTauAnalysisConfig.DiTauWorkingPointConfig.quality
quality
Definition: DiTauAnalysisConfig.py:150
python.DiTauAnalysisConfig.DiTauWorkingPointConfig.instanceName
def instanceName(self)
Definition: DiTauAnalysisConfig.py:129
python.DiTauAnalysisConfig.DiTauWorkingPointConfig.makeAlgs
def makeAlgs(self, config)
Definition: DiTauAnalysisConfig.py:136
python.DiTauAnalysisConfig.DiTauWorkingPointConfig
Definition: DiTauAnalysisConfig.py:105
python.DiTauAnalysisConfig.DiTauCalibrationConfig.makeAlgs
def makeAlgs(self, config)
Definition: DiTauAnalysisConfig.py:35
python.DiTauAnalysisConfig.DiTauCalibrationConfig.instanceName
def instanceName(self)
Definition: DiTauAnalysisConfig.py:31
python.DiTauAnalysisConfig.DiTauCalibrationConfig
Definition: DiTauAnalysisConfig.py:8
python.DiTauAnalysisConfig.DiTauCalibrationConfig.__init__
def __init__(self)
Definition: DiTauAnalysisConfig.py:11
python.DiTauAnalysisConfig.DiTauWorkingPointConfig.__init__
def __init__(self)
Definition: DiTauAnalysisConfig.py:110