CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecoTauEnergyAlgorithmPlugin.cc
Go to the documentation of this file.
1 /*
2  * =============================================================================
3  * Filename: RecoTauEnergyAlgorithmPlugin.cc
4  *
5  * Description: Determine best estimate for tau energy
6  * for tau candidates reconstructed in different decay modes
7  *
8  * Created: 04/09/2013 11:40:00
9  *
10  * Authors: Christian Veelken (LLR)
11  *
12  * =============================================================================
13  */
14 
16 
27 
30 
31 #include <vector>
32 #include <cmath>
33 
34 namespace reco { namespace tau {
35 
37 {
38  public:
39 
42  void operator()(PFTau&) const;
43  virtual void beginEvent();
44  virtual void endEvent();
45 
46  private:
47 
50  double dRaddPhoton_;
51  double minGammaEt_;
52 
54 };
55 
57  : RecoTauModifierPlugin(cfg, std::move(iC)),
58  dRaddNeutralHadron_(cfg.getParameter<double>("dRaddNeutralHadron")),
59  minNeutralHadronEt_(cfg.getParameter<double>("minNeutralHadronEt")),
60  dRaddPhoton_(cfg.getParameter<double>("dRaddPhoton")),
61  minGammaEt_(cfg.getParameter<double>("minGammaEt"))
62 {
63  verbosity_ = ( cfg.exists("verbosity") ) ?
64  cfg.getParameter<int>("verbosity") : 0;
65 }
66 
68 {}
69 
71 {}
72 
73 namespace
74 {
75  double getTrackPerr2(const reco::Track& track)
76  {
77  double trackPerr = track.p()*(track.ptError()/track.pt());
78  return trackPerr*trackPerr;
79  }
80 
81  void updateTauP4(PFTau& tau, double sf, const reco::Candidate::LorentzVector& addP4)
82  {
83  // preserve tau candidate mass when adding extra neutral energy
84  double tauPx_modified = tau.px() + sf*addP4.px();
85  double tauPy_modified = tau.py() + sf*addP4.py();
86  double tauPz_modified = tau.pz() + sf*addP4.pz();
87  double tauMass = tau.mass();
88  double tauEn_modified = sqrt(tauPx_modified*tauPx_modified + tauPy_modified*tauPy_modified + tauPz_modified*tauPz_modified + tauMass*tauMass);
89  reco::Candidate::LorentzVector tauP4_modified(tauPx_modified, tauPy_modified, tauPz_modified, tauEn_modified);
90  tau.setP4(tauP4_modified);
91  }
92 
93  void killTau(PFTau& tau)
94  {
95  reco::Candidate::LorentzVector tauP4_modified(0.,0.,0.,0.);
96  tau.setP4(tauP4_modified);
97  tau.setStatus(-1);
98  }
99 }
100 
102 {
103  if ( verbosity_ ) {
104  std::cout << "<PFRecoTauEnergyAlgorithmPlugin::operator()>:" << std::endl;
105  std::cout << "tau: Pt = " << tau.pt() << ", eta = " << tau.eta() << ", phi = " << tau.phi() << " (En = " << tau.energy() << ", decayMode = " << tau.decayMode() << ")" << std::endl;
106  }
107 
108  // Add high Pt PFNeutralHadrons and PFGammas that are not "used" by tau decay mode object
109  std::vector<reco::PFCandidatePtr> addNeutrals;
110  reco::Candidate::LorentzVector addNeutralsSumP4;
111  std::vector<reco::PFCandidatePtr> jetConstituents = tau.jetRef()->getPFConstituents();
112  for ( std::vector<reco::PFCandidatePtr>::const_iterator jetConstituent = jetConstituents.begin();
113  jetConstituent != jetConstituents.end(); ++jetConstituent ) {
114  reco::PFCandidate::ParticleType jetConstituentType = (*jetConstituent)->particleId();
115  if ( !((jetConstituentType == reco::PFCandidate::h0 && (*jetConstituent)->et() > minNeutralHadronEt_) ||
116  (jetConstituentType == reco::PFCandidate::gamma && (*jetConstituent)->et() > minGammaEt_ )) ) continue;
117 
118  bool isSignalPFCand = false;
119  const std::vector<reco::PFCandidatePtr>& signalPFCands = tau.signalPFCands();
120  for ( std::vector<reco::PFCandidatePtr>::const_iterator signalPFCand = signalPFCands.begin();
121  signalPFCand != signalPFCands.end(); ++signalPFCand ) {
122  if ( (*jetConstituent) == (*signalPFCand) ) isSignalPFCand = true;
123  }
124  if ( isSignalPFCand ) continue;
125 
126  double dR = deltaR((*jetConstituent)->p4(), tau.p4());
127  double dRadd = -1.;
128  if ( jetConstituentType == reco::PFCandidate::h0 ) dRadd = dRaddNeutralHadron_;
129  else if ( jetConstituentType == reco::PFCandidate::gamma ) dRadd = dRaddPhoton_;
130  if ( dR < dRadd ) {
131  addNeutrals.push_back(*jetConstituent);
132  addNeutralsSumP4 += (*jetConstituent)->p4();
133  }
134  }
135  if ( verbosity_ ) {
136  std::cout << "addNeutralsSumP4: En = " << addNeutralsSumP4.energy() << std::endl;
137  }
138 
139  unsigned numNonPFCandTracks = 0;
140  double nonPFCandTracksSumP = 0.;
141  double nonPFCandTracksSumPerr2 = 0.;
142  const std::vector<PFRecoTauChargedHadron>& chargedHadrons = tau.signalTauChargedHadronCandidatesRestricted();
143  for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
144  chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
145  if ( chargedHadron->algoIs(PFRecoTauChargedHadron::kTrack) ) {
146  ++numNonPFCandTracks;
147  const edm::Ptr<Track>& chargedHadronTrack = chargedHadron->getTrack();
148  nonPFCandTracksSumP += chargedHadronTrack->p();
149  nonPFCandTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
150  }
151  }
152  if ( verbosity_ ) {
153  std::cout << "nonPFCandTracksSumP = " << nonPFCandTracksSumP << " +/- " << sqrt(nonPFCandTracksSumPerr2)
154  << " (numNonPFCandTracks = " << numNonPFCandTracks << ")" << std::endl;
155  }
156 
157  if ( numNonPFCandTracks == 0 ) {
158  // This is the easy case:
159  // All tau energy is taken from PFCandidates reconstructed by PFlow algorithm
160  // and there is no issue with double-counting of energy.
161  if ( verbosity_ ) {
162  std::cout << "easy case: all tracks are associated to PFCandidates --> leaving tau momentum untouched." << std::endl;
163  }
164  updateTauP4(tau, 1., addNeutralsSumP4);
165  return;
166  } else {
167  // This is the difficult case:
168  // The tau energy needs to be computed for an arbitrary mix of charged and neutral PFCandidates plus reco::Tracks.
169  // We need to make sure not to double-count energy deposited by reco::Track in ECAL and/or HCAL as neutral PFCandidates.
170 
171  // Check if we have enough energy in collection of PFNeutralHadrons and PFGammas that are not "used" by tau decay mode object
172  // to balance track momenta:
173  if ( nonPFCandTracksSumP < addNeutralsSumP4.energy() ) {
174  double scaleFactor = 1. - nonPFCandTracksSumP/addNeutralsSumP4.energy();
175  if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
176  edm::LogWarning("PFRecoTauEnergyAlgorithmPlugin::operator()")
177  << "Failed to compute tau energy --> killing tau candidate !!" << std::endl;
178  killTau(tau);
179  return;
180  }
181  if ( verbosity_ ) {
182  std::cout << "case (2): addNeutralsSumEn > nonPFCandTracksSumP --> adjusting tau momentum." << std::endl;
183  }
184  updateTauP4(tau, scaleFactor, addNeutralsSumP4);
185  return;
186  }
187 
188  // Determine which neutral PFCandidates are close to PFChargedHadrons
189  // and have been merged into ChargedHadrons
190  std::vector<reco::PFCandidatePtr> mergedNeutrals;
191  reco::Candidate::LorentzVector mergedNeutralsSumP4;
192  for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
193  chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
194  if ( chargedHadron->algoIs(PFRecoTauChargedHadron::kTrack) ) {
195  const std::vector<reco::PFCandidatePtr>& neutralPFCands = chargedHadron->getNeutralPFCandidates();
196  for ( std::vector<reco::PFCandidatePtr>::const_iterator neutralPFCand = neutralPFCands.begin();
197  neutralPFCand != neutralPFCands.end(); ++neutralPFCand ) {
198  mergedNeutrals.push_back(*neutralPFCand);
199  mergedNeutralsSumP4 += (*neutralPFCand)->p4();
200  }
201  }
202  }
203  if ( verbosity_ ) {
204  std::cout << "mergedNeutralsSumP4: En = " << mergedNeutralsSumP4.energy() << std::endl;
205  }
206 
207  // Check if track momenta are balanced by sum of PFNeutralHadrons and PFGammas that are not "used" by tau decay mode object
208  // plus neutral PFCandidates close to PFChargedHadrons:
209  if ( nonPFCandTracksSumP < (addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy()) ) {
210  double scaleFactor = ((addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy()) - nonPFCandTracksSumP)/mergedNeutralsSumP4.energy();
211  if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
212  edm::LogWarning("PFRecoTauEnergyAlgorithmPlugin::operator()")
213  << "Failed to compute tau energy --> killing tau candidate !!" << std::endl;
214  killTau(tau);
215  return;
216  }
218  size_t numChargedHadrons = chargedHadrons.size();
219  for ( size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
220  const PFRecoTauChargedHadron& chargedHadron = chargedHadrons[iChargedHadron];
221  if ( chargedHadron.getNeutralPFCandidates().size() >= 1 ) {
222  PFRecoTauChargedHadron chargedHadron_modified = chargedHadron;
223  setChargedHadronP4(chargedHadron_modified, scaleFactor);
224  tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
225  diffP4 += (chargedHadron.p4() - chargedHadron_modified.p4());
226  }
227  }
228  if ( verbosity_ ) {
229  std::cout << "case (3): (addNeutralsSumEn + mergedNeutralsSumEn) > nonPFCandTracksSumP --> adjusting tau momentum." << std::endl;
230  }
231  updateTauP4(tau, -1., diffP4);
232  return;
233  }
234 
235  // Determine energy sum of all PFNeutralHadrons interpreted as ChargedHadrons with missing track
236  unsigned numChargedHadronNeutrals = 0;
237  std::vector<reco::PFCandidatePtr> chargedHadronNeutrals;
238  reco::Candidate::LorentzVector chargedHadronNeutralsSumP4;
239  for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
240  chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
241  if ( chargedHadron->algoIs(PFRecoTauChargedHadron::kPFNeutralHadron) ) {
242  ++numChargedHadronNeutrals;
243  chargedHadronNeutrals.push_back(chargedHadron->getChargedPFCandidate());
244  chargedHadronNeutralsSumP4 += chargedHadron->getChargedPFCandidate()->p4();
245  }
246  }
247  if ( verbosity_ ) {
248  std::cout << "chargedHadronNeutralsSumP4: En = " << chargedHadronNeutralsSumP4.energy()
249  << " (numChargedHadronNeutrals = " << numChargedHadronNeutrals << ")" << std::endl;
250  }
251 
252  // Check if sum of PFNeutralHadrons and PFGammas that are not "used" by tau decay mode object
253  // plus neutral PFCandidates close to PFChargedHadrons plus PFNeutralHadrons interpreted as ChargedHadrons with missing track balances track momenta
254  if ( nonPFCandTracksSumP < (addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy() + chargedHadronNeutralsSumP4.energy()) ) {
255  double scaleFactor = ((addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy() + chargedHadronNeutralsSumP4.energy()) - nonPFCandTracksSumP)/chargedHadronNeutralsSumP4.energy();
256  if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
257  edm::LogWarning("PFRecoTauEnergyAlgorithmPlugin::operator()")
258  << "Failed to compute tau energy --> killing tau candidate !!" << std::endl;
259  killTau(tau);
260  return;
261  }
263  size_t numChargedHadrons = chargedHadrons.size();
264  for ( size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
265  const PFRecoTauChargedHadron& chargedHadron = chargedHadrons[iChargedHadron];
266  if ( chargedHadron.algoIs(PFRecoTauChargedHadron::kPFNeutralHadron) ) {
267  PFRecoTauChargedHadron chargedHadron_modified = chargedHadron;
268  chargedHadron_modified.neutralPFCandidates_.clear();
269  const PFCandidatePtr& chargedPFCand = chargedHadron.getChargedPFCandidate();
270  double chargedHadronPx_modified = scaleFactor*chargedPFCand->px();
271  double chargedHadronPy_modified = scaleFactor*chargedPFCand->py();
272  double chargedHadronPz_modified = scaleFactor*chargedPFCand->pz();
273  reco::Candidate::LorentzVector chargedHadronP4_modified = compChargedHadronP4fromPxPyPz(chargedHadronPx_modified, chargedHadronPy_modified, chargedHadronPz_modified);
274  chargedHadron_modified.setP4(chargedHadronP4_modified);
275  tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
276  diffP4 += (chargedHadron.p4() - chargedHadron_modified.p4());
277  }
278  }
279  if ( verbosity_ ) {
280  std::cout << "case (4): (addNeutralsSumEn + mergedNeutralsSumEn + chargedHadronNeutralsSumEn) > nonPFCandTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
281  }
282  updateTauP4(tau, -1., diffP4);
283  return;
284  } else {
285  double allTracksSumP = 0.;
286  double allTracksSumPerr2 = 0.;
287  const std::vector<PFRecoTauChargedHadron> chargedHadrons = tau.signalTauChargedHadronCandidatesRestricted();
288  for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
289  chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
290  if ( chargedHadron->algoIs(PFRecoTauChargedHadron::kChargedPFCandidate) || chargedHadron->algoIs(PFRecoTauChargedHadron::kTrack) ) {
291  const edm::Ptr<Track>& chargedHadronTrack = chargedHadron->getTrack();
292  if ( chargedHadronTrack.isNonnull() ) {
293  allTracksSumP += chargedHadronTrack->p();
294  allTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
295  } else {
296  edm::LogWarning("PFRecoTauEnergyAlgorithmPlugin::operator()")
297  << "PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
298  if ( verbosity_ ) {
299  chargedHadron->print();
300  }
301  }
302  }
303  }
304  if ( verbosity_ ) {
305  std::cout << "allTracksSumP = " << allTracksSumP << " +/- " << sqrt(allTracksSumPerr2) << std::endl;
306  }
307  double allNeutralsSumEn = 0.;
308  const std::vector<reco::PFCandidatePtr>& signalPFCands = tau.signalPFCands();
309  for ( std::vector<reco::PFCandidatePtr>::const_iterator signalPFCand = signalPFCands.begin();
310  signalPFCand != signalPFCands.end(); ++signalPFCand ) {
311  if ( verbosity_ ) {
312  std::cout << "PFCandidate #" << signalPFCand->id() << ":" << signalPFCand->key() << ":"
313  << " Pt = " << (*signalPFCand)->pt() << ", eta = " << (*signalPFCand)->eta() << ", phi = " << (*signalPFCand)->phi() << std::endl;
314  std::cout << "calorimeter energy:"
315  << " ECAL = " << (*signalPFCand)->ecalEnergy() << ","
316  << " HCAL = " << (*signalPFCand)->hcalEnergy() << ","
317  << " HO = " << (*signalPFCand)->hoEnergy() << std::endl;
318  }
319  if ( edm::isFinite((*signalPFCand)->ecalEnergy()) ) allNeutralsSumEn += (*signalPFCand)->ecalEnergy();
320  if ( edm::isFinite((*signalPFCand)->hcalEnergy()) ) allNeutralsSumEn += (*signalPFCand)->hcalEnergy();
321  if ( edm::isFinite((*signalPFCand)->hoEnergy()) ) allNeutralsSumEn += (*signalPFCand)->hoEnergy();
322  }
323  allNeutralsSumEn += addNeutralsSumP4.energy();
324  if ( allNeutralsSumEn < 0. ) allNeutralsSumEn = 0.;
325  if ( verbosity_ ) {
326  std::cout << "allNeutralsSumEn = " << allNeutralsSumEn << std::endl;
327  }
328  if ( allNeutralsSumEn > allTracksSumP ) {
329  // Adjust momenta of neutral PFCandidates merged into ChargedHadrons
330  size_t numChargedHadrons = chargedHadrons.size();
331  for ( size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
332  const PFRecoTauChargedHadron& chargedHadron = chargedHadrons[iChargedHadron];
334  PFRecoTauChargedHadron chargedHadron_modified = chargedHadron;
335  chargedHadron_modified.neutralPFCandidates_.clear();
336  chargedHadron_modified.setP4(chargedHadron.getChargedPFCandidate()->p4());
337  if ( verbosity_ ) {
338  std::cout << "chargedHadron #" << iChargedHadron << ": changing En = " << chargedHadron.energy() << " to " << chargedHadron_modified.energy() << std::endl;
339  }
340  tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
341  } else if ( chargedHadron.algoIs(PFRecoTauChargedHadron::kTrack) ) {
342  PFRecoTauChargedHadron chargedHadron_modified = chargedHadron;
343  chargedHadron_modified.neutralPFCandidates_.clear();
344  reco::Candidate::LorentzVector chargedHadronP4_modified(0.,0.,0.,0.);
345  if ( (chargedHadron.getTrack()).isNonnull() ) {
346  const Track& chargedHadronTrack = *(chargedHadron.getTrack());
347  double chargedHadronPx_modified = chargedHadronTrack.px();
348  double chargedHadronPy_modified = chargedHadronTrack.py();
349  double chargedHadronPz_modified = chargedHadronTrack.pz();
350  chargedHadronP4_modified = compChargedHadronP4fromPxPyPz(chargedHadronPx_modified, chargedHadronPy_modified, chargedHadronPz_modified);
351  } else {
352  edm::LogWarning("PFRecoTauEnergyAlgorithmPlugin::operator()")
353  << "PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
354  if ( verbosity_ ) {
355  chargedHadron.print();
356  }
357  }
358  chargedHadron_modified.setP4(chargedHadronP4_modified);
359  if ( verbosity_ ) {
360  std::cout << "chargedHadron #" << iChargedHadron << ": changing En = " << chargedHadron.energy() << " to " << chargedHadron_modified.energy() << std::endl;
361  }
362  tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
363  }
364  }
365  double scaleFactor = allNeutralsSumEn/tau.energy();
366  if ( verbosity_ ) {
367  std::cout << "case (5): allNeutralsSumEn > allTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
368  }
369  updateTauP4(tau, scaleFactor - 1., tau.p4());
370  return;
371  } else {
372  if ( numChargedHadronNeutrals == 0 && tau.signalPiZeroCandidates().size() == 0 ) {
373  // Adjust momenta of ChargedHadrons build from reco::Tracks to match sum of energy deposits in ECAL + HCAL + HO
374  size_t numChargedHadrons = chargedHadrons.size();
375  for ( size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
376  const PFRecoTauChargedHadron& chargedHadron = chargedHadrons[iChargedHadron];
378  PFRecoTauChargedHadron chargedHadron_modified = chargedHadron;
379  chargedHadron_modified.neutralPFCandidates_.clear();
380  reco::Candidate::LorentzVector chargedHadronP4_modified(0.,0.,0.,0.);
381  const edm::Ptr<Track>& chargedHadronTrack = chargedHadron.getTrack();
382  if ( chargedHadronTrack.isNonnull() ) {
383  double trackP = chargedHadronTrack->p();
384  double trackPerr2 = getTrackPerr2(*chargedHadronTrack);
385  if ( verbosity_ ) {
386  std::cout << "trackP = " << trackP << " +/- " << sqrt(trackPerr2) << std::endl;
387  }
388  // CV: adjust track momenta such that difference beeen (measuredTrackP - adjustedTrackP)/sigmaMeasuredTrackP is minimal
389  // (expression derived using Mathematica)
390  double trackP_modified =
391  (trackP*(allTracksSumPerr2 - trackPerr2)
392  + trackPerr2*(allNeutralsSumEn - (allTracksSumP - trackP)))/
393  allTracksSumPerr2;
394  // CV: trackP_modified may actually become negative in case sum of energy deposits in ECAL + HCAL + HO is small
395  // and one of the tracks has a significantly larger momentum uncertainty than the other tracks.
396  // In this case set track momentum to small positive value.
397  if ( trackP_modified < 1.e-1 ) trackP_modified = 1.e-1;
398  if ( verbosity_ ) {
399  std::cout << "trackP (modified) = " << trackP_modified << std::endl;
400  }
401  double scaleFactor = trackP_modified/trackP;
402  if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
403  edm::LogWarning("PFRecoTauEnergyAlgorithmPlugin::operator()")
404  << "Failed to compute tau energy --> killing tau candidate !!" << std::endl;
405  killTau(tau);
406  return;
407  }
408  double chargedHadronPx_modified = scaleFactor*chargedHadronTrack->px();
409  double chargedHadronPy_modified = scaleFactor*chargedHadronTrack->py();
410  double chargedHadronPz_modified = scaleFactor*chargedHadronTrack->pz();
411  chargedHadronP4_modified = compChargedHadronP4fromPxPyPz(chargedHadronPx_modified, chargedHadronPy_modified, chargedHadronPz_modified);
412  } else {
413  edm::LogWarning("PFRecoTauEnergyAlgorithmPlugin::operator()")
414  << "PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
415  if ( verbosity_ ) {
416  chargedHadron.print();
417  }
418  }
419  chargedHadron_modified.setP4(chargedHadronP4_modified);
420  if ( verbosity_ ) {
421  std::cout << "chargedHadron #" << iChargedHadron << ": changing En = " << chargedHadron.energy() << " to " << chargedHadron_modified.energy() << std::endl;
422  }
423  tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
424  }
425  }
426  double scaleFactor = allNeutralsSumEn/tau.energy();
427  if ( verbosity_ ) {
428  std::cout << "case (6): allNeutralsSumEn < allTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
429  }
430  updateTauP4(tau, scaleFactor - 1., tau.p4());
431  return;
432  } else {
433  // Interpretation of PFNeutralHadrons as ChargedHadrons with missing track and/or reconstruction of extra PiZeros
434  // is not compatible with the fact that sum of reco::Track momenta exceeds sum of energy deposits in ECAL + HCAL + HO:
435  // kill tau candidate (by setting its four-vector to zero)
436  if ( verbosity_ ) {
437  std::cout << "case (7): allNeutralsSumEn < allTracksSumP not compatible with tau decay mode hypothesis --> killing tau candidate." << std::endl;
438  }
439  killTau(tau);
440  return;
441  }
442  }
443  }
444  }
445 
446  // CV: You should never come here.
447  if ( verbosity_ ) {
448  std::cout << "undefined case: you should never come here !!" << std::endl;
449  }
450  assert(0);
451 }
452 
454 {}
455 
456 }} // end namespace reco::tau
457 
459 
double p() const
momentum vector magnitude
Definition: TrackBase.h:610
T getParameter(std::string const &) const
ParticleType
particle types
Definition: PFCandidate.h:44
const PFJetRef & jetRef() const
Definition: PFTau.cc:58
tuple cfg
Definition: looper.py:293
virtual double energy() const final
energy
assert(m_qm.get())
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual double phi() const final
momentum azimuthal angle
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:622
const std::vector< reco::PFCandidatePtr > & signalPFCands() const
PFCandidates in signal region.
Definition: PFTau.cc:78
bool isFinite(T x)
hadronicDecayMode decayMode() const
Definition: PFTau.cc:212
void print(std::ostream &stream=std::cout) const
const double tauMass
const std::vector< RecoTauPiZero > & signalPiZeroCandidates() const
Retrieve the association of signal region gamma candidates into candidate PiZeros.
Definition: PFTau.cc:127
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:616
def move
Definition: eostools.py:510
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
Definition: TrackBase.h:758
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
virtual double py() const final
y coordinate of momentum vector
const TrackPtr & getTrack() const
reference to reco::Track
virtual double mass() const final
mass
virtual double pz() const final
z coordinate of momentum vector
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:169
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:634
const std::vector< PFCandidatePtr > & getNeutralPFCandidates() const
references to additional neutral PFCandidates
std::vector< PFCandidatePtr > neutralPFCandidates_
virtual void setP4(const LorentzVector &p4) final
set 4-momentum
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
PFRecoTauEnergyAlgorithmPlugin(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
bool algoIs(PFRecoTauChargedHadronAlgorithm algo) const
Check whether a given algo produced this charged hadron.
virtual double px() const final
x coordinate of momentum vector
tuple cout
Definition: gather_cfg.py:145
#define DEFINE_EDM_PLUGIN(factory, type, name)
virtual double eta() const final
momentum pseudorapidity
std::vector< PFRecoTauChargedHadron > & signalTauChargedHadronCandidatesRestricted()
Definition: PFTau.cc:180
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
virtual const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:628
const PFCandidatePtr & getChargedPFCandidate() const
reference to &quot;charged&quot; PFCandidate (either charged PFCandidate or PFNeutralHadron) ...
virtual double pt() const final
transverse momentum
reco::Candidate::LorentzVector compChargedHadronP4fromPxPyPz(double, double, double)