32 const G4ThreeVector& localPosition,
34 const unsigned int version{copyNumber / 0x01000000};
37 return ldmx::HcalID{Index(copyNumber).field2(), Index(copyNumber).field1(),
38 Index(copyNumber).field0()};
42 unsigned int strip_id = 0;
43 const unsigned int section = copyNumber / 1000;
44 const unsigned int layer = copyNumber % 1000;
47 if (section == ldmx::HcalID::BACK) {
48 if (geometry.backLayerIsHorizontal(layer)) {
49 strip_id = int((localPosition.y() + scint->GetYHalfLength()) / 50.0);
51 strip_id = int((localPosition.x() + scint->GetXHalfLength()) / 50.0);
54 strip_id = int((localPosition.z() + scint->GetZHalfLength()) / 50.0);
61 G4double edep = aStep->GetTotalEnergyDeposit();
65 ldmx_log(trace) <<
"CalorimeterSD skipping step with zero edep.";
97 G4double birks_factor(1.0);
98 G4double step_length = aStep->GetStepLength() / CLHEP::cm;
101 if (step_length > 1.0e-6) {
102 G4double rho = aStep->GetPreStepPoint()->GetMaterial()->GetDensity() /
103 (CLHEP::g / CLHEP::cm3);
104 G4double dedx = edep / (rho * step_length);
105 birks_factor = 1.0 / (1.0 + birksc1_ * dedx + birksc2_ * dedx * dedx);
106 if (aStep->GetTrack()->GetDefinition() == G4Gamma::GammaDefinition())
108 if (aStep->GetTrack()->GetDefinition() == G4Neutron::NeutronDefinition())
113 edep *= birks_factor;
116 G4Box* scint =
nullptr;
119 const auto* pre_step_point = aStep->GetPreStepPoint();
120 if (pre_step_point) {
121 const auto& touchable_handle = pre_step_point->GetTouchableHandle();
122 if (touchable_handle) {
123 const auto* volume = touchable_handle->GetVolume();
126 const auto* logical_volume = volume->GetLogicalVolume();
127 if (logical_volume) {
128 auto* solid = logical_volume->GetSolid();
130 scint =
static_cast<G4Box*
>(solid);
139 G4StepPoint* pre_point = aStep->GetPreStepPoint();
140 G4StepPoint* post_point = aStep->GetPostStepPoint();
149 auto touchable_history{pre_point->GetTouchableHandle()->GetHistory()};
151 auto top_transform{touchable_history->GetTopTransform()};
152 G4ThreeVector position =
153 0.5 * (pre_point->GetPosition() + post_point->GetPosition());
154 G4ThreeVector local_position = top_transform.TransformPoint(position);
160 int copy_num = touchable_history->GetVolume(2)->GetCopyNo();
165 auto& new_hit =
hits_[id];
166 new_hit.setID(
id.raw());
167 new_hit.setPosition(position[0], position[1], position[2]);
170 auto& hit =
hits_[id];
173 const G4Track* track = aStep->GetTrack();
174 auto time = track->GetGlobalTime();
175 auto track_id = track->GetTrackID();
176 auto pdg = track->GetParticleDefinition()->GetPDGEncoding();
179 int contrib_i = hit.findContribIndex(track_id, pdg);
181 hit.updateContrib(contrib_i, edep, time);
184 auto incident{map.findIncident(track_id)};
188 int origin{incident};
190 if (map.isDescendant(track_id, i, 100)) {
195 hit.addContrib(incident, track_id, pdg, edep, time, origin);
199 hit.setEdep(hit.getEdep() + edep);
200 if (time < hit.getTime() or hit.getTime() == 0) {
209 hit.setPathLength(step_length * CLHEP::cm / CLHEP::mm);
210 hit.setVelocity(track->GetVelocity());
215 const auto local_pre_step_point{
216 top_transform.TransformPoint(pre_point->GetPosition())};
217 const auto local_post_step_point{
218 top_transform.TransformPoint(post_point->GetPosition())};
222 auto local_pre_position_rotated{geometry.rotateGlobalToLocalBarPosition(
223 {local_pre_step_point[0], local_pre_step_point[1],
224 local_pre_step_point[2]},
227 auto local_post_position_rotated{geometry.rotateGlobalToLocalBarPosition(
228 {local_post_step_point[0], local_post_step_point[1],
229 local_post_step_point[2]},
231 hit.setPreStepPosition(local_pre_position_rotated[0],
232 local_pre_position_rotated[1],
233 local_pre_position_rotated[2]);
234 hit.setPostStepPosition(local_post_position_rotated[0],
235 local_post_position_rotated[1],
236 local_post_position_rotated[2]);
237 hit.setPreStepTime(pre_point->GetGlobalTime());
238 hit.setPostStepTime(post_point->GetGlobalTime());
240 ldmx_log(trace) << hit;