4#include "G4EventManager.hh"
5#include "G4Material.hh"
6#include "G4RunManager.hh"
8#include "G4StepPoint.hh"
10#include "G4VProcess.hh"
12#include "SimCore/G4User/UserEventInformation.h"
33 <<
" PN interactions";
38 const std::vector<const G4Track*>* secondaries =
39 step->GetSecondaryInCurrentStep();
40 if (!secondaries || secondaries->empty())
return;
43 bool is_pn_interaction =
false;
44 for (
const G4Track* secondary : *secondaries) {
45 const G4VProcess* creator = secondary->GetCreatorProcess();
47 const G4String& creator_name = creator->GetProcessName();
48 if (creator_name.contains(
"photonNuclear")) {
49 is_pn_interaction =
true;
55 if (!is_pn_interaction)
return;
61 const G4Track* incident_track = step->GetTrack();
62 const G4StepPoint* pre_step = step->GetPreStepPoint();
64 auto incident_pos = pre_step->GetPosition();
65 auto incident_momentum = pre_step->GetMomentum();
68 incident_track->GetTrackID(),
69 incident_track->GetDefinition()->GetPDGEncoding(),
70 pre_step->GetKineticEnergy() +
71 incident_track->GetDefinition()->GetPDGMass(),
72 incident_momentum.x(), incident_momentum.y(), incident_momentum.z(),
73 incident_pos.x(), incident_pos.y(), incident_pos.z(),
74 pre_step->GetGlobalTime());
77 int target_z, target_a;
78 std::string target_material;
80 pn_interaction.
setTarget(target_z, target_a, target_material);
92 G4EventManager::GetEventManager()->GetUserInformation());
94 event_info->setPNTargetZ(target_z);
95 event_info->setPNTargetA(target_a);
98 for (
const G4Track* secondary : *secondaries) {
103 int secondary_id = secondary->GetTrackID();
108 ldmx_log(debug) <<
" Immediate secondary: track_id=" << secondary_id
109 <<
" pdg=" << particle_info.pdg_id_
110 <<
" E=" << particle_info.energy_ <<
" MeV";
116 ldmx_log(debug) <<
"Detected PN interaction #" << pn_index <<
" with "
117 << secondaries->size() <<
" secondaries";
122 int track_id = track->GetTrackID();
123 int parent_id = track->GetParentID();
131 ldmx_log(debug) <<
" Track " << track_id
132 <<
" is descendant of PN secondary " << parent_it->second
133 <<
" (parent=" << parent_id <<
")";
138 int track_id = track->GetTrackID();
147 int immediate_secondary_id = ancestry_it->second;
152 ldmx_log(warn) <<
"Inconsistent ancestry mapping for track " << track_id;
156 int pn_index = pn_index_it->second;
163 ldmx_log(debug) <<
" Recording descendant: track " << track_id
164 <<
" -> secondary " << immediate_secondary_id
165 <<
" in PN interaction " << pn_index;
169 std::string& material) {
170 const G4Material* mat = step->GetPreStepPoint()->GetMaterial();
171 material = mat->GetName();
175 const G4Element* element = mat->GetElement(0);
176 Z =
static_cast<int>(element->GetZ());
177 A =
static_cast<int>(element->GetA() /
178 (CLHEP::g / CLHEP::mole));
185 info.track_id_ = track->GetTrackID();
186 info.pdg_id_ = track->GetDefinition()->GetPDGEncoding();
188 auto position = track->GetPosition();
189 info.x_ = position.x();
190 info.y_ = position.y();
191 info.z_ = position.z();
193 auto momentum = track->GetMomentum();
194 info.px_ = momentum.x();
195 info.py_ = momentum.y();
196 info.pz_ = momentum.z();
199 track->GetKineticEnergy() + track->GetDefinition()->GetPDGMass();
200 info.time_ = track->GetGlobalTime();
UserAction for tracking detailed photonuclear interaction information.
Class which implements the user tracking action.
#define DECLARE_ACTION(CLASS)
register a new UserAction with its factory
Class encapsulating parameters for configuring a processor.
Stores detailed information about a photonuclear interaction.
void setProcessName(const std::string &process)
Set the process name.
void setInteractionVolume(const std::string &volume)
Set the volume where the interaction occurred.
void addImmediateSecondary(const ParticleInfo &particle)
Add an immediate secondary particle from the PN interaction.
void setIncidentPhoton(int track_id, int pdg_id, double energy, double px, double py, double pz, double x, double y, double z, double time)
Set the incident photon information.
void setTarget(int Z, int A, const std::string &material)
Set the target nucleus information.
Tracks detailed information about photonuclear interactions.
static PhotonuclearTracker * instance
Static pointer to the current instance.
void BeginOfEventAction(const G4Event *event) override
Called at the beginning of each event.
ldmx::PhotonuclearInteraction::ParticleInfo createParticleInfo(const G4Track *track)
Create a ParticleInfo struct from a G4Track.
std::map< int, int > descendant_ancestry_
Maps descendant track ID -> immediate secondary track ID Propagates through the genealogy to trace ba...
void PreUserTrackingAction(const G4Track *track) override
Called before tracking a new track.
PhotonuclearTracker(const std::string &name, framework::config::Parameters ¶meters)
Constructor.
std::map< int, int > secondary_to_pn_index_
Maps secondary track ID -> index in pn_interactions_ Used to quickly find which PN interaction a seco...
void extractTargetInfo(const G4Step *step, int &Z, int &A, std::string &material)
Extract target nucleus information from the current step.
void PostUserTrackingAction(const G4Track *track) override
Called after tracking a track.
void EndOfEventAction(const G4Event *event) override
Called at the end of each event.
void stepping(const G4Step *step) override
Called after each simulation step.
std::vector< ldmx::PhotonuclearInteraction > pn_interactions_
Collection of PN interactions in this event.
Interface that defines a user action.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...
Stores kinematic and identity information for a particle.