34 const G4ThreeVector& localPosition,
36 const unsigned int version{copyNumber / 0x01000000};
39 return ldmx::HcalID{Index(copyNumber).field2(), Index(copyNumber).field1(),
40 Index(copyNumber).field0()};
44 unsigned int strip_id = 0;
45 const unsigned int section = copyNumber / 1000;
46 const unsigned int layer = copyNumber % 1000;
49 if (section == ldmx::HcalID::BACK) {
50 if (geometry.backLayerIsHorizontal(layer)) {
51 strip_id = int((localPosition.y() + scint->GetYHalfLength()) / 50.0);
53 strip_id = int((localPosition.x() + scint->GetXHalfLength()) / 50.0);
56 strip_id = int((localPosition.z() + scint->GetZHalfLength()) / 50.0);
63 G4double edep = aStep->GetTotalEnergyDeposit();
67 ldmx_log(trace) <<
"CalorimeterSD skipping step with zero edep.";
99 G4double birks_factor(1.0);
100 G4double step_length = aStep->GetStepLength() / CLHEP::cm;
103 if (step_length > 1.0e-6) {
104 G4double rho = aStep->GetPreStepPoint()->GetMaterial()->GetDensity() /
105 (CLHEP::g / CLHEP::cm3);
106 G4double dedx = edep / (rho * step_length);
107 birks_factor = 1.0 / (1.0 + birksc1_ * dedx + birksc2_ * dedx * dedx);
108 if (aStep->GetTrack()->GetDefinition() == G4Gamma::GammaDefinition())
110 if (aStep->GetTrack()->GetDefinition() == G4Neutron::NeutronDefinition())
115 edep *= birks_factor;
118 G4Box* scint =
nullptr;
121 const auto* pre_step_point = aStep->GetPreStepPoint();
122 if (pre_step_point) {
123 const auto& touchable_handle = pre_step_point->GetTouchableHandle();
124 if (touchable_handle) {
125 const auto* volume = touchable_handle->GetVolume();
128 const auto* logical_volume = volume->GetLogicalVolume();
129 if (logical_volume) {
130 auto* solid = logical_volume->GetSolid();
132 scint =
static_cast<G4Box*
>(solid);
141 G4StepPoint* pre_point = aStep->GetPreStepPoint();
142 G4StepPoint* post_point = aStep->GetPostStepPoint();
151 auto touchable_history{pre_point->GetTouchableHandle()->GetHistory()};
153 auto top_transform{touchable_history->GetTopTransform()};
154 G4ThreeVector position =
155 0.5 * (pre_point->GetPosition() + post_point->GetPosition());
156 G4ThreeVector local_position = top_transform.TransformPoint(position);
162 int copy_num = touchable_history->GetVolume(2)->GetCopyNo();
167 auto& new_hit =
hits_[id];
168 new_hit.setID(
id.raw());
169 new_hit.setPosition(position[0], position[1], position[2]);
172 auto& hit =
hits_[id];
175 const G4Track* track = aStep->GetTrack();
176 auto time = track->GetGlobalTime();
177 auto track_id = track->GetTrackID();
178 auto pdg = track->GetParticleDefinition()->GetPDGEncoding();
181 int contrib_i = hit.findContribIndex(track_id, pdg);
183 hit.updateContrib(contrib_i, edep, time);
186 auto incident{map.findIncident(track_id)};
190 int origin{incident};
192 if (map.isDescendant(track_id, i, 100)) {
197 hit.addContrib(incident, track_id, pdg, edep, time, origin);
201 hit.setEdep(hit.getEdep() + edep);
202 if (time < hit.getTime() or hit.getTime() == 0) {
211 hit.setPathLength(step_length * CLHEP::cm / CLHEP::mm);
212 hit.setVelocity(track->GetVelocity());
217 const auto local_pre_step_point{
218 top_transform.TransformPoint(pre_point->GetPosition())};
219 const auto local_post_step_point{
220 top_transform.TransformPoint(post_point->GetPosition())};
224 auto local_pre_position_rotated{geometry.rotateGlobalToLocalBarPosition(
225 {local_pre_step_point[0], local_pre_step_point[1],
226 local_pre_step_point[2]},
229 auto local_post_position_rotated{geometry.rotateGlobalToLocalBarPosition(
230 {local_post_step_point[0], local_post_step_point[1],
231 local_post_step_point[2]},
233 hit.setPreStepPosition(local_pre_position_rotated[0],
234 local_pre_position_rotated[1],
235 local_pre_position_rotated[2]);
236 hit.setPostStepPosition(local_post_position_rotated[0],
237 local_post_position_rotated[1],
238 local_post_position_rotated[2]);
239 hit.setPreStepTime(pre_point->GetGlobalTime());
240 hit.setPostStepTime(post_point->GetGlobalTime());
242 ldmx_log(trace) << hit;