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 verbosity_(
cfg.getParameter<
int>(
"verbosity")) {}
71 return trackPerr * trackPerr;
76 double tauPx_modified =
tau.px() + sf * addP4.px();
77 double tauPy_modified =
tau.py() + sf * addP4.py();
78 double tauPz_modified =
tau.pz() + sf * addP4.pz();
79 double tauMass =
tau.mass();
80 double tauEn_modified =
sqrt(tauPx_modified * tauPx_modified + tauPy_modified * tauPy_modified +
81 tauPz_modified * tauPz_modified + tauMass * tauMass);
83 tau.setP4(tauP4_modified);
88 tau.setP4(tauP4_modified);
93 template <
class Base,
class Der>
105 std::cout <<
"<PFRecoTauEnergyAlgorithmPlugin::operator()>:" << std::endl;
106 std::cout <<
"tau: Pt = " <<
tau.pt() <<
", eta = " <<
tau.eta() <<
", phi = " <<
tau.phi()
107 <<
" (En = " <<
tau.energy() <<
", decayMode = " <<
tau.decayMode() <<
")" << std::endl;
111 std::vector<reco::CandidatePtr> addNeutrals;
113 const auto& jetConstituents =
tau.jetRef()->daughterPtrVector();
114 for (
const auto& jetConstituent : jetConstituents) {
115 int jetConstituentPdgId =
std::abs(jetConstituent->pdgId());
117 (jetConstituentPdgId == 22 && jetConstituent->et() >
minGammaEt_)))
120 bool isSignalCand =
false;
121 const auto& signalCands =
tau.signalCands();
122 for (
const auto& signalCand : signalCands) {
129 double dR =
deltaR(jetConstituent->p4(),
tau.p4());
131 if (jetConstituentPdgId == 130)
133 else if (jetConstituentPdgId == 22)
136 addNeutrals.push_back(jetConstituent);
137 addNeutralsSumP4 += jetConstituent->p4();
141 std::cout <<
"addNeutralsSumP4: En = " << addNeutralsSumP4.energy() << std::endl;
144 unsigned numNonPFCandTracks = 0;
145 double nonPFCandTracksSumP = 0.;
146 double nonPFCandTracksSumPerr2 = 0.;
147 const std::vector<PFRecoTauChargedHadron>& chargedHadrons =
tau.signalTauChargedHadronCandidatesRestricted();
148 for (std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
152 ++numNonPFCandTracks;
154 if (chargedHadronTrack !=
nullptr) {
155 nonPFCandTracksSumP += chargedHadronTrack->
p();
156 nonPFCandTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
161 std::cout <<
"nonPFCandTracksSumP = " << nonPFCandTracksSumP <<
" +/- " <<
sqrt(nonPFCandTracksSumPerr2)
162 <<
" (numNonPFCandTracks = " << numNonPFCandTracks <<
")" << std::endl;
165 if (numNonPFCandTracks == 0) {
170 std::cout <<
"easy case: all tracks are associated to PFCandidates --> leaving tau momentum untouched." 173 updateTauP4(
tau, 1., addNeutralsSumP4);
182 if (nonPFCandTracksSumP < addNeutralsSumP4.energy()) {
183 double scaleFactor = 1. - nonPFCandTracksSumP / addNeutralsSumP4.energy();
186 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
191 std::cout <<
"case (2): addNeutralsSumEn > nonPFCandTracksSumP --> adjusting tau momentum." << std::endl;
199 std::vector<reco::CandidatePtr> mergedNeutrals;
201 for (std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
205 const std::vector<reco::CandidatePtr>& neutralPFCands =
chargedHadron->getNeutralPFCandidates();
206 for (std::vector<reco::CandidatePtr>::const_iterator neutralPFCand = neutralPFCands.begin();
207 neutralPFCand != neutralPFCands.end();
209 mergedNeutrals.push_back(*neutralPFCand);
210 mergedNeutralsSumP4 += (*neutralPFCand)->p4();
215 std::cout <<
"mergedNeutralsSumP4: En = " << mergedNeutralsSumP4.energy() << std::endl;
220 if (nonPFCandTracksSumP < (addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy())) {
221 double scaleFactor = ((addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy()) - nonPFCandTracksSumP) /
222 mergedNeutralsSumP4.energy();
225 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
230 size_t numChargedHadrons = chargedHadrons.size();
231 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron) {
236 tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
241 std::cout <<
"case (3): (addNeutralsSumEn + mergedNeutralsSumEn) > nonPFCandTracksSumP --> adjusting tau " 245 updateTauP4(
tau, -1., diffP4);
250 unsigned numChargedHadronNeutrals = 0;
251 std::vector<reco::CandidatePtr> chargedHadronNeutrals;
253 for (std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
257 ++numChargedHadronNeutrals;
258 chargedHadronNeutrals.push_back(
chargedHadron->getChargedPFCandidate());
259 chargedHadronNeutralsSumP4 +=
chargedHadron->getChargedPFCandidate()->p4();
263 std::cout <<
"chargedHadronNeutralsSumP4: En = " << chargedHadronNeutralsSumP4.energy()
264 <<
" (numChargedHadronNeutrals = " << numChargedHadronNeutrals <<
")" << std::endl;
269 if (nonPFCandTracksSumP <
270 (addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy() + chargedHadronNeutralsSumP4.energy())) {
272 ((addNeutralsSumP4.energy() + mergedNeutralsSumP4.energy() + chargedHadronNeutralsSumP4.energy()) -
273 nonPFCandTracksSumP) /
274 chargedHadronNeutralsSumP4.energy();
277 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
282 size_t numChargedHadrons = chargedHadrons.size();
283 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron) {
289 double chargedHadronPx_modified =
scaleFactor * chargedPFCand->px();
290 double chargedHadronPy_modified =
scaleFactor * chargedPFCand->py();
291 double chargedHadronPz_modified =
scaleFactor * chargedPFCand->pz();
293 chargedHadronPx_modified, chargedHadronPy_modified, chargedHadronPz_modified);
294 chargedHadron_modified.
setP4(chargedHadronP4_modified);
295 tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
300 std::cout <<
"case (4): (addNeutralsSumEn + mergedNeutralsSumEn + chargedHadronNeutralsSumEn) > " 301 "nonPFCandTracksSumP --> adjusting momenta of tau and chargedHadrons." 304 updateTauP4(
tau, -1., diffP4);
307 double allTracksSumP = 0.;
308 double allTracksSumPerr2 = 0.;
309 const std::vector<PFRecoTauChargedHadron> chargedHadrons =
tau.signalTauChargedHadronCandidatesRestricted();
310 for (std::vector<PFRecoTauChargedHadron>::const_iterator
chargedHadron = chargedHadrons.begin();
316 if (chargedHadronTrack !=
nullptr) {
317 allTracksSumP += chargedHadronTrack->
p();
318 allTracksSumPerr2 += getTrackPerr2(*chargedHadronTrack);
323 chargedHadron->getLostTrackCandidate()->bestTrack() ==
nullptr)) {
324 edm::LogInfo(
"PFRecoTauEnergyAlgorithmPlugin::operator()")
325 <<
"PFRecoTauChargedHadron has no associated reco::Track !!";
334 std::cout <<
"allTracksSumP = " << allTracksSumP <<
" +/- " <<
sqrt(allTracksSumPerr2) << std::endl;
336 double allNeutralsSumEn = 0.;
337 const auto& signalCands =
tau.signalCands();
338 for (
const auto& signalCand : signalCands) {
340 std::cout <<
"Candidate #" << signalCand.id() <<
":" << signalCand.key() <<
":" 341 <<
" Pt = " << (signalCand)->
pt() <<
", eta = " << (signalCand)->
eta()
342 <<
", phi = " << (signalCand)->phi() << std::endl;
348 <<
" ECAL = " << (pfCand)->ecalEnergy() <<
"," 349 <<
" HCAL = " << (pfCand)->hcalEnergy() <<
"," 350 <<
" HO = " << (pfCand)->hoEnergy() << std::endl;
357 allNeutralsSumEn += pfCand->
hoEnergy();
364 double ecalEn = caloEn - hcalEn;
367 <<
" ECAL = " << ecalEn <<
"," 368 <<
" HCAL = " << hcalEn <<
"," 369 <<
" HO unknown for PackedCand" << std::endl;
372 allNeutralsSumEn += ecalEn;
374 allNeutralsSumEn += hcalEn;
377 allNeutralsSumEn += addNeutralsSumP4.energy();
378 if (allNeutralsSumEn < 0.)
379 allNeutralsSumEn = 0.;
381 std::cout <<
"allNeutralsSumEn = " << allNeutralsSumEn << std::endl;
383 if (allNeutralsSumEn > allTracksSumP) {
385 size_t numChargedHadrons = chargedHadrons.size();
386 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron) {
394 <<
" to " << chargedHadron_modified.
energy() << std::endl;
396 tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
402 if (chTrack !=
nullptr) {
403 double chargedHadronPx_modified = chTrack->
px();
404 double chargedHadronPy_modified = chTrack->
py();
405 double chargedHadronPz_modified = chTrack->
pz();
407 chargedHadronPx_modified, chargedHadronPy_modified, chargedHadronPz_modified);
412 chargedHadron.getLostTrackCandidate()->bestTrack() ==
nullptr)) {
414 <<
"PFRecoTauChargedHadron has no associated reco::Track !!" << std::endl;
420 chargedHadron_modified.
setP4(chargedHadronP4_modified);
423 <<
" to " << chargedHadron_modified.
energy() << std::endl;
425 tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
430 std::cout <<
"case (5): allNeutralsSumEn > allTracksSumP --> adjusting momenta of tau and chargedHadrons." 436 if (numChargedHadronNeutrals == 0 &&
tau.signalPiZeroCandidates().empty()) {
438 size_t numChargedHadrons = chargedHadrons.size();
439 for (
size_t iChargedHadron = 0; iChargedHadron < numChargedHadrons; ++iChargedHadron) {
447 if (chargedHadronTrack !=
nullptr) {
448 double trackP = chargedHadronTrack->
p();
449 double trackPerr2 = getTrackPerr2(*chargedHadronTrack);
451 std::cout <<
"trackP = " << trackP <<
" +/- " <<
sqrt(trackPerr2) << std::endl;
455 double trackP_modified = (trackP * (allTracksSumPerr2 - trackPerr2) +
456 trackPerr2 * (allNeutralsSumEn - (allTracksSumP - trackP))) /
461 if (trackP_modified < 1.
e-1)
462 trackP_modified = 1.e-1;
464 std::cout <<
"trackP (modified) = " << trackP_modified << std::endl;
469 <<
"Failed to compute tau energy --> killing tau candidate !!" << std::endl;
473 double chargedHadronPx_modified =
scaleFactor * chargedHadronTrack->
px();
474 double chargedHadronPy_modified =
scaleFactor * chargedHadronTrack->
py();
475 double chargedHadronPz_modified =
scaleFactor * chargedHadronTrack->
pz();
477 chargedHadronPx_modified, chargedHadronPy_modified, chargedHadronPz_modified);
482 chargedHadron.getLostTrackCandidate()->bestTrack() ==
nullptr)) {
483 edm::LogInfo(
"PFRecoTauEnergyAlgorithmPlugin::operator()")
484 <<
"PFRecoTauChargedHadron has no associated reco::Track !!";
490 chargedHadron_modified.
setP4(chargedHadronP4_modified);
493 <<
" to " << chargedHadron_modified.
energy() << std::endl;
495 tau.signalTauChargedHadronCandidatesRestricted()[iChargedHadron] = chargedHadron_modified;
501 <<
"case (6): allNeutralsSumEn < allTracksSumP --> adjusting momenta of tau and chargedHadrons." 511 std::cout <<
"case (7): allNeutralsSumEn < allTracksSumP not compatible with tau decay mode hypothesis " 512 "--> killing tau candidate." 524 std::cout <<
"undefined case: you should never come here !!" << std::endl;
538 "PFRecoTauEnergyAlgorithmPlugin");
double px() const
x coordinate of momentum vector
double p() const
momentum vector magnitude
double py() const
y coordinate of momentum vector
float caloFraction() const
Set the fraction of ECAL+HCAL energy over candidate energy.
void beginEvent() override
constexpr bool isFinite(T x)
double minNeutralHadronEt_
const LorentzVector & p4() const final
four-momentum Lorentz vector
double hcalEnergy() const
return corrected Hcal energy
Abs< T >::type abs(const T &t)
~PFRecoTauEnergyAlgorithmPlugin() override
std::vector< CandidatePtr > neutralPFCandidates_
double ecalEnergy() const
return corrected Ecal energy
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Log< level::Info, false > LogInfo
bool isPtrEqual(const edm::Ptr< Base > &b, const edm::Ptr< Der > &d)
double hoEnergy() const
return corrected Hcal energy
double dRaddNeutralHadron_
double pz() const
z coordinate of momentum vector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
const reco::Track * getTrackFromChargedHadron(const reco::PFRecoTauChargedHadron &chargedHadron)
void operator()(reco::PFTau &) const override
float hcalFraction() const
Particle reconstructed by the particle flow algorithm.
double energy() const override
energy
PFRecoTauEnergyAlgorithmPlugin(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
#define DEFINE_EDM_PLUGIN(factory, type, name)
Log< level::Warning, false > LogWarning
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
void setP4(const LorentzVector &p4) final
set 4-momentum
double energy() const final
energy
reco::Candidate::LorentzVector compChargedHadronP4fromPxPyPz(double, double, double)