144 std::map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
151 for (
auto const& sim_hit : hcal_sim_hits) {
153 unsigned int hit_id = sim_hit.getID();
155 auto idh = hits_by_id.find(hit_id);
156 if (idh == hits_by_id.end()) {
158 std::vector<const ldmx::SimCalorimeterHit*>(1, &sim_hit);
160 idh->second.push_back(&sim_hit);
164 ldmx::HgcrocPulseTruthCollection hcal_pulse_truth_coll;
166 hgcroc_->pulse_truth_coll_ = &hcal_pulse_truth_coll;
167 hgcroc_->save_pulse_truth_info_ =
true;
173 double time_delta{flat_time_shift_};
174 if (do_time_spread_per_spill_) {
176 time_spread_per_spill_parameters_);
178 for (
auto const& sim_bar : hits_by_id) {
180 int section = det_id.section();
181 int layer = det_id.
layer();
182 int strip = det_id.
strip();
185 double half_total_width = hcal_geometry.getHalfTotalWidth(section, layer);
186 double ecal_dx = hcal_geometry.getEcalDx();
187 double ecal_dy = hcal_geometry.getEcalDy();
190 std::vector<std::pair<double, double>> pulses_posend;
191 std::vector<std::pair<double, double>> pulses_negend;
193 for (
auto psim_hit : sim_bar.second) {
196 std::vector<float> position = sim_hit.
getPosition();
226 float distance_along_bar, distance_ecal;
227 float distance_close, distance_far;
229 const auto orientation{hcal_geometry.getScintillatorOrientation(det_id)};
230 if (section == ldmx::HcalID::HcalSection::BACK) {
233 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
236 end_close = (distance_along_bar > 0) ? 0 : 1;
237 distance_close = half_total_width;
238 distance_far = half_total_width;
240 if ((section == ldmx::HcalID::HcalSection::TOP) ||
241 ((section == ldmx::HcalID::HcalSection::BOTTOM))) {
242 distance_along_bar = position[0];
243 distance_ecal = ecal_dx;
244 }
else if ((section == ldmx::HcalID::HcalSection::LEFT) ||
245 (section == ldmx::HcalID::HcalSection::RIGHT)) {
246 distance_along_bar = position[1];
247 distance_ecal = ecal_dy;
249 distance_along_bar = -9999.;
252 "We should never end up here "
253 "All cases of HCAL considered, end_close is meaningless");
255 end_close = (distance_along_bar > half_total_width) ? 0 : 1;
256 distance_close = (end_close == 0)
257 ? 2 * half_total_width - distance_ecal / 2
259 distance_far = (end_close == 0)
261 : 2 * half_total_width - distance_ecal / 2;
267 float v = 299.792 / 1.6;
269 exp(-1. * ((distance_close - fabs(distance_along_bar)) / 1000.) /
272 exp(-1. * ((distance_far + fabs(distance_along_bar)) / 1000.) /
275 fabs((distance_close - fabs(distance_along_bar)) / v);
276 double shift_far = fabs((distance_far + fabs(distance_along_bar)) / v);
285 time -= position.at(2) / 299.702547;
286 if (do_time_spread_per_hit_) {
288 time_spread_per_hit_parameters_);
292 if (end_close == 0) {
293 pulses_posend.emplace_back(voltage * att_close, time + shift_close);
294 pulses_negend.emplace_back(voltage * att_far, time + shift_far);
296 pulses_posend.emplace_back(voltage * att_far, time + shift_far);
297 pulses_negend.emplace_back(voltage * att_close, time + shift_close);
311 if (section == ldmx::HcalID::HcalSection::BACK) {
312 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add_posend,
317 bool pos_end_activity =
318 hgcroc_->digitize(posend_id.
raw(), pulses_posend, digi_to_add_posend);
319 bool neg_end_activity =
320 hgcroc_->digitize(negend_id.
raw(), pulses_negend, digi_to_add_negend);
323 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
324 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
329 if (pos_end_activity) {
330 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
332 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
336 if (neg_end_activity) {
337 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
339 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
346 bool is_posend =
false;
347 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add;
348 if ((section == ldmx::HcalID::HcalSection::TOP) ||
349 (section == ldmx::HcalID::HcalSection::LEFT)) {
351 }
else if ((section == ldmx::HcalID::HcalSection::BOTTOM) ||
352 (section == ldmx::HcalID::HcalSection::RIGHT)) {
357 if (
hgcroc_->digitize(digi_id.
raw(), pulses_posend, digi_to_add)) {
358 hcal_digis.
addDigi(digi_id.
raw(), digi_to_add);
360 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
366 if (
hgcroc_->digitize(digi_id.
raw(), pulses_negend, digi_to_add)) {
367 hcal_digis.
addDigi(digi_id.
raw(), digi_to_add);
369 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
381 std::vector<ldmx::HcalDigiID> channel_map;
382 int num_channels = 0;
383 for (
int section = 0; section < hcal_geometry.getNumSections(); section++) {
384 for (
int layer = 1; layer <= hcal_geometry.getNumLayers(section);
387 for (
int strip = 0; strip < hcal_geometry.getNumStrips(section, layer);
389 if (section == ldmx::HcalID::HcalSection::BACK) {
392 channel_map.push_back(digi_i_dend0);
393 channel_map.push_back(digi_i_dend1);
397 channel_map.push_back(digi_id);
405 std::uniform_int_distribution<int> section_dist(
406 0, hcal_geometry.getNumSections() - 1);
407 std::uniform_int_distribution<int> end_dist(0, 1);
408 std::uniform_int_distribution<int> clock_dist(0,
clock_cycle_);
412 int num_empty_channels = num_channels - hcal_digis.
getNumDigis();
415 auto noise_hit_amplitudes{
417 std::vector<std::pair<double, double>> fake_pulse(1, {0., 0.});
419 for (
double noise_hit : noise_hit_amplitudes) {
422 unsigned int noise_id;
423 int section_id, layer_id, strip_id, end_id;
426 section_id = section_dist(
rng_);
429 std::uniform_int_distribution<int> layer_dist(
430 0, hcal_geometry.getNumLayers(section_id) - 1);
431 layer_id = layer_dist(
rng_);
434 if (layer_id == 0) layer_id = 1;
437 std::uniform_int_distribution<int> strips_dist(
438 0, hcal_geometry.getNumStrips(section_id, layer_id) - 1);
439 strip_id = strips_dist(
rng_);
442 if ((section_id == ldmx::HcalID::HcalSection::TOP) ||
443 (section_id == ldmx::HcalID::HcalSection::LEFT)) {
445 }
else if ((section_id == ldmx::HcalID::HcalSection::BOTTOM) ||
446 (section_id == ldmx::HcalID::HcalSection::RIGHT)) {
449 end_id = end_dist(
rng_);
453 noise_id = det_id.raw();
454 }
while (hits_by_id.find(noise_id) != hits_by_id.end());
455 hits_by_id[noise_id] =
456 std::vector<const ldmx::SimCalorimeterHit*>();
459 fake_pulse[0].second = clock_dist(
rng_);
463 double gain =
hgcroc_->gain(noise_id);
464 fake_pulse[0].first = noise_hit +
465 gain *
hgcroc_->readoutThreshold(noise_id) -
466 gain *
hgcroc_->pedestal(noise_id);
468 if (section_id == ldmx::HcalID::HcalSection::BACK) {
469 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add_posend,
473 if (
hgcroc_->digitize(posend_id.
raw(), fake_pulse,
474 digi_to_add_posend) &&
475 hgcroc_->digitize(negend_id.
raw(), fake_pulse,
476 digi_to_add_negend)) {
477 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
478 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
481 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add;
482 if (
hgcroc_->digitize(noise_id, fake_pulse, digi_to_add)) {
483 hcal_digis.
addDigi(noise_id, digi_to_add);
489 for (
auto digi_id : channel_map) {
492 ldmx::HcalID detid(digi_id.section(), digi_id.layer(), digi_id.strip());
493 unsigned int rawdet_id = detid.
raw();
494 if (hits_by_id.find(rawdet_id) == hits_by_id.end()) {
495 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
496 hgcroc_->noiseDigi(digi_id.raw(), 0.0);
497 hcal_digis.
addDigi(digi_id.raw(), digi);