34 moduleLabel_(
pset.getParameter<
std::
string>(
"@module_label")),
36 includeTracks_ =
pset.getParameter<
bool>(
"ApplyDiscriminationByTrackerIsolation");
37 includeGammas_ =
pset.getParameter<
bool>(
"ApplyDiscriminationByECALIsolation");
39 calculateWeights_ =
pset.getParameter<
bool>(
"ApplyDiscriminationByWeightedECALIsolation");
41 enableHGCalWorkaround_ =
pset.getParameter<
bool>(
"enableHGCalWorkaround");
46 weightGammas_ =
pset.getParameter<
double>(
"WeightECALIsolation");
49 minPtForNoIso_ =
pset.getParameter<
double>(
"minTauPtForNoIso");
51 applyOccupancyCut_ =
pset.getParameter<
bool>(
"applyOccupancyCut");
52 maximumOccupancy_ =
pset.getParameter<uint32_t>(
"maximumOccupancy");
54 applySumPtCut_ =
pset.getParameter<
bool>(
"applySumPtCut");
55 maximumSumPt_ =
pset.getParameter<
double>(
"maximumSumPtCut");
57 applyRelativeSumPtCut_ =
pset.getParameter<
bool>(
"applyRelativeSumPtCut");
58 maximumRelativeSumPt_ =
pset.getParameter<
double>(
"relativeSumPtCut");
59 offsetRelativeSumPt_ =
pset.getParameter<
double>(
"relativeSumPtOffset");
61 storeRawOccupancy_ =
pset.getParameter<
bool>(
"storeRawOccupancy");
62 storeRawSumPt_ =
pset.getParameter<
bool>(
"storeRawSumPt");
63 storeRawPUsumPt_ =
pset.getParameter<
bool>(
"storeRawPUsumPt");
64 storeRawFootprintCorrection_ =
pset.getParameter<
bool>(
"storeRawFootprintCorrection");
65 storeRawPhotonSumPt_outsideSignalCone_ =
pset.getParameter<
bool>(
"storeRawPhotonSumPt_outsideSignalCone");
69 if (applySumPtCut_ || applyOccupancyCut_ || applyRelativeSumPtCut_) {
70 if (storeRawSumPt_ || storeRawOccupancy_ || storeRawPUsumPt_) {
71 throw cms::Exception(
"BadIsoConfig") <<
"A 'store raw' and a 'apply cut' option have been set to true " 72 <<
"simultaneously. These options are mutually exclusive.";
77 if (includeGammas_ && calculateWeights_) {
79 <<
"Both 'ApplyDiscriminationByECALIsolation' and 'ApplyDiscriminationByWeightedECALIsolation' " 80 <<
"have been set to true. These options are mutually exclusive.";
84 int numStoreOptions = 0;
87 if (storeRawOccupancy_)
91 if (storeRawFootprintCorrection_)
93 if (storeRawPhotonSumPt_outsideSignalCone_)
95 if (numStoreOptions > 1) {
96 throw cms::Exception(
"BadIsoConfig") <<
"Multiple 'store sum pt' and/or 'store occupancy' options are set." 97 <<
" These options are mutually exclusive.";
100 customIsoCone_ =
pset.getParameter<
double>(
"customOuterCone");
102 applyPhotonPtSumOutsideSignalConeCut_ =
pset.getParameter<
bool>(
"applyPhotonPtSumOutsideSignalConeCut");
103 if (applyPhotonPtSumOutsideSignalConeCut_) {
104 maxAbsPhotonSumPt_outsideSignalCone_ =
pset.getParameter<
double>(
"maxAbsPhotonSumPt_outsideSignalCone");
105 maxRelPhotonSumPt_outsideSignalCone_ =
pset.getParameter<
double>(
"maxRelPhotonSumPt_outsideSignalCone");
108 applyFootprintCorrection_ =
pset.getParameter<
bool>(
"applyFootprintCorrection");
109 if (applyFootprintCorrection_ || storeRawFootprintCorrection_) {
111 for (edm::VParameterSet::const_iterator cfgFootprintCorrection = cfgFootprintCorrections.begin();
112 cfgFootprintCorrection != cfgFootprintCorrections.end();
113 ++cfgFootprintCorrection) {
117 footprintCorrections_.push_back(
std::move(footprintCorrection));
124 qcuts_ = std::make_unique<tau::RecoTauQualityCuts>(isolationQCuts);
126 vertexAssociator_ = std::make_unique<tau::RecoTauVertexAssociator>(qualityCutsPSet_, consumesCollector());
128 applyDeltaBeta_ =
pset.getParameter<
bool>(
"applyDeltaBetaCorrection");
130 if (applyDeltaBeta_ || calculateWeights_) {
133 std::pair<edm::ParameterSet, edm::ParameterSet> puFactorizedIsoQCuts =
145 puFactorizedIsoQCuts.second.addParameter<
double>(
"minTrackPt",
149 pileupQcutsPUTrackSelection_ = std::make_unique<tau::RecoTauQualityCuts>(puFactorizedIsoQCuts.first);
151 pileupQcutsGeneralQCuts_ = std::make_unique<tau::RecoTauQualityCuts>(puFactorizedIsoQCuts.second);
154 pfCand_token = consumes<edm::View<reco::Candidate> >(pfCandSrc_);
156 vertex_token = consumes<reco::VertexCollection>(vertexSrc_);
157 deltaBetaCollectionCone_ =
pset.getParameter<
double>(
"isoConeSizeForDeltaBeta");
158 std::string deltaBetaFactorFormula =
pset.getParameter<
string>(
"deltaBetaFactor");
159 deltaBetaFormula_ = std::make_unique<TFormula>(
"DB_corr", deltaBetaFactorFormula.c_str());
162 applyRhoCorrection_ =
pset.getParameter<
bool>(
"applyRhoCorrection");
163 if (applyRhoCorrection_) {
165 rho_token = consumes<double>(rhoProducer_);
166 rhoConeSize_ =
pset.getParameter<
double>(
"rhoConeSize");
167 rhoUEOffsetCorrection_ =
pset.getParameter<
double>(
"rhoUEOffsetCorrection");
169 useAllPFCands_ =
pset.getParameter<
bool>(
"UseAllPFCandsForWeights");
171 verbosity_ =
pset.getParameter<
int>(
"verbosity");
177 double discriminate(
const PFTauRef& pfTau)
const override;
179 inline double weightedSum(
const std::vector<CandidatePtr>& inColl_,
double eta,
double phi)
const {
181 for (
auto const& inObj_ : inColl_) {
182 double sum = (inObj_->pt() * inObj_->pt()) / (
deltaR2(
eta, phi, inObj_->eta(), inObj_->phi()));
195 std::unique_ptr<tau::RecoTauQualityCuts>
qcuts_;
276 vertexAssociator_->setEvent(
event);
280 if (applyDeltaBeta_ || calculateWeights_) {
284 chargedPFCandidatesInEvent_.clear();
285 chargedPFCandidatesInEvent_.reserve(
pfCandidates->size());
287 for (
size_t i = 0;
i < numPFCandidates; ++
i) {
289 if (pfCandidate->
charge() != 0) {
290 chargedPFCandidatesInEvent_.push_back(pfCandidate);
296 event.getByToken(vertex_token,
vertices);
297 size_t nVtxThisEvent =
vertices->size();
298 deltaBetaFactorThisEvent_ = deltaBetaFormula_->Eval(nVtxThisEvent);
301 if (applyRhoCorrection_) {
303 event.getByToken(rho_token, rhoHandle_);
304 rhoThisEvent_ = (*rhoHandle_ - rhoUEOffsetCorrection_) * (3.14159) * rhoConeSize_ * rhoConeSize_;
309 LogDebug(
"discriminate") <<
" tau: Pt = " << pfTau->pt() <<
", eta = " << pfTau->eta() <<
", phi = " << pfTau->phi();
313 std::vector<CandidatePtr> isoCharged_;
314 std::vector<CandidatePtr> isoNeutral_;
315 std::vector<CandidatePtr> isoPU_;
317 std::vector<CandidatePtr> chPV_;
318 isoCharged_.
reserve(pfTau->isolationChargedHadrCands().size());
319 isoNeutral_.reserve(pfTau->isolationGammaCands().size());
320 isoPU_.reserve(
std::min(100UL, chargedPFCandidatesInEvent_.size()));
321 isoNeutralWeight_.
reserve(pfTau->isolationGammaCands().size());
323 chPV_.reserve(
std::min(50UL, chargedPFCandidatesInEvent_.size()));
330 if (
pv.isNonnull()) {
331 LogTrace(
"discriminate") <<
"pv: x = " <<
pv->position().x() <<
", y = " <<
pv->position().y()
332 <<
", z = " <<
pv->position().z();
334 LogTrace(
"discriminate") <<
"pv: N/A";
336 if (pfTau->leadChargedHadrCand().
isNonnull()) {
337 LogTrace(
"discriminate") <<
"leadPFChargedHadron:" 338 <<
" Pt = " << pfTau->leadChargedHadrCand()->pt() <<
"," 339 <<
" eta = " << pfTau->leadChargedHadrCand()->eta() <<
"," 340 <<
" phi = " << pfTau->leadChargedHadrCand()->phi();
342 LogTrace(
"discriminate") <<
"leadPFChargedHadron: N/A";
347 if (!(
pv.isNonnull() && pfTau->leadChargedHadrCand().
isNonnull()))
351 qcuts_->setLeadTrack(*pfTau->leadChargedHadrCand());
353 if (applyDeltaBeta_ || calculateWeights_) {
354 pileupQcutsGeneralQCuts_->setPV(
pv);
355 pileupQcutsGeneralQCuts_->setLeadTrack(*pfTau->leadChargedHadrCand());
356 pileupQcutsPUTrackSelection_->setPV(
pv);
357 pileupQcutsPUTrackSelection_->setLeadTrack(*pfTau->leadChargedHadrCand());
361 if (includeTracks_) {
362 for (
auto const&
cand : pfTau->isolationChargedHadrCands()) {
363 if (qcuts_->filterCandRef(
cand)) {
364 LogTrace(
"discriminate") <<
"adding charged iso cand with pt " <<
cand->pt();
365 isoCharged_.push_back(
cand);
369 if (includeGammas_ || calculateWeights_) {
370 for (
auto const&
cand : pfTau->isolationGammaCands()) {
371 if (qcuts_->filterCandRef(
cand)) {
372 LogTrace(
"discriminate") <<
"adding neutral iso cand with pt " <<
cand->pt();
373 isoNeutral_.push_back(
cand);
382 if (applyDeltaBeta_ || calculateWeights_) {
385 std::cout <<
"Initial PFCands: " << chargedPFCandidatesInEvent_.size() << std::endl;
388 std::vector<CandidatePtr> allPU = pileupQcutsPUTrackSelection_->filterCandRefs(chargedPFCandidatesInEvent_,
true);
390 std::vector<CandidatePtr> allNPU = pileupQcutsPUTrackSelection_->filterCandRefs(chargedPFCandidatesInEvent_);
391 LogTrace(
"discriminate") <<
"After track cuts: " << allPU.size();
394 if (!useAllPFCands_) {
395 std::vector<CandidatePtr> cleanPU = pileupQcutsGeneralQCuts_->filterCandRefs(allPU);
397 std::vector<CandidatePtr> cleanNPU = pileupQcutsGeneralQCuts_->filterCandRefs(allNPU);
399 LogTrace(
"discriminate") <<
"After cleaning cuts: " << cleanPU.size();
402 DRFilter deltaBetaFilter(pfTau->p4(), 0, deltaBetaCollectionCone_);
403 for (
auto const&
cand : cleanPU) {
404 if (deltaBetaFilter(
cand))
405 isoPU_.push_back(
cand);
408 for (
auto const&
cand : cleanNPU) {
409 if (deltaBetaFilter(
cand))
410 chPV_.push_back(
cand);
412 LogTrace(
"discriminate") <<
"After cone cuts: " << isoPU_.size() <<
" " << chPV_.size();
419 if (calculateWeights_) {
420 for (
auto const& isoObject : isoNeutral_) {
421 if (isoObject->charge() != 0) {
427 double eta = isoObject->eta();
428 double phi = isoObject->phi();
429 double sumNPU = 0.5 *
log(weightedSum(chPV_,
eta, phi));
431 double sumPU = 0.5 *
log(weightedSum(isoPU_,
eta, phi));
433 if ((sumNPU + sumPU) > 0)
434 neutral.
setP4(((sumNPU) / (sumNPU + sumPU)) * neutral.
p4());
441 if (customIsoCone_ >= 0.) {
442 DRFilter
filter(pfTau->p4(), 0, customIsoCone_);
443 DRFilter2 filter2(pfTau->p4(), 0, customIsoCone_);
444 std::vector<CandidatePtr> isoCharged_filter;
445 std::vector<CandidatePtr> isoNeutral_filter;
448 for (
auto const& isoObject : isoCharged_) {
452 if (!calculateWeights_) {
453 for (
auto const& isoObject : isoNeutral_) {
455 isoNeutral_filter.push_back(isoObject);
457 isoNeutral_ = isoNeutral_filter;
459 for (
auto const& isoObject : isoNeutralWeight_) {
460 if (filter2(isoObject))
461 isoNeutralWeight_filter.
push_back(isoObject);
463 isoNeutralWeight_ = isoNeutralWeight_filter;
465 isoCharged_ = isoCharged_filter;
468 bool failsOccupancyCut =
false;
469 bool failsSumPtCut =
false;
470 bool failsRelativeSumPtCut =
false;
473 int neutrals = isoNeutral_.
size();
475 if (applyDeltaBeta_) {
476 neutrals -= TMath::Nint(deltaBetaFactorThisEvent_ * isoPU_.size());
482 size_t nOccupants = isoCharged_.size() + neutrals;
484 failsOccupancyCut = (nOccupants > maximumOccupancy_);
486 double footprintCorrection_value = 0.;
487 if (applyFootprintCorrection_ || storeRawFootprintCorrection_) {
488 for (
std::vector<std::unique_ptr<FootprintCorrection> >::const_iterator footprintCorrection =
489 footprintCorrections_.begin();
490 footprintCorrection != footprintCorrections_.end();
491 ++footprintCorrection) {
492 if ((*footprintCorrection)->selection_(*pfTau)) {
493 footprintCorrection_value = (*footprintCorrection)->offset_(*pfTau);
501 if (applySumPtCut_ || applyRelativeSumPtCut_ || storeRawSumPt_ || storeRawPUsumPt_) {
502 double chargedPt = 0.;
503 double neutralPt = 0.;
504 double weightedNeutralPt = 0.;
505 for (
auto const& isoObject : isoCharged_) {
509 if (enableHGCalWorkaround_) {
510 double trackPt = (isoObject->bestTrack()) ? isoObject->bestTrack()->pt() : 0.;
511 double pfCandPt = isoObject->pt();
514 neutralPt += pfCandPt -
trackPt;
516 chargedPt += isoObject->pt();
519 chargedPt += isoObject->pt();
523 if (!calculateWeights_) {
524 for (
auto const& isoObject : isoNeutral_) {
525 neutralPt += isoObject->pt();
528 for (
auto const& isoObject : isoNeutralWeight_) {
529 weightedNeutralPt += isoObject.pt();
532 for (
auto const& isoObject : isoPU_) {
533 puPt += isoObject->pt();
535 LogTrace(
"discriminate") <<
"chargedPt = " << chargedPt;
536 LogTrace(
"discriminate") <<
"neutralPt = " << neutralPt;
537 LogTrace(
"discriminate") <<
"weighted neutral Pt = " << weightedNeutralPt;
538 LogTrace(
"discriminate") <<
"puPt = " << puPt <<
" (delta-beta corr. = " << (deltaBetaFactorThisEvent_ * puPt)
541 if (calculateWeights_) {
542 neutralPt = weightedNeutralPt;
545 if (applyDeltaBeta_) {
546 neutralPt -= (deltaBetaFactorThisEvent_ * puPt);
549 if (applyFootprintCorrection_) {
550 neutralPt -= footprintCorrection_value;
553 if (applyRhoCorrection_) {
554 neutralPt -= rhoThisEvent_;
557 if (neutralPt < 0.) {
561 totalPt = chargedPt + weightGammas_ * neutralPt;
562 LogTrace(
"discriminate") <<
"totalPt = " << totalPt <<
" (cut = " << maximumSumPt_ <<
")";
564 failsSumPtCut = (totalPt > maximumSumPt_);
567 failsRelativeSumPtCut = (totalPt > ((pfTau->pt() - offsetRelativeSumPt_) * maximumRelativeSumPt_));
570 bool failsPhotonPtSumOutsideSignalConeCut =
false;
571 double photonSumPt_outsideSignalCone = 0.;
572 if (applyPhotonPtSumOutsideSignalConeCut_ || storeRawPhotonSumPt_outsideSignalCone_) {
573 const std::vector<reco::CandidatePtr>& signalGammas = pfTau->signalGammaCands();
574 for (std::vector<reco::CandidatePtr>::const_iterator signalGamma = signalGammas.begin();
575 signalGamma != signalGammas.end();
577 double dR =
deltaR(pfTau->eta(), pfTau->phi(), (*signalGamma)->eta(), (*signalGamma)->phi());
578 if (
dR > pfTau->signalConeSize())
579 photonSumPt_outsideSignalCone += (*signalGamma)->pt();
581 if (photonSumPt_outsideSignalCone > maxAbsPhotonSumPt_outsideSignalCone_ ||
582 photonSumPt_outsideSignalCone > (maxRelPhotonSumPt_outsideSignalCone_ * pfTau->pt())) {
583 failsPhotonPtSumOutsideSignalConeCut =
true;
587 bool fails = (applyOccupancyCut_ && failsOccupancyCut) || (applySumPtCut_ && failsSumPtCut) ||
588 (applyRelativeSumPtCut_ && failsRelativeSumPtCut) ||
589 (applyPhotonPtSumOutsideSignalConeCut_ && failsPhotonPtSumOutsideSignalConeCut);
591 if (pfTau->pt() > minPtForNoIso_ && minPtForNoIso_ > 0.) {
593 LogDebug(
"discriminate") <<
"tau pt = " << pfTau->pt() <<
"\t min cutoff pt = " << minPtForNoIso_;
597 if (storeRawSumPt_) {
599 }
else if (storeRawPUsumPt_) {
602 else if (applyRhoCorrection_)
603 return rhoThisEvent_;
606 }
else if (storeRawOccupancy_) {
608 }
else if (storeRawFootprintCorrection_) {
609 return footprintCorrection_value;
610 }
else if (storeRawPhotonSumPt_outsideSignalCone_) {
611 return photonSumPt_outsideSignalCone;
613 return (fails ? 0. : 1.);
620 desc.add<
bool>(
"storeRawFootprintCorrection",
false);
622 desc.add<
bool>(
"storeRawOccupancy",
false);
623 desc.add<
double>(
"maximumSumPtCut", 6.0);
629 desc.add<
double>(
"minTauPtForNoIso", -99.0);
630 desc.add<
double>(
"maxAbsPhotonSumPt_outsideSignalCone", 1000000000.0);
632 desc.add<
bool>(
"applySumPtCut",
false);
633 desc.add<
double>(
"rhoConeSize", 0.5);
634 desc.add<
bool>(
"ApplyDiscriminationByTrackerIsolation",
true);
635 desc.add<
bool>(
"storeRawPhotonSumPt_outsideSignalCone",
false);
637 desc.add<
bool>(
"enableHGCalWorkaround",
false);
643 desc.addVPSet(
"footprintCorrections", vpsd1, {});
647 desc.add<
bool>(
"applyFootprintCorrection",
false);
648 desc.add<
bool>(
"UseAllPFCandsForWeights",
false);
649 desc.add<
double>(
"relativeSumPtCut", 0.0);
655 psd1.
add<
double>(
"cut");
671 psd1.
add<
double>(
"cut");
684 psd1.
add<
double>(
"cut");
691 desc.add<
unsigned int>(
"maximumOccupancy", 0);
692 desc.add<
int>(
"verbosity", 0);
694 desc.add<
bool>(
"applyOccupancyCut",
true);
695 desc.add<
bool>(
"applyDeltaBetaCorrection",
false);
696 desc.add<
bool>(
"applyRelativeSumPtCut",
false);
697 desc.add<
bool>(
"storeRawPUsumPt",
false);
698 desc.add<
bool>(
"applyPhotonPtSumOutsideSignalConeCut",
false);
699 desc.add<
bool>(
"deltaBetaPUTrackPtCutOverride",
false);
700 desc.add<
bool>(
"ApplyDiscriminationByWeightedECALIsolation",
false);
701 desc.add<
bool>(
"storeRawSumPt",
false);
702 desc.add<
bool>(
"ApplyDiscriminationByECALIsolation",
true);
703 desc.add<
bool>(
"applyRhoCorrection",
false);
705 desc.add<
double>(
"WeightECALIsolation", 1.0);
706 desc.add<
double>(
"rhoUEOffsetCorrection", 1.0);
707 desc.add<
double>(
"maxRelPhotonSumPt_outsideSignalCone", 0.1);
708 desc.add<
double>(
"deltaBetaPUTrackPtCutOverride_val", -1.5);
709 desc.add<
double>(
"isoConeSizeForDeltaBeta", 0.5);
710 desc.add<
double>(
"relativeSumPtOffset", 0.0);
711 desc.add<
double>(
"customOuterCone", -1.0);
714 descriptions.
add(
"pfRecoTauDiscriminationByIsolation",
desc);
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
PFRecoTauDiscriminationByIsolation(const edm::ParameterSet &pset)
std::unique_ptr< tau::RecoTauQualityCuts > pileupQcutsGeneralQCuts_
T getParameter(std::string const &) const
bool enableHGCalWorkaround_
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
edm::EDGetTokenT< double > rho_token
static void fillDescriptions(edm::ParameterSetDescription &descriptions)
Declare all parameters read from python config file.
deltaBetaPUTrackPtCutOverride_val
bool applyPhotonPtSumOutsideSignalConeCut_
#define DEFINE_FWK_MODULE(type)
std::vector< ParameterSet > VParameterSet
edm::EDGetTokenT< edm::View< reco::Candidate > > pfCand_token
std::unique_ptr< TFormula > deltaBetaFormula_
ParameterSet const & getParameterSet(std::string const &) const
void beginEvent(const edm::Event &evt, const edm::EventSetup &evtSetup) override
bool isNonnull() const
Checks for non-null.
double rhoUEOffsetCorrection_
double maximumRelativeSumPt_
bool applyRelativeSumPtCut_
const LorentzVector & p4() const final
four-momentum Lorentz vector
~PFRecoTauDiscriminationByIsolation() override
double rhoCorrectionThisEvent_
double deltaBetaFactorThisEvent_
bool applyFootprintCorrection_
double offsetRelativeSumPt_
std::vector< std::unique_ptr< FootprintCorrection > > footprintCorrections_
deltaBetaPUTrackPtCutOverride
bool storeRawFootprintCorrection_
virtual int charge() const =0
electric charge
std::pair< edm::ParameterSet, edm::ParameterSet > factorizePUQCuts(const edm::ParameterSet &inputSet)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
double discriminate(const PFTauRef &pfTau) const override
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
double deltaBetaCollectionCone_
std::vector< reco::CandidatePtr > chargedPFCandidatesInEvent_
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
double weightedSum(const std::vector< CandidatePtr > &inColl_, double eta, double phi) const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
uint32_t maximumOccupancy_
double maxRelPhotonSumPt_outsideSignalCone_
edm::InputTag rhoProducer_
std::unique_ptr< tau::RecoTauQualityCuts > pileupQcutsPUTrackSelection_
double maxAbsPhotonSumPt_outsideSignalCone_
bool storeRawPhotonSumPt_outsideSignalCone_
edm::ParameterSet qualityCutsPSet_
void setP4(const LorentzVector &p4) final
set 4-momentum
std::unique_ptr< tau::RecoTauQualityCuts > qcuts_
std::unique_ptr< tau::RecoTauVertexAssociator > vertexAssociator_
edm::EDGetTokenT< reco::VertexCollection > vertex_token