CBAlgoCenterOfMass.cxx
Go to the documentation of this file.
1 #include "CBAlgoCenterOfMass.h"
2 
3 #include "TString.h"
4 
5 namespace cmtool {
6 
7  //----------------------------------------
9  //----------------------------------------
10  {
11 
12  SetDebug(false);
15  SetMaxDistance(20.);
16  SetLengthReach(3.0);
17  UseCOMInPoly(true);
18  UseCOMInCone(true);
19  UseCOMNearClus(true);
20 
21  }
22 
23  //---------------------------------------------------------------------------
24  bool CBAlgoCenterOfMass::Bool(const ::cluster::ClusterParamsAlg &cluster1,
25  const ::cluster::ClusterParamsAlg &cluster2)
26  //---------------------------------------------------------------------------
27  {
28 
29  int small = 0;
30  int hitssmall = 0;
31 
32  //determine if clusters ok and if so which is big and which is small
33  if ( (cluster1.GetHitVector().size() > _minHits) and (cluster2.GetHitVector().size() < _maxHits) )
34  small = 2;
35  else if ( (cluster2.GetHitVector().size() > _minHits) and (cluster1.GetHitVector().size() < _maxHits) )
36  small = 1;
37  else
38  return false;
39 
40  //Define COM values on w & t
41  double COM_t_s = 0;
42  double COM_w_s = 0;
43  double Q_s = 0;
44  //Define cone parameters
45  double opening_angle;
46  double direc_angle;
47  double length;
48  double start_w;
49  double start_t;
50  double end_w;
51  double end_t;
52  Polygon2D poly;
53 
54  //Get Hit vector for small cluster
55  //std::vector<util::PxHit> hitss;
56  std::vector<util::PxHit> hitss;
57  if ( small == 1 ){
58  hitss = cluster1.GetHitVector();
59  hitssmall = hitss.size();
60  direc_angle = cluster2.GetParams().angle_2d;
61  opening_angle = cluster2.GetParams().opening_angle * (180./3.14);
62  length = cluster2.GetParams().length;
63  start_w = cluster2.GetParams().start_point.w;
64  start_t = cluster2.GetParams().start_point.t;
65  end_w = cluster2.GetParams().end_point.w;
66  end_t = cluster2.GetParams().end_point.t;
67  poly = cluster2.GetParams().PolyObject;
68  }
69  if ( small == 2 ){
70  hitss = cluster2.GetHitVector();
71  hitssmall = hitss.size();
72  direc_angle = cluster1.GetParams().angle_2d;
73  opening_angle = cluster1.GetParams().opening_angle * (180./3.14);
74  length = cluster1.GetParams().length;
75  start_w = cluster1.GetParams().start_point.w;
76  start_t = cluster1.GetParams().start_point.t;
77  end_w = cluster1.GetParams().end_point.w;
78  end_t = cluster1.GetParams().end_point.t;
79  poly = cluster1.GetParams().PolyObject;
80  }
81 
82  if (_debug){
83  std::cout << "Big Cluster:" << std::endl;
84  std::cout << "\tOpening Angle: " << opening_angle << std::endl;
85  std::cout << "\tLength: " << length << std::endl;
86  std::cout << "\tStart Point: (" << start_w << ", " << end_w << ")" << std::endl;
87  std::cout << "\tDirection Angle: " << direc_angle << std::endl;
88  std::cout << std::endl;
89  }
90 
91  for (auto& hit: hitss){
92  COM_t_s += hit.t * hit.charge;
93  COM_w_s += hit.w * hit.charge;
94  Q_s += hit.charge;
95  }
96  COM_t_s /= Q_s;
97  COM_w_s /= Q_s;
98 
99  if (_debug) {
100  std::cout << "Small Cluster: " << std::endl;
101  std::cout << "N Hits: " << hitssmall << std::endl;
102  std::cout << "COM: (w,t) -> (" << COM_w_s << ", " << COM_t_s << ")" << std::endl;
103  std::cout << std::endl;
104  }
105 
106  //Get COM
107  std::pair<float,float> COM_s;
108  COM_s = std::make_pair( COM_w_s, COM_t_s );
109 
110  //Get rotate COM to see if in cone
111  double COM_w_rot = (COM_w_s - start_w)*cos(direc_angle*3.14/180.) + (COM_t_s - start_t)*sin(direc_angle*3.14/180.);
112  double COM_t_rot = - (COM_w_s - start_w)*sin(direc_angle*3.14/180.) + (COM_t_s - start_t)*cos(direc_angle*3.14/180.);
113 
114  //look for polygon overlap
115  if ( ( poly.PointInside(COM_s) ) and _COMinPolyAlg ){
116  if (_verbose) { std::cout << "Polygon Overlap -> Merge!" << std::endl << std::endl;}
117  return true;
118  }
119  //look for COM in cone
120  if ( _COMinConeAlg and
121  (COM_w_rot < length*_lengthReach ) and ( COM_w_rot > 0 ) and
122  ( abs(COM_t_rot) < abs(COM_w_rot*sin(opening_angle*3.14/180.)) ) ){
123  if (_verbose) { std::cout << "COM in Cone -> Merge! " << std::endl; }
124  return true;
125  }
126  //look for COM close to start-end of other cluster
127  if ( _COMNearClus and
128  ShortestDistanceSquared( COM_w_s, COM_t_s, start_w, start_t, end_w, end_t ) < _MaxDist ) {
129  if (_verbose) { std::cout << "COM close to start-end -> Merge!" << std::endl; }
130  return true;
131  }
132 
133  return false;
134  }
135 
136  //-----------------------
138  //-----------------------
139  {
140 
141  }
142 
143  double CBAlgoCenterOfMass::ShortestDistanceSquared(double point_x, double point_y,
144  double start_x, double start_y,
145  double end_x, double end_y ) const {
146 
147  //This code finds the shortest distance between a point and a line segment.
148  //code based off sample from
149  //http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
150  //note to self: rewrite this with TVector2 and compare time differences...
151  //TVector2 code might be more understandable
152 
153  double distance_squared = -1;
154 
155  // Line segment: from ("V") = (start_x, start_y) to ("W")=(end_x, end_y)
156  double length_squared = pow((end_x - start_x), 2) + pow((end_y - start_y), 2);
157 
158  // Treat the case start & end point overlaps
159  if(length_squared < 0.1) {
160  if(_verbose){
161  std::cout << std::endl;
162  std::cout << Form(" Provided very short line segment: (%g,%g) => (%g,%g)",
163  start_x,start_y,end_x,end_y) << std::endl;
164  std::cout << " Likely this means one of two clusters have start & end point identical." << std::endl;
165  std::cout << " Check the cluster output!" << std::endl;
166  std::cout << std::endl;
167  std::cout << Form(" At this time, the algorithm uses a point (%g,%g)",start_x,start_y) << std::endl;
168  std::cout << " to represent this cluster's location." << std::endl;
169  std::cout << std::endl;
170  }
171 
172  return (pow((point_x - start_x),2) + pow((point_y - start_y),2));
173  }
174 
175  //Find shortest distance between point ("P")=(point_x,point_y) to this line segment
176  double t = ( (point_x - start_x)*(end_x - start_x) + (point_y - start_y)*(end_y - start_y) ) / length_squared;
177 
178  if(t<0.0) distance_squared = pow((point_x - start_x), 2) + pow((point_y - start_y), 2);
179 
180  else if (t>1.0) distance_squared = pow((point_x - end_x), 2) + pow(point_y - end_y, 2);
181 
182  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);
183 
184  return distance_squared;
185 
186  }//end ShortestDistanceSquared function
187 
188 
189 }
constexpr T pow(T x)
Definition: pow.h:72
void SetLengthReach(double frac)
Set Length Reach: How for out the cone extends as percent of cluster length.
void SetMaxDistance(double d)
Function to set Max Distance for COM to be from start-end.
void UseCOMInCone(bool on)
Use COM in Poly algo to decide merging.
T abs(T value)
void UseCOMNearClus(bool on)
Use COM in Poly algo to decide merging.
void UseCOMInPoly(bool on)
Use COM in Poly algo to decide merging.
CBAlgoCenterOfMass()
Default constructor.
void SetDebug(bool on)
Function to set Debug mode of output.
Detector simulation of raw signals on wires.
void SetMaxHitsSmallClus(size_t n)
Function to set Max hits for small clsuters.
virtual bool Bool(const ::cluster::ClusterParamsAlg &cluster1, const ::cluster::ClusterParamsAlg &cluster2)
bool PointInside(const std::pair< float, float > &point) const
Definition: Polygon2D.cxx:252
Class def header for a class CBAlgoCenterOfMass.
double ShortestDistanceSquared(double point_x, double point_y, double start_x, double start_y, double end_x, double end_y) const
virtual void Report()
Function to report what&#39;s going on per merging iteration.
void SetMinHitsBigClus(size_t n)
Function to se Min hits for big clusters.
bool _verbose
Boolean to choose verbose mode. Turned on if CMergeManager/CMatchManager&#39;s verbosity level is >= kPer...
Definition: CMAlgoBase.h:102
bool _COMinPolyAlg
How four out - as percent of cluster length - cone will extend from start point.
QTextStream & endl(QTextStream &s)