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