File indexing completed on 2023-10-25 09:48:57
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/HepMCProduct.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 <iostream>
0023 #include <map>
0024
0025 using namespace std;
0026
0027 class GenParticles2HepMCConverter : public edm::stream::EDProducer<> {
0028 public:
0029 explicit GenParticles2HepMCConverter(const edm::ParameterSet& pset);
0030 ~GenParticles2HepMCConverter() override{};
0031
0032 void beginRun(edm::Run const& iRun, edm::EventSetup const&) override;
0033 void produce(edm::Event& event, const edm::EventSetup& eventSetup) override;
0034
0035 private:
0036 edm::EDGetTokenT<reco::CandidateView> genParticlesToken_;
0037 edm::EDGetTokenT<GenEventInfoProduct> genEventInfoToken_;
0038 edm::EDGetTokenT<GenRunInfoProduct> genRunInfoToken_;
0039 edm::ESGetToken<HepPDT::ParticleDataTable, PDTRecord> pTable_;
0040
0041 std::vector<int> signalParticlePdgIds_;
0042 const double cmEnergy_;
0043 HepMC::GenCrossSection xsec_;
0044
0045 private:
0046 inline HepMC::FourVector FourVector(const reco::Candidate::Point& point) {
0047 return HepMC::FourVector(10 * point.x(), 10 * point.y(), 10 * point.z(), 0);
0048 };
0049
0050 inline HepMC::FourVector FourVector(const reco::Candidate::LorentzVector& lvec) {
0051
0052 return HepMC::FourVector(lvec.px(), lvec.py(), lvec.pz(), std::hypot(lvec.P(), std::max(0., lvec.mass())));
0053 };
0054 };
0055
0056 GenParticles2HepMCConverter::GenParticles2HepMCConverter(const edm::ParameterSet& pset)
0057
0058 : cmEnergy_(pset.getUntrackedParameter<double>("cmEnergy", 13000)) {
0059 genParticlesToken_ = consumes<reco::CandidateView>(pset.getParameter<edm::InputTag>("genParticles"));
0060 genEventInfoToken_ = consumes<GenEventInfoProduct>(pset.getParameter<edm::InputTag>("genEventInfo"));
0061 genRunInfoToken_ = consumes<GenRunInfoProduct, edm::InRun>(pset.getParameter<edm::InputTag>("genEventInfo"));
0062 pTable_ = esConsumes<HepPDT::ParticleDataTable, PDTRecord>();
0063 signalParticlePdgIds_ = pset.getParameter<std::vector<int>>("signalParticlePdgIds");
0064
0065 produces<edm::HepMCProduct>("unsmeared");
0066 }
0067
0068 void GenParticles2HepMCConverter::beginRun(edm::Run const& iRun, edm::EventSetup const&) {
0069 edm::Handle<GenRunInfoProduct> genRunInfoHandle;
0070 iRun.getByToken(genRunInfoToken_, genRunInfoHandle);
0071
0072 xsec_.set_cross_section(genRunInfoHandle->internalXSec().value(), genRunInfoHandle->internalXSec().error());
0073 }
0074
0075 void GenParticles2HepMCConverter::produce(edm::Event& event, const edm::EventSetup& eventSetup) {
0076 edm::Handle<reco::CandidateView> genParticlesHandle;
0077 event.getByToken(genParticlesToken_, genParticlesHandle);
0078
0079 edm::Handle<GenEventInfoProduct> genEventInfoHandle;
0080 event.getByToken(genEventInfoToken_, genEventInfoHandle);
0081
0082 auto const& pTableData = eventSetup.getData(pTable_);
0083
0084 HepMC::GenEvent* hepmc_event = new HepMC::GenEvent();
0085 hepmc_event->set_event_number(event.id().event());
0086 hepmc_event->set_signal_process_id(genEventInfoHandle->signalProcessID());
0087 hepmc_event->set_event_scale(genEventInfoHandle->qScale());
0088 hepmc_event->set_alphaQED(genEventInfoHandle->alphaQED());
0089 hepmc_event->set_alphaQCD(genEventInfoHandle->alphaQCD());
0090
0091 hepmc_event->weights() = genEventInfoHandle->weights();
0092
0093 hepmc_event->set_cross_section(xsec_);
0094
0095
0096 const gen::PdfInfo* pdf = genEventInfoHandle->pdf();
0097 if (pdf != nullptr) {
0098 const int pdf_id1 = pdf->id.first, pdf_id2 = pdf->id.second;
0099 const double pdf_x1 = pdf->x.first, pdf_x2 = pdf->x.second;
0100 const double pdf_scalePDF = pdf->scalePDF;
0101 const double pdf_xPDF1 = pdf->xPDF.first, pdf_xPDF2 = pdf->xPDF.second;
0102 HepMC::PdfInfo hepmc_pdfInfo(pdf_id1, pdf_id2, pdf_x1, pdf_x2, pdf_scalePDF, pdf_xPDF1, pdf_xPDF2);
0103 hepmc_event->set_pdf_info(hepmc_pdfInfo);
0104 }
0105
0106
0107 std::map<const reco::Candidate*, HepMC::GenParticle*> genCandToHepMCMap;
0108 HepMC::GenParticle *hepmc_parton1 = nullptr, *hepmc_parton2 = nullptr;
0109 std::vector<HepMC::GenParticle*> hepmc_particles;
0110 const reco::Candidate *parton1 = nullptr, *parton2 = nullptr;
0111 for (unsigned int i = 0, n = genParticlesHandle->size(); i < n; ++i) {
0112 const reco::Candidate* p = &genParticlesHandle->at(i);
0113 HepMC::GenParticle* hepmc_particle = new HepMC::GenParticle(FourVector(p->p4()), p->pdgId(), p->status());
0114 hepmc_particle->suggest_barcode(i + 1);
0115
0116
0117 double particleMass;
0118 if (pTableData.particle(p->pdgId()))
0119 particleMass = pTableData.particle(p->pdgId())->mass();
0120 else
0121 particleMass = p->mass();
0122
0123 hepmc_particle->set_generated_mass(particleMass);
0124
0125 hepmc_particles.push_back(hepmc_particle);
0126 genCandToHepMCMap[p] = hepmc_particle;
0127
0128
0129 if (p->mother() == nullptr and std::abs(p->eta()) > 5 and std::abs(p->pz()) > 1000) {
0130 if (!parton1 and p->pz() > 0) {
0131 parton1 = p;
0132 hepmc_parton1 = hepmc_particle;
0133 } else if (!parton2 and p->pz() < 0) {
0134 parton2 = p;
0135 hepmc_parton2 = hepmc_particle;
0136 }
0137 }
0138 }
0139
0140 HepMC::GenVertex* vertex1 = nullptr;
0141 HepMC::GenVertex* vertex2 = nullptr;
0142 if (parton1 == nullptr || parton2 == nullptr) {
0143
0144
0145 const reco::Candidate::LorentzVector nullP4(0, 0, 0, 0);
0146 const reco::Candidate::LorentzVector beamP4(0, 0, cmEnergy_ / 2, cmEnergy_ / 2);
0147 vertex1 = new HepMC::GenVertex(FourVector(nullP4));
0148 vertex2 = new HepMC::GenVertex(FourVector(nullP4));
0149 hepmc_parton1 = new HepMC::GenParticle(FourVector(+beamP4), 2212, 4);
0150 hepmc_parton2 = new HepMC::GenParticle(FourVector(-beamP4), 2212, 4);
0151 } else {
0152
0153 vertex1 = new HepMC::GenVertex(FourVector(parton1->vertex()));
0154 vertex2 = new HepMC::GenVertex(FourVector(parton2->vertex()));
0155 }
0156 hepmc_event->add_vertex(vertex1);
0157 hepmc_event->add_vertex(vertex2);
0158 vertex1->add_particle_in(hepmc_parton1);
0159 vertex2->add_particle_in(hepmc_parton2);
0160
0161
0162
0163 typedef std::map<const reco::Candidate*, HepMC::GenVertex*> ParticleToVertexMap;
0164 ParticleToVertexMap particleToVertexMap;
0165 particleToVertexMap[parton1] = vertex1;
0166 particleToVertexMap[parton2] = vertex2;
0167 for (unsigned int i = 0, n = genParticlesHandle->size(); i < n; ++i) {
0168 const reco::Candidate* p = &genParticlesHandle->at(i);
0169 if (p == parton1 or p == parton2)
0170 continue;
0171
0172
0173 for (unsigned int j = 0, nMothers = p->numberOfMothers(); j < nMothers; ++j) {
0174
0175 const reco::Candidate* elder = p->mother(j)->daughter(0);
0176 HepMC::GenVertex* vertex;
0177 if (particleToVertexMap.find(elder) == particleToVertexMap.end()) {
0178 vertex = new HepMC::GenVertex(FourVector(elder->vertex()));
0179 hepmc_event->add_vertex(vertex);
0180 particleToVertexMap[elder] = vertex;
0181 } else {
0182 vertex = particleToVertexMap[elder];
0183 }
0184
0185
0186 const reco::Candidate* mother = p->mother(j);
0187 vertex->add_particle_in(genCandToHepMCMap[mother]);
0188 vertex->add_particle_out(hepmc_particles[i]);
0189 }
0190 }
0191
0192
0193 bool hasSignalVertex = false;
0194 if (!signalParticlePdgIds_.empty()) {
0195
0196 for (auto v = hepmc_event->vertices_begin(); v != hepmc_event->vertices_end(); ++v) {
0197 for (auto p = (*v)->particles_begin(HepMC::children); p != (*v)->particles_end(HepMC::children); ++p) {
0198 const int pdgId = (*p)->pdg_id();
0199 if (std::find(signalParticlePdgIds_.begin(), signalParticlePdgIds_.end(), pdgId) !=
0200 signalParticlePdgIds_.end()) {
0201 hepmc_event->set_signal_process_vertex(*v);
0202 hasSignalVertex = true;
0203 break;
0204 }
0205 }
0206 if (hasSignalVertex)
0207 break;
0208 }
0209 }
0210
0211 if (!hasSignalVertex)
0212 hepmc_event->set_signal_process_vertex(*(vertex1->vertices_begin()));
0213
0214 std::unique_ptr<edm::HepMCProduct> hepmc_product(new edm::HepMCProduct());
0215 hepmc_product->addHepMCData(hepmc_event);
0216 event.put(std::move(hepmc_product), "unsmeared");
0217 }
0218
0219 DEFINE_FWK_MODULE(GenParticles2HepMCConverter);