CMS 3D CMS Logo

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