File indexing completed on 2025-01-18 09:11:36
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Geant4/SimParticleTranslation.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "ActsExamples/EventData/SimParticle.hpp"
0014 #include "ActsExamples/Framework/DataHandle.hpp"
0015 #include "ActsExamples/Framework/WhiteBoard.hpp"
0016 #include "ActsExamples/Geant4/EventStore.hpp"
0017
0018 #include <ostream>
0019 #include <unordered_map>
0020 #include <utility>
0021
0022 #include <G4ChargedGeantino.hh>
0023 #include <G4Event.hh>
0024 #include <G4Geantino.hh>
0025 #include <G4ParticleDefinition.hh>
0026 #include <G4ParticleTable.hh>
0027 #include <G4PrimaryParticle.hh>
0028 #include <G4PrimaryVertex.hh>
0029 #include <G4UnitsTable.hh>
0030
0031 namespace ActsExamples::Geant4 {
0032
0033 SimParticleTranslation::SimParticleTranslation(
0034 const Config& cfg, std::unique_ptr<const Acts::Logger> logger)
0035 : G4VUserPrimaryGeneratorAction(),
0036 m_cfg(cfg),
0037 m_logger(std::move(logger)) {}
0038
0039 SimParticleTranslation::~SimParticleTranslation() = default;
0040
0041 void SimParticleTranslation::GeneratePrimaries(G4Event* anEvent) {
0042 anEvent->SetEventID(m_eventNr++);
0043 unsigned int eventID = anEvent->GetEventID();
0044
0045 ACTS_DEBUG("Primary Generator Action for Event: " << eventID);
0046
0047 if (eventStore().store == nullptr) {
0048 ACTS_WARNING("No WhiteBoard instance could be found for this event!");
0049 return;
0050 }
0051
0052 if (eventStore().inputParticles == nullptr) {
0053 ACTS_WARNING("No input particle handle found");
0054 return;
0055 }
0056
0057
0058 const auto inputParticles =
0059 (*eventStore().inputParticles)(*eventStore().store);
0060
0061
0062 eventStore().hits.reserve(inputParticles.size() *
0063 m_cfg.reserveHitsPerParticle);
0064
0065
0066 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
0067 G4PrimaryVertex* pVertex = nullptr;
0068
0069
0070 std::optional<Acts::Vector4> lastVertex;
0071
0072 constexpr double convertLength = CLHEP::mm / Acts::UnitConstants::mm;
0073 constexpr double convertTime = CLHEP::ns / Acts::UnitConstants::ns;
0074 constexpr double convertEnergy = CLHEP::GeV / Acts::UnitConstants::GeV;
0075
0076 unsigned int pCounter = 0;
0077 unsigned int trackId = 1;
0078
0079 for (const auto& part : inputParticles) {
0080 auto currentVertex = part.fourPosition();
0081 if (!lastVertex || !currentVertex.isApprox(*lastVertex)) {
0082
0083 if (pVertex != nullptr) {
0084 anEvent->AddPrimaryVertex(pVertex);
0085 ACTS_DEBUG("Flushing " << pCounter
0086 << " particles associated with vertex "
0087 << lastVertex->transpose());
0088 pCounter = 0;
0089 }
0090 lastVertex = currentVertex;
0091 pVertex = new G4PrimaryVertex(
0092 currentVertex[0] * convertLength, currentVertex[1] * convertLength,
0093 currentVertex[2] * convertLength, currentVertex[3] * convertTime);
0094 }
0095
0096
0097
0098 Acts::Vector4 mom4 = part.fourMomentum() * convertEnergy;
0099
0100
0101 G4int particlePdgCode = m_cfg.forcedPdgCode.value_or(part.pdg());
0102 G4double particleCharge = m_cfg.forcedCharge.value_or(part.charge());
0103 G4double particleMass =
0104 m_cfg.forcedMass.value_or(part.mass() * convertEnergy);
0105
0106
0107 G4ParticleDefinition* particleDefinition =
0108 particleTable->FindParticle(particlePdgCode);
0109 if (particleDefinition == nullptr) {
0110 if (particlePdgCode == 0 && particleMass == 0 && particleCharge == 0) {
0111 particleDefinition = G4Geantino::Definition();
0112 }
0113 if (particlePdgCode == 0 && particleMass == 0 && particleCharge != 0) {
0114 if (particleCharge != 1) {
0115 ACTS_ERROR("invalid charged geantino charge " << particleCharge
0116 << ". should be 1");
0117 }
0118 particleDefinition = G4ChargedGeantino::Definition();
0119 }
0120 }
0121
0122
0123 if (particleDefinition == nullptr) {
0124 ACTS_DEBUG(
0125 "Could not translate particle with PDG code : " << particlePdgCode);
0126 continue;
0127 }
0128
0129 ACTS_VERBOSE("Adding particle with name '"
0130 << particleDefinition->GetParticleName()
0131 << "' and properties:");
0132 ACTS_VERBOSE(" -> mass: " << particleMass);
0133 ACTS_VERBOSE(" -> charge: " << particleCharge);
0134 ACTS_VERBOSE(" -> momentum: " << mom4.transpose());
0135
0136
0137 G4PrimaryParticle* particle = new G4PrimaryParticle(particleDefinition);
0138
0139 particle->SetMass(particleMass);
0140 particle->SetCharge(particleCharge);
0141 particle->Set4Momentum(mom4[0], mom4[1], mom4[2], mom4[3]);
0142 particle->SetTrackID(trackId++);
0143
0144
0145 pVertex->SetPrimary(particle);
0146
0147 eventStore().particlesInitial.insert(part);
0148 eventStore().trackIdMapping[particle->GetTrackID()] = part.particleId();
0149
0150 ++pCounter;
0151 }
0152
0153 if (pVertex != nullptr) {
0154 anEvent->AddPrimaryVertex(pVertex);
0155 ACTS_DEBUG("Flushing " << pCounter << " particles associated with vertex "
0156 << lastVertex->transpose());
0157 }
0158 }
0159
0160 }