LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
CBAlgoCenterOfMass.cxx
Go to the documentation of this file.
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  bool CBAlgoCenterOfMass::Bool(const ::cluster::ClusterParamsAlg& cluster1,
24  const ::cluster::ClusterParamsAlg& cluster2)
25  //---------------------------------------------------------------------------
26  {
27 
28  int small = 0;
29  int hitssmall = 0;
30 
31  //determine if clusters ok and if so which is big and which is small
32  if ((cluster1.GetHitVector().size() > _minHits) and (cluster2.GetHitVector().size() < _maxHits))
33  small = 2;
34  else if ((cluster2.GetHitVector().size() > _minHits) and
35  (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.) +
112  (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.) +
114  (COM_t_s - start_t) * cos(direc_angle * 3.14 / 180.);
115 
116  //look for polygon overlap
117  if ((poly.PointInside(COM_s)) and _COMinPolyAlg) {
118  if (_verbose) { std::cout << "Polygon Overlap -> Merge!" << std::endl << std::endl; }
119  return true;
120  }
121  //look for COM in cone
122  if (_COMinConeAlg and (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 
143  double point_y,
144  double start_x,
145  double start_y,
146  double end_x,
147  double end_y) const
148  {
149 
150  //This code finds the shortest distance between a point and a line segment.
151  //code based off sample from
152  //http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
153  //note to self: rewrite this with TVector2 and compare time differences...
154  //TVector2 code might be more understandable
155 
156  double distance_squared = -1;
157 
158  // Line segment: from ("V") = (start_x, start_y) to ("W")=(end_x, end_y)
159  double length_squared = pow((end_x - start_x), 2) + pow((end_y - start_y), 2);
160 
161  // Treat the case start & end point overlaps
162  if (length_squared < 0.1) {
163  if (_verbose) {
164  std::cout << std::endl;
165  std::cout << Form(" Provided very short line segment: (%g,%g) => (%g,%g)",
166  start_x,
167  start_y,
168  end_x,
169  end_y)
170  << std::endl;
171  std::cout << " Likely this means one of two clusters have start & end point identical."
172  << std::endl;
173  std::cout << " Check the cluster output!" << std::endl;
174  std::cout << std::endl;
175  std::cout << Form(" At this time, the algorithm uses a point (%g,%g)", start_x, start_y)
176  << std::endl;
177  std::cout << " to represent this cluster's location." << std::endl;
178  std::cout << std::endl;
179  }
180 
181  return (pow((point_x - start_x), 2) + pow((point_y - start_y), 2));
182  }
183 
184  //Find shortest distance between point ("P")=(point_x,point_y) to this line segment
185  double t = ((point_x - start_x) * (end_x - start_x) + (point_y - start_y) * (end_y - start_y)) /
186  length_squared;
187 
188  if (t < 0.0)
189  distance_squared = pow((point_x - start_x), 2) + pow((point_y - start_y), 2);
190 
191  else if (t > 1.0)
192  distance_squared = pow((point_x - end_x), 2) + pow(point_y - end_y, 2);
193 
194  else
195  distance_squared = pow((point_x - (start_x + t * (end_x - start_x))), 2) +
196  pow((point_y - (start_y + t * (end_y - start_y))), 2);
197 
198  return distance_squared;
199 
200  } //end ShortestDistanceSquared function
201 
202 }
void SetLengthReach(double frac)
Set Length Reach: How for out the cone extends as percent of cluster length.
constexpr auto abs(T v)
Returns the absolute value of the argument.
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:271
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:82
bool _COMinPolyAlg
How four out - as percent of cluster length - cone will extend from start point.