Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:06

0001 /**\class TopProjector
0002 \brief
0003 
0004 \author Colin Bernet
0005 \date   february 2008
0006 */
0007 
0008 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0009 #include "DataFormats/Candidate/interface/OverlapChecker.h"
0010 #include "DataFormats/JetReco/interface/PFJet.h"
0011 #include "DataFormats/JetReco/interface/PFJetCollection.h"
0012 #include "DataFormats/Math/interface/deltaR.h"
0013 #include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidate.h"
0014 #include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidateFwd.h"
0015 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0016 #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidate.h"
0017 #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidateFwd.h"
0018 #include "DataFormats/Provenance/interface/ProductID.h"
0019 #include "DataFormats/TauReco/interface/PFTau.h"
0020 #include "DataFormats/TauReco/interface/PFTauFwd.h"
0021 #include "DataFormats/TrackReco/interface/Track.h"
0022 #include "FWCore/Framework/interface/ESHandle.h"
0023 #include "FWCore/Framework/interface/Event.h"
0024 #include "FWCore/Framework/interface/EventSetup.h"
0025 #include "FWCore/Framework/interface/stream/EDProducer.h"
0026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0027 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0030 #include "FWCore/Utilities/interface/Exception.h"
0031 
0032 #include <iostream>
0033 #include <memory>
0034 #include <string>
0035 
0036 /// This checks a slew of possible overlaps for FwdPtr<Candidate> and derivatives.
0037 template <class Top, class Bottom>
0038 class TopProjectorFwdPtrOverlap {
0039 public:
0040   typedef edm::FwdPtr<Top> TopFwdPtr;
0041   typedef edm::FwdPtr<Bottom> BottomFwdPtr;
0042 
0043   explicit TopProjectorFwdPtrOverlap() { bottom_ = 0; }
0044 
0045   explicit TopProjectorFwdPtrOverlap(edm::ParameterSet const& iConfig)
0046       : bottom_(nullptr), matchByPtrDirect_(iConfig.getParameter<bool>("matchByPtrDirect")) {}
0047 
0048   inline void setBottom(BottomFwdPtr const& bottom) { bottom_ = &bottom; }
0049 
0050   bool operator()(TopFwdPtr const& top) const {
0051     if (std::is_same<Top, Bottom>::value && matchByPtrDirect_)
0052       return top.ptr().refCore() == bottom_->ptr().refCore() && top.ptr().key() == bottom_->ptr().key();
0053     bool topFwdGood = top.ptr().isNonnull() && top.ptr().isAvailable();
0054     bool topBckGood = top.backPtr().isNonnull() && top.backPtr().isAvailable();
0055     bool bottomFwdGood = bottom_->ptr().isNonnull() && bottom_->ptr().isAvailable();
0056     bool bottomBckGood = bottom_->backPtr().isNonnull() && bottom_->backPtr().isAvailable();
0057 
0058     bool matched = (topFwdGood && bottomFwdGood && top.ptr().refCore() == bottom_->ptr().refCore() &&
0059                     top.ptr().key() == bottom_->ptr().key()) ||
0060                    (topFwdGood && bottomBckGood && top.ptr().refCore() == bottom_->backPtr().refCore() &&
0061                     top.ptr().key() == bottom_->backPtr().key()) ||
0062                    (topBckGood && bottomFwdGood && top.backPtr().refCore() == bottom_->ptr().refCore() &&
0063                     top.backPtr().key() == bottom_->ptr().key()) ||
0064                    (topBckGood && bottomBckGood && top.backPtr().refCore() == bottom_->backPtr().refCore() &&
0065                     top.backPtr().key() == bottom_->backPtr().key());
0066     if (!matched) {
0067       for (unsigned isource = 0; isource < top->numberOfSourceCandidatePtrs(); ++isource) {
0068         reco::CandidatePtr const& topSrcPtr = top->sourceCandidatePtr(isource);
0069         bool topSrcGood = topSrcPtr.isNonnull() && topSrcPtr.isAvailable();
0070         if ((topSrcGood && bottomFwdGood && topSrcPtr.refCore() == bottom_->ptr().refCore() &&
0071              topSrcPtr.key() == bottom_->ptr().key()) ||
0072             (topSrcGood && bottomBckGood && topSrcPtr.refCore() == bottom_->backPtr().refCore() &&
0073              topSrcPtr.key() == bottom_->backPtr().key())) {
0074           matched = true;
0075           break;
0076         }
0077       }
0078     }
0079     if (!matched) {
0080       for (unsigned isource = 0; isource < (*bottom_)->numberOfSourceCandidatePtrs(); ++isource) {
0081         reco::CandidatePtr const& bottomSrcPtr = (*bottom_)->sourceCandidatePtr(isource);
0082         bool bottomSrcGood = bottomSrcPtr.isNonnull() && bottomSrcPtr.isAvailable();
0083         if ((topFwdGood && bottomSrcGood && bottomSrcPtr.refCore() == top.ptr().refCore() &&
0084              bottomSrcPtr.key() == top.ptr().key()) ||
0085             (topBckGood && bottomSrcGood && bottomSrcPtr.refCore() == top.backPtr().refCore() &&
0086              bottomSrcPtr.key() == top.backPtr().key())) {
0087           matched = true;
0088           break;
0089         }
0090       }
0091     }
0092 
0093     return matched;
0094   }
0095 
0096 protected:
0097   BottomFwdPtr const* bottom_;
0098   const bool matchByPtrDirect_ = false;
0099 };
0100 
0101 /// This checks matching based on delta R
0102 template <class Top, class Bottom>
0103 class TopProjectorDeltaROverlap {
0104 public:
0105   typedef edm::FwdPtr<Top> TopFwdPtr;
0106   typedef edm::FwdPtr<Bottom> BottomFwdPtr;
0107 
0108   explicit TopProjectorDeltaROverlap() { bottom_ = 0; }
0109   explicit TopProjectorDeltaROverlap(edm::ParameterSet const& config)
0110       : deltaR2_(config.getParameter<double>("deltaR")),
0111         bottom_(nullptr),
0112         bottomCPtr_(nullptr),
0113         botEta_(-999.f),
0114         botPhi_(0.f) {
0115     deltaR2_ *= deltaR2_;
0116   }
0117 
0118   inline void setBottom(BottomFwdPtr const& bottom) {
0119     bottom_ = &bottom;
0120     bottomCPtr_ = &**bottom_;
0121     botEta_ = bottomCPtr_->eta();
0122     botPhi_ = bottomCPtr_->phi();
0123   }
0124 
0125   bool operator()(TopFwdPtr const& top) const {
0126     const Top& oTop = *top;
0127     float topEta = oTop.eta();
0128     float topPhi = oTop.phi();
0129     bool matched = reco::deltaR2(topEta, topPhi, botEta_, botPhi_) < deltaR2_;
0130     return matched;
0131   }
0132 
0133 protected:
0134   double deltaR2_;
0135   BottomFwdPtr const* bottom_;
0136   const Bottom* bottomCPtr_;
0137   float botEta_, botPhi_;
0138 };
0139 
0140 template <class Top, class Bottom, class Matcher = TopProjectorFwdPtrOverlap<Top, Bottom>>
0141 class TopProjector : public edm::stream::EDProducer<> {
0142 public:
0143   typedef std::vector<Top> TopCollection;
0144   typedef edm::FwdPtr<Top> TopFwdPtr;
0145   typedef std::vector<TopFwdPtr> TopFwdPtrCollection;
0146 
0147   typedef std::vector<Bottom> BottomCollection;
0148   typedef edm::FwdPtr<Bottom> BottomFwdPtr;
0149   typedef std::vector<BottomFwdPtr> BottomFwdPtrCollection;
0150 
0151   TopProjector(const edm::ParameterSet&);
0152 
0153   ~TopProjector() override = default;
0154 
0155   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0156 
0157   void produce(edm::Event&, const edm::EventSetup&) override;
0158 
0159 private:
0160   /// Matching method.
0161   Matcher match_;
0162 
0163   /// enable? if not, all candidates in the bottom collection are copied to the output collection
0164   const bool enable_;
0165 
0166   /// name of the top projection
0167   const std::string name_;
0168 
0169   /// input tag for the top (masking) collection
0170   const edm::EDGetTokenT<TopFwdPtrCollection> tokenTop_;
0171 
0172   /// input tag for the masked collection.
0173   const edm::EDGetTokenT<BottomFwdPtrCollection> tokenBottom_;
0174 };
0175 
0176 template <class Top, class Bottom, class Matcher>
0177 TopProjector<Top, Bottom, Matcher>::TopProjector(const edm::ParameterSet& iConfig)
0178     : match_(iConfig),
0179       enable_(iConfig.getParameter<bool>("enable")),
0180       name_(iConfig.getUntrackedParameter<std::string>("name", "No Name")),
0181       tokenTop_(consumes<TopFwdPtrCollection>(iConfig.getParameter<edm::InputTag>("topCollection"))),
0182       tokenBottom_(consumes<BottomFwdPtrCollection>(iConfig.getParameter<edm::InputTag>("bottomCollection"))) {
0183   // will produce a collection of the unmasked candidates in the
0184   // bottom collection
0185   produces<BottomFwdPtrCollection>();
0186 }
0187 
0188 template <class Top, class Bottom, class Matcher>
0189 void TopProjector<Top, Bottom, Matcher>::fillDescriptions(edm::ConfigurationDescriptions& desc) {
0190   edm::ParameterSetDescription psD;
0191   psD.add<bool>("enable");
0192   if (std::is_same<Matcher, TopProjectorDeltaROverlap<Top, Bottom>>::value)
0193     psD.add<double>("deltaR");
0194   psD.addUntracked<std::string>("name", "No Name");
0195   psD.add<edm::InputTag>("topCollection");
0196   psD.add<edm::InputTag>("bottomCollection");
0197   if (std::is_same<Matcher, TopProjectorFwdPtrOverlap<Top, Bottom>>::value)
0198     psD.add<bool>("matchByPtrDirect", false)->setComment("fast check by ptr() only");
0199   desc.addWithDefaultLabel(psD);
0200 }
0201 
0202 template <class Top, class Bottom, class Matcher>
0203 void TopProjector<Top, Bottom, Matcher>::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0204   // get the various collections
0205 
0206   // Access the masking collection
0207   auto const& tops = iEvent.get(tokenTop_);
0208   std::list<TopFwdPtr> topsList;
0209 
0210   for (auto const& top : tops) {
0211     topsList.push_back(top);
0212   }
0213 
0214   // Access the collection to
0215   // be masked by the other ones
0216   auto const& bottoms = iEvent.get(tokenBottom_);
0217 
0218   // output collection of FwdPtrs to objects,
0219   // selected from the Bottom collection
0220   std::unique_ptr<BottomFwdPtrCollection> pBottomFwdPtrOutput(new BottomFwdPtrCollection);
0221 
0222   LogDebug("TopProjection") << " Remaining candidates in the bottom collection ------ ";
0223 
0224   int iB = -1;
0225   for (auto const& bottom : bottoms) {
0226     iB++;
0227     match_.setBottom(bottom);
0228     auto found = topsList.end();
0229     if (enable_) {
0230       found = std::find_if(topsList.begin(), topsList.end(), match_);
0231     }
0232 
0233     // If this is masked in the top projection, we remove it.
0234     if (found != topsList.end()) {
0235       LogDebug("TopProjection") << "X " << iB << *bottom;
0236       topsList.erase(found);
0237       continue;
0238     }
0239     // otherwise, we keep it.
0240     else {
0241       LogDebug("TopProjection") << "O " << iB << *bottom;
0242       pBottomFwdPtrOutput->push_back(bottom);
0243     }
0244   }
0245 
0246   iEvent.put(std::move(pBottomFwdPtrOutput));
0247 }
0248 
0249 using namespace std;
0250 using namespace edm;
0251 using namespace reco;
0252 
0253 typedef TopProjector<PFJet, PFCandidate> TPPFJetsOnPFCandidates;
0254 typedef TopProjector<PFCandidate, PFCandidate> TPPFCandidatesOnPFCandidates;
0255 typedef TopProjector<PileUpPFCandidate, PFCandidate> TPPileUpPFCandidatesOnPFCandidates;
0256 typedef TopProjector<IsolatedPFCandidate, PFCandidate> TPIsolatedPFCandidatesOnPFCandidates;
0257 
0258 typedef TopProjector<PFCandidate, PileUpPFCandidate> TPPFCandidatesOnPileUpPFCandidates;
0259 typedef TopProjector<PFTau, PFJet> TPPFTausOnPFJets;
0260 typedef TopProjector<PFTau, PFJet, TopProjectorDeltaROverlap<PFTau, PFJet>> TPPFTausOnPFJetsDeltaR;
0261 
0262 #include "FWCore/Framework/interface/MakerMacros.h"
0263 DEFINE_FWK_MODULE(TPPFJetsOnPFCandidates);
0264 DEFINE_FWK_MODULE(TPPFCandidatesOnPFCandidates);
0265 DEFINE_FWK_MODULE(TPPileUpPFCandidatesOnPFCandidates);
0266 DEFINE_FWK_MODULE(TPIsolatedPFCandidatesOnPFCandidates);
0267 DEFINE_FWK_MODULE(TPPFCandidatesOnPileUpPFCandidates);
0268 DEFINE_FWK_MODULE(TPPFTausOnPFJets);
0269 DEFINE_FWK_MODULE(TPPFTausOnPFJetsDeltaR);