File indexing completed on 2024-07-03 04:17:53
0001 #include <memory>
0002
0003 #include "GeneratorInterface/RivetInterface/interface/ParticleLevelProducer.h"
0004
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "DataFormats/Candidate/interface/Candidate.h"
0007 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0008 #include "DataFormats/Common/interface/RefToPtr.h"
0009 #include "DataFormats/METReco/interface/METFwd.h"
0010 #include "DataFormats/METReco/interface/MET.h"
0011 #include "RecoJets/JetProducers/interface/JetSpecific.h"
0012 #include "CommonTools/Utils/interface/PtComparator.h"
0013
0014 #include "Rivet/Analysis.hh"
0015
0016 using namespace std;
0017 using namespace edm;
0018 using namespace reco;
0019 using namespace Rivet;
0020
0021 ParticleLevelProducer::ParticleLevelProducer(const edm::ParameterSet& pset)
0022 : srcToken_(consumes<edm::HepMC3Product>(pset.getParameter<edm::InputTag>("src"))), pset_(pset) {
0023 usesResource("Rivet");
0024 genVertex_ = reco::Particle::Point(0, 0, 0);
0025
0026 produces<reco::GenParticleCollection>("neutrinos");
0027 produces<reco::GenParticleCollection>("photons");
0028 produces<reco::GenJetCollection>("leptons");
0029 produces<reco::GenJetCollection>("jets");
0030 produces<reco::GenJetCollection>("fatjets");
0031 produces<reco::GenParticleCollection>("consts");
0032 produces<reco::GenParticleCollection>("tags");
0033 produces<reco::METCollection>("mets");
0034 }
0035
0036 void ParticleLevelProducer::addGenJet(Rivet::Jet jet,
0037 std::unique_ptr<reco::GenJetCollection>& jets,
0038 std::unique_ptr<reco::GenParticleCollection>& consts,
0039 edm::RefProd<reco::GenParticleCollection>& constsRefHandle,
0040 int& iConstituent,
0041 std::unique_ptr<reco::GenParticleCollection>& tags,
0042 edm::RefProd<reco::GenParticleCollection>& tagsRefHandle,
0043 int& iTag) {
0044 const auto pjet = jet.pseudojet();
0045
0046 reco::GenJet genJet;
0047 genJet.setP4(p4(jet));
0048 genJet.setVertex(genVertex_);
0049 if (jet.bTagged())
0050 genJet.setPdgId(5);
0051 else if (jet.cTagged())
0052 genJet.setPdgId(4);
0053 genJet.setJetArea(pjet.has_area() ? pjet.area() : 0);
0054
0055 for (auto const& p : jet.particles()) {
0056 auto pp4 = p4(p);
0057 bool match = false;
0058 int iMatch = -1;
0059 for (auto const& q : *consts) {
0060 ++iMatch;
0061 if (q.p4() == pp4) {
0062 match = true;
0063 break;
0064 }
0065 }
0066 if (match) {
0067 genJet.addDaughter(edm::refToPtr(reco::GenParticleRef(constsRefHandle, iMatch)));
0068 } else {
0069 consts->push_back(reco::GenParticle(p.charge(), pp4, genVertex_, p.pid(), 1, true));
0070 genJet.addDaughter(edm::refToPtr(reco::GenParticleRef(constsRefHandle, ++iConstituent)));
0071 }
0072 }
0073 for (auto const& p : jet.tags()) {
0074
0075
0076 auto pp4 = p4(p) * 1e-20;
0077 bool match = false;
0078 int iMatch = -1;
0079 for (auto const& q : *tags) {
0080 ++iMatch;
0081 if (q.p4() == pp4) {
0082 match = true;
0083 break;
0084 }
0085 }
0086 if (match) {
0087 genJet.addDaughter(edm::refToPtr(reco::GenParticleRef(tagsRefHandle, iMatch)));
0088 } else {
0089 tags->push_back(reco::GenParticle(p.charge(), p4(p) * 1e-20, genVertex_, p.pid(), 2, true));
0090 genJet.addDaughter(edm::refToPtr(reco::GenParticleRef(tagsRefHandle, ++iTag)));
0091
0092 int iTagMother = iTag;
0093 for (auto const& d : p.constituents()) {
0094 ++iTag;
0095 int d_status = (d.isStable()) ? 1 : 2;
0096 tags->push_back(reco::GenParticle(d.charge(), p4(d) * 1e-20, genVertex_, d.pid(), d_status, true));
0097 tags->at(iTag).addMother(reco::GenParticleRef(tagsRefHandle, iTagMother));
0098 tags->at(iTagMother).addDaughter(reco::GenParticleRef(tagsRefHandle, iTag));
0099 genJet.addDaughter(edm::refToPtr(reco::GenParticleRef(tagsRefHandle, iTag)));
0100 }
0101 }
0102 }
0103
0104 jets->push_back(genJet);
0105 }
0106
0107 void ParticleLevelProducer::produce(edm::Event& event, const edm::EventSetup& eventSetup) {
0108 using namespace Rivet;
0109 typedef reco::Candidate::LorentzVector LorentzVector;
0110
0111 std::unique_ptr<reco::GenParticleCollection> neutrinos(new reco::GenParticleCollection);
0112 std::unique_ptr<reco::GenParticleCollection> photons(new reco::GenParticleCollection);
0113 std::unique_ptr<reco::GenJetCollection> leptons(new reco::GenJetCollection);
0114 std::unique_ptr<reco::GenJetCollection> jets(new reco::GenJetCollection);
0115 std::unique_ptr<reco::GenJetCollection> fatjets(new reco::GenJetCollection);
0116 std::unique_ptr<reco::GenParticleCollection> consts(new reco::GenParticleCollection);
0117 std::unique_ptr<reco::GenParticleCollection> tags(new reco::GenParticleCollection);
0118 std::unique_ptr<reco::METCollection> mets(new reco::METCollection);
0119 auto constsRefHandle = event.getRefBeforePut<reco::GenParticleCollection>("consts");
0120 auto tagsRefHandle = event.getRefBeforePut<reco::GenParticleCollection>("tags");
0121
0122 edm::Handle<HepMC3Product> srcHandle;
0123 event.getByToken(srcToken_, srcHandle);
0124
0125 const HepMC3::GenEventData* genEventData = srcHandle->GetEvent();
0126 std::unique_ptr<HepMC3::GenEvent> genEvent = std::make_unique<HepMC3::GenEvent>();
0127 genEvent->read_data(*genEventData);
0128
0129 if (!rivetAnalysis_ || !rivetAnalysis_->hasProjection("FS")) {
0130 rivetAnalysis_ = new Rivet::RivetAnalysis(pset_);
0131 analysisHandler_ = std::make_unique<Rivet::AnalysisHandler>();
0132
0133 analysisHandler_->setCheckBeams(false);
0134 analysisHandler_->addAnalysis(rivetAnalysis_);
0135 }
0136
0137 analysisHandler_->analyze(const_cast<GenEvent&>(*genEvent));
0138
0139
0140
0141 for (auto const& p : rivetAnalysis_->neutrinos()) {
0142 neutrinos->push_back(reco::GenParticle(p.charge(), p4(p), genVertex_, p.pid(), 1, true));
0143 }
0144 std::sort(neutrinos->begin(), neutrinos->end(), GreaterByPt<reco::Candidate>());
0145
0146
0147 for (auto const& p : rivetAnalysis_->photons()) {
0148 photons->push_back(reco::GenParticle(p.charge(), p4(p), genVertex_, p.pid(), 1, true));
0149 }
0150 std::sort(photons->begin(), photons->end(), GreaterByPt<reco::Candidate>());
0151
0152
0153 int iConstituent = -1;
0154 int iTag = -1;
0155 for (auto const& lepton : rivetAnalysis_->leptons()) {
0156 reco::GenJet lepJet;
0157 lepJet.setP4(p4(lepton));
0158 lepJet.setVertex(genVertex_);
0159 lepJet.setPdgId(lepton.pid());
0160 lepJet.setCharge(lepton.charge());
0161
0162 for (auto const& p : lepton.constituents()) {
0163
0164 if (p.abspid() == 15) {
0165 tags->push_back(reco::GenParticle(p.charge(), p4(p), genVertex_, p.pid(), 2, true));
0166 lepJet.addDaughter(edm::refToPtr(reco::GenParticleRef(tagsRefHandle, ++iTag)));
0167 }
0168
0169 else {
0170 consts->push_back(reco::GenParticle(p.charge(), p4(p), genVertex_, p.pid(), 1, true));
0171 lepJet.addDaughter(edm::refToPtr(reco::GenParticleRef(constsRefHandle, ++iConstituent)));
0172 }
0173 }
0174
0175 leptons->push_back(lepJet);
0176 }
0177 std::sort(leptons->begin(), leptons->end(), GreaterByPt<reco::GenJet>());
0178
0179
0180 for (const auto& jet : rivetAnalysis_->jets()) {
0181 addGenJet(jet, jets, consts, constsRefHandle, iConstituent, tags, tagsRefHandle, iTag);
0182 }
0183 for (const auto& jet : rivetAnalysis_->fatjets()) {
0184 addGenJet(jet, fatjets, consts, constsRefHandle, iConstituent, tags, tagsRefHandle, iTag);
0185 }
0186
0187
0188 reco::Candidate::LorentzVector metP4(rivetAnalysis_->met().x(),
0189 rivetAnalysis_->met().y(),
0190 0.,
0191 sqrt(pow(rivetAnalysis_->met().x(), 2) + pow(rivetAnalysis_->met().y(), 2)));
0192 mets->push_back(reco::MET(metP4, genVertex_));
0193
0194 event.put(std::move(neutrinos), "neutrinos");
0195 event.put(std::move(photons), "photons");
0196 event.put(std::move(leptons), "leptons");
0197 event.put(std::move(jets), "jets");
0198 event.put(std::move(fatjets), "fatjets");
0199 event.put(std::move(consts), "consts");
0200 event.put(std::move(tags), "tags");
0201 event.put(std::move(mets), "mets");
0202 }
0203
0204 DEFINE_FWK_MODULE(ParticleLevelProducer);