All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
27  void
29  {
31  _tmp_merged_clusters.clear();
32  _tmp_merged_indexes.clear();
33  _out_clusters.clear();
35  _book_keeper_v.clear();
38  _iter_ctr = 0;
39  }
40 
41  /// FMWK function called @ beginning of Process()
42  void
44  {
45  // Initialization per event
46  if (!_merge_algo) throw CMTException("No algorithm to run!");
47 
48  // Merging algorithm
51 
52  // Separation algorithm
53  if (_separate_algo) {
56  }
57 
58  // Priority ordering algorithm
59  if (_priority_algo) {
62  }
63 
64  // Verbosity setting
65  if (_debug_mode <= kPerMerging) {
66  _merge_algo->SetVerbose(true);
69  }
70 
71  // Book keeper reinitialization
73 
74  // Clear temporary variables
75  _iter_ctr = 0;
76  _tmp_merged_clusters.clear();
77  _tmp_merged_indexes.clear();
78  _book_keeper_v.clear();
79  }
80 
81  /// FMWK function called @ beginning of iterative loop inside Process()
82  void
84  {
85 
86  if (!_iter_ctr) {
87 
91  }
92  else {
93 
97  }
98 
99  if (_debug_mode <= kPerIteration) {
100 
101  size_t nclusters = _tmp_merged_clusters.size();
102 
103  if (!_iter_ctr) nclusters = _in_clusters.size();
104 
105  std::cout << std::endl
106  << Form(" Merging iteration %zu: processing %zu clusters...", _iter_ctr, nclusters)
107  << std::endl;
108  }
109  }
110 
111  /// FMWK function called @ end of iterative loop inside Process()
112  void
114  {
115 
119 
120  if (_debug_mode <= kPerIteration) {
121 
122  _merge_algo->Report();
125 
126  std::cout << Form(" Input / Output cluster length: %zu/%zu",
127  _tmp_merged_clusters.size(),
128  _out_clusters.size())
129  << std::endl;
130 
131  if (_tmp_merged_clusters.size() == _out_clusters.size())
132 
133  std::cout << " Did not find any newly merged clusters..." << std::endl;
134 
135  if (_out_clusters.size() == 1)
136 
137  std::cout << " Output cluster length is 1 (= no more merging needed)" << std::endl;
138 
139  if (!_merge_till_converge) std::cout << " Non-iterative option: terminating..." << std::endl;
140  }
141 
142  _iter_ctr++;
143  }
144 
145  /// FMWK function called @ end of Process()
146  void
148  {
149  // Gather the full book keeping result
150  for (auto const& bk : _book_keeper_v)
151 
152  _book_keeper.Combine(bk);
153 
154  // Call EventEnd for algorithms
158 
159  _book_keeper_v.clear();
160  _tmp_merged_clusters.clear();
161  _tmp_merged_indexes.clear();
162  }
163 
164  bool
166  {
167  // Configure input for RunMerge
168  CMergeBookKeeper bk;
169 
170  if (!_iter_ctr)
172  else
174  _out_clusters.clear();
175 
176  bk.Reset(_tmp_merged_clusters.size());
177 
178  std::vector<bool> merge_switch(_tmp_merged_clusters.size(), true);
179 
180  for (size_t i = 0; i < _tmp_merged_indexes.size(); ++i)
181  if (_tmp_merged_indexes.at(i).size() == 1) merge_switch.at(i) = false;
182 
184 
185  // Run separation algorithm
187 
188  // Run merging algorithm
189  RunMerge(_tmp_merged_clusters, merge_switch, bk);
191 
192  // Save output
194 
195  if (bk.size() == _tmp_merged_indexes.size())
197  else {
198  _out_clusters.reserve(_tmp_merged_indexes.size());
199  for (auto const& indexes_v : _tmp_merged_indexes) {
200 
201  if (indexes_v.size() == 1) {
202  _out_clusters.push_back(_tmp_merged_clusters.at(indexes_v.at(0)));
203  continue;
204  }
205 
206  size_t tmp_hit_counts = 0;
207  for (auto const& index : indexes_v)
208  tmp_hit_counts += _tmp_merged_clusters.at(index).GetHitVector().size();
209  //std::vector<larutil::PxHit> tmp_hits;
210  std::vector<util::PxHit> tmp_hits;
211  tmp_hits.reserve(tmp_hit_counts);
212 
213  for (auto const& index : indexes_v) {
214  for (auto const& hit : _tmp_merged_clusters.at(index).GetHitVector())
215  tmp_hits.push_back(hit);
216  }
218  (*_out_clusters.rbegin()).SetVerbose(false);
219  (*_out_clusters.rbegin()).DisableFANN();
220 
221  if ((*_out_clusters.rbegin()).SetHits(tmp_hits) < 1) continue;
222  (*_out_clusters.rbegin()).FillParams(gser, true, true, true, true, true, false);
223  (*_out_clusters.rbegin()).FillPolygon(gser);
224  }
225  _book_keeper_v.push_back(bk);
226  }
227 
228  // Break if no more merging occurred
229  if (_tmp_merged_clusters.size() == _out_clusters.size()) return false;
230 
231  if (_out_clusters.size() == _planes.size()) return false;
232 
233  return true;
234  }
235 
236  void
237  CMergeManager::RunMerge(const std::vector<cluster::ClusterParamsAlg>& in_clusters,
238  CMergeBookKeeper& book_keeper) const
239  {
240  RunMerge(in_clusters, std::vector<bool>(in_clusters.size(), true), book_keeper);
241  }
242 
243  void
244  CMergeManager::RunMerge(const std::vector<cluster::ClusterParamsAlg>& in_clusters,
245  const std::vector<bool>& merge_flag,
246  CMergeBookKeeper& book_keeper) const
247  {
248  if (merge_flag.size() != in_clusters.size())
249  throw CMTException(
250  Form("in_clusters (%zu) and merge_flag (%zu) vectors must be of same length!",
251  in_clusters.size(),
252  merge_flag.size()));
253  if (_debug_mode <= kPerIteration) {
254 
255  std::cout << Form(" Calling %s with %zu clusters...", __FUNCTION__, in_clusters.size())
256  << std::endl;
257  }
258 
259  //
260  // Merging
261  //
262 
263  // Run over clusters and execute merging algorithms
264  for (auto citer1 = _priority.rbegin(); citer1 != _priority.rend(); ++citer1) {
265 
266  auto citer2 = citer1;
267 
268  UChar_t plane1 = in_clusters.at((*citer1).second).Plane();
269 
270  while (1) {
271  citer2++;
272  if (citer2 == _priority.rend()) break;
273 
274  // Skip if not on the same plane
275  UChar_t plane2 = in_clusters.at((*citer2).second).Plane();
276  if (plane1 != plane2) continue;
277 
278  // Skip if this combination is not meant to be compared
279  if (!(merge_flag.at((*citer2).second)) && !(merge_flag.at((*citer1).second))) continue;
280 
281  // Skip if this combination is not allowed to merge
282  if (!(book_keeper.MergeAllowed((*citer1).second, (*citer2).second))) continue;
283 
284  if (_debug_mode <= kPerMerging) {
285 
286  std::cout << Form(" \033[93mInspecting a pair (%zu, %zu) for merging... \033[00m",
287  (*citer1).second,
288  (*citer2).second)
289  << std::endl;
290  }
291 
292  bool merge =
293  _merge_algo->Bool(in_clusters.at((*citer1).second), in_clusters.at((*citer2).second));
294 
295  if (_debug_mode <= kPerMerging) {
296 
297  if (merge)
298  std::cout << " \033[93mfound to be merged!\033[00m " << std::endl << std::endl;
299 
300  else
301  std::cout << " \033[93mfound NOT to be merged...\033[00m" << std::endl << std::endl;
302 
303  } // end looping over all sets of algorithms
304 
305  if (merge) book_keeper.Merge((*citer1).second, (*citer2).second);
306 
307  } // end looping over all cluster pairs for citer1
308 
309  } // end looping over clusters
310 
311  if (_debug_mode <= kPerIteration && book_keeper.GetResult().size() != in_clusters.size()) {
312 
313  std::cout << " Found following clusters to be merged..." << std::endl;
314  for (auto const& indexes_v : book_keeper.GetResult()) {
315 
316  if (indexes_v.size() == 1) continue;
317  std::cout << " ";
318  for (auto index : indexes_v)
319 
320  std::cout << index << " ";
321  std::cout << " ... indexes to be merged!" << std::endl;
322  }
323  }
324  }
325 
326  void
327  CMergeManager::RunSeparate(const std::vector<cluster::ClusterParamsAlg>& in_clusters,
328  CMergeBookKeeper& book_keeper) const
329  {
330  /*
331  if(separate_flag.size() != in_clusters.size())
332  throw CMTException(Form("in_clusters (%zu) and separate_flag (%zu) vectors must be of same length!",
333  in_clusters.size(),
334  separate_flag.size()
335  )
336  );
337  */
338  if (_debug_mode <= kPerIteration) {
339 
340  std::cout << Form(" Calling %s with %zu clusters...", __FUNCTION__, in_clusters.size())
341  << std::endl;
342  }
343 
344  //
345  // Separation
346  //
347 
348  // Run over clusters and execute merging algorithms
349  for (size_t cindex1 = 0; cindex1 < in_clusters.size(); ++cindex1) {
350 
351  UChar_t plane1 = in_clusters.at(cindex1).Plane();
352 
353  for (size_t cindex2 = cindex1 + 1; cindex2 < in_clusters.size(); ++cindex2) {
354 
355  // Skip if not on the same plane
356  UChar_t plane2 = in_clusters.at(cindex2).Plane();
357  if (plane1 != plane2) continue;
358 
359  // Skip if this combination is not meant to be compared
360  //if(!(separate_flag.at(cindex2))) continue;
361 
362  if (_debug_mode <= kPerMerging) {
363 
364  std::cout << Form(" \033[93mInspecting a pair (%zu, %zu) for separation... \033[00m",
365  cindex1,
366  cindex2)
367  << std::endl;
368  }
369 
370  bool separate = _separate_algo->Bool(in_clusters.at(cindex1), in_clusters.at(cindex2));
371 
372  if (_debug_mode <= kPerMerging) {
373 
374  if (separate)
375  std::cout << " \033[93mfound to be separated!\033[00m " << std::endl << std::endl;
376 
377  else
378  std::cout << " \033[93mfound NOT to be separated...\033[00m" << std::endl
379  << std::endl;
380 
381  } // end looping over all sets of algorithms
382 
383  if (separate) book_keeper.ProhibitMerge(cindex1, cindex2);
384 
385  } // end looping over all cluster pairs for citer1
386 
387  } // end looping over clusters
388  }
389 
390 }
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:80
std::vector< std::vector< unsigned short > > _tmp_merged_indexes
::cmtool::CBoolAlgoBase * _merge_algo
Merging algorithm.
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.
std::vector< std::vector< unsigned short > > GetResult() const
process_name hit
Definition: cheaterreco.fcl:51
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:55
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:41
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
::cmtool::CBoolAlgoBase * _separate_algo
Separation algorithm.
CMergeBookKeeper _book_keeper
Book keeper instance.
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:85
void Combine(const CMergeBookKeeper &another)
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:92
virtual void IterationBegin(const std::vector< cluster::ClusterParamsAlg > &)
Definition: CMAlgoBase.h:64
Extremely verbose (cout per individual algorithm execution)
Definition: CMManagerBase.h:46
void PassResult(std::vector< std::vector< unsigned short > > &result) const
Class def header for a class CMManagerBase.
Class def header for a class CMergeManager.
virtual void IterationEnd()
Definition: CMAlgoBase.h:71
BEGIN_PROLOG could also be cout
void Reset(unsigned short nclusters=0)
Reset method.
virtual void EventBegin(const std::vector< cluster::ClusterParamsAlg > &)
Definition: CMAlgoBase.h:48
void Reset()
Method to reset itself.