LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CBAlgoShortestDistNonEndPoint.cxx
Go to the documentation of this file.
1 #ifndef CBALGOSHORTESTDISTNONENDPOINT_CXX
2 #define CBALGOSHORTESTDISTNONENDPOINT_CXX
3 
5 
6 namespace cmtool {
7 
8 
10 
11  //this just sets default values
12  SetVerbose(true);
13  SetDebug(false);
14  SetMinHits(0);
15 
16  //1e9 is huge; everything will be merged
18 
19  _min_distance_unit = 1.e-3;
20  } //end constructor
21 
22  bool CBAlgoShortestDistNonEndpoint::Bool(const ::cluster::ClusterParamsAlg &cluster1,
23  const ::cluster::ClusterParamsAlg &cluster2)
24  {
25 
26  //if number of hits not large enough skip
27  if ( (_minHits > 0) and ((cluster1.GetParams().N_Hits < _minHits) or (cluster2.GetParams().N_Hits < _minHits)) ) {
28  if (_debug) { std::cout << "Num of Hits below threshold..." << std::endl; }
29  return false;
30  }
31 
32  double w_start1 = cluster1.GetParams().start_point.w;
33  double t_start1 = cluster1.GetParams().start_point.t;
34  double w_end1 = cluster1.GetParams().end_point.w;
35  double t_end1 = cluster1.GetParams().end_point.t;
36 
37  double w_start2 = cluster2.GetParams().start_point.w;
38  double t_start2 = cluster2.GetParams().start_point.t;
39  double w_end2 = cluster2.GetParams().end_point.w;
40  double t_end2 = cluster2.GetParams().end_point.t;
41 
42  if (_debug){
43  std::cout << "Start point Cluster 1: (" << w_start1 << ", " << t_start1 << ")" << std::endl;
44  std::cout << "End point Cluster 2: (" << w_end1 << ", " << t_end1 << ")" << std::endl;
45  std::cout << "Start point Cluster 1: (" << w_start2 << ", " << t_start2 << ")" << std::endl;
46  std::cout << "End point Cluster 2: (" << w_end2 << ", " << t_end2 << ")" << std::endl;
47  }
48 
49  //First, pretend the first cluster is a 2D line segment, from its start point to end point
50  //Find the shortest distance between start point of the second cluster to this line segment.
51  //Repeat for end point of second cluster to this line segment.
52  //Then, pretend second cluster is a 2D line segment, from its start point to end point.
53  //Find the shortest distance between start point of the first cluster to this line segment.
54  //Repeat for end point of first cluster to this line segment.
55  //If the shortest of these four distances is less than the cutoff,
56  //return true (the clusters are merge-compatible). else, return false.
57 
58  // Step 1: inspect (w_start1, t_start1) vs. line (w_start2, t_start2) => (w_end2, t_end2)
59  double shortest_distance2 = ShortestDistanceSquared(w_start1, t_start1,
60  w_start2, t_start2,
61  w_end2, t_end2);
62 
63  // Step 2: inspect (w_end1, t_end1) vs. line (w_start2, t_start2) => (w_end2, t_end2)
64  double shortest_distance2_tmp = ShortestDistanceSquared(w_end1, t_end1,
65  w_start2, t_start2,
66  w_end2, t_end2);
67 
68  shortest_distance2 = (shortest_distance2_tmp < shortest_distance2) ?
69  shortest_distance2_tmp : shortest_distance2;
70 
71  // Step 3: inspect (w_start2, t_start2) vs. line (w_start1, t_start1) => (w_end1, t_end1)
72  shortest_distance2_tmp = ShortestDistanceSquared(w_start2, t_start2,
73  w_start1, t_start1,
74  w_end1, t_end1);
75 
76  shortest_distance2 = (shortest_distance2_tmp < shortest_distance2) ?
77  shortest_distance2_tmp : shortest_distance2;
78 
79  // Step 4: inspect (w_end2, t_end2) vs. line (w_start1, t_start1) => (w_end1, t_end1)
80  shortest_distance2_tmp = ShortestDistanceSquared(w_end2, t_end2,
81  w_start1, t_start1,
82  w_end1, t_end1);
83 
84  shortest_distance2 = (shortest_distance2_tmp < shortest_distance2) ?
85  shortest_distance2_tmp : shortest_distance2;
86 
87  bool compatible = shortest_distance2 < _max_2D_dist2;
88 
89  if(_verbose) {
90 
91  if(compatible) std::cout<<Form(" Compatible in distance (%g).\n",shortest_distance2);
92  else std::cout<<Form(" NOT compatible in distance (%g).\n",shortest_distance2);
93 
94  }
95 
96  return compatible;
97 
98 
99  }//end Bool function
100 
101  double CBAlgoShortestDistNonEndpoint::ShortestDistanceSquared(double point_x, double point_y,
102  double start_x, double start_y,
103  double end_x, double end_y ) const {
104 
105  //This code finds the shortest distance between a point and a line segment.
106  //code based off sample from
107  //http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
108  //note to self: rewrite this with TVector2 and compare time differences...
109  //TVector2 code might be more understandable
110 
111  double distance_squared = 999999;
112 
113  // Line segment: from ("V") = (start_x, start_y) to ("W")=(end_x, end_y)
114  double length_squared = pow((end_x - start_x), 2) + pow((end_y - start_y), 2);
115 
116  // Treat the case start & end point overlaps
117  if(length_squared < _min_distance_unit) {
118  if(_verbose){
119  std::cout << std::endl;
120  std::cout << Form(" Provided very short line segment: (%g,%g) => (%g,%g)",
121  start_x,start_y,end_x,end_y) << std::endl;
122  std::cout << " Likely this means one of two clusters have start & end point identical." << std::endl;
123  std::cout << " Check the cluster output!" << std::endl;
124  std::cout << std::endl;
125  std::cout << Form(" At this time, the algorithm uses a point (%g,%g)",start_x,start_y) << std::endl;
126  std::cout << " to represent this cluster's location." << std::endl;
127  std::cout << std::endl;
128  }
129 
130  return (pow((point_x - start_x),2) + pow((point_y - start_y),2));
131  }
132 
133  //Find shortest distance between point ("P")=(point_x,point_y) to this line segment
134  double t = ( (point_x - start_x)*(end_x - start_x) + (point_y - start_y)*(end_y - start_y) ) / length_squared;
135 
136  //if(t<0.0) distance_squared = pow((point_x - start_x), 2) + pow((point_y - start_y), 2);
137 
138  //else if (t>1.0) distance_squared = pow((point_x - end_x), 2) + pow(point_y - end_y, 2);
139 
140  //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);
141 
142 
143  if(t>0.1 && t < 0.9) distance_squared = pow((point_x - (start_x + t*(end_x - start_x))), 2) + pow((point_y - (start_y + t*(end_y - start_y))),2);
144 
145 
146  return distance_squared;
147 
148  }//end ShortestDistanceSquared function
149 
150 }
151 #endif
double ShortestDistanceSquared(double point_x, double point_y, double start_x, double start_y, double end_x, double end_y) const
virtual bool Bool(const ::cluster::ClusterParamsAlg &cluster1, const ::cluster::ClusterParamsAlg &cluster2)
Overloaded (from CBoolAlgoBase) Bool function.
size_t _minHits
bool to suppress lots of output if you want
void SetMinHits(int n)
Set Minimum Number of Hits to consider Cluster.
void SetVerbose(bool on)
Method to set verbose mode.
double _min_distance_unit
Min Number of hits for cluster to be considered.
void SetSquaredDistanceCut(double d)
Method to set cut value in cm^2 for distance compatibility test.
double _max_2D_dist2
minimum distance b/t start and end point of cluster to use it
bool _debug
bool to suppress lots of output if you want
Class def header for a class CBAlgoShortestDistNonEndpoint.
void SetDebug(bool on)
Method to set debug mode.