Skip to content

Commit 003e500

Browse files
committed
More asserts on geometry for HGCal
These are meant to convert segmentation faults into asserts and help guarantee geometry descriptions are consistent. Also fixed some naming inconsistencies.
1 parent 9fcde00 commit 003e500

File tree

3 files changed

+50
-39
lines changed

3 files changed

+50
-39
lines changed

SimCalorimetry/HGCalSimProducers/interface/HGCFEElectronics.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ class HGCFEElectronics {
204204
uint32_t tdcNbits_;
205205
bool thresholdFollowsMIP_;
206206
//caches
207-
std::array<bool, hgc::nSamples> busyFlags, totFlags, toaFlags;
208-
hgc::HGCSimHitData newCharge, toaFromToT;
207+
std::array<bool, hgc::nSamples> busyFlags_, totFlags_, toaFlags_;
208+
hgc::HGCSimHitData newCharge_, toaFromToT_;
209209
};
210210

211211
#endif

SimCalorimetry/HGCalSimProducers/plugins/HGCDigitizer.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ namespace {
196196
auto simIt = simData.emplace(detectorId, HGCCellInfo()).first;
197197
const bool orderChanged = hitOrder_monitor[detectorId];
198198
int waferThickness = getCellThickness(geom, detectorId);
199+
assert(waferThickness - 1 < static_cast<int>(tdcForToAOnset.size()));
199200
float cell_threshold = tdcForToAOnset[waferThickness - 1];
200201
const auto& hitRec = hitmapIterator.second;
201202
float fireTDC(0.f);
@@ -496,6 +497,7 @@ void HGCDigitizer::accumulate_forPreMix(edm::Handle<edm::PCaloHitContainer> cons
496497
//cumulate the charge of new entry for all elements that follow in the sorted list
497498
//and resize list accounting for cases when the inserted element itself crosses the threshold
498499

500+
assert(waferThickness - 1 < static_cast<int>(tdcForToAOnset.size()));
499501
for (auto step = insertedPos; step != PhitRefs_bx0[id].end(); ++step) {
500502
if (step != insertedPos)
501503
std::get<1>(*(step)) += charge;
@@ -610,6 +612,7 @@ void HGCDigitizer::accumulate(edm::Handle<edm::PCaloHitContainer> const& hits,
610612
//for time-of-arrival: save the time-sorted list of timestamps with cumulative charge just above threshold
611613
//working version with pileup only for in-time hits
612614
int waferThickness = getCellThickness(geom, id);
615+
assert(waferThickness - 1 < static_cast<int>(tdcForToAOnset.size()));
613616
bool orderChanged = false;
614617
if (itime == (int)thisBx_) {
615618
//if start empty => just add charge and time

SimCalorimetry/HGCalSimProducers/src/HGCFEElectronics.cc

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "FWCore/Utilities/interface/transform.h"
55

66
#include "vdt/vdtMath.h"
7+
#include <cassert>
78

89
using namespace hgc_digi;
910
//#define EDM_ML_DEBUG
@@ -158,7 +159,7 @@ void HGCFEElectronics<DFr>::runSimpleShaper(DFr& dataFrame,
158159
float maxADC,
159160
const hgc_digi::FEADCPulseShape& adcPulse) {
160161
//convolute with pulse shape to compute new ADCs
161-
newCharge.fill(0.f);
162+
newCharge_.fill(0.f);
162163
bool debug(false);
163164
for (int it = 0; it < (int)(chargeColl.size()); it++) {
164165
const float charge(chargeColl[it]);
@@ -178,7 +179,7 @@ void HGCFEElectronics<DFr>::runSimpleShaper(DFr& dataFrame,
178179
if (it + ipulse >= (int)(dataFrame.size()))
179180
continue;
180181
const float chargeLeak = charge * adcPulse[(ipulse + 2)];
181-
newCharge[it + ipulse] += chargeLeak;
182+
newCharge_[it + ipulse] += chargeLeak;
182183

183184
if (debug)
184185
edm::LogVerbatim("HGCFE") << " | " << it + ipulse << " " << chargeLeak;
@@ -188,15 +189,15 @@ void HGCFEElectronics<DFr>::runSimpleShaper(DFr& dataFrame,
188189
edm::LogVerbatim("HGCFE") << std::endl;
189190
}
190191

191-
for (int it = 0; it < (int)(newCharge.size()); it++) {
192+
for (int it = 0; it < (int)(newCharge_.size()); it++) {
192193
//brute force saturation, maybe could to better with an exponential like saturation
193-
const uint32_t adc = std::floor(std::min(newCharge[it], maxADC) / lsbADC);
194+
const uint32_t adc = std::floor(std::min(newCharge_[it], maxADC) / lsbADC);
194195
HGCSample newSample;
195196
newSample.set(adc > thrADC, false, gainIdx, 0, adc);
196197
dataFrame.setSample(it, newSample);
197198

198199
if (debug)
199-
edm::LogVerbatim("HGCFE") << adc << " (" << std::min(newCharge[it], maxADC) << "/" << lsbADC << " ) ";
200+
edm::LogVerbatim("HGCFE") << adc << " (" << std::min(newCharge_[it], maxADC) << "/" << lsbADC << " ) ";
200201
}
201202

202203
if (debug) {
@@ -220,11 +221,11 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
220221
float tdcOnsetAuto,
221222
float noiseWidth,
222223
const hgc_digi::FEADCPulseShape& adcPulse) {
223-
busyFlags.fill(false);
224-
totFlags.fill(false);
225-
toaFlags.fill(false);
226-
newCharge.fill(0.f);
227-
toaFromToT.fill(0.f);
224+
busyFlags_.fill(false);
225+
totFlags_.fill(false);
226+
toaFlags_.fill(false);
227+
newCharge_.fill(0.f);
228+
toaFromToT_.fill(0.f);
228229

229230
#ifdef EDM_ML_DEBUG
230231
constexpr bool debug_state(true);
@@ -253,6 +254,9 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
253254
int fireBX = 9;
254255
//noise fluctuation on charge is added after ToA computation
255256
//to be done properly with realistic ToA shaper and jitter for the moment accounted in the smearing
257+
assert(static_cast<int>(tdcForToAOnset_fC_.size()) > thickness - 1);
258+
assert(static_cast<int>(noise_fC_.size()) > thickness - 1);
259+
assert(static_cast<int>(eventTimeOffset_ns_.size()) > thickness - 1);
256260
if (toaColl[fireBX] != 0.f && chargeColl[fireBX] > tdcForToAOnset_fC_[thickness - 1]) {
257261
timeToA = toaColl[fireBX];
258262
float sensor_noise = noiseWidth <= 0 ? noise_fC_[thickness - 1] : noiseWidth;
@@ -264,16 +268,19 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
264268
timeToA = CLHEP::RandGaussQ::shoot(engine, timeToA, tdcResolutionInNs_);
265269
timeToA += eventTimeOffset_ns_[thickness - 1];
266270
if (timeToA >= 0.f && timeToA <= 25.f)
267-
toaFlags[fireBX] = true;
271+
toaFlags_[fireBX] = true;
268272
}
269273

270274
//now look at charge
271275
//first identify bunches which will trigger ToT
272276
//if(debug_state) edm::LogVerbatim("HGCFE") << "[runShaperWithToT]";
277+
assert(chargeColl.size() <= busyFlags_.size());
278+
assert(chargeColl.size() <= totFlags_.size());
279+
assert(chargeColl.size() <= newCharge_.size());
273280
for (int it = 0; it < (int)(chargeColl.size()); ++it) {
274281
debug = debug_state;
275282
//if already flagged as busy it can't be re-used to trigger the ToT
276-
if (busyFlags[it])
283+
if (busyFlags_[it])
277284
continue;
278285

279286
if (tdcOnsetAuto < 0) {
@@ -289,7 +296,7 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
289296
//raise TDC mode for charge computation
290297
//ToA anyway fired independently will be sorted out with realistic ToA dedicated shaper
291298
float toa = timeToA;
292-
totFlags[it] = true;
299+
totFlags_[it] = true;
293300

294301
if (debug)
295302
edm::LogVerbatim("HGCFE") << "\t q=" << charge << " fC with <toa>=" << toa << " ns, triggers ToT @ " << it;
@@ -348,7 +355,7 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
348355
//add leakage from previous bunches in SARS ADC mode
349356
for (int jt = 0; jt < it; ++jt) {
350357
const unsigned int deltaT = (it - jt);
351-
if ((deltaT + 2) >= adcPulse.size() || chargeColl[jt] == 0.f || totFlags[jt] || busyFlags[jt])
358+
if ((deltaT + 2) >= adcPulse.size() || chargeColl[jt] == 0.f || totFlags_[jt] || busyFlags_[jt])
352359
continue;
353360

354361
const float leakCharge = chargeColl[jt] * adcPulse[deltaT + 2];
@@ -365,7 +372,7 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
365372
for (int jt = it + 1; jt < it + busyBxs && jt < dataFrame.size(); ++jt) {
366373
//this charge will be integrated in TDC mode
367374
//disable for SARS ADC
368-
busyFlags[jt] = true;
375+
busyFlags_[jt] = true;
369376

370377
const float extraCharge = chargeColl[jt];
371378
if (extraCharge == 0.f)
@@ -383,23 +390,23 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
383390
finalToA /= totalCharge;
384391
}
385392

386-
newCharge[it] = (totalCharge - tdcOnset);
393+
newCharge_[it] = (totalCharge - tdcOnset);
387394

388395
if (debug)
389396
edm::LogVerbatim("HGCFE") << "\t Final busy estimate=" << integTime << " ns = " << busyBxs << " bxs" << std::endl
390-
<< "\t Total integrated=" << totalCharge << " fC <toa>=" << toaFromToT[it]
397+
<< "\t Total integrated=" << totalCharge << " fC <toa>=" << toaFromToT_[it]
391398
<< " (raw=" << finalToA << ") ns ";
392399

393400
//last fC (tdcOnset) are dissipated trough pulse
394-
if (it + busyBxs < (int)(newCharge.size())) {
401+
if (it + busyBxs < (int)(newCharge_.size())) {
395402
const float deltaT2nextBx((busyBxs * 25 - integTime));
396403
const float tdcOnsetLeakage(tdcOnset * vdt::fast_expf(-deltaT2nextBx / tdcChargeDrainParameterisation_[11]));
397404
if (debug)
398405
edm::LogVerbatim("HGCFE") << "\t Leaking remainder of TDC onset " << tdcOnset << " fC, to be dissipated in "
399406
<< deltaT2nextBx << " DeltaT/tau=" << deltaT2nextBx << " / "
400407
<< tdcChargeDrainParameterisation_[11] << " ns, adds " << tdcOnsetLeakage << " fC @ "
401408
<< it + busyBxs << " bx (first free bx)";
402-
newCharge[it + busyBxs] += tdcOnsetLeakage;
409+
newCharge_[it + busyBxs] += tdcOnsetLeakage;
403410
}
404411
}
405412

@@ -409,19 +416,19 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
409416
for (int it = 0; it < (int)(chargeColl.size()); ++it) {
410417
//if busy, charge has been already integrated
411418
//if(debug) edm::LogVerbatim("HGCFE") << "\t SARS ADC pulse activated @ " << it << " : ";
412-
if (!totFlags[it] && !busyFlags[it]) {
419+
if (!totFlags_[it] && !busyFlags_[it]) {
413420
const int start = std::max(0, 2 - it);
414-
const int stop = std::min((int)adcPulse.size(), (int)newCharge.size() - it + 2);
421+
const int stop = std::min((int)adcPulse.size(), (int)newCharge_.size() - it + 2);
415422
for (ipulse = start; ipulse < stop; ++ipulse) {
416423
const int itoffset = it + ipulse - 2;
417424
//notice that if the channel is already busy,
418425
//it has already been affected by the leakage of the SARS ADC
419-
//if(totFlags[itoffset] || busyFlags[itoffset]) continue;
420-
if (!totFlags[itoffset] && !busyFlags[itoffset]) {
421-
newCharge[itoffset] += chargeColl[it] * adcPulse[ipulse];
426+
//if(totFlags_[itoffset] || busyFlags_[itoffset]) continue;
427+
if (!totFlags_[itoffset] && !busyFlags_[itoffset]) {
428+
newCharge_[itoffset] += chargeColl[it] * adcPulse[ipulse];
422429
}
423430
//if(debug) edm::LogVerbatim("HGCFE") << " | " << itoffset << " " << chargeColl[it]*adcPulse[ipulse] << "( " << chargeColl[it] << "->";
424-
//if(debug) edm::LogVerbatim("HGCFE") << newCharge[itoffset] << ") ";
431+
//if(debug) edm::LogVerbatim("HGCFE") << newCharge_[itoffset] << ") ";
425432
}
426433
}
427434

@@ -435,13 +442,13 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
435442
//and for that should keep track of the BX firing the ToA somewhere (also to restore the use of finalToA)
436443
/*
437444
float finalToA(0.);
438-
for(int it=0; it<(int)(newCharge.size()); it++){
439-
if(toaFlags[it]){
440-
finalToA = toaFromToT[it];
445+
for(int it=0; it<(int)(newCharge_.size()); it++){
446+
if(toaFlags_[it]){
447+
finalToA = toaFromToT_[it];
441448
//to avoid +=25 for small negative time taken as 0
442449
while(finalToA < -1.e-5) finalToA+=25.f;
443450
while(finalToA > 25.f) finalToA-=25.f;
444-
toaFromToT[it] = finalToA;
451+
toaFromToT_[it] = finalToA;
445452
}
446453
}
447454
*/
@@ -450,29 +457,30 @@ void HGCFEElectronics<DFr>::runShaperWithToT(DFr& dataFrame,
450457
//set new ADCs and ToA
451458
if (debug)
452459
edm::LogVerbatim("HGCFE") << "\t final result : ";
453-
for (int it = 0; it < (int)(newCharge.size()); it++) {
460+
assert(chargeColl.size() >= newCharge_.size());
461+
for (int it = 0; it < (int)(newCharge_.size()); it++) {
454462
if (debug)
455-
edm::LogVerbatim("HGCFE") << chargeColl[it] << " -> " << newCharge[it] << " ";
463+
edm::LogVerbatim("HGCFE") << chargeColl[it] << " -> " << newCharge_[it] << " ";
456464

457465
HGCSample newSample;
458-
if (totFlags[it] || busyFlags[it]) {
459-
if (totFlags[it]) {
466+
if (totFlags_[it] || busyFlags_[it]) {
467+
if (totFlags_[it]) {
460468
//brute force saturation, maybe could to better with an exponential like saturation
461-
const float saturatedCharge(std::min(newCharge[it], tdcSaturation_fC_));
469+
const float saturatedCharge(std::min(newCharge_[it], tdcSaturation_fC_));
462470
//working version for in-time PU and signal
463471
newSample.set(
464472
true, true, gainIdx, (uint16_t)(timeToA / toaLSB_ns_), (uint16_t)(std::floor(saturatedCharge / tdcLSB_fC_)));
465-
if (toaFlags[it])
473+
if (toaFlags_[it])
466474
newSample.setToAValid(true);
467475
} else {
468476
newSample.set(false, true, gainIdx, 0, 0);
469477
}
470478
} else {
471479
//brute force saturation, maybe could to better with an exponential like saturation
472-
const uint16_t adc = std::floor(std::min(newCharge[it], maxADC) / lsbADC);
480+
const uint16_t adc = std::floor(std::min(newCharge_[it], maxADC) / lsbADC);
473481
//working version for in-time PU and signal
474482
newSample.set(adc > thrADC, false, gainIdx, (uint16_t)(timeToA / toaLSB_ns_), adc);
475-
if (toaFlags[it])
483+
if (toaFlags_[it])
476484
newSample.setToAValid(true);
477485
}
478486
dataFrame.setSample(it, newSample);

0 commit comments

Comments
 (0)