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