CMS 3D CMS Logo

GenParticles2HepMCConverter.cc
Go to the documentation of this file.
3 
9 
13 
21 
22 #include "HepMC3/GenParticle.h"
23 #include "HepMC3/GenVertex.h"
24 #include "HepMC3/Print.h"
25 
26 #include <iostream>
27 #include <map>
28 
29 using namespace std;
30 
32 public:
35 
36  void beginRun(edm::Run const& iRun, edm::EventSetup const&) override;
37  void produce(edm::Event& event, const edm::EventSetup& eventSetup) override;
38 
39 private:
44 
45  const double cmEnergy_;
46  HepMC3::GenCrossSectionPtr xsec_;
47 
48 private:
49  inline HepMC3::FourVector FourVector(const reco::Candidate::Point& point) {
50  return HepMC3::FourVector(10 * point.x(), 10 * point.y(), 10 * point.z(), 0);
51  };
52 
53  inline HepMC3::FourVector FourVector(const reco::Candidate::LorentzVector& lvec) {
54  // Avoid negative mass, set minimum m^2 = 0
55  return HepMC3::FourVector(lvec.px(), lvec.py(), lvec.pz(), std::hypot(lvec.P(), std::max(0., lvec.mass())));
56  };
57 };
58 
60  // dummy value to set incident proton pz for particle gun samples
61  : cmEnergy_(pset.getUntrackedParameter<double>("cmEnergy", 13000)) {
62  genParticlesToken_ = consumes<reco::CandidateView>(pset.getParameter<edm::InputTag>("genParticles"));
63  genEventInfoToken_ = consumes<GenEventInfoProduct>(pset.getParameter<edm::InputTag>("genEventInfo"));
64  genRunInfoToken_ = consumes<GenRunInfoProduct, edm::InRun>(pset.getParameter<edm::InputTag>("genEventInfo"));
65  pTable_ = esConsumes<HepPDT::ParticleDataTable, PDTRecord>();
66 
67  produces<edm::HepMC3Product>("unsmeared");
68 }
69 
71  edm::Handle<GenRunInfoProduct> genRunInfoHandle;
72  iRun.getByToken(genRunInfoToken_, genRunInfoHandle);
73 
74  xsec_ = make_shared<HepMC3::GenCrossSection>();
75  if (genRunInfoHandle.isValid()) {
76  xsec_->set_cross_section(genRunInfoHandle->internalXSec().value(), genRunInfoHandle->internalXSec().error());
77  } else {
78  // dummy cross section
79  xsec_->set_cross_section(1., 0.);
80  }
81 }
82 
84  edm::Handle<reco::CandidateView> genParticlesHandle;
85  event.getByToken(genParticlesToken_, genParticlesHandle);
86 
87  edm::Handle<GenEventInfoProduct> genEventInfoHandle;
88  event.getByToken(genEventInfoToken_, genEventInfoHandle);
89 
90  auto const& pTableData = eventSetup.getData(pTable_);
91 
92  HepMC3::GenEvent* hepmc_event = new HepMC3::GenEvent();
93  hepmc_event->set_event_number(event.id().event());
94  hepmc_event->add_attribute("signal_process_id",
95  std::make_shared<HepMC3::IntAttribute>(genEventInfoHandle->signalProcessID()));
96  hepmc_event->add_attribute("event_scale", std::make_shared<HepMC3::DoubleAttribute>(genEventInfoHandle->qScale()));
97  hepmc_event->add_attribute("alphaQCD", std::make_shared<HepMC3::DoubleAttribute>(genEventInfoHandle->alphaQCD()));
98  hepmc_event->add_attribute("alphaQED", std::make_shared<HepMC3::DoubleAttribute>(genEventInfoHandle->alphaQED()));
99 
100  hepmc_event->weights() = genEventInfoHandle->weights();
101  // add dummy weight if necessary
102  if (hepmc_event->weights().size() == 0) {
103  hepmc_event->weights().push_back(1.);
104  }
105 
106  // resize cross section to number of weights
107  if (xsec_->xsecs().size() < hepmc_event->weights().size()) {
108  xsec_->set_cross_section(std::vector<double>(hepmc_event->weights().size(), xsec_->xsec(0)),
109  std::vector<double>(hepmc_event->weights().size(), xsec_->xsec_err(0)));
110  }
111  hepmc_event->set_cross_section(xsec_);
112 
113  // Set PDF
114  const gen::PdfInfo* pdf = genEventInfoHandle->pdf();
115  if (pdf != nullptr) {
116  const int pdf_id1 = pdf->id.first, pdf_id2 = pdf->id.second;
117  const double pdf_x1 = pdf->x.first, pdf_x2 = pdf->x.second;
118  const double pdf_scalePDF = pdf->scalePDF;
119  const double pdf_xPDF1 = pdf->xPDF.first, pdf_xPDF2 = pdf->xPDF.second;
120  HepMC3::GenPdfInfoPtr hepmc_pdfInfo = make_shared<HepMC3::GenPdfInfo>();
121  hepmc_pdfInfo->set(pdf_id1, pdf_id2, pdf_x1, pdf_x2, pdf_scalePDF, pdf_xPDF1, pdf_xPDF2);
122  hepmc_event->set_pdf_info(hepmc_pdfInfo);
123  }
124 
125  // Prepare list of HepMC3::GenParticles
126  std::map<const reco::Candidate*, HepMC3::GenParticlePtr> genCandToHepMCMap;
127  HepMC3::GenParticlePtr hepmc_parton1, hepmc_parton2;
128  std::vector<HepMC3::GenParticlePtr> hepmc_particles;
129  const reco::Candidate *parton1 = nullptr, *parton2 = nullptr;
130  for (unsigned int i = 0, n = genParticlesHandle->size(); i < n; ++i) {
131  const reco::Candidate* p = &genParticlesHandle->at(i);
132  HepMC3::GenParticlePtr hepmc_particle =
133  std::make_shared<HepMC3::GenParticle>(FourVector(p->p4()), p->pdgId(), p->status());
134 
135  // Assign particle's generated mass from the standard particle data table
136  double particleMass;
137  if (pTableData.particle(p->pdgId()))
138  particleMass = pTableData.particle(p->pdgId())->mass();
139  else
140  particleMass = p->mass();
141 
142  hepmc_particle->set_generated_mass(particleMass);
143 
144  hepmc_particles.push_back(hepmc_particle);
145  genCandToHepMCMap[p] = hepmc_particle;
146 
147  // Find incident proton pair
148  if (p->mother() == nullptr and std::abs(p->eta()) > 5 and std::abs(p->pz()) > 1000) {
149  if (!parton1 and p->pz() > 0) {
150  parton1 = p;
151  hepmc_parton1 = hepmc_particle;
152  } else if (!parton2 and p->pz() < 0) {
153  parton2 = p;
154  hepmc_parton2 = hepmc_particle;
155  }
156  }
157  }
158 
159  HepMC3::GenVertexPtr vertex1;
160  HepMC3::GenVertexPtr vertex2;
161  if (parton1 == nullptr || parton2 == nullptr) {
162  // Particle gun samples do not have incident partons. Put dummy incident particle and prod vertex
163  // Note: leave parton1 and parton2 as nullptr since it is not used anymore after creating hepmc_parton1 and 2
164  const reco::Candidate::LorentzVector nullP4(0, 0, 0, 0);
165  const reco::Candidate::LorentzVector beamP4(0, 0, cmEnergy_ / 2, cmEnergy_ / 2);
166  vertex1 = make_shared<HepMC3::GenVertex>(FourVector(nullP4));
167  vertex2 = make_shared<HepMC3::GenVertex>(FourVector(nullP4));
168  hepmc_parton1 = make_shared<HepMC3::GenParticle>(FourVector(+beamP4), 2212, 4);
169  hepmc_parton2 = make_shared<HepMC3::GenParticle>(FourVector(-beamP4), 2212, 4);
170  } else {
171  // Put incident beam particles : proton -> parton vertex
172  vertex1 = make_shared<HepMC3::GenVertex>(FourVector(parton1->vertex()));
173  vertex2 = make_shared<HepMC3::GenVertex>(FourVector(parton2->vertex()));
174  }
175  hepmc_event->add_vertex(vertex1);
176  hepmc_event->add_vertex(vertex2);
177  vertex1->add_particle_in(hepmc_parton1);
178  vertex2->add_particle_in(hepmc_parton2);
179  //hepmc_event->set_beam_particles(hepmc_parton1, hepmc_parton2);
180 
181  // Prepare vertex list
182  typedef std::map<const reco::Candidate*, HepMC3::GenVertexPtr> ParticleToVertexMap;
183  ParticleToVertexMap particleToVertexMap;
184  particleToVertexMap[parton1] = vertex1;
185  particleToVertexMap[parton2] = vertex2;
186  for (unsigned int i = 0, n = genParticlesHandle->size(); i < n; ++i) {
187  const reco::Candidate* p = &genParticlesHandle->at(i);
188  if (p == parton1 or p == parton2)
189  continue;
190 
191  // Connect mother-daughters for the other cases
192  for (unsigned int j = 0, nMothers = p->numberOfMothers(); j < nMothers; ++j) {
193  // Mother-daughter hierarchy defines vertex
194  const reco::Candidate* elder = p->mother(j)->daughter(0);
195  HepMC3::GenVertexPtr vertex;
196  if (particleToVertexMap.find(elder) == particleToVertexMap.end()) {
197  vertex = make_shared<HepMC3::GenVertex>(FourVector(elder->vertex()));
198  hepmc_event->add_vertex(vertex);
199  particleToVertexMap[elder] = vertex;
200  } else {
201  vertex = particleToVertexMap[elder];
202  }
203 
204  // Vertex is found. Now connect each other
205  const reco::Candidate* mother = p->mother(j);
206  vertex->add_particle_in(genCandToHepMCMap[mother]);
207  vertex->add_particle_out(hepmc_particles[i]);
208  }
209  }
210 
211  // Finalize HepMC event record
212  std::unique_ptr<edm::HepMC3Product> hepmc_product(new edm::HepMC3Product());
213  hepmc_product->addHepMCData(hepmc_event);
214  event.put(std::move(hepmc_product), "unsmeared");
215 }
216 
void produce(edm::Event &event, const edm::EventSetup &eventSetup) override
edm::EDGetTokenT< GenRunInfoProduct > genRunInfoToken_
edm::EDGetTokenT< GenEventInfoProduct > genEventInfoToken_
MPlex< T, D1, D2, N > hypot(const MPlex< T, D1, D2, N > &a, const MPlex< T, D1, D2, N > &b)
Definition: Matriplex.h:436
const XSec & internalXSec() const
void beginRun(edm::Run const &iRun, edm::EventSetup const &) override
std::pair< double, double > x
Definition: PdfInfo.h:13
edm::EDGetTokenT< reco::CandidateView > genParticlesToken_
size_type size() const
edm::ESGetToken< HepPDT::ParticleDataTable, PDTRecord > pTable_
std::pair< double, double > xPDF
Definition: PdfInfo.h:14
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
virtual const Point & vertex() const =0
vertex position
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
unsigned int signalProcessID() const
const_reference at(size_type pos) const
edm::Ptr< GenParticle > GenParticlePtr
persistent reference to a GenParticle
std::pair< int, int > id
Definition: PdfInfo.h:12
HepMC3::FourVector FourVector(const reco::Candidate::Point &point)
HepMC3::FourVector FourVector(const reco::Candidate::LorentzVector &lvec)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Run.h:313
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
const PDF * pdf() const
bool isValid() const
Definition: HandleBase.h:70
std::vector< double > & weights()
math::XYZPoint Point
point in the space
Definition: Candidate.h:40
GenParticles2HepMCConverter(const edm::ParameterSet &pset)
double scalePDF
Definition: PdfInfo.h:15
def move(src, dest)
Definition: eostools.py:511
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
Definition: event.py:1
Definition: Run.h:45