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, 'omniScore', 'omniScore', noSys=True)
82  config.addOutputVar (self.containerName, 'leadSubjetPt', 'leadSubjetPt', noSys=True)
83  config.addOutputVar (self.containerName, 'leadSubjetEta', 'leadSubjetEta', noSys=True)
84  config.addOutputVar (self.containerName, 'leadSubjetPhi', 'leadSubjetPhi', noSys=True)
85  config.addOutputVar (self.containerName, 'leadSubjetE', 'leadSubjetE', noSys=True)
86  config.addOutputVar (self.containerName, 'leadSubjetNTracks', 'leadSubjetNTracks', noSys=True)
87  config.addOutputVar (self.containerName, 'leadSubjetCharge', 'leadSubjetCharge', noSys=True)
88  config.addOutputVar (self.containerName, 'subleadSubjetPt', 'subleadSubjetPt', noSys=True)
89  config.addOutputVar (self.containerName, 'subleadSubjetEta', 'subleadSubjetEta', noSys=True)
90  config.addOutputVar (self.containerName, 'subleadSubjetPhi', 'subleadSubjetPhi', noSys=True)
91  config.addOutputVar (self.containerName, 'subleadSubjetE', 'subleadSubjetE', noSys=True)
92  config.addOutputVar (self.containerName, 'subleadSubjetNTracks', 'subleadSubjetNTracks', noSys=True)
93  config.addOutputVar (self.containerName, 'subleadSubjetCharge', 'subleadSubjetCharge', noSys=True)
94 
95  # Set up the tau 4-momentum smearing algorithm:
96  alg = config.createAlgorithm( 'CP::DiTauSmearingAlg', 'DiTauSmearingAlg' )
97  config.addPrivateTool( 'smearingTool', 'TauAnalysisTools::DiTauSmearingTool' )
98  alg.taus = config.readName (self.containerName)
99  alg.tausOut = config.copyName (self.containerName)
100  alg.preselection = config.getPreselection (self.containerName, '')
101 
102  # Save base kinematic ditau variables in output
103  config.addOutputVar (self.containerName, 'pt', 'pt')
104  config.addOutputVar (self.containerName, 'eta', 'eta', noSys=True)
105  config.addOutputVar (self.containerName, 'phi', 'phi', noSys=True)
106  config.addOutputVar (self.containerName, 'm', 'm', noSys=True)
107 
108 
109 
110 class DiTauWorkingPointConfig (ConfigBlock) :
111  """the ConfigBlock for the tau working point
112 
113  This may at some point be split into multiple blocks (16 Mar 22)."""
114 
115  def __init__ (self) :
116  super (DiTauWorkingPointConfig, self).__init__ ()
117  self.addOption ('containerName', '', type=str,
118  noneAction='error',
119  info="the name of the input container.")
120  self.addOption ('selectionName', '', type=str,
121  noneAction='error',
122  info="the name of the tau-jet selection to define (e.g. tight or "
123  "loose).")
124  self.addOption ('postfix', None, type=str,
125  info="a postfix to apply to decorations and algorithm names. "
126  "Typically not needed here as selectionName is used internally.")
127  self.addOption ('quality', None, type=str,
128  info="the ID WP (string) to use. Supported ID WPs: Tight, Medium, "
129  "Loose, VeryLoose, Baseline, BaselineForFakes.")
130  self.addOption ('addSelectionToPreselection', True, type=bool,
131  info="whether to retain only ditau-jets satisfying the working point "
132  "requirements. The default is True.")
133 
134  def instanceName (self) :
135  """Return the instance name for this block"""
136  if self.postfix is not None:
137  return self.containerName + '_' + self.selectionName + self.postfix
138  else:
139  return self.containerName + '_' + self.selectionName
140 
141  def makeAlgs (self, config) :
142 
143  selectionPostfix = self.selectionName
144  if selectionPostfix != '' and selectionPostfix[0] != '_' :
145  selectionPostfix = '_' + selectionPostfix
146 
147  postfix = self.postfix
148  if postfix is None :
149  postfix = self.selectionName
150  if postfix != '' and postfix[0] != '_' :
151  postfix = '_' + postfix
152 
153  # using enum value from: https://gitlab.cern.ch/atlas/athena/blob/21.2/PhysicsAnalysis/TauID/TauAnalysisTools/TauAnalysisTools/Enums.h
154  # the dictionary is missing in Athena, so hard-coding values here
155  if self.quality == 'Tight' :
156  IDLevel = 4 # ROOT.TauAnalysisTools.JETIDBDTTIGHT
157  elif self.quality == 'Medium' :
158  IDLevel = 3 # ROOT.TauAnalysisTools.JETIDBDTMEDIUM
159  elif self.quality == 'Loose' :
160  IDLevel = 2 # ROOT.TauAnalysisTools.JETIDBDTLOOSE
161  else :
162  raise ValueError ("invalid tau quality: \"" + self.quality +
163  "\", allowed values are Tight, Medium, Loose")
164 
165  inputfile = 'TauAnalysisAlgorithms/ditau_selection_highpt.conf'
166  if "DiTauJetsLowPt" in self.containerName:
167  inputfile = 'TauAnalysisAlgorithms/ditau_selection_lowpt.conf'
168 
169  # Set up the algorithm selecting taus:
170  alg = config.createAlgorithm( 'CP::AsgSelectionAlg', 'DiTauSelectionAlg' )
171  config.addPrivateTool( 'selectionTool', 'TauAnalysisTools::DiTauSelectionTool' )
172  alg.selectionTool.ConfigPath = inputfile
173  alg.selectionDecoration = 'selected_ditau' + selectionPostfix + ',as_char'
174  alg.particles = config.readName (self.containerName)
175  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
176  config.addSelection (self.containerName, self.selectionName, alg.selectionDecoration,
177  preselection=self.addSelectionToPreselection)
178 
179 
180  # Set up the algorithm calculating the efficiency scale factors for the
181  # taus:
182  if config.dataType() is not DataType.Data:
183  alg = config.createAlgorithm( 'CP::DiTauEfficiencyCorrectionsAlg',
184  'DiTauEfficiencyCorrectionsAlg' )
185  config.addPrivateTool( 'efficiencyCorrectionsTool',
186  'TauAnalysisTools::DiTauEfficiencyCorrectionsTool' )
187  alg.efficiencyCorrectionsTool.JetIDLevel = IDLevel
188  alg.scaleFactorDecoration = 'tau_effSF' + postfix + '_%SYS%'
189  # alg.outOfValidity = 2 #silent
190  # alg.outOfValidityDeco = "bad_eff"
191  alg.taus = config.readName (self.containerName)
192  alg.preselection = config.getPreselection (self.containerName, self.selectionName)
193  config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
194  'effSF' + postfix)
195 
python.DiTauAnalysisConfig.DiTauWorkingPointConfig.quality
quality
Definition: DiTauAnalysisConfig.py:155
python.DiTauAnalysisConfig.DiTauWorkingPointConfig.instanceName
def instanceName(self)
Definition: DiTauAnalysisConfig.py:134
python.DiTauAnalysisConfig.DiTauWorkingPointConfig.makeAlgs
def makeAlgs(self, config)
Definition: DiTauAnalysisConfig.py:141
python.DiTauAnalysisConfig.DiTauWorkingPointConfig
Definition: DiTauAnalysisConfig.py:110
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:115