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