34#ifdef _PERFORM_TIMING_
53 mFiredChipsPtr.clear();
56 mFiredChipsPtr.push_back(curChipData);
57 nPix += curChipData->
getData().size();
60 auto& rof = vecROFRec->emplace_back(reader.
getInteractionRecord(), vecROFRec->size(), compClus->size(), 0);
62 uint16_t nFired = mFiredChipsPtr.size();
69 if (nFired < nThreads) {
75 uint16_t chipStep = nThreads > 1 ? (nThreads == 2 ? 20 : 10) : nFired;
76 int dynGrp = std::min(4, std::max(1, nThreads / 2));
77 if (nThreads > mThreads.size()) {
78 int oldSz = mThreads.size();
79 mThreads.resize(nThreads);
80 for (
size_t i = oldSz;
i < nThreads;
i++) {
81 mThreads[
i] = std::make_unique<ClustererThread>(
this,
i);
85#pragma omp parallel for schedule(dynamic, dynGrp) num_threads(nThreads)
87 for (uint16_t ic = 0; ic < nFired; ic += chipStep) {
88 auto ith = omp_get_thread_num();
90 mThreads[ith]->process(ic, std::min(chipStep, uint16_t(nFired - ic)),
91 &mThreads[ith]->compClusters,
92 patterns ? &mThreads[ith]->patterns :
nullptr,
94 labelsCl ? &mThreads[ith]->labels :
nullptr, rof);
96 mThreads[0]->process(0, nFired, compClus, patterns, labelsCl ? reader.
getDigitsMCTruth() :
nullptr, labelsCl, rof);
101 mThreads[0]->process(0, nFired, compClus, patterns, labelsCl ? reader.
getDigitsMCTruth() :
nullptr, labelsCl, rof);
105#ifdef _PERFORM_TIMING_
106 mTimerMerge.Start(
false);
108 size_t nClTot = 0, nPattTot = 0;
110 std::vector<size_t> thrStatIdx(nThreads, 0);
111 for (
int ith = 0; ith < nThreads; ith++) {
112 std::sort(mThreads[ith]->stats.begin(), mThreads[ith]->stats.end(), [](
const ThreadStat&
a,
const ThreadStat&
b) { return a.firstChip < b.firstChip; });
113 nClTot += mThreads[ith]->compClusters.size();
114 nPattTot += mThreads[ith]->patterns.size();
116 compClus->reserve(nClTot);
118 patterns->reserve(nPattTot);
120 while (
chid < nFired) {
121 for (
int ith = 0; ith < nThreads; ith++) {
122 if (thrStatIdx[ith] >= mThreads[ith]->stats.size()) {
125 const auto& stat = mThreads[ith]->stats[thrStatIdx[ith]];
126 if (stat.firstChip ==
chid) {
129 const auto clbeg = mThreads[ith]->compClusters.begin() + stat.firstClus;
130 compClus->insert(compClus->end(), clbeg, clbeg + stat.nClus);
132 const auto ptbeg = mThreads[ith]->patterns.begin() + stat.firstPatt;
133 patterns->insert(patterns->end(), ptbeg, ptbeg + stat.nPatt);
136 labelsCl->
mergeAtBack(mThreads[ith]->labels, stat.firstClus, stat.nClus);
141 for (
int ith = 0; ith < nThreads; ith++) {
142 mThreads[ith]->patterns.clear();
143 mThreads[ith]->compClusters.clear();
144 mThreads[ith]->labels.clear();
145 mThreads[ith]->stats.clear();
147#ifdef _PERFORM_TIMING_
151 mThreads[0]->stats.clear();
153 rof.setNEntries(compClus->size() - rof.getFirstEntry());
154 }
while (autoDecode);
156#ifdef _PERFORM_TIMING_
165 if (
stats.empty() ||
stats.back().firstChip +
stats.back().nChips != chip) {
166 stats.emplace_back(
ThreadStat{chip, 0, uint32_t(compClusPtr->size()), patternsPtr ? uint32_t(patternsPtr->size()) : 0, 0, 0});
168 for (
int ic = 0; ic < nChips; ic++) {
169 auto* curChipData =
parent->mFiredChipsPtr[chip + ic];
170 auto chipID = curChipData->getChipID();
171 if (
parent->mMaxBCSeparationToMask > 0) {
172 const auto& chipInPrevROF =
parent->mChipsOld[chipID];
174 parent->mMaxRowColDiffToMask != 0 ? curChipData->maskFiredInSample(
parent->mChipsOld[chipID],
parent->mMaxRowColDiffToMask) : curChipData->maskFiredInSample(
parent->mChipsOld[chipID]);
177 auto validPixID = curChipData->getFirstUnmasked();
178 auto npix = curChipData->getData().size();
179 if (validPixID < npix) {
180 auto valp = validPixID++;
181 if (validPixID == npix) {
185 for (; validPixID < npix; validPixID++) {
186 if (!curChipData->getData()[validPixID].isMasked()) {
190 finishChip(curChipData, compClusPtr, patternsPtr, labelsDigPtr, labelsClPtr);
193 if (
parent->mMaxBCSeparationToMask > 0) {
194 parent->mChipsOld[chipID].swap(*curChipData);
197 auto& currStat =
stats.back();
198 currStat.nChips += nChips;
199 currStat.nClus = compClusPtr->size() - currStat.firstClus;
200 currStat.nPatt = patternsPtr ? (patternsPtr->size() - currStat.firstPatt) : 0;
207 const auto& pixData = curChipData->
getData();
208 for (
size_t i1 = 0; i1 < preClusterHeads.size(); ++i1) {
209 auto ci = preClusterIndices[i1];
215 int next = preClusterHeads[i1];
218 const auto& pixEntry =
pixels[next];
219 const auto pix = pixData[pixEntry.second];
220 pixArrBuff.push_back(pix);
221 bbox.adjust(pix.getRowDirect(), pix.getCol());
223 if (parent->mSquashingDepth) {
224 fetchMCLabels(curChipData->
getOrderedPixId(pixEntry.second), labelsDigPtr, nlab);
226 fetchMCLabels(pixEntry.second + curChipData->
getStartID(), labelsDigPtr, nlab);
229 next = pixEntry.first;
231 preClusterIndices[i1] = -1;
232 for (
size_t i2 = i1 + 1; i2 < preClusterHeads.size(); ++i2) {
233 if (preClusterIndices[i2] != ci) {
236 next = preClusterHeads[i2];
238 const auto& pixEntry =
pixels[next];
239 const auto pix = pixData[pixEntry.second];
240 pixArrBuff.push_back(pix);
241 bbox.adjust(pix.getRowDirect(), pix.getCol());
242 if (labelsClusPtr !=
nullptr) {
243 if (parent->mSquashingDepth) {
244 fetchMCLabels(curChipData->
getOrderedPixId(pixEntry.second), labelsDigPtr, nlab);
246 fetchMCLabels(pixEntry.second + curChipData->
getStartID(), labelsDigPtr, nlab);
249 next = pixEntry.first;
251 preClusterIndices[i2] = -1;
253 if (
bbox.isAcceptableSize()) {
258 LOGP(warn,
"Splitting a huge cluster: chipID {}, rows {}:{} cols {}:{}{}",
bbox.chipID,
bbox.rowMin,
bbox.rowMax,
bbox.colMin,
bbox.colMax,
259 warnLeft == 1 ?
" (Further warnings will be muted)" :
"");
264 parent->mNHugeClus++;
268 std::vector<PixelData> pixbuf;
274 for (
const auto& pix : pixArrBuff) {
275 if (bboxT.
isInside(pix.getRowDirect(), pix.getCol())) {
276 pixbuf.push_back(pix);
279 if (!pixbuf.empty()) {
280 parent->streamCluster(pixbuf, &labelsBuff, bboxT, parent->mPattIdConverter, compClusPtr, patternsPtr, labelsClusPtr, nlab,
constants::detID::isDetITS3(curChipData->
getChipID()),
true);
295 auto pix = curChipData->
getData()[hit];
296 uint16_t
row = pix.getRowDirect(),
col = pix.getCol();
300 fetchMCLabels(curChipData->
getStartID() + hit, labelsDigPtr, nlab);
301 auto cnt = compClusPtr->size();
302 for (
int i = nlab;
i--;) {
311 uint16_t pattID = (parent->mPattIdConverter.size(ib) == 0) ?
CompCluster::InvalidPatternID : parent->mPattIdConverter.findGroupID(1, 1, ib, patt);
313 patternsPtr->emplace_back(1);
314 patternsPtr->emplace_back(1);
315 patternsPtr->insert(patternsPtr->end(), std::begin(patt), std::begin(patt) + 1);