CMS 3D CMS Logo

taus_cff.py
Go to the documentation of this file.
1 import FWCore.ParameterSet.Config as cms
3 from PhysicsTools.NanoAOD.nano_eras_cff import run3_nanoAOD_124
4 from PhysicsTools.NanoAOD.simpleCandidateFlatTableProducer_cfi import simpleCandidateFlatTableProducer
5 
6 from PhysicsTools.JetMCAlgos.TauGenJets_cfi import tauGenJets
7 from PhysicsTools.JetMCAlgos.TauGenJetsDecayModeSelectorAllHadrons_cfi import tauGenJetsSelectorAllHadrons
8 
9 from PhysicsTools.PatAlgos.patTauSignalCandidatesProducer_cfi import patTauSignalCandidatesProducer
10 
11 
14 
15 
16 
17 # Original DeepTau v2p5 in 12_4_X doesn't include WPs in MINIAOD
18 # Import thresholds here to define WPs manually from raw scores
19 from RecoTauTag.RecoTau.tauIdWPsDefs import WORKING_POINTS_v2p5
20 
21 finalTaus = cms.EDFilter("PATTauRefSelector",
22  src = cms.InputTag("slimmedTaus"),
23  cut = cms.string("pt > 18 && ((tauID('decayModeFindingNewDMs') > 0.5 && (tauID('byLooseCombinedIsolationDeltaBetaCorr3Hits') || (tauID('chargedIsoPtSumdR03')+max(0.,tauID('neutralIsoPtSumdR03')-0.072*tauID('puCorrPtSum'))<2.5) || tauID('byVVVLooseDeepTau2017v2p1VSjet') || tauID('byVVVLooseDeepTau2018v2p5VSjet'))) || (?isTauIDAvailable('byPNetVSjetraw')?tauID('byPNetVSjetraw'):-1) > {})".format(0.05))
24 )
25 
26 run3_nanoAOD_124.toModify(
27  finalTaus,
28  cut = cms.string("pt > 18 && ((tauID('decayModeFindingNewDMs') > 0.5 && (tauID('byLooseCombinedIsolationDeltaBetaCorr3Hits') || (tauID('chargedIsoPtSumdR03')+max(0.,tauID('neutralIsoPtSumdR03')-0.072*tauID('puCorrPtSum'))<2.5) || tauID('byVVVLooseDeepTau2017v2p1VSjet') || (tauID('byDeepTau2018v2p5VSjetraw') > {}))) || (?isTauIDAvailable('byPNetVSjetraw')?tauID('byPNetVSjetraw'):-1) > {})".format(WORKING_POINTS_v2p5["jet"]["VVVLoose"],0.05))
29 )
30 
31 
32 def _tauIdWPMask(pattern, choices, doc="", from_raw=False, wp_thrs=None):
33  if from_raw:
34  assert wp_thrs is not None, "wp_thrs argument in _tauIdWPMask() is None, expect it to be dict-like"
35 
36  var_definition = []
37  for wp_name in choices:
38  if not isinstance(wp_thrs[wp_name], float):
39  raise TypeError("Threshold for WP=%s is not a float number." % wp_name)
40  wp_definition = "test_bit(tauID('{}')-{}+1,0)".format(pattern, wp_thrs[wp_name])
41  var_definition.append(wp_definition)
42  var_definition = " + ".join(var_definition)
43  var_definition = ("?isTauIDAvailable('%s')?(" % pattern) + var_definition + "):0"
44  else:
45  var_definition = " + ".join(["tauID('%s')" % (pattern % c) for c in choices])
46  var_definition = ("?isTauIDAvailable('%s')?(" % (pattern % choices[0])) + var_definition + "):0"
47 
48  doc = doc + ": "+", ".join(["%d = %s" % (i,c) for (i,c) in enumerate(choices, start=1)])
49  return Var(var_definition, "uint8", doc=doc)
50 
51 
52 tauTable = simpleCandidateFlatTableProducer.clone(
53  src = cms.InputTag("linkedObjects","taus"),
54  name= cms.string("Tau"),
55  doc = cms.string("slimmedTaus after basic selection (" + finalTaus.cut.value()+")")
56 )
57 
58 _tauVarsBase = cms.PSet(P4Vars,
59  charge = Var("charge", "int16", doc="electric charge"),
60  jetIdx = Var("?hasUserCand('jet')?userCand('jet').key():-1", "int16", doc="index of the associated jet (-1 if none)"),
61  eleIdx = Var("?overlaps('electrons').size()>0?overlaps('electrons')[0].key():-1", "int16", doc="index of first matching electron"),
62  muIdx = Var("?overlaps('muons').size()>0?overlaps('muons')[0].key():-1", "int16", doc="index of first matching muon"),
63  svIdx1 = Var("?overlaps('vertices').size()>0?overlaps('vertices')[0].key():-1", "int16", doc="index of first matching secondary vertex"),
64  svIdx2 = Var("?overlaps('vertices').size()>1?overlaps('vertices')[1].key():-1", "int16", doc="index of second matching secondary vertex"),
65  nSVs = Var("?hasOverlaps('vertices')?overlaps('vertices').size():0", "uint8", doc="number of secondary vertices in the tau"),
66  decayMode = Var("decayMode()", "uint8"),
67  idDecayModeOldDMs = Var("(?isTauIDAvailable('decayModeFinding')?tauID('decayModeFinding'):-1) > 0", bool),
68  idDecayModeNewDMs = Var("(?isTauIDAvailable('decayModeFindingNewDMs')?tauID('decayModeFindingNewDMs'):-1) > 0", bool),
69  leadTkPtOverTauPt = Var("?leadChargedHadrCand.isNonnull()?leadChargedHadrCand.pt/pt:1",float, doc="pt of the leading track divided by tau pt",precision=10),
70  leadTkDeltaEta = Var("?leadChargedHadrCand.isNonnull()?(leadChargedHadrCand.eta - eta):0",float, doc="eta of the leading track, minus tau eta",precision=8),
71  leadTkDeltaPhi = Var("?leadChargedHadrCand.isNonnull()?deltaPhi(leadChargedHadrCand.phi, phi):0",float, doc="phi of the leading track, minus tau phi",precision=8),
72 
73  dxy = Var("?leadChargedHadrCand.isNonnull()?leadChargedHadrCand().dxy():0",float, doc="d_{xy} of lead track with respect to PV, in cm (with sign)",precision=10),
74  dz = Var("?leadChargedHadrCand.isNonnull()?leadChargedHadrCand().dz():0",float, doc="d_{z} of lead track with respect to PV, in cm (with sign)",precision=14),
75 
76  # these are too many, we may have to suppress some
77  rawIso = Var("?isTauIDAvailable('byCombinedIsolationDeltaBetaCorrRaw3Hits')?tauID('byCombinedIsolationDeltaBetaCorrRaw3Hits'):-1", float, doc = "combined isolation (deltaBeta corrections)", precision=10),
78  rawIsodR03 = Var("?isTauIDAvailable('chargedIsoPtSumdR03')?(tauID('chargedIsoPtSumdR03')+max(0.,tauID('neutralIsoPtSumdR03')-0.072*tauID('puCorrPtSum'))):-1", float, doc = "combined isolation (deltaBeta corrections, dR=0.3)", precision=10),
79  chargedIso = Var("?isTauIDAvailable('chargedIsoPtSum')?tauID('chargedIsoPtSum'):-1", float, doc = "charged isolation", precision=10),
80  neutralIso = Var("?isTauIDAvailable('neutralIsoPtSum')?tauID('neutralIsoPtSum'):-1", float, doc = "neutral (photon) isolation", precision=10),
81  puCorr = Var("?isTauIDAvailable('puCorrPtSum')?tauID('puCorrPtSum'):-1", float, doc = "pileup correction", precision=10),
82  photonsOutsideSignalCone = Var("?isTauIDAvailable('photonPtSumOutsideSignalCone')?tauID('photonPtSumOutsideSignalCone'):-1", float, doc = "sum of photons outside signal cone", precision=10),
83 
84  idAntiMu = _tauIdWPMask("againstMuon%s3", choices=("Loose","Tight"), doc= "Anti-muon discriminator V3: "),
85  idAntiEleDeadECal = Var("(?isTauIDAvailable('againstElectronDeadECAL')?tauID('againstElectronDeadECAL'):-1) > 0", bool, doc = "Anti-electron dead-ECal discriminator"),
86 
87 )
88 
89 _deepTauVars2017v2p1 = cms.PSet(
90  rawDeepTau2017v2p1VSe = Var("?isTauIDAvailable('byDeepTau2017v2p1VSeraw')?tauID('byDeepTau2017v2p1VSeraw'):-1", float, doc="byDeepTau2017v2p1VSe raw output discriminator (deepTau2017v2p1)", precision=10),
91  rawDeepTau2017v2p1VSmu = Var("?isTauIDAvailable('byDeepTau2017v2p1VSmuraw')?tauID('byDeepTau2017v2p1VSmuraw'):-1", float, doc="byDeepTau2017v2p1VSmu raw output discriminator (deepTau2017v2p1)", precision=10),
92  rawDeepTau2017v2p1VSjet = Var("?isTauIDAvailable('byDeepTau2017v2p1VSjetraw')?tauID('byDeepTau2017v2p1VSjetraw'):-1", float, doc="byDeepTau2017v2p1VSjet raw output discriminator (deepTau2017v2p1)", precision=10),
93  idDeepTau2017v2p1VSe = _tauIdWPMask("by%sDeepTau2017v2p1VSe",
94  choices=("VVVLoose","VVLoose","VLoose","Loose","Medium","Tight","VTight","VVTight"),
95  doc="byDeepTau2017v2p1VSe ID working points (deepTau2017v2p1)"),
96  idDeepTau2017v2p1VSmu = _tauIdWPMask("by%sDeepTau2017v2p1VSmu",
97  choices=("VLoose", "Loose", "Medium", "Tight"),
98  doc="byDeepTau2017v2p1VSmu ID working points (deepTau2017v2p1)"),
99  idDeepTau2017v2p1VSjet = _tauIdWPMask("by%sDeepTau2017v2p1VSjet",
100  choices=("VVVLoose","VVLoose","VLoose","Loose","Medium","Tight","VTight","VVTight"),
101  doc="byDeepTau2017v2p1VSjet ID working points (deepTau2017v2p1)"),
102 )
103 _deepTauVars2018v2p5 = cms.PSet(
104  rawDeepTau2018v2p5VSe = Var("?isTauIDAvailable('byDeepTau2018v2p5VSeraw')?tauID('byDeepTau2018v2p5VSeraw'):-1", float, doc="byDeepTau2018v2p5VSe raw output discriminator (deepTau2018v2p5)", precision=10),
105  rawDeepTau2018v2p5VSmu = Var("?isTauIDAvailable('byDeepTau2018v2p5VSmuraw')?tauID('byDeepTau2018v2p5VSmuraw'):-1", float, doc="byDeepTau2018v2p5VSmu raw output discriminator (deepTau2018v2p5)", precision=10),
106  rawDeepTau2018v2p5VSjet = Var("?isTauIDAvailable('byDeepTau2018v2p5VSjetraw')?tauID('byDeepTau2018v2p5VSjetraw'):-1", float, doc="byDeepTau2018v2p5VSjet raw output discriminator (deepTau2018v2p5)", precision=10),
107  idDeepTau2018v2p5VSe = _tauIdWPMask("by%sDeepTau2018v2p5VSe",
108  choices=("VVVLoose","VVLoose","VLoose","Loose","Medium","Tight","VTight","VVTight"),
109  doc="byDeepTau2018v2p5VSe ID working points (deepTau2018v2p5)"),
110  idDeepTau2018v2p5VSmu = _tauIdWPMask("by%sDeepTau2018v2p5VSmu",
111  choices=("VLoose", "Loose", "Medium", "Tight"),
112  doc="byDeepTau2018v2p5VSmu ID working points (deepTau2018v2p5)"),
113  idDeepTau2018v2p5VSjet = _tauIdWPMask("by%sDeepTau2018v2p5VSjet",
114  choices=("VVVLoose","VVLoose","VLoose","Loose","Medium","Tight","VTight","VVTight"),
115  doc="byDeepTau2018v2p5VSjet ID working points (deepTau2018v2p5)"),
116 )
117 
118 _pnet2023 = cms.PSet(
119  decayModePNet = Var("?isTauIDAvailable('byPNetDecayMode')?tauID('byPNetDecayMode'):-1", "int16",doc="decay mode of the highest tau score of ParticleNet"),
120  rawPNetVSe = Var("?isTauIDAvailable('byPNetVSeraw')?tauID('byPNetVSeraw'):-1", float, doc="raw output of ParticleNetVsE discriminator (PNet 2023)", precision=10),
121  rawPNetVSmu = Var("?isTauIDAvailable('byPNetVSmuraw')?tauID('byPNetVSmuraw'):-1", float, doc="raw output of ParticleNetVsMu discriminator (PNet 2023)", precision=10),
122  rawPNetVSjet = Var("?isTauIDAvailable('byPNetVSjetraw')?tauID('byPNetVSjetraw'):-1", float, doc="raw output of ParticleNetVsJet discriminator (PNet 2023)", precision=10),
123  ptCorrPNet = Var("?isTauIDAvailable('byPNetPtCorr')?tauID('byPNetPtCorr'):1", float, doc="pt correction (PNet 2023)", precision=10),
124  qConfPNet = Var("?isTauIDAvailable('byPNetQConf')?tauID('byPNetQConf'):0", float, doc="signed charge confidence (PNet 2023)", precision=10),
125  probDM0PNet = Var("?isTauIDAvailable('byPNetProb1h0pi0')?tauID('byPNetProb1h0pi0'):-1", float, doc="normalised probablity of decayMode 0, 1h+0pi0 (PNet 2023)", precision=10),
126  probDM1PNet = Var("?isTauIDAvailable('byPNetProb1h1pi0')?tauID('byPNetProb1h1pi0'):-1", float, doc="normalised probablity of decayMode 1, 1h+1pi0 (PNet 2023)", precision=10),
127  probDM2PNet = Var("?isTauIDAvailable('byPNetProb1h2pi0')?tauID('byPNetProb1h2pi0'):-1", float, doc="normalised probablity of decayMode 2, 1h+2pi0 (PNet 2023)", precision=10),
128  probDM10PNet = Var("?isTauIDAvailable('byPNetProb3h0pi0')?tauID('byPNetProb3h0pi0'):-1", float, doc="normalised probablity of decayMode 10, 3h+0pi0 (PNet 2023)", precision=10),
129  probDM11PNet = Var("?isTauIDAvailable('byPNetProb3h1pi0')?tauID('byPNetProb3h1pi0'):-1", float, doc="normalised probablity of decayMode 11, 3h+1pi0 (PNet 2023)", precision=10),
130 )
131 
132 _variablesMiniV2 = cms.PSet(
133  _tauVarsBase,
134  _deepTauVars2017v2p1,
135  _deepTauVars2018v2p5,
136  _pnet2023
137 )
138 
139 tauTable.variables = _variablesMiniV2
140 
141 run3_nanoAOD_124.toModify(
142  tauTable.variables,
143  idDeepTau2018v2p5VSe = _tauIdWPMask("byDeepTau2018v2p5VSeraw",
144  choices=("VVVLoose","VVLoose","VLoose","Loose","Medium","Tight","VTight","VVTight"),
145  doc="byDeepTau2018v2p5VSe ID working points (deepTau2018v2p5)",
146  from_raw=True, wp_thrs=WORKING_POINTS_v2p5["e"]),
147  idDeepTau2018v2p5VSmu = _tauIdWPMask("byDeepTau2018v2p5VSmuraw",
148  choices=("VLoose", "Loose", "Medium", "Tight"),
149  doc="byDeepTau2018v2p5VSmu ID working points (deepTau2018v2p5)",
150  from_raw=True, wp_thrs=WORKING_POINTS_v2p5["mu"]),
151  idDeepTau2018v2p5VSjet = _tauIdWPMask("byDeepTau2018v2p5VSjetraw",
152  choices=("VVVLoose","VVLoose","VLoose","Loose","Medium","Tight","VTight","VVTight"),
153  doc="byDeepTau2018v2p5VSjet ID working points (deepTau2018v2p5)",
154  from_raw=True, wp_thrs=WORKING_POINTS_v2p5["jet"])
155 )
156 
157 tauSignalCands = patTauSignalCandidatesProducer.clone(
158  src = tauTable.src,
159  storeLostTracks = True
160 )
161 
162 tauSignalCandsTable = simpleCandidateFlatTableProducer.clone(
163  src = cms.InputTag("tauSignalCands"),
164  cut = cms.string("pt > 0."),
165  name = cms.string("TauProd"),
166  doc = cms.string("tau signal candidates"),
167  variables = cms.PSet(
168  P3Vars,
169  pdgId = Var("pdgId", int, doc="PDG code assigned by the event reconstruction (not by MC truth)"),
170  tauIdx = Var("status", "int16", doc="index of the mother tau"),
171  #trkPt = Var("?daughter(0).hasTrackDetails()?daughter(0).bestTrack().pt():0", float, precision=-1, doc="pt of associated track"), #MB: better to store ratio over cand pt?
172  )
173 )
174 
175 tauGenJetsForNano = tauGenJets.clone(
176  GenParticles = "finalGenParticles",
177  includeNeutrinos = False
178 )
179 
180 tauGenJetsSelectorAllHadronsForNano = tauGenJetsSelectorAllHadrons.clone(
181  src = "tauGenJetsForNano"
182 )
183 
184 genVisTaus = cms.EDProducer("GenVisTauProducer",
185  src = cms.InputTag("tauGenJetsSelectorAllHadronsForNano"),
186  srcGenParticles = cms.InputTag("finalGenParticles")
187 )
188 
189 genVisTauTable = simpleCandidateFlatTableProducer.clone(
190  src = cms.InputTag("genVisTaus"),
191  cut = cms.string("pt > 10."),
192  name = cms.string("GenVisTau"),
193  doc = cms.string("gen hadronic taus "),
194  variables = cms.PSet(
195  pt = Var("pt", float,precision=8),
196  phi = Var("phi", float,precision=8),
197  eta = Var("eta", float,precision=8),
198  mass = Var("mass", float,precision=8),
199  charge = Var("charge", "int16"),
200  status = Var("status", "uint8", doc="Hadronic tau decay mode. 0=OneProng0PiZero, 1=OneProng1PiZero, 2=OneProng2PiZero, 10=ThreeProng0PiZero, 11=ThreeProng1PiZero, 15=Other"),
201  genPartIdxMother = Var("?numberOfMothers>0?motherRef(0).key():-1", "int16", doc="index of the mother particle"),
202  )
203 )
204 
205 tausMCMatchLepTauForTable = cms.EDProducer("MCMatcher", # cut on deltaR, deltaPt/Pt; pick best by deltaR
206  src = tauTable.src, # final reco collection
207  matched = cms.InputTag("finalGenParticles"), # final mc-truth particle collection
208  mcPdgId = cms.vint32(11,13), # one or more PDG ID (11 = electron, 13 = muon); absolute values (see below)
209  checkCharge = cms.bool(False), # True = require RECO and MC objects to have the same charge
210  mcStatus = cms.vint32(), # PYTHIA status code (1 = stable, 2 = shower, 3 = hard scattering)
211  maxDeltaR = cms.double(0.3), # Minimum deltaR for the match
212  maxDPtRel = cms.double(0.5), # Minimum deltaPt/Pt for the match
213  resolveAmbiguities = cms.bool(True), # Forbid two RECO objects to match to the same GEN object
214  resolveByMatchQuality = cms.bool(True), # False = just match input in order; True = pick lowest deltaR pair first
215 )
216 
217 tausMCMatchHadTauForTable = cms.EDProducer("MCMatcher", # cut on deltaR, deltaPt/Pt; pick best by deltaR
218  src = tauTable.src, # final reco collection
219  matched = cms.InputTag("genVisTaus"), # generator level hadronic tau decays
220  mcPdgId = cms.vint32(15), # one or more PDG ID (15 = tau); absolute values (see below)
221  checkCharge = cms.bool(False), # True = require RECO and MC objects to have the same charge
222  mcStatus = cms.vint32(), # CV: no *not* require certain status code for matching (status code corresponds to decay mode for hadronic tau decays)
223  maxDeltaR = cms.double(0.3), # Maximum deltaR for the match
224  maxDPtRel = cms.double(1.), # Maximum deltaPt/Pt for the match
225  resolveAmbiguities = cms.bool(True), # Forbid two RECO objects to match to the same GEN object
226  resolveByMatchQuality = cms.bool(True), # False = just match input in order; True = pick lowest deltaR pair first
227 )
228 
229 tauMCTable = cms.EDProducer("CandMCMatchTableProducer",
230  src = tauTable.src,
231  mcMap = cms.InputTag("tausMCMatchLepTauForTable"),
232  mcMapVisTau = cms.InputTag("tausMCMatchHadTauForTable"),
233  objName = tauTable.name,
234  objType = tauTable.name, #cms.string("Tau"),
235  branchName = cms.string("genPart"),
236  docString = cms.string("MC matching to status==2 taus"),
237 )
238 
239 
240 tauTask = cms.Task(finalTaus)
241 tauTablesTask = cms.Task(tauTable)
242 tauSignalCandsTask = cms.Task(tauSignalCands,tauSignalCandsTable)
243 tauTablesTask.add(tauSignalCandsTask)
244 
245 genTauTask = cms.Task(tauGenJetsForNano,tauGenJetsSelectorAllHadronsForNano,genVisTaus,genVisTauTable)
246 tauMCTask = cms.Task(genTauTask,tausMCMatchLepTauForTable,tausMCMatchHadTauForTable,tauMCTable)
247 
def Var(expr, valtype, doc=None, precision=-1)
Definition: common_cff.py:16
Updated tau collection with MVA-based tau-Ids rerun ####### Used only in some eras.
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
def _tauIdWPMask(pattern, choices, doc="", from_raw=False, wp_thrs=None)
Tables for final output and docs ##########################.
Definition: taus_cff.py:32