145 std::map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
152 for (
auto const& sim_hit : hcal_sim_hits) {
154 unsigned int hit_id = sim_hit.getID();
156 auto idh = hits_by_id.find(hit_id);
157 if (idh == hits_by_id.end()) {
159 std::vector<const ldmx::SimCalorimeterHit*>(1, &sim_hit);
161 idh->second.push_back(&sim_hit);
165 ldmx::HgcrocPulseTruthCollection hcal_pulse_truth_coll;
167 hgcroc_->pulse_truth_coll_ = &hcal_pulse_truth_coll;
168 hgcroc_->save_pulse_truth_info_ =
true;
174 double time_delta{flat_time_shift_};
175 if (do_time_spread_per_spill_) {
177 time_spread_per_spill_parameters_);
179 const bool explicit_layout{hcal_geometry.hasExplicitLayout()};
180 for (
auto const& sim_bar : hits_by_id) {
182 int section = det_id.section();
183 int layer = det_id.
layer();
184 int strip = det_id.
strip();
187 double half_total_width = hcal_geometry.getHalfTotalWidth(section, layer);
188 double ecal_dx = hcal_geometry.getEcalDx();
189 double ecal_dy = hcal_geometry.getEcalDy();
192 std::vector<std::pair<double, double>> pulses_posend;
193 std::vector<std::pair<double, double>> pulses_negend;
195 for (
auto psim_hit : sim_bar.second) {
198 std::vector<float> position = sim_hit.
getPosition();
228 float distance_along_bar, distance_ecal;
229 float distance_close, distance_far;
231 const auto orientation{hcal_geometry.getScintillatorOrientation(det_id)};
232 if (explicit_layout) {
234 distance_along_bar = hcal_geometry.getDistanceAlongBar(
235 det_id, position[0], position[1], position[2]);
236 end_close = (distance_along_bar > 0) ? 0 : 1;
237 distance_close = hcal_geometry.getScintillatorLength(det_id) / 2;
238 distance_far = distance_close;
239 }
else if (section == ldmx::HcalID::HcalSection::BACK) {
242 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
245 end_close = (distance_along_bar > 0) ? 0 : 1;
246 distance_close = half_total_width;
247 distance_far = half_total_width;
249 if ((section == ldmx::HcalID::HcalSection::TOP) ||
250 ((section == ldmx::HcalID::HcalSection::BOTTOM))) {
251 distance_along_bar = position[0];
252 distance_ecal = ecal_dx;
253 }
else if ((section == ldmx::HcalID::HcalSection::LEFT) ||
254 (section == ldmx::HcalID::HcalSection::RIGHT)) {
255 distance_along_bar = position[1];
256 distance_ecal = ecal_dy;
258 distance_along_bar = -9999.;
261 "We should never end up here "
262 "All cases of HCAL considered, end_close is meaningless");
264 end_close = (distance_along_bar > half_total_width) ? 0 : 1;
265 distance_close = (end_close == 0)
266 ? 2 * half_total_width - distance_ecal / 2
268 distance_far = (end_close == 0)
270 : 2 * half_total_width - distance_ecal / 2;
276 float v = 299.792 / 1.6;
278 exp(-1. * ((distance_close - fabs(distance_along_bar)) / 1000.) /
281 exp(-1. * ((distance_far + fabs(distance_along_bar)) / 1000.) /
284 fabs((distance_close - fabs(distance_along_bar)) / v);
285 double shift_far = fabs((distance_far + fabs(distance_along_bar)) / v);
295 if (do_time_spread_per_hit_) {
297 time_spread_per_hit_parameters_);
301 if (end_close == 0) {
302 pulses_posend.emplace_back(voltage * att_close, time + shift_close);
303 pulses_negend.emplace_back(voltage * att_far, time + shift_far);
305 pulses_posend.emplace_back(voltage * att_far, time + shift_far);
306 pulses_negend.emplace_back(voltage * att_close, time + shift_close);
320 if (hcal_geometry.isDoubleEnded(section)) {
321 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add_posend,
326 bool pos_end_activity =
327 hgcroc_->digitize(posend_id.
raw(), pulses_posend, digi_to_add_posend);
328 bool neg_end_activity =
329 hgcroc_->digitize(negend_id.
raw(), pulses_negend, digi_to_add_negend);
332 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
333 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
338 if (pos_end_activity) {
339 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
341 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
345 if (neg_end_activity) {
346 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
348 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
355 bool is_posend =
false;
356 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add;
357 if (explicit_layout || (section == ldmx::HcalID::HcalSection::TOP) ||
358 (section == ldmx::HcalID::HcalSection::LEFT)) {
360 }
else if ((section == ldmx::HcalID::HcalSection::BOTTOM) ||
361 (section == ldmx::HcalID::HcalSection::RIGHT)) {
366 if (
hgcroc_->digitize(digi_id.
raw(), pulses_posend, digi_to_add)) {
367 hcal_digis.
addDigi(digi_id.
raw(), digi_to_add);
369 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
375 if (
hgcroc_->digitize(digi_id.
raw(), pulses_negend, digi_to_add)) {
376 hcal_digis.
addDigi(digi_id.
raw(), digi_to_add);
378 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
390 std::vector<ldmx::HcalDigiID> channel_map;
391 int num_channels = 0;
392 for (
int section = 0; section < hcal_geometry.getNumSections(); section++) {
393 for (
int layer = 1; layer <= hcal_geometry.getNumLayers(section);
396 for (
int strip = 0; strip < hcal_geometry.getNumStrips(section, layer);
398 if (hcal_geometry.isDoubleEnded(section)) {
401 channel_map.push_back(digi_i_dend0);
402 channel_map.push_back(digi_i_dend1);
406 channel_map.push_back(digi_id);
414 std::uniform_int_distribution<int> section_dist(
415 0, hcal_geometry.getNumSections() - 1);
416 std::uniform_int_distribution<int> end_dist(0, 1);
417 std::uniform_int_distribution<int> clock_dist(0,
clock_cycle_);
419 std::vector<int> live_sections;
420 for (
int section = 0; section < hcal_geometry.getNumSections(); section++) {
421 if (hcal_geometry.getNumLayers(section) > 0) {
422 live_sections.push_back(section);
425 std::uniform_int_distribution<int> live_section_dist(
426 0,
static_cast<int>(live_sections.size()) - 1);
430 int num_empty_channels = num_channels - hcal_digis.
getNumDigis();
433 auto noise_hit_amplitudes{
435 std::vector<std::pair<double, double>> fake_pulse(1, {0., 0.});
437 for (
double noise_hit : noise_hit_amplitudes) {
440 unsigned int noise_id;
441 int section_id, layer_id, strip_id, end_id;
443 if (explicit_layout) {
444 section_id = live_sections[live_section_dist(
rng_)];
445 layer_id = std::uniform_int_distribution<int>(
446 1, hcal_geometry.getNumLayers(section_id))(
rng_);
447 strip_id = std::uniform_int_distribution<int>(
448 0, hcal_geometry.getNumStrips(section_id, layer_id) - 1)(
rng_);
450 hcal_geometry.isDoubleEnded(section_id) ? end_dist(
rng_) : 0;
456 section_id = section_dist(
rng_);
459 std::uniform_int_distribution<int> layer_dist(
460 0, hcal_geometry.getNumLayers(section_id) - 1);
461 layer_id = layer_dist(
rng_);
464 if (layer_id == 0) layer_id = 1;
467 std::uniform_int_distribution<int> strips_dist(
468 0, hcal_geometry.getNumStrips(section_id, layer_id) - 1);
469 strip_id = strips_dist(
rng_);
472 if ((section_id == ldmx::HcalID::HcalSection::TOP) ||
473 (section_id == ldmx::HcalID::HcalSection::LEFT)) {
475 }
else if ((section_id == ldmx::HcalID::HcalSection::BOTTOM) ||
476 (section_id == ldmx::HcalID::HcalSection::RIGHT)) {
479 end_id = end_dist(
rng_);
483 noise_id = det_id.raw();
484 }
while (hits_by_id.find(noise_id) != hits_by_id.end());
485 hits_by_id[noise_id] =
486 std::vector<const ldmx::SimCalorimeterHit*>();
489 fake_pulse[0].second = clock_dist(
rng_);
493 double gain =
hgcroc_->gain(noise_id);
494 fake_pulse[0].first = noise_hit +
495 gain *
hgcroc_->readoutThreshold(noise_id) -
496 gain *
hgcroc_->pedestal(noise_id);
498 if (hcal_geometry.isDoubleEnded(section_id)) {
499 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add_posend,
503 if (
hgcroc_->digitize(posend_id.
raw(), fake_pulse,
504 digi_to_add_posend) &&
505 hgcroc_->digitize(negend_id.
raw(), fake_pulse,
506 digi_to_add_negend)) {
507 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
508 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
511 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add;
512 if (
hgcroc_->digitize(noise_id, fake_pulse, digi_to_add)) {
513 hcal_digis.
addDigi(noise_id, digi_to_add);
519 for (
auto digi_id : channel_map) {
522 ldmx::HcalID detid(digi_id.section(), digi_id.layer(), digi_id.strip());
523 unsigned int rawdet_id = detid.
raw();
524 if (hits_by_id.find(rawdet_id) == hits_by_id.end()) {
525 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
526 hgcroc_->noiseDigi(digi_id.raw(), 0.0);
527 hcal_digis.
addDigi(digi_id.raw(), digi);