ATLAS Offline Software
LeptonSFCalculatorConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
4 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
5 
6 
7 class LeptonSFCalculatorBlock(ConfigBlock):
8  """ConfigBlock for the common electron-muon-photon-tau SF calculator"""
9  """--> combine all the per-object SFs into a single per-event SF"""
10 
11  def __init__(self):
12  super(LeptonSFCalculatorBlock, self).__init__()
13  self.addOption('electrons', None, type=str,
14  info='the input electron container, with a possible selection, in the format `container` or `container.selection`.')
15  self.addOption('electronSFs', None, type=list,
16  info='list of decorated electron SFs to use in the computation. If not set, will use reconstruction x ID x isolation, also ECIDS (charge ID) if available.')
17  self.addOption('muons', None, type=str,
18  info='the input muon container, with a possible selection, in the format `container` or `container.selection`.')
19  self.addOption('muonSFs', None, type=list,
20  info='list of decorated muon SFs to use in the computation. If not set, will use reconstruction x isolation x TTVA.')
21  self.addOption('photons', None, type=str,
22  info='the input photon container, with a possible selection, in the format `container` or `container.selection`.')
23  self.addOption('photonSFs', None, type=list,
24  info='list of decorated photon SFs to use in the computation. If not set, will use ID x isolation.')
25  self.addOption('taus', None, type=str,
26  info='the input tau container, with a possible selection, in the format `container` or `container.selection`.')
27  self.addOption('tauSFs', None, type=list,
28  info='list of decorated tau SFs to use in the computation. If not set, will use reconstruction x ID x eVeto.')
29  self.addOption('lepton_postfix', None, type=str,
30  info='the name of the common lepton SF, e.g. `tight`.')
31  self.addOption('includeElectronChargeMisID', False, type=str,
32  info='whether to include the electron charge mis-ID SFs in the computation. The user is responsible for determining whether these are available.')
33  self.addOption('includeMuonBadVeto', False, type=str,
34  info='whether to include the muon bad veto SFs in the computation. The user is responsible for determining whether these are available.')
35 
36  def instanceName (self) :
37  """Return the instance name for this block"""
38  return self.lepton_postfix
39 
40  def makeAlgs(self, config):
41  if config.dataType() is DataType.Data: return
42 
43  alg = config.createAlgorithm('CP::LeptonSFCalculatorAlg',
44  'leptonSFCalculator')
45 
46  if self.electrons:
47  electrons, electronSelection = config.readNameAndSelection(self.electrons)
48  alg.electrons = electrons
49  alg.electronSelection = electronSelection
50  if self.electronSFs:
51  alg.electronSFs = self.electronSFs
52  else:
53  alg.electronSFs = [ f'el_reco_effSF_{self.electrons.split(".")[1]}_%SYS%',
54  f'el_id_effSF_{self.electrons.split(".")[1]}_%SYS%' ]
55  if 'isolated' in alg.electronSelection:
56  alg.electronSFs += [ f'el_isol_effSF_{self.electrons.split(".")[1]}_%SYS%' ]
57  if 'chargeID' in alg.electronSelection:
58  alg.electronSFs += [ f'el_ecids_effSF_{self.electrons.split(".")[1]}_%SYS%' ]
59  if self.includeElectronChargeMisID:
60  alg.electronSFs += [ f'el_charge_misid_effSF_{self.electrons.split(".")[1]}_%SYS%' ]
61 
62  if self.muons:
63  muons, muonSelection = config.readNameAndSelection(self.muons)
64  alg.muons = muons
65  alg.muonSelection = muonSelection
66  if self.muonSFs:
67  alg.muonSFs = self.muonSFs
68  else:
69  alg.muonSFs = [ f'muon_reco_effSF_{self.muons.split(".")[1]}_%SYS%']
70  if 'trackSelection' in alg.muonSelection:
71  alg.muonSFs += [ f'muon_TTVA_effSF_{self.muons.split(".")[1]}_%SYS%' ]
72  if 'isolated' in alg.muonSelection:
73  alg.muonSFs += [ f'muon_isol_effSF_{self.muons.split(".")[1]}_%SYS%' ]
74  if self.includeMuonBadVeto:
75  alg.muonSFs += [ f'muon_BadMuonVeto_effSF_{self.muons.split(".")[1]}_%SYS%' ]
76 
77  if self.photons:
78  photons, photonSelection = config.readNameAndSelection(self.photons)
79  alg.photons = photons
80  alg.photonSelection = photonSelection
81  if self.photonSFs:
82  alg.photonSFs = self.photonSFs
83  else:
84  alg.photonSFs = [ f'ph_id_effSF_{self.photons.split(".")[1]}_%SYS%' ]
85  if 'isolated' in alg.photonSelection:
86  alg.photonSFs += [ f'ph_isol_effSF_{self.photons.split(".")[1]}_%SYS%' ]
87 
88  if self.taus:
89  taus, tauSelection = config.readNameAndSelection(self.taus)
90  alg.taus = taus
91  alg.tauSelection = tauSelection
92  if self.tauSFs:
93  alg.tauSFs = self.tauSFs
94  else:
95  alg.tauSFs = [ f'tau_Reco_effSF_{self.taus.split(".")[1]}_%SYS%',
96  f'tau_ID_effSF_{self.taus.split(".")[1]}_%SYS%']
97  if 'eVeto' in alg.tauSelection:
98  alg.tauSFs += [ f'tau_EvetoFakeTau_effSF_{self.taus.split(".")[1]}_%SYS%',
99  f'tau_EvetoTrueTau_effSF_{self.taus.split(".")[1]}_%SYS%']
100 
101  alg.event_leptonSF = f'leptonSF_{self.lepton_postfix}_%SYS%'
102 
103  config.addOutputVar('EventInfo', alg.event_leptonSF, f'weight_leptonSF_{self.lepton_postfix}')
python.LeptonSFCalculatorConfig.LeptonSFCalculatorBlock
Definition: LeptonSFCalculatorConfig.py:7
python.LeptonSFCalculatorConfig.LeptonSFCalculatorBlock.makeAlgs
def makeAlgs(self, config)
Definition: LeptonSFCalculatorConfig.py:40
python.LeptonSFCalculatorConfig.LeptonSFCalculatorBlock.__init__
def __init__(self)
Definition: LeptonSFCalculatorConfig.py:11
python.LeptonSFCalculatorConfig.LeptonSFCalculatorBlock.instanceName
def instanceName(self)
Definition: LeptonSFCalculatorConfig.py:36