34 namespace reco {
namespace tau {
58 dRaddNeutralHadron_(cfg.getParameter<double>(
"dRaddNeutralHadron")),
59 minNeutralHadronEt_(cfg.getParameter<double>(
"minNeutralHadronEt")),
60 dRaddPhoton_(cfg.getParameter<double>(
"dRaddPhoton")),
61 minGammaEt_(cfg.getParameter<double>(
"minGammaEt"))
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();
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();
144 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
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();
193 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
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();
240 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
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();
289 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
293 allTracksSumP += chargedHadronTrack->p();
294 allTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
297 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
299 chargedHadron->print();
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;
365 double scaleFactor = allNeutralsSumEn/tau.
energy();
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;
401 double scaleFactor = trackP_modified/trackP;
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;
426 double scaleFactor = allNeutralsSumEn/tau.
energy();
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
virtual ~PFRecoTauEnergyAlgorithmPlugin()
ParticleType
particle types
const PFJetRef & jetRef() const
virtual float pt() const
transverse momentum
std::vector< reco::PFRecoTauChargedHadron > signalTauChargedHadronCandidates_
virtual float phi() const
momentum azimuthal angle
bool exists(std::string const ¶meterName) const
checks if a parameter exists
virtual void setP4(const LorentzVector &p4)
set 4-momentum
double deltaR(const T1 &t1, const T2 &t2)
double px() const
x coordinate of momentum vector
double minNeutralHadronEt_
const std::vector< reco::PFCandidatePtr > & signalPFCands() const
PFCandidates in signal region.
hadronicDecayMode decayMode() const
void print(std::ostream &stream=std::cout) const
virtual double energy() const
energy
bool isNonnull() const
Checks for non-null.
void operator()(PFTau &) const
const std::vector< RecoTauPiZero > & signalPiZeroCandidates() const
Retrieve the association of signal region gamma candidates into candidate PiZeros.
virtual float eta() const
momentum pseudorapidity
double pt() const
track transverse momentum
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
const TrackPtr & getTrack() const
reference to reco::Track
double pz() const
z coordinate of momentum vector
double dRaddNeutralHadron_
virtual double px() const
x coordinate of momentum vector
const std::vector< PFCandidatePtr > & getNeutralPFCandidates() const
references to additional neutral PFCandidates
std::vector< PFCandidatePtr > neutralPFCandidates_
virtual double pz() const
z coordinate of momentum vector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
virtual void beginEvent()
PFRecoTauEnergyAlgorithmPlugin(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
bool algoIs(PFRecoTauChargedHadronAlgorithm algo) const
Check whether a given algo produced this charged hadron.
const std::vector< PFRecoTauChargedHadron > & signalTauChargedHadronCandidates() const
Retrieve the association of signal region PF candidates into candidate PFRecoTauChargedHadrons.
virtual float mass() const
mass
#define DEFINE_EDM_PLUGIN(factory, type, name)
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
virtual const LorentzVector & p4() const
four-momentum Lorentz vector
virtual double py() const
y coordinate of momentum vector
double py() const
y coordinate of momentum vector
const PFCandidatePtr & getChargedPFCandidate() const
reference to "charged" PFCandidate (either charged PFCandidate or PFNeutralHadron) ...
reco::Candidate::LorentzVector compChargedHadronP4fromPxPyPz(double, double, double)