LDMX Software
TrigScintSD.cxx
1#include "SimCore/SDs/TrigScintSD.h"
2
3/*~~~~~~~~~~~~~~*/
4/* DetDescr */
5/*~~~~~~~~~~~~~~*/
6#include "DetDescr/TrigScintID.h"
7
8/*~~~~~~~~~~~~*/
9/* Geant4 */
10/*~~~~~~~~~~~~*/
11#include "G4Step.hh"
12#include "G4StepPoint.hh"
13
14namespace simcore {
15
16TrigScintSD::TrigScintSD(const std::string& name,
19 : SensitiveDetector(name, ci, p) {
20 module_id_ = p.get<int>("module_id");
21 collection_name_ = p.get<std::string>("collection_name");
22 vol_name_ = p.get<std::string>("volume_name");
23 use_birks_law_ = p.get<bool>("use_birks_law");
24 birks_const_one_ = p.get<double>("birks_const_one");
25 birks_const_two_ = p.get<double>("birks_const_two");
26}
27
28G4bool TrigScintSD::ProcessHits(G4Step* step, G4TouchableHistory* history) {
29 // Get the energy deposited by the particle during the step
30 auto energy{step->GetTotalEnergyDeposit()};
31
32 // If a non-Geantino particle doesn't deposit energy during the step,
33 // skip processing it.
34 if (energy == 0 and not isGeantino(step)) {
35 ldmx_log(trace) << "No energy deposited in step, skipping.";
36 return false;
37 }
38
39 // Create a new instance of a calorimeter hit
40 // emplace_back returns a *reference* to the hit that was constructed
41 // and we should keep that reference so that we are editing the correct hit
42 ldmx::SimCalorimeterHit& hit = hits_.emplace_back();
43
44 G4StepPoint* pre_point = step->GetPreStepPoint();
45 G4StepPoint* post_point = step->GetPostStepPoint();
46 if (pre_point == nullptr || post_point == nullptr) {
47 return false;
48 }
49
50 // A Geant4 "touchable" is a way to uniquely identify a particular volume,
51 // short for touchable detector element. See the detector definition and
52 // response section of the Geant4 application developers manual for details.
53 //
54 // The TouchableHandle is just a reference counted pointer to a
55 // G4TouchableHistory object, which is a concrete implementation of a
56 // G4Touchable interface.
57 if (!pre_point->GetTouchableHandle()) {
58 return false;
59 }
60 auto touchable_history{pre_point->GetTouchableHandle()->GetHistory()};
61 // Affine transform for converting between local and global coordinates
62 auto top_transform{touchable_history->GetTopTransform()};
63 // Set the hit position
64 auto position{0.5 * (pre_point->GetPosition() + post_point->GetPosition())};
65
66 // Convert the center of the bar to its corresponding global position
67 auto volume_position{top_transform.Inverse().TransformPoint(G4ThreeVector())};
68 hit.setPosition(position[0], position[1], volume_position.z());
69
70 // Get the track associated with this step
71 auto track{step->GetTrack()};
72
73 // Set the ID on the hit.
74 auto bar{track->GetVolume()->GetCopyNo()};
76 hit.setID(id.raw());
77
78 // Implement Birks law
79 G4double birks_factor(1.0);
80 G4double step_length = step->GetStepLength() / CLHEP::cm;
81 // Do not apply Birks for gamma deposits!
82 // Check, cut if necessary.
83 if (step_length > 1.0e-6) {
84 G4double rho = step->GetPreStepPoint()->GetMaterial()->GetDensity() /
85 (CLHEP::g / CLHEP::cm3);
86 G4double dedx = energy / (rho * step_length); //[MeV*cm^2/g]
87 birks_factor =
88 1.0 / (1.0 + birks_const_one_ * dedx + birks_const_two_ * dedx * dedx);
89 // Birks law is only applied to charged particles
90 if (step->GetTrack()->GetDefinition()->GetPDGCharge() == 0) {
91 birks_factor = 1.0;
92 }
93 }
94
95 // update the energy to include birks_factor
96 if (use_birks_law_) {
97 ldmx_log(trace) << "Applying Birks law with factor: " << birks_factor;
98 energy *= birks_factor;
99 }
100
101 // add single contrib to this calorimeter hit
102 // IncidentID - this track's ID
103 // Track ID
104 // PDG ID
105 // energy deposited
106 // global time of this hit
107 hit.addContrib(track->GetTrackID(), track->GetTrackID(),
108 track->GetParticleDefinition()->GetPDGEncoding(), energy,
109 track->GetGlobalTime());
110
111 // Step details
112 hit.setPathLength(step->GetStepLength());
113 hit.setVelocity(track->GetVelocity());
114 // Convert pre/post step position from global coordinates to coordinates
115 // within the scintillator bar
116 const auto local_pre_step_point{
117 top_transform.TransformPoint(pre_point->GetPosition())};
118 const auto local_post_step_point{
119 top_transform.TransformPoint(post_point->GetPosition())};
120 hit.setPreStepPosition(local_pre_step_point[0], local_pre_step_point[1],
121 local_pre_step_point[2]);
122
123 hit.setPostStepPosition(local_post_step_point[0], local_post_step_point[1],
124 local_post_step_point[2]);
125
126 hit.setPreStepTime(pre_point->GetGlobalTime());
127 hit.setPostStepTime(post_point->GetGlobalTime());
128
129 return true;
130}
131
132} // namespace simcore
133
134DECLARE_SENSITIVEDETECTOR(simcore::TrigScintSD)
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
Stores simulated calorimeter hit information.
void setPreStepTime(const float time)
Set global pre-step time of the hit [ns].
void setPathLength(const float length)
Set the physical path length for the interaction [mm].
void setPosition(const float x, const float y, const float z)
Set the XYZ position of the hit [mm].
void setPostStepPosition(const float x, const float y, const float z)
Set the XYZ post-step position of the hit in the coordinate frame of the sensitive volume [mm].
void setID(const int id)
Set the detector ID.
void setPostStepTime(const float time)
Set global post-step time of the hit [ns].
void addContrib(int incidentID, int trackID, int pdgCode, float edep, float time, int originID=-1)
Add a hit contribution from a SimParticle.
void setPreStepPosition(const float x, const float y, const float z)
Set the XYZ pre-step position of the hit in the coordinate frame of the sensitive volume [mm].
void setVelocity(float velocity)
Set the velocity of the track [mm/ns].
Class that defines the detector ID of the trigger scintillator.
Definition TrigScintID.h:14
Handle to the conditions system, provided at construction to classes which require it.
Dynamically loaded Geant4 SensitiveDetector for saving hits in specific volumes within the simulation...
bool isGeantino(const G4Step *step) const
Check if the passed step is a step of a geantino.
Class defining a sensitive detector of type trigger scintillator.
Definition TrigScintSD.h:12
std::string vol_name_
name of trigger pad volume this SD is capturing
Definition TrigScintSD.h:65
bool use_birks_law_
Whether to use Birks law for energy deposition.
Definition TrigScintSD.h:69
G4bool ProcessHits(G4Step *step, G4TouchableHistory *history) override
Process steps to create hits_.
double birks_const_two_
Birks law constants c2.
Definition TrigScintSD.h:73
std::string collection_name_
name of the hit collection for this SD
Definition TrigScintSD.h:63
std::vector< ldmx::SimCalorimeterHit > hits_
our collection of hits in this SD
Definition TrigScintSD.h:61
double birks_const_one_
Birks law constants c1.
Definition TrigScintSD.h:71
TrigScintSD(const std::string &name, simcore::ConditionsInterface &ci, const framework::config::Parameters &p)
Class constructor.
int module_id_
the ID number for the module we are gathering hits from
Definition TrigScintSD.h:67
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...