CMS 3D CMS Logo

PFRecoTauClusterVariables.cc
Go to the documentation of this file.
2 
3 namespace {
4  struct PFTau_traits {
5  typedef reco::PFTau Tau_t;
6  typedef const std::vector<reco::CandidatePtr>& Ret_t;
7  };
8  struct PATTau_traits {
9  typedef pat::Tau Tau_t;
10  typedef reco::CandidatePtrVector Ret_t;
11  };
12 
13  template <typename T>
14  typename T::Ret_t getGammas_T(const typename T::Tau_t& tau, bool signal) {
15  return typename T::Ret_t();
16  }
18  template <>
19  const std::vector<reco::CandidatePtr>& getGammas_T<PFTau_traits>(const reco::PFTau& tau, bool signal) {
20  if (signal) {
21  return tau.signalGammaCands();
22  }
23  return tau.isolationGammaCands();
24  }
25 
26  template <>
27  reco::CandidatePtrVector getGammas_T<PATTau_traits>(const pat::Tau& tau, bool signal) {
28  if (signal) {
29  return tau.signalGammaCands();
30  }
31  return tau.isolationGammaCands();
32  }
33 
35  bool isInside(float photon_pt, float deta, float dphi) {
36  constexpr double stripEtaAssociationDistance_0p95_p0 = 0.197077;
37  constexpr double stripEtaAssociationDistance_0p95_p1 = 0.658701;
38  constexpr double stripPhiAssociationDistance_0p95_p0 = 0.352476;
39  constexpr double stripPhiAssociationDistance_0p95_p1 = 0.707716;
40  if (photon_pt == 0) {
41  return false;
42  }
43  if ((dphi < 0.3 && dphi < std::max(0.05,
44  stripPhiAssociationDistance_0p95_p0 *
45  std::pow(photon_pt, -stripPhiAssociationDistance_0p95_p1))) &&
46  (deta < 0.15 && deta < std::max(0.05,
47  stripEtaAssociationDistance_0p95_p0 *
48  std::pow(photon_pt, -stripEtaAssociationDistance_0p95_p1)))) {
49  return true;
50  }
51  return false;
52  }
53 } // namespace
54 
55 namespace reco {
56  namespace tau {
58  float lead_track_chi2(const reco::PFTau& tau) {
59  float LeadingTracknormalizedChi2 = 0;
60  const reco::CandidatePtr& leadingCharged = tau.leadChargedHadrCand();
61  if (leadingCharged.isNonnull()) {
62  const reco::PFCandidate* pfcand = dynamic_cast<const reco::PFCandidate*>(leadingCharged.get());
63  if (pfcand != nullptr) {
64  reco::TrackRef tref = pfcand->trackRef();
65  if (tref.isNonnull()) {
66  LeadingTracknormalizedChi2 = tref->normalizedChi2();
67  }
68  } else {
69  const pat::PackedCandidate* patcand = dynamic_cast<const pat::PackedCandidate*>(leadingCharged.get());
70  if (patcand != nullptr && patcand->hasTrackDetails()) {
71  LeadingTracknormalizedChi2 = patcand->pseudoTrack().normalizedChi2();
72  }
73  }
74  }
75  return LeadingTracknormalizedChi2;
76  }
78  float eratio(const reco::PFTau& tau) {
79  float ecal_en_in_signal_pf_cands = 0;
80  float hcal_en_in_signal_pf_cands = 0;
81  for (const auto& signal_cand : tau.signalCands()) {
82  const reco::PFCandidate* signal_pfcand = dynamic_cast<const reco::PFCandidate*>(signal_cand.get());
83  if (signal_pfcand != nullptr) {
84  ecal_en_in_signal_pf_cands += signal_pfcand->ecalEnergy();
85  hcal_en_in_signal_pf_cands += signal_pfcand->hcalEnergy();
86  }
87  // TauReco@MiniAOD: recalculate for PackedCandidate if added to MiniAOD event content
88  }
89  float total = ecal_en_in_signal_pf_cands + hcal_en_in_signal_pf_cands;
90  if (total == 0.) {
91  return -1.;
92  }
93  return ecal_en_in_signal_pf_cands / total;
94  }
95  float eratio(const pat::Tau& tau) {
96  float ecal_en_in_signal_cands = tau.ecalEnergy();
97  float hcal_en_in_signal_cands = tau.hcalEnergy();
98  float total = ecal_en_in_signal_cands + hcal_en_in_signal_cands;
99  if (total == 0.) {
100  return -1.;
101  }
102  return ecal_en_in_signal_cands / total;
103  }
106  template <typename T>
107  float pt_weighted_dx_T(const typename T::Tau_t& tau, int mode, int var, int decaymode) {
108  float sum_pt = 0.;
109  float sum_dx_pt = 0.;
110  float signalrad = std::max(0.05, std::min(0.1, 3. / std::max(1., tau.pt())));
111  int is3prong = (decaymode == 10);
112  const auto& cands = getGammas_T<T>(tau, mode < 2);
113  for (const auto& cand : cands) {
114  // only look at electrons/photons with pT > 0.5
115  if (cand->pt() < 0.5) {
116  continue;
117  }
118  float dr = reco::deltaR(cand->eta(), cand->phi(), tau.eta(), tau.phi());
119  float deta = std::abs(cand->eta() - tau.eta());
120  float dphi = std::abs(reco::deltaPhi(cand->phi(), tau.phi()));
121  float pt = cand->pt();
122  bool flag = isInside(pt, deta, dphi);
123  if (is3prong == 0) {
124  if (mode == 2 || (mode == 0 && dr < signalrad) || (mode == 1 && dr > signalrad)) {
125  sum_pt += pt;
126  if (var == 0)
127  sum_dx_pt += pt * dr;
128  else if (var == 1)
129  sum_dx_pt += pt * deta;
130  else if (var == 2)
131  sum_dx_pt += pt * dphi;
132  }
133  } else if (is3prong == 1) {
134  if ((mode == 2 && flag == false) || (mode == 1 && flag == true) || mode == 0) {
135  sum_pt += pt;
136  if (var == 0)
137  sum_dx_pt += pt * dr;
138  else if (var == 1)
139  sum_dx_pt += pt * deta;
140  else if (var == 2)
141  sum_dx_pt += pt * dphi;
142  }
143  }
144  }
145  if (sum_pt > 0.) {
146  return sum_dx_pt / sum_pt;
147  }
148  return 0.;
149  }
150  float pt_weighted_dx(const reco::PFTau& tau, int mode, int var, int decaymode) {
151  return pt_weighted_dx_T<PFTau_traits>(tau, mode, var, decaymode);
152  }
153  float pt_weighted_dx(const pat::Tau& tau, int mode, int var, int decaymode) {
154  return pt_weighted_dx_T<PATTau_traits>(tau, mode, var, decaymode);
155  }
157  unsigned int n_photons_total(const reco::PFTau& tau) {
158  unsigned int n_photons = 0;
159  for (auto& cand : tau.signalGammaCands()) {
160  if (cand->pt() > 0.5)
161  ++n_photons;
162  }
163  for (auto& cand : tau.isolationGammaCands()) {
164  if (cand->pt() > 0.5)
165  ++n_photons;
166  }
167  return n_photons;
168  }
169  unsigned int n_photons_total(const pat::Tau& tau) {
170  unsigned int n_photons = 0;
171  for (auto& cand : tau.signalGammaCands()) {
172  if (cand->pt() > 0.5)
173  ++n_photons;
174  }
175  for (auto& cand : tau.isolationGammaCands()) {
176  if (cand->pt() > 0.5)
177  ++n_photons;
178  }
179  return n_photons;
180  }
181 
182  bool fillIsoMVARun2Inputs(float* mvaInput,
183  const pat::Tau& tau,
184  int mvaOpt,
185  const std::string& nameCharged,
186  const std::string& nameNeutral,
187  const std::string& namePu,
188  const std::string& nameOutside,
189  const std::string& nameFootprint) {
190  int tauDecayMode = tau.decayMode();
191 
192  if (((mvaOpt == kOldDMwoLT || mvaOpt == kOldDMwLT || mvaOpt == kDBoldDMwLT || mvaOpt == kPWoldDMwLT ||
193  mvaOpt == kDBoldDMwLTwGJ) &&
194  (tauDecayMode == 0 || tauDecayMode == 1 || tauDecayMode == 2 || tauDecayMode == 10)) ||
195  ((mvaOpt == kNewDMwoLT || mvaOpt == kNewDMwLT || mvaOpt == kDBnewDMwLT || mvaOpt == kPWnewDMwLT ||
196  mvaOpt == kDBnewDMwLTwGJ) &&
197  (tauDecayMode == 0 || tauDecayMode == 1 || tauDecayMode == 2 || tauDecayMode == 5 || tauDecayMode == 6 ||
198  tauDecayMode == 10 || tauDecayMode == 11))) {
199  float chargedIsoPtSum = tau.tauID(nameCharged);
200  float neutralIsoPtSum = tau.tauID(nameNeutral);
201  float puCorrPtSum = tau.tauID(namePu);
202  float photonPtSumOutsideSignalCone = tau.tauID(nameOutside);
203  float footprintCorrection = tau.tauID(nameFootprint);
204 
205  float decayDistX = tau.flightLength().x();
206  float decayDistY = tau.flightLength().y();
207  float decayDistZ = tau.flightLength().z();
208  float decayDistMag = std::sqrt(decayDistX * decayDistX + decayDistY * decayDistY + decayDistZ * decayDistZ);
209 
210  // --- The following 5 variables differ slightly between AOD & MiniAOD
211  // because they are recomputed using packedCandidates saved in the tau
212  float nPhoton = reco::tau::n_photons_total(tau);
213  float ptWeightedDetaStrip = reco::tau::pt_weighted_deta_strip(tau, tauDecayMode);
214  float ptWeightedDphiStrip = reco::tau::pt_weighted_dphi_strip(tau, tauDecayMode);
215  float ptWeightedDrSignal = reco::tau::pt_weighted_dr_signal(tau, tauDecayMode);
216  float ptWeightedDrIsolation = reco::tau::pt_weighted_dr_iso(tau, tauDecayMode);
217  // ---
218  float leadingTrackChi2 = tau.leadingTrackNormChi2();
219  float eRatio = reco::tau::eratio(tau);
220 
221  // Difference between measured and maximally allowed Gottfried-Jackson angle
222  float gjAngleDiff = -999;
223  if (tauDecayMode == 10) {
224  double mTau = 1.77682;
225  double mAOne = tau.p4().M();
226  double pAOneMag = tau.p();
227  double argumentThetaGJmax = (std::pow(mTau, 2) - std::pow(mAOne, 2)) / (2 * mTau * pAOneMag);
228  double argumentThetaGJmeasured =
229  (tau.p4().px() * decayDistX + tau.p4().py() * decayDistY + tau.p4().pz() * decayDistZ) /
230  (pAOneMag * decayDistMag);
231  if (std::abs(argumentThetaGJmax) <= 1. && std::abs(argumentThetaGJmeasured) <= 1.) {
232  double thetaGJmax = std::asin(argumentThetaGJmax);
233  double thetaGJmeasured = std::acos(argumentThetaGJmeasured);
234  gjAngleDiff = thetaGJmeasured - thetaGJmax;
235  }
236  }
237 
238  if (mvaOpt == kOldDMwoLT || mvaOpt == kNewDMwoLT) {
239  mvaInput[0] = std::log(std::max(1.f, (float)tau.pt()));
240  mvaInput[1] = std::abs((float)tau.eta());
241  mvaInput[2] = std::log(std::max(1.e-2f, chargedIsoPtSum));
242  mvaInput[3] = std::log(std::max(1.e-2f, neutralIsoPtSum - 0.125f * puCorrPtSum));
243  mvaInput[4] = std::log(std::max(1.e-2f, puCorrPtSum));
244  mvaInput[5] = tauDecayMode;
245  } else if (mvaOpt == kOldDMwLT || mvaOpt == kNewDMwLT) {
246  mvaInput[0] = std::log(std::max(1.f, (float)tau.pt()));
247  mvaInput[1] = std::abs((float)tau.eta());
248  mvaInput[2] = std::log(std::max(1.e-2f, chargedIsoPtSum));
249  mvaInput[3] = std::log(std::max(1.e-2f, neutralIsoPtSum - 0.125f * puCorrPtSum));
250  mvaInput[4] = std::log(std::max(1.e-2f, puCorrPtSum));
251  mvaInput[5] = tauDecayMode;
252  mvaInput[6] = std::copysign(+1.f, tau.dxy());
253  mvaInput[7] = std::sqrt(std::min(1.f, std::abs(tau.dxy())));
254  mvaInput[8] = std::min(10.f, std::abs(tau.dxy_Sig()));
255  mvaInput[9] = (tau.hasSecondaryVertex()) ? 1. : 0.;
256  mvaInput[10] = std::sqrt(decayDistMag);
257  mvaInput[11] = std::min(10.f, tau.flightLengthSig());
258  } else if (mvaOpt == kDBoldDMwLT || mvaOpt == kDBnewDMwLT) {
259  mvaInput[0] = std::log(std::max(1.f, (float)tau.pt()));
260  mvaInput[1] = std::abs((float)tau.eta());
261  mvaInput[2] = std::log(std::max(1.e-2f, chargedIsoPtSum));
262  mvaInput[3] = std::log(std::max(1.e-2f, neutralIsoPtSum));
263  mvaInput[4] = std::log(std::max(1.e-2f, puCorrPtSum));
264  mvaInput[5] = std::log(std::max(1.e-2f, photonPtSumOutsideSignalCone));
265  mvaInput[6] = tauDecayMode;
266  mvaInput[7] = std::min(30.f, nPhoton);
267  mvaInput[8] = std::min(0.5f, ptWeightedDetaStrip);
268  mvaInput[9] = std::min(0.5f, ptWeightedDphiStrip);
269  mvaInput[10] = std::min(0.5f, ptWeightedDrSignal);
270  mvaInput[11] = std::min(0.5f, ptWeightedDrIsolation);
271  mvaInput[12] = std::min(100.f, leadingTrackChi2);
272  mvaInput[13] = std::min(1.f, eRatio);
273  mvaInput[14] = std::copysign(+1.f, tau.dxy());
274  mvaInput[15] = std::sqrt(std::min(1.f, std::abs(tau.dxy())));
275  mvaInput[16] = std::min(10.f, std::abs(tau.dxy_Sig()));
276  mvaInput[17] = std::copysign(+1.f, tau.ip3d());
277  mvaInput[18] = std::sqrt(std::min(1.f, std::abs(tau.ip3d())));
278  mvaInput[19] = std::min(10.f, std::abs(tau.ip3d_Sig()));
279  mvaInput[20] = (tau.hasSecondaryVertex()) ? 1. : 0.;
280  mvaInput[21] = std::sqrt(decayDistMag);
281  mvaInput[22] = std::min(10.f, tau.flightLengthSig());
282  } else if (mvaOpt == kPWoldDMwLT || mvaOpt == kPWnewDMwLT) {
283  mvaInput[0] = std::log(std::max(1.f, (float)tau.pt()));
284  mvaInput[1] = std::abs((float)tau.eta());
285  mvaInput[2] = std::log(std::max(1.e-2f, chargedIsoPtSum));
286  mvaInput[3] = std::log(std::max(1.e-2f, neutralIsoPtSum));
287  mvaInput[4] = std::log(std::max(1.e-2f, footprintCorrection));
288  mvaInput[5] = std::log(std::max(1.e-2f, photonPtSumOutsideSignalCone));
289  mvaInput[6] = tauDecayMode;
290  mvaInput[7] = std::min(30.f, nPhoton);
291  mvaInput[8] = std::min(0.5f, ptWeightedDetaStrip);
292  mvaInput[9] = std::min(0.5f, ptWeightedDphiStrip);
293  mvaInput[10] = std::min(0.5f, ptWeightedDrSignal);
294  mvaInput[11] = std::min(0.5f, ptWeightedDrIsolation);
295  mvaInput[12] = std::min(100.f, leadingTrackChi2);
296  mvaInput[13] = std::min(1.f, eRatio);
297  mvaInput[14] = std::copysign(+1.f, tau.dxy());
298  mvaInput[15] = std::sqrt(std::min(1.f, std::abs(tau.dxy())));
299  mvaInput[16] = std::min(10.f, std::abs(tau.dxy_Sig()));
300  mvaInput[17] = std::copysign(+1.f, tau.ip3d());
301  mvaInput[18] = std::sqrt(std::min(1.f, std::abs(tau.ip3d())));
302  mvaInput[19] = std::min(10.f, std::abs(tau.ip3d_Sig()));
303  mvaInput[20] = (tau.hasSecondaryVertex()) ? 1. : 0.;
304  mvaInput[21] = std::sqrt(decayDistMag);
305  mvaInput[22] = std::min(10.f, tau.flightLengthSig());
306  } else if (mvaOpt == kDBoldDMwLTwGJ || mvaOpt == kDBnewDMwLTwGJ) {
307  mvaInput[0] = std::log(std::max(1.f, (float)tau.pt()));
308  mvaInput[1] = std::abs((float)tau.eta());
309  mvaInput[2] = std::log(std::max(1.e-2f, chargedIsoPtSum));
310  mvaInput[3] = std::log(std::max(1.e-2f, neutralIsoPtSum));
311  mvaInput[4] = std::log(std::max(1.e-2f, puCorrPtSum));
312  mvaInput[5] = std::log(std::max(1.e-2f, photonPtSumOutsideSignalCone));
313  mvaInput[6] = tauDecayMode;
314  mvaInput[7] = std::min(30.f, nPhoton);
315  mvaInput[8] = std::min(0.5f, ptWeightedDetaStrip);
316  mvaInput[9] = std::min(0.5f, ptWeightedDphiStrip);
317  mvaInput[10] = std::min(0.5f, ptWeightedDrSignal);
318  mvaInput[11] = std::min(0.5f, ptWeightedDrIsolation);
319  mvaInput[12] = std::min(1.f, eRatio);
320  mvaInput[13] = std::copysign(+1.f, tau.dxy());
321  mvaInput[14] = std::sqrt(std::min(1.f, std::abs(tau.dxy())));
322  mvaInput[15] = std::min(10.f, std::abs(tau.dxy_Sig()));
323  mvaInput[16] = std::copysign(+1.f, tau.ip3d());
324  mvaInput[17] = std::sqrt(std::min(1.f, std::abs(tau.ip3d())));
325  mvaInput[18] = std::min(10.f, std::abs(tau.ip3d_Sig()));
326  mvaInput[19] = (tau.hasSecondaryVertex()) ? 1. : 0.;
327  mvaInput[20] = std::sqrt(decayDistMag);
328  mvaInput[21] = std::min(10.f, tau.flightLengthSig());
329  mvaInput[22] = std::max(-1.f, gjAngleDiff);
330  }
331 
332  return true;
333  }
334  return false;
335  }
336 
337  } // namespace tau
338 } // namespace reco
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
double ecalEnergy() const
return corrected Ecal energy
Definition: PFCandidate.h:220
unsigned int n_photons_total(const reco::PFTau &tau)
return total number of pf photon candidates with pT>500 MeV, which are associated to signal ...
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
double eta() const final
momentum pseudorapidity
float pt_weighted_dx(const reco::PFTau &tau, int mode=0, int var=0, int decaymode=-1)
float pt_weighted_dr_signal(const reco::PFTau &tau, int dm)
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:572
float dxy() const
Definition: Tau.h:277
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:139
bool fillIsoMVARun2Inputs(float *mvaInput, const pat::Tau &tau, int mvaOpt, const std::string &nameCharged, const std::string &nameNeutral, const std::string &namePu, const std::string &nameOutside, const std::string &nameFootprint)
double pt() const final
transverse momentum
const std::vector< reco::CandidatePtr > & signalGammaCands() const
Gamma candidates in signal region.
Definition: PFTau.cc:83
float ip3d_Sig() const
float tauID(const std::string &name) const
float hcalEnergy() const
return sum of hcal energies from signal candidates
Definition: Tau.h:299
float ecalEnergy() const
Definition: Tau.h:297
reco::CandidatePtrVector signalGammaCands() const
const std::vector< reco::CandidatePtr > & isolationGammaCands() const
Gamma candidates in isolation region.
Definition: PFTau.cc:98
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:408
float ip3d() const
Definition: Tau.h:290
const CandidatePtr & leadChargedHadrCand() const
Definition: PFTau.cc:62
float pt_weighted_deta_strip(const reco::PFTau &tau, int dm)
T sqrt(T t)
Definition: SSEVec.h:19
const pat::tau::TauPFEssential::Vector & flightLength() const
Definition: Tau.h:284
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float pt_weighted_dr_iso(const reco::PFTau &tau, int dm)
virtual const reco::Track & pseudoTrack() const
double f[11][100]
const LorentzVector & p4() const final
four-momentum Lorentz vector
bool hasSecondaryVertex() const
Definition: Tau.h:283
T min(T a, T b)
Definition: MathUtil.h:58
Analysis-level tau class.
Definition: Tau.h:53
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:146
bool hasTrackDetails() const
Return true if a bestTrack can be extracted from this Candidate.
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
double p() const final
magnitude of momentum vector
float pt_weighted_dphi_strip(const reco::PFTau &tau, int dm)
int decayMode() const
reconstructed tau decay mode (specific to PFTau)
Definition: Tau.h:328
float eratio(const reco::PFTau &tau)
return ratio of energy in ECAL over sum of energy in ECAL and HCAL
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
float flightLengthSig() const
Definition: Tau.h:285
fixed size matrix
float dxy_Sig() const
float leadingTrackNormChi2() const
return normalized chi2 of leading track
Definition: Tau.h:301
float pt_weighted_dx_T(const typename T::Tau_t &tau, int mode, int var, int decaymode)
double hcalEnergy() const
return corrected Hcal energy
Definition: PFCandidate.h:232
reco::CandidatePtrVector isolationGammaCands() const
float lead_track_chi2(const reco::PFTau &tau)
return chi2 of the leading track ==> deprecated? <==
const std::vector< reco::CandidatePtr > & signalCands() const
Candidates in signal region.
Definition: PFTau.cc:73
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30
#define constexpr