Belle II Software development
ClusterCache.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <pxd/reconstruction/ClusterCache.h>
10
11namespace Belle2 {
16
17 namespace PXD {
18
19 ClusterCache::ClusterCache(unsigned int maxU): m_maxU(maxU + 2)
20 {
23 clear();
24 }
25
27 {
28 delete[] m_clsTop;
29 delete[] m_clsCur;
30 }
31
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 }
40
42 ClusterCandidate& ClusterCache::findCluster(unsigned int u, unsigned int v)
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 }
83
86 {
87 if (cls2) {
88 if (!cls1 || cls1 == cls2) return cls2;
89 return cls1->merge(*cls2);
90 }
91 return cls1;
92 }
93
95 void ClusterCache::switchRow(unsigned int v)
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 }
111 }
113} //Belle2 namespace
ClusterCandidate & findCluster(unsigned int u, unsigned int v)
Find a cluster adjacent to the given coordinates.
~ClusterCache()
Delete the cache and free the memory.
const unsigned int m_maxU
number of columns of the cache.
std::deque< ClusterCandidate > m_clusters
list of all the clusters created so far
ClusterCandidate * mergeCluster(ClusterCandidate *cls1, ClusterCandidate *cls2)
Merge two cluster and update the list of cached clusters.
ClusterCandidate ** m_clsCur
cache of the current row
ClusterCandidate ** m_clsTop
cache of the top row
std::deque< ClusterCandidate >::iterator m_currCluster
iterator to the next free cluster to be used if a new cluster is needed.
ClusterCache(unsigned int maxU=c_defaultNumberColumns)
Create a new cache.
void switchRow(unsigned int v)
Switch the internal rows.
void clear()
Clear the cache structure.
unsigned int m_curV
current v coordinate, needed to switch top row
Class representing a possible cluster during clustering of the PXD It supports merging of different c...
ClusterCandidate * merge(ClusterCandidate &cls)
Merge the given cluster with this one.
void clear()
Clear the Cluster information (to reuse the same cluster instance)
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
Abstract base class for different kinds of events.