67 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
70 rseed.getSeed(
"HcalDigiProducer::NoiseGenerator"));
73 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
76 rseed.getSeed(
"HcalDigiProducer::NoiseInjector"));
79 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
81 hgcroc_->seedGenerator(rseed.getSeed(
"HcalDigiProducer::HgcrocEmulator"));
86 getCondition<conditions::DoubleTableCondition>(
"HcalHgcrocConditions"));
89 const auto& hcalGeometry = getCondition<ldmx::HcalGeometry>(
97 std::map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>> hitsByID;
103 for (
auto const& simHit : hcalSimHits) {
105 unsigned int hitID = simHit.
getID();
107 auto idh = hitsByID.find(hitID);
108 if (idh == hitsByID.end()) {
109 hitsByID[hitID] = std::vector<const ldmx::SimCalorimeterHit*>(1, &simHit);
111 idh->second.push_back(&simHit);
118 for (
auto const& simBar : hitsByID) {
120 int section = detID.section();
121 int layer = detID.
layer();
122 int strip = detID.
strip();
125 double half_total_width = hcalGeometry.getHalfTotalWidth(section, layer);
126 double ecal_dx = hcalGeometry.getEcalDx();
127 double ecal_dy = hcalGeometry.getEcalDy();
130 std::vector<std::pair<double, double>> pulses_posend;
131 std::vector<std::pair<double, double>> pulses_negend;
133 for (
auto psimHit : simBar.second) {
136 std::vector<float> position = simHit.
getPosition();
166 float distance_along_bar, distance_ecal;
167 float distance_close, distance_far;
169 const auto orientation{hcalGeometry.getScintillatorOrientation(detID)};
170 if (section == ldmx::HcalID::HcalSection::BACK) {
173 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
176 end_close = (distance_along_bar > 0) ? 0 : 1;
177 distance_close = half_total_width;
178 distance_far = half_total_width;
180 if ((section == ldmx::HcalID::HcalSection::TOP) ||
181 ((section == ldmx::HcalID::HcalSection::BOTTOM))) {
182 distance_along_bar = position[0];
183 distance_ecal = ecal_dx;
184 }
else if ((section == ldmx::HcalID::HcalSection::LEFT) ||
185 (section == ldmx::HcalID::HcalSection::RIGHT)) {
186 distance_along_bar = position[1];
187 distance_ecal = ecal_dy;
189 distance_along_bar = -9999.;
192 "We should never end up here "
193 "All cases of HCAL considered, end_close is meaningless");
195 end_close = (distance_along_bar > half_total_width) ? 0 : 1;
196 distance_close = (end_close == 0)
197 ? 2 * half_total_width - distance_ecal / 2
199 distance_far = (end_close == 0)
201 : 2 * half_total_width - distance_ecal / 2;
209 exp(-1. * ((distance_close - fabs(distance_along_bar)) / 1000.) /
212 exp(-1. * ((distance_far + fabs(distance_along_bar)) / 1000.) /
215 fabs((distance_close - fabs(distance_along_bar)) / v);
216 double shift_far = fabs((distance_far + fabs(distance_along_bar)) / v);
224 time -= position.at(2) /
227 if (end_close == 0) {
228 pulses_posend.emplace_back(voltage * att_close, time + shift_close);
229 pulses_negend.emplace_back(voltage * att_far, time + shift_far);
231 pulses_posend.emplace_back(voltage * att_far, time + shift_far);
232 pulses_negend.emplace_back(voltage * att_close, time + shift_close);
246 if (section == ldmx::HcalID::HcalSection::BACK) {
247 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAddPosend,
251 if (
hgcroc_->digitize(posendID.
raw(), pulses_posend, digiToAddPosend) &&
252 hgcroc_->digitize(negendID.
raw(), pulses_negend, digiToAddNegend)) {
253 hcalDigis.
addDigi(posendID.
raw(), digiToAddPosend);
254 hcalDigis.
addDigi(negendID.
raw(), digiToAddNegend);
257 bool is_posend =
false;
258 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAdd;
259 if ((section == ldmx::HcalID::HcalSection::TOP) ||
260 (section == ldmx::HcalID::HcalSection::LEFT)) {
262 }
else if ((section == ldmx::HcalID::HcalSection::BOTTOM) ||
263 (section == ldmx::HcalID::HcalSection::RIGHT)) {
268 if (
hgcroc_->digitize(digiID.
raw(), pulses_posend, digiToAdd)) {
273 if (
hgcroc_->digitize(digiID.
raw(), pulses_negend, digiToAdd)) {
285 for (
int section = 0; section < hcalGeometry.getNumSections(); section++) {
286 int numChannelsInSection = 0;
287 for (
int layer = 1; layer <= hcalGeometry.getNumLayers(section);
289 numChannelsInSection += hcalGeometry.getNumStrips(section, layer);
293 if (section == ldmx::HcalID::HcalSection::BACK) {
294 numChannelsInSection *= 2;
296 numChannels += numChannelsInSection;
298 int numEmptyChannels = numChannels - hcalDigis.
getNumDigis();
301 auto noiseHitAmplitudes{
303 std::vector<std::pair<double, double>> fake_pulse(1, {0., 0.});
304 for (
double noiseHit : noiseHitAmplitudes) {
307 unsigned int noiseID;
308 int sectionID, layerID, stripID, endID;
310 sectionID =
noiseInjector_->Integer(hcalGeometry.getNumSections());
311 layerID =
noiseInjector_->Integer(hcalGeometry.getNumLayers(sectionID));
314 if (layerID == 0) layerID = 1;
316 hcalGeometry.getNumStrips(sectionID, layerID));
318 if ((sectionID == ldmx::HcalID::HcalSection::TOP) ||
319 (sectionID == ldmx::HcalID::HcalSection::LEFT)) {
321 }
else if ((sectionID == ldmx::HcalID::HcalSection::BOTTOM) ||
322 (sectionID == ldmx::HcalID::HcalSection::RIGHT)) {
326 noiseID = detID.raw();
327 }
while (hitsByID.find(noiseID) != hitsByID.end());
329 std::vector<const ldmx::SimCalorimeterHit*>();
336 double gain =
hgcroc_->gain(noiseID);
337 fake_pulse[0].first = noiseHit +
338 gain *
hgcroc_->readoutThreshold(noiseID) -
339 gain *
hgcroc_->pedestal(noiseID);
341 if (sectionID == ldmx::HcalID::HcalSection::BACK) {
342 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAddPosend,
346 if (
hgcroc_->digitize(posendID.
raw(), fake_pulse, digiToAddPosend) &&
347 hgcroc_->digitize(negendID.
raw(), fake_pulse, digiToAddNegend)) {
348 hcalDigis.
addDigi(posendID.
raw(), digiToAddPosend);
349 hcalDigis.
addDigi(negendID.
raw(), digiToAddNegend);
352 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAdd;
353 if (
hgcroc_->digitize(noiseID, fake_pulse, digiToAdd)) {
354 hcalDigis.
addDigi(noiseID, digiToAdd);