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
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.
Definition: AutomatonCell.h:96
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.
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.