Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /acts/Examples/Io/HepMC3/src/HepMC3Event.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsExamples/Io/HepMC3/HepMC3Event.hpp"
0010 
0011 #include "ActsExamples/Io/HepMC3/HepMC3Particle.hpp"
0012 #include "ActsExamples/Io/HepMC3/HepMC3Vertex.hpp"
0013 
0014 namespace ActsExamples {
0015 
0016 namespace {
0017 
0018 /// @brief Converts an SimParticle into HepMC3::GenParticle
0019 /// @note The conversion ignores HepMC status codes
0020 /// @param actsParticle Acts particle that will be converted
0021 /// @return converted particle
0022 HepMC3::GenParticlePtr actsParticleToGen(
0023     const std::shared_ptr<SimParticle>& actsParticle) {
0024   // Extract momentum and energy from Acts particle for HepMC3::FourVector
0025   const auto mom4 = actsParticle->fourMomentum();
0026   const HepMC3::FourVector vec(mom4[0], mom4[1], mom4[2], mom4[3]);
0027   // Create HepMC3::GenParticle
0028   auto genParticle =
0029       std::make_shared<HepMC3::GenParticle>(vec, actsParticle->pdg());
0030   genParticle->set_generated_mass(actsParticle->mass());
0031 
0032   return genParticle;
0033 }
0034 
0035 /// @brief Converts an Acts vertex to a HepMC3::GenVertexPtr
0036 /// @note The conversion ignores HepMC status codes
0037 /// @param actsVertex Acts vertex that will be converted
0038 /// @return Converted Acts vertex to HepMC3::GenVertexPtr
0039 HepMC3::GenVertexPtr createGenVertex(
0040     const std::shared_ptr<SimVertex>& actsVertex) {
0041   const HepMC3::FourVector vec(
0042       actsVertex->position4[0], actsVertex->position4[1],
0043       actsVertex->position4[2], actsVertex->position4[3]);
0044 
0045   // Create vertex
0046   auto genVertex = std::make_shared<HepMC3::GenVertex>(vec);
0047 
0048   return genVertex;
0049 }
0050 
0051 /// @brief Compares an Acts vertex with a HepMC3::GenVertex
0052 /// @note An Acts vertex does not store a barcode. Therefore the content of
0053 /// both vertices is compared. The position, time and number of incoming and
0054 /// outgoing particles will be compared. Since a second vertex could exist in
0055 /// the record with identical information (although unlikely), this
0056 /// comparison could lead to false positive results. On the other hand, a
0057 /// numerical deviation of the parameters could lead to a false negative.
0058 /// @param actsVertex Acts vertex
0059 /// @param genVertex HepMC3::GenVertex
0060 /// @return boolean result if both vertices are identical
0061 bool compareVertices(const std::shared_ptr<SimVertex>& actsVertex,
0062                      const HepMC3::GenVertexPtr& genVertex) {
0063   // Compare position, time, number of incoming and outgoing particles between
0064   // both vertices. Return false if one criterium does not match, else true.
0065   HepMC3::FourVector genVec = genVertex->position();
0066   if (actsVertex->position4[0] != genVec.x()) {
0067     return false;
0068   }
0069   if (actsVertex->position4[1] != genVec.y()) {
0070     return false;
0071   }
0072   if (actsVertex->position4[2] != genVec.z()) {
0073     return false;
0074   }
0075   if (actsVertex->position4[3] != genVec.t()) {
0076     return false;
0077   }
0078   if (actsVertex->incoming.size() != genVertex->particles_in().size()) {
0079     return false;
0080   }
0081   if (actsVertex->outgoing.size() != genVertex->particles_out().size()) {
0082     return false;
0083   }
0084   return true;
0085 }
0086 }  // namespace
0087 
0088 ///
0089 /// Setter
0090 ///
0091 
0092 void HepMC3Event::momentumUnit(HepMC3::GenEvent& event,
0093                                const double momentumUnit) {
0094   // Check, if the momentum unit fits Acts::UnitConstants::MeV or _GeV
0095   HepMC3::Units::MomentumUnit mom = HepMC3::Units::MomentumUnit::GEV;
0096   if (momentumUnit == Acts::UnitConstants::MeV) {
0097     mom = HepMC3::Units::MomentumUnit::MEV;
0098   } else if (momentumUnit == Acts::UnitConstants::GeV) {
0099     mom = HepMC3::Units::MomentumUnit::GEV;
0100   } else {
0101     // Report invalid momentum unit and set GeV
0102     std::cout << "Invalid unit of momentum: " << momentumUnit << std::endl;
0103     std::cout << "Momentum unit [GeV] will be used instead" << std::endl;
0104   }
0105   // Set units
0106   event.set_units(mom, event.length_unit());
0107 }
0108 
0109 void HepMC3Event::lengthUnit(HepMC3::GenEvent& event, const double lengthUnit) {
0110   // Check, if the length unit fits Acts::UnitConstants::mm or _cm
0111   HepMC3::Units::LengthUnit len = HepMC3::Units::LengthUnit::MM;
0112   if (lengthUnit == Acts::UnitConstants::mm) {
0113     len = HepMC3::Units::LengthUnit::MM;
0114   } else if (lengthUnit == Acts::UnitConstants::cm) {
0115     len = HepMC3::Units::LengthUnit::CM;
0116   } else {
0117     // Report invalid length unit and set mm
0118     std::cout << "Invalid unit of length: " << lengthUnit << std::endl;
0119     std::cout << "Length unit [mm] will be used instead" << std::endl;
0120   }
0121 
0122   // Set units
0123   event.set_units(event.momentum_unit(), len);
0124 }
0125 
0126 void HepMC3Event::shiftPositionBy(HepMC3::GenEvent& event,
0127                                   const Acts::Vector3& deltaPos,
0128                                   const double deltaTime) {
0129   // Create HepMC3::FourVector from position and time for shift
0130   const HepMC3::FourVector vec(deltaPos(0), deltaPos(1), deltaPos(2),
0131                                deltaTime);
0132   event.shift_position_by(vec);
0133 }
0134 
0135 void HepMC3Event::shiftPositionTo(HepMC3::GenEvent& event,
0136                                   const Acts::Vector3& pos, const double time) {
0137   // Create HepMC3::FourVector from position and time for the new position
0138   const HepMC3::FourVector vec(pos(0), pos(1), pos(2), time);
0139   event.shift_position_to(vec);
0140 }
0141 
0142 void HepMC3Event::shiftPositionTo(HepMC3::GenEvent& event,
0143                                   const Acts::Vector3& pos) {
0144   // Create HepMC3::FourVector from position and time for the new position
0145   const HepMC3::FourVector vec(pos(0), pos(1), pos(2), event.event_pos().t());
0146   event.shift_position_to(vec);
0147 }
0148 
0149 void HepMC3Event::shiftPositionTo(HepMC3::GenEvent& event, const double time) {
0150   // Create HepMC3::FourVector from position and time for the new position
0151   const HepMC3::FourVector vec(event.event_pos().x(), event.event_pos().y(),
0152                                event.event_pos().z(), time);
0153   event.shift_position_to(vec);
0154 }
0155 
0156 ///
0157 /// Adder
0158 ///
0159 
0160 void HepMC3Event::addParticle(HepMC3::GenEvent& event,
0161                               const std::shared_ptr<SimParticle>& particle) {
0162   // Add new particle
0163   event.add_particle(actsParticleToGen(particle));
0164 }
0165 
0166 void HepMC3Event::addVertex(HepMC3::GenEvent& event,
0167                             const std::shared_ptr<SimVertex>& vertex) {
0168   // Add new vertex
0169   event.add_vertex(createGenVertex(vertex));
0170 }
0171 
0172 ///
0173 /// Remover
0174 ///
0175 
0176 void HepMC3Event::removeParticle(HepMC3::GenEvent& event,
0177                                  const std::shared_ptr<SimParticle>& particle) {
0178   const std::vector<HepMC3::GenParticlePtr> genParticles = event.particles();
0179   const auto id = particle->particleId();
0180   // Search HepMC3::GenParticle with the same id as the Acts particle
0181   for (auto& genParticle : genParticles) {
0182     if (genParticle->id() == id) {
0183       // Remove particle if found
0184       event.remove_particle(genParticle);
0185       break;
0186     }
0187   }
0188 }
0189 
0190 void HepMC3Event::removeVertex(HepMC3::GenEvent& event,
0191                                const std::shared_ptr<SimVertex>& vertex) {
0192   const std::vector<HepMC3::GenVertexPtr> genVertices = event.vertices();
0193   // Walk over every recorded vertex
0194   for (auto& genVertex : genVertices) {
0195     if (compareVertices(vertex, genVertex)) {
0196       // Remove vertex if it matches actsVertex
0197       event.remove_vertex(genVertex);
0198       break;
0199     }
0200   }
0201 }
0202 
0203 ///
0204 /// Getter
0205 ///
0206 
0207 double HepMC3Event::momentumUnit(const HepMC3::GenEvent& event) {
0208   // HepMC allows only MEV and GEV. This allows an easy identification.
0209   return (event.momentum_unit() == HepMC3::Units::MomentumUnit::MEV
0210               ? Acts::UnitConstants::MeV
0211               : Acts::UnitConstants::GeV);
0212 }
0213 
0214 double HepMC3Event::lengthUnit(const HepMC3::GenEvent& event) {
0215   // HepMC allows only MM and CM. This allows an easy identification.
0216   return (event.length_unit() == HepMC3::Units::LengthUnit::MM
0217               ? Acts::UnitConstants::mm
0218               : Acts::UnitConstants::cm);
0219 }
0220 
0221 Acts::Vector3 HepMC3Event::eventPos(const HepMC3::GenEvent& event) {
0222   // Extract the position from HepMC3::FourVector
0223   Acts::Vector3 vec;
0224   vec(0) = event.event_pos().x();
0225   vec(1) = event.event_pos().y();
0226   vec(2) = event.event_pos().z();
0227   return vec;
0228 }
0229 
0230 double HepMC3Event::eventTime(const HepMC3::GenEvent& event) {
0231   // Extract the time from HepMC3::FourVector
0232   return event.event_pos().t();
0233 }
0234 
0235 std::vector<SimParticle> HepMC3Event::particles(const HepMC3::GenEvent& event) {
0236   std::vector<SimParticle> actsParticles;
0237   const std::vector<HepMC3::ConstGenParticlePtr> genParticles =
0238       event.particles();
0239 
0240   // Translate all particles
0241   for (auto& genParticle : genParticles) {
0242     actsParticles.push_back(HepMC3Particle::particle(
0243         std::make_shared<HepMC3::GenParticle>(*genParticle)));
0244   }
0245 
0246   return actsParticles;
0247 }
0248 
0249 std::vector<std::unique_ptr<SimVertex>> HepMC3Event::vertices(
0250     const HepMC3::GenEvent& event) {
0251   std::vector<std::unique_ptr<SimVertex>> actsVertices;
0252   const std::vector<HepMC3::ConstGenVertexPtr> genVertices = event.vertices();
0253 
0254   // Translate all vertices
0255   for (auto& genVertex : genVertices) {
0256     actsVertices.push_back(HepMC3Vertex::processVertex(
0257         std::make_shared<HepMC3::GenVertex>(*genVertex)));
0258   }
0259   return actsVertices;
0260 }
0261 
0262 std::vector<SimParticle> HepMC3Event::beams(const HepMC3::GenEvent& event) {
0263   std::vector<SimParticle> actsBeams;
0264   const std::vector<HepMC3::ConstGenParticlePtr> genBeams = event.beams();
0265 
0266   // Translate beam particles and store the result
0267   for (auto& genBeam : genBeams) {
0268     actsBeams.push_back(HepMC3Particle::particle(
0269         std::make_shared<HepMC3::GenParticle>(*genBeam)));
0270   }
0271   return actsBeams;
0272 }
0273 
0274 std::vector<SimParticle> HepMC3Event::finalState(
0275     const HepMC3::GenEvent& event) {
0276   std::vector<HepMC3::ConstGenParticlePtr> particles = event.particles();
0277   std::vector<SimParticle> fState;
0278 
0279   // Walk over every vertex
0280   for (auto& particle : particles) {
0281     // Collect particles without end vertex
0282     if (!particle->end_vertex()) {
0283       fState.push_back(HepMC3Particle::particle(
0284           std::make_shared<HepMC3::GenParticle>(*particle)));
0285     }
0286   }
0287   return fState;
0288 }
0289 
0290 }  // namespace ActsExamples