LDMX Software
TargetBremFilter.cxx
1/*~~~~~~~~~~~~~*/
2/* Biasing */
3/*~~~~~~~~~~~~~*/
4#include "Biasing/TargetBremFilter.h"
5
6/*~~~~~~~~~~~~*/
7/* Geant4 */
8/*~~~~~~~~~~~~*/
9#include "G4Electron.hh"
10#include "G4EventManager.hh"
11#include "G4RunManager.hh"
12
13/*~~~~~~~~~~~~~*/
14/* SimCore */
15/*~~~~~~~~~~~~~*/
16#include "SimCore/G4User/PtrRetrieval.h"
17#include "SimCore/G4User/UserEventInformation.h"
18#include "SimCore/G4User/UserTrackInformation.h"
19
20namespace biasing {
21
22TargetBremFilter::TargetBremFilter(const std::string& name,
24 : simcore::UserAction(name, parameters) {
25 recoil_max_p_threshold_ = parameters.get<double>("recoil_max_p_threshold");
26 brem_energy_threshold_ = parameters.get<double>("brem_min_energy_threshold");
27 kill_recoil_ = parameters.get<bool>("kill_recoil_track");
28}
29
31
32G4ClassificationOfNewTrack TargetBremFilter::ClassifyNewTrack(
33 const G4Track* track, const G4ClassificationOfNewTrack& currentTrackClass) {
34 // get the PDGID of the track.
35 G4int pdg_id = track->GetParticleDefinition()->GetPDGEncoding();
36
37 // Get the particle type.
38 G4String particle_name = track->GetParticleDefinition()->GetParticleName();
39
40 // Use current classification by default so values from other plugins are not
41 // overridden.
42 G4ClassificationOfNewTrack classification = currentTrackClass;
43
44 if (track->GetTrackID() == 1 && pdg_id == 11) {
45 return fWaiting;
46 }
47
48 return classification;
49}
50
51void TargetBremFilter::stepping(const G4Step* step) {
52 // Get the track associated with this step.
53 auto track{step->GetTrack()};
54
55 // Only process the primary electron track
56 if (track->GetParentID() != 0) return;
57
58 // Get the PDG ID of the track and make sure it's an electron. If
59 // another particle type is found, thrown an exception.
60 if (auto pdg_id{track->GetParticleDefinition()->GetPDGEncoding()};
61 pdg_id != 11)
62 return;
63
64 // Get the region the particle is currently in. Continue processing
65 // the particle only if it's in the target region.
66 static auto target_region =
67 simcore::g4user::ptrretrieval::getRegion("target");
68 if (!target_region) {
69 ldmx_log(warn) << "Region 'target' not found in Geant4 region store";
70 }
71 auto phy_vol{track->GetVolume()};
72 auto log_vol{phy_vol ? phy_vol->GetLogicalVolume() : nullptr};
73 auto track_region{log_vol ? log_vol->GetRegion() : nullptr};
74 if (track_region != target_region) return;
75
76 /*
77 std::cout << "[TargetBremFilter] : Stepping primary electron in 'target'
78 region into "
79 << track->GetNextVolume()->GetName()
80 << std::endl;
81 */
82
95 auto recoil_physical_volume =
96 simcore::g4user::ptrretrieval::getPhysicalVolume("recoil_PV");
97 auto world_physical_volume =
98 simcore::g4user::ptrretrieval::getPhysicalVolume("World_PV");
99 if (!recoil_physical_volume) {
100 ldmx_log(warn) << "Volume 'recoil_PV' not found in Geant4 volume store";
101 }
102 if (!world_physical_volume) {
103 ldmx_log(warn) << "Volume 'World_PV' not found in Geant4 volume store";
104 }
105 auto track_volume = track->GetNextVolume();
106 if (track_volume == recoil_physical_volume or
107 track_volume == world_physical_volume) {
108 // If the recoil electron
109 if (track->GetMomentum().mag() >= recoil_max_p_threshold_) {
110 track->SetTrackStatus(fKillTrackAndSecondaries);
111 G4RunManager::GetRunManager()->AbortEvent();
112 return;
113 }
114
115 // Get the electron secondries
116 bool has_brem_candidate = false;
117 if (auto secondaries = step->GetSecondary(); secondaries->size() == 0) {
118 track->SetTrackStatus(fKillTrackAndSecondaries);
119 G4RunManager::GetRunManager()->AbortEvent();
120 return;
121 } else {
122 for (auto& secondary_track : *secondaries) {
123 auto electron = G4Electron::Definition();
124 auto ebrem_process =
125 simcore::g4user::ptrretrieval::getProcess(electron, "eBrem");
126 if (!ebrem_process) {
127 ldmx_log(warn) << "Process 'eBrem' not found in Geant4 process store";
128 }
129
130 if (ebrem_process &&
131 secondary_track->GetKineticEnergy() > brem_energy_threshold_) {
132 auto track_info{simcore::UserTrackInformation::get(secondary_track)};
133 track_info->tagBremCandidate();
134
136
137 has_brem_candidate = true;
138 }
139 }
140 }
141
142 if (!has_brem_candidate) {
143 track->SetTrackStatus(fKillTrackAndSecondaries);
144 G4RunManager::GetRunManager()->AbortEvent();
145 return;
146 }
147
148 /*
149 std::cout << "[TargetBremFilter] : Found brem candidate" << std::endl;
150 */
151
152 // Check if the recoil electron should be killed. If not, postpone
153 // its processing until the brem gamma has been processed.
154 if (kill_recoil_)
155 track->SetTrackStatus(fStopAndKill);
156 else
157 track->SetTrackStatus(fSuspend);
158
159 } else if (step->GetPostStepPoint()->GetKineticEnergy() == 0) {
160 track->SetTrackStatus(fKillTrackAndSecondaries);
161 G4RunManager::GetRunManager()->AbortEvent();
162 return;
163 }
164}
165
167} // namespace biasing
168
#define DECLARE_ACTION(CLASS)
register a new UserAction with its factory
Definition UserAction.h:206
User action that allows a user to filter out events that don't result in a brem within the target.
void EndOfEventAction(const G4Event *) override
Method called at the end of every event.
TargetBremFilter(const std::string &name, framework::config::Parameters &parameters)
Constructor.
void stepping(const G4Step *step) override
Implement the stepping action which performs the target volume biasing.
G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track *aTrack, const G4ClassificationOfNewTrack &currentTrackClass) override
Classify a new track which postpones track processing.
bool kill_recoil_
Flag indicating if the recoil electron track should be killed.
double brem_energy_threshold_
Brem gamma energy treshold.
double recoil_max_p_threshold_
Recoil electron threshold.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
UserEventInformation * getEventInfo() const
Get a handle to the event information.
void incBremCandidateCount()
Increment the number of brem candidates in an event.
static UserTrackInformation * get(const G4Track *track)
get
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...