LDMX Software
DeepEcalProcessFilter.cxx
2
3/*~~~~~~~~~~~~*/
4/* Geant4 */
5/*~~~~~~~~~~~~*/
6#include "G4EventManager.hh"
7#include "G4RunManager.hh"
8#include "G4Step.hh"
9#include "G4String.hh"
10#include "G4Track.hh"
11
12/*~~~~~~~~~~~~~*/
13/* SimCore */
14/*~~~~~~~~~~~~~*/
15#include "SimCore/UserEventInformation.h"
16#include "SimCore/UserTrackInformation.h"
17
18namespace biasing {
19
21 const std::string& name, framework::config::Parameters& parameters)
22 : simcore::UserAction(name, parameters) {
23 bias_threshold_ = parameters.getParameter<double>("bias_threshold");
24 processes_ = parameters.getParameter<std::vector<std::string>>("processes");
25 ecal_min_Z_ = parameters.getParameter<double>("ecal_min_Z");
27 parameters.getParameter<bool>("require_photon_fromTarget");
28}
29
31 hasDeepEcalProcess_ = false;
32 photonFromTarget_ = false;
33}
34
35void DeepEcalProcessFilter::stepping(const G4Step* step) {
36 // Get the track associated with this step.
37 auto track{step->GetTrack()};
38
39 // Check the creation process and PDG ID of the particle
40 auto processName = track->GetCreatorProcess()
41 ? track->GetCreatorProcess()->GetProcessName()
42 : "unknown";
43 auto PDGid = track->GetParticleDefinition()->GetPDGEncoding();
44
45 // Skip the steps that are for the recoil electron
46 // PrimaryToEcalFilter made sure there is a fiducial e-
47 if (processName.contains("unknown")) return;
48
49 // Energy of the particle is below threshold, move to next step
50 if (track->GetKineticEnergy() < bias_threshold_) {
51 return;
52 }
53
54 // Check in which volume the particle is currently
55 auto volume{track->GetVolume()->GetLogicalVolume()
56 ? track->GetVolume()->GetLogicalVolume()->GetName()
57 : "undefined"};
58
59 auto trackInfo{simcore::UserTrackInformation::get(track)};
60 // Tag the brem photon from the primary electron
61 if (processName.contains("eBrem") and (track->GetParentID() == 1)) {
62 trackInfo->tagBremCandidate();
64 trackInfo->setSaveFlag(true);
65 if (volume.contains("target")) {
66 photonFromTarget_ = true;
67 }
68 }
69
70 // If we require that the photon comes from the target and
71 // and if it does not, let's skip the event
72 if (require_photon_fromTarget_ and !photonFromTarget_) {
73 return;
74 }
75
76 // Tag if the event has the processes we are looking for
77 bool hasProcessNeeded{false};
78 for (auto& process : processes_) {
79 // ldmx_log(debug) << "Allowed processed " << process << " now we have " <<
80 // processName;
81 if (processName.contains(process)) {
82 hasProcessNeeded = true;
83 break;
84 }
85 }
86 // skip this step if it does not have any of the processes needed
87 if (not hasProcessNeeded) return;
88
89 // isInEcal should be taken from
90 // simcore::logical_volume_tests::isInEcal(volume) but for now it's under
91 // its own namespace so I cannot reach it here, see issue
92 // https://github.com/LDMX-Software/ldmx-sw/issues/1286
93 auto isInEcal{((volume.contains("Si") || volume.contains("W") ||
94 volume.contains("PCB") || volume.contains("strongback") ||
95 volume.contains("Glue") || volume.contains("CFMix") ||
96 volume.contains("Al") || volume.contains("C")) &&
97 volume.contains("volume")) ||
98 (volume.contains("nohole_motherboard"))};
99
100 // Skip this step if it does not have the processes needed
101 // or if it's not in the ECAL
102 if (not isInEcal) return;
103
104 // Check the z position of the particle, and
105 // flag if it is deeper than the min Z we are considering (but in ECAL)
106 auto zPosition = step->GetPreStepPoint()->GetPosition().z();
107 // Printout for testing
108 if (zPosition > (0.75 * ecal_min_Z_)) {
109 ldmx_log(debug) << " Particle ID " << PDGid << " with energy "
110 << track->GetKineticEnergy() << " on " << volume << " from "
111 << processName << " at Z = " << zPosition;
112 if (zPosition > ecal_min_Z_) {
113 hasDeepEcalProcess_ = true;
114 }
115 }
116 return;
117}
118
121 ldmx_log(debug) << "> Event with a hard deep conversion found, yaaay!";
122 ldmx_log(debug) << "> -----------------------------------------";
123 } else {
124 // ldmx_log(debug) << "> -----------------------------------------";
125 G4RunManager::GetRunManager()->AbortEvent();
126 }
127}
128} // namespace biasing
129
130DECLARE_ACTION(biasing, DeepEcalProcessFilter)
Class defining a UserActionPlugin that allows a user to filter out events where the interaction happe...
void NewStage() override
Method called at the beginning of a new stage.
bool hasDeepEcalProcess_
member used to help tag events that have a deep-ecal process ocurr
DeepEcalProcessFilter(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.
double bias_threshold_
Minimal energy the products should have.
std::vector< std::string > processes_
The allowed processes that can happen deep inside the ECAL, default is conversion (conv) and photoele...
void BeginOfEventAction(const G4Event *event) override
Method to set flags in the beginning of the event.
double ecal_min_Z_
Minimum Z location where the deep process should happen.
bool require_photon_fromTarget_
Require that the hard brem photon originates from the target.
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
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
void tagBremCandidate(bool isBremCandidate=true)
Tag this track as a brem candidate by the biasing filters.