Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-18 03:27:25

0001 // -*- C++ -*-
0002 //
0003 // Package:    PhysicsTools/NanoAOD
0004 // Class:      PATObjectCrossLinker
0005 //
0006 /**\class PATObjectCrossLinker PATObjectCrossLinker.cc PhysicsTools/PATObjectCrossLinker/plugins/PATObjectCrossLinker.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Andrea Rizzi
0015 //         Created:  Mon, 28 Aug 2017 09:26:39 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 
0022 // user include files
0023 #include "FWCore/Framework/interface/Frameworkfwd.h"
0024 #include "FWCore/Framework/interface/stream/EDProducer.h"
0025 
0026 #include "FWCore/Framework/interface/Event.h"
0027 #include "FWCore/Framework/interface/MakerMacros.h"
0028 
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030 #include "FWCore/Utilities/interface/StreamID.h"
0031 
0032 #include "DataFormats/PatCandidates/interface/Muon.h"
0033 #include "DataFormats/PatCandidates/interface/Jet.h"
0034 #include "DataFormats/PatCandidates/interface/Electron.h"
0035 #include "DataFormats/PatCandidates/interface/Photon.h"
0036 #include "DataFormats/PatCandidates/interface/Tau.h"
0037 
0038 #include "DataFormats/Common/interface/View.h"
0039 
0040 #include "PhysicsTools/NanoAOD/interface/MatchingUtils.h"
0041 //
0042 // class declaration
0043 //
0044 
0045 class PATObjectCrossLinker : public edm::stream::EDProducer<> {
0046 public:
0047   explicit PATObjectCrossLinker(const edm::ParameterSet&);
0048   ~PATObjectCrossLinker() override;
0049 
0050   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0051 
0052 private:
0053   void beginStream(edm::StreamID) override;
0054   void produce(edm::Event&, const edm::EventSetup&) override;
0055   void endStream() override;
0056 
0057   template <class C1, class C2, class C3, class C4>
0058   void matchOneToMany(const C1& refProdOne,
0059                       C2& itemsOne,
0060                       const std::string& nameOne,
0061                       const C3& refProdMany,
0062                       C4& itemsMany,
0063                       const std::string& nameMany);
0064 
0065   template <class C1, class C2, class C3, class C4>
0066   void matchElectronToPhoton(const C1& refProdOne,
0067                              C2& itemsOne,
0068                              const std::string& nameOne,
0069                              const C3& refProdMany,
0070                              C4& itemsMany,
0071                              const std::string& nameMany);
0072 
0073   template <class C1, class C2, class C3, class C4>
0074   void matchLowPtToElectron(const C1& refProdOne,
0075                             C2& itemsOne,
0076                             const std::string& nameOne,
0077                             const C3& refProdMany,
0078                             C4& itemsMany,
0079                             const std::string& nameMany);
0080 
0081   //virtual void beginRun(edm::Run const&, edm::EventSetup const&) override;
0082   //virtual void endRun(edm::Run const&, edm::EventSetup const&) override;
0083   //virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0084   //virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0085 
0086   // ----------member data ---------------------------
0087   const edm::EDGetTokenT<edm::View<pat::Jet>> jets_;
0088   const edm::EDGetTokenT<edm::View<pat::Muon>> muons_;
0089   const edm::EDGetTokenT<edm::View<pat::Electron>> electrons_;
0090   edm::InputTag lowPtElectronsTag_;
0091   edm::EDGetTokenT<edm::View<pat::Electron>> lowPtElectrons_;
0092   const edm::EDGetTokenT<edm::View<pat::Tau>> taus_;
0093   const edm::EDGetTokenT<edm::View<pat::Photon>> photons_;
0094 };
0095 
0096 //
0097 // constructors and destructor
0098 //
0099 PATObjectCrossLinker::PATObjectCrossLinker(const edm::ParameterSet& params)
0100     : jets_(consumes<edm::View<pat::Jet>>(params.getParameter<edm::InputTag>("jets"))),
0101       muons_(consumes<edm::View<pat::Muon>>(params.getParameter<edm::InputTag>("muons"))),
0102       electrons_(consumes<edm::View<pat::Electron>>(params.getParameter<edm::InputTag>("electrons"))),
0103       lowPtElectronsTag_(params.getParameter<edm::InputTag>("lowPtElectrons")),
0104       lowPtElectrons_(mayConsume<edm::View<pat::Electron>>(lowPtElectronsTag_)),
0105       taus_(consumes<edm::View<pat::Tau>>(params.getParameter<edm::InputTag>("taus"))),
0106       photons_(consumes<edm::View<pat::Photon>>(params.getParameter<edm::InputTag>("photons")))
0107 
0108 {
0109   produces<std::vector<pat::Jet>>("jets");
0110   produces<std::vector<pat::Muon>>("muons");
0111   produces<std::vector<pat::Electron>>("electrons");
0112   if (!lowPtElectronsTag_.label().empty())
0113     produces<std::vector<pat::Electron>>("lowPtElectrons");
0114   produces<std::vector<pat::Tau>>("taus");
0115   produces<std::vector<pat::Photon>>("photons");
0116 }
0117 
0118 PATObjectCrossLinker::~PATObjectCrossLinker() {
0119   // do anything here that needs to be done at destruction time
0120   // (e.g. close files, deallocate resources etc.)
0121 }
0122 
0123 //
0124 // member functions
0125 //
0126 
0127 // ------------ method called to produce the data  ------------
0128 
0129 ///
0130 template <class C1, class C2, class C3, class C4>
0131 void PATObjectCrossLinker::matchOneToMany(const C1& refProdOne,
0132                                           C2& itemsOne,
0133                                           const std::string& nameOne,
0134                                           const C3& refProdMany,
0135                                           C4& itemsMany,
0136                                           const std::string& nameMany) {
0137   size_t ji = 0;
0138   for (auto& j : itemsOne) {
0139     edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
0140     size_t mi = 0;
0141     for (auto& m : itemsMany) {
0142       if (matchByCommonSourceCandidatePtr(j, m) && (!m.hasUserCand(nameOne))) {
0143         m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
0144         overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
0145       }
0146       mi++;
0147     }
0148     j.setOverlaps(nameMany, overlaps);
0149     ji++;
0150   }
0151 }
0152 
0153 template <class C1, class C2, class C3, class C4>
0154 void PATObjectCrossLinker::matchElectronToPhoton(const C1& refProdOne,
0155                                                  C2& itemsOne,
0156                                                  const std::string& nameOne,
0157                                                  const C3& refProdMany,
0158                                                  C4& itemsMany,
0159                                                  const std::string& nameMany) {
0160   size_t ji = 0;
0161   for (auto& j : itemsOne) {
0162     edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
0163     size_t mi = 0;
0164     for (auto& m : itemsMany) {
0165       if (matchByCommonParentSuperClusterRef(j, m) && (!m.hasUserCand(nameOne))) {
0166         m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
0167         overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
0168       }
0169       mi++;
0170     }
0171     j.setOverlaps(nameMany, overlaps);
0172     ji++;
0173   }
0174 }
0175 
0176 template <class C1, class C2, class C3, class C4>
0177 void PATObjectCrossLinker::matchLowPtToElectron(const C1& refProdOne,
0178                                                 C2& itemsOne,
0179                                                 const std::string& nameOne,
0180                                                 const C3& refProdMany,
0181                                                 C4& itemsMany,
0182                                                 const std::string& nameMany) {
0183   size_t ji = 0;
0184   for (auto& j : itemsOne) {
0185     std::vector<std::pair<size_t, float>> idxs;
0186     size_t mi = 0;
0187     for (auto& m : itemsMany) {
0188       float dr2 = deltaR2(m, j);
0189       if (dr2 < 1.e-6) {  // deltaR < 1.e-3
0190         m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
0191         idxs.push_back(std::make_pair(mi, dr2));
0192       }
0193       mi++;
0194     }
0195     std::sort(idxs.begin(), idxs.end(), [](auto& left, auto& right) { return left.second < right.second; });
0196 
0197     edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
0198     for (auto idx : idxs) {
0199       overlaps.push_back(reco::CandidatePtr(refProdMany.id(), idx.first, refProdMany.productGetter()));
0200     }
0201     j.setOverlaps(nameMany, overlaps);
0202     ji++;
0203   }
0204 }
0205 
0206 void PATObjectCrossLinker::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0207   using namespace edm;
0208   edm::Handle<edm::View<pat::Jet>> jetsIn;
0209   iEvent.getByToken(jets_, jetsIn);
0210   auto jets = std::make_unique<std::vector<pat::Jet>>();
0211   for (const auto& j : *jetsIn)
0212     jets->push_back(j);
0213   auto jetRefProd = iEvent.getRefBeforePut<std::vector<pat::Jet>>("jets");
0214 
0215   edm::Handle<edm::View<pat::Muon>> muonsIn;
0216   iEvent.getByToken(muons_, muonsIn);
0217   auto muons = std::make_unique<std::vector<pat::Muon>>();
0218   for (const auto& m : *muonsIn)
0219     muons->push_back(m);
0220   auto muRefProd = iEvent.getRefBeforePut<std::vector<pat::Muon>>("muons");
0221 
0222   edm::Handle<edm::View<pat::Electron>> electronsIn;
0223   iEvent.getByToken(electrons_, electronsIn);
0224   auto electrons = std::make_unique<std::vector<pat::Electron>>();
0225   for (const auto& e : *electronsIn)
0226     electrons->push_back(e);
0227   auto eleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("electrons");
0228 
0229   edm::Handle<edm::View<pat::Electron>> lowPtElectronsIn;
0230   auto lowPtElectrons = std::make_unique<std::vector<pat::Electron>>();
0231   if (!lowPtElectronsTag_.label().empty()) {
0232     iEvent.getByToken(lowPtElectrons_, lowPtElectronsIn);
0233     for (const auto& e : *lowPtElectronsIn) {
0234       lowPtElectrons->push_back(e);
0235     }
0236   }
0237 
0238   edm::Handle<edm::View<pat::Tau>> tausIn;
0239   iEvent.getByToken(taus_, tausIn);
0240   auto taus = std::make_unique<std::vector<pat::Tau>>();
0241   for (const auto& t : *tausIn)
0242     taus->push_back(t);
0243   auto tauRefProd = iEvent.getRefBeforePut<std::vector<pat::Tau>>("taus");
0244 
0245   edm::Handle<edm::View<pat::Photon>> photonsIn;
0246   iEvent.getByToken(photons_, photonsIn);
0247   auto photons = std::make_unique<std::vector<pat::Photon>>();
0248   for (const auto& p : *photonsIn)
0249     photons->push_back(p);
0250   auto phRefProd = iEvent.getRefBeforePut<std::vector<pat::Photon>>("photons");
0251 
0252   matchOneToMany(jetRefProd, *jets, "jet", muRefProd, *muons, "muons");
0253   matchOneToMany(jetRefProd, *jets, "jet", eleRefProd, *electrons, "electrons");
0254   matchOneToMany(jetRefProd, *jets, "jet", tauRefProd, *taus, "taus");
0255   matchOneToMany(jetRefProd, *jets, "jet", phRefProd, *photons, "photons");
0256 
0257   matchElectronToPhoton(eleRefProd, *electrons, "electron", phRefProd, *photons, "photons");
0258   if (!lowPtElectronsTag_.label().empty()) {
0259     auto lowPtEleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("lowPtElectrons");
0260     matchLowPtToElectron(lowPtEleRefProd, *lowPtElectrons, "lowPtElectron", eleRefProd, *electrons, "electrons");
0261   }
0262 
0263   iEvent.put(std::move(jets), "jets");
0264   iEvent.put(std::move(muons), "muons");
0265   iEvent.put(std::move(electrons), "electrons");
0266   if (!lowPtElectronsTag_.label().empty())
0267     iEvent.put(std::move(lowPtElectrons), "lowPtElectrons");
0268   iEvent.put(std::move(taus), "taus");
0269   iEvent.put(std::move(photons), "photons");
0270 }
0271 
0272 // ------------ method called once each stream before processing any runs, lumis or events  ------------
0273 void PATObjectCrossLinker::beginStream(edm::StreamID) {}
0274 
0275 // ------------ method called once each stream after processing all runs, lumis and events  ------------
0276 void PATObjectCrossLinker::endStream() {}
0277 
0278 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0279 void PATObjectCrossLinker::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0280   //The following says we do not know what parameters are allowed so do no validation
0281   // Please change this to state exactly what you do use, even if it is no parameters
0282   edm::ParameterSetDescription desc;
0283   desc.setUnknown();
0284   descriptions.addDefault(desc);
0285 }
0286 
0287 //define this as a plug-in
0288 DEFINE_FWK_MODULE(PATObjectCrossLinker);