42 std::vector<ldmx::HcalHit> hcal_rec_hits;
46 std::unordered_map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
50 for (
const auto& hit : sim_hits) {
52 auto found{hits_by_id.find(
id)};
53 if (found == hits_by_id.end()) {
54 hits_by_id[id] = std::vector<const ldmx::SimCalorimeterHit*>{&hit};
56 hits_by_id[id].push_back(&hit);
59 for (
const auto& [barID, simhits_in_bar] : hits_by_id) {
63 std::vector<double> pos{0, 0, 0};
64 for (
auto hit : simhits_in_bar) {
65 edep += hit->getEdep();
66 double edep_hit = hit->getEdep();
67 time += hit->getTime() * edep_hit;
68 auto hit_pos{hit->getPosition()};
69 pos[0] += hit_pos[0] * edep_hit;
70 pos[1] += hit_pos[1] * edep_hit;
71 pos[2] += hit_pos[2] * edep_hit;
76 double mean_pe{(edep / mev_per_mip_) * pe_per_mip_};
77 double xpos{pos[0] / edep};
78 double ypos{pos[1] / edep};
79 double zpos{pos[2] / edep};
82 auto orientation{hcal_geometry.getScintillatorOrientation(barID)};
83 double half_total_width{
84 hcal_geometry.getHalfTotalWidth(hit_id.section(), hit_id.layer())};
85 double scint_bar_length{hcal_geometry.getScintillatorLength(hit_id)};
87 auto strip_center{hcal_geometry.getStripCenterPosition(hit_id)};
88 if (hcal_geometry.isDoubleEnded(hit_id.section())) {
89 double distance_along_bar =
90 hcal_geometry.hasExplicitLayout()
91 ? hcal_geometry.getDistanceAlongBar(hit_id, xpos, ypos, zpos)
93 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
97 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
98 ypos = strip_center.y();
99 xpos += (*position_resolution_smear_)(rng_);
101 xpos = strip_center.x();
102 ypos += (*position_resolution_smear_)(rng_);
104 zpos = strip_center.z();
106 mean_pe *= exp(1. / attenuation_length_);
107 double mean_pe_close =
109 ((half_total_width - distance_along_bar) /
110 (scint_bar_length * 0.5)) /
111 attenuation_length_);
114 ((half_total_width + distance_along_bar) /
115 (scint_bar_length * 0.5)) /
116 attenuation_length_);
118 std::poisson_distribution<int>(mean_pe_close + mean_noise_)(rng_)};
120 std::poisson_distribution<int>(mean_pe_far + mean_noise_)(rng_)};
121 rec_hit.
setPE(pe_close + pe_far);
122 rec_hit.
setMinPE(std::min(pe_close, pe_far));
125 int pe{std::poisson_distribution<int>(mean_pe + mean_noise_)(rng_)};
132 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
133 xpos += (*position_resolution_smear_)(rng_);
134 ypos = strip_center.y();
135 zpos = strip_center.z();
136 }
else if (orientation ==
137 ldmx::HcalGeometry::ScintillatorOrientation::vertical) {
138 xpos = strip_center.x();
139 ypos += (*position_resolution_smear_)(rng_);
140 zpos = strip_center.z();
141 }
else if (orientation ==
142 ldmx::HcalGeometry::ScintillatorOrientation::depth) {
143 xpos = strip_center.x();
144 ypos = strip_center.y();
145 zpos += (*position_resolution_smear_)(rng_);
147 xpos = strip_center.x();
148 ypos = strip_center.y();
149 zpos = strip_center.z();
150 ldmx_log(warn) <<
"Bar orientation not found. Hit" << hit_id.raw()
151 <<
"positioned at bar center.";
155 rec_hit.
setID(hit_id.raw());
167 event.add(output_coll_name_, hcal_rec_hits);