diff --git a/PhysicsTools/HepMCCandAlgos/plugins/MCTruthMatchers.cc b/PhysicsTools/HepMCCandAlgos/plugins/MCTruthMatchers.cc index ed97e42070cc0..7d92063c8873b 100644 --- a/PhysicsTools/HepMCCandAlgos/plugins/MCTruthMatchers.cc +++ b/PhysicsTools/HepMCCandAlgos/plugins/MCTruthMatchers.cc @@ -10,37 +10,39 @@ // Match by deltaR and deltaPt, ranking by deltaR (default) typedef reco::PhysObjectMatcher< - reco::CandidateView, - reco::GenParticleCollection, - reco::MCMatchSelector, - reco::MatchByDRDPt -> MCMatcher; + reco::CandidateView, + reco::GenParticleCollection, + reco::MCMatchSelector, + reco::MatchByDRDPt > + MCMatcher; // Alternative: match by deltaR and deltaPt, ranking by deltaPt typedef reco::PhysObjectMatcher< - reco::CandidateView, - reco::GenParticleCollection, - reco::MCMatchSelector, - reco::MatchByDRDPt, - reco::MatchLessByDPt -> MCMatcherByPt; + reco::CandidateView, + reco::GenParticleCollection, + reco::MCMatchSelector, + reco::MatchByDRDPt, + reco::MatchLessByDPt > + MCMatcherByPt; // JET Match by deltaR, ranking by deltaR (default) typedef reco::PhysObjectMatcher< - reco::CandidateView, - reco::GenJetCollection, - reco::MCMatchSelector, - reco::MatchByDR -> GenJetMatcher; + reco::CandidateView, + reco::GenJetCollection, + reco::MCMatchSelector, + reco::MatchByDR > + GenJetMatcher; + +// JET Match by deltaR and dPt, ranking by deltaR +typedef reco::PhysObjectMatcher< + reco::CandidateView, + reco::GenJetCollection, + reco::MCMatchSelector, + reco::MatchByDRDPt > + GenJetMatcherDRPtByDR; #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(MCMatcher); DEFINE_FWK_MODULE(MCMatcherByPt); DEFINE_FWK_MODULE(GenJetMatcher); +DEFINE_FWK_MODULE(GenJetMatcherDRPtByDR); diff --git a/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc b/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc index 77d0aaed31355..dd771cc26c2f0 100644 --- a/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc @@ -7,149 +7,282 @@ #include "DataFormats/Common/interface/View.h" #include "DataFormats/Candidate/interface/Candidate.h" #include "DataFormats/HepMCCandidate/interface/GenParticle.h" +#include +#include "DataFormats/JetReco/interface/GenJetCollection.h" #include #include - class CandMCMatchTableProducer : public edm::global::EDProducer<> { - public: - CandMCMatchTableProducer( edm::ParameterSet const & params ) : - objName_(params.getParameter("objName")), - branchName_(params.getParameter("branchName")), - doc_(params.getParameter("docString")), - src_(consumes(params.getParameter("src"))), - candMap_(consumes>(params.getParameter("mcMap"))) - { - produces(); - const std::string & type = params.getParameter("objType"); - if (type == "Muon") type_ = MMuon; - else if (type == "Electron") type_ = MElectron; - else if (type == "Tau") type_ = MTau; - else if (type == "Photon") type_ = MPhoton; - else if (type == "Other") type_ = MOther; - else throw cms::Exception("Configuration", "Unsupported objType '"+type+"'\n"); - - switch(type_) { - case MMuon: flavDoc_ = "1 = prompt muon (including gamma*->mu mu), 15 = muon from prompt tau, " // continues below - "5 = muon from b, 4 = muon from c, 3 = muon from light or unknown, 0 = unmatched"; break; - case MElectron: flavDoc_ = "1 = prompt electron (including gamma*->mu mu), 15 = electron from prompt tau, 22 = prompt photon (likely conversion), " // continues below - "5 = electron from b, 4 = electron from c, 3 = electron from light or unknown, 0 = unmatched"; break; - case MPhoton: flavDoc_ = "1 = prompt photon, 11 = prompt electron, 0 = unknown or unmatched"; break; - case MTau: flavDoc_ = "1 = prompt electron, 2 = prompt muon, 3 = tau->e decay, 4 = tau->mu decay, 5 = hadronic tau decay, 0 = unknown or unmatched"; break; - case MOther: flavDoc_ = "1 = from hard scatter, 0 = unknown or unmatched"; break; - } +public: + CandMCMatchTableProducer(edm::ParameterSet const& params) + : objName_(params.getParameter("objName")), + branchName_(params.getParameter("branchName")), + doc_(params.getParameter("docString")), + src_(consumes(params.getParameter("src"))), + candMap_(consumes>(params.getParameter("mcMap"))) { + produces(); + const std::string& type = params.getParameter("objType"); + if (type == "Muon") + type_ = MMuon; + else if (type == "Electron") + type_ = MElectron; + else if (type == "ElectronDressed") + type_ = MElectronDressed; + else if (type == "Tau") + type_ = MTau; + else if (type == "Photon") + type_ = MPhoton; + else if (type == "Other") + type_ = MOther; + else + throw cms::Exception("Configuration", "Unsupported objType '" + type + "'\n"); - if ( type_ == MTau ) { - candMapVisTau_ = consumes>(params.getParameter("mcMapVisTau")); - } - } + switch (type_) { + case MMuon: + flavDoc_ = + "1 = prompt muon (including gamma*->mu mu), 15 = muon from prompt tau, " // continues below + "5 = muon from b, 4 = muon from c, 3 = muon from light or unknown, 0 = unmatched"; + break; + case MElectron: + flavDoc_ = + "1 = prompt electron (including gamma*->mu mu), 15 = electron from prompt tau, 22 = prompt photon (likely " + "conversion), " // continues below + "5 = electron from b, 4 = electron from c, 3 = electron from light or unknown, 0 = unmatched"; + break; + case MElectronDressed: + flavDoc_ = + "1 = prompt electron (including gamma*->mu mu), 15 = electron from prompt tau, 22 = prompt photon (likely " + "conversion), " // continues below + "5 = electron from b, 4 = electron from c, 3 = electron from light or unknown, 0 = unmatched"; + break; + case MPhoton: + flavDoc_ = "1 = prompt photon, 11 = prompt electron, 0 = unknown or unmatched"; + break; + case MTau: + flavDoc_ = + "1 = prompt electron, 2 = prompt muon, 3 = tau->e decay, 4 = tau->mu decay, 5 = hadronic tau decay, 0 = " + "unknown or unmatched"; + break; + case MOther: + flavDoc_ = "1 = from hard scatter, 0 = unknown or unmatched"; + break; + } + + if (type_ == MTau) { + candMapVisTau_ = + consumes>(params.getParameter("mcMapVisTau")); + } + if (type_ == MElectronDressed) { + candMapDressedLep_ = + consumes>(params.getParameter("mcMapDressedLep")); + mapTauAnc_ = consumes>(params.getParameter("mapTauAnc")); + genPartsToken_ = consumes(params.getParameter("genparticles")); + } + } + + ~CandMCMatchTableProducer() override {} + + void produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const override { + edm::Handle cands; + iEvent.getByToken(src_, cands); + unsigned int ncand = cands->size(); + + auto tab = std::make_unique(ncand, objName_, false, true); + + edm::Handle> map; + iEvent.getByToken(candMap_, map); - ~CandMCMatchTableProducer() override {} - - void produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const override { - - edm::Handle cands; - iEvent.getByToken(src_, cands); - unsigned int ncand = cands->size(); - - auto tab = std::make_unique(ncand, objName_, false, true); - - edm::Handle> map; - iEvent.getByToken(candMap_, map); - - edm::Handle> mapVisTau; - if ( type_ == MTau ) { - iEvent.getByToken(candMapVisTau_, mapVisTau); - } - - std::vector key(ncand, -1), flav(ncand, 0); - for (unsigned int i = 0; i < ncand; ++i) { - //std::cout << "cand #" << i << ": pT = " << cands->ptrAt(i)->pt() << ", eta = " << cands->ptrAt(i)->eta() << ", phi = " << cands->ptrAt(i)->phi() << std::endl; - reco::GenParticleRef match = (*map)[cands->ptrAt(i)]; - reco::GenParticleRef matchVisTau; - if ( type_ == MTau ) { - matchVisTau = (*mapVisTau)[cands->ptrAt(i)]; - } - if ( match.isNonnull() ) key[i] = match.key(); - else if ( matchVisTau.isNonnull() ) key[i] = matchVisTau.key(); - else continue; - switch(type_) { - case MMuon: - if (match->isPromptFinalState()) flav[i] = 1; // prompt - else if (match->isDirectPromptTauDecayProductFinalState()) flav[i] = 15; // tau - else flav[i] = getParentHadronFlag(match); // 3 = light, 4 = charm, 5 = b - break; - case MElectron: - if (match->isPromptFinalState()) flav[i] = (match->pdgId() == 22 ? 22 : 1); // prompt electron or photon - else if (match->isDirectPromptTauDecayProductFinalState()) flav[i] = 15; // tau - else flav[i] = getParentHadronFlag(match); // 3 = light, 4 = charm, 5 = b - break; - case MPhoton: - if (match->isPromptFinalState() && match->pdgId() == 22) - flav[i] = 1; // prompt photon - else if ((match->isPromptFinalState() || match->isDirectPromptTauDecayProductFinalState()) && - abs(match->pdgId()) == 11) - flav[i] = 11; // prompt electron - break; - case MTau: - // CV: assignment of status codes according to https://twiki.cern.ch/twiki/bin/viewauth/CMS/HiggsToTauTauWorking2016#MC_Matching - if ( match.isNonnull() && match->statusFlags().isPrompt() && abs(match->pdgId()) == 11 ) flav[i] = 1; - else if ( match.isNonnull() && match->statusFlags().isPrompt() && abs(match->pdgId()) == 13 ) flav[i] = 2; - else if ( match.isNonnull() && match->isDirectPromptTauDecayProductFinalState() && abs(match->pdgId()) == 11 ) flav[i] = 3; - else if ( match.isNonnull() && match->isDirectPromptTauDecayProductFinalState() && abs(match->pdgId()) == 13 ) flav[i] = 4; - else if ( matchVisTau.isNonnull() ) flav[i] = 5; - break; - default: - flav[i] = match->statusFlags().fromHardProcess(); - }; - } - - tab->addColumn(branchName_+"Idx", key, "Index into genParticle list for "+doc_, nanoaod::FlatTable::IntColumn); - tab->addColumn(branchName_+"Flav", flav, "Flavour of genParticle for "+doc_+": "+flavDoc_, nanoaod::FlatTable::UInt8Column); - - iEvent.put(std::move(tab)); + edm::Handle> mapVisTau; + if (type_ == MTau) { + iEvent.getByToken(candMapVisTau_, mapVisTau); + } + + edm::Handle> mapDressedLep; + edm::Handle> mapTauAnc; + edm::Handle genParts; + if (type_ == MElectronDressed) { + iEvent.getByToken(candMapDressedLep_, mapDressedLep); + iEvent.getByToken(mapTauAnc_, mapTauAnc); + iEvent.getByToken(genPartsToken_, genParts); + } + + std::vector key(ncand, -1), flav(ncand, 0); + for (unsigned int i = 0; i < ncand; ++i) { + //std::cout << "cand #" << i << ": pT = " << cands->ptrAt(i)->pt() << ", eta = " << cands->ptrAt(i)->eta() << ", phi = " << cands->ptrAt(i)->phi() << std::endl; + reco::GenParticleRef match = (*map)[cands->ptrAt(i)]; + reco::GenParticleRef matchVisTau; + reco::GenJetRef matchDressedLep; + bool hasTauAnc = false; + if (type_ == MTau) { + matchVisTau = (*mapVisTau)[cands->ptrAt(i)]; + } + if (type_ == MElectronDressed) { + matchDressedLep = (*mapDressedLep)[cands->ptrAt(i)]; + if (matchDressedLep.isNonnull()) { + hasTauAnc = (*mapTauAnc)[matchDressedLep]; } + } + if (match.isNonnull()) + key[i] = match.key(); + else if (matchVisTau.isNonnull()) + key[i] = matchVisTau.key(); + else if (type_ != MElectronDressed) + continue; // go ahead with electrons, as those may be matched to a dressed lepton + switch (type_) { + case MMuon: + if (match->isPromptFinalState()) + flav[i] = 1; // prompt + else if (match->isDirectPromptTauDecayProductFinalState()) + flav[i] = 15; // tau + else + flav[i] = getParentHadronFlag(match); // 3 = light, 4 = charm, 5 = b + break; + case MElectron: + if (match->isPromptFinalState()) + flav[i] = (match->pdgId() == 22 ? 22 : 1); // prompt electron or photon + else if (match->isDirectPromptTauDecayProductFinalState()) + flav[i] = 15; // tau + else + flav[i] = getParentHadronFlag(match); // 3 = light, 4 = charm, 5 = b + break; + case MElectronDressed: + if (matchDressedLep.isNonnull()) { + if (matchDressedLep->pdgId() == 22) + flav[i] = 22; + else + flav[i] = (hasTauAnc) ? 15 : 1; - static int getParentHadronFlag(const reco::GenParticleRef match) { - bool has4 = false; - for (unsigned int im = 0, nm = match->numberOfMothers(); im < nm; ++im) { - reco::GenParticleRef mom = match->motherRef(im); - assert(mom.isNonnull() && mom.isAvailable()); // sanity - if (mom.key() >= match.key()) continue; // prevent circular refs - int id = std::abs(mom->pdgId()); - if (id / 1000 == 5 || id / 100 == 5 || id == 5) return 5; - if (id / 1000 == 4 || id / 100 == 4 || id == 4) has4 = true; - if (mom->status() == 2) { - id = getParentHadronFlag(mom); - if (id == 5) return 5; - else if (id == 4) has4 = true; - } + float minpt = 0; + const reco::GenParticle* highestPtConstituent = nullptr; + for (auto& consti : matchDressedLep->getGenConstituents()) { + if (abs(consti->pdgId()) != 11) + continue; + if (consti->pt() < minpt) + continue; + minpt = consti->pt(); + highestPtConstituent = consti; } - return has4 ? 4 : 3; - } + if (highestPtConstituent) { + auto iter = + std::find_if(genParts->begin(), genParts->end(), [highestPtConstituent](reco::GenParticle genp) { + return (abs(genp.pdgId()) == 11) && (deltaR(genp, *highestPtConstituent) < 0.01) && + (abs(genp.pt() - highestPtConstituent->pt()) / highestPtConstituent->pt() < 0.01); + }); + if (iter != genParts->end()) { + key[i] = iter - genParts->begin(); + } + } + } else if (!match.isNonnull()) + flav[i] = 0; + else if (match->isPromptFinalState()) + flav[i] = (match->pdgId() == 22 ? 22 : 1); // prompt electron or photon + else if (match->isDirectPromptTauDecayProductFinalState()) + flav[i] = 15; // tau + else + flav[i] = getParentHadronFlag(match); // 3 = light, 4 = charm, 5 = b + break; + case MPhoton: + if (match->isPromptFinalState() && match->pdgId() == 22) + flav[i] = 1; // prompt photon + else if ((match->isPromptFinalState() || match->isDirectPromptTauDecayProductFinalState()) && + abs(match->pdgId()) == 11) + flav[i] = 11; // prompt electron + break; + case MTau: + // CV: assignment of status codes according to https://twiki.cern.ch/twiki/bin/viewauth/CMS/HiggsToTauTauWorking2016#MC_Matching + if (match.isNonnull() && match->statusFlags().isPrompt() && abs(match->pdgId()) == 11) + flav[i] = 1; + else if (match.isNonnull() && match->statusFlags().isPrompt() && abs(match->pdgId()) == 13) + flav[i] = 2; + else if (match.isNonnull() && match->isDirectPromptTauDecayProductFinalState() && abs(match->pdgId()) == 11) + flav[i] = 3; + else if (match.isNonnull() && match->isDirectPromptTauDecayProductFinalState() && abs(match->pdgId()) == 13) + flav[i] = 4; + else if (matchVisTau.isNonnull()) + flav[i] = 5; + break; + default: + flav[i] = match->statusFlags().fromHardProcess(); + }; + } - static void fillDescriptions(edm::ConfigurationDescriptions & descriptions) { - edm::ParameterSetDescription desc; - desc.add("objName")->setComment("name of the nanoaod::FlatTable to extend with this table"); - desc.add("branchName")->setComment("name of the column to write (the final branch in the nanoaod will be _Idx and _Flav"); - desc.add("docString")->setComment("documentation to forward to the output"); - desc.add("src")->setComment("physics object collection for the reconstructed objects (e.g. leptons)"); - desc.add("mcMap")->setComment("tag to an edm::Association mapping src to gen, such as the one produced by MCMatcher"); - desc.add("objType")->setComment("type of object to match (Muon, Electron, Tau, Photon, Other), taylors what's in t Flav branch"); - desc.addOptional("mcMapVisTau")->setComment("as mcMap, but pointing to the visible gen taus (only if objType == Tau)"); - descriptions.add("candMcMatchTable", desc); - } + tab->addColumn( + branchName_ + "Idx", key, "Index into genParticle list for " + doc_, nanoaod::FlatTable::IntColumn); + switch (type_) { + case MElectronDressed: + tab->addColumn(branchName_ + "Flav", + flav, + "Flavour of genParticle (DressedLeptons for electrons) for " + doc_ + ": " + flavDoc_, + nanoaod::FlatTable::UInt8Column); + break; + default: + tab->addColumn(branchName_ + "Flav", + flav, + "Flavour of genParticle for " + doc_ + ": " + flavDoc_, + nanoaod::FlatTable::UInt8Column); + } + iEvent.put(std::move(tab)); + } + + static int getParentHadronFlag(const reco::GenParticleRef match) { + bool has4 = false; + for (unsigned int im = 0, nm = match->numberOfMothers(); im < nm; ++im) { + reco::GenParticleRef mom = match->motherRef(im); + assert(mom.isNonnull() && mom.isAvailable()); // sanity + if (mom.key() >= match.key()) + continue; // prevent circular refs + int id = std::abs(mom->pdgId()); + if (id / 1000 == 5 || id / 100 == 5 || id == 5) + return 5; + if (id / 1000 == 4 || id / 100 == 4 || id == 4) + has4 = true; + if (mom->status() == 2) { + id = getParentHadronFlag(mom); + if (id == 5) + return 5; + else if (id == 4) + has4 = true; + } + } + return has4 ? 4 : 3; + } - protected: - const std::string objName_, branchName_, doc_; - const edm::EDGetTokenT src_; - const edm::EDGetTokenT> candMap_; - edm::EDGetTokenT> candMapVisTau_; - enum MatchType { MMuon, MElectron, MTau, MPhoton, MOther } type_; - std::string flavDoc_; + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("objName")->setComment("name of the nanoaod::FlatTable to extend with this table"); + desc.add("branchName") + ->setComment( + "name of the column to write (the final branch in the nanoaod will be _Idx and " + "_Flav"); + desc.add("docString")->setComment("documentation to forward to the output"); + desc.add("src")->setComment( + "physics object collection for the reconstructed objects (e.g. leptons)"); + desc.add("mcMap")->setComment( + "tag to an edm::Association mapping src to gen, such as the one produced by MCMatcher"); + desc.add("objType")->setComment( + "type of object to match (Muon, Electron, Tau, Photon, Other), taylors what's in t Flav branch"); + desc.addOptional("mcMapVisTau") + ->setComment("as mcMap, but pointing to the visible gen taus (only if objType == Tau)"); + desc.addOptional("mcMapDressedLep") + ->setComment("as mcMap, but pointing to gen dressed leptons (only if objType == Electrons)"); + desc.addOptional("mapTauAnc") + ->setComment("Value map of matched gen electrons containing info on the tau ancestry"); + desc.addOptional("genparticles")->setComment("Collection of genParticles to be stored."); + descriptions.add("candMcMatchTable", desc); + } + +protected: + const std::string objName_, branchName_, doc_; + const edm::EDGetTokenT src_; + const edm::EDGetTokenT> candMap_; + edm::EDGetTokenT> candMapVisTau_; + edm::EDGetTokenT> candMapDressedLep_; + edm::EDGetTokenT> mapTauAnc_; + edm::EDGetTokenT genPartsToken_; + enum MatchType { MMuon, MElectron, MTau, MPhoton, MOther, MElectronDressed } type_; + std::string flavDoc_; }; #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(CandMCMatchTableProducer); - diff --git a/PhysicsTools/NanoAOD/plugins/GenJetGenPartMerger.cc b/PhysicsTools/NanoAOD/plugins/GenJetGenPartMerger.cc new file mode 100644 index 0000000000000..4107afbdf66ea --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/GenJetGenPartMerger.cc @@ -0,0 +1,113 @@ + +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "DataFormats/JetReco/interface/GenJetCollection.h" +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" + +#include "DataFormats/Common/interface/ValueMap.h" + +// +// class declaration +// + +class GenJetGenPartMerger : public edm::stream::EDProducer<> { +public: + explicit GenJetGenPartMerger(const edm::ParameterSet&); + ~GenJetGenPartMerger() override; + +private: + void beginStream(edm::StreamID) override; + void produce(edm::Event&, const edm::EventSetup&) override; + void endStream() override; + + const edm::EDGetTokenT jetToken_; + const edm::EDGetTokenT partToken_; + const edm::EDGetTokenT> tauAncToken_; +}; + +// +// constants, enums and typedefs +// + +// +// static data member definitions +// + +// +// constructors and destructor +// +GenJetGenPartMerger::GenJetGenPartMerger(const edm::ParameterSet& iConfig) + : jetToken_(consumes(iConfig.getParameter("srcJet"))), + partToken_(consumes(iConfig.getParameter("srcPart"))), + tauAncToken_(consumes>(iConfig.getParameter("hasTauAnc"))) { + produces("merged"); + produces>("hasTauAnc"); +} + +GenJetGenPartMerger::~GenJetGenPartMerger() {} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void GenJetGenPartMerger::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + std::unique_ptr merged(new reco::GenJetCollection); + + std::vector hasTauAncValues; + + edm::Handle jetHandle; + iEvent.getByToken(jetToken_, jetHandle); + + edm::Handle partHandle; + iEvent.getByToken(partToken_, partHandle); + + edm::Handle> tauAncHandle; + iEvent.getByToken(tauAncToken_, tauAncHandle); + + for (unsigned int ijet = 0; ijet < jetHandle->size(); ++ijet) { + auto jet = jetHandle->at(ijet); + merged->push_back(reco::GenJet(jet)); + reco::GenJetRef jetRef(jetHandle, ijet); + hasTauAncValues.push_back((*tauAncHandle)[jetRef]); + } + + for (auto& part : *partHandle) { + reco::GenJet jet; + jet.setP4(part.p4()); + jet.setPdgId(part.pdgId()); + jet.setCharge(part.charge()); + merged->push_back(jet); + hasTauAncValues.push_back(false); + } + + auto newmerged = iEvent.put(std::move(merged), "merged"); + + std::unique_ptr> out(new edm::ValueMap()); + edm::ValueMap::Filler filler(*out); + filler.insert(newmerged, hasTauAncValues.begin(), hasTauAncValues.end()); + filler.fill(); + + iEvent.put(std::move(out), "hasTauAnc"); +} + +// ------------ method called once each stream before processing any runs, lumis or events ------------ +void GenJetGenPartMerger::beginStream(edm::StreamID) {} + +// ------------ method called once each stream after processing all runs, lumis and events ------------ +void GenJetGenPartMerger::endStream() {} + +//define this as a plug-in +DEFINE_FWK_MODULE(GenJetGenPartMerger); diff --git a/PhysicsTools/NanoAOD/python/electrons_cff.py b/PhysicsTools/NanoAOD/python/electrons_cff.py index bcd4cd9f11476..dd2d61fc133c4 100644 --- a/PhysicsTools/NanoAOD/python/electrons_cff.py +++ b/PhysicsTools/NanoAOD/python/electrons_cff.py @@ -466,6 +466,35 @@ def _get_bitmapVIDForEle_docstring(modules,WorkingPoints): ) +from PhysicsTools.NanoAOD.particlelevel_cff import particleLevel +particleLevelForMatching = particleLevel.clone( + lepMinPt = cms.double(3.), + phoMinPt = cms.double(3), +) +tautaggerForMatching = cms.EDProducer("GenJetTauTaggerProducer", + src = cms.InputTag('particleLevelForMatching:leptons') +) + +matchingElecPhoton = cms.EDProducer("GenJetGenPartMerger", + srcJet =cms.InputTag("particleLevelForMatching:leptons"), + srcPart=cms.InputTag("particleLevelForMatching:photons"), + hasTauAnc=cms.InputTag("tautaggerForMatching"), +) + + +electronsMCMatchForTableAlt = cms.EDProducer("GenJetMatcherDRPtByDR", # cut on deltaR, deltaPt/Pt; pick best by deltaR + src = electronTable.src, # final reco collection + matched = cms.InputTag("matchingElecPhoton:merged"), # final mc-truth particle collection + mcPdgId = cms.vint32(11,22), # one or more PDG ID (11 = el, 22 = pho); absolute values (see below) + checkCharge = cms.bool(False), # True = require RECO and MC objects to have the same charge + mcStatus = cms.vint32(), + maxDeltaR = cms.double(0.3), # Minimum deltaR for the match + maxDPtRel = cms.double(0.5), # Minimum deltaPt/Pt for the match + resolveAmbiguities = cms.bool(True), # Forbid two RECO objects to match to the same GEN object + resolveByMatchQuality = cms.bool(True), # False = just match input in order; True = pick lowest deltaR pair first +) + + electronsMCMatchForTable = cms.EDProducer("MCMatcher", # cut on deltaR, deltaPt/Pt; pick best by deltaR src = electronTable.src, # final reco collection matched = cms.InputTag("finalGenParticles"), # final mc-truth particle collection @@ -478,18 +507,39 @@ def _get_bitmapVIDForEle_docstring(modules,WorkingPoints): resolveByMatchQuality = cms.bool(True), # False = just match input in order; True = pick lowest deltaR pair first ) +# electronOldMCTable = cms.EDProducer("CandMCMatchTableProducer", +# src = electronTable.src, +# mcMap = cms.InputTag("electronsMCMatchForTable"), +# objName = electronTable.name, +# objType = electronTable.name, #cms.string("Electron"), +# branchName = cms.string("genPart"), +# docString = cms.string("MC matching to status==1 electrons or photons"), +# ) + electronMCTable = cms.EDProducer("CandMCMatchTableProducer", src = electronTable.src, + mcMapDressedLep = cms.InputTag("electronsMCMatchForTableAlt"), mcMap = cms.InputTag("electronsMCMatchForTable"), + mapTauAnc = cms.InputTag("matchingElecPhoton:hasTauAnc"), objName = electronTable.name, - objType = electronTable.name, #cms.string("Electron"), + objType = cms.string("ElectronDressed"), branchName = cms.string("genPart"), docString = cms.string("MC matching to status==1 electrons or photons"), + genparticles = cms.InputTag("finalGenParticles"), ) + electronSequence = cms.Sequence(bitmapVIDForEle + bitmapVIDForEleHEEP + isoForEle + ptRatioRelForEle + seedGainEle + slimmedElectronsWithUserData + finalElectrons) electronTables = cms.Sequence (electronMVATTH + electronTable) -electronMC = cms.Sequence(electronsMCMatchForTable + electronMCTable) +electronMCold = cms.Sequence(electronsMCMatchForTable + electronMCTable) +electronMC = cms.Sequence(particleLevelForMatching + tautaggerForMatching + matchingElecPhoton + electronsMCMatchForTable + electronsMCMatchForTableAlt + electronMCTable) +( run2_nanoAOD_106Xv1 & ~run2_nanoAOD_devel).toModify( electronMCTable, + mcMapDressedLep=None, + mcMap = cms.InputTag("electronsMCMatchForTable"), + mapTauAnc=None, + objType=electronTable.name, + genparticles=None) +( run2_nanoAOD_106Xv1 & ~run2_nanoAOD_devel).toReplaceWith(electronMC, electronMCold) #for NANO from reminAOD, no need to run slimmedElectronsUpdated, other modules of electron sequence will run on slimmedElectrons for modifier in run2_miniAOD_80XLegacy,run2_nanoAOD_94XMiniAODv1,run2_nanoAOD_94XMiniAODv2,run2_nanoAOD_94X2016,run2_nanoAOD_102Xv1,run2_nanoAOD_106Xv1: