14 #include <G4RunManager.hh>
26 bool findAttribute(
const HepMC3::ConstGenVertexPtr&
vertex,
27 const std::vector<std::string>& processFilter) {
29 if ((vertex->particles_in().size() == 1) &&
30 (vertex->particles_out().size() == 1)) {
32 const std::vector<std::string> vertexAttributes = vertex->attribute_names();
33 for (
const auto& att : vertexAttributes) {
35 if (std::find(processFilter.begin(), processFilter.end(),
process) !=
36 processFilter.end()) {
50 void reduceVertex(HepMC3::GenEvent&
event, HepMC3::GenVertexPtr vertex,
51 const std::vector<std::string>& processFilter) {
53 HepMC3::GenParticlePtr particleIn = vertex->particles_in()[0];
54 HepMC3::GenParticlePtr particleOut = vertex->particles_out()[0];
57 while (findAttribute(particleIn->production_vertex(), processFilter)) {
60 HepMC3::GenVertexPtr currentVertex = particleOut->production_vertex();
61 HepMC3::GenParticlePtr nextParticle = currentVertex->particles_in()[0];
63 if (particleIn->end_vertex()) {
64 particleIn->end_vertex()->remove_particle_in(particleIn);
66 currentVertex->remove_particle_out(particleIn);
67 event.remove_particle(particleIn);
69 particleIn = nextParticle;
70 currentVertex->remove_particle_in(particleIn);
71 event.remove_vertex(currentVertex);
74 while (findAttribute(particleOut->end_vertex(), processFilter)) {
77 HepMC3::GenVertexPtr currentVertex = particleOut->end_vertex();
78 HepMC3::GenParticlePtr nextParticle = currentVertex->particles_out()[0];
80 if (particleOut->production_vertex()) {
81 particleOut->production_vertex()->remove_particle_out(particleOut);
83 currentVertex->remove_particle_in(particleOut);
84 event.remove_particle(particleOut);
86 particleOut = nextParticle;
87 currentVertex->remove_particle_out(particleOut);
88 event.remove_vertex(currentVertex);
92 auto reducedVertex = std::make_shared<HepMC3::GenVertex>();
93 event.add_vertex(reducedVertex);
95 reducedVertex->add_particle_in(particleIn);
96 reducedVertex->add_particle_out(particleOut);
99 event.remove_vertex(vertex);
100 vertex = reducedVertex;
109 void followOutgoingParticles(HepMC3::GenEvent& event,
110 const HepMC3::GenVertexPtr& vertex,
111 const std::vector<std::string>& processFilter) {
113 if (findAttribute(vertex, processFilter)) {
114 reduceVertex(event, vertex, processFilter);
117 for (
const auto&
particle : vertex->particles_out()) {
118 followOutgoingParticles(event,
particle->end_vertex(), processFilter);
123 namespace ActsExamples::Geant4::HepMC3 {
133 : G4UserEventAction(), m_processFilter(std::
move(processFilter)) {
135 throw std::logic_error(
"Attempted to duplicate a singleton");
147 m_event = ::HepMC3::GenEvent(::HepMC3::Units::GEV, ::HepMC3::Units::MM);
148 m_event.add_beam_particle(std::make_shared<::HepMC3::GenParticle>());
153 if (
m_event.vertices().empty()) {
157 auto currentVertex =
m_event.vertices()[0];
158 for (
auto& bp :
m_event.beams()) {
159 if (!bp->end_vertex()) {
160 currentVertex->add_particle_in(bp);
168 for (
const auto&
v :
m_event.vertices()) {
172 if (
v->particles_out().empty()) {
177 for (
const auto&
p :
m_event.particles()) {
181 if (!
p->production_vertex()) {