@@ -133,15 +133,17 @@ void Clusterer::process(int nThreads, PixelReader& reader, CompClusCont* compClu
133133 if (stat.firstChip == chid) {
134134 thrStatIdx[ith]++;
135135 chid += stat.nChips; // next chip to look
136- const auto clbeg = mThreads[ith]->compClusters.begin() + stat.firstClus;
137- auto szold = compClus->size();
138- compClus->insert(compClus->end(), clbeg, clbeg + stat.nClus);
139- if (patterns) {
140- const auto ptbeg = mThreads[ith]->patterns.begin() + stat.firstPatt;
141- patterns->insert(patterns->end(), ptbeg, ptbeg + stat.nPatt);
142- }
143- if (labelsCl) {
144- labelsCl->mergeAtBack(mThreads[ith]->labels, stat.firstClus, stat.nClus);
136+ if (stat.nClus > 0) {
137+ const auto clbeg = mThreads[ith]->compClusters.begin() + stat.firstClus;
138+ auto szold = compClus->size();
139+ compClus->insert(compClus->end(), clbeg, clbeg + stat.nClus);
140+ if (patterns) {
141+ const auto ptbeg = mThreads[ith]->patterns.begin() + stat.firstPatt;
142+ patterns->insert(patterns->end(), ptbeg, ptbeg + stat.nPatt);
143+ }
144+ if (labelsCl) {
145+ labelsCl->mergeAtBack(mThreads[ith]->labels, stat.firstClus, stat.nClus);
146+ }
145147 }
146148 }
147149 }
@@ -214,14 +216,22 @@ void Clusterer::ClustererThread::finishChip(ChipPixelData* curChipData, CompClus
214216 PatternCont* patternsPtr, const ConstMCTruth* labelsDigPtr, MCTruth* labelsClusPtr)
215217{
216218 const auto& pixData = curChipData->getData();
217- for (int i1 = 0; i1 < preClusterHeads.size(); ++i1) {
218- auto ci = preClusterIndices[i1];
219+ int nPreclusters = preClusters.size();
220+ // account for the eventual reindexing of preClusters: Id2 might have been reindexed to Id1, which later was reindexed to Id0
221+ for (int i = 1; i < nPreclusters; i++) {
222+ if (preClusters[i].index != i) { // reindexing is always done towards smallest index
223+ preClusters[i].index = preClusters[preClusters[i].index].index;
224+ }
225+ }
226+ for (int i1 = 0; i1 < nPreclusters; ++i1) {
227+ auto& preCluster = preClusters[i1];
228+ auto ci = preCluster.index;
219229 if (ci < 0) {
220230 continue;
221231 }
222232 BBox bbox(curChipData->getChipID());
223233 int nlab = 0;
224- int next = preClusterHeads[i1] ;
234+ int next = preCluster.head ;
225235 pixArrBuff.clear();
226236 while (next >= 0) {
227237 const auto& pixEntry = pixels[next];
@@ -237,12 +247,13 @@ void Clusterer::ClustererThread::finishChip(ChipPixelData* curChipData, CompClus
237247 }
238248 next = pixEntry.first;
239249 }
240- preClusterIndices[i1] = -1;
241- for (int i2 = i1 + 1; i2 < preClusterHeads.size(); ++i2) {
242- if (preClusterIndices[i2] != ci) {
250+ preCluster.index = -1;
251+ for (int i2 = i1 + 1; i2 < nPreclusters; ++i2) {
252+ auto& preCluster2 = preClusters[i2];
253+ if (preCluster2.index != ci) {
243254 continue;
244255 }
245- next = preClusterHeads[i2] ;
256+ next = preCluster2.head ;
246257 while (next >= 0) {
247258 const auto& pixEntry = pixels[next];
248259 const auto pix = pixData[pixEntry.second]; // PixelData
@@ -257,7 +268,7 @@ void Clusterer::ClustererThread::finishChip(ChipPixelData* curChipData, CompClus
257268 }
258269 next = pixEntry.first;
259270 }
260- preClusterIndices[i2] = -1;
271+ preCluster2.index = -1;
261272 }
262273 if (bbox.isAcceptableSize()) {
263274 parent->streamCluster(pixArrBuff, &labelsBuff, bbox, parent->mPattIdConverter, compClusPtr, patternsPtr, labelsClusPtr, nlab);
@@ -344,18 +355,15 @@ void Clusterer::ClustererThread::initChip(const ChipPixelData* curChipData, uint
344355 prev = column1 + 1;
345356 curr = column2 + 1;
346357 resetColumn(curr);
347-
348358 pixels.clear();
349- preClusterHeads.clear();
350- preClusterIndices.clear();
359+ preClusters.clear();
351360 auto pix = curChipData->getData()[first];
352361 currCol = pix.getCol();
353362 curr[pix.getRowDirect()] = 0; // can use getRowDirect since the pixel is not masked
354363 // start the first pre-cluster
355- preClusterHeads.push_back(0);
356- preClusterIndices.push_back(0);
364+ preClusters.emplace_back();
357365 pixels.emplace_back(-1, first); // id of current pixel
358- noLeftCol = true; // flag that there is no column on the left to check yet
366+ noLeftCol = true;
359367}
360368
361369//__________________________________________________
@@ -378,39 +386,58 @@ void Clusterer::ClustererThread::updateChip(const ChipPixelData* curChipData, ui
378386 currCol = pix.getCol();
379387 }
380388
381- Bool_t orphan = true;
382-
383389 if (noLeftCol) { // check only the row above
384390 if (curr[row - 1] >= 0) {
385391 expandPreCluster(ip, row, curr[row - 1]); // attach to the precluster of the previous row
386- return;
392+ } else {
393+ addNewPrecluster(ip, row); // start new precluster
387394 }
388395 } else {
396+ // row above should be always checked
397+ int nnb = 0, lowestIndex = curr[row - 1], lowestNb = 0, *nbrCol[4], nbrRow[4];
398+ if (lowestIndex >= 0) {
399+ nbrCol[nnb] = curr;
400+ nbrRow[nnb++] = row - 1;
401+ } else {
402+ lowestIndex = 0x7ffff;
403+ lowestNb = -1;
404+ }
389405#ifdef _ALLOW_DIAGONAL_ALPIDE_CLUSTERS_
390- int neighbours[]{curr[row - 1], prev[row], prev[row + 1], prev[row - 1]};
391- #else
392- int neighbours[]{curr[row - 1], prev[row]};
393- #endif
394- for (auto pci : neighbours) {
395- if (pci < 0) {
396- continue;
406+ for (int i : {-1, 0, 1}) {
407+ auto v = prev[row + i];
408+ if (v >= 0) {
409+ nbrCol[nnb] = prev;
410+ nbrRow[nnb] = row + i;
411+ if (v < lowestIndex) {
412+ lowestIndex = v;
413+ lowestNb = nnb;
414+ }
415+ nnb++;
397416 }
398- if (orphan) {
399- expandPreCluster(ip, row, pci); // attach to the adjascent precluster
400- orphan = false;
401- continue;
417+ }
418+ #else
419+ if (prev[row] >= 0) {
420+ nbrCol[nnb] = prev;
421+ nbrRow[nnb] = row;
422+ if (prev[row] < lowestIndex) {
423+ lowestIndex = v;
424+ lowestNb = nnb;
402425 }
403- // reassign precluster index to smallest one
404- if (preClusterIndices[pci] < preClusterIndices[curr[row]]) {
405- preClusterIndices[curr[row]] = preClusterIndices[pci];
406- } else {
407- preClusterIndices[pci] = preClusterIndices[curr[row]];
426+ nnb++;
427+ }
428+ #endif
429+ if (!nnb) { // no neighbours, create new precluster
430+ addNewPrecluster(ip, row); // start new precluster
431+ } else {
432+ expandPreCluster(ip, row, lowestIndex); // attach to the adjascent precluster with smallest index
433+ if (nnb > 1) {
434+ for (int inb = 0; inb < nnb; inb++) { // reassign precluster index to smallest one, replicating updated values to columns caches
435+ auto& prevIndex = (nbrCol[inb])[nbrRow[inb]];
436+ prevIndex = preClusters[prevIndex].index = lowestIndex;
437+ }
408438 }
409439 }
410440 }
411- if (orphan) {
412- addNewPrecluster(ip, row); // start new precluster
413- }
414441}
415442
416443//__________________________________________________
0 commit comments