1 //--------------------------------------------------------------------------
4 // This software is part of the EvtGen package. If you use all or part
5 // of it, please give an appropriate acknowledgement.
7 // Copyright Information: See EvtGen/COPYRIGHT
8 // Copyright (C) 2011 University of Warwick, UK
10 // Module: EvtHepMCEvent
12 // Description: Create an HepMC::GenEvent for the complete EvtParticle
15 // Modification history:
17 // John Back June 2011 Module created
19 //------------------------------------------------------------------------
21 #include "EvtGenBase/EvtPatches.hh"
22 #include "EvtGenBase/EvtHepMCEvent.hh"
23 #include "EvtGenBase/EvtParticle.hh"
24 #include "EvtGenBase/EvtPDL.hh"
26 #include "HepMC/Units.h"
28 EvtHepMCEvent::EvtHepMCEvent() :
30 _translation(0.0, 0.0, 0.0, 0.0)
34 EvtHepMCEvent::~EvtHepMCEvent() {
38 void EvtHepMCEvent::deleteEvent() {
42 delete _theEvent; _theEvent = 0;
47 void EvtHepMCEvent::constructEvent(EvtParticle* baseParticle) {
49 EvtVector4R origin(0.0, 0.0, 0.0, 0.0);
50 this->constructEvent(baseParticle, origin);
54 void EvtHepMCEvent::constructEvent(EvtParticle* baseParticle, EvtVector4R& translation) {
56 // This class does not take ownership of the base particle pointer.
57 // Rather, it uses the base particle to construct the event.
60 if (baseParticle == 0) {return;}
62 _theEvent = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM);
63 _translation = translation;
65 // Use the recursive function addVertex to add a vertex with incoming/outgoing
66 // particles. Adds a new vertex for any EvtParticles with decay daughters.
67 // All particles are in the rest frame of the base particle ("lab frame").
69 HepMC::GenParticle* hepMCGenParticle = this->createGenParticle(baseParticle, EvtHepMCEvent::LAB);
71 this->addVertex(baseParticle, hepMCGenParticle);
75 HepMC::GenParticle* EvtHepMCEvent::createGenParticle(EvtParticle* theParticle, int frameType) {
77 // Create an HepMC GenParticle, with the 4-momenta in the frame given by the frameType integer
78 HepMC::GenParticle* genParticle = 0;
80 if (theParticle != 0) {
82 // Set the particle status integer to either stable or decayed
83 int status(EvtHepMCEvent::STABLE);
84 int nDaug = theParticle->getNDaug();
85 if (nDaug > 0) {status = EvtHepMCEvent::DECAYED;}
87 // Get the 4-momentum (E, px, py, pz) for the EvtParticle.
88 EvtVector4R p4(0.0, 0.0, 0.0, 0.0);
90 if (frameType == EvtHepMCEvent::RESTFRAME) {
91 p4 = theParticle->getP4Restframe();
92 } else if (frameType == EvtHepMCEvent::LAB) {
93 p4 = theParticle->getP4Lab();
95 p4 = theParticle->getP4();
98 // Convert this to the HepMC 4-momentum
100 double px = p4.get(1);
101 double py = p4.get(2);
102 double pz = p4.get(3);
104 HepMC::FourVector hepMC_p4(px, py, pz, E);
106 // Get the particle PDG integer id
107 int PDGInt = EvtPDL::getStdHep(theParticle->getId());
109 genParticle = new HepMC::GenParticle(hepMC_p4, PDGInt, status);
117 void EvtHepMCEvent::addVertex(EvtParticle* inEvtParticle, HepMC::GenParticle* inGenParticle) {
119 // This is a recursive function that adds GenVertices to the GenEvent for
120 // the incoming EvtParticle and its daughters. We use two separate
121 // pointers for the EvtParticle and GenParticle information: the former
122 // to obtain the PDGId, 4-momenta, daughter and vertex positions, the latter to
123 // set the incoming particle to the vertex. Note that the outgoing particle for
124 // one vertex might be the incoming particle for another vertex - this needs to
125 // be the same GenParticle pointer, hence the reason for using it as a 2nd argument
128 if (_theEvent == 0 || inEvtParticle == 0 || inGenParticle == 0) {return;}
130 // Create the decay vertex
131 HepMC::FourVector vtxCoord = this->getVertexCoord(inEvtParticle);
132 HepMC::GenVertex* theVertex = new HepMC::GenVertex(vtxCoord);
134 // Add the vertex to the event
135 _theEvent->add_vertex(theVertex);
137 // Set the incoming particle
138 theVertex->add_particle_in(inGenParticle);
140 // Set the outgoing particles (decay products)
141 int nDaug = inEvtParticle->getNDaug();
143 // Loop over the daughters
144 for (iDaug = 0; iDaug < nDaug; iDaug++) {
146 EvtParticle* evtDaughter = inEvtParticle->getDaug(iDaug);
147 HepMC::GenParticle* genDaughter = this->createGenParticle(evtDaughter, EvtHepMCEvent::LAB);
149 if (genDaughter != 0) {
151 // Add a new GenParticle (outgoing) particle daughter to the vertex
152 theVertex->add_particle_out(genDaughter);
154 // Find out if the daughter also has decay products.
155 // If so, recursively run this function again.
156 int nDaugProducts = evtDaughter->getNDaug();
158 if (nDaugProducts > 0) {
160 // Recursively process daughter particles and add their vertices to the event
161 this->addVertex(evtDaughter, genDaughter);
163 } // Have daughter products
165 } // hepMCDaughter != 0
167 } // Loop over daughters
171 HepMC::FourVector EvtHepMCEvent::getVertexCoord(EvtParticle* theParticle) {
173 HepMC::FourVector vertexCoord(0.0, 0.0, 0.0, 0.0);
175 if (theParticle != 0 && theParticle->getNDaug() != 0) {
177 // Get the position (t,x,y,z) of the EvtParticle, offset by the translation vector.
178 // This position will be the point where the particle decays. So we ask
179 // the position of the (1st) daughter particle.
180 EvtParticle* daugParticle = theParticle->getDaug(0);
182 if (daugParticle != 0) {
184 EvtVector4R vtxPosition = daugParticle->get4Pos() + _translation;
186 // Create the HepMC 4 vector of the position (x,y,z,t)
187 vertexCoord.setX(vtxPosition.get(1));
188 vertexCoord.setY(vtxPosition.get(2));
189 vertexCoord.setZ(vtxPosition.get(3));
190 vertexCoord.setT(vtxPosition.get(0));