136 std::map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
143 for (
auto const& sim_hit : hcal_sim_hits) {
145 unsigned int hit_id = sim_hit.getID();
147 auto idh = hits_by_id.find(hit_id);
148 if (idh == hits_by_id.end()) {
150 std::vector<const ldmx::SimCalorimeterHit*>(1, &sim_hit);
152 idh->second.push_back(&sim_hit);
156 ldmx::HgcrocPulseTruthCollection hcal_pulse_truth_coll;
158 hgcroc_->pulse_truth_coll_ = &hcal_pulse_truth_coll;
159 hgcroc_->save_pulse_truth_info_ =
true;
165 double time_delta{flat_time_shift_};
166 if (do_time_spread_per_spill_) {
168 time_spread_per_spill_parameters_);
170 for (
auto const& sim_bar : hits_by_id) {
172 int section = det_id.section();
173 int layer = det_id.
layer();
174 int strip = det_id.
strip();
177 double half_total_width = hcal_geometry.getHalfTotalWidth(section, layer);
178 double ecal_dx = hcal_geometry.getEcalDx();
179 double ecal_dy = hcal_geometry.getEcalDy();
182 std::vector<std::pair<double, double>> pulses_posend;
183 std::vector<std::pair<double, double>> pulses_negend;
185 for (
auto psim_hit : sim_bar.second) {
188 std::vector<float> position = sim_hit.
getPosition();
218 float distance_along_bar, distance_ecal;
219 float distance_close, distance_far;
221 const auto orientation{hcal_geometry.getScintillatorOrientation(det_id)};
222 if (section == ldmx::HcalID::HcalSection::BACK) {
225 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
228 end_close = (distance_along_bar > 0) ? 0 : 1;
229 distance_close = half_total_width;
230 distance_far = half_total_width;
232 if ((section == ldmx::HcalID::HcalSection::TOP) ||
233 ((section == ldmx::HcalID::HcalSection::BOTTOM))) {
234 distance_along_bar = position[0];
235 distance_ecal = ecal_dx;
236 }
else if ((section == ldmx::HcalID::HcalSection::LEFT) ||
237 (section == ldmx::HcalID::HcalSection::RIGHT)) {
238 distance_along_bar = position[1];
239 distance_ecal = ecal_dy;
241 distance_along_bar = -9999.;
244 "We should never end up here "
245 "All cases of HCAL considered, end_close is meaningless");
247 end_close = (distance_along_bar > half_total_width) ? 0 : 1;
248 distance_close = (end_close == 0)
249 ? 2 * half_total_width - distance_ecal / 2
251 distance_far = (end_close == 0)
253 : 2 * half_total_width - distance_ecal / 2;
259 float v = 299.792 / 1.6;
261 exp(-1. * ((distance_close - fabs(distance_along_bar)) / 1000.) /
264 exp(-1. * ((distance_far + fabs(distance_along_bar)) / 1000.) /
267 fabs((distance_close - fabs(distance_along_bar)) / v);
268 double shift_far = fabs((distance_far + fabs(distance_along_bar)) / v);
277 time -= position.at(2) / 299.702547;
278 if (do_time_spread_per_hit_) {
280 time_spread_per_hit_parameters_);
284 if (end_close == 0) {
285 pulses_posend.emplace_back(voltage * att_close, time + shift_close);
286 pulses_negend.emplace_back(voltage * att_far, time + shift_far);
288 pulses_posend.emplace_back(voltage * att_far, time + shift_far);
289 pulses_negend.emplace_back(voltage * att_close, time + shift_close);
303 if (section == ldmx::HcalID::HcalSection::BACK) {
304 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add_posend,
309 bool pos_end_activity =
310 hgcroc_->digitize(posend_id.
raw(), pulses_posend, digi_to_add_posend);
311 bool neg_end_activity =
312 hgcroc_->digitize(negend_id.
raw(), pulses_negend, digi_to_add_negend);
315 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
316 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
321 if (pos_end_activity) {
322 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
324 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
328 if (neg_end_activity) {
329 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
331 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
338 bool is_posend =
false;
339 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add;
340 if ((section == ldmx::HcalID::HcalSection::TOP) ||
341 (section == ldmx::HcalID::HcalSection::LEFT)) {
343 }
else if ((section == ldmx::HcalID::HcalSection::BOTTOM) ||
344 (section == ldmx::HcalID::HcalSection::RIGHT)) {
349 if (
hgcroc_->digitize(digi_id.
raw(), pulses_posend, digi_to_add)) {
350 hcal_digis.
addDigi(digi_id.
raw(), digi_to_add);
352 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
358 if (
hgcroc_->digitize(digi_id.
raw(), pulses_negend, digi_to_add)) {
359 hcal_digis.
addDigi(digi_id.
raw(), digi_to_add);
361 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
373 std::vector<ldmx::HcalDigiID> channel_map;
374 int num_channels = 0;
375 for (
int section = 0; section < hcal_geometry.getNumSections(); section++) {
376 for (
int layer = 1; layer <= hcal_geometry.getNumLayers(section);
379 for (
int strip = 0; strip < hcal_geometry.getNumStrips(section, layer);
381 if (section == ldmx::HcalID::HcalSection::BACK) {
384 channel_map.push_back(digi_i_dend0);
385 channel_map.push_back(digi_i_dend1);
389 channel_map.push_back(digi_id);
397 std::uniform_int_distribution<int> section_dist(
398 0, hcal_geometry.getNumSections() - 1);
399 std::uniform_int_distribution<int> end_dist(0, 1);
400 std::uniform_int_distribution<int> clock_dist(0,
clock_cycle_);
404 int num_empty_channels = num_channels - hcal_digis.
getNumDigis();
407 auto noise_hit_amplitudes{
409 std::vector<std::pair<double, double>> fake_pulse(1, {0., 0.});
411 for (
double noise_hit : noise_hit_amplitudes) {
414 unsigned int noise_id;
415 int section_id, layer_id, strip_id, end_id;
418 section_id = section_dist(
rng_);
421 std::uniform_int_distribution<int> layer_dist(
422 0, hcal_geometry.getNumLayers(section_id) - 1);
423 layer_id = layer_dist(
rng_);
426 if (layer_id == 0) layer_id = 1;
429 std::uniform_int_distribution<int> strips_dist(
430 0, hcal_geometry.getNumStrips(section_id, layer_id) - 1);
431 strip_id = strips_dist(
rng_);
434 if ((section_id == ldmx::HcalID::HcalSection::TOP) ||
435 (section_id == ldmx::HcalID::HcalSection::LEFT)) {
437 }
else if ((section_id == ldmx::HcalID::HcalSection::BOTTOM) ||
438 (section_id == ldmx::HcalID::HcalSection::RIGHT)) {
441 end_id = end_dist(
rng_);
445 noise_id = det_id.raw();
446 }
while (hits_by_id.find(noise_id) != hits_by_id.end());
447 hits_by_id[noise_id] =
448 std::vector<const ldmx::SimCalorimeterHit*>();
451 fake_pulse[0].second = clock_dist(
rng_);
455 double gain =
hgcroc_->gain(noise_id);
456 fake_pulse[0].first = noise_hit +
457 gain *
hgcroc_->readoutThreshold(noise_id) -
458 gain *
hgcroc_->pedestal(noise_id);
460 if (section_id == ldmx::HcalID::HcalSection::BACK) {
461 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add_posend,
465 if (
hgcroc_->digitize(posend_id.
raw(), fake_pulse,
466 digi_to_add_posend) &&
467 hgcroc_->digitize(negend_id.
raw(), fake_pulse,
468 digi_to_add_negend)) {
469 hcal_digis.
addDigi(posend_id.
raw(), digi_to_add_posend);
470 hcal_digis.
addDigi(negend_id.
raw(), digi_to_add_negend);
473 std::vector<ldmx::HgcrocDigiCollection::Sample> digi_to_add;
474 if (
hgcroc_->digitize(noise_id, fake_pulse, digi_to_add)) {
475 hcal_digis.
addDigi(noise_id, digi_to_add);
481 for (
auto digi_id : channel_map) {
484 ldmx::HcalID detid(digi_id.section(), digi_id.layer(), digi_id.strip());
485 unsigned int rawdet_id = detid.
raw();
486 if (hits_by_id.find(rawdet_id) == hits_by_id.end()) {
487 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
488 hgcroc_->noiseDigi(digi_id.raw(), 0.0);
489 hcal_digis.
addDigi(digi_id.raw(), digi);