@@ -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