CMatchManager.cxx
Go to the documentation of this file.
1 #include "CMatchManager.h"
2 
3 #include <algorithm>
4 #include <iostream>
5 #include <set>
6 #include <stdlib.h>
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
11 #include "TStopwatch.h"
18 
19 namespace cmtool {
20 
22  {
23  throw CMTException("Default ctor needs # planes as an argument!");
24  }
25 
27  {
28  _match_algo = nullptr;
29  _nplanes = nplanes;
30  Reset();
31  }
32 
33  void
35  {
40  }
41 
42  void
44  {
45  if (_debug_mode <= kPerMerging) {
48  }
49 
52  }
53 
54  void
56  {
59  }
60 
61  void
63  {
66  }
67 
68  void
70  {
73  }
74 
75  unsigned int
76  CMFactorial(unsigned int n)
77  {
78  return (n == 1 || n == 0) ? 1 : CMFactorial(n - 1) * n;
79  }
80 
81  std::vector<std::vector<size_t>>
82  SimpleCombination(size_t n, size_t r)
83  {
84 
85  if (!n || !r) exit(1);
86  if (r > n) exit(1);
87 
88  std::vector<bool> v(n, false);
89  std::fill(v.begin() + n - r, v.end(), true);
90  std::vector<std::vector<size_t>> res;
91  res.reserve(CMFactorial(n) / CMFactorial(n - r) / CMFactorial(r));
92 
93  do {
94  std::vector<size_t> tmp;
95  tmp.reserve(r);
96 
97  for (size_t i = 0; i < n; ++i) {
98  if (v[i]) tmp.push_back(i);
99  }
100  res.push_back(tmp);
101  } while (std::next_permutation(v.begin(), v.end()));
102 
103  return res;
104  }
105 
106  std::vector<std::vector<size_t>>
107  ClusterCombinations(const std::vector<size_t>& seed)
108  {
109 
110  std::vector<size_t> ctr(seed.size(), 0);
111 
112  std::vector<std::vector<size_t>> res;
113 
114  while (1) {
115 
116  res.push_back(std::vector<size_t>(seed.size(), 0));
117  for (size_t index = 0; index < ctr.size(); ++index)
118 
119  (*res.rbegin())[index] = ctr.at(index);
120 
121  for (size_t i = 0; i < ctr.size(); ++i) {
122 
123  size_t index = (size_t)(ctr.size() - i - 1);
124 
125  ctr.at(index) += 1;
126 
127  if (ctr.at(index) < seed.at(index)) break;
128 
129  ctr.at(index) = 0;
130  }
131 
132  bool abort = true;
133  for (auto const& value : ctr)
134 
135  abort = abort && (!(value));
136 
137  if (abort) break;
138  }
139  return res;
140  }
141 
142  std::vector<std::vector<std::pair<size_t, size_t>>>
143  PlaneClusterCombinations(const std::vector<size_t>& seed)
144  {
145  // Result container
146  std::vector<std::vector<std::pair<size_t, size_t>>> result;
147 
148  // Loop over N-planes: start from max number of planes => down to 2 planes
149  for (size_t i = 0; i < seed.size(); ++i) {
150 
151  // If finish making clusters down to 2 palnes, break
152  if (seed.size() < 2 + i) break;
153 
154  // Compute possible N-plane combinations
155  auto const& plane_comb_v = SimpleCombination(seed.size(), seed.size() - i);
156 
157  // Loop over possible N-plane combinations
158  for (auto const& plane_comb : plane_comb_v) {
159 
160  // Make a seed for cluster combinations
161  std::vector<size_t> cluster_seed_v;
162  cluster_seed_v.reserve(plane_comb.size());
163  for (auto const& index : plane_comb)
164  cluster_seed_v.push_back(seed[index]);
165 
166  // Compute cluster combinations
167  for (auto const& cluster_comb : ClusterCombinations(cluster_seed_v)) {
168 
169  // Store result
170  result.push_back(std::vector<std::pair<size_t, size_t>>());
171  for (size_t i = 0; i < cluster_comb.size(); ++i)
172 
173  (*result.rbegin()).push_back(std::make_pair(plane_comb.at(i), cluster_comb.at(i)));
174  }
175  }
176  }
177  return result;
178  }
179 
180  bool
182  {
183  TStopwatch localWatch;
184 
185  //
186  // Create plane-by-plane vectors
187  //
189 
190  if (_planes.size() < 2) return false;
191 
192  if (_planes.size() > _nplanes)
193  throw CMTException("Found more plane IDs than specified number of planes!");
194 
195  // Index array of clusters per plane
196  std::vector<std::vector<size_t>> cluster_array;
197 
198  // Resize to # of planes w/ clusters
199  cluster_array.reserve(_planes.size());
200 
201  // plane-to-index map
202  std::vector<size_t> plane_to_index(_nplanes, _nplanes);
203 
204  // Fill plane-to-index map
205  for (size_t plane = 0; plane < _nplanes; ++plane) {
206  if (_planes.find(plane) != _planes.end()) {
207  plane_to_index[plane] = cluster_array.size();
208 
209  cluster_array.push_back(std::vector<size_t>());
210  }
211  }
212 
213  // Fill cluster_array
214  for (auto riter = _priority.rbegin(); riter != _priority.rend(); ++riter)
215  cluster_array.at(plane_to_index.at(_in_clusters.at((*riter).second).Plane()))
216  .push_back((*riter).second);
217 
218  // Find combinations
219  std::vector<size_t> seed;
220  seed.reserve(cluster_array.size());
221  for (auto const& clusters_per_plane : cluster_array)
222  seed.push_back(clusters_per_plane.size());
223 
224  auto const& combinations = PlaneClusterCombinations(seed);
225 
226  // Loop over combinations and call algorithm
227  for (auto const& comb : combinations) {
228 
229  std::vector<const cluster::ClusterParamsAlg*> ptr_v;
230 
231  std::vector<unsigned int> tmp_index_v;
232  tmp_index_v.reserve(comb.size());
233 
234  ptr_v.reserve(comb.size());
235 
236  for (auto const& plane_cluster : comb) {
237  auto const& in_cluster_index =
238  cluster_array.at(plane_cluster.first).at(plane_cluster.second);
239 
240  tmp_index_v.push_back(in_cluster_index);
241 
242  ptr_v.push_back(&(_in_clusters.at(in_cluster_index)));
243  }
244 
245  if (_debug_mode <= kPerMerging) {
246  std::cout << " \033[93m"
247  << "Inspecting a pair (";
248  for (auto const& index : tmp_index_v)
249  std::cout << index << " ";
250  std::cout << ") \033[00m" << std::flush;
251 
252  localWatch.Start();
253  }
254 
255  auto const& score = _match_algo->Float(gser, ptr_v);
256 
257  if (_debug_mode <= kPerMerging)
258  std::cout << " ... Time taken = " << localWatch.RealTime() << " [s]" << std::endl;
259 
260  if (score > 0) _book_keeper.Match(tmp_index_v, score);
261  }
262 
263  if (_debug_mode <= kPerIteration) {
266  }
267 
268  return false;
269  }
270 
271 }
unsigned int CMFactorial(unsigned int n)
virtual void EventEnd()
FMWK function called @ end of Process()
Somewhat verbose (cout per merging iteration)
Definition: CMManagerBase.h:48
Class def header for a class CMatchBookKeeper.
virtual void Reset()
Method to reset itself.
static QCString result
virtual void Report()
Definition: CMAlgoBase.h:80
Class def header for a class CFloatAlgoBase.
std::vector< std::vector< std::pair< size_t, size_t > > > PlaneClusterCombinations(const std::vector< size_t > &seed)
::cmtool::CFloatAlgoBase * _match_algo
Merging algorithm.
Definition: CMatchManager.h:84
struct vector vector
CMatchManager()
Default constructor is private because we need an argument to configure w/ # planes in the detector...
virtual float Float(util::GeometryUtilities const &, const std::vector< const cluster::ClusterParamsAlg * > &clusters)
std::vector< std::vector< size_t > > ClusterCombinations(const std::vector< size_t > &seed)
CMatchBookKeeper _book_keeper
Book keeper instance.
Definition: CMatchManager.h:81
void ComputePriority(const std::vector< cluster::ClusterParamsAlg > &clusters)
Function to compute priority.
virtual void EventEnd()
Definition: CMAlgoBase.h:55
virtual bool IterationProcess(util::GeometryUtilities const &gser)
FMWK function called @ iterative loop inside Process()
Class def header for a class CPriorityAlgoBase.
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
virtual void EventBegin()
FMWK function called @ beginning of Process()
void Match(const std::vector< unsigned int > &matched_indexes, const float &score)
Method to register matched clusters.
std::multimap< float, size_t > _priority
Priority record.
virtual void Reset()
Function to reset the algorithm instance called within CMergeManager/CMatchManager&#39;s Reset() ...
Definition: CMAlgoBase.h:41
std::void_t< T > n
Class def header for exception classes in CMTException.
QTextStream & flush(QTextStream &s)
CMMSGLevel_t _debug_mode
Debug mode switch.
string tmp
Definition: languages.py:63
def fill(s)
Definition: translator.py:93
Class def header for a class CMatchManager.
std::vector< cluster::ClusterParamsAlg > _in_clusters
Input clusters.
virtual void IterationEnd()
FMWK function called @ end of iterative loop inside Process()
::cmtool::CPriorityAlgoBase * _priority_algo
Priority algorithm.
std::set< UChar_t > _planes
A holder for # of unique planes in the clusters, computed in ComputePriority() function.
void Reset()
Reset method.
virtual void SetVerbose(bool doit=true)
Setter function for verbosity.
Definition: CMAlgoBase.h:92
virtual void IterationBegin(const std::vector< cluster::ClusterParamsAlg > &)
Definition: CMAlgoBase.h:64
Extremely verbose (cout per individual algorithm execution)
Definition: CMManagerBase.h:46
virtual void IterationBegin()
FMWK function called @ beginning of iterative loop inside Process()
Class def header for a class CMManagerBase.
std::vector< std::vector< size_t > > SimpleCombination(size_t n, size_t r)
size_t _nplanes
Number of planes.
Definition: CMatchManager.h:87
virtual void IterationEnd()
Definition: CMAlgoBase.h:71
QTextStream & endl(QTextStream &s)
void Reset()
Method to reset itself.