Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HepMC3Event.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HepMC3Event.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
13 
14 namespace {
19 HepMC3::GenParticlePtr actsParticleToGen(
20  const std::shared_ptr<ActsExamples::SimParticle>& actsParticle) {
21  // Extract momentum and energy from Acts particle for HepMC3::FourVector
22  const auto mom4 = actsParticle->fourMomentum();
23  const HepMC3::FourVector vec(mom4[0], mom4[1], mom4[2], mom4[3]);
24  // Create HepMC3::GenParticle
25  auto genParticle =
26  std::make_shared<HepMC3::GenParticle>(vec, actsParticle->pdg());
27  genParticle->set_generated_mass(actsParticle->mass());
28 
29  return genParticle;
30 }
31 
36 HepMC3::GenVertexPtr createGenVertex(
37  const std::shared_ptr<ActsExamples::SimVertex>& actsVertex) {
38  const HepMC3::FourVector vec(
39  actsVertex->position4[0], actsVertex->position4[1],
40  actsVertex->position4[2], actsVertex->position4[3]);
41 
42  // Create vertex
43  auto genVertex = std::make_shared<HepMC3::GenVertex>(vec);
44 
45  // Store incoming particles
46  for (auto& particle : actsVertex->incoming) {
47  HepMC3::GenParticlePtr genParticle = actsParticleToGen(
48  std::make_shared<ActsExamples::SimParticle>(particle));
49  genVertex->add_particle_in(genParticle);
50  }
51  // Store outgoing particles
52  for (auto& particle : actsVertex->outgoing) {
53  HepMC3::GenParticlePtr genParticle = actsParticleToGen(
54  std::make_shared<ActsExamples::SimParticle>(particle));
55  genVertex->add_particle_out(genParticle);
56  }
57  return genVertex;
58 }
59 
70 bool compareVertices(const std::shared_ptr<ActsExamples::SimVertex>& actsVertex,
71  const HepMC3::GenVertexPtr& genVertex) {
72  // Compare position, time, number of incoming and outgoing particles between
73  // both vertices. Return false if one criterium does not match, else true.
74  HepMC3::FourVector genVec = genVertex->position();
75  if (actsVertex->position4[0] != genVec.x()) {
76  return false;
77  }
78  if (actsVertex->position4[1] != genVec.y()) {
79  return false;
80  }
81  if (actsVertex->position4[2] != genVec.z()) {
82  return false;
83  }
84  if (actsVertex->position4[3] != genVec.t()) {
85  return false;
86  }
87  if (actsVertex->incoming.size() != genVertex->particles_in().size()) {
88  return false;
89  }
90  if (actsVertex->outgoing.size() != genVertex->particles_out().size()) {
91  return false;
92  }
93  return true;
94 }
95 } // namespace
96 
100 
102  const double momentumUnit) {
103  // Check, if the momentum unit fits Acts::UnitConstants::MeV or _GeV
104  HepMC3::Units::MomentumUnit mom = HepMC3::Units::MomentumUnit::GEV;
105  if (momentumUnit == Acts::UnitConstants::MeV) {
106  mom = HepMC3::Units::MomentumUnit::MEV;
107  } else if (momentumUnit == Acts::UnitConstants::GeV) {
108  mom = HepMC3::Units::MomentumUnit::GEV;
109  } else {
110  // Report invalid momentum unit and set GeV
111  std::cout << "Invalid unit of momentum: " << momentumUnit << std::endl;
112  std::cout << "Momentum unit [GeV] will be used instead" << std::endl;
113  }
114  // Set units
115  event.set_units(mom, event.length_unit());
116 }
117 
119  const double lengthUnit) {
120  // Check, if the length unit fits Acts::UnitConstants::mm or _cm
121  HepMC3::Units::LengthUnit len = HepMC3::Units::LengthUnit::MM;
122  if (lengthUnit == Acts::UnitConstants::mm) {
123  len = HepMC3::Units::LengthUnit::MM;
124  } else if (lengthUnit == Acts::UnitConstants::cm) {
125  len = HepMC3::Units::LengthUnit::CM;
126  } else {
127  // Report invalid length unit and set mm
128  std::cout << "Invalid unit of length: " << lengthUnit << std::endl;
129  std::cout << "Length unit [mm] will be used instead" << std::endl;
130  }
131 
132  // Set units
133  event.set_units(event.momentum_unit(), len);
134 }
135 
137  const Acts::Vector3& deltaPos,
138  const double deltaTime) {
139  // Create HepMC3::FourVector from position and time for shift
140  const HepMC3::FourVector vec(deltaPos(0), deltaPos(1), deltaPos(2),
141  deltaTime);
142  event.shift_position_by(vec);
143 }
144 
146  const Acts::Vector3& pos,
147  const double time) {
148  // Create HepMC3::FourVector from position and time for the new position
149  const HepMC3::FourVector vec(pos(0), pos(1), pos(2), time);
150  event.shift_position_to(vec);
151 }
152 
154  const Acts::Vector3& pos) {
155  // Create HepMC3::FourVector from position and time for the new position
156  const HepMC3::FourVector vec(pos(0), pos(1), pos(2), event.event_pos().t());
157  event.shift_position_to(vec);
158 }
159 
161  const double time) {
162  // Create HepMC3::FourVector from position and time for the new position
163  const HepMC3::FourVector vec(event.event_pos().x(), event.event_pos().y(),
164  event.event_pos().z(), time);
165  event.shift_position_to(vec);
166 }
167 
171 
173  HepMC3::GenEvent& event, const std::shared_ptr<SimParticle>& particle) {
174  // Add new particle
175  event.add_particle(actsParticleToGen(particle));
176 }
177 
179  HepMC3::GenEvent& event, const std::shared_ptr<SimVertex>& vertex) {
180  // Add new vertex
181  event.add_vertex(createGenVertex(vertex));
182 }
183 
187 
189  HepMC3::GenEvent& event, const std::shared_ptr<SimParticle>& particle) {
190  const std::vector<HepMC3::GenParticlePtr> genParticles = event.particles();
191  const auto id = particle->particleId();
192  // Search HepMC3::GenParticle with the same id as the Acts particle
193  for (auto& genParticle : genParticles) {
194  if (genParticle->id() == id) {
195  // Remove particle if found
196  event.remove_particle(genParticle);
197  break;
198  }
199  }
200 }
201 
203  HepMC3::GenEvent& event, const std::shared_ptr<SimVertex>& vertex) {
204  const std::vector<HepMC3::GenVertexPtr> genVertices = event.vertices();
205  // Walk over every recorded vertex
206  for (auto& genVertex : genVertices) {
207  if (compareVertices(vertex, genVertex)) {
208  // Remove vertex if it matches actsVertex
209  event.remove_vertex(genVertex);
210  break;
211  }
212  }
213 }
214 
218 
219 double ActsExamples::HepMC3Event::momentumUnit(const HepMC3::GenEvent& event) {
220  // HepMC allows only MEV and GEV. This allows an easy identification.
221  return (event.momentum_unit() == HepMC3::Units::MomentumUnit::MEV
224 }
225 
226 double ActsExamples::HepMC3Event::lengthUnit(const HepMC3::GenEvent& event) {
227  // HepMC allows only MM and CM. This allows an easy identification.
228  return (event.length_unit() == HepMC3::Units::LengthUnit::MM
231 }
232 
234  const HepMC3::GenEvent& event) {
235  // Extract the position from HepMC3::FourVector
237  vec(0) = event.event_pos().x();
238  vec(1) = event.event_pos().y();
239  vec(2) = event.event_pos().z();
240  return vec;
241 }
242 
243 double ActsExamples::HepMC3Event::eventTime(const HepMC3::GenEvent& event) {
244  // Extract the time from HepMC3::FourVector
245  return event.event_pos().t();
246 }
247 
248 std::vector<ActsExamples::SimParticle> ActsExamples::HepMC3Event::particles(
249  const HepMC3::GenEvent& event) {
250  std::vector<SimParticle> actsParticles;
251  const std::vector<HepMC3::ConstGenParticlePtr> genParticles =
252  event.particles();
253 
254  // Translate all particles
255  for (auto& genParticle : genParticles) {
256  actsParticles.push_back(HepMC3Particle::particle(
257  std::make_shared<HepMC3::GenParticle>(*genParticle)));
258  }
259 
260  return actsParticles;
261 }
262 
263 std::vector<std::unique_ptr<ActsExamples::SimVertex>>
264 ActsExamples::HepMC3Event::vertices(const HepMC3::GenEvent& event) {
265  std::vector<std::unique_ptr<SimVertex>> actsVertices;
266  const std::vector<HepMC3::ConstGenVertexPtr> genVertices = event.vertices();
267 
268  // Translate all vertices
269  for (auto& genVertex : genVertices) {
270  actsVertices.push_back(HepMC3Vertex::processVertex(
271  std::make_shared<HepMC3::GenVertex>(*genVertex)));
272  }
273  return actsVertices;
274 }
275 
276 std::vector<ActsExamples::SimParticle> ActsExamples::HepMC3Event::beams(
277  const HepMC3::GenEvent& event) {
278  std::vector<SimParticle> actsBeams;
279  const std::vector<HepMC3::ConstGenParticlePtr> genBeams = event.beams();
280 
281  // Translate beam particles and store the result
282  for (auto& genBeam : genBeams) {
283  actsBeams.push_back(HepMC3Particle::particle(
284  std::make_shared<HepMC3::GenParticle>(*genBeam)));
285  }
286  return actsBeams;
287 }
288 
289 std::vector<ActsExamples::SimParticle> ActsExamples::HepMC3Event::finalState(
290  const HepMC3::GenEvent& event) {
291  std::vector<HepMC3::ConstGenParticlePtr> particles = event.particles();
292  std::vector<SimParticle> fState;
293 
294  // Walk over every vertex
295  for (auto& particle : particles) {
296  // Collect particles without end vertex
297  if (!particle->end_vertex()) {
298  fState.push_back(HepMC3Particle::particle(
299  std::make_shared<HepMC3::GenParticle>(*particle)));
300  }
301  }
302  return fState;
303 }