46 mThresholdMax = ic.options().get<
float>(
"threshold-max");
47 mThresholdAbs = ic.options().get<
float>(
"threshold-abs");
48 mThresholdSigma = ic.options().get<
float>(
"threshold-sigma");
49 mTimeBinsBefore = ic.options().get<
int>(
"time-bins-before");
50 mTimeBinsAfter = ic.options().get<
int>(
"time-bins-after");
51 mMaxTimeBins = ic.options().get<
int>(
"max-time-bins");
52 mSkipIROCTSensors = ic.options().get<
bool>(
"skip-iroc-tsen");
53 LOGP(info,
"threshold-max: {}, threshold-abs: {}, threshold-sigma: {}, time-bins-before: {}, time-bins-after: {}, max-time-bins: {}, skip-iroc-tsen: {}", mThresholdMax, mThresholdAbs, mThresholdSigma, mTimeBinsBefore, mTimeBinsAfter, mMaxTimeBins, mSkipIROCTSensors);
59 const size_t MAXROWS = 152;
60 const size_t MAXPADS = 138;
63 auto const* sectorHeader = DataRefUtils::getHeader<TPCSectorHeader*>(inputRef);
64 if (sectorHeader ==
nullptr) {
65 LOGP(error,
"sector header missing on header stack for input on ", inputRef.spec->binding);
69 const int sector = sectorHeader->sector();
70 auto inDigitsO = pc.inputs().get<gsl::span<o2::tpc::Digit>>(inputRef);
71 LOGP(
debug,
"processing sector {} with {} input digits", sector, inDigitsO.size());
75 std::vector<float> inDigits(MAXROWS * MAXPADS * mMaxTimeBins);
78 std::vector<size_t> nTriggered(MAXROWS * MAXPADS);
85 std::vector<DigitInfo> maxDigits;
87 for (
const auto& digit : inDigitsO) {
88 const auto time = digit.getTimeStamp();
89 if (
time >= mMaxTimeBins) {
93 const auto pad = digit.getPad();
94 const auto row = digit.getRow();
95 const auto charge = digit.getChargeFloat();
97 const size_t offset =
row * MAXPADS * mMaxTimeBins + pad * mMaxTimeBins;
100 const auto noiseThreshold = mNoise ? mThresholdSigma * mNoise->
getValue(
Sector(sector),
row, pad) : 0.f;
101 if ((
charge > mThresholdMax) && (
charge > noiseThreshold)) {
102 if (!(mSkipIROCTSensors && (
row == 47) && (pad > 40))) {
103 if ((
time > mTimeBinsBefore) && (
time < (mMaxTimeBins - mTimeBinsAfter))) {
104 maxDigits.emplace_back(DigitInfo{
row, pad,
time});
105 ++nTriggered[
row * MAXPADS + pad];
114 auto isLocalMaximum = [&inDigits,
this](
const int row,
const int pad,
const int time) {
115 const size_t offset =
row * MAXPADS * mMaxTimeBins + pad * mMaxTimeBins +
time;
116 const auto testCharge = inDigits[
offset];
119 if (!(testCharge > inDigits[
offset + 1])) {
122 if (testCharge < inDigits[
offset - 1]) {
127 if (!(testCharge > inDigits[
offset + mMaxTimeBins])) {
130 if (testCharge < inDigits[
offset - mMaxTimeBins]) {
135 if (!(testCharge > inDigits[
offset + mMaxTimeBins + 1])) {
138 if (!(testCharge > inDigits[
offset + mMaxTimeBins - 1])) {
141 if (testCharge < inDigits[
offset - mMaxTimeBins + 1]) {
144 if (testCharge < inDigits[
offset - mMaxTimeBins - 1]) {
152 std::vector<Digit>
digits;
155 auto fillDigits = [&
digits, &inDigits, §or,
this](
const size_t row,
const size_t pad,
const size_t time) {
157 const size_t offset =
row * MAXPADS * mMaxTimeBins + pad * mMaxTimeBins;
159 const auto chargeMax = inDigits[
offset +
time];
161 for (
int iTime =
time - mTimeBinsBefore; iTime <
time + mTimeBinsAfter; ++iTime) {
167 inDigits[
offset + iTime] = -1000.f;
170 const auto noiseThreshold = mNoise ? mThresholdSigma * mNoise->
getValue(
Sector(sector),
row, pad) : 0.f;
171 return (chargeMax > mThresholdAbs) && (chargeMax > noiseThreshold);
175 for (
const auto& maxDigit : maxDigits) {
176 const auto row = maxDigit.row;
177 const auto pad = maxDigit.pad;
179 if (nTriggered[
row * MAXPADS + pad] > mMaxTimeBins / 4) {
182 const auto time = maxDigit.time;
183 const int nPads = mapper.getNumberOfPadsInRowSector(
row);
185 if ((pad == 0) || (pad == nPads - 1)) {
189 if (isLocalMaximum(
row, pad,
time)) {
191 while ((padRef >= 0) && fillDigits(
row, padRef,
time)) {
195 while ((padRef < nPads) && fillDigits(
row, padRef,
time)) {
201 snapshot(pc.outputs(),
digits, sector);
203 LOGP(info,
"processed sector {} with {} input and {} filtered digits", sector, inDigitsO.size(),
digits.size());
207 LOGP(info,
"Number of processed time frames: {}", mProcessedTFs);