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/G4User/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.get<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 volume_name = volume->GetName();
31 // looking for ecal volumes
32 if (volume_name.contains("volume") and
33 (volume_name.contains("Si") or volume_name.contains("W") or
34 volume_name.contains("CFMix") or volume_name.contains("PCB") or
35 volume_name.contains("Al"))) {
36 volumes_.push_back(volume);
37 }
38 }
39
40 ldmx_log(trace) << "Looking for A' in: ";
41 for (auto const& volume : volumes_) {
42 ldmx_log(trace) << "\t" << volume->GetName() << ", ";
43 }
44}
45
47 found_ap_ = false;
48 return;
49}
50
51G4ClassificationOfNewTrack EcalDarkBremFilter::classifyNewTrack(
52 const G4Track* aTrack, const G4ClassificationOfNewTrack& cl) {
53 if (aTrack->GetParticleDefinition() == G4APrime::APrime()) {
54 // there is an A'! Yay!
55 ldmx_log(trace) << "Found A', still need to check if it originated in "
56 "requested volume.";
57
58 if (not found_ap_ and aTrack->GetTotalEnergy() > threshold_) {
59 // The A' is the first one created in this event and is above the energy
60 // threshold
61 found_ap_ = true;
62 } else if (found_ap_) {
63 abortEvent("Found more than one A' during filtering.");
64 } else {
65 abortEvent("A' was not produced above the required threshold.");
66 }
67 }
68
69 return cl;
70}
71
73 if (not found_ap_) abortEvent("A' wasn't produced.");
74
75 return;
76}
77
79 // Check that generational stacking is working
80 ldmx_log(trace) << track->GetTrackID() << " "
81 << track->GetParticleDefinition()->GetPDGEncoding();
82
83 const G4VProcess* creator = track->GetCreatorProcess();
84 if (creator and
85 creator->GetProcessName().contains(G4DarkBremsstrahlung::PROCESS_NAME)) {
86 // make sure all secondaries of dark brem process are saved
89 // make sure A' is persisted into output file
90 user_info->setSaveFlag(true);
91 if (track->GetParticleDefinition() == G4APrime::APrime()) {
92 // check if A' was made in the desired volume and has the minimum energy
93 if (not inDesiredVolume(track)) {
94 abortEvent("A' wasn't produced inside of the requested volume.");
95 } // A' was made in desired volume and has the minimum energy
96 } // track was A'
97 } // track created by dark brem process
98
99 return;
100}
101
102bool EcalDarkBremFilter::inDesiredVolume(const G4Track* track) const {
108 auto in_vol = track->GetLogicalVolumeAtVertex();
109 for (auto const& volume : volumes_) {
110 if (in_vol == volume) return true;
111 }
112
113 return false;
114}
115
116} // namespace biasing
117
#define DECLARE_ACTION(CLASS)
register a new UserAction with its factory
Definition UserAction.h:215
This class is meant to filter for events that produce a dark brem occuring within the ECal and produc...
void newStage() override
When using the PartialEnergySorter, the first time that a new stage begins is when all particles are ...
void postUserTrackingAction(const G4Track *track) override
Make sure A' is saved.
bool found_ap_
Have we found the A' yet?
double threshold_
Minimum energy [MeV] that the A' should have to keep the event.
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 beginOfEventAction(const G4Event *event) override
Reset flag on if A' has been found.
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...
EcalDarkBremFilter(const std::string &name, framework::config::Parameters &parameters)
Class constructor.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
void abortEvent(const std::string &reason) const
Helper to abort an event with a message.
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.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...