Belle II Software development
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 iteratively
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
115 ConstVectorRange<WeightedRelation<ACellHolder> > neighborRelations(
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.
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 iteratively 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.
void setCellWeight(ACellHolder *cellHolder, Weight cellWeight) const
Setter for the cell weight of a pointed object that holds an AutomatonCell.
Weight getCellState(ACellHolder *cellHolder) const
Getter for the cell state of a pointed object that holds an AutomatonCell.
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
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.