22#include <fairlogger/Logger.h>
30HwClusterer::HwClusterer(
31 std::vector<ClusterHardwareContainer8kb>* clusterOutputContainer,
36 mCurrentMcContainerInBuffer(0),
38 mClusterSector(sectorid),
43 mPeakChargeThreshold(2),
44 mContributionChargeThreshold(0),
46 mIsContinuousReadout(
true),
47 mRejectSinglePadClusters(
false),
48 mRejectSingleTimeClusters(
false),
49 mRejectLaterTimebin(
false),
52 mGlobalRowToLocalRow(),
53 mGlobalRowToVcIndex(),
60 mClusterMcLabelArray(labelOutput),
61 mClusterArray(clusterOutputContainer)
63 LOG(
debug) <<
"Enter Initializer of HwClusterer";
66 assert(sectorid >= 0 && sectorid < 36);
75 mDataBuffer.resize(mNumRowSets);
76 mIndexBuffer.resize(mNumRowSets);
77 mPadsPerRowSet.resize(mNumRowSets);
79 mGlobalRowToVcIndex.resize(mNumRows);
80 mGlobalRowToRowSet.resize(mNumRows);
81 for (
unsigned short row = 0;
row < mNumRowSets; ++
row) {
84 for (
int subrow = 0; subrow < Vc::uint_v::Size; ++subrow) {
86 mGlobalRowToRowSet[
row * Vc::uint_v::Size + subrow] =
row;
87 mGlobalRowToVcIndex[
row * Vc::uint_v::Size + subrow] = subrow;
92 mDataBuffer[
row].resize(mPadsPerRowSet[
row] * mTimebinsInBuffer, 0);
93 mIndexBuffer[
row].resize(mPadsPerRowSet[
row] * mTimebinsInBuffer, -1);
96 mTmpClusterArray.resize(10);
97 mTmpLabelArray.resize(10);
98 for (
unsigned short region = 0; region < 10; ++region) {
99 mTmpClusterArray[region] = std::make_unique<std::vector<ClusterHardware>>();
100 mTmpLabelArray[region] = std::make_unique<std::vector<std::vector<std::pair<MCCompLabel, unsigned>>>>();
103 mGlobalRowToRegion.resize(mNumRows);
104 mGlobalRowToLocalRow.resize(mNumRows);
105 unsigned short row = 0;
106 for (
unsigned short region = 0; region < 10; ++region) {
108 mGlobalRowToRegion[
row] = region;
109 mGlobalRowToLocalRow[
row] = localRow;
113 mMCtruth.resize(mTimebinsInBuffer,
nullptr);
121 mPeakChargeThreshold =
param.peakChargeThreshold;
122 mContributionChargeThreshold =
param.contributionChargeThreshold;
123 mFirstTimebin =
param.firstTimeBin;
124 mLastTimebin =
param.lastTimeBin;
125 mSplittingMode =
param.splittingMode;
126 mIsContinuousReadout =
param.isContinuousReadout;
127 mRejectSinglePadClusters =
param.rejectSinglePadClusters;
128 mRejectSingleTimeClusters =
param.rejectSingleTimeClusters;
129 mRejectLaterTimebin =
param.rejectLaterTimebin;
135 if (clearContainerFirst) {
137 mClusterArray->clear();
140 if (mClusterMcLabelArray) {
141 mClusterMcLabelArray->
clear();
149 mCurrentMcContainerInBuffer = 0;
154 for (
const auto& digit :
digits) {
168 const auto timeBin = digit.getTimeStamp();
170 if (timeBin < mFirstTimebin) {
172 }
else if (timeBin > mLastTimebin) {
176 if (timeBin != mPreviousTimebin) {
183 for (
int i = mPreviousTimebin; (
i < timeBin) && (
i - mPreviousTimebin < mTimebinsInBuffer); ++
i) {
194 HB =
i < 3 ? 0 : (
i - 3) / 447;
196 writeOutputWithTimeOffset(mLastHB * 447);
222 computeClusterForTime(
i - 3);
233 if (mCurrentMcContainerInBuffer == 0) {
234 auto tmp = std::make_shared<MCLabelContainer>();
236 mMCtruth[mapTimeInRange(timeBin)] = tmp;
238 mMCtruth[mapTimeInRange(timeBin)] = std::shared_ptr<MCLabelContainer const>(mMCtruth[getFirstSetBitOfField()]);
240 mCurrentMcContainerInBuffer |= (0x1 << (mapTimeInRange(timeBin)));
247 const auto row = digit.getRow();
248 const auto pad = digit.getPad();
249 index = mapTimeInRange(timeBin) * mPadsPerRowSet[mGlobalRowToRowSet[
row]] + (pad + 2);
252 float charge = digit.getChargeFloat();
262 mDataBuffer[mGlobalRowToRowSet[
row]][
index][mGlobalRowToVcIndex[
row]] =
265 mIndexBuffer[mGlobalRowToRowSet[
row]][
index][mGlobalRowToVcIndex[
row]] = digitIndex++;
267 mPreviousTimebin = timeBin;
270 if (!mIsContinuousReadout) {
275 LOG(
debug) <<
"Event ranged from time bin " <<
digits[0].getTimeStamp() <<
" to " <<
digits[
digits.size() - 1].getTimeStamp() <<
".";
290void HwClusterer::hwClusterProcessor(
const Vc::uint_m peakMask,
unsigned qMaxIndex,
short centerPad,
int centerTime,
unsigned short row)
295 Vc::int_v sigmaPad2 = 0;
296 Vc::int_v sigmaTime2 = 0;
299 using labelPair = std::pair<MCCompLabel, unsigned>;
300 std::vector<std::unique_ptr<std::vector<labelPair>>> mcLabels(Vc::uint_v::Size);
301 for (
int i = 0;
i < Vc::uint_v::Size; ++
i) {
302 mcLabels[
i] = std::make_unique<std::vector<labelPair>>();
305 const unsigned llttIndex = mapTimeInRange(centerTime - 2) * mPadsPerRowSet[
row] + centerPad - 2;
306 const unsigned lltIndex = mapTimeInRange(centerTime - 1) * mPadsPerRowSet[
row] + centerPad - 2;
307 const unsigned llIndex = mapTimeInRange(centerTime + 0) * mPadsPerRowSet[
row] + centerPad - 2;
308 const unsigned llbIndex = mapTimeInRange(centerTime + 1) * mPadsPerRowSet[
row] + centerPad - 2;
309 const unsigned llbbIndex = mapTimeInRange(centerTime + 2) * mPadsPerRowSet[
row] + centerPad - 2;
311 const unsigned lttIndex = llttIndex + 1;
312 const unsigned ltIndex = lltIndex + 1;
313 const unsigned lIndex = llIndex + 1;
314 const unsigned lbIndex = llbIndex + 1;
315 const unsigned lbbIndex = llbbIndex + 1;
317 const unsigned ttIndex = lttIndex + 1;
318 const unsigned tIndex = ltIndex + 1;
319 const unsigned bIndex = lbIndex + 1;
320 const unsigned bbIndex = lbbIndex + 1;
322 const unsigned rttIndex = ttIndex + 1;
323 const unsigned rtIndex = tIndex + 1;
324 const unsigned rIndex = lIndex + 2;
325 const unsigned rbIndex = bIndex + 1;
326 const unsigned rbbIndex = bbIndex + 1;
328 const unsigned rrttIndex = rttIndex + 1;
329 const unsigned rrtIndex = rtIndex + 1;
330 const unsigned rrIndex = rIndex + 1;
331 const unsigned rrbIndex = rbIndex + 1;
332 const unsigned rrbbIndex = rbbIndex + 1;
334 Vc::uint_m selectionMask;
335 if (mSplittingMode == 0) {
350 for (
short dt = -1; dt <= 1; ++dt) {
351 for (
short dp = -1; dp <= 1; ++dp) {
352 updateCluster(peakMask,
row, centerPad, centerTime, dp, dt, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
362 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][lIndex]) > (mContributionChargeThreshold << 4));
363 updateCluster(selectionMask,
row, centerPad, centerTime, -2, 0, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
365 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][rIndex]) > (mContributionChargeThreshold << 4));
366 updateCluster(selectionMask,
row, centerPad, centerTime, +2, 0, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
368 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][tIndex]) > (mContributionChargeThreshold << 4));
369 updateCluster(selectionMask,
row, centerPad, centerTime, 0, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
371 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][bIndex]) > (mContributionChargeThreshold << 4));
372 updateCluster(selectionMask,
row, centerPad, centerTime, 0, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
379 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][ltIndex]) > (mContributionChargeThreshold << 4));
380 updateCluster(selectionMask,
row, centerPad, centerTime, -2, -1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
381 updateCluster(selectionMask,
row, centerPad, centerTime, -2, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
382 updateCluster(selectionMask,
row, centerPad, centerTime, -1, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
384 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][lbIndex]) > (mContributionChargeThreshold << 4));
385 updateCluster(selectionMask,
row, centerPad, centerTime, -2, +1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
386 updateCluster(selectionMask,
row, centerPad, centerTime, -2, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
387 updateCluster(selectionMask,
row, centerPad, centerTime, -1, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
389 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][rtIndex]) > (mContributionChargeThreshold << 4));
390 updateCluster(selectionMask,
row, centerPad, centerTime, +2, -1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
391 updateCluster(selectionMask,
row, centerPad, centerTime, +2, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
392 updateCluster(selectionMask,
row, centerPad, centerTime, +1, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
394 selectionMask = peakMask & (getFpOfADC(mDataBuffer[
row][rbIndex]) > (mContributionChargeThreshold << 4));
395 updateCluster(selectionMask,
row, centerPad, centerTime, +2, +1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
396 updateCluster(selectionMask,
row, centerPad, centerTime, +2, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
397 updateCluster(selectionMask,
row, centerPad, centerTime, +1, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
399 }
else if (mSplittingMode == 1) {
410 updateCluster(peakMask,
row, centerPad, centerTime, 0, 0, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels);
413 auto splitMask = (((mDataBuffer[
row][lIndex] >> 26) & 0x1) == 0x1);
414 updateCluster(peakMask,
row, centerPad, centerTime, -1, 0, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
416 splitMask = (((mDataBuffer[
row][rIndex] >> 26) & 0x1) == 0x1);
417 updateCluster(peakMask,
row, centerPad, centerTime, +1, 0, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
420 splitMask = (((mDataBuffer[
row][tIndex] >> 25) & 0x1) == 0x1);
421 updateCluster(peakMask,
row, centerPad, centerTime, 0, -1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
423 splitMask = (((mDataBuffer[
row][bIndex] >> 25) & 0x1) == 0x1);
424 updateCluster(peakMask,
row, centerPad, centerTime, 0, +1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
427 splitMask = (((mDataBuffer[
row][ltIndex] >> 24) & 0x1) == 0x1) |
428 (((mDataBuffer[
row][ltIndex] >> 25) & 0x1) == 0x1) |
429 (((mDataBuffer[
row][ltIndex] >> 26) & 0x1) == 0x1);
430 updateCluster(peakMask,
row, centerPad, centerTime, -1, -1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
432 splitMask = (((mDataBuffer[
row][rbIndex] >> 24) & 0x1) == 0x1) |
433 (((mDataBuffer[
row][rbIndex] >> 25) & 0x1) == 0x1) |
434 (((mDataBuffer[
row][rbIndex] >> 26) & 0x1) == 0x1);
435 updateCluster(peakMask,
row, centerPad, centerTime, +1, +1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
438 splitMask = (((mDataBuffer[
row][rtIndex] >> 23) & 0x1) == 0x1) |
439 (((mDataBuffer[
row][rtIndex] >> 25) & 0x1) == 0x1) |
440 (((mDataBuffer[
row][rtIndex] >> 26) & 0x1) == 0x1);
441 updateCluster(peakMask,
row, centerPad, centerTime, +1, -1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
443 splitMask = (((mDataBuffer[
row][lbIndex] >> 23) & 0x1) == 0x1) |
444 (((mDataBuffer[
row][lbIndex] >> 25) & 0x1) == 0x1) |
445 (((mDataBuffer[
row][lbIndex] >> 26) & 0x1) == 0x1);
446 updateCluster(peakMask,
row, centerPad, centerTime, -1, +1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
456 selectionMask = peakMask &
457 (getFpOfADC(mDataBuffer[
row][lIndex]) > (mContributionChargeThreshold << 4)) &
458 (((mDataBuffer[
row][lIndex] >> 26) & 0x1) != 0x1);
459 splitMask = (((mDataBuffer[
row][llIndex] >> 26) & 0x1) == 0x1);
460 updateCluster(selectionMask,
row, centerPad, centerTime, -2, 0, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
462 selectionMask = peakMask &
463 (getFpOfADC(mDataBuffer[
row][rIndex]) > (mContributionChargeThreshold << 4)) &
464 (((mDataBuffer[
row][rIndex] >> 26) & 0x1) != 0x1);
465 splitMask = (((mDataBuffer[
row][rrIndex] >> 26) & 0x1) == 0x1);
466 updateCluster(selectionMask,
row, centerPad, centerTime, +2, 0, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
468 selectionMask = peakMask &
469 (getFpOfADC(mDataBuffer[
row][tIndex]) > (mContributionChargeThreshold << 4)) &
470 (((mDataBuffer[
row][tIndex] >> 25) & 0x1) != 0x1);
471 splitMask = (((mDataBuffer[
row][ttIndex] >> 26) & 0x1) == 0x1);
472 updateCluster(selectionMask,
row, centerPad, centerTime, 0, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
474 selectionMask = peakMask &
475 (getFpOfADC(mDataBuffer[
row][bIndex]) > (mContributionChargeThreshold << 4)) &
476 (((mDataBuffer[
row][bIndex] >> 25) & 0x1) != 0x1);
477 splitMask = (((mDataBuffer[
row][bbIndex] >> 26) & 0x1) == 0x1);
478 updateCluster(selectionMask,
row, centerPad, centerTime, 0, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
485 selectionMask = peakMask &
486 (getFpOfADC(mDataBuffer[
row][ltIndex]) > (mContributionChargeThreshold << 4)) &
487 (((mDataBuffer[
row][ltIndex] >> 26) & 0x1) != 0x1);
488 splitMask = (((mDataBuffer[
row][lltIndex] >> 26) & 0x1) == 0x1) |
489 (((mDataBuffer[
row][lltIndex] >> 24) & 0x1) == 0x1);
490 updateCluster(selectionMask,
row, centerPad, centerTime, -2, -1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
492 selectionMask = peakMask &
493 (getFpOfADC(mDataBuffer[
row][ltIndex]) > (mContributionChargeThreshold << 4)) &
494 (((mDataBuffer[
row][ltIndex] >> 24) & 0x1) != 0x1) &
495 (((mDataBuffer[
row][ltIndex] >> 25) & 0x1) != 0x1) &
496 (((mDataBuffer[
row][ltIndex] >> 26) & 0x1) != 0x1) &
497 (((mDataBuffer[
row][lltIndex] >> 25) & 0x1) != 0x1) &
498 (((mDataBuffer[
row][lttIndex] >> 26) & 0x1) != 0x1);
499 splitMask = (((mDataBuffer[
row][llttIndex] >> 24) & 0x1) == 0x1) |
500 (((mDataBuffer[
row][llttIndex] >> 25) & 0x1) == 0x1) |
501 (((mDataBuffer[
row][llttIndex] >> 26) & 0x1) == 0x1);
502 updateCluster(selectionMask,
row, centerPad, centerTime, -2, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
504 selectionMask = peakMask &
505 (getFpOfADC(mDataBuffer[
row][ltIndex]) > (mContributionChargeThreshold << 4)) &
506 (((mDataBuffer[
row][ltIndex] >> 25) & 0x1) != 0x1);
507 splitMask = (((mDataBuffer[
row][lttIndex] >> 25) & 0x1) == 0x1) |
508 (((mDataBuffer[
row][lttIndex] >> 24) & 0x1) == 0x1);
509 updateCluster(selectionMask,
row, centerPad, centerTime, -1, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
511 selectionMask = peakMask &
512 (getFpOfADC(mDataBuffer[
row][lbIndex]) > (mContributionChargeThreshold << 4)) &
513 (((mDataBuffer[
row][lbIndex] >> 26) & 0x1) != 0x1);
514 splitMask = (((mDataBuffer[
row][llbIndex] >> 26) & 0x1) == 0x1) |
515 (((mDataBuffer[
row][llbIndex] >> 23) & 0x1) == 0x1);
516 updateCluster(selectionMask,
row, centerPad, centerTime, -2, +1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
518 selectionMask = peakMask &
519 (getFpOfADC(mDataBuffer[
row][lbIndex]) > (mContributionChargeThreshold << 4)) &
520 (((mDataBuffer[
row][lbIndex] >> 23) & 0x1) != 0x1) &
521 (((mDataBuffer[
row][lbIndex] >> 25) & 0x1) != 0x1) &
522 (((mDataBuffer[
row][lbIndex] >> 26) & 0x1) != 0x1) &
523 (((mDataBuffer[
row][llbIndex] >> 25) & 0x1) != 0x1) &
524 (((mDataBuffer[
row][lbbIndex] >> 26) & 0x1) != 0x1);
525 splitMask = (((mDataBuffer[
row][llbbIndex] >> 23) & 0x1) == 0x1) |
526 (((mDataBuffer[
row][llbbIndex] >> 25) & 0x1) == 0x1) |
527 (((mDataBuffer[
row][llbbIndex] >> 26) & 0x1) == 0x1);
528 updateCluster(selectionMask,
row, centerPad, centerTime, -2, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
530 selectionMask = peakMask &
531 (getFpOfADC(mDataBuffer[
row][lbIndex]) > (mContributionChargeThreshold << 4)) &
532 (((mDataBuffer[
row][lbIndex] >> 25) & 0x1) != 0x1);
533 splitMask = (((mDataBuffer[
row][lbbIndex] >> 25) & 0x1) == 0x1) |
534 (((mDataBuffer[
row][lbbIndex] >> 23) & 0x1) == 0x1);
535 updateCluster(selectionMask,
row, centerPad, centerTime, -1, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
537 selectionMask = peakMask &
538 (getFpOfADC(mDataBuffer[
row][rtIndex]) > (mContributionChargeThreshold << 4)) &
539 (((mDataBuffer[
row][rtIndex] >> 26) & 0x1) != 0x1);
540 splitMask = (((mDataBuffer[
row][rrtIndex] >> 26) & 0x1) == 0x1) |
541 (((mDataBuffer[
row][rrtIndex] >> 23) & 0x1) == 0x1);
542 updateCluster(selectionMask,
row, centerPad, centerTime, +2, -1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
544 selectionMask = peakMask &
545 (getFpOfADC(mDataBuffer[
row][rtIndex]) > (mContributionChargeThreshold << 4)) &
546 (((mDataBuffer[
row][rtIndex] >> 23) & 0x1) != 0x1) &
547 (((mDataBuffer[
row][rtIndex] >> 25) & 0x1) != 0x1) &
548 (((mDataBuffer[
row][rtIndex] >> 26) & 0x1) != 0x1) &
549 (((mDataBuffer[
row][rrtIndex] >> 25) & 0x1) != 0x1) &
550 (((mDataBuffer[
row][rttIndex] >> 26) & 0x1) != 0x1);
551 splitMask = (((mDataBuffer[
row][rrttIndex] >> 23) & 0x1) == 0x1) |
552 (((mDataBuffer[
row][rrttIndex] >> 25) & 0x1) == 0x1) |
553 (((mDataBuffer[
row][rrttIndex] >> 26) & 0x1) == 0x1);
554 updateCluster(selectionMask,
row, centerPad, centerTime, +2, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
556 selectionMask = peakMask &
557 (getFpOfADC(mDataBuffer[
row][rtIndex]) > (mContributionChargeThreshold << 4)) &
558 (((mDataBuffer[
row][rtIndex] >> 25) & 0x1) != 0x1);
559 splitMask = (((mDataBuffer[
row][rttIndex] >> 25) & 0x1) == 0x1) |
560 (((mDataBuffer[
row][rttIndex] >> 23) & 0x1) == 0x1);
561 updateCluster(selectionMask,
row, centerPad, centerTime, +1, -2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
563 selectionMask = peakMask &
564 (getFpOfADC(mDataBuffer[
row][rbIndex]) > (mContributionChargeThreshold << 4)) &
565 (((mDataBuffer[
row][rbIndex] >> 26) & 0x1) != 0x1);
566 splitMask = (((mDataBuffer[
row][rrbIndex] >> 26) & 0x1) == 0x1) |
567 (((mDataBuffer[
row][rrbIndex] >> 24) & 0x1) == 0x1);
568 updateCluster(selectionMask,
row, centerPad, centerTime, +2, +1, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
570 selectionMask = peakMask &
571 (getFpOfADC(mDataBuffer[
row][rbIndex]) > (mContributionChargeThreshold << 4)) &
572 (((mDataBuffer[
row][rbIndex] >> 24) & 0x1) != 0x1) &
573 (((mDataBuffer[
row][rbIndex] >> 25) & 0x1) != 0x1) &
574 (((mDataBuffer[
row][rbIndex] >> 26) & 0x1) != 0x1) &
575 (((mDataBuffer[
row][rrbIndex] >> 25) & 0x1) != 0x1) &
576 (((mDataBuffer[
row][rbbIndex] >> 26) & 0x1) != 0x1);
577 splitMask = (((mDataBuffer[
row][rrbbIndex] >> 24) & 0x1) == 0x1) |
578 (((mDataBuffer[
row][rrbbIndex] >> 25) & 0x1) == 0x1) |
579 (((mDataBuffer[
row][rrbbIndex] >> 26) & 0x1) == 0x1);
580 updateCluster(selectionMask,
row, centerPad, centerTime, +2, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
582 selectionMask = peakMask &
583 (getFpOfADC(mDataBuffer[
row][rbIndex]) > (mContributionChargeThreshold << 4)) &
584 (((mDataBuffer[
row][rbIndex] >> 25) & 0x1) != 0x1);
585 splitMask = (((mDataBuffer[
row][rbbIndex] >> 25) & 0x1) == 0x1) |
586 (((mDataBuffer[
row][rbbIndex] >> 24) & 0x1) == 0x1);
587 updateCluster(selectionMask,
row, centerPad, centerTime, +1, +2, qTot, pad,
time, sigmaPad2, sigmaTime2, mcLabels, splitMask);
590 selectionMask = peakMask;
591 if (mRejectSinglePadClusters) {
592 selectionMask &= !(sigmaPad2 == 0);
594 if (mRejectSingleTimeClusters) {
595 selectionMask &= !(sigmaTime2 == 0);
599 for (
int i = 0;
i < Vc::uint_v::Size; ++
i) {
600 if (selectionMask[
i]) {
602 mTmpClusterArray[mGlobalRowToRegion[
row * Vc::uint_v::Size +
i]]->emplace_back();
603 mTmpClusterArray[mGlobalRowToRegion[
row * Vc::uint_v::Size +
i]]->back().setCluster(
607 sigmaPad2[
i], sigmaTime2[
i],
608 (getFpOfADC(mDataBuffer[
row][qMaxIndex])[
i] >> 3),
610 mGlobalRowToLocalRow[
row * Vc::uint_v::Size +
i],
613 std::sort(mcLabels[
i]->
begin(), mcLabels[
i]->
end(), [](
const labelPair&
a,
const labelPair&
b) {
return a.second >
b.second; });
614 mTmpLabelArray[mGlobalRowToRegion[
row * Vc::uint_v::Size +
i]]->push_back(std::move(*mcLabels[
i]));
620void HwClusterer::hwPeakFinder(
unsigned qMaxIndex,
short centerPad,
int mappedCenterTime,
unsigned short row)
653 const int compareIndex0 = mappedCenterTime * mPadsPerRowSet[
row] + centerPad - 1;
654 const int compareIndex1 = mapTimeInRange(mappedCenterTime - 1) * mPadsPerRowSet[
row] + centerPad;
655 const int compareIndex2 = compareIndex1 - 1;
656 const int compareIndex3 = compareIndex1 + 1;
657 const auto adcMask = (getFpOfADC(mDataBuffer[
row][qMaxIndex]) == 0) &
658 (getFpOfADC(mDataBuffer[
row][compareIndex0]) == 0) &
659 (getFpOfADC(mDataBuffer[
row][compareIndex1]) == 0) &
660 (getFpOfADC(mDataBuffer[
row][compareIndex2]) == 0) &
661 (getFpOfADC(mDataBuffer[
row][compareIndex3]) == 0);
662 if (adcMask.isFull()) {
665 mDataBuffer[
row][qMaxIndex] |= (0x1 << 31);
666 mDataBuffer[
row][compareIndex0] &= ~(0x1 << 31);
667 mDataBuffer[
row][qMaxIndex] |= (0x1 << 30);
668 mDataBuffer[
row][compareIndex1] &= ~(0x1 << 30);
669 mDataBuffer[
row][qMaxIndex] |= (0x1 << 29);
670 mDataBuffer[
row][compareIndex2] &= ~(0x1 << 29);
671 mDataBuffer[
row][qMaxIndex] |= (0x1 << 28);
672 mDataBuffer[
row][compareIndex3] &= ~(0x1 << 28);
679 auto tmpMask = getFpOfADC(mDataBuffer[
row][qMaxIndex]) >= getFpOfADC(mDataBuffer[
row][compareIndex0]);
684 Vc::where(tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 31);
685 Vc::where(tmpMask) | mDataBuffer[
row][compareIndex0] &= ~(0x1 << 31);
691 Vc::where(!tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 26);
692 Vc::where(!tmpMask) | mDataBuffer[
row][compareIndex0] &= ~(0x1 << 26);
696 tmpMask = getFpOfADC(mDataBuffer[
row][qMaxIndex]) >= getFpOfADC(mDataBuffer[
row][compareIndex1]);
697 Vc::where(tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 30);
698 Vc::where(tmpMask) | mDataBuffer[
row][compareIndex1] &= ~(0x1 << 30);
699 Vc::where(!tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 25);
700 Vc::where(!tmpMask) | mDataBuffer[
row][compareIndex1] &= ~(0x1 << 25);
704 tmpMask = getFpOfADC(mDataBuffer[
row][qMaxIndex]) >= getFpOfADC(mDataBuffer[
row][compareIndex2]);
705 Vc::where(tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 29);
706 Vc::where(tmpMask) | mDataBuffer[
row][compareIndex2] &= ~(0x1 << 29);
707 Vc::where(!tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 24);
708 Vc::where(!tmpMask) | mDataBuffer[
row][compareIndex2] &= ~(0x1 << 24);
712 tmpMask = getFpOfADC(mDataBuffer[
row][qMaxIndex]) >= getFpOfADC(mDataBuffer[
row][compareIndex3]);
713 Vc::where(tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 28);
714 Vc::where(tmpMask) | mDataBuffer[
row][compareIndex3] &= ~(0x1 << 28);
715 Vc::where(!tmpMask) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 23);
716 Vc::where(!tmpMask) | mDataBuffer[
row][compareIndex3] &= ~(0x1 << 23);
720 Vc::where(getFpOfADC(mDataBuffer[
row][qMaxIndex]) > (mPeakChargeThreshold << 4)) | mDataBuffer[
row][qMaxIndex] |= (0x1 << 27);
724void HwClusterer::writeOutputWithTimeOffset(
int timeOffset)
727 for (
unsigned int region = 0; region < 10; ++region) {
728 if (mTmpClusterArray[region]->
size() == 0) {
734 mClusterArray->emplace_back();
735 auto clusterContainer = mClusterArray->back().getContainer();
738 clusterContainer->CRU = mClusterSector * 10 + region;
739 clusterContainer->numberOfClusters = 0;
740 clusterContainer->timeBinOffset = timeOffset;
742 for (
int c = 0;
c < mTmpClusterArray[region]->size(); ++
c) {
744 if (clusterContainer->numberOfClusters == mClusterArray->back().getMaxNumberOfClusters()) {
745 mClusterArray->emplace_back();
746 clusterContainer = mClusterArray->back().getContainer();
747 clusterContainer->CRU = mClusterSector * 10 + region;
748 clusterContainer->numberOfClusters = 0;
749 clusterContainer->timeBinOffset = timeOffset;
752 clusterContainer->clusters[clusterContainer->numberOfClusters++] = std::move((*mTmpClusterArray[region])[
c]);
753 if (mClusterMcLabelArray) {
754 for (
auto& mcLabel : (*mTmpLabelArray[region])[
c]) {
755 mClusterMcLabelArray->
addElement(mClusterCounter, mcLabel.first);
763 mTmpClusterArray[region]->clear();
764 mTmpLabelArray[region]->clear();
769void HwClusterer::findPeaksForTime(
int timebin)
775 const unsigned timeBinWrapped = mapTimeInRange(timebin);
776 for (
unsigned short row = 0;
row < mNumRowSets; ++
row) {
777 const unsigned padOffset = timeBinWrapped * mPadsPerRowSet[
row];
780 for (
short pad = 1; pad < mPadsPerRowSet[
row] - 1; ++pad) {
781 const unsigned qMaxIndex = padOffset + pad;
782 hwPeakFinder(qMaxIndex, pad, timeBinWrapped,
row);
788void HwClusterer::computeClusterForTime(
int timebin)
794 const unsigned timeBinWrapped = mapTimeInRange(timebin);
795 if (mRejectLaterTimebin) {
796 const unsigned previousTimeBinWrapped = mapTimeInRange(timebin - 2);
797 for (
unsigned short row = 0;
row < mNumRowSets; ++
row) {
798 const unsigned padOffset = timeBinWrapped * mPadsPerRowSet[
row];
799 const unsigned previousPadOffset = previousTimeBinWrapped * mPadsPerRowSet[
row];
801 for (
short pad = 2; pad < mPadsPerRowSet[
row] - 2; ++pad) {
802 const unsigned qMaxIndex = padOffset + pad;
803 const unsigned qMaxPreviousIndex = previousPadOffset + pad;
806 const auto peakMask = ((mDataBuffer[
row][qMaxIndex] >> 27) == 0x1F) &
807 (getFpOfADC(mDataBuffer[
row][qMaxIndex]) > getFpOfADC(mDataBuffer[
row][qMaxPreviousIndex]) |
808 !((mDataBuffer[
row][qMaxPreviousIndex] >> 27) == 0x1F));
809 if (peakMask.isEmpty()) {
813 hwClusterProcessor(peakMask, qMaxIndex, pad, timebin,
row);
817 for (
unsigned short row = 0;
row < mNumRowSets; ++
row) {
818 const unsigned padOffset = timeBinWrapped * mPadsPerRowSet[
row];
820 for (
short pad = 2; pad < mPadsPerRowSet[
row] - 2; ++pad) {
821 const unsigned qMaxIndex = padOffset + pad;
823 const auto peakMask = ((mDataBuffer[
row][qMaxIndex] >> 27) == 0x1F);
824 if (peakMask.isEmpty()) {
828 hwClusterProcessor(peakMask, qMaxIndex, pad, timebin,
row);
835void HwClusterer::finishFrame(
bool clear)
839 for (
int i = mPreviousTimebin;
i - mPreviousTimebin < mTimebinsInBuffer; ++
i) {
840 HB =
i < 3 ? 0 : (
i - 3) / 447;
842 writeOutputWithTimeOffset(mLastHB * 447);
846 computeClusterForTime(
i - 3);
850 writeOutputWithTimeOffset(mLastHB * 447);
853 for (
int i = 0;
i < mTimebinsInBuffer; ++
i) {
860void HwClusterer::clearBuffer(
int timebin)
862 const int wrappedTime = mapTimeInRange(timebin);
863 mMCtruth[wrappedTime].reset();
864 mCurrentMcContainerInBuffer &= ~(0x1 << wrappedTime);
865 for (
unsigned short row = 0;
row < mNumRowSets; ++
row) {
867 std::fill(mDataBuffer[
row].
begin() + wrappedTime * mPadsPerRowSet[
row],
868 mDataBuffer[
row].
begin() + wrappedTime * mPadsPerRowSet[
row] + mPadsPerRowSet[
row], 0);
869 std::fill(mIndexBuffer[
row].
begin() + wrappedTime * mPadsPerRowSet[
row],
870 mIndexBuffer[
row].
begin() + wrappedTime * mPadsPerRowSet[
row] + mPadsPerRowSet[
row], -1);
875void HwClusterer::updateCluster(
876 const Vc::uint_m selectionMask,
int row,
short centerPad,
int centerTime,
short dp,
short dt,
877 Vc::uint_v& qTot, Vc::int_v& pad, Vc::int_v&
time, Vc::int_v& sigmaPad2, Vc::int_v& sigmaTime2,
878 std::vector<std::unique_ptr<std::vector<std::pair<MCCompLabel, unsigned>>>>& mcLabels,
const Vc::uint_m splitMask)
880 if (selectionMask.isEmpty()) {
884 const int mappedTime = mapTimeInRange(centerTime + dt);
885 const int index = mappedTime * mPadsPerRowSet[
row] + centerPad + dp;
888 Vc::where(selectionMask & splitMask) | qTot += (getFpOfADC(mDataBuffer[
row][
index]) >> 1);
889 Vc::where(selectionMask & splitMask) | pad += (getFpOfADC(mDataBuffer[
row][
index]) >> 1) * dp;
890 Vc::where(selectionMask & splitMask) |
time += (getFpOfADC(mDataBuffer[
row][
index]) >> 1) * dt;
891 Vc::where(selectionMask & splitMask) | sigmaPad2 += (getFpOfADC(mDataBuffer[
row][
index]) >> 1) * dp * dp;
892 Vc::where(selectionMask & splitMask) | sigmaTime2 += (getFpOfADC(mDataBuffer[
row][
index]) >> 1) * dt * dt;
895 Vc::where(selectionMask & (!splitMask)) | qTot += getFpOfADC(mDataBuffer[
row][
index]);
896 Vc::where(selectionMask & (!splitMask)) | pad += getFpOfADC(mDataBuffer[
row][
index]) * dp;
897 Vc::where(selectionMask & (!splitMask)) |
time += getFpOfADC(mDataBuffer[
row][
index]) * dt;
898 Vc::where(selectionMask & (!splitMask)) | sigmaPad2 += getFpOfADC(mDataBuffer[
row][
index]) * dp * dp;
899 Vc::where(selectionMask & (!splitMask)) | sigmaTime2 += getFpOfADC(mDataBuffer[
row][
index]) * dt * dt;
901 for (
int i = 0;
i < Vc::uint_v::Size; ++
i) {
902 if (selectionMask[
i] && mMCtruth[mappedTime] !=
nullptr) {
904 bool isKnown =
false;
905 for (
auto& vecLabel : *mcLabels[
i]) {
906 if (
label == vecLabel.first) {
912 mcLabels[
i]->emplace_back(
label, 1);
Class of a TPC cluster as produced by the hardware cluster finder (needs a postprocessing step to con...
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to process
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions false
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc true
configStandalone Reconstruction rec_tpc float
Implementation of the parameter class for the hardware clusterer.
Class for TPC HW cluster finding.
static const HwClustererParam & Instance()
const T getValue(const int sec, const int globalPadInSector) const
Base Class for TPC clusterer.
CalDet< float > * mPedestalObject
Pointer to the CalDet object for the pedestal subtraction.
void process(gsl::span< o2::tpc::Digit const > const &digits, ConstMCLabelContainerView const &mcDigitTruth) override
void init()
initialize the clusterer from HwClustererParam
void finishProcess(gsl::span< o2::tpc::Digit const > const &digits, ConstMCLabelContainerView const &mcDigitTruth) override
int getNumberOfRows() const
int getNumberOfPadsInRowSector(int row) const
static Mapper & instance(const std::string mappingDir="")
int getNumberOfRowsRegion(int region) const
GLboolean GLboolean GLboolean b
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
std::unique_ptr< const o2::dataformats::MCTruthContainer< MCLabel > > getLabels(framework::ProcessingContext &pc, std::string_view dataBind, EventType eventType=EventType::Standard)
Global TPC definitions and constants.
Enum< T >::Iterator begin(Enum< T >)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits