34 namespace reco {
namespace tau {
77 double trackPerr = track.
p()*(track.
ptError()/track.
pt());
78 return trackPerr*trackPerr;
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);
90 tau.
setP4(tauP4_modified);
93 void killTau(
PFTau& tau)
96 tau.
setP4(tauP4_modified);
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;
109 std::vector<reco::PFCandidatePtr> addNeutrals;
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 ) {
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;
124 if ( isSignalPFCand )
continue;
126 double dR =
deltaR((*jetConstituent)->p4(), tau.
p4());
131 addNeutrals.push_back(*jetConstituent);
132 addNeutralsSumP4 += (*jetConstituent)->p4();
136 std::cout <<
"addNeutralsSumP4: En = " << addNeutralsSumP4.energy() << std::endl;
139 unsigned numNonPFCandTracks = 0;
140 double nonPFCandTracksSumP = 0.;
141 double nonPFCandTracksSumPerr2 = 0.;
143 for ( std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
146 ++numNonPFCandTracks;
148 nonPFCandTracksSumP += chargedHadronTrack->p();
149 nonPFCandTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
153 std::cout <<
"nonPFCandTracksSumP = " << nonPFCandTracksSumP <<
" +/- " <<
sqrt(nonPFCandTracksSumPerr2)
154 <<
" (numNonPFCandTracks = " << numNonPFCandTracks <<
")" << std::endl;
157 if ( numNonPFCandTracks == 0 ) {
162 std::cout <<
"easy case: all tracks are associated to PFCandidates --> leaving tau momentum untouched." << std::endl;
164 updateTauP4(tau, 1., addNeutralsSumP4);
173 if ( nonPFCandTracksSumP < addNeutralsSumP4.energy() ) {
174 double scaleFactor = 1. - nonPFCandTracksSumP/addNeutralsSumP4.energy();
175 if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
177 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
182 std::cout <<
"case (2): addNeutralsSumEn > nonPFCandTracksSumP --> adjusting tau momentum." << std::endl;
184 updateTauP4(tau, scaleFactor, addNeutralsSumP4);
190 std::vector<reco::PFCandidatePtr> mergedNeutrals;
192 for ( std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
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();
204 std::cout <<
"mergedNeutralsSumP4: En = " << mergedNeutralsSumP4.energy() << std::endl;
209 if ( nonPFCandTracksSumP < (addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy()) ) {
210 double scaleFactor = ((addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy()) - nonPFCandTracksSumP)/mergedNeutralsSumP4.energy();
211 if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
213 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
218 size_t numChargedHadrons = chargedHadrons.size();
219 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
225 diffP4 += (chargedHadron.
p4() - chargedHadron_modified.
p4());
229 std::cout <<
"case (3): (addNeutralsSumEn + mergedNeutralsSumEn) > nonPFCandTracksSumP --> adjusting tau momentum." << std::endl;
231 updateTauP4(tau, -1., diffP4);
236 unsigned numChargedHadronNeutrals = 0;
237 std::vector<reco::PFCandidatePtr> chargedHadronNeutrals;
239 for ( std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
242 ++numChargedHadronNeutrals;
243 chargedHadronNeutrals.push_back(
chargedHadron->getChargedPFCandidate());
244 chargedHadronNeutralsSumP4 +=
chargedHadron->getChargedPFCandidate()->p4();
248 std::cout <<
"chargedHadronNeutralsSumP4: En = " << chargedHadronNeutralsSumP4.energy()
249 <<
" (numChargedHadronNeutrals = " << numChargedHadronNeutrals <<
")" << std::endl;
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.) ) {
258 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
263 size_t numChargedHadrons = chargedHadrons.size();
264 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
270 double chargedHadronPx_modified = scaleFactor*chargedPFCand->px();
271 double chargedHadronPy_modified = scaleFactor*chargedPFCand->py();
272 double chargedHadronPz_modified = scaleFactor*chargedPFCand->pz();
274 chargedHadron_modified.
setP4(chargedHadronP4_modified);
276 diffP4 += (chargedHadron.
p4() - chargedHadron_modified.
p4());
280 std::cout <<
"case (4): (addNeutralsSumEn + mergedNeutralsSumEn + chargedHadronNeutralsSumEn) > nonPFCandTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
282 updateTauP4(tau, -1., diffP4);
285 double allTracksSumP = 0.;
286 double allTracksSumPerr2 = 0.;
288 for ( std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
293 allTracksSumP += chargedHadronTrack->p();
294 allTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
297 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
305 std::cout <<
"allTracksSumP = " << allTracksSumP <<
" +/- " <<
sqrt(allTracksSumPerr2) << std::endl;
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 ) {
312 std::cout <<
"PFCandidate #" << signalPFCand->id() <<
":" << signalPFCand->key() <<
":" 313 <<
" Pt = " << (*signalPFCand)->pt() <<
", eta = " << (*signalPFCand)->eta() <<
", phi = " << (*signalPFCand)->phi() << std::endl;
315 <<
" ECAL = " << (*signalPFCand)->ecalEnergy() <<
"," 316 <<
" HCAL = " << (*signalPFCand)->hcalEnergy() <<
"," 317 <<
" HO = " << (*signalPFCand)->hoEnergy() << std::endl;
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();
323 allNeutralsSumEn += addNeutralsSumP4.energy();
324 if ( allNeutralsSumEn < 0. ) allNeutralsSumEn = 0.;
326 std::cout <<
"allNeutralsSumEn = " << allNeutralsSumEn << std::endl;
328 if ( allNeutralsSumEn > allTracksSumP ) {
330 size_t numChargedHadrons = chargedHadrons.size();
331 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
338 std::cout <<
"chargedHadron #" << iChargedHadron <<
": changing En = " << chargedHadron.
energy() <<
" to " << chargedHadron_modified.
energy() << std::endl;
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();
353 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
355 chargedHadron.
print();
358 chargedHadron_modified.
setP4(chargedHadronP4_modified);
360 std::cout <<
"chargedHadron #" << iChargedHadron <<
": changing En = " << chargedHadron.
energy() <<
" to " << chargedHadron_modified.
energy() << std::endl;
367 std::cout <<
"case (5): allNeutralsSumEn > allTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
369 updateTauP4(tau, scaleFactor - 1., tau.
p4());
374 size_t numChargedHadrons = chargedHadrons.size();
375 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
383 double trackP = chargedHadronTrack->p();
384 double trackPerr2 = getTrackPerr2(*chargedHadronTrack);
386 std::cout <<
"trackP = " << trackP <<
" +/- " <<
sqrt(trackPerr2) << std::endl;
390 double trackP_modified =
391 (trackP*(allTracksSumPerr2 - trackPerr2)
392 + trackPerr2*(allNeutralsSumEn - (allTracksSumP - trackP)))/
397 if ( trackP_modified < 1.
e-1 ) trackP_modified = 1.e-1;
399 std::cout <<
"trackP (modified) = " << trackP_modified << std::endl;
402 if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
404 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
408 double chargedHadronPx_modified = scaleFactor*chargedHadronTrack->px();
409 double chargedHadronPy_modified = scaleFactor*chargedHadronTrack->py();
410 double chargedHadronPz_modified = scaleFactor*chargedHadronTrack->pz();
414 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
416 chargedHadron.
print();
419 chargedHadron_modified.
setP4(chargedHadronP4_modified);
421 std::cout <<
"chargedHadron #" << iChargedHadron <<
": changing En = " << chargedHadron.
energy() <<
" to " << chargedHadron_modified.
energy() << std::endl;
428 std::cout <<
"case (6): allNeutralsSumEn < allTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
430 updateTauP4(tau, scaleFactor - 1., tau.
p4());
437 std::cout <<
"case (7): allNeutralsSumEn < allTracksSumP not compatible with tau decay mode hypothesis --> killing tau candidate." << std::endl;
448 std::cout <<
"undefined case: you should never come here !!" << std::endl;
double p() const
momentum vector magnitude
T getParameter(std::string const &) const
ParticleType
particle types
const PFJetRef & jetRef() const
double eta() const final
momentum pseudorapidity
double px() const final
x coordinate of momentum vector
bool exists(std::string const ¶meterName) const
checks if a parameter exists
double pt() const final
transverse momentum
double px() const
x coordinate of momentum vector
void beginEvent() override
double minNeutralHadronEt_
const std::vector< reco::PFCandidatePtr > & signalPFCands() const
PFCandidates in signal region.
hadronicDecayMode decayMode() const
void print(std::ostream &stream=std::cout) const
double pz() const final
z coordinate of momentum vector
const std::vector< RecoTauPiZero > & signalPiZeroCandidates() const
Retrieve the association of signal region gamma candidates into candidate PiZeros.
double pt() const
track transverse momentum
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
double energy() const final
energy
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
~PFRecoTauEnergyAlgorithmPlugin() override
const LorentzVector & p4() const final
four-momentum Lorentz vector
const TrackPtr & getTrack() const
reference to reco::Track
void operator()(PFTau &) const override
bool isNonnull() const
Checks for non-null.
double pz() const
z coordinate of momentum vector
double dRaddNeutralHadron_
const std::vector< PFCandidatePtr > & getNeutralPFCandidates() const
references to additional neutral PFCandidates
std::vector< PFCandidatePtr > neutralPFCandidates_
double py() const final
y coordinate of momentum vector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
PFRecoTauEnergyAlgorithmPlugin(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
bool algoIs(PFRecoTauChargedHadronAlgorithm algo) const
Check whether a given algo produced this charged hadron.
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::vector< PFRecoTauChargedHadron > & signalTauChargedHadronCandidatesRestricted()
void setStatus(int status) final
set status word
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
double phi() const final
momentum azimuthal angle
void setP4(const LorentzVector &p4) final
set 4-momentum
double py() const
y coordinate of momentum vector
const PFCandidatePtr & getChargedPFCandidate() const
reference to "charged" PFCandidate (either charged PFCandidate or PFNeutralHadron) ...
double mass() const final
mass
reco::Candidate::LorentzVector compChargedHadronP4fromPxPyPz(double, double, double)