LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
cmtool::CMergeBookKeeper Class Reference

#include "CMergeBookKeeper.h"

Inheritance diagram for cmtool::CMergeBookKeeper:

Public Member Functions

 CMergeBookKeeper (unsigned short nclusters=0)
 Default constructor. More...
 
void Reset (unsigned short nclusters=0)
 Reset method. More...
 
void ProhibitMerge (unsigned short index1, unsigned short index2)
 Method to set a pair of clusters to prohibit from merging. More...
 
bool MergeAllowed (unsigned short index1, unsigned short index2)
 Method to inqury if a combination is prohibited to merge. More...
 
void Merge (unsigned short index1, unsigned short index2)
 Method to merge 2 clusters via index numbers. More...
 
std::vector< unsigned short > GetMergedSet (unsigned short index1) const
 
bool IsMerged (unsigned short index1, unsigned short index2) const
 
void PassResult (std::vector< std::vector< unsigned short >> &result) const
 
std::vector< std::vector< unsigned short > > GetResult () const
 
void Combine (const CMergeBookKeeper &another)
 
void Report () const
 

Public Attributes

elements
 STL member. More...
 

Protected Attributes

std::vector< std::vector< bool > > _prohibit_merge
 
size_t _out_cluster_count
 Number of output clusters. More...
 

Detailed Description

A utility class for CMergeManager which merge clusters using merging algorithms. One of major task for CMergeManager is to keep track of which clusters to be merged in the original input. CMergeBookKeeper handles this part. It works with indexes. The user (primarily CMergeManager) provides number of clusters to CMergeBookKeeper's constructor. Then it can ask CMergeBookKeeper to merge two specific clusters by specifying index number of the cluster which has to be smaller than the previously specified number of clusters. CMergeBookKeeper keeps track of which clusters are asked to merge together, and it can be asked to return a vector of merged cluster indexes.

Definition at line 33 of file CMergeBookKeeper.h.

Constructor & Destructor Documentation

cmtool::CMergeBookKeeper::CMergeBookKeeper ( unsigned short  nclusters = 0)

Default constructor.

Definition at line 10 of file CMergeBookKeeper.cxx.

References Reset().

11  {
12  Reset(nclusters);
13  }
void Reset(unsigned short nclusters=0)
Reset method.

Member Function Documentation

void cmtool::CMergeBookKeeper::Combine ( const CMergeBookKeeper another)

Method to combine with another CMergeBookKeeper instance.

Definition at line 261 of file CMergeBookKeeper.cxx.

References Merge(), PassResult(), and target.

Referenced by cmtool::CMergeManager::EventEnd(), GetResult(), and cmtool::CMergeHelper::Process().

262  {
263  // Check length compatibility between this instance's result and "another"
264  std::vector<std::vector<unsigned short>> my_result;
265  this->PassResult(my_result);
266  if (my_result.size() != another.size()) {
267  throw CMTException(
268  Form("Input has an incompatible size (%zu != %zu)", my_result.size(), another.size()));
269  return;
270  }
271 
272  // Check if "another" result is different from input
273  std::vector<std::vector<unsigned short>> another_result;
274  another.PassResult(another_result);
275  if (another_result.size() >= my_result.size())
276  throw CMTException(Form("The input has equal or more number of output clusters (%zu>=%zu)",
277  another_result.size(),
278  my_result.size()));
279 
280  // Combine
281  for (auto const& ares : another_result) {
282 
283  if (ares.size() == 1) continue;
284 
285  // Get one of cluster to be used for merging
286  unsigned short target = my_result.at(ares.at(0)).at(0);
287 
288  for (auto const& res_index : ares) {
289 
290  for (auto const& orig_index : my_result.at(res_index)) {
291 
292  if (target == orig_index)
293  continue;
294 
295  else
296  this->Merge(target, orig_index);
297  }
298  }
299  }
300  }
void PassResult(std::vector< std::vector< unsigned short >> &result) const
void Merge(unsigned short index1, unsigned short index2)
Method to merge 2 clusters via index numbers.
cout<< "-> Edep in the target
Definition: analysis.C:53
std::vector< unsigned short > cmtool::CMergeBookKeeper::GetMergedSet ( unsigned short  index1) const

Method to retrieve a vector of cluster indexes which is merged with the input cluster index. All indexes here are regarding the original cluster index.

Definition at line 237 of file CMergeBookKeeper.cxx.

References util::size().

238  {
239 
240  if (index1 >= this->size()) throw CMTException(Form("Invalid cluster index: %d ", index1));
241 
242  auto out_index = this->at(index1);
243  std::vector<unsigned short> result;
244 
245  for (size_t i = 0; i < this->size(); ++i)
246  if (this->at(i) == out_index) result.push_back(i);
247 
248  return result;
249  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
std::vector<std::vector<unsigned short> > cmtool::CMergeBookKeeper::GetResult ( ) const
inline

Definition at line 72 of file CMergeBookKeeper.h.

References Combine(), PassResult(), and Report().

Referenced by cluster::ClusterMergeHelper::Process(), and cmtool::CMergeManager::RunMerge().

73  {
74  std::vector<std::vector<unsigned short>> result;
75  PassResult(result);
76  return result;
77  }
void PassResult(std::vector< std::vector< unsigned short >> &result) const
bool cmtool::CMergeBookKeeper::IsMerged ( unsigned short  index1,
unsigned short  index2 
) const

Method to ask if a given 2 clusters are already merged. This method is expected to be much faster than obtaining a merged cluster sets from GetMergedIndexes and check if two clusters are merged.

Definition at line 229 of file CMergeBookKeeper.cxx.

References util::size().

230  {
231  if (index1 >= this->size() || index2 >= this->size())
232  throw CMTException(Form("Invalid cluster index: %d or %d", index1, index2));
233 
234  return this->at(index1) == this->at(index2);
235  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
void cmtool::CMergeBookKeeper::Merge ( unsigned short  index1,
unsigned short  index2 
)

Method to merge 2 clusters via index numbers.

Definition at line 71 of file CMergeBookKeeper.cxx.

References _out_cluster_count, _prohibit_merge, and util::size().

Referenced by Combine(), and cmtool::CMergeManager::RunMerge().

72  {
73 
74  if (index1 == index2)
75 
76  throw CMTException(Form("<<%s>> Two input clusters identical (%d)", __FUNCTION__, index1));
77 
78  if (index1 >= this->size() || index2 >= this->size())
79 
80  throw CMTException(Form("Input cluster index (%d and/or %d) out of range", index1, index2));
81 
82  auto out_index1 = this->at(index1);
83  auto out_index2 = this->at(index2);
84 
85  if (out_index1 == out_index2) return;
86 
87  if (out_index2 < out_index1) std::swap(out_index1, out_index2);
88 
89  if (_prohibit_merge.at(out_index1).at(out_index2 - out_index1))
90 
91  throw CMTException(
92  Form("Clusters (%d,%d) correspond to output (%d,%d) which is prohibited to merge",
93  index1,
94  index2,
95  out_index1,
96  out_index2));
97 
98  //
99  // Merge cluster indexes
100  //
101  for (auto& v : (*this)) {
102 
103  if (v == out_index1 || v == out_index2)
104  v = out_index1;
105  else if (v > out_index2)
106  v -= 1;
107  }
108 
109  //
110  // Merge prohibit rule
111  //
112  // (1) handle index < out_index1
113  for (size_t index = 0; index < out_index1; ++index) {
114 
115  size_t tmp_out_index1 = out_index1 - index;
116  size_t tmp_out_index2 = out_index2 - index;
117 
118  _prohibit_merge.at(index).at(tmp_out_index1) =
119  (_prohibit_merge.at(index).at(tmp_out_index1) ||
120  _prohibit_merge.at(index).at(tmp_out_index2));
121 
122  for (size_t in_index = tmp_out_index2;
123  //in_index < _prohibit_merge.at(index).size() - 1;
124  in_index < (_out_cluster_count - index - 1);
125  ++in_index) {
126 
127  /*
128  if(in_index >= (_out_cluster_count - 1 - index))
129 
130  _prohibit_merge.at(index).at(in_index) = false;
131 
132  else
133  */
134  _prohibit_merge.at(index).at(in_index) = _prohibit_merge.at(index).at(in_index + 1);
135  }
136 
137  //(*_prohibit_merge.at(index).rbegin()) = false;
138  _prohibit_merge.at(index).at(_out_cluster_count - index - 1) = false;
139  }
140 
141  // (2) handle index == out_index1
142  for (size_t in_index = 1;
143  //in_index < _prohibit_merge.at(out_index1).size() - 1;
144  in_index < (_out_cluster_count - out_index1 - 1);
145  ++in_index) {
146  if ((in_index + out_index1) < out_index2) {
147  /*
148  std::cout<<Form("Inspecting1 : (%d,%zu) to (%zu,%zu)",
149  out_index1,in_index,
150  (in_index + out_index1),(out_index2 - (in_index+out_index1)))
151  << std::endl;
152  */
153  _prohibit_merge.at(out_index1).at(in_index) =
154  (_prohibit_merge.at(out_index1).at(in_index) ||
155  _prohibit_merge.at(in_index + out_index1).at(out_index2 - (in_index + out_index1)));
156  }
157  else {
158  /*
159  std::cout<<Form("Inspecting2 : (%d,%zu) to (%d,%zu) ...",
160  out_index1,in_index+1,
161  out_index2,(in_index+out_index1-out_index2));
162  if(_prohibit_merge.at(out_index1).at(in_index+1)) std::cout<<"T";
163  else std::cout<<"F";
164  std::cout<<",";
165  if(_prohibit_merge.at(out_index2).at(in_index+out_index1-out_index2)) std::cout<<"T";
166  else std::cout<<"F";
167  std::cout<<std::endl;
168  */
169  _prohibit_merge.at(out_index1).at(in_index) =
170  (_prohibit_merge.at(out_index1).at(in_index + 1) ||
171  _prohibit_merge.at(out_index2).at(in_index + 1 + out_index1 - out_index2));
172  }
173  }
174  //(*_prohibit_merge.at(out_index1).rbegin()) = false;
175  _prohibit_merge.at(out_index1).at(_out_cluster_count - out_index1 - 1) = false;
176 
177  // (3) handle out_index1 < index < out_index2
178  for (size_t index = out_index1 + 1; index < out_index2; ++index) {
179  for (size_t in_index = (out_index2 - index);
180  //in_index < (_prohibit_merge.at(index).size() - 1);
181  in_index < (_out_cluster_count - index - 1);
182  ++in_index)
183 
184  _prohibit_merge.at(index).at(in_index) = _prohibit_merge.at(index).at(in_index + 1);
185 
186  //(*_prohibit_merge.at(index).rbegin()) = false;
187  _prohibit_merge.at(index).at(_out_cluster_count - index - 1) = false;
188  }
189  // (4) handle out_index2 <= index
190  for (size_t index = out_index2;
191  //index < (_prohibit_merge.size() - 1);
192  index < (_out_cluster_count - 1);
193  ++index) {
194 
195  for (size_t in_index = 0; in_index < _prohibit_merge.at(index).size(); ++in_index)
196 
197  if (in_index < _prohibit_merge.at(index + 1).size())
198  _prohibit_merge.at(index).at(in_index) = _prohibit_merge.at(index + 1).at(in_index);
199 
200  else
201  _prohibit_merge.at(index).at(in_index) = false;
202  }
203 
204  _out_cluster_count -= 1;
205  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
size_t _out_cluster_count
Number of output clusters.
std::vector< std::vector< bool > > _prohibit_merge
void swap(lar::deep_const_fwd_iterator_nested< CITER, INNERCONTEXTRACT > &a, lar::deep_const_fwd_iterator_nested< CITER, INNERCONTEXTRACT > &b)
bool cmtool::CMergeBookKeeper::MergeAllowed ( unsigned short  index1,
unsigned short  index2 
)

Method to inqury if a combination is prohibited to merge.

Definition at line 50 of file CMergeBookKeeper.cxx.

References _prohibit_merge, and util::size().

Referenced by cmtool::CMergeManager::RunMerge().

51  {
52 
53  if (index1 == index2)
54 
55  throw CMTException(Form("<<%s>> Two input clusters identical (%d)", __FUNCTION__, index1));
56 
57  if (index1 >= this->size() || index2 >= this->size())
58 
59  throw CMTException(Form("Input cluster index (%d and/or %d) out of range", index1, index2));
60 
61  auto out_index1 = this->at(index1);
62  auto out_index2 = this->at(index2);
63 
64  if (out_index1 == out_index2) return true;
65 
66  if (out_index2 < out_index1) std::swap(out_index1, out_index2);
67 
68  return !(_prohibit_merge.at(out_index1).at(out_index2 - out_index1));
69  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
std::vector< std::vector< bool > > _prohibit_merge
void swap(lar::deep_const_fwd_iterator_nested< CITER, INNERCONTEXTRACT > &a, lar::deep_const_fwd_iterator_nested< CITER, INNERCONTEXTRACT > &b)
void cmtool::CMergeBookKeeper::PassResult ( std::vector< std::vector< unsigned short >> &  result) const

A method to get the full result. The return is a vector of merged cluster indexes (which is a vector of original cluster indexes).

Definition at line 251 of file CMergeBookKeeper.cxx.

References _out_cluster_count, and util::size().

Referenced by Combine(), GetResult(), and cmtool::CMergeManager::IterationProcess().

252  {
253 
254  result.clear();
255  result.resize(_out_cluster_count, std::vector<unsigned short>());
256 
257  for (size_t i = 0; i < this->size(); ++i)
258  result.at(this->at(i)).push_back(i);
259  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
size_t _out_cluster_count
Number of output clusters.
void cmtool::CMergeBookKeeper::ProhibitMerge ( unsigned short  index1,
unsigned short  index2 
)

Method to set a pair of clusters to prohibit from merging.

Definition at line 29 of file CMergeBookKeeper.cxx.

References _prohibit_merge, and util::size().

Referenced by cmtool::CMergeManager::RunSeparate().

30  {
31  if (index1 == index2)
32 
33  throw CMTException(Form("<<%s>> Two input clusters identical (%d)", __FUNCTION__, index1));
34 
35  if (index1 >= this->size() || index2 >= this->size())
36 
37  throw CMTException(Form("Input cluster index (%d and/or %d) out of range", index1, index2));
38 
39  auto out_index1 = this->at(index1);
40  auto out_index2 = this->at(index2);
41 
42  if (out_index1 == out_index2)
43  throw CMTException(Form("Cluster %d and %d already merged!", index1, index2));
44 
45  if (out_index2 < out_index1) std::swap(out_index1, out_index2);
46 
47  _prohibit_merge.at(out_index1).at(out_index2 - out_index1) = true;
48  }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
std::vector< std::vector< bool > > _prohibit_merge
void swap(lar::deep_const_fwd_iterator_nested< CITER, INNERCONTEXTRACT > &a, lar::deep_const_fwd_iterator_nested< CITER, INNERCONTEXTRACT > &b)
void cmtool::CMergeBookKeeper::Report ( ) const

Definition at line 207 of file CMergeBookKeeper.cxx.

References _prohibit_merge.

Referenced by GetResult().

208  {
209  std::cout << "Merge Result:" << std::endl;
210  for (auto const& v : *this)
211  std::cout << v << " ";
212  std::cout << std::endl << std::endl;
213 
214  std::cout << "Prohibit Status:" << std::endl;
215  for (auto const& bs : _prohibit_merge) {
216 
217  for (auto const& b : bs) {
218 
219  if (b)
220  std::cout << "\033[93mT\033[00m ";
221  else
222  std::cout << "\033[95mF\033[00m ";
223  }
224  std::cout << std::endl;
225  }
226  std::cout << std::endl;
227  }
std::vector< std::vector< bool > > _prohibit_merge
void cmtool::CMergeBookKeeper::Reset ( unsigned short  nclusters = 0)

Reset method.

Definition at line 15 of file CMergeBookKeeper.cxx.

References _out_cluster_count, _prohibit_merge, and clear().

Referenced by CMergeBookKeeper(), cmtool::CMergeManager::EventBegin(), cmtool::CMergeManager::IterationProcess(), and cmtool::CMergeManager::Reset().

16  {
17  _prohibit_merge.clear();
18  _prohibit_merge.reserve(nclusters);
20  std::vector<unsigned short>::reserve(nclusters);
21 
22  for (size_t i = 0; i < nclusters; ++i) {
23  this->push_back(i);
24  _prohibit_merge.push_back(std::vector<bool>(nclusters - i, false));
25  }
26  _out_cluster_count = nclusters;
27  }
size_t _out_cluster_count
Number of output clusters.
std::vector< std::vector< bool > > _prohibit_merge
vec_iX clear()

Member Data Documentation

size_t cmtool::CMergeBookKeeper::_out_cluster_count
protected

Number of output clusters.

Definition at line 94 of file CMergeBookKeeper.h.

Referenced by Merge(), PassResult(), and Reset().

std::vector<std::vector<bool> > cmtool::CMergeBookKeeper::_prohibit_merge
protected

A 2D-map vector that stores pair of clusters for which merging is prohibited

Definition at line 91 of file CMergeBookKeeper.h.

Referenced by Merge(), MergeAllowed(), ProhibitMerge(), Report(), and Reset().

T std::vector< T >::elements
inherited

STL member.


The documentation for this class was generated from the following files: