ECCE @ EIC 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 
17 
18 void FW::HepMC3Event::momentumUnit(std::shared_ptr<HepMC3::GenEvent> event,
19  const double momentumUnit) {
20  // Check, if the momentum unit fits Acts::units::_MeV or _GeV
21  HepMC3::Units::MomentumUnit mom;
22  if (momentumUnit == Acts::units::_MeV)
23  mom = HepMC3::Units::MomentumUnit::MEV;
24  else if (momentumUnit == Acts::units::_GeV)
25  mom = HepMC3::Units::MomentumUnit::GEV;
26  else {
27  // Report invalid momentum unit and set GeV
28  std::cout << "Invalid unit of momentum: " << momentumUnit << std::endl;
29  std::cout << "Momentum unit [GeV] will be used instead" << std::endl;
30  mom = HepMC3::Units::MomentumUnit::GEV;
31  }
32  // Set units
33  event->set_units(mom, event->length_unit());
34 }
35 
36 void FW::HepMC3Event::lengthUnit(std::shared_ptr<HepMC3::GenEvent> event,
37  const double lengthUnit) {
38  // Check, if the length unit fits Acts::units::_mm or _cm
39  HepMC3::Units::LengthUnit len;
40  if (lengthUnit == Acts::units::_mm)
41  len = HepMC3::Units::LengthUnit::MM;
42  else if (lengthUnit == Acts::units::_cm)
43  len = HepMC3::Units::LengthUnit::CM;
44  else {
45  // Report invalid length unit and set mm
46  std::cout << "Invalid unit of length: " << lengthUnit << std::endl;
47  std::cout << "Length unit [mm] will be used instead" << std::endl;
48  len = HepMC3::Units::LengthUnit::MM;
49  }
50 
51  // Set units
52  event->set_units(event->momentum_unit(), len);
53 }
54 
55 void FW::HepMC3Event::shiftPositionBy(std::shared_ptr<HepMC3::GenEvent> event,
56  const Acts::Vector3D& deltaPos,
57  const double deltaTime) {
58  // Create HepMC3::FourVector from position and time for shift
59  const HepMC3::FourVector vec(deltaPos(0), deltaPos(1), deltaPos(2),
60  deltaTime);
61  event->shift_position_by(vec);
62 }
63 
64 void FW::HepMC3Event::shiftPositionTo(std::shared_ptr<HepMC3::GenEvent> event,
65  const Acts::Vector3D& pos,
66  const double time) {
67  // Create HepMC3::FourVector from position and time for the new position
68  const HepMC3::FourVector vec(pos(0), pos(1), pos(2), time);
69  event->shift_position_to(vec);
70 }
71 
72 void FW::HepMC3Event::shiftPositionTo(std::shared_ptr<HepMC3::GenEvent> event,
73  const Acts::Vector3D& pos) {
74  // Create HepMC3::FourVector from position and time for the new position
75  const HepMC3::FourVector vec(pos(0), pos(1), pos(2), event->event_pos().t());
76  event->shift_position_to(vec);
77 }
78 
79 void FW::HepMC3Event::shiftPositionTo(std::shared_ptr<HepMC3::GenEvent> event,
80  const double time) {
81  // Create HepMC3::FourVector from position and time for the new position
82  const HepMC3::FourVector vec(event->event_pos().x(), event->event_pos().y(),
83  event->event_pos().z(), time);
84  event->shift_position_to(vec);
85 }
86 
90 
91 HepMC3::GenParticlePtr FW::HepMC3Event::actsParticleToGen(
92  std::shared_ptr<SimParticle> actsParticle) {
93  // Extract momentum and energy from Acts particle for HepMC3::FourVector
94  const auto mom4 = actsParticle->momentum4();
95  const HepMC3::FourVector vec(mom4[0], mom4[1], mom4[2], mom4[3]);
96  // Create HepMC3::GenParticle
97  HepMC3::GenParticle genParticle(vec, actsParticle->pdg());
98  genParticle.set_generated_mass(actsParticle->mass());
99 
100  return std::shared_ptr<HepMC3::GenParticle>(&genParticle);
101 }
102 
103 void FW::HepMC3Event::addParticle(std::shared_ptr<HepMC3::GenEvent> event,
104  std::shared_ptr<SimParticle> particle) {
105  // Add new particle
106  event->add_particle(actsParticleToGen(particle));
107 }
108 
109 HepMC3::GenVertexPtr FW::HepMC3Event::createGenVertex(
110  const std::shared_ptr<SimVertex>& actsVertex) {
111  const HepMC3::FourVector vec(
112  actsVertex->position4[0], actsVertex->position4[1],
113  actsVertex->position4[2], actsVertex->position4[3]);
114 
115  // Create vertex
116  HepMC3::GenVertex genVertex(vec);
117 
118  // Store incoming particles
119  for (auto& particle : actsVertex->incoming) {
120  HepMC3::GenParticlePtr genParticle =
121  actsParticleToGen(std::make_shared<SimParticle>(particle));
122  genVertex.add_particle_in(genParticle);
123  }
124  // Store outgoing particles
125  for (auto& particle : actsVertex->outgoing) {
126  HepMC3::GenParticlePtr genParticle =
127  actsParticleToGen(std::make_shared<SimParticle>(particle));
128  genVertex.add_particle_out(genParticle);
129  }
130  return std::shared_ptr<HepMC3::GenVertex>(&genVertex);
131 }
132 
133 void FW::HepMC3Event::addVertex(std::shared_ptr<HepMC3::GenEvent> event,
134  const std::shared_ptr<SimVertex> vertex) {
135  // Add new vertex
136  event->add_vertex(createGenVertex(vertex));
137 }
138 
142 
144  std::shared_ptr<HepMC3::GenEvent> event,
145  const std::shared_ptr<SimParticle>& particle) {
146  const std::vector<HepMC3::GenParticlePtr> genParticles = event->particles();
147  const auto id = particle->particleId();
148  // Search HepMC3::GenParticle with the same id as the Acts particle
149  for (auto& genParticle : genParticles) {
150  if (genParticle->id() == id) {
151  // Remove particle if found
152  event->remove_particle(genParticle);
153  break;
154  }
155  }
156 }
157 
159  const std::shared_ptr<SimVertex>& actsVertex,
160  const HepMC3::GenVertexPtr& genVertex) {
161  // Compare position, time, number of incoming and outgoing particles between
162  // both vertices. Return false if one criterium does not match, else true.
163  HepMC3::FourVector genVec = genVertex->position();
164  if (actsVertex->position4[0] != genVec.x())
165  return false;
166  if (actsVertex->position4[1] != genVec.y())
167  return false;
168  if (actsVertex->position4[2] != genVec.z())
169  return false;
170  if (actsVertex->position4[3] != genVec.t())
171  return false;
172  if (actsVertex->incoming.size() != genVertex->particles_in().size())
173  return false;
174  if (actsVertex->outgoing.size() != genVertex->particles_out().size())
175  return false;
176  return true;
177 }
178 
179 void FW::HepMC3Event::removeVertex(std::shared_ptr<HepMC3::GenEvent> event,
180  const std::shared_ptr<SimVertex>& vertex) {
181  const std::vector<HepMC3::GenVertexPtr> genVertices = event->vertices();
182  // Walk over every recorded vertex
183  for (auto& genVertex : genVertices)
184  if (compareVertices(vertex, genVertex)) {
185  // Remove vertex if it matches actsVertex
186  event->remove_vertex(genVertex);
187  break;
188  }
189 }
190 
194 
196  const std::shared_ptr<HepMC3::GenEvent> event) {
197  // HepMC allows only MEV and GEV. This allows an easy identification.
198  return (event->momentum_unit() == HepMC3::Units::MomentumUnit::MEV
201 }
202 
204  const std::shared_ptr<HepMC3::GenEvent> event) {
205  // HepMC allows only MM and CM. This allows an easy identification.
206  return (event->length_unit() == HepMC3::Units::LengthUnit::MM
208  : Acts::units::_cm);
209 }
210 
212  const std::shared_ptr<HepMC3::GenEvent> event) {
213  // Extract the position from HepMC3::FourVector
214  Acts::Vector3D vec;
215  vec(0) = event->event_pos().x();
216  vec(1) = event->event_pos().y();
217  vec(2) = event->event_pos().z();
218  return vec;
219 }
220 
222  const std::shared_ptr<HepMC3::GenEvent> event) {
223  // Extract the time from HepMC3::FourVector
224  return event->event_pos().t();
225 }
226 
227 std::vector<std::unique_ptr<FW::SimParticle>> FW::HepMC3Event::particles(
228  const std::shared_ptr<HepMC3::GenEvent> event) {
229  std::vector<std::unique_ptr<SimParticle>> actsParticles;
230  const std::vector<HepMC3::GenParticlePtr> genParticles = event->particles();
231 
232  HepMC3Particle simPart;
233 
234  // Translate all particles
235  for (auto& genParticle : genParticles)
236  actsParticles.push_back(std::move(
237  simPart.particle(std::make_shared<HepMC3::GenParticle>(*genParticle))));
238 
239  return std::move(actsParticles);
240 }
241 
242 std::vector<std::unique_ptr<FW::SimVertex>> FW::HepMC3Event::vertices(
243  const std::shared_ptr<HepMC3::GenEvent> event) {
244  std::vector<std::unique_ptr<SimVertex>> actsVertices;
245  const std::vector<HepMC3::GenVertexPtr> genVertices = event->vertices();
246 
247  HepMC3Vertex simVert;
248 
249  // Translate all vertices
250  for (auto& genVertex : genVertices) {
251  actsVertices.push_back(std::move(simVert.processVertex(
252  std::make_shared<HepMC3::GenVertex>(*genVertex))));
253  }
254  return std::move(actsVertices);
255 }
256 
257 std::vector<std::unique_ptr<FW::SimParticle>> FW::HepMC3Event::beams(
258  const std::shared_ptr<HepMC3::GenEvent> event) {
259  std::vector<std::unique_ptr<SimParticle>> actsBeams;
260  const std::vector<HepMC3::GenParticlePtr> genBeams = event->beams();
261 
262  HepMC3Particle simPart;
263 
264  // Translate beam particles and store the result
265  for (auto& genBeam : genBeams)
266  actsBeams.push_back(std::move(
267  simPart.particle(std::make_shared<HepMC3::GenParticle>(*genBeam))));
268  return std::move(actsBeams);
269 }
270 
271 std::vector<std::unique_ptr<FW::SimParticle>> FW::HepMC3Event::finalState(
272  const std::shared_ptr<HepMC3::GenEvent> event) {
273  std::vector<HepMC3::GenParticlePtr> particles = event->particles();
274  std::vector<std::unique_ptr<SimParticle>> fState;
275 
276  HepMC3Particle simPart;
277 
278  // Walk over every vertex
279  for (auto& particle : particles) {
280  // Collect particles without end vertex
281  if (!particle->end_vertex())
282  fState.push_back(
283  simPart.particle(std::make_shared<HepMC3::GenParticle>(*particle)));
284  }
285  return fState;
286 }