File indexing completed on 2023-05-08 23:19:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <vector>
0012 #include <algorithm>
0013
0014 #include "RecoTauTag/RecoTau/interface/RecoTauBuilderPlugins.h"
0015 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
0016 #include "RecoTauTag/RecoTau/interface/RecoTauConstructor.h"
0017 #include "RecoTauTag/RecoTau/interface/RecoTauQualityCuts.h"
0018
0019 #include "RecoTauTag/RecoTau/interface/ConeTools.h"
0020 #include "RecoTauTag/RecoTau/interface/RecoTauCrossCleaning.h"
0021
0022 #include "DataFormats/TauReco/interface/PFTau.h"
0023 #include "DataFormats/TauReco/interface/PFRecoTauChargedHadron.h"
0024 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
0025 #include "DataFormats/VertexReco/interface/Vertex.h"
0026 #include "DataFormats/Math/interface/deltaR.h"
0027
0028 #include "CommonTools/Utils/interface/StringObjectFunction.h"
0029
0030 namespace reco {
0031 namespace tau {
0032
0033 typedef std::vector<RecoTauPiZero> PiZeroList;
0034
0035 class RecoTauBuilderConePlugin : public RecoTauBuilderPlugin {
0036 public:
0037 explicit RecoTauBuilderConePlugin(const edm::ParameterSet& pset, edm::ConsumesCollector&& iC);
0038 ~RecoTauBuilderConePlugin() override {}
0039
0040 return_type operator()(const reco::JetBaseRef& jet,
0041 const std::vector<reco::PFRecoTauChargedHadron>& chargedHadrons,
0042 const std::vector<RecoTauPiZero>& piZeros,
0043 const std::vector<CandidatePtr>& regionalExtras) const override;
0044
0045 private:
0046 std::unique_ptr<RecoTauQualityCuts> qcuts_;
0047
0048 bool usePFLeptonsAsChargedHadrons_;
0049
0050 double leadObjecPtThreshold_;
0051
0052
0053 typedef StringObjectFunction<reco::Jet> JetFunc;
0054
0055
0056 JetFunc matchingCone_;
0057 JetFunc signalConeChargedHadrons_;
0058 JetFunc isoConeChargedHadrons_;
0059 JetFunc signalConePiZeros_;
0060 StringObjectFunction<reco::PFTau> signalConeSizeToStore_;
0061 JetFunc isoConePiZeros_;
0062 JetFunc signalConeNeutralHadrons_;
0063 JetFunc isoConeNeutralHadrons_;
0064
0065 int maxSignalConeChargedHadrons_;
0066 double minAbsPhotonSumPt_insideSignalCone_;
0067 double minRelPhotonSumPt_insideSignalCone_;
0068
0069 void setTauQuantities(reco::PFTau& aTau,
0070 double minAbsPhotonSumPt_insideSignalCone = 2.5,
0071 double minRelPhotonSumPt_insideSignalCone = 0.,
0072 double minAbsPhotonSumPt_outsideSignalCone = 1.e+9,
0073 double minRelPhotonSumPt_outsideSignalCone = 1.e+9) const;
0074 };
0075
0076
0077 RecoTauBuilderConePlugin::RecoTauBuilderConePlugin(const edm::ParameterSet& pset, edm::ConsumesCollector&& iC)
0078 : RecoTauBuilderPlugin(pset, std::move(iC)),
0079 qcuts_(new RecoTauQualityCuts(pset.getParameterSet("qualityCuts").getParameterSet("signalQualityCuts"))),
0080 usePFLeptonsAsChargedHadrons_(pset.getParameter<bool>("usePFLeptons")),
0081 leadObjecPtThreshold_(pset.getParameter<double>("leadObjectPt")),
0082 matchingCone_(pset.getParameter<std::string>("matchingCone")),
0083 signalConeChargedHadrons_(pset.getParameter<std::string>("signalConeChargedHadrons")),
0084 isoConeChargedHadrons_(pset.getParameter<std::string>("isoConeChargedHadrons")),
0085 signalConePiZeros_(pset.getParameter<std::string>("signalConePiZeros")),
0086 signalConeSizeToStore_(
0087 pset.getParameter<std::string>("signalConePiZeros")),
0088 isoConePiZeros_(pset.getParameter<std::string>("isoConePiZeros")),
0089 signalConeNeutralHadrons_(pset.getParameter<std::string>("signalConeNeutralHadrons")),
0090 isoConeNeutralHadrons_(pset.getParameter<std::string>("isoConeNeutralHadrons")),
0091 maxSignalConeChargedHadrons_(pset.getParameter<int>("maxSignalConeChargedHadrons")),
0092 minAbsPhotonSumPt_insideSignalCone_(pset.getParameter<double>("minAbsPhotonSumPt_insideSignalCone")),
0093 minRelPhotonSumPt_insideSignalCone_(pset.getParameter<double>("minRelPhotonSumPt_insideSignalCone"))
0094
0095 {}
0096
0097 namespace xclean {
0098
0099 template <>
0100 inline void CrossCleanPiZeros<cone::CandPtrDRFilterIter>::initialize(
0101 const cone::CandPtrDRFilterIter& signalTracksBegin, const cone::CandPtrDRFilterIter& signalTracksEnd) {
0102
0103 for (cone::CandPtrDRFilterIter signalTrack = signalTracksBegin; signalTrack != signalTracksEnd; ++signalTrack) {
0104 toRemove_.insert(reco::CandidatePtr(*signalTrack));
0105 }
0106 }
0107
0108 template <>
0109 inline void CrossCleanPtrs<PiZeroList::const_iterator>::initialize(const PiZeroList::const_iterator& piZerosBegin,
0110 const PiZeroList::const_iterator& piZerosEnd) {
0111 for (auto const& ptr : flattenPiZeros(piZerosBegin, piZerosEnd)) {
0112 toRemove_.insert(CandidatePtr(ptr));
0113 }
0114 }
0115 }
0116
0117 void RecoTauBuilderConePlugin::setTauQuantities(reco::PFTau& aTau,
0118 double minAbsPhotonSumPt_insideSignalCone,
0119 double minRelPhotonSumPt_insideSignalCone,
0120 double minAbsPhotonSumPt_outsideSignalCone,
0121 double minRelPhotonSumPt_outsideSignalCone) const {
0122
0123
0124
0125
0126 int charge = 0;
0127 int leadCharge = aTau.leadChargedHadrCand().isNonnull() ? aTau.leadChargedHadrCand()->charge() : 0;
0128 const std::vector<reco::CandidatePtr>& pfChs = aTau.signalChargedHadrCands();
0129 for (const reco::CandidatePtr& pfCh : pfChs) {
0130 charge += pfCh->charge();
0131 }
0132 charge = charge == 0 ? leadCharge : charge;
0133 aTau.setCharge(charge);
0134
0135
0136 aTau.setPdgId(aTau.charge() < 0 ? 15 : -15);
0137
0138
0139 PFTau::hadronicDecayMode dm = PFTau::kNull;
0140 unsigned int nPiZeros = 0;
0141 const std::vector<RecoTauPiZero>& piZeros = aTau.signalPiZeroCandidates();
0142 for (const RecoTauPiZero& piZero : piZeros) {
0143 double photonSumPt_insideSignalCone = 0.;
0144 double photonSumPt_outsideSignalCone = 0.;
0145 int numPhotons = piZero.numberOfDaughters();
0146 for (int idxPhoton = 0; idxPhoton < numPhotons; ++idxPhoton) {
0147 const reco::Candidate* photon = piZero.daughter(idxPhoton);
0148 double dR = deltaR(photon->p4(), aTau.p4());
0149 if (dR < aTau.signalConeSize()) {
0150 photonSumPt_insideSignalCone += photon->pt();
0151 } else {
0152 photonSumPt_outsideSignalCone += photon->pt();
0153 }
0154 }
0155 if (photonSumPt_insideSignalCone > minAbsPhotonSumPt_insideSignalCone ||
0156 photonSumPt_insideSignalCone > (minRelPhotonSumPt_insideSignalCone * aTau.pt()) ||
0157 photonSumPt_outsideSignalCone > minAbsPhotonSumPt_outsideSignalCone ||
0158 photonSumPt_outsideSignalCone > (minRelPhotonSumPt_outsideSignalCone * aTau.pt()))
0159 ++nPiZeros;
0160 }
0161
0162 const unsigned int maxPiZeros = PFTau::kOneProngNPiZero;
0163
0164 unsigned int nCharged = pfChs.size();
0165 if (nCharged > 0) {
0166 unsigned int trackIndex = (nCharged - 1) * (maxPiZeros + 1);
0167
0168 if (trackIndex >= PFTau::kRareDecayMode)
0169 dm = PFTau::kRareDecayMode;
0170 else
0171 dm = static_cast<PFTau::hadronicDecayMode>(trackIndex + std::min(nPiZeros, maxPiZeros));
0172 } else {
0173 dm = PFTau::kNull;
0174 }
0175 aTau.setDecayMode(dm);
0176 return;
0177 }
0178
0179 RecoTauBuilderConePlugin::return_type RecoTauBuilderConePlugin::operator()(
0180 const reco::JetBaseRef& jet,
0181 const std::vector<reco::PFRecoTauChargedHadron>& chargedHadrons,
0182 const std::vector<RecoTauPiZero>& piZeros,
0183 const std::vector<CandidatePtr>& regionalExtras) const {
0184
0185
0186
0187
0188 using namespace cone;
0189
0190 output_type output;
0191
0192
0193
0194 RecoTauConstructor tau(jet,
0195 getPFCands(),
0196 true,
0197 &signalConeSizeToStore_,
0198 minAbsPhotonSumPt_insideSignalCone_,
0199 minRelPhotonSumPt_insideSignalCone_);
0200
0201 qcuts_->setPV(primaryVertex(jet));
0202
0203 typedef std::vector<CandidatePtr> CandPtrs;
0204
0205
0206 CandPtrs pfchs;
0207 if (!usePFLeptonsAsChargedHadrons_) {
0208 pfchs = qcuts_->filterCandRefs(pfCandidatesByPdgId(*jet, 211));
0209 } else {
0210
0211
0212
0213 pfchs = qcuts_->filterCandRefs(pfChargedCands(*jet));
0214 }
0215
0216
0217 std::sort(pfchs.begin(), pfchs.end(), SortPFCandsDescendingPt());
0218
0219
0220 CandPtrs pfGammas = qcuts_->filterCandRefs(pfCandidatesByPdgId(*jet, 22));
0221
0222 CandPtrs pfnhs = qcuts_->filterCandRefs(pfCandidatesByPdgId(*jet, 130));
0223
0224
0225 CandPtrs regionalJunk = qcuts_->filterCandRefs(regionalExtras);
0226
0227
0228
0229
0230
0231
0232 double matchingCone = matchingCone_(*jet);
0233 CandPtrDRFilter matchingConeFilter(jet->p4(), 0, matchingCone);
0234
0235
0236
0237
0238 CandidatePtr leadPFCH;
0239 CandPtrs::iterator leadPFCH_iter = std::find_if(pfchs.begin(), pfchs.end(), matchingConeFilter);
0240
0241 if (leadPFCH_iter != pfchs.end()) {
0242 leadPFCH = *leadPFCH_iter;
0243
0244 tau.setleadChargedHadrCand(leadPFCH);
0245 } else {
0246
0247
0248 return output;
0249 }
0250
0251
0252 CandidatePtr leadPFGamma;
0253 CandPtrs::iterator leadPFGamma_iter = std::find_if(pfGammas.begin(), pfGammas.end(), matchingConeFilter);
0254
0255 if (leadPFGamma_iter != pfGammas.end()) {
0256 leadPFGamma = *leadPFGamma_iter;
0257
0258 tau.setleadNeutralCand(leadPFGamma);
0259 }
0260
0261 CandidatePtr leadPFCand;
0262
0263 if (leadPFCH.isNonnull() && leadPFCH->pt() > leadObjecPtThreshold_) {
0264 leadPFCand = leadPFCH;
0265 } else if (leadPFGamma.isNonnull() && leadPFGamma->pt() > leadObjecPtThreshold_) {
0266
0267 leadPFCand = leadPFGamma;
0268 } else {
0269
0270 leadPFCand = leadPFCH;
0271 }
0272
0273 tau.setleadCand(leadPFCand);
0274
0275
0276 reco::Candidate::LorentzVector coneAxis = leadPFCH->p4();
0277
0278
0279
0280
0281
0282
0283
0284
0285 CandPtrDRFilter signalConePFCHFilter(coneAxis, -0.1, signalConeChargedHadrons_(*jet));
0286 CandPtrDRFilter signalConePFNHFilter(coneAxis, -0.1, signalConeNeutralHadrons_(*jet));
0287 PiZeroDRFilter signalConePiZeroFilter(coneAxis, -0.1, signalConePiZeros_(*jet));
0288
0289 CandPtrDRFilter isoConePFCHFilter(coneAxis, signalConeChargedHadrons_(*jet), isoConeChargedHadrons_(*jet));
0290 CandPtrDRFilter isoConePFGammaFilter(coneAxis, signalConePiZeros_(*jet), isoConePiZeros_(*jet));
0291 CandPtrDRFilter isoConePFNHFilter(coneAxis, signalConeNeutralHadrons_(*jet), isoConeNeutralHadrons_(*jet));
0292 PiZeroDRFilter isoConePiZeroFilter(coneAxis, signalConePiZeros_(*jet), isoConePiZeros_(*jet));
0293
0294
0295
0296 typedef xclean::PredicateAND<xclean::FilterCandByAbsPdgId, CandPtrDRFilter> RegionalJunkConeAndIdFilter;
0297
0298 xclean::FilterCandByAbsPdgId pfchCandSelector(211);
0299 xclean::FilterCandByAbsPdgId pfgammaCandSelector(22);
0300 xclean::FilterCandByAbsPdgId pfnhCandSelector(130);
0301
0302
0303 RegionalJunkConeAndIdFilter pfChargedJunk(pfchCandSelector,
0304 isoConePFCHFilter
0305 );
0306
0307 RegionalJunkConeAndIdFilter pfGammaJunk(pfgammaCandSelector,
0308 isoConePFGammaFilter
0309 );
0310
0311 RegionalJunkConeAndIdFilter pfNeutralJunk(pfnhCandSelector,
0312 isoConePFNHFilter
0313 );
0314
0315
0316 CandPtrDRFilterIter signalPFCHCands_begin(signalConePFCHFilter, pfchs.begin(), pfchs.end());
0317 CandPtrDRFilterIter signalPFCHCands_end(signalConePFCHFilter, pfchs.end(), pfchs.end());
0318 CandPtrs signalPFCHs;
0319 int numSignalPFCHs = 0;
0320 CandPtrs isolationPFCHs;
0321 for (CandPtrDRFilterIter iter = signalPFCHCands_begin; iter != signalPFCHCands_end; ++iter) {
0322 if (numSignalPFCHs < maxSignalConeChargedHadrons_ || maxSignalConeChargedHadrons_ == -1) {
0323
0324 signalPFCHs.push_back(*iter);
0325 ++numSignalPFCHs;
0326 } else {
0327
0328 isolationPFCHs.push_back(*iter);
0329 }
0330 }
0331 CandPtrs::const_iterator signalPFCHs_begin = signalPFCHs.begin();
0332 CandPtrs::const_iterator signalPFCHs_end = signalPFCHs.end();
0333
0334
0335 xclean::CrossCleanPiZeros<CandPtrDRFilterIter> piZeroXCleaner(signalPFCHCands_begin, signalPFCHCands_end);
0336 std::vector<reco::RecoTauPiZero> cleanPiZeros = piZeroXCleaner(piZeros);
0337
0338
0339
0340 xclean::CrossCleanPtrs<PiZeroList::const_iterator> pfCandXCleaner(cleanPiZeros.begin(), cleanPiZeros.end());
0341
0342 auto isolationPFCHCands_begin(boost::make_filter_iterator(
0343 xclean::makePredicateAND(isoConePFCHFilter, pfCandXCleaner), pfchs.begin(), pfchs.end()));
0344 auto isolationPFCHCands_end(boost::make_filter_iterator(
0345 xclean::makePredicateAND(isoConePFCHFilter, pfCandXCleaner), pfchs.end(), pfchs.end()));
0346 for (auto iter = isolationPFCHCands_begin; iter != isolationPFCHCands_end; ++iter) {
0347 isolationPFCHs.push_back(*iter);
0348 }
0349 CandPtrs::const_iterator isolationPFCHs_begin = isolationPFCHs.begin();
0350 CandPtrs::const_iterator isolationPFCHs_end = isolationPFCHs.end();
0351
0352
0353 tau.addPFCands(
0354 RecoTauConstructor::kSignal, RecoTauConstructor::kChargedHadron, signalPFCHs_begin, signalPFCHs_end);
0355
0356 tau.addPFCands(RecoTauConstructor::kSignal,
0357 RecoTauConstructor::kNeutralHadron,
0358 boost::make_filter_iterator(
0359 xclean::makePredicateAND(signalConePFNHFilter, pfCandXCleaner), pfnhs.begin(), pfnhs.end()),
0360 boost::make_filter_iterator(
0361 xclean::makePredicateAND(signalConePFNHFilter, pfCandXCleaner), pfnhs.end(), pfnhs.end()));
0362
0363
0364 tau.addPiZeros(RecoTauConstructor::kSignal,
0365 PiZeroDRFilterIter(signalConePiZeroFilter, cleanPiZeros.begin(), cleanPiZeros.end()),
0366 PiZeroDRFilterIter(signalConePiZeroFilter, cleanPiZeros.end(), cleanPiZeros.end()));
0367
0368
0369 tau.addPFCands(
0370 RecoTauConstructor::kIsolation, RecoTauConstructor::kChargedHadron, isolationPFCHs_begin, isolationPFCHs_end);
0371
0372
0373 tau.addPFCands(RecoTauConstructor::kIsolation,
0374 RecoTauConstructor::kChargedHadron,
0375 boost::make_filter_iterator(pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
0376 boost::make_filter_iterator(pfChargedJunk, regionalJunk.end(), regionalJunk.end()));
0377
0378
0379 tau.addPFCands(RecoTauConstructor::kIsolation,
0380 RecoTauConstructor::kNeutralHadron,
0381 boost::make_filter_iterator(
0382 xclean::makePredicateAND(isoConePFNHFilter, pfCandXCleaner), pfnhs.begin(), pfnhs.end()),
0383 boost::make_filter_iterator(
0384 xclean::makePredicateAND(isoConePFNHFilter, pfCandXCleaner), pfnhs.end(), pfnhs.end()));
0385
0386
0387 tau.addPFCands(RecoTauConstructor::kIsolation,
0388 RecoTauConstructor::kNeutralHadron,
0389 boost::make_filter_iterator(pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
0390 boost::make_filter_iterator(pfNeutralJunk, regionalJunk.end(), regionalJunk.end()));
0391
0392
0393 tau.addPiZeros(RecoTauConstructor::kIsolation,
0394 PiZeroDRFilterIter(isoConePiZeroFilter, cleanPiZeros.begin(), cleanPiZeros.end()),
0395 PiZeroDRFilterIter(isoConePiZeroFilter, cleanPiZeros.end(), cleanPiZeros.end()));
0396
0397
0398 tau.addPFCands(RecoTauConstructor::kIsolation,
0399 RecoTauConstructor::kGamma,
0400 boost::make_filter_iterator(pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
0401 boost::make_filter_iterator(pfGammaJunk, regionalJunk.end(), regionalJunk.end()));
0402
0403
0404
0405
0406 std::unique_ptr<reco::PFTau> tauPtr = tau.get(false);
0407
0408
0409 reco::VertexRef primaryVertexRef = primaryVertex(*tauPtr);
0410 if (primaryVertexRef.isNonnull())
0411 tauPtr->setVertex(primaryVertexRef->position());
0412
0413
0414 setTauQuantities(*tauPtr, minAbsPhotonSumPt_insideSignalCone_, minRelPhotonSumPt_insideSignalCone_);
0415
0416 output.push_back(std::move(tauPtr));
0417 return output;
0418 }
0419 }
0420 }
0421
0422 #include "FWCore/Framework/interface/MakerMacros.h"
0423 DEFINE_EDM_PLUGIN(RecoTauBuilderPluginFactory, reco::tau::RecoTauBuilderConePlugin, "RecoTauBuilderConePlugin");