Belle II Software  release-08-01-10
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 
19 namespace 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.
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 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
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
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.