LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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...
 
virtual ~CMergeBookKeeper ()
 Default destructor. 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 35 of file CMergeBookKeeper.h.

Constructor & Destructor Documentation

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

Default constructor.

Definition at line 8 of file CMergeBookKeeper.cxx.

References Reset().

9  {
10  Reset(nclusters);
11  }
void Reset(unsigned short nclusters=0)
Reset method.
virtual cmtool::CMergeBookKeeper::~CMergeBookKeeper ( )
inlinevirtual

Default destructor.

Definition at line 43 of file CMergeBookKeeper.h.

References GetMergedSet(), IsMerged(), Merge(), MergeAllowed(), PassResult(), ProhibitMerge(), Reset(), and lar::dump::vector().

43 {};

Member Function Documentation

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

Method to combine with another CMergeBookKeeper instance.

Definition at line 276 of file CMergeBookKeeper.cxx.

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

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

277  {
278  // Check length compatibility between this instance's result and "another"
279  std::vector<std::vector<unsigned short> > my_result;
280  this->PassResult(my_result);
281  if(my_result.size() != another.size()) {
282  throw CMTException(Form("Input has an incompatible size (%zu != %zu)",
283  my_result.size(),
284  another.size())
285  );
286  return;
287  }
288 
289  // Check if "another" result is different from input
290  std::vector<std::vector<unsigned short> > another_result;
291  another.PassResult(another_result);
292  if(another_result.size() >= my_result.size())
293  throw CMTException(Form("The input has equal or more number of output clusters (%zu>=%zu)",
294  another_result.size(),
295  my_result.size())
296  );
297 
298  // Combine
299  for(auto const& ares : another_result) {
300 
301  if(ares.size()==1) continue;
302 
303  // Get one of cluster to be used for merging
304  unsigned short target = my_result.at(ares.at(0)).at(0);
305 
306  for(auto const &res_index : ares) {
307 
308  for(auto const &orig_index : my_result.at(res_index)) {
309 
310  if(target == orig_index) continue;
311 
312  else this->Merge(target,orig_index);
313 
314  }
315 
316  }
317 
318  }
319 
320  }
cout<< "-> Edep in the target
Definition: analysis.C:54
void Merge(unsigned short index1, unsigned short index2)
Method to merge 2 clusters via index numbers.
void PassResult(std::vector< std::vector< unsigned short > > &result) const
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 251 of file CMergeBookKeeper.cxx.

Referenced by ~CMergeBookKeeper().

252  {
253 
254  if( index1 >= this->size() )
255  throw CMTException(Form("Invalid cluster index: %d ",index1));
256 
257  auto out_index = this->at(index1);
258  std::vector<unsigned short> result;
259 
260  for(size_t i=0; i<this->size(); ++i)
261  if( this->at(i) == out_index ) result.push_back(i);
262 
263  return result;
264  }
std::vector<std::vector<unsigned short> > cmtool::CMergeBookKeeper::GetResult ( ) const
inline

Definition at line 79 of file CMergeBookKeeper.h.

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

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

80  {
81  std::vector<std::vector<unsigned short> > result;
82  PassResult(result);
83  return result;
84  }
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 242 of file CMergeBookKeeper.cxx.

Referenced by ~CMergeBookKeeper().

243  {
244  if( index1 >= this->size() || index2 >= this->size() )
245  throw CMTException(Form("Invalid cluster index: %d or %d",index1,index2));
246 
247  return this->at(index1) == this->at(index2);
248  }
void cmtool::CMergeBookKeeper::Merge ( unsigned short  index1,
unsigned short  index2 
)

Method to merge 2 clusters via index numbers.

Definition at line 75 of file CMergeBookKeeper.cxx.

References _out_cluster_count, and _prohibit_merge.

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

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

Method to inqury if a combination is prohibited to merge.

Definition at line 51 of file CMergeBookKeeper.cxx.

References _prohibit_merge.

Referenced by cmtool::CMergeManager::RunMerge(), and ~CMergeBookKeeper().

53  {
54 
55  if(index1 == index2)
56 
57  throw CMTException(Form("<<%s>> Two input clusters identical (%d)",__FUNCTION__,index1));
58 
59 
60  if( index1 >= this->size() || index2 >= this->size() )
61 
62  throw CMTException(Form("Input cluster index (%d and/or %d) out of range",index1,index2));
63 
64  auto out_index1 = this->at(index1);
65  auto out_index2 = this->at(index2);
66 
67  if(out_index1 == out_index2) return true;
68 
69  if(out_index2 < out_index1) std::swap(out_index1,out_index2);
70 
71  return !(_prohibit_merge.at(out_index1).at(out_index2-out_index1));
72 
73  }
std::vector< std::vector< bool > > _prohibit_merge
void swap(art::HLTGlobalStatus &lhs, art::HLTGlobalStatus &rhs)
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 266 of file CMergeBookKeeper.cxx.

References _out_cluster_count.

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

267  {
268 
269  result.clear();
270  result.resize(_out_cluster_count, std::vector<unsigned short>());
271 
272  for(size_t i=0; i<this->size(); ++i)
273  result.at(this->at(i)).push_back(i);
274  }
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 28 of file CMergeBookKeeper.cxx.

References _prohibit_merge.

Referenced by cmtool::CMergeManager::RunSeparate(), and ~CMergeBookKeeper().

29  {
30  if(index1 == index2)
31 
32  throw CMTException(Form("<<%s>> Two input clusters identical (%d)",__FUNCTION__,index1));
33 
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 
49  }
std::vector< std::vector< bool > > _prohibit_merge
void swap(art::HLTGlobalStatus &lhs, art::HLTGlobalStatus &rhs)
void cmtool::CMergeBookKeeper::Report ( ) const

Definition at line 220 of file CMergeBookKeeper.cxx.

References _prohibit_merge.

Referenced by GetResult().

221  {
222  std::cout<<"Merge Result:"<<std::endl;
223  for(auto const& v : *this)
224  std::cout<<v<< " ";
225  std::cout<<std::endl<<std::endl;
226 
227  std::cout<<"Prohibit Status:"<<std::endl;
228  for(auto const &bs : _prohibit_merge) {
229 
230  for(auto const &b : bs) {
231 
232  if(b) std::cout<<"\033[93mT\033[00m ";
233  else std::cout<<"\033[95mF\033[00m ";
234 
235  }
236  std::cout<<std::endl;
237  }
238  std::cout<<std::endl;
239 
240  }
std::vector< std::vector< bool > > _prohibit_merge
void cmtool::CMergeBookKeeper::Reset ( unsigned short  nclusters = 0)

Reset method.

Definition at line 13 of file CMergeBookKeeper.cxx.

References _out_cluster_count, _prohibit_merge, and clear().

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

14  {
15  _prohibit_merge.clear();
16  _prohibit_merge.reserve(nclusters);
18  std::vector<unsigned short>::reserve(nclusters);
19 
20  for(size_t i=0; i<nclusters; ++i) {
21  this->push_back(i);
22  _prohibit_merge.push_back(std::vector<bool>(nclusters-i,false));
23  }
24  _out_cluster_count = nclusters;
25 
26  }
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 102 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 99 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: