Belle II Software development
ClusterCache Class Reference

Class to remember recently assigned clusters This class will remember the current and the last pixel row to allow fast finding of the correct cluster a pixel belongs to. More...

#include <ClusterCache.h>

Public Types

enum  { c_defaultNumberColumns = 250 }
 
typedef std::deque< ClusterCandidate >::iterator iterator
 Define iterator type.
 
typedef std::deque< ClusterCandidate >::const_iterator const_iterator
 Define const iterator type.
 

Public Member Functions

 ClusterCache (unsigned int maxU=c_defaultNumberColumns)
 Create a new cache.
 
 ClusterCache (const ClusterCache &)=delete
 No copy construction.
 
ClusterCacheoperator= (const ClusterCache &)=delete
 No operator=.
 
 ~ClusterCache ()
 Delete the cache and free the memory.
 
void clear ()
 Clear the cache structure.
 
ClusterCandidatefindCluster (unsigned int u, unsigned int v)
 Find a cluster adjacent to the given coordinates.
 
std::deque< ClusterCandidate >::iterator begin ()
 Return iterator to the begin of of created clusters.
 
std::deque< ClusterCandidate >::iterator end ()
 Return iterator to the end of created clusters.
 
bool empty () const
 Check if there are any clusters.
 

Private Member Functions

ClusterCandidatemergeCluster (ClusterCandidate *cls1, ClusterCandidate *cls2)
 Merge two cluster and update the list of cached clusters.
 
void switchRow (unsigned int v)
 Switch the internal rows.
 

Private Attributes

const unsigned int m_maxU
 number of columns of the cache.
 
unsigned int m_curV
 current v coordinate, needed to switch top row
 
ClusterCandidate ** m_clsTop
 cache of the top row
 
ClusterCandidate ** m_clsCur
 cache of the current row
 
std::deque< ClusterCandidatem_clusters
 list of all the clusters created so far
 
std::deque< ClusterCandidate >::iterator m_currCluster
 iterator to the next free cluster to be used if a new cluster is needed.
 

Detailed Description

Class to remember recently assigned clusters This class will remember the current and the last pixel row to allow fast finding of the correct cluster a pixel belongs to.

All hit pixels above noise threshold will be processed sorted, row wise with increasing u (column) and v (row) ids. For each pixel we look at the left neighbor in the same row and the three direct neighbors in the last row. If at least one cluster is found in any of these pixels, all those clusters will be merged and the pixel gets assigned to the existing cluster. Otherwise a new cluster is created. At the end, all clusters will be checked if they satisfy the requirements for a valid cluster (seed and cluster charge) and only valid clusters are kept

Lets assume that we have a hit in the pixel marked with X. If we process the pixels in a sorted way, than we only have to check the pixels marked O to see if this pixel belongs to a cluster. To do this, we cache the top row and the current row. For each pixel, we just have to check the left cluster and three elements of the top row. If we already found a valid left cluster we only have to check the top right position in addition as we are sure that top left and top are already pointing to the same cluster as the left position due to the sorted processing. If we find more than one adjoining cluster (like the clusters 1 and 2 when looking at 3), all those clusters will be merged. After this step the pixels belonging to 2 and 3 will all belong to cluster 1.

We save the row we are currently looking at. Once the v coordinate of the next hit changes we either switch the current row to top row or erase it if the v coordinate changed by more than one (complete row without an hit).

With this algorithm we only have to look at each pixel once and otherwise just update the list of clusters. To further improve performance the number of free/malloc calls is kept to a minimum: The list of clusters is kept in a std::deque (to keep pointer valid at all times) and not cleared between events but reused. Each new cluster keeps the pixel information in a std::vector is constructed with a capacity of 10 pixels so that relocation should only occur in rare cases and the current and top row pointers are kept and reused over the lifetime of the Cache.

*   u → → → → → → → → → →
* v┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
* ↓│ │ │O│O│O│ │ │ │ │ │ │
*  ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
* ↓│ │ │O│X│ │ │ │ │ │ │ │
*  ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
* ↓│ │ │ │ │ │ │ │ │ │ │ │
*  ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
* ↓│ │ │1│ │2│2│ │ │ │ │ │
*  ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
* ↓│ │ │ │3│ │ │ │ │ │ │ │
*  ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
* ↓│ │ │ │ │ │ │ │ │ │ │ │
*  └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
* 

Definition at line 77 of file ClusterCache.h.

Member Typedef Documentation

◆ const_iterator

typedef std::deque<ClusterCandidate>::const_iterator const_iterator

Define const iterator type.

Definition at line 82 of file ClusterCache.h.

◆ iterator

typedef std::deque<ClusterCandidate>::iterator iterator

Define iterator type.

Definition at line 80 of file ClusterCache.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
c_defaultNumberColumns 

Default maximum number of PIXEL columns the cache can handle.

Definition at line 84 of file ClusterCache.h.

84 {
87 };
@ c_defaultNumberColumns
Default maximum number of PIXEL columns the cache can handle.
Definition: ClusterCache.h:86

Constructor & Destructor Documentation

◆ ClusterCache()

ClusterCache ( unsigned int  maxU = c_defaultNumberColumns)
explicit

Create a new cache.

Definition at line 19 of file ClusterCache.cc.

19 : m_maxU(maxU + 2)
20 {
21 m_clsTop = new ClusterCandidate*[m_maxU];
22 m_clsCur = new ClusterCandidate*[m_maxU];
23 clear();
24 }
const unsigned int m_maxU
number of columns of the cache.
Definition: ClusterCache.h:141
ClusterCandidate ** m_clsCur
cache of the current row
Definition: ClusterCache.h:147
ClusterCandidate ** m_clsTop
cache of the top row
Definition: ClusterCache.h:145
void clear()
Clear the cache structure.
Definition: ClusterCache.cc:33

◆ ~ClusterCache()

Delete the cache and free the memory.

Definition at line 26 of file ClusterCache.cc.

27 {
28 delete[] m_clsTop;
29 delete[] m_clsCur;
30 }

Member Function Documentation

◆ begin()

std::deque< ClusterCandidate >::iterator begin ( )
inline

Return iterator to the begin of of created clusters.

This list also contains clusters which were already merged with other clusters so one has to check that the cluster size is >0 To loop over all cluster candidates use something like

for(ClusterCandidate &cls: cache){
//...
}
Class representing a possible cluster during clustering of the PXD It supports merging of different c...

Definition at line 121 of file ClusterCache.h.

121{ return m_clusters.begin(); }
std::deque< ClusterCandidate > m_clusters
list of all the clusters created so far
Definition: ClusterCache.h:149

◆ clear()

void clear ( )

Clear the cache structure.

clear the Cache

Definition at line 33 of file ClusterCache.cc.

34 {
35 memset(m_clsTop, 0, m_maxU * sizeof(ClusterCandidate*));
36 memset(m_clsCur, 0, m_maxU * sizeof(ClusterCandidate*));
37 m_curV = 0;
38 m_currCluster = m_clusters.begin();
39 }
std::deque< ClusterCandidate >::iterator m_currCluster
iterator to the next free cluster to be used if a new cluster is needed.
Definition: ClusterCache.h:157
unsigned int m_curV
current v coordinate, needed to switch top row
Definition: ClusterCache.h:143

◆ empty()

bool empty ( ) const
inline

Check if there are any clusters.

Definition at line 126 of file ClusterCache.h.

126{ return m_clusters.begin() == m_currCluster; }

◆ end()

std::deque< ClusterCandidate >::iterator end ( )
inline

Return iterator to the end of created clusters.

Definition at line 123 of file ClusterCache.h.

123{ return m_currCluster; }

◆ findCluster()

ClusterCandidate & findCluster ( unsigned int  u,
unsigned int  v 
)

Find a cluster adjacent to the given coordinates.

If no adjacent cluster is found, a new cluster is returned.

Parameters
ucolumn id to look for a adjacent clusters
vrow id to look for adjacent clusters
Returns
cluster reference, either existing, adjacent cluster or empty cluster

If no cluster is found, 0 is returned

Definition at line 42 of file ClusterCache.cc.

43 {
44 if (u >= m_maxU - 2) {
45 throw std::out_of_range("u cell id is outside of valid range");
46 }
47 switchRow(v);
48 const unsigned int u1 = u + 1;
49 //Look for cluster top of current pixel (0,0 at top left corner, rows going
50 //down, columns going left) The ClusterCache is two columns wider than the
51 //actual pixel sensor to get rid of edge effects. Column 0 is at index 1 so
52 //the three neighbors of column u have the indices (u,u+1,u+2)
53
54 //So the left neighbor has index u in the current row
55 ClusterCandidate* cls = m_clsCur[u];
56 //And the topleft, top and topright clusters have u+i, i in 0..2 But if we
57 //already have a left neighbor we do not need to check topleft and top as
58 //those are guaranteed to be already merged with the left one
59 if (!cls) {
60 cls = mergeCluster(cls, m_clsTop[u]);
61 cls = mergeCluster(cls, m_clsTop[u1]);
62 }
63 cls = mergeCluster(cls, m_clsTop[u + 2]);
64
65 //If no cluster was found create a new one
66 if (!cls) {
67 if (m_currCluster == m_clusters.end()) {
68 //We already use all ClusterCandidates, create a new one
69 m_clusters.emplace_front();
70 cls = &m_clusters.front();
71 } else {
72 //There are some Candidates left, use them
73 cls = &(*m_currCluster++);
74 cls->clear();
75 }
76 }
77 //Save the cluster and the current position in the cache
78 m_curV = v;
79 m_clsCur[u1] = cls;
80 //Return the cluster
81 return *cls;
82 }
ClusterCandidate * mergeCluster(ClusterCandidate *cls1, ClusterCandidate *cls2)
Merge two cluster and update the list of cached clusters.
Definition: ClusterCache.cc:85
void switchRow(unsigned int v)
Switch the internal rows.
Definition: ClusterCache.cc:95

◆ mergeCluster()

ClusterCandidate * mergeCluster ( ClusterCandidate cls1,
ClusterCandidate cls2 
)
private

Merge two cluster and update the list of cached clusters.

Definition at line 85 of file ClusterCache.cc.

86 {
87 if (cls2) {
88 if (!cls1 || cls1 == cls2) return cls2;
89 return cls1->merge(*cls2);
90 }
91 return cls1;
92 }

◆ switchRow()

void switchRow ( unsigned int  v)
private

Switch the internal rows.

Switch current and top row or clear cache.

We always keep current and last row. This method switches these rows and resets the new current row

Parameters
vcurrent row id

Definition at line 95 of file ClusterCache.cc.

96 {
97 if (v == m_curV) return;
98 //Clear top row
99 std::memset(m_clsTop, 0, m_maxU * sizeof(ClusterCandidate*));
100 //We skipped a row, forget current row, no need to switch rows, both got emptied
101 if (v > m_curV + 1) {
102 std::memset(m_clsCur, 0, m_maxU * sizeof(ClusterCandidate*));
103 } else {
104 //Switch rows, Current row will be top and we reuse memory of last top
105 //row as new current row
106 std::swap(m_clsTop, m_clsCur);
107 }
108 //save current row coordinate
109 m_curV = v;
110 }

Member Data Documentation

◆ m_clsCur

ClusterCandidate** m_clsCur
private

cache of the current row

Definition at line 147 of file ClusterCache.h.

◆ m_clsTop

ClusterCandidate** m_clsTop
private

cache of the top row

Definition at line 145 of file ClusterCache.h.

◆ m_clusters

std::deque<ClusterCandidate> m_clusters
private

list of all the clusters created so far

Definition at line 149 of file ClusterCache.h.

◆ m_currCluster

std::deque<ClusterCandidate>::iterator m_currCluster
private

iterator to the next free cluster to be used if a new cluster is needed.

The List of clusters is kept between clustering calls to save malloc/free calls. On clear, this iterator will point to the beginning of m_clusters and will be incremented every time a cluster is needed. Once it reaches m_clusters.end(), new clusters will be added to the front of the m_clusters container.

Definition at line 157 of file ClusterCache.h.

◆ m_curV

unsigned int m_curV
private

current v coordinate, needed to switch top row

Definition at line 143 of file ClusterCache.h.

◆ m_maxU

const unsigned int m_maxU
private

number of columns of the cache.

This is the actual number of columns + 2 to get rid of edge effects

Definition at line 141 of file ClusterCache.h.


The documentation for this class was generated from the following files: