LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CBAlgoCenterOfMassSmall.cxx
Go to the documentation of this file.
1 #ifndef RECOTOOL_CBALGOCENTEROFMASSSMALL_CXX
2 #define RECOTOOL_CBALGOCENTEROFMASSSMALL_CXX
3 
5 
6 namespace cmtool {
7 
8  //----------------------------------------
10  //----------------------------------------
11  {
12 
13  SetDebug(false);
15  SetMaxDistance(20.);
16  SetMaxCOMDistance(25.);
17  UseCOMInPoly(true);
18  UseCOMClose(true);
19  UseCOMNearClus(true);
20 
21  }
22 
23  //---------------------------------------------------------------------------
24  bool CBAlgoCenterOfMassSmall::Bool(const ::cluster::ClusterParamsAlg &cluster1,
25  const ::cluster::ClusterParamsAlg &cluster2)
26  //---------------------------------------------------------------------------
27  {
28 
29  int Nhits1 = 0;
30  int Nhits2 = 0;
31 
32  //Both clusters should have less hits than some threshold
33  if ( (cluster1.GetHitVector().size() > _maxHits) or (cluster2.GetHitVector().size() > _maxHits) )
34  return false;
35 
36  //Define COM values on w & t
37  double COM_t_1 = 0;
38  double COM_w_1 = 0;
39  double Q_1 = 0;
40  double start_w_1;
41  double start_t_1;
42  double end_w_1;
43  double end_t_1;
44  Polygon2D poly1;
45  double COM_t_2 = 0;
46  double COM_w_2 = 0;
47  double Q_2 = 0;
48  double start_w_2;
49  double start_t_2;
50  double end_w_2;
51  double end_t_2;
52  Polygon2D poly2;
53 
54  //Get Hit vector for cluster 1
55  //std::vector<util::PxHit> hits1;
56  std::vector<util::PxHit> hits1;
57  hits1 = cluster1.GetHitVector();
58  Nhits1 = hits1.size();
59  poly1 = cluster1.GetParams().PolyObject;
60  start_w_1 = cluster1.GetParams().start_point.w;
61  start_t_1 = cluster1.GetParams().start_point.t;
62  end_w_1 = cluster1.GetParams().end_point.w;
63  end_t_1 = cluster1.GetParams().end_point.t;
64  //Get Hit vector for cluster 2
65  //std::vector<util::PxHit> hits2;
66  std::vector<util::PxHit> hits2;
67  hits2 = cluster2.GetHitVector();
68  Nhits2 = hits2.size();
69  poly2 = cluster2.GetParams().PolyObject;
70  start_w_2 = cluster2.GetParams().start_point.w;
71  start_t_2 = cluster2.GetParams().start_point.t;
72  end_w_2 = cluster2.GetParams().end_point.w;
73  end_t_2 = cluster2.GetParams().end_point.t;
74 
75  //Find COM for cluster 1
76  for (auto& hit: hits1){
77  COM_t_1 += hit.t * hit.charge;
78  COM_w_1 += hit.w * hit.charge;
79  Q_1 += hit.charge;
80  }
81  COM_t_1 /= Q_1;
82  COM_w_1 /= Q_1;
83 
84  //Find COM for cluster 2
85  for (auto& hit: hits2){
86  COM_t_2 += hit.t * hit.charge;
87  COM_w_2 += hit.w * hit.charge;
88  Q_2 += hit.charge;
89  }
90  COM_t_2 /= Q_2;
91  COM_w_2 /= Q_2;
92 
93  if (_debug) {
94  std::cout << "Cluster 1: " << std::endl;
95  std::cout << "N Hits: " << Nhits1 << std::endl;
96  std::cout << "COM: (w,t) -> (" << COM_w_1 << ", " << COM_t_1 << ")" << std::endl;
97  std::cout << "Cluster 2: " << std::endl;
98  std::cout << "N Hits: " << Nhits2 << std::endl;
99  std::cout << "COM: (w,t) -> (" << COM_w_2 << ", " << COM_t_2 << ")" << std::endl;
100  std::cout << std::endl;
101  }
102 
103  //Get COM
104  std::pair<float,float> COM_1;
105  COM_1 = std::make_pair( COM_w_1, COM_t_1 );
106  std::pair<float,float> COM_2;
107  COM_2 = std::make_pair( COM_w_2, COM_t_2 );
108 
109  //look for polygon overlap
110  if ( ( ( poly2.PointInside(COM_1) ) and _COMinPolyAlg ) or
111  ( ( poly1.PointInside(COM_2) ) and _COMinPolyAlg ) ){
112  if (_verbose) { std::cout << "Polygon Overlap -> Merge!" << std::endl << std::endl;}
113  return true;
114  }
115 
116  //look for COM of 1 close to COM of 2
117  double distCOMs = ( COM_w_1-COM_w_2 )*( COM_w_1-COM_w_2 ) +
118  ( COM_t_1-COM_t_2 )*( COM_t_1-COM_t_2 );
119  if ( _COMsClose and ( distCOMs < _MaxCOMDistSquared ) ){
120  if (_verbose) { std::cout << "COMs close to each other -> Merge!" << std::endl << std::endl;}
121  return true;
122  }
123 
124  //look for COM close to start-end of other cluster
125  if ( _COMNearClus and
126  ( ( ShortestDistanceSquared( COM_w_1, COM_t_1, start_w_2, start_t_2, end_w_2, end_t_2 ) < _MaxDist ) or
127  ( ShortestDistanceSquared( COM_w_2, COM_t_2, start_w_1, start_t_1, end_w_1, end_t_1 ) < _MaxDist ) ) ) {
128  if (_verbose) { std::cout << "COM close to start-end -> Merge!" << std::endl; }
129  return true;
130  }
131 
132  return false;
133  }
134 
135  //-----------------------
137  //-----------------------
138  {
139 
140  }
141 
142  double CBAlgoCenterOfMassSmall::ShortestDistanceSquared(double point_x, double point_y,
143  double start_x, double start_y,
144  double end_x, double end_y ) const {
145 
146  //This code finds the shortest distance between a point and a line segment.
147  //code based off sample from
148  //http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
149  //note to self: rewrite this with TVector2 and compare time differences...
150  //TVector2 code might be more understandable
151 
152  double distance_squared = -1;
153 
154  // Line segment: from ("V") = (start_x, start_y) to ("W")=(end_x, end_y)
155  double length_squared = pow((end_x - start_x), 2) + pow((end_y - start_y), 2);
156 
157  // Treat the case start & end point overlaps
158  if(length_squared < 0.1) {
159  if(_verbose){
160  std::cout << std::endl;
161  std::cout << Form(" Provided very short line segment: (%g,%g) => (%g,%g)",
162  start_x,start_y,end_x,end_y) << std::endl;
163  std::cout << " Likely this means one of two clusters have start & end point identical." << std::endl;
164  std::cout << " Check the cluster output!" << std::endl;
165  std::cout << std::endl;
166  std::cout << Form(" At this time, the algorithm uses a point (%g,%g)",start_x,start_y) << std::endl;
167  std::cout << " to represent this cluster's location." << std::endl;
168  std::cout << std::endl;
169  }
170 
171  return (pow((point_x - start_x),2) + pow((point_y - start_y),2));
172  }
173 
174  //Find shortest distance between point ("P")=(point_x,point_y) to this line segment
175  double t = ( (point_x - start_x)*(end_x - start_x) + (point_y - start_y)*(end_y - start_y) ) / length_squared;
176 
177  if(t<0.0) distance_squared = pow((point_x - start_x), 2) + pow((point_y - start_y), 2);
178 
179  else if (t>1.0) distance_squared = pow((point_x - end_x), 2) + pow(point_y - end_y, 2);
180 
181  else distance_squared = pow((point_x - (start_x + t*(end_x - start_x))), 2) + pow((point_y - (start_y + t*(end_y - start_y))),2);
182 
183  return distance_squared;
184 
185  }//end ShortestDistanceSquared function
186 
187 
188 
189 
190 }
191 
192 #endif
bool _COMinPolyAlg
How four out - as percent of cluster length - cone will extend from start point.
virtual bool Bool(const ::cluster::ClusterParamsAlg &cluster1, const ::cluster::ClusterParamsAlg &cluster2)
void SetMaxCOMDistance(double d)
Function to set Max Distance between COMs.
virtual void Report()
Function to report what&#39;s going on per merging iteration.
double ShortestDistanceSquared(double point_x, double point_y, double start_x, double start_y, double end_x, double end_y) const
void UseCOMClose(bool on)
Use COM in Poly algo to decide merging.
CBAlgoCenterOfMassSmall()
Default constructor.
Detector simulation of raw signals on wires.
Class def header for a class CBAlgoCenterOfMassSmall.
void SetMaxDistance(double d)
Function to set Max Distance for COM to be from start-end.
void UseCOMInPoly(bool on)
Use COM in Poly algo to decide merging.
void SetDebug(bool on)
Function to set Debug mode of output.
void UseCOMNearClus(bool on)
Use COM in Poly algo to decide merging.
bool PointInside(const std::pair< float, float > &point) const
Definition: Polygon2D.cxx:249
void SetMaxHitsSmallClus(size_t n)
Function to set Max hits for small clsuters.
bool _verbose
Boolean to choose verbose mode. Turned on if CMergeManager/CMatchManager&#39;s verbosity level is >= kPer...
Definition: CMAlgoBase.h:88