LDMX Software
EcalDarkBremFilter.cxx
1/*
2 * @file EcalDarkBremFilter.cxx
3 * @class EcalDarkBremFilter
4 * @brief Class defining a UserActionPlugin that allows a user to filter out
5 * events that don't result in a dark brem within a given volume
6 * @author Michael Revering, University of Minnesota
7 * @author Tom Eichlersmith, University of Minnesota
8 */
9
11
12#include "G4DarkBreM/G4APrime.h" //checking if particles match A'
13#include "G4DarkBreM/G4DarkBremsstrahlung.h" //checking for dark brem secondaries
14#include "G4LogicalVolumeStore.hh" //for the store
15#include "SimCore/UserTrackInformation.h" //make sure A' is saved
16
17namespace biasing {
18
20 const std::string& name, framework::config::Parameters& parameters)
21 : simcore::UserAction(name, parameters) {
22 threshold_ = parameters.getParameter<double>("threshold");
23
24 /*
25 * We look for the logical volumes that match the following pattern:
26 * - 'volume' is in the name AND
27 * - 'Si' OR 'W' OR 'CFMix' OR 'PCB' are in the name
28 */
29 for (G4LogicalVolume* volume : *G4LogicalVolumeStore::GetInstance()) {
30 G4String volumeName = volume->GetName();
31 // looking for ecal volumes
32 if (volumeName.contains("volume") and
33 (volumeName.contains("Si") or volumeName.contains("W") or
34 volumeName.contains("CFMix") or volumeName.contains("PCB") or
35 volumeName.contains("Al"))) {
36 volumes_.push_back(volume);
37 }
38 }
39
40 if (G4RunManager::GetRunManager()->GetVerboseLevel() > 0) {
41 std::cout << "[ EcalDarkBremFilter ]: "
42 << "Looking for A' in: ";
43 for (auto const& volume : volumes_) std::cout << volume->GetName() << ", ";
44 std::cout << std::endl;
45 }
46}
47
49 /* Debug message
50 std::cout << "[ EcalDarkBremFilter ]: "
51 << "(" <<
52 G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID() << ")
53 "
54 << "Beginning event."
55 << std::endl;
56 */
57 foundAp_ = false;
58 return;
59}
60
61G4ClassificationOfNewTrack EcalDarkBremFilter::ClassifyNewTrack(
62 const G4Track* aTrack, const G4ClassificationOfNewTrack& cl) {
63 if (aTrack->GetParticleDefinition() == G4APrime::APrime()) {
64 // there is an A'! Yay!
65 /* Debug message
66 std::cout << "[ EcalDarkBremFilter ]: "
67 << "Found A', still need to check if it originated in requested
68 volume."
69 << std::endl;
70 */
71 if (not foundAp_ and aTrack->GetTotalEnergy() > threshold_) {
72 // The A' is the first one created in this event and is above the energy
73 // threshold
74 foundAp_ = true;
75 } else if (foundAp_) {
76 AbortEvent("Found more than one A' during filtering.");
77 } else {
78 AbortEvent("A' was not produced above the required threshold.");
79 }
80 }
81
82 return cl;
83}
84
86 if (not foundAp_) AbortEvent("A' wasn't produced.");
87
88 return;
89}
90
92 /* Check that generational stacking is working
93 std::cout << "[ EcalDarkBremFilter ]:"
94 << track->GetTrackID() << " " <<
95 track->GetParticleDefinition()->GetPDGEncoding()
96 << std::endl;
97 */
98
99 const G4VProcess* creator = track->GetCreatorProcess();
100 if (creator and
101 creator->GetProcessName().contains(G4DarkBremsstrahlung::PROCESS_NAME)) {
102 // make sure all secondaries of dark brem process are saved
105 // make sure A' is persisted into output file
106 userInfo->setSaveFlag(true);
107 if (track->GetParticleDefinition() == G4APrime::APrime()) {
108 // check if A' was made in the desired volume and has the minimum energy
109 if (not inDesiredVolume(track)) {
110 AbortEvent("A' wasn't produced inside of the requested volume.");
111 } // A' was made in desired volume and has the minimum energy
112 } // track was A'
113 } // track created by dark brem process
114
115 return;
116}
117
118bool EcalDarkBremFilter::inDesiredVolume(const G4Track* track) const {
124 auto inVol = track->GetLogicalVolumeAtVertex();
125 for (auto const& volume : volumes_) {
126 if (inVol == volume) return true;
127 }
128
129 return false;
130}
131
132void EcalDarkBremFilter::AbortEvent(const std::string& reason) const {
133 if (G4RunManager::GetRunManager()->GetVerboseLevel() > 1) {
134 std::cout << "[ EcalDarkBremFilter ]: "
135 << "("
136 << G4EventManager::GetEventManager()
137 ->GetConstCurrentEvent()
138 ->GetEventID()
139 << ") " << reason << " Aborting event." << std::endl;
140 }
141 G4RunManager::GetRunManager()->AbortEvent();
142 return;
143}
144} // namespace biasing
145
146DECLARE_ACTION(biasing, EcalDarkBremFilter)
Class defining a simcore::UserActionPlugin that allows a user to filter out events that don't result ...
void BeginOfEventAction(const G4Event *event) override
Reset flag on if A' has been found.
void NewStage() override
When using the PartialEnergySorter, the first time that a new stage begins is when all particles are ...
double threshold_
Minimum energy [MeV] that the A' should have to keep the event.
void PostUserTrackingAction(const G4Track *track) override
Make sure A' is saved.
bool foundAp_
Have we found the A' yet?
bool inDesiredVolume(const G4Track *) const
Check if input volume is in the desired volume name.
std::vector< G4LogicalVolume * > volumes_
The volumes that the filter will be applied to.
void AbortEvent(const std::string &reason) const
Helper to abort an event with a message.
EcalDarkBremFilter(const std::string &name, framework::config::Parameters &parameters)
Class constructor.
G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track *aTrack, const G4ClassificationOfNewTrack &currentTrackClass) override
We return the classification of the track done by the PartialEnergySorter, but we can check here if t...
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:27
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
Provides user defined information to associate with a Geant4 track.
static UserTrackInformation * get(const G4Track *track)
get
void setSaveFlag(bool saveFlag)
Set the save flag so the associated track will be persisted as a Trajectory.