34 namespace reco {
namespace tau {
59 dRaddNeutralHadron_(cfg.getParameter<double>(
"dRaddNeutralHadron")),
60 minNeutralHadronEt_(cfg.getParameter<double>(
"minNeutralHadronEt")),
61 dRaddPhoton_(cfg.getParameter<double>(
"dRaddPhoton")),
62 minGammaEt_(cfg.getParameter<double>(
"minGammaEt"))
81 double trackPerr = track.
p()*(track.
ptError()/track.
pt());
82 return trackPerr*trackPerr;
88 double tauPx_modified = tau.
px() + sf*addP4.px();
89 double tauPy_modified = tau.
py() + sf*addP4.py();
90 double tauPz_modified = tau.
pz() + sf*addP4.pz();
92 double tauEn_modified =
sqrt(tauPx_modified*tauPx_modified + tauPy_modified*tauPy_modified + tauPz_modified*tauPz_modified + tauMass*tauMass);
94 tau.
setP4(tauP4_modified);
97 void killTau(
PFTau& tau)
100 tau.setP4(tauP4_modified);
108 std::cout <<
"<PFRecoTauEnergyAlgorithmPlugin::operator()>:" << std::endl;
109 std::cout <<
"tau: Pt = " << tau.
pt() <<
", eta = " << tau.
eta() <<
", phi = " << tau.
phi() <<
" (En = " << tau.
energy() <<
", decayMode = " << tau.
decayMode() <<
")" << std::endl;
113 std::vector<reco::PFCandidatePtr> addNeutrals;
115 std::vector<reco::PFCandidatePtr> jetConstituents = tau.
jetRef()->getPFConstituents();
116 for ( std::vector<reco::PFCandidatePtr>::const_iterator jetConstituent = jetConstituents.begin();
117 jetConstituent != jetConstituents.end(); ++jetConstituent ) {
122 bool isSignalPFCand =
false;
123 const std::vector<reco::PFCandidatePtr>& signalPFCands = tau.
signalPFCands();
124 for ( std::vector<reco::PFCandidatePtr>::const_iterator signalPFCand = signalPFCands.begin();
125 signalPFCand != signalPFCands.end(); ++signalPFCand ) {
126 if ( (*jetConstituent) == (*signalPFCand) ) isSignalPFCand =
true;
128 if ( isSignalPFCand )
continue;
130 double dR =
deltaR((*jetConstituent)->p4(), tau.
p4());
135 addNeutrals.push_back(*jetConstituent);
136 addNeutralsSumP4 += (*jetConstituent)->p4();
140 std::cout <<
"addNeutralsSumP4: En = " << addNeutralsSumP4.energy() << std::endl;
143 unsigned numNonPFCandTracks = 0;
144 double nonPFCandTracksSumP = 0.;
145 double nonPFCandTracksSumPerr2 = 0.;
147 for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
148 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
150 ++numNonPFCandTracks;
152 nonPFCandTracksSumP += chargedHadronTrack->p();
153 nonPFCandTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
157 std::cout <<
"nonPFCandTracksSumP = " << nonPFCandTracksSumP <<
" +/- " <<
sqrt(nonPFCandTracksSumPerr2)
158 <<
" (numNonPFCandTracks = " << numNonPFCandTracks <<
")" << std::endl;
161 if ( numNonPFCandTracks == 0 ) {
166 std::cout <<
"easy case: all tracks are associated to PFCandidates --> leaving tau momentum untouched." << std::endl;
168 updateTauP4(tau, 1., addNeutralsSumP4);
177 if ( nonPFCandTracksSumP < addNeutralsSumP4.energy() ) {
178 double scaleFactor = 1. - nonPFCandTracksSumP/addNeutralsSumP4.energy();
179 if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
181 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
186 std::cout <<
"case (2): addNeutralsSumEn > nonPFCandTracksSumP --> adjusting tau momentum." << std::endl;
188 updateTauP4(tau, scaleFactor, addNeutralsSumP4);
194 std::vector<reco::PFCandidatePtr> mergedNeutrals;
196 for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
197 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
199 const std::vector<reco::PFCandidatePtr>& neutralPFCands = chargedHadron->getNeutralPFCandidates();
200 for ( std::vector<reco::PFCandidatePtr>::const_iterator neutralPFCand = neutralPFCands.begin();
201 neutralPFCand != neutralPFCands.end(); ++neutralPFCand ) {
202 mergedNeutrals.push_back(*neutralPFCand);
203 mergedNeutralsSumP4 += (*neutralPFCand)->p4();
208 std::cout <<
"mergedNeutralsSumP4: En = " << mergedNeutralsSumP4.energy() << std::endl;
213 if ( nonPFCandTracksSumP < (addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy()) ) {
214 double scaleFactor = ((addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy()) - nonPFCandTracksSumP)/mergedNeutralsSumP4.energy();
215 if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
217 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
222 size_t numChargedHadrons = chargedHadrons.size();
223 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
229 diffP4 += (chargedHadron.
p4() - chargedHadron_modified.
p4());
233 std::cout <<
"case (3): (addNeutralsSumEn + mergedNeutralsSumEn) > nonPFCandTracksSumP --> adjusting tau momentum." << std::endl;
235 updateTauP4(tau, -1., diffP4);
240 unsigned numChargedHadronNeutrals = 0;
241 std::vector<reco::PFCandidatePtr> chargedHadronNeutrals;
243 for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
244 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
246 ++numChargedHadronNeutrals;
247 chargedHadronNeutrals.push_back(chargedHadron->getChargedPFCandidate());
248 chargedHadronNeutralsSumP4 += chargedHadron->getChargedPFCandidate()->p4();
252 std::cout <<
"chargedHadronNeutralsSumP4: En = " << chargedHadronNeutralsSumP4.energy()
253 <<
" (numChargedHadronNeutrals = " << numChargedHadronNeutrals <<
")" << std::endl;
258 if ( nonPFCandTracksSumP < (addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy() + chargedHadronNeutralsSumP4.energy()) ) {
259 double scaleFactor = ((addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy() + chargedHadronNeutralsSumP4.energy()) - nonPFCandTracksSumP)/chargedHadronNeutralsSumP4.energy();
260 if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
262 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
267 size_t numChargedHadrons = chargedHadrons.size();
268 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
274 double chargedHadronPx_modified = scaleFactor*chargedPFCand->px();
275 double chargedHadronPy_modified = scaleFactor*chargedPFCand->py();
276 double chargedHadronPz_modified = scaleFactor*chargedPFCand->pz();
278 chargedHadron_modified.
setP4(chargedHadronP4_modified);
280 diffP4 += (chargedHadron.
p4() - chargedHadron_modified.
p4());
284 std::cout <<
"case (4): (addNeutralsSumEn + mergedNeutralsSumEn + chargedHadronNeutralsSumEn) > nonPFCandTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
286 updateTauP4(tau, -1., diffP4);
289 double allTracksSumP = 0.;
290 double allTracksSumPerr2 = 0.;
292 for ( std::vector<PFRecoTauChargedHadron>::const_iterator chargedHadron = chargedHadrons.begin();
293 chargedHadron != chargedHadrons.end(); ++chargedHadron ) {
297 allTracksSumP += chargedHadronTrack->p();
298 allTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
301 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
303 chargedHadron->print();
309 std::cout <<
"allTracksSumP = " << allTracksSumP <<
" +/- " <<
sqrt(allTracksSumPerr2) << std::endl;
311 double allNeutralsSumEn = 0.;
312 const std::vector<reco::PFCandidatePtr>& signalPFCands = tau.
signalPFCands();
313 for ( std::vector<reco::PFCandidatePtr>::const_iterator signalPFCand = signalPFCands.begin();
314 signalPFCand != signalPFCands.end(); ++signalPFCand ) {
316 std::cout <<
"PFCandidate #" << signalPFCand->id() <<
":" << signalPFCand->key() <<
":"
317 <<
" Pt = " << (*signalPFCand)->pt() <<
", eta = " << (*signalPFCand)->eta() <<
", phi = " << (*signalPFCand)->phi() << std::endl;
319 <<
" ECAL = " << (*signalPFCand)->ecalEnergy() <<
","
320 <<
" HCAL = " << (*signalPFCand)->hcalEnergy() <<
","
321 <<
" HO = " << (*signalPFCand)->hoEnergy() << std::endl;
323 if (
edm::isFinite((*signalPFCand)->ecalEnergy()) ) allNeutralsSumEn += (*signalPFCand)->ecalEnergy();
324 if (
edm::isFinite((*signalPFCand)->hcalEnergy()) ) allNeutralsSumEn += (*signalPFCand)->hcalEnergy();
325 if (
edm::isFinite((*signalPFCand)->hoEnergy()) ) allNeutralsSumEn += (*signalPFCand)->hoEnergy();
327 allNeutralsSumEn += addNeutralsSumP4.energy();
328 if ( allNeutralsSumEn < 0. ) allNeutralsSumEn = 0.;
330 std::cout <<
"allNeutralsSumEn = " << allNeutralsSumEn << std::endl;
332 if ( allNeutralsSumEn > allTracksSumP ) {
334 size_t numChargedHadrons = chargedHadrons.size();
335 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
342 std::cout <<
"chargedHadron #" << iChargedHadron <<
": changing En = " << chargedHadron.
energy() <<
" to " << chargedHadron_modified.
energy() << std::endl;
349 if ( (chargedHadron.
getTrack()).isNonnull() ) {
350 const Track& chargedHadronTrack = *(chargedHadron.
getTrack());
351 double chargedHadronPx_modified = chargedHadronTrack.
px();
352 double chargedHadronPy_modified = chargedHadronTrack.
py();
353 double chargedHadronPz_modified = chargedHadronTrack.
pz();
357 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
359 chargedHadron.
print();
362 chargedHadron_modified.
setP4(chargedHadronP4_modified);
364 std::cout <<
"chargedHadron #" << iChargedHadron <<
": changing En = " << chargedHadron.
energy() <<
" to " << chargedHadron_modified.
energy() << std::endl;
369 double scaleFactor = allNeutralsSumEn/tau.
energy();
371 std::cout <<
"case (5): allNeutralsSumEn > allTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
373 updateTauP4(tau, scaleFactor - 1., tau.
p4());
378 size_t numChargedHadrons = chargedHadrons.size();
379 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron ) {
387 double trackP = chargedHadronTrack->p();
388 double trackPerr2 = getTrackPerr2(*chargedHadronTrack);
390 std::cout <<
"trackP = " << trackP <<
" +/- " <<
sqrt(trackPerr2) << std::endl;
394 double trackP_modified =
395 (trackP*(allTracksSumPerr2 - trackPerr2)
396 + trackPerr2*(allNeutralsSumEn - (allTracksSumP - trackP)))/
401 if ( trackP_modified < 1.
e-1 ) trackP_modified = 1.e-1;
403 std::cout <<
"trackP (modified) = " << trackP_modified << std::endl;
405 double scaleFactor = trackP_modified/trackP;
406 if ( !(scaleFactor >= 0. && scaleFactor <= 1.) ) {
408 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
412 double chargedHadronPx_modified = scaleFactor*chargedHadronTrack->px();
413 double chargedHadronPy_modified = scaleFactor*chargedHadronTrack->py();
414 double chargedHadronPz_modified = scaleFactor*chargedHadronTrack->pz();
418 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
420 chargedHadron.
print();
423 chargedHadron_modified.
setP4(chargedHadronP4_modified);
425 std::cout <<
"chargedHadron #" << iChargedHadron <<
": changing En = " << chargedHadron.
energy() <<
" to " << chargedHadron_modified.
energy() << std::endl;
430 double scaleFactor = allNeutralsSumEn/tau.
energy();
432 std::cout <<
"case (6): allNeutralsSumEn < allTracksSumP --> adjusting momenta of tau and chargedHadrons." << std::endl;
434 updateTauP4(tau, scaleFactor - 1., tau.
p4());
441 std::cout <<
"case (7): allNeutralsSumEn < allTracksSumP not compatible with tau decay mode hypothesis --> killing tau candidate." << std::endl;
452 std::cout <<
"undefined case: you should never come here !!" << std::endl;
double p() const
momentum vector magnitude
virtual double energy() const GCC11_FINAL
energy
T getParameter(std::string const &) const
virtual ~PFRecoTauEnergyAlgorithmPlugin()
ParticleType
particle types
const PFJetRef & jetRef() const
virtual const LorentzVector & p4() const GCC11_FINAL
four-momentum Lorentz vector
std::vector< reco::PFRecoTauChargedHadron > signalTauChargedHadronCandidates_
bool exists(std::string const ¶meterName) const
checks if a parameter exists
double px() const
x coordinate of momentum vector
virtual double pz() const GCC11_FINAL
z coordinate of momentum vector
double minNeutralHadronEt_
virtual double py() const GCC11_FINAL
y coordinate of momentum vector
const std::vector< reco::PFCandidatePtr > & signalPFCands() const
PFCandidates in signal region.
hadronicDecayMode decayMode() const
void print(std::ostream &stream=std::cout) const
virtual float phi() const GCC11_FINAL
momentum azimuthal angle
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.
double pt() const
track transverse momentum
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
virtual double px() const GCC11_FINAL
x coordinate of momentum vector
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
const TrackPtr & getTrack() const
reference to reco::Track
virtual void beginJob(edm::EDProducer *)
double pz() const
z coordinate of momentum vector
virtual float eta() const GCC11_FINAL
momentum pseudorapidity
virtual float mass() const GCC11_FINAL
mass
double dRaddNeutralHadron_
const std::vector< PFCandidatePtr > & getNeutralPFCandidates() const
references to additional neutral PFCandidates
std::vector< PFCandidatePtr > neutralPFCandidates_
math::XYZTLorentzVector LorentzVector
Lorentz vector.
virtual void beginEvent()
virtual void setP4(const LorentzVector &p4) GCC11_FINAL
set 4-momentum
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.
#define DEFINE_EDM_PLUGIN(factory, type, name)
virtual float pt() const GCC11_FINAL
transverse momentum
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
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)