File indexing completed on 2024-04-06 12:23:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <memory>
0021
0022
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 #include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h"
0038
0039 #include "DataFormats/Common/interface/View.h"
0040
0041 #include "PhysicsTools/NanoAOD/interface/MatchingUtils.h"
0042
0043
0044
0045
0046 class PATObjectCrossLinker : public edm::stream::EDProducer<> {
0047 public:
0048 explicit PATObjectCrossLinker(const edm::ParameterSet&);
0049
0050 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0051
0052 private:
0053 void produce(edm::Event&, const edm::EventSetup&) override;
0054
0055 template <class C1, class C2, class C3, class C4>
0056 void matchOneToMany(const C1& refProdOne,
0057 C2& itemsOne,
0058 const std::string& nameOne,
0059 const C3& refProdMany,
0060 C4& itemsMany,
0061 const std::string& nameMany);
0062
0063 template <class C1, class C2, class C3, class C4>
0064 void matchElectronToPhoton(const C1& refProdOne,
0065 C2& itemsOne,
0066 const std::string& nameOne,
0067 const C3& refProdMany,
0068 C4& itemsMany,
0069 const std::string& nameMany);
0070
0071 template <class C1, class C2, class C3, class C4>
0072 void matchLowPtToElectron(const C1& refProdOne,
0073 C2& itemsOne,
0074 const std::string& nameOne,
0075 const C3& refProdMany,
0076 C4& itemsMany,
0077 const std::string& nameMany);
0078
0079 template <class C1, class C2, class C3>
0080 void matchOneToVertices(C1& itemsOne, const C2& refProdVtx, C3& itemsVtx, const std::string& nameVtx);
0081
0082 template <class C1, class C2, class C3>
0083 void matchVertexToMany(const C1& refProdVtx, C2& itemsVtx, const std::string& nameVtx, C3& itemsMany);
0084
0085
0086 const edm::EDGetTokenT<edm::View<pat::Jet>> jets_;
0087 const edm::EDGetTokenT<edm::View<pat::Muon>> muons_;
0088 const edm::EDGetTokenT<edm::View<pat::Electron>> electrons_;
0089 const edm::EDGetTokenT<edm::View<pat::Photon>> photons_;
0090 const edm::EDGetTokenT<edm::View<pat::Tau>> taus_;
0091 edm::InputTag lowPtElectronsTag_;
0092 edm::EDGetTokenT<edm::View<pat::Electron>> lowPtElectrons_;
0093 edm::InputTag boostedTausTag_;
0094 edm::EDGetTokenT<edm::View<pat::Tau>> boostedTaus_;
0095 edm::InputTag verticesTag_;
0096 edm::EDGetTokenT<edm::View<reco::VertexCompositePtrCandidate>> vertices_;
0097 };
0098
0099
0100
0101
0102 PATObjectCrossLinker::PATObjectCrossLinker(const edm::ParameterSet& params)
0103 : jets_(consumes<edm::View<pat::Jet>>(params.getParameter<edm::InputTag>("jets"))),
0104 muons_(consumes<edm::View<pat::Muon>>(params.getParameter<edm::InputTag>("muons"))),
0105 electrons_(consumes<edm::View<pat::Electron>>(params.getParameter<edm::InputTag>("electrons"))),
0106 photons_(consumes<edm::View<pat::Photon>>(params.getParameter<edm::InputTag>("photons"))),
0107 taus_(consumes<edm::View<pat::Tau>>(params.getParameter<edm::InputTag>("taus"))),
0108 lowPtElectronsTag_(params.getParameter<edm::InputTag>("lowPtElectrons")),
0109 boostedTausTag_(params.getParameter<edm::InputTag>("boostedTaus")),
0110 verticesTag_(params.getParameter<edm::InputTag>("vertices")) {
0111 produces<std::vector<pat::Jet>>("jets");
0112 produces<std::vector<pat::Muon>>("muons");
0113 produces<std::vector<pat::Electron>>("electrons");
0114 produces<std::vector<pat::Photon>>("photons");
0115 produces<std::vector<pat::Tau>>("taus");
0116 if (!lowPtElectronsTag_.label().empty()) {
0117 lowPtElectrons_ = consumes<edm::View<pat::Electron>>(lowPtElectronsTag_),
0118 produces<std::vector<pat::Electron>>("lowPtElectrons");
0119 }
0120 if (!boostedTausTag_.label().empty()) {
0121 boostedTaus_ = consumes<edm::View<pat::Tau>>(boostedTausTag_);
0122 produces<std::vector<pat::Tau>>("boostedTaus");
0123 }
0124 if (!verticesTag_.label().empty()) {
0125 vertices_ = consumes<edm::View<reco::VertexCompositePtrCandidate>>(verticesTag_);
0126 produces<std::vector<reco::VertexCompositePtrCandidate>>("vertices");
0127 }
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137 template <class C1, class C2, class C3, class C4>
0138 void PATObjectCrossLinker::matchOneToMany(const C1& refProdOne,
0139 C2& itemsOne,
0140 const std::string& nameOne,
0141 const C3& refProdMany,
0142 C4& itemsMany,
0143 const std::string& nameMany) {
0144 size_t ji = 0;
0145 for (auto& j : itemsOne) {
0146 edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
0147 size_t mi = 0;
0148 for (auto& m : itemsMany) {
0149 if (matchByCommonSourceCandidatePtr(j, m) && (!m.hasUserCand(nameOne))) {
0150 m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
0151 overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
0152 }
0153 mi++;
0154 }
0155 j.setOverlaps(nameMany, overlaps);
0156 ji++;
0157 }
0158 }
0159
0160
0161 template <class C1, class C2, class C3, class C4>
0162 void PATObjectCrossLinker::matchElectronToPhoton(const C1& refProdOne,
0163 C2& itemsOne,
0164 const std::string& nameOne,
0165 const C3& refProdMany,
0166 C4& itemsMany,
0167 const std::string& nameMany) {
0168 size_t ji = 0;
0169 for (auto& j : itemsOne) {
0170 edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
0171 size_t mi = 0;
0172 for (auto& m : itemsMany) {
0173 if (matchByCommonParentSuperClusterRef(j, m) && (!m.hasUserCand(nameOne))) {
0174 m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
0175 overlaps.push_back(reco::CandidatePtr(refProdMany.id(), mi, refProdMany.productGetter()));
0176 }
0177 mi++;
0178 }
0179 j.setOverlaps(nameMany, overlaps);
0180 ji++;
0181 }
0182 }
0183
0184
0185 template <class C1, class C2, class C3, class C4>
0186 void PATObjectCrossLinker::matchLowPtToElectron(const C1& refProdOne,
0187 C2& itemsOne,
0188 const std::string& nameOne,
0189 const C3& refProdMany,
0190 C4& itemsMany,
0191 const std::string& nameMany) {
0192 size_t ji = 0;
0193 for (auto& j : itemsOne) {
0194 std::vector<std::pair<size_t, float>> idxs;
0195 size_t mi = 0;
0196 for (auto& m : itemsMany) {
0197 float dr2 = deltaR2(m, j);
0198 if (dr2 < 1.e-6) {
0199 m.addUserCand(nameOne, reco::CandidatePtr(refProdOne.id(), ji, refProdOne.productGetter()));
0200 idxs.push_back(std::make_pair(mi, dr2));
0201 }
0202 mi++;
0203 }
0204 std::sort(idxs.begin(), idxs.end(), [](auto& left, auto& right) { return left.second < right.second; });
0205
0206 edm::PtrVector<reco::Candidate> overlaps(refProdMany.id());
0207 for (auto idx : idxs) {
0208 overlaps.push_back(reco::CandidatePtr(refProdMany.id(), idx.first, refProdMany.productGetter()));
0209 }
0210 j.setOverlaps(nameMany, overlaps);
0211 ji++;
0212 }
0213 }
0214
0215
0216
0217 template <class C1, class C2, class C3>
0218 void PATObjectCrossLinker::matchOneToVertices(C1& itemsOne,
0219 const C2& refProdVtx,
0220 C3& itemsVtx,
0221 const std::string& nameVtx) {
0222 for (auto& j : itemsOne) {
0223 edm::PtrVector<reco::Candidate> overlaps(refProdVtx.id());
0224 size_t vi = 0;
0225 for (auto& v : itemsVtx) {
0226 if (matchByCommonSourceCandidatePtr(j, v)) {
0227 overlaps.push_back(reco::CandidatePtr(refProdVtx.id(), vi, refProdVtx.productGetter()));
0228 }
0229 vi++;
0230 }
0231 j.setOverlaps(nameVtx, overlaps);
0232 }
0233 }
0234
0235
0236
0237 template <class C1, class C2, class C3>
0238 void PATObjectCrossLinker::matchVertexToMany(const C1& refProdVtx,
0239 C2& itemsVtx,
0240 const std::string& nameVtx,
0241 C3& itemsMany) {
0242 size_t vi = 0;
0243 for (auto& v : itemsVtx) {
0244 for (auto& m : itemsMany) {
0245 if (matchByCommonSourceCandidatePtr(v, m) && (!m.hasUserCand(nameVtx))) {
0246 m.addUserCand(nameVtx, reco::CandidatePtr(refProdVtx.id(), vi, refProdVtx.productGetter()));
0247 }
0248 }
0249 vi++;
0250 }
0251 }
0252
0253 void PATObjectCrossLinker::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0254 using namespace edm;
0255 const auto& jetsIn = iEvent.get(jets_);
0256 auto jets = std::make_unique<std::vector<pat::Jet>>();
0257 jets->reserve(jetsIn.size());
0258 for (const auto& j : jetsIn)
0259 jets->push_back(j);
0260 auto jetRefProd = iEvent.getRefBeforePut<std::vector<pat::Jet>>("jets");
0261
0262 const auto& muonsIn = iEvent.get(muons_);
0263 auto muons = std::make_unique<std::vector<pat::Muon>>();
0264 muons->reserve(muonsIn.size());
0265 for (const auto& m : muonsIn)
0266 muons->push_back(m);
0267 auto muRefProd = iEvent.getRefBeforePut<std::vector<pat::Muon>>("muons");
0268
0269 const auto& electronsIn = iEvent.get(electrons_);
0270 auto electrons = std::make_unique<std::vector<pat::Electron>>();
0271 electrons->reserve(electronsIn.size());
0272 for (const auto& e : electronsIn)
0273 electrons->push_back(e);
0274 auto eleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("electrons");
0275
0276 const auto& tausIn = iEvent.get(taus_);
0277 auto taus = std::make_unique<std::vector<pat::Tau>>();
0278 taus->reserve(tausIn.size());
0279 for (const auto& t : tausIn)
0280 taus->push_back(t);
0281 auto tauRefProd = iEvent.getRefBeforePut<std::vector<pat::Tau>>("taus");
0282
0283 const auto& photonsIn = iEvent.get(photons_);
0284 auto photons = std::make_unique<std::vector<pat::Photon>>();
0285 photons->reserve(photonsIn.size());
0286 for (const auto& p : photonsIn)
0287 photons->push_back(p);
0288 auto phRefProd = iEvent.getRefBeforePut<std::vector<pat::Photon>>("photons");
0289
0290 auto lowPtElectrons = std::make_unique<std::vector<pat::Electron>>();
0291 if (!lowPtElectronsTag_.label().empty()) {
0292 const auto& lowPtElectronsIn = iEvent.get(lowPtElectrons_);
0293 lowPtElectrons->reserve(lowPtElectronsIn.size());
0294 for (const auto& e : lowPtElectronsIn) {
0295 lowPtElectrons->push_back(e);
0296 }
0297 }
0298
0299 auto boostedTaus = std::make_unique<std::vector<pat::Tau>>();
0300 if (!boostedTausTag_.label().empty()) {
0301 const auto& boostedTausIn = iEvent.get(boostedTaus_);
0302 boostedTaus->reserve(boostedTausIn.size());
0303 for (const auto& e : boostedTausIn) {
0304 boostedTaus->push_back(e);
0305 }
0306 }
0307
0308 auto vertices = std::make_unique<std::vector<reco::VertexCompositePtrCandidate>>();
0309 if (!verticesTag_.label().empty()) {
0310 const auto& verticesIn = iEvent.get(vertices_);
0311 vertices->reserve(verticesIn.size());
0312 for (const auto& e : verticesIn) {
0313 vertices->push_back(e);
0314 }
0315 }
0316
0317 matchOneToMany(jetRefProd, *jets, "jet", muRefProd, *muons, "muons");
0318 matchOneToMany(jetRefProd, *jets, "jet", eleRefProd, *electrons, "electrons");
0319 matchOneToMany(jetRefProd, *jets, "jet", tauRefProd, *taus, "taus");
0320 matchOneToMany(jetRefProd, *jets, "jet", phRefProd, *photons, "photons");
0321
0322 matchOneToMany(tauRefProd, *taus, "tau", muRefProd, *muons, "muons");
0323 matchOneToMany(tauRefProd, *taus, "tau", eleRefProd, *electrons, "electrons");
0324
0325 matchElectronToPhoton(eleRefProd, *electrons, "electron", phRefProd, *photons, "photons");
0326
0327 if (!lowPtElectronsTag_.label().empty()) {
0328 auto lowPtEleRefProd = iEvent.getRefBeforePut<std::vector<pat::Electron>>("lowPtElectrons");
0329 matchLowPtToElectron(lowPtEleRefProd, *lowPtElectrons, "lowPtElectron", eleRefProd, *electrons, "electrons");
0330 matchElectronToPhoton(lowPtEleRefProd, *lowPtElectrons, "lowPtElectron", phRefProd, *photons, "photons");
0331 }
0332
0333 if (!boostedTausTag_.label().empty()) {
0334 auto boostedTauRefProd = iEvent.getRefBeforePut<std::vector<pat::Tau>>("boostedTaus");
0335 matchOneToMany(jetRefProd, *jets, "jet", boostedTauRefProd, *boostedTaus, "boostedTaus");
0336 }
0337
0338 if (!verticesTag_.label().empty()) {
0339 auto vtxRefProd = iEvent.getRefBeforePut<std::vector<reco::VertexCompositePtrCandidate>>("vertices");
0340 matchOneToVertices(*jets, vtxRefProd, *vertices, "vertices");
0341 matchOneToVertices(*taus, vtxRefProd, *vertices, "vertices");
0342 matchVertexToMany(vtxRefProd, *vertices, "vertex", *muons);
0343 matchVertexToMany(vtxRefProd, *vertices, "vertex", *electrons);
0344 }
0345
0346 iEvent.put(std::move(jets), "jets");
0347 iEvent.put(std::move(muons), "muons");
0348 iEvent.put(std::move(electrons), "electrons");
0349 iEvent.put(std::move(taus), "taus");
0350 iEvent.put(std::move(photons), "photons");
0351 if (!lowPtElectronsTag_.label().empty())
0352 iEvent.put(std::move(lowPtElectrons), "lowPtElectrons");
0353 if (!boostedTausTag_.label().empty())
0354 iEvent.put(std::move(boostedTaus), "boostedTaus");
0355 if (!verticesTag_.label().empty())
0356 iEvent.put(std::move(vertices), "vertices");
0357 }
0358
0359
0360 void PATObjectCrossLinker::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0361 edm::ParameterSetDescription desc;
0362 desc.add<edm::InputTag>("jets")->setComment("a jet collection derived from pat::Jet");
0363 desc.add<edm::InputTag>("muons")->setComment("a muon collection derived from pat::Muon");
0364 desc.add<edm::InputTag>("electrons")->setComment("an electron collection derived from pat::Electron");
0365 desc.add<edm::InputTag>("photons")->setComment("a photon collection derived from pat::Photon");
0366 desc.add<edm::InputTag>("taus")->setComment("a tau collection derived from pat::Tau");
0367 desc.add<edm::InputTag>("lowPtElectrons", edm::InputTag(""))
0368 ->setComment("an optional electron collection derived from pat::Electron, empty=>not used");
0369 desc.add<edm::InputTag>("boostedTaus", edm::InputTag(""))
0370 ->setComment("an optional boosted tau collection derived from pat::Tau, empty=>not used");
0371 desc.add<edm::InputTag>("vertices", edm::InputTag(""))
0372 ->setComment("an optional vertex collection derived from reco::VertexCompositePtrCandidate,empty=>not used");
0373 descriptions.add("patObjectCrossLinker", desc);
0374 }
0375
0376
0377 DEFINE_FWK_MODULE(PATObjectCrossLinker);