39 std::vector<ldmx::HcalHit> hcal_rec_hits;
43 std::unordered_map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
47 for (
const auto& hit : sim_hits) {
49 auto found{hits_by_id.find(
id)};
50 if (found == hits_by_id.end()) {
51 hits_by_id[id] = std::vector<const ldmx::SimCalorimeterHit*>{&hit};
53 hits_by_id[id].push_back(&hit);
56 for (
const auto& [barID, simhits_in_bar] : hits_by_id) {
60 std::vector<double> pos{0, 0, 0};
61 for (
auto hit : simhits_in_bar) {
62 edep += hit->getEdep();
63 double edep_hit = hit->getEdep();
64 time += hit->getTime() * edep_hit;
65 auto hit_pos{hit->getPosition()};
66 pos[0] += hit_pos[0] * edep_hit;
67 pos[1] += hit_pos[1] * edep_hit;
68 pos[2] += hit_pos[2] * edep_hit;
73 double mean_pe{(edep / mev_per_mip_) * pe_per_mip_};
74 double xpos{pos[0] / edep};
75 double ypos{pos[1] / edep};
76 double zpos{pos[2] / edep};
79 auto orientation{hcal_geometry.getScintillatorOrientation(barID)};
80 double half_total_width{
81 hcal_geometry.getHalfTotalWidth(hit_id.section(), hit_id.layer())};
82 double scint_bar_length{hcal_geometry.getScintillatorLength(hit_id)};
84 auto strip_center{hcal_geometry.getStripCenterPosition(hit_id)};
85 if (hit_id.section() == ldmx::HcalID::HcalSection::BACK) {
86 double distance_along_bar =
88 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
92 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
93 ypos = strip_center.y();
94 xpos += (*position_resolution_smear_)(rng_);
96 xpos = strip_center.x();
97 ypos += (*position_resolution_smear_)(rng_);
99 zpos = strip_center.z();
101 mean_pe *= exp(1. / attenuation_length_);
102 double mean_pe_close =
104 ((half_total_width - distance_along_bar) /
105 (scint_bar_length * 0.5)) /
106 attenuation_length_);
109 ((half_total_width + distance_along_bar) /
110 (scint_bar_length * 0.5)) /
111 attenuation_length_);
113 std::poisson_distribution<int>(mean_pe_close + mean_noise_)(rng_)};
115 std::poisson_distribution<int>(mean_pe_far + mean_noise_)(rng_)};
116 rec_hit.
setPE(pe_close + pe_far);
117 rec_hit.
setMinPE(std::min(pe_close, pe_far));
120 int pe{std::poisson_distribution<int>(mean_pe + mean_noise_)(rng_)};
127 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
128 xpos += (*position_resolution_smear_)(rng_);
129 ypos = strip_center.y();
130 zpos = strip_center.z();
131 }
else if (orientation ==
132 ldmx::HcalGeometry::ScintillatorOrientation::vertical) {
133 xpos = strip_center.x();
134 ypos += (*position_resolution_smear_)(rng_);
135 zpos = strip_center.z();
136 }
else if (orientation ==
137 ldmx::HcalGeometry::ScintillatorOrientation::depth) {
138 xpos = strip_center.x();
139 ypos = strip_center.y();
140 zpos += (*position_resolution_smear_)(rng_);
142 xpos = strip_center.x();
143 ypos = strip_center.y();
144 zpos = strip_center.z();
145 ldmx_log(warn) <<
"Bar orientation not found. Hit" << hit_id.raw()
146 <<
"positioned at bar center.";
150 rec_hit.
setID(hit_id.raw());
162 event.add(output_coll_name_, hcal_rec_hits);