LDMX Software
EcalProcessFilter.cxx
1/*~~~~~~~~~~~~~*/
2/* Biasing */
3/*~~~~~~~~~~~~~*/
4#include "Biasing/EcalProcessFilter.h"
5
6/*~~~~~~~~~~~~*/
7/* Geant4 */
8/*~~~~~~~~~~~~*/
9#include "G4EventManager.hh"
10#include "G4RunManager.hh"
11#include "G4Step.hh"
12#include "G4Track.hh"
13
14/*~~~~~~~~~~~~~*/
15/* SimCore */
16/*~~~~~~~~~~~~~*/
17#include "SimCore/G4User/PtrRetrieval.h"
18#include "SimCore/G4User/UserTrackInformation.h"
19
20namespace biasing {
21
22EcalProcessFilter::EcalProcessFilter(const std::string& name,
24 : simcore::UserAction(name, parameters) {
25 process_ = parameters.get<std::string>("process");
26}
27
28G4ClassificationOfNewTrack EcalProcessFilter::ClassifyNewTrack(
29 const G4Track* track, const G4ClassificationOfNewTrack& currentTrackClass) {
30 // Get the particle type.
31 G4String particle_name = track->GetParticleDefinition()->GetParticleName();
32
33 if (track == current_track_) {
34 /*
35 std::cout << "[ EcalProcessFilter ]: "
36 << "Putting track " << track->GetTrackID()
37 << " onto waiting stack." << std::endl;
38 */
39 current_track_ = nullptr;
40 return fWaiting;
41 }
42
43 // Use current classification by default so values from other plugins are not
44 // overridden.
45 G4ClassificationOfNewTrack classification = currentTrackClass;
46
47 return classification;
48}
49
50void EcalProcessFilter::stepping(const G4Step* step) {
51 static auto calorimeter_region =
52 simcore::g4user::ptrretrieval::getRegion("CalorimeterRegion");
53 if (!calorimeter_region) {
54 ldmx_log(warn)
55 << "Region 'CalorimeterRegion' not found in Geant4 region store";
56 }
57 // Get the track associated with this step.
58 auto track{step->GetTrack()};
59
60 if (G4EventManager::GetEventManager()->GetConstCurrentEvent()->IsAborted())
61 return;
62
63 // Get the track info and check if this track is a brem candidate
64 auto track_info{simcore::UserTrackInformation::get(track)};
65 if ((track_info != nullptr) && !track_info->isBremCandidate()) return;
66
67 // Get the particles daughters.
68 auto secondaries{step->GetSecondary()};
69
70 // Get the region the particle is currently in. Continue processing
71 // the particle only if it's in the calorimeter region.
72 auto phys_vol{track->GetVolume()};
73 auto lv{phys_vol ? phys_vol->GetLogicalVolume() : nullptr};
74 auto region{lv ? lv->GetRegion() : nullptr};
75 if (region != calorimeter_region) {
76 // If secondaries were produced outside of the volume of interest,
77 // and there aren't additional brems to process, abort the
78 // event. Otherwise, suspend the track and move on to the next
79 // brem.
80 if (secondaries->size() != 0) {
81 /*
82 std::cout << "[ EcalProcessFilter ]: "
83 <<
84 G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID()
85 << " secondaries outside ecal...";
86 */
87 if (getEventInfo()->bremCandidateCount() == 1) {
88 // std::cout << "aborting the event." << std::endl;
89 track->SetTrackStatus(fKillTrackAndSecondaries);
90 G4RunManager::GetRunManager()->AbortEvent();
91 current_track_ = nullptr;
92 } else {
93 /*
94 std::cout << "suspending the track " << track->GetTrackID()
95 << " , " << getEventInfo()->bremCandidateCount() << " brems left."
96 << std::endl;
97 */
98 current_track_ = track;
99 track->SetTrackStatus(fSuspend);
100 getEventInfo()->decBremCandidateCount();
101 track_info->tagBremCandidate(false);
102 }
103 }
104 return;
105 }
106
107 // If the particle doesn't interact, then move on to the next step.
108 if (secondaries->size() == 0) {
115 static auto volume_after_exiting_ecal =
116 simcore::g4user::ptrretrieval::getLogicalVolume("hadronic_calorimeter");
117 if (!volume_after_exiting_ecal) {
118 ldmx_log(warn) << "Unable to find 'hadronic_calorimeter' logical volume.";
119 }
120 auto next_phys_vol = track->GetNextVolume();
121 auto next_log_vol{next_phys_vol ? next_phys_vol->GetLogicalVolume()
122 : nullptr};
123 if (next_log_vol == volume_after_exiting_ecal) {
124 /*
125 std::cout << "[ EcalProcessFilter ]: "
126 <<
127 G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID()
128 << " no secondaries when leaving ecal...";
129 */
130 if (getEventInfo()->bremCandidateCount() == 1) {
131 // std::cout << "aborting the event." << std::endl;
132 track->SetTrackStatus(fKillTrackAndSecondaries);
133 G4RunManager::GetRunManager()->AbortEvent();
134 current_track_ = nullptr;
135 } else {
136 /*
137 std::cout << "suspending the track " << track->GetTrackID()
138 << " , " << getEventInfo()->bremCandidateCount() << " brems left."
139 << std::endl;
140 */
141 current_track_ = track;
142 track->SetTrackStatus(fSuspend);
143 getEventInfo()->decBremCandidateCount();
144 track_info->tagBremCandidate(false);
145 }
146 }
147
148 return;
149 } else {
150 // If the brem gamma interacts and produces secondaries, get the
151 // process used to create them.
152 auto process_name{
153 secondaries->at(0)->GetCreatorProcess()->GetProcessName()};
154
155 // Only record the process that is being biased
156 if (!process_name.contains(process_)) {
157 /*
158 std::cout << "[ EcalProcessFilter ]: "
159 <<
160 G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID()
161 << " not PN products...";
162 */
163 if (getEventInfo()->bremCandidateCount() == 1) {
164 // std::cout << "aborting the event." << std::endl;
165 track->SetTrackStatus(fKillTrackAndSecondaries);
166 G4RunManager::GetRunManager()->AbortEvent();
167 current_track_ = nullptr;
168 } else {
169 /*
170 std::cout << "suspending the track " << track->GetTrackID()
171 << " , " << getEventInfo()->bremCandidateCount() << " brems left."
172 << std::endl;
173 */
174 current_track_ = track;
175 track->SetTrackStatus(fSuspend);
176 getEventInfo()->decBremCandidateCount();
177 track_info->tagBremCandidate(false);
178 }
179 return;
180 }
181
182 ldmx_log(info) << " Brem photon produced " << secondaries->size()
183 << " particles via " << process_name << " process.";
184 track_info->tagBremCandidate(false);
185 track_info->setSaveFlag(true);
186 track_info->tagPNGamma();
187 getEventInfo()->decBremCandidateCount();
188 }
189}
190} // namespace biasing
191
#define DECLARE_ACTION(CLASS)
register a new UserAction with its factory
Definition UserAction.h:206
User action plugin that filters events that don't see a hard brem from the target undergo a photo-nuc...
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
static UserTrackInformation * get(const G4Track *track)
get
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...