10 input_coll_name_ = ps.getParameter<std::string>(
"input_coll_name");
11 input_pass_name_ = ps.getParameter<std::string>(
"input_pass_name");
12 output_coll_name_ = ps.getParameter<std::string>(
"output_coll_name");
13 mev_per_mip_ = ps.getParameter<
double>(
"mev_per_mip");
14 pe_per_mip_ = ps.getParameter<
double>(
"pe_per_mip");
15 attenuation_length_ = ps.getParameter<
double>(
"attenuation_length");
16 readout_threshold_ = ps.getParameter<
int>(
"readout_threshold");
17 mean_noise_ = ps.getParameter<
double>(
"mean_noise");
18 position_resolution_smear_ =
19 std::make_unique<std::normal_distribution<double>>(
20 0.0, ps.getParameter<
double>(
"position_resolution"));
39 std::vector<ldmx::HcalHit> hcalRecHits;
43 std::unordered_map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
47 for (
const auto& hit : simHits) {
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 hitPos{hit->getPosition()};
66 pos[0] += hitPos[0] * edep_hit;
67 pos[1] += hitPos[1] * edep_hit;
68 pos[2] += hitPos[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{hcalGeometry.getScintillatorOrientation(barID)};
80 double half_total_width{
81 hcalGeometry.getHalfTotalWidth(hitID.section(), hitID.layer())};
82 double scint_bar_length{hcalGeometry.getScintillatorLength(hitID)};
84 auto stripCenter{hcalGeometry.getStripCenterPosition(hitID)};
85 if (hitID.section() == ldmx::HcalID::HcalSection::BACK) {
86 double distance_along_bar =
88 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
92 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
93 ypos = stripCenter.y();
94 xpos += (*position_resolution_smear_)(rng_);
96 xpos = stripCenter.x();
97 ypos += (*position_resolution_smear_)(rng_);
99 zpos = stripCenter.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 recHit.
setPE(PE_close + PE_far);
117 recHit.
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 = stripCenter.y();
130 zpos = stripCenter.z();
131 }
else if (orientation ==
132 ldmx::HcalGeometry::ScintillatorOrientation::vertical) {
133 xpos = stripCenter.x();
134 ypos += (*position_resolution_smear_)(rng_);
135 zpos = stripCenter.z();
136 }
else if (orientation ==
137 ldmx::HcalGeometry::ScintillatorOrientation::depth) {
138 xpos = stripCenter.x();
139 ypos = stripCenter.y();
140 zpos += (*position_resolution_smear_)(rng_);
142 xpos = stripCenter.x();
143 ypos = stripCenter.y();
144 zpos = stripCenter.z();
145 ldmx_log(warn) <<
"Bar orientation not found. Hit" << hitID.raw()
146 <<
"positioned at bar center.";
150 recHit.
setID(hitID.raw());
162 event.add(output_coll_name_, hcalRecHits);