Belle II Software release-09-00-11
Clusterizer.h
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#pragma once
9
10#include <tracking/trackFindingCDC/ca/AutomatonCell.h>
11
12#include <tracking/trackFindingCDC/utilities/VectorRange.h>
13#include <tracking/trackFindingCDC/utilities/WeightedRelation.h>
14
15#include <tracking/trackFindingCDC/findlets/base/Findlet.h>
16
17#include <framework/logging/Logger.h>
18
19namespace Belle2 {
24 namespace TrackFindingCDC {
25
39 template <class ACellHolder, class ACluster = std::vector<ACellHolder*> >
41 : public Findlet<ACellHolder* const, WeightedRelation<ACellHolder> const, ACluster> {
42
43 public:
54 void apply(std::vector<ACellHolder*> const& cellHolders,
55 std::vector<WeightedRelation<ACellHolder> > const& cellHolderRelations,
56 std::vector<ACluster>& clusters) override
57 {
58 // Expect the relations to be sorted for lookup
59 assert(std::is_sorted(cellHolderRelations.begin(),
60 cellHolderRelations.end()));
61
62 // Prepare some output clusters
63 clusters.reserve(30);
64
65 // Prepare states
66 for (ACellHolder* cellHolder : cellHolders) {
67 setCellState(cellHolder, -1);
68 }
69
70 // Work horse cluster
71 std::vector<ACellHolder*> cluster;
72
73 // Go through each cell holder and start a cluster on each that is unassigned yet
74 int iCluster = -1;
75 for (ACellHolder* cellHolder : cellHolders) {
76 if (getCellState(cellHolder) != -1) continue;
77
78 cluster.clear();
79
80 ++iCluster;
81 setCellState(cellHolder, iCluster);
82 cluster.push_back(cellHolder);
83
84 expandCluster(cellHolderRelations, cluster);
85
86 clusters.emplace_back(std::move(cluster));
87 cluster.clear();
88 }
89 }
90
91 private:
93 void expandCluster(std::vector<WeightedRelation<ACellHolder>> const& cellHolderRelations,
94 std::vector<ACellHolder*>& cluster) const
95 {
96 ACellHolder* seedCellHolder = cluster.front();
97 int iCluster = getCellState(seedCellHolder);
98
99 // Grow the cluster iterativelly
100 std::vector<ACellHolder*> checkNow;
101 std::vector<ACellHolder*> checkNext;
102
103 checkNow.reserve(10);
104 checkNext.reserve(10);
105
106 checkNext.push_back(seedCellHolder);
107
108 while (not checkNext.empty()) {
109
110 checkNow.swap(checkNext);
111 checkNext.clear();
112
113 for (ACellHolder* cellHolder : checkNow) {
114
116 std::equal_range(cellHolderRelations.begin(),
117 cellHolderRelations.end(),
118 cellHolder));
119
120 // Setting the cell weight to the number of neighbors
121 size_t nNeighbors = neighborRelations.size();
122 setCellWeight(cellHolder, nNeighbors);
123
124 for (const WeightedRelation<ACellHolder>& neighborRelation : neighborRelations) {
125 ACellHolder* neighborCellHolder = neighborRelation.getTo();
126
127 Weight neighborICluster = getCellState(neighborCellHolder);
128 if (neighborICluster == -1) {
129 // Neighbor not yet in cluster
130 setCellState(neighborCellHolder, iCluster);
131 cluster.push_back(neighborCellHolder);
132
133 // Register neighbor for further expansion
134 checkNext.push_back(neighborCellHolder);
135 continue;
136 }
137
138 if (neighborICluster != iCluster) {
139 B2WARNING("Clusterizer: Neighboring item was already assigned to different "
140 "cluster. Check if the neighborhood is symmetric.");
141 continue;
142 }
143 }
144 }
145 }
146 }
147
149 void setCellState(ACellHolder* cellHolder, Weight cellState) const
150 {
151 AutomatonCell& automatonCell = cellHolder->getAutomatonCell();
152 automatonCell.setCellState(cellState);
153 }
154
156 Weight getCellState(ACellHolder* cellHolder) const
157 {
158 const AutomatonCell& automatonCell = cellHolder->getAutomatonCell();
159 return automatonCell.getCellState();
160 }
161
163 void setCellWeight(ACellHolder* cellHolder, Weight cellWeight) const
164 {
165 AutomatonCell& automatonCell = cellHolder->getAutomatonCell();
166 automatonCell.setCellWeight(cellWeight);
167 }
168
169 };
170 }
172}
Cell used by the cellular automata.
Definition: AutomatonCell.h:29
Weight getCellState() const
Getter for the cell state.
void setCellState(Weight state)
Setter for the cell state.
void setCellWeight(Weight weight)
Setter for the cell weight.
Implementation of the clustering Clusters elements of a given collection using the relations presente...
Definition: Clusterizer.h:41
void expandCluster(std::vector< WeightedRelation< ACellHolder > > const &cellHolderRelations, std::vector< ACellHolder * > &cluster) const
Helper function. Starting a new cluster and iterativelly expands it.
Definition: Clusterizer.h:93
void setCellState(ACellHolder *cellHolder, Weight cellState) const
Setter for the cell state of a pointed object that holds an AutomatonCell.
Definition: Clusterizer.h:149
void setCellWeight(ACellHolder *cellHolder, Weight cellWeight) const
Setter for the cell weight of a pointed object that holds an AutomatonCell.
Definition: Clusterizer.h:163
Weight getCellState(ACellHolder *cellHolder) const
Getter for the cell state of a pointed object that holds an AutomatonCell.
Definition: Clusterizer.h:156
void apply(std::vector< ACellHolder * > const &cellHolders, std::vector< WeightedRelation< ACellHolder > > const &cellHolderRelations, std::vector< ACluster > &clusters) override
Creates the clusters.
Definition: Clusterizer.h:54
Interface for a minimal algorithm part that wants to expose some parameters to a module.
Definition: Findlet.h:26
A pair of iterators usable with the range base for loop.
Definition: Range.h:25
std::size_t size() const
Returns the total number of objects in this range.
Definition: Range.h:76
Type for two related objects with a weight.
Abstract base class for different kinds of events.