File indexing completed on 2024-10-23 22:47:56
0001 #include "FWCore/Framework/interface/Frameworkfwd.h"
0002 #include "FWCore/Framework/interface/stream/EDProducer.h"
0003
0004 #include "FWCore/Framework/interface/Event.h"
0005 #include "FWCore/Framework/interface/EventSetup.h"
0006 #include "FWCore/Framework/interface/ESHandle.h"
0007 #include "FWCore/Framework/interface/Run.h"
0008 #include "FWCore/Framework/interface/MakerMacros.h"
0009
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/Utilities/interface/InputTag.h"
0012 #include "DataFormats/Common/interface/Handle.h"
0013
0014 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0015 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
0016 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0017 #include "SimDataFormats/GeneratorProducts/interface/HepMC3Product.h"
0018 #include "SimDataFormats/GeneratorProducts/interface/GenRunInfoProduct.h"
0019 #include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
0020 #include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h"
0021
0022 #include "HepMC3/GenParticle.h"
0023 #include "HepMC3/GenVertex.h"
0024 #include "HepMC3/Print.h"
0025
0026 #include <iostream>
0027 #include <map>
0028
0029 using namespace std;
0030
0031 class GenParticles2HepMCConverter : public edm::stream::EDProducer<> {
0032 public:
0033 explicit GenParticles2HepMCConverter(const edm::ParameterSet& pset);
0034 ~GenParticles2HepMCConverter() override {}
0035
0036 void beginRun(edm::Run const& iRun, edm::EventSetup const&) override;
0037 void produce(edm::Event& event, const edm::EventSetup& eventSetup) override;
0038
0039 private:
0040 edm::EDGetTokenT<reco::CandidateView> genParticlesToken_;
0041 edm::EDGetTokenT<GenEventInfoProduct> genEventInfoToken_;
0042 edm::EDGetTokenT<GenRunInfoProduct> genRunInfoToken_;
0043 edm::ESGetToken<HepPDT::ParticleDataTable, PDTRecord> pTable_;
0044
0045 const double cmEnergy_;
0046 HepMC3::GenCrossSectionPtr xsec_;
0047
0048 private:
0049 inline HepMC3::FourVector FourVector(const reco::Candidate::Point& point) {
0050 return HepMC3::FourVector(10 * point.x(), 10 * point.y(), 10 * point.z(), 0);
0051 };
0052
0053 inline HepMC3::FourVector FourVector(const reco::Candidate::LorentzVector& lvec) {
0054
0055 return HepMC3::FourVector(lvec.px(), lvec.py(), lvec.pz(), std::hypot(lvec.P(), std::max(0., lvec.mass())));
0056 };
0057 };
0058
0059 GenParticles2HepMCConverter::GenParticles2HepMCConverter(const edm::ParameterSet& pset)
0060
0061 : cmEnergy_(pset.getUntrackedParameter<double>("cmEnergy", 13000)) {
0062 genParticlesToken_ = consumes<reco::CandidateView>(pset.getParameter<edm::InputTag>("genParticles"));
0063 genEventInfoToken_ = consumes<GenEventInfoProduct>(pset.getParameter<edm::InputTag>("genEventInfo"));
0064 genRunInfoToken_ = consumes<GenRunInfoProduct, edm::InRun>(pset.getParameter<edm::InputTag>("genEventInfo"));
0065 pTable_ = esConsumes<HepPDT::ParticleDataTable, PDTRecord>();
0066
0067 produces<edm::HepMC3Product>("unsmeared");
0068 }
0069
0070 void GenParticles2HepMCConverter::beginRun(edm::Run const& iRun, edm::EventSetup const&) {
0071 edm::Handle<GenRunInfoProduct> genRunInfoHandle;
0072 iRun.getByToken(genRunInfoToken_, genRunInfoHandle);
0073
0074 xsec_ = make_shared<HepMC3::GenCrossSection>();
0075 if (genRunInfoHandle.isValid()) {
0076 xsec_->set_cross_section(genRunInfoHandle->internalXSec().value(), genRunInfoHandle->internalXSec().error());
0077 } else {
0078
0079 xsec_->set_cross_section(1., 0.);
0080 }
0081 }
0082
0083 void GenParticles2HepMCConverter::produce(edm::Event& event, const edm::EventSetup& eventSetup) {
0084 edm::Handle<reco::CandidateView> genParticlesHandle;
0085 event.getByToken(genParticlesToken_, genParticlesHandle);
0086
0087 edm::Handle<GenEventInfoProduct> genEventInfoHandle;
0088 event.getByToken(genEventInfoToken_, genEventInfoHandle);
0089
0090 auto const& pTableData = eventSetup.getData(pTable_);
0091
0092 HepMC3::GenEvent hepmc_event;
0093 hepmc_event.set_event_number(event.id().event());
0094 hepmc_event.add_attribute("signal_process_id",
0095 std::make_shared<HepMC3::IntAttribute>(genEventInfoHandle->signalProcessID()));
0096 hepmc_event.add_attribute("event_scale", std::make_shared<HepMC3::DoubleAttribute>(genEventInfoHandle->qScale()));
0097 hepmc_event.add_attribute("alphaQCD", std::make_shared<HepMC3::DoubleAttribute>(genEventInfoHandle->alphaQCD()));
0098 hepmc_event.add_attribute("alphaQED", std::make_shared<HepMC3::DoubleAttribute>(genEventInfoHandle->alphaQED()));
0099
0100 hepmc_event.weights() = genEventInfoHandle->weights();
0101
0102 if (hepmc_event.weights().size() == 0) {
0103 hepmc_event.weights().push_back(1.);
0104 }
0105
0106
0107 if (xsec_->xsecs().size() < hepmc_event.weights().size()) {
0108 xsec_->set_cross_section(std::vector<double>(hepmc_event.weights().size(), xsec_->xsec(0)),
0109 std::vector<double>(hepmc_event.weights().size(), xsec_->xsec_err(0)));
0110 }
0111 hepmc_event.set_cross_section(xsec_);
0112
0113
0114 const gen::PdfInfo* pdf = genEventInfoHandle->pdf();
0115 if (pdf != nullptr) {
0116 const int pdf_id1 = pdf->id.first, pdf_id2 = pdf->id.second;
0117 const double pdf_x1 = pdf->x.first, pdf_x2 = pdf->x.second;
0118 const double pdf_scalePDF = pdf->scalePDF;
0119 const double pdf_xPDF1 = pdf->xPDF.first, pdf_xPDF2 = pdf->xPDF.second;
0120 HepMC3::GenPdfInfoPtr hepmc_pdfInfo = make_shared<HepMC3::GenPdfInfo>();
0121 hepmc_pdfInfo->set(pdf_id1, pdf_id2, pdf_x1, pdf_x2, pdf_scalePDF, pdf_xPDF1, pdf_xPDF2);
0122 hepmc_event.set_pdf_info(hepmc_pdfInfo);
0123 }
0124
0125
0126 std::map<const reco::Candidate*, HepMC3::GenParticlePtr> genCandToHepMCMap;
0127 HepMC3::GenParticlePtr hepmc_parton1, hepmc_parton2;
0128 std::vector<HepMC3::GenParticlePtr> hepmc_particles;
0129 const reco::Candidate *parton1 = nullptr, *parton2 = nullptr;
0130 for (unsigned int i = 0, n = genParticlesHandle->size(); i < n; ++i) {
0131 const reco::Candidate* p = &genParticlesHandle->at(i);
0132 HepMC3::GenParticlePtr hepmc_particle =
0133 std::make_shared<HepMC3::GenParticle>(FourVector(p->p4()), p->pdgId(), p->status());
0134
0135
0136 double particleMass;
0137 if (pTableData.particle(p->pdgId()))
0138 particleMass = pTableData.particle(p->pdgId())->mass();
0139 else
0140 particleMass = p->mass();
0141
0142 hepmc_particle->set_generated_mass(particleMass);
0143
0144 hepmc_particles.push_back(hepmc_particle);
0145 genCandToHepMCMap[p] = hepmc_particle;
0146
0147
0148 if (p->mother() == nullptr and std::abs(p->eta()) > 5 and std::abs(p->pz()) > 1000) {
0149 if (!parton1 and p->pz() > 0) {
0150 parton1 = p;
0151 hepmc_parton1 = hepmc_particle;
0152 } else if (!parton2 and p->pz() < 0) {
0153 parton2 = p;
0154 hepmc_parton2 = hepmc_particle;
0155 }
0156 }
0157 }
0158
0159 HepMC3::GenVertexPtr vertex1;
0160 HepMC3::GenVertexPtr vertex2;
0161 if (parton1 == nullptr || parton2 == nullptr) {
0162
0163
0164 const reco::Candidate::LorentzVector nullP4(0, 0, 0, 0);
0165 const reco::Candidate::LorentzVector beamP4(0, 0, cmEnergy_ / 2, cmEnergy_ / 2);
0166 vertex1 = make_shared<HepMC3::GenVertex>(FourVector(nullP4));
0167 vertex2 = make_shared<HepMC3::GenVertex>(FourVector(nullP4));
0168 hepmc_parton1 = make_shared<HepMC3::GenParticle>(FourVector(+beamP4), 2212, 4);
0169 hepmc_parton2 = make_shared<HepMC3::GenParticle>(FourVector(-beamP4), 2212, 4);
0170 } else {
0171
0172 vertex1 = make_shared<HepMC3::GenVertex>(FourVector(parton1->vertex()));
0173 vertex2 = make_shared<HepMC3::GenVertex>(FourVector(parton2->vertex()));
0174 }
0175 hepmc_event.add_vertex(vertex1);
0176 hepmc_event.add_vertex(vertex2);
0177 vertex1->add_particle_in(hepmc_parton1);
0178 vertex2->add_particle_in(hepmc_parton2);
0179
0180
0181
0182 typedef std::map<const reco::Candidate*, HepMC3::GenVertexPtr> ParticleToVertexMap;
0183 ParticleToVertexMap particleToVertexMap;
0184 particleToVertexMap[parton1] = vertex1;
0185 particleToVertexMap[parton2] = vertex2;
0186 for (unsigned int i = 0, n = genParticlesHandle->size(); i < n; ++i) {
0187 const reco::Candidate* p = &genParticlesHandle->at(i);
0188 if (p == parton1 or p == parton2)
0189 continue;
0190
0191
0192 for (unsigned int j = 0, nMothers = p->numberOfMothers(); j < nMothers; ++j) {
0193
0194 const reco::Candidate* elder = p->mother(j)->daughter(0);
0195 HepMC3::GenVertexPtr vertex;
0196 if (particleToVertexMap.find(elder) == particleToVertexMap.end()) {
0197 vertex = make_shared<HepMC3::GenVertex>(FourVector(elder->vertex()));
0198 hepmc_event.add_vertex(vertex);
0199 particleToVertexMap[elder] = vertex;
0200 } else {
0201 vertex = particleToVertexMap[elder];
0202 }
0203
0204
0205 const reco::Candidate* mother = p->mother(j);
0206 vertex->add_particle_in(genCandToHepMCMap[mother]);
0207 vertex->add_particle_out(hepmc_particles[i]);
0208 }
0209 }
0210
0211
0212 auto hepmc_product = std::make_unique<edm::HepMC3Product>(&hepmc_event);
0213 event.put(std::move(hepmc_product), "unsmeared");
0214 }
0215
0216 DEFINE_FWK_MODULE(GenParticles2HepMCConverter);