LDMX Software
EcalSD.cxx
2
3namespace simcore {
4
5const std::string EcalSD::COLLECTION_NAME = "EcalSimHits";
6
7EcalSD::EcalSD(const std::string& name, simcore::ConditionsInterface& ci,
9 : SensitiveDetector(name, ci, p) {
10 enable_hit_contribs_ = p.get<bool>("enableHitContribs");
11 compress_hit_contribs_ = p.get<bool>("compressHitContribs");
12 max_origin_track_id_ = p.get<int>("max_origin_track_id");
13}
14
15G4bool EcalSD::ProcessHits(G4Step* aStep, G4TouchableHistory*) {
16 static const int layer_depth = 2; // index depends on GDML implementation
17 const auto& geometry = getCondition<ldmx::EcalGeometry>(
18 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
19
20 // Get the edep from the step.
21 G4double edep = aStep->GetTotalEnergyDeposit();
22
23 // Skip steps with no energy dep which come from non-Geantino particles.
24 if (edep == 0.0 and not isGeantino(aStep)) {
25 ldmx_log(trace) << "CalorimeterSD skipping step with zero edep.";
26 return false;
27 }
28
29 // Compute the hit position
30 G4StepPoint* pre_point = aStep->GetPreStepPoint();
31 G4StepPoint* post_point = aStep->GetPostStepPoint();
32 G4ThreeVector position =
33 0.5 * (pre_point->GetPosition() + post_point->GetPosition());
34
35 // Create the ID for the hit.
36 int cpynum{0}; // Initialize cpynum to 0
37
38 auto pre_step_point = aStep->GetPreStepPoint();
39 if (pre_step_point) {
40 const auto& touchable_handle = pre_step_point->GetTouchableHandle();
41 if (touchable_handle) {
42 auto history = touchable_handle->GetHistory();
43 if (history) {
44 auto volume = history->GetVolume(layer_depth);
45 if (volume) {
46 cpynum = volume->GetCopyNo();
47 }
48 }
49 }
50 }
51 int layer_number;
52 layer_number = cpynum / 7;
53 int module_position = cpynum % 7;
65 // fastest, but need to trust module number between GDML and EcalGeometry
66 // match
67 ldmx::EcalID id =
68 geometry.getID(position.x(), position.y(), layer_number, module_position);
69
70 // medium, only need to trust z-layer positions in GDML and EcalGeometry match
71 // helpful for debugging any issues where transverse position is not
72 // matching between the GDML and EcalGeometry
73 // ldmx::EcalID id = geometry.getID(position[0], position[1], layerNumber);
74
75 // slowest, completely rely on EcalGeometry
76 // this is helpful for validating the EcalGeometry implementation and
77 // configuration since this will be called with any hit position that
78 // is inside of the configured SD volumes from Geant4's point of view
79 // ldmx::EcalID id = geometry.getID(position[0], position[1], position[2]);
80
81 if (hits_.find(id) == hits_.end()) {
82 // hit in empty cell
83 auto& hit = hits_[id];
84 hit.setID(id.raw());
85 hit.setPosition(position.x(), position.y(), position.z());
86 }
87
88 auto& hit = hits_[id];
89
90 // hit variables
91 auto track = aStep->GetTrack();
92 auto time = track->GetGlobalTime();
93 auto track_id = track->GetTrackID();
94 auto pdg = track->GetParticleDefinition()->GetPDGEncoding();
95
97 int contrib_i = hit.findContribIndex(track_id, pdg);
98 if (compress_hit_contribs_ and contrib_i != -1) {
99 hit.updateContrib(contrib_i, edep, time);
100 } else {
101 auto map{getTrackMap()};
102 auto incident{map.findIncident(track_id)};
103 // default "origin" is just the same as incident
104 // "origin" checks if a hit "originates" from one of the earliest
105 // track IDs (i.e. probably one of the primaries)
106 int origin{incident};
107 for (int i{1}; i < max_origin_track_id_; ++i) {
108 if (map.isDescendant(track_id, i, 100)) {
109 origin = i;
110 break;
111 }
112 }
113 hit.addContrib(incident, track_id, pdg, edep, time, origin);
114 }
115 } else {
116 // no hit contribs and hit already exists
117 hit.setEdep(hit.getEdep() + edep);
118 if (time < hit.getTime() or hit.getTime() == 0) {
119 hit.setTime(time);
120 }
121 }
122
123 return true;
124}
125
127 // squash hits into list
128 std::vector<ldmx::SimCalorimeterHit> hits;
129 hits.reserve(hits_.size());
130 for (const auto& [id, hit] : hits_) hits.push_back(hit);
131 event.add(COLLECTION_NAME, hits);
132}
133
134} // namespace simcore
135
136DECLARE_SENSITIVEDETECTOR(simcore::EcalSD)
Class defining an ECal sensitive detector using an EcalHexReadout to create the hits_.
Implements an event buffer system for storing event data.
Definition Event.h:42
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
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Definition EcalID.h:20
Handle to the conditions system, provided at construction to classes which require it.
ECal sensitive detector that uses an EcalHexReadout to create the hits_.
Definition EcalSD.h:37
static const std::string COLLECTION_NAME
Name of output collection of hits_.
Definition EcalSD.h:40
std::map< ldmx::EcalID, ldmx::SimCalorimeterHit > hits_
map of hits to add to the event (will be squashed)
Definition EcalSD.h:88
EcalSD(const std::string &name, simcore::ConditionsInterface &ci, const framework::config::Parameters &p)
Class constructor.
Definition EcalSD.cxx:7
virtual void saveHits(framework::Event &event) override
Add our hits to the event bus.
Definition EcalSD.cxx:126
int max_origin_track_id_
maximum track ID to be considered an "origin"
Definition EcalSD.h:94
bool enable_hit_contribs_
enable hit contribs
Definition EcalSD.h:90
G4bool ProcessHits(G4Step *aStep, G4TouchableHistory *ROhist) override
Process steps to create hits_.
Definition EcalSD.cxx:15
bool compress_hit_contribs_
compress hit contribs
Definition EcalSD.h:92
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.
const TrackMap & getTrackMap() const
Get a handle to the current track map.
const T & getCondition(const std::string &condition_name)
Record the configuration of this detector into the run header.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...