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 (hit_id.section() == ldmx::HcalID::HcalSection::BACK) {
89 double distance_along_bar =
91 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
95 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
96 ypos = strip_center.y();
97 xpos += (*position_resolution_smear_)(rng_);
99 xpos = strip_center.x();
100 ypos += (*position_resolution_smear_)(rng_);
102 zpos = strip_center.z();
104 mean_pe *= exp(1. / attenuation_length_);
105 double mean_pe_close =
107 ((half_total_width - distance_along_bar) /
108 (scint_bar_length * 0.5)) /
109 attenuation_length_);
112 ((half_total_width + distance_along_bar) /
113 (scint_bar_length * 0.5)) /
114 attenuation_length_);
116 std::poisson_distribution<int>(mean_pe_close + mean_noise_)(rng_)};
118 std::poisson_distribution<int>(mean_pe_far + mean_noise_)(rng_)};
119 rec_hit.
setPE(pe_close + pe_far);
120 rec_hit.
setMinPE(std::min(pe_close, pe_far));
123 int pe{std::poisson_distribution<int>(mean_pe + mean_noise_)(rng_)};
130 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
131 xpos += (*position_resolution_smear_)(rng_);
132 ypos = strip_center.y();
133 zpos = strip_center.z();
134 }
else if (orientation ==
135 ldmx::HcalGeometry::ScintillatorOrientation::vertical) {
136 xpos = strip_center.x();
137 ypos += (*position_resolution_smear_)(rng_);
138 zpos = strip_center.z();
139 }
else if (orientation ==
140 ldmx::HcalGeometry::ScintillatorOrientation::depth) {
141 xpos = strip_center.x();
142 ypos = strip_center.y();
143 zpos += (*position_resolution_smear_)(rng_);
145 xpos = strip_center.x();
146 ypos = strip_center.y();
147 zpos = strip_center.z();
148 ldmx_log(warn) <<
"Bar orientation not found. Hit" << hit_id.raw()
149 <<
"positioned at bar center.";
153 rec_hit.
setID(hit_id.raw());
165 event.add(output_coll_name_, hcal_rec_hits);