LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
CMergeManager.cxx
Go to the documentation of this file.
2 
3 #include "RtypesCore.h"
4 #include "TString.h"
5 #include <iostream>
6 #include <map>
7 #include <set>
8 #include <string>
9 
16 
17 namespace cmtool {
18 
20  {
21  _iter_ctr = 0;
22  _merge_algo = nullptr;
23  _separate_algo = nullptr;
24  Reset();
25  }
26 
28  {
30  _tmp_merged_clusters.clear();
31  _tmp_merged_indexes.clear();
32  _out_clusters.clear();
34  _book_keeper_v.clear();
37  _iter_ctr = 0;
38  }
39 
42  {
43  // Initialization per event
44  if (!_merge_algo) throw CMTException("No algorithm to run!");
45 
46  // Merging algorithm
49 
50  // Separation algorithm
51  if (_separate_algo) {
54  }
55 
56  // Priority ordering algorithm
57  if (_priority_algo) {
60  }
61 
62  // Verbosity setting
63  if (_debug_mode <= kPerMerging) {
64  _merge_algo->SetVerbose(true);
67  }
68 
69  // Book keeper reinitialization
71 
72  // Clear temporary variables
73  _iter_ctr = 0;
74  _tmp_merged_clusters.clear();
75  _tmp_merged_indexes.clear();
76  _book_keeper_v.clear();
77  }
78 
81  {
82 
83  if (!_iter_ctr) {
84 
88  }
89  else {
90 
94  }
95 
96  if (_debug_mode <= kPerIteration) {
97 
98  size_t nclusters = _tmp_merged_clusters.size();
99 
100  if (!_iter_ctr) nclusters = _in_clusters.size();
101 
102  std::cout << std::endl
103  << Form(" Merging iteration %zu: processing %zu clusters...", _iter_ctr, nclusters)
104  << std::endl;
105  }
106  }
107 
110  {
111 
115 
116  if (_debug_mode <= kPerIteration) {
117 
118  _merge_algo->Report();
121 
122  std::cout << Form(" Input / Output cluster length: %zu/%zu",
123  _tmp_merged_clusters.size(),
124  _out_clusters.size())
125  << std::endl;
126 
127  if (_tmp_merged_clusters.size() == _out_clusters.size())
128 
129  std::cout << " Did not find any newly merged clusters..." << std::endl;
130 
131  if (_out_clusters.size() == 1)
132 
133  std::cout << " Output cluster length is 1 (= no more merging needed)" << std::endl;
134 
135  if (!_merge_till_converge) std::cout << " Non-iterative option: terminating..." << std::endl;
136  }
137 
138  _iter_ctr++;
139  }
140 
143  {
144  // Gather the full book keeping result
145  for (auto const& bk : _book_keeper_v)
146 
147  _book_keeper.Combine(bk);
148 
149  // Call EventEnd for algorithms
153 
154  _book_keeper_v.clear();
155  _tmp_merged_clusters.clear();
156  _tmp_merged_indexes.clear();
157  }
158 
160  {
161  // Configure input for RunMerge
162  CMergeBookKeeper bk;
163 
164  if (!_iter_ctr)
166  else
168  _out_clusters.clear();
169 
170  bk.Reset(_tmp_merged_clusters.size());
171 
172  std::vector<bool> merge_switch(_tmp_merged_clusters.size(), true);
173 
174  for (size_t i = 0; i < _tmp_merged_indexes.size(); ++i)
175  if (_tmp_merged_indexes.at(i).size() == 1) merge_switch.at(i) = false;
176 
178 
179  // Run separation algorithm
181 
182  // Run merging algorithm
183  RunMerge(_tmp_merged_clusters, merge_switch, bk);
185 
186  // Save output
188 
189  if (bk.size() == _tmp_merged_indexes.size())
191  else {
192  _out_clusters.reserve(_tmp_merged_indexes.size());
193  for (auto const& indexes_v : _tmp_merged_indexes) {
194 
195  if (indexes_v.size() == 1) {
196  _out_clusters.push_back(_tmp_merged_clusters.at(indexes_v.at(0)));
197  continue;
198  }
199 
200  size_t tmp_hit_counts = 0;
201  for (auto const& index : indexes_v)
202  tmp_hit_counts += _tmp_merged_clusters.at(index).GetHitVector().size();
203  //std::vector<larutil::PxHit> tmp_hits;
204  std::vector<util::PxHit> tmp_hits;
205  tmp_hits.reserve(tmp_hit_counts);
206 
207  for (auto const& index : indexes_v) {
208  for (auto const& hit : _tmp_merged_clusters.at(index).GetHitVector())
209  tmp_hits.push_back(hit);
210  }
212  (*_out_clusters.rbegin()).SetVerbose(false);
213  (*_out_clusters.rbegin()).DisableFANN();
214 
215  if ((*_out_clusters.rbegin()).SetHits(tmp_hits) < 1) continue;
216  (*_out_clusters.rbegin()).FillParams(gser, true, true, true, true, true, false);
217  (*_out_clusters.rbegin()).FillPolygon(gser);
218  }
219  _book_keeper_v.push_back(bk);
220  }
221 
222  // Break if no more merging occurred
223  if (_tmp_merged_clusters.size() == _out_clusters.size()) return false;
224 
225  if (_out_clusters.size() == _planes.size()) return false;
226 
227  return true;
228  }
229 
230  void CMergeManager::RunMerge(const std::vector<cluster::ClusterParamsAlg>& in_clusters,
231  CMergeBookKeeper& book_keeper) const
232  {
233  RunMerge(in_clusters, std::vector<bool>(in_clusters.size(), true), book_keeper);
234  }
235 
236  void CMergeManager::RunMerge(const std::vector<cluster::ClusterParamsAlg>& in_clusters,
237  const std::vector<bool>& merge_flag,
238  CMergeBookKeeper& book_keeper) const
239  {
240  if (merge_flag.size() != in_clusters.size())
241  throw CMTException(
242  Form("in_clusters (%zu) and merge_flag (%zu) vectors must be of same length!",
243  in_clusters.size(),
244  merge_flag.size()));
245  if (_debug_mode <= kPerIteration) {
246 
247  std::cout << Form(" Calling %s with %zu clusters...", __FUNCTION__, in_clusters.size())
248  << std::endl;
249  }
250 
251  //
252  // Merging
253  //
254 
255  // Run over clusters and execute merging algorithms
256  for (auto citer1 = _priority.rbegin(); citer1 != _priority.rend(); ++citer1) {
257 
258  auto citer2 = citer1;
259 
260  UChar_t plane1 = in_clusters.at((*citer1).second).Plane();
261 
262  while (1) {
263  citer2++;
264  if (citer2 == _priority.rend()) break;
265 
266  // Skip if not on the same plane
267  UChar_t plane2 = in_clusters.at((*citer2).second).Plane();
268  if (plane1 != plane2) continue;
269 
270  // Skip if this combination is not meant to be compared
271  if (!(merge_flag.at((*citer2).second)) && !(merge_flag.at((*citer1).second))) continue;
272 
273  // Skip if this combination is not allowed to merge
274  if (!(book_keeper.MergeAllowed((*citer1).second, (*citer2).second))) continue;
275 
276  if (_debug_mode <= kPerMerging) {
277 
278  std::cout << Form(" \033[93mInspecting a pair (%zu, %zu) for merging... \033[00m",
279  (*citer1).second,
280  (*citer2).second)
281  << std::endl;
282  }
283 
284  bool merge =
285  _merge_algo->Bool(in_clusters.at((*citer1).second), in_clusters.at((*citer2).second));
286 
287  if (_debug_mode <= kPerMerging) {
288 
289  if (merge)
290  std::cout << " \033[93mfound to be merged!\033[00m " << std::endl << std::endl;
291 
292  else
293  std::cout << " \033[93mfound NOT to be merged...\033[00m" << std::endl << std::endl;
294 
295  } // end looping over all sets of algorithms
296 
297  if (merge) book_keeper.Merge((*citer1).second, (*citer2).second);
298 
299  } // end looping over all cluster pairs for citer1
300 
301  } // end looping over clusters
302 
303  if (_debug_mode <= kPerIteration && book_keeper.GetResult().size() != in_clusters.size()) {
304 
305  std::cout << " Found following clusters to be merged..." << std::endl;
306  for (auto const& indexes_v : book_keeper.GetResult()) {
307 
308  if (indexes_v.size() == 1) continue;
309  std::cout << " ";
310  for (auto index : indexes_v)
311 
312  std::cout << index << " ";
313  std::cout << " ... indexes to be merged!" << std::endl;
314  }
315  }
316  }
317 
318  void CMergeManager::RunSeparate(const std::vector<cluster::ClusterParamsAlg>& in_clusters,
319  CMergeBookKeeper& book_keeper) const
320  {
321  /*
322  if(separate_flag.size() != in_clusters.size())
323  throw CMTException(Form("in_clusters (%zu) and separate_flag (%zu) vectors must be of same length!",
324  in_clusters.size(),
325  separate_flag.size()
326  )
327  );
328  */
329  if (_debug_mode <= kPerIteration) {
330 
331  std::cout << Form(" Calling %s with %zu clusters...", __FUNCTION__, in_clusters.size())
332  << std::endl;
333  }
334 
335  //
336  // Separation
337  //
338 
339  // Run over clusters and execute merging algorithms
340  for (size_t cindex1 = 0; cindex1 < in_clusters.size(); ++cindex1) {
341 
342  UChar_t plane1 = in_clusters.at(cindex1).Plane();
343 
344  for (size_t cindex2 = cindex1 + 1; cindex2 < in_clusters.size(); ++cindex2) {
345 
346  // Skip if not on the same plane
347  UChar_t plane2 = in_clusters.at(cindex2).Plane();
348  if (plane1 != plane2) continue;
349 
350  // Skip if this combination is not meant to be compared
351  //if(!(separate_flag.at(cindex2))) continue;
352 
353  if (_debug_mode <= kPerMerging) {
354 
355  std::cout << Form(" \033[93mInspecting a pair (%zu, %zu) for separation... \033[00m",
356  cindex1,
357  cindex2)
358  << std::endl;
359  }
360 
361  bool separate = _separate_algo->Bool(in_clusters.at(cindex1), in_clusters.at(cindex2));
362 
363  if (_debug_mode <= kPerMerging) {
364 
365  if (separate)
366  std::cout << " \033[93mfound to be separated!\033[00m " << std::endl << std::endl;
367 
368  else
369  std::cout << " \033[93mfound NOT to be separated...\033[00m" << std::endl
370  << std::endl;
371 
372  } // end looping over all sets of algorithms
373 
374  if (separate) book_keeper.ProhibitMerge(cindex1, cindex2);
375 
376  } // end looping over all cluster pairs for citer1
377 
378  } // end looping over clusters
379  }
380 
381 }
Class def header for algorithm classes for CMergeManager.
virtual void EventEnd()
FMWK function called @ end of Process()
Somewhat verbose (cout per merging iteration)
Definition: CMManagerBase.h:48
bool _merge_till_converge
Iteration loop switch.
std::vector< CMergeBookKeeper > _book_keeper_v
TFile * _fout
Output analysis plot TFile.
virtual void Report()
Definition: CMAlgoBase.h:69
std::vector< std::vector< unsigned short > > _tmp_merged_indexes
::cmtool::CBoolAlgoBase * _merge_algo
Merging algorithm.
Definition: CMergeManager.h:93
virtual void EventBegin()
FMWK function called @ beginning of Process()
void ProhibitMerge(unsigned short index1, unsigned short index2)
Method to set a pair of clusters to prohibit from merging.
std::vector< cluster::ClusterParamsAlg > _out_clusters
Output clusters.
Definition: CMergeManager.h:87
std::vector< std::vector< unsigned short > > GetResult() const
std::vector< cluster::ClusterParamsAlg > _tmp_merged_clusters
virtual bool IterationProcess(util::GeometryUtilities const &gser)
FMWK function called @ iterative loop inside Process()
virtual void IterationEnd()
FMWK function called @ end of iterative loop inside Process()
Class def header for a class CMergeBookKeeper.
void ComputePriority(const std::vector< cluster::ClusterParamsAlg > &clusters)
Function to compute priority.
virtual void EventEnd()
Definition: CMAlgoBase.h:50
virtual void IterationBegin()
FMWK function called @ beginning of iterative loop inside Process()
void RunMerge(const std::vector< cluster::ClusterParamsAlg > &in_clusters, CMergeBookKeeper &book_keeper) const
Class def header for a class CPriorityAlgoBase.
void RunSeparate(const std::vector< cluster::ClusterParamsAlg > &in_clusters, CMergeBookKeeper &book_keeper) const
virtual bool Bool(const ::cluster::ClusterParamsAlg &cluster1, const ::cluster::ClusterParamsAlg &cluster2)
Definition: CBoolAlgoBase.h:40
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:40
::cmtool::CBoolAlgoBase * _separate_algo
Separation algorithm.
Definition: CMergeManager.h:96
CMergeBookKeeper _book_keeper
Book keeper instance.
Definition: CMergeManager.h:90
void PassResult(std::vector< std::vector< unsigned short >> &result) const
Class def header for exception classes in CMTException.
virtual void Reset()
Method to reset itself.
CMMSGLevel_t _debug_mode
Debug mode switch.
void SetAnaFile(TFile *fout)
Setter function for an output plot TFile pointer.
Definition: CMAlgoBase.h:72
void Combine(const CMergeBookKeeper &another)
Detector simulation of raw signals on wires.
std::vector< cluster::ClusterParamsAlg > _in_clusters
Input clusters.
::cmtool::CPriorityAlgoBase * _priority_algo
Priority algorithm.
void Merge(unsigned short index1, unsigned short index2)
Method to merge 2 clusters via index numbers.
std::set< UChar_t > _planes
A holder for # of unique planes in the clusters, computed in ComputePriority() function.
bool MergeAllowed(unsigned short index1, unsigned short index2)
Method to inqury if a combination is prohibited to merge.
virtual void SetVerbose(bool doit=true)
Setter function for verbosity.
Definition: CMAlgoBase.h:75
virtual void IterationBegin(const std::vector< cluster::ClusterParamsAlg > &)
Definition: CMAlgoBase.h:57
Extremely verbose (cout per individual algorithm execution)
Definition: CMManagerBase.h:46
Class def header for a class CMManagerBase.
Class def header for a class CMergeManager.
virtual void IterationEnd()
Definition: CMAlgoBase.h:62
void Reset(unsigned short nclusters=0)
Reset method.
virtual void EventBegin(const std::vector< cluster::ClusterParamsAlg > &)
Definition: CMAlgoBase.h:45
void Reset()
Method to reset itself.