Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SteppingAction.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SteppingAction.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 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 
9 #include "SteppingAction.hpp"
10 
11 #include <stdexcept>
12 
13 #include <G4RunManager.hh>
14 #include <G4Step.hh>
15 #include <G4VProcess.hh>
16 #include <HepMC3/Attribute.h>
17 #include <HepMC3/Units.h>
18 
19 #include "EventAction.hpp"
20 
21 namespace ActsExamples::Geant4::HepMC3 {
22 
23 SteppingAction* SteppingAction::s_instance = nullptr;
24 
26  // Static access function via G4RunManager
27  return s_instance;
28 }
29 
30 SteppingAction::SteppingAction(std::vector<std::string> eventRejectionProcess)
31  : G4UserSteppingAction(),
32  m_eventRejectionProcess(std::move(eventRejectionProcess)) {
33  if (s_instance != nullptr) {
34  throw std::logic_error("Attempted to duplicate a singleton");
35  } else {
36  s_instance = this;
37  }
38 }
39 
41  s_instance = nullptr;
42 }
43 
45  // Test if the event should be aborted
46  if (std::find(m_eventRejectionProcess.begin(), m_eventRejectionProcess.end(),
47  step->GetPostStepPoint()
48  ->GetProcessDefinedStep()
49  ->GetProcessName()) != m_eventRejectionProcess.end()) {
50  m_eventAborted = true;
51  G4RunManager::GetRunManager()->AbortEvent();
52  return;
53  }
54 
62 
63  ::HepMC3::GenEvent& event = EventAction::instance()->event();
64 
65  // Unit conversions G4->::HepMC3
66  constexpr double convertLength = 1. / CLHEP::mm;
67  constexpr double convertEnergy = 1. / CLHEP::GeV;
68  constexpr double convertTime = 1. / CLHEP::s;
69 
70  // The particle after the step
71  auto* track = step->GetTrack();
72  const std::string trackId = std::to_string(track->GetTrackID());
73  auto postStepMomentum = track->GetMomentum() * convertEnergy;
74  auto postStepEnergy = track->GetTotalEnergy() * convertEnergy;
75  ::HepMC3::FourVector mom4{postStepMomentum[0], postStepMomentum[1],
76  postStepMomentum[2], postStepEnergy};
77  auto postParticle = std::make_shared<::HepMC3::GenParticle>(
78  mom4, track->GetDynamicParticle()->GetPDGcode());
79 
80  // The process that led to the current state
81  auto process = std::make_shared<::HepMC3::StringAttribute>(
82  step->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName());
83 
84  // Assign particle to a production vertex
85  if (!m_previousVertex) {
86  // Get the production position of the particle
87  auto* preStep = step->GetPreStepPoint();
88  auto prePosition = preStep->GetPosition() * convertLength;
89  auto preTime = preStep->GetGlobalTime() * convertTime;
90  ::HepMC3::FourVector prePos{prePosition[0], prePosition[1], prePosition[2],
91  preTime};
92 
93  // Handle the first step: No vertices exist
94  if (event.vertices().empty()) {
95  auto vertex = std::make_shared<::HepMC3::GenVertex>(prePos);
96  vertex->add_particle_out(postParticle);
97  event.add_vertex(vertex);
98  vertex->set_status(1);
99  vertex->add_attribute("NextProcessOf" + trackId, process);
100  } else {
101  // Search for an existing vertex
102  for (const auto& vertex : event.vertices()) {
103  if (vertex->position() == prePos) {
104  // Add particle to existing vertex
105  vertex->add_particle_out(postParticle);
106  vertex->add_attribute("NextProcessOf-" + trackId, process);
107  auto preStepMomentum =
108  step->GetPreStepPoint()->GetMomentum() * convertEnergy;
109  auto preStepEnergy =
110  step->GetPreStepPoint()->GetTotalEnergy() * convertEnergy;
111  auto preMom4 = std::make_shared<::HepMC3::VectorDoubleAttribute>(
112  std::vector<double>{preStepMomentum[0], preStepMomentum[1],
113  preStepMomentum[2], preStepEnergy});
114  vertex->add_attribute("InitialParametersOf-" + trackId, preMom4);
115  }
116  }
117  }
118  if (track->GetCreatorProcess() != nullptr) {
119  postParticle->add_attribute(
120  "CreatorProcessOf-" + trackId,
121  std::make_shared<::HepMC3::StringAttribute>(
122  track->GetCreatorProcess()->GetProcessName()));
123  }
124  } else {
125  // Add particle from same track to vertex
126  m_previousVertex->add_particle_out(postParticle);
127  m_previousVertex->add_attribute("NextProcessOf-" + trackId, process);
128  }
129 
130  // Build the end vertex
131  auto* postStep = step->GetPostStepPoint();
132  auto postPosition = postStep->GetPosition() * convertLength;
133  auto postTime = postStep->GetGlobalTime() * convertTime;
134  ::HepMC3::FourVector postPos{postPosition[0], postPosition[1],
135  postPosition[2], postTime};
136  m_previousVertex = std::make_shared<::HepMC3::GenVertex>(postPos);
137 
138  // Add particle to the vertex
139  m_previousVertex->add_particle_in(postParticle);
140 
141  // Store the vertex
142  event.add_vertex(m_previousVertex);
143 
144  // Store additional data in the particle
145  postParticle->add_attribute(
146  "TrackID", std::make_shared<::HepMC3::IntAttribute>(track->GetTrackID()));
147  postParticle->add_attribute(
148  "ParentID",
149  std::make_shared<::HepMC3::IntAttribute>(track->GetParentID()));
150  const double X0 = track->GetMaterial()->GetRadlen() * convertLength;
151  const double L0 =
152  track->GetMaterial()->GetNuclearInterLength() * convertLength;
153  const double stepLength = track->GetStepLength();
154  postParticle->add_attribute("NextX0",
155  std::make_shared<::HepMC3::DoubleAttribute>(X0));
156  postParticle->add_attribute("NextL0",
157  std::make_shared<::HepMC3::DoubleAttribute>(L0));
158  postParticle->add_attribute(
159  "StepLength", std::make_shared<::HepMC3::DoubleAttribute>(stepLength));
160  postParticle->set_status(1);
161 
162  // Stop tracking the vertex if the particle dies
163  if (track->GetTrackStatus() != fAlive) {
164  process = std::make_shared<::HepMC3::StringAttribute>("Death");
165  m_previousVertex->add_attribute("NextProcessOf-" + trackId, process);
166  m_previousVertex = nullptr;
167  }
168 }
169 
171  m_previousVertex = nullptr;
172  m_eventAborted = false;
173 }
174 
175 } // namespace ActsExamples::Geant4::HepMC3