LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CFAlgoWireOverlap.cxx
Go to the documentation of this file.
1 #ifndef RECOTOOL_CFALGOWIREOVERLAP_CXX
2 #define RECOTOOL_CFALGOWIREOVERLAP_CXX
3 
4 #include "CFAlgoWireOverlap.h"
5 #include <algorithm>
6 
7 namespace cmtool {
8 
9  //-------------------------------------------------------
11  //-------------------------------------------------------
12  {
14  _w2cm = geou.WireToCm();
15  _t2cm = geou.TimeToCm();
16  SetVerbose(false);
17  SetDebug(false);
18  SetUseAllPlanes(false); // Any plane combination OK
19  }
20 
21  //-----------------------------
23  //-----------------------------
24  {
25  }
26 
27  //----------------------------------------------------------------------------------------------
28  float CFAlgoWireOverlap::Float(const std::vector<const cluster::ClusterParamsAlg*> &clusters)
29  //----------------------------------------------------------------------------------------------
30  {
32  // Code-block by Kazu starts
33  // This ensures the algorithm works only if # clusters is > 2 (and not =2)
34  // You may take out this block if you want to allow matching using clusters from only 2 planes.
35  if (_UseAllPlanes) { if(clusters.size()==2) return -1; }
36  // Code-block by Kazu ends
37 
38  //This algorithm now works for 3 planes: find 3Dstart point from first 2 planes and find
39  //How well that agrees with 3rd plane's start point location.
40 
41  //So first, make sure clusters vector has more than 1 element.
42  //If not, return -1. Algorithm does not make sense
43  if ( clusters.size() == 1 )
44  return -1;
45 
46  if (_verbose) { std::cout << "Number of clusters taken into account: " << clusters.size() << std::endl; }
47 
48  //Nomenclature:
49  //Planes: U == 0; V == 1; Y == 2.
50 
51  //Get hits for all 3 clusters
52  std::vector<std::vector<util::PxHit> > Hits(3, std::vector<util::PxHit>());
53 
54  for (size_t c=0; c < clusters.size(); c++)
55  Hits.at( clusters.at(c)->Plane() ) = clusters.at(c)->GetHitVector();
56 
57  //std::vector<util::PxHit> hits0 = clusters.at(0)->GetHitVector();
58  //std::vector<util::PxHit> hits1 = clusters.at(1)->GetHitVector();
59  //std::vector<util::PxHit> hits2 = clusters.at(2)->GetHitVector();
60 
61  //Wire Range Vector. Entries 0,1,2 correspond to planes
62  std::vector<int> StartWires;
63  std::vector<int> EndWires;
64  //loop over number of planes and pre-fill StartWires and EndWires
65  for (int pl=0; pl < 3; pl++){
66  StartWires.push_back(9999);
67  EndWires.push_back(0);
68  }
69 
70  for (size_t h=0; h < Hits.size(); h++){
71  for ( auto& hit: Hits.at(h) ){
72  if ( Hits.at(h).size() == 0 ){
73  std::cout << "Need to insert fake hit ranges...";
74  }
75  else{
76  if ( int(hit.w / _w2cm) < StartWires.at(h) ) { StartWires.at(h) = int(hit.w / _w2cm); }
77  if ( int(hit.w / _w2cm) > EndWires.at(h) ) { EndWires.at(h) = int(hit.w / _w2cm); }
78  }
79  }//for all hits in range
80  }//for all hit-lists (i.e. for all clusters)
81 
82  //if one of the plane's wire-range is still [9999, 0] then replace it
83  //with min/max wire number from that plane
84  //This allows for easy 2-Plane matching: if we are ignoring one plane
85  //completely by giving the wire-range for the whole plane the intersection
86  //will effectively be the intersection of the other two planes
87  for (size_t h=0; h < Hits.size(); h++){
88  if ( StartWires.at(h) == 9999 ) { StartWires.at(h) = 1; }
89  if ( EndWires.at(h) == 0 ) { EndWires.at(h) = geo->Nwires(h)-1; }
90  }
91  /*
92  //Get Wire-Range for all 3 clusters
93  int startWire0 = 9999, endWire0 = 0;
94  int startWire1 = 9999, endWire1 = 0;
95  int startWire2 = 9999, endWire2 = 0;
96  for (auto& hit: hits0){
97  if ( int(hit.w / _w2cm) < startWire0 ) { startWire0 = int(hit.w / _w2cm); }
98  if ( int(hit.w / _w2cm) > endWire0 ) { endWire0 = int(hit.w / _w2cm); }
99  }
100  for (auto& hit: hits1){
101  if ( int(hit.w / _w2cm) < startWire1 ) { startWire1 = int(hit.w / _w2cm); }
102  if ( int(hit.w / _w2cm) > endWire1 ) { endWire1 = int(hit.w / _w2cm); }
103  }
104  for (auto& hit: hits2){
105  if ( int(hit.w / _w2cm) < startWire2 ) { startWire2 = int(hit.w / _w2cm); }
106  if ( int(hit.w / _w2cm) > endWire2 ) { endWire2 = int(hit.w / _w2cm); }
107  }
108  */
109  //Now get start & end points of all these wires
110  Double_t xyzStart0WireStart[3] = {0., 0., 0.}; //xyz array info of start point for smallest wire number on plane 0
111  Double_t xyzStart0WireEnd[3] = {0., 0., 0.};
112  Double_t xyzEnd0WireStart[3] = {0., 0., 0.};
113  Double_t xyzEnd0WireEnd[3] = {0., 0., 0.};
114  Double_t xyzStart1WireStart[3] = {0., 0., 0.}; //xyz array info of start point for smallest wire number on plane 1
115  Double_t xyzStart1WireEnd[3] = {0., 0., 0.};
116  Double_t xyzEnd1WireStart[3] = {0., 0., 0.};
117  Double_t xyzEnd1WireEnd[3] = {0., 0., 0.};
118  Double_t xyzStart2WireStart[3] = {0., 0., 0.}; //xyz array info of start point for smallest wire number on plane 2
119  Double_t xyzStart2WireEnd[3] = {0., 0., 0.};
120  Double_t xyzEnd2WireStart[3] = {0., 0., 0.};
121  Double_t xyzEnd2WireEnd[3] = {0., 0., 0.};
122 
123  if (_debug) {
124  std::cout << "Wire Ranges:" << std::endl;
125  std::cout << "U-Plane: [ " << StartWires.at(0) << ", " << EndWires.at(0) << "]" << std::endl;
126  std::cout << "V-Plane: [ " << StartWires.at(1) << ", " << EndWires.at(1) << "]" << std::endl;
127  std::cout << "Y-Plane: [ " << StartWires.at(2) << ", " << EndWires.at(2) << "]" << std::endl;
128  std::cout << std::endl;
129  }
130  /*
131  geo->WireEndPoints(0, StartWires.at(0), xyzStart0WireStart, xyzStart0WireEnd);
132  geo->WireEndPoints(0, EndWires.at(0), xyzEnd0WireStart, xyzEnd0WireEnd);
133  geo->WireEndPoints(1, StartWires.at(1), xyzStart1WireStart, xyzStart1WireEnd);
134  geo->WireEndPoints(1, EndWires.at(1), xyzEnd1WireStart, xyzEnd1WireEnd);
135  geo->WireEndPoints(2, StartWires.at(2), xyzStart2WireStart, xyzStart2WireEnd);
136  geo->WireEndPoints(2, EndWires.at(2), xyzEnd2WireStart, xyzEnd2WireEnd);
137  */
138  geo->WireEndPoints(0, 0, 0, StartWires.at(0), xyzStart0WireStart, xyzStart0WireEnd);
139  geo->WireEndPoints(0, 0, 0, EndWires.at(0), xyzEnd0WireStart, xyzEnd0WireEnd);
140  geo->WireEndPoints(0, 0, 1, StartWires.at(1), xyzStart1WireStart, xyzStart1WireEnd);
141  geo->WireEndPoints(0, 0, 1, EndWires.at(1), xyzEnd1WireStart, xyzEnd1WireEnd);
142  geo->WireEndPoints(0, 0, 2, StartWires.at(2), xyzStart2WireStart, xyzStart2WireEnd);
143  geo->WireEndPoints(0, 0, 2, EndWires.at(2), xyzEnd2WireStart, xyzEnd2WireEnd);
144 
145  //check that z-positions for plane2 are the same...if not error!
146  //if ( xyzStart2WireStart[2] != xyzStart2WireEnd[2] ) { std::cout << "Y-wire does not have same Z start and end..." << std::endl; }
147  double zMin = xyzStart2WireStart[2];
148  //if ( xyzEnd2WireStart[2] != xyzEnd2WireEnd[2] ) { std::cout << "Y-wire does not have same Z start and end..." << std::endl; }
149  double zMax = xyzEnd2WireStart[2];
150 
151  //Plane U == Plane 0
152  //Plane V == Plane 1
153  //Plane Y == Plane 2
154 
155  //Each line can be described by function y = s*z + b (x,y,z coordinates same as uBooNE coord.)
156  //Slopes known: Pl0 is +60 clockwise from vertical. Pl1 is -60, counterclockwise from vertical. Looking at TPC with beam from left
157  double slopeU = tan(30*3.14/180.);
158  double slopeV = tan(-30*3.14/180.);
159 
160  //Find intercepts:
161  double bUup = xyzStart0WireStart[1] - xyzStart0WireStart[2] * slopeU;
162  double bUdn = xyzEnd0WireStart[1] - xyzEnd0WireStart[2] * slopeU;
163  double bVdn = xyzStart1WireStart[1] - xyzStart1WireStart[2] * slopeV;
164  double bVup = xyzEnd1WireStart[1] - xyzEnd1WireStart[2] * slopeV;
165  //make sure we know which line is above which
166  if ( bUup < bUdn ) { std::cout << "Uup and Udn are mixed up!" << std::endl; }
167  if ( bVdn > bVup ) { std::cout << "Vup and Vdn are mixed up!" << std::endl; }
168  //Pl2 lines are vertical...slope is infinite and no intercept.
169 
170  //Find intercepts of U wire-ranges with Y plane (easy since vertical)
171  //For now assume wire-ranges go to infinity, worry about TPC constraints later
172 
173  //Plug in Y-plane zMin and zMax coordinates into equations for U/V wire lines
174  double VdnZmin = slopeV * zMin + bVdn;
175  double VdnZmax = slopeV * zMax + bVdn;
176  double VupZmin = slopeV * zMin + bVup;
177  double VupZmax = slopeV * zMax + bVup;
178  double UdnZmin = slopeU * zMin + bUdn;
179  double UdnZmax = slopeU * zMax + bUdn;
180  double UupZmin = slopeU * zMin + bUup;
181  double UupZmax = slopeU * zMax + bUup;
182 
183  if (_debug){
184  std::cout << "Y-Plane and U-Plane points [Z,Y]:" << std::endl;
185  std::cout << "\t\t[ " << zMin << ", " << UdnZmin << "]" << std::endl;
186  std::cout << "\t\t[ " << zMin << ", " << UupZmin << "]" << std::endl;
187  std::cout << "\t\t[ " << zMax << ", " << UupZmax << "]" << std::endl;
188  std::cout << "\t\t[ " << zMax << ", " << UdnZmax << "]" << std::endl;
189  std::cout << "Y-Plane and V-Plane points [Z,Y]:" << std::endl;
190  std::cout << "\t\t[ " << zMin << ", " << VdnZmin << "]" << std::endl;
191  std::cout << "\t\t[ " << zMin << ", " << VupZmin << "]" << std::endl;
192  std::cout << "\t\t[ " << zMax << ", " << VupZmax << "]" << std::endl;
193  std::cout << "\t\t[ " << zMax << ", " << VdnZmax << "]" << std::endl;
194  }
195  //We now have Two polygons:
196  //One is the intersection of Y-Plane wires with U-Plane wires
197  //The other the intersection of planes Y and V.
198  //The intersection points of these two polygons is the
199  //overall intersection Area of the 3 clusters on the Y-Z plane.
200 
201  //Go through all segment intersections. If one is found add to
202  //list of points.
203  //Create a list of points for polygon
204  std::vector< std::pair<float,float> > WireIntersection;
205  double zInt; // temporary holder for z-intersection point of oblique sides
206  //Check: Vup and Uup, Vup and Uright, Vup and Uleft, Vup and Udn.
207  //Intersection between Vup and Uup: if within zMin, zMax then ok!
208  zInt = (bUup-bVup)/(slopeV-slopeU);
209  if ( (zInt > zMin) and (zInt < zMax) )
210  WireIntersection.push_back( std::make_pair( zInt, slopeV*zInt+bVup ) );
211  //Intersection between Vup and Uright:
212  if ( (VupZmax < UupZmax) and (VupZmax > UdnZmax) )
213  WireIntersection.push_back( std::make_pair( zMax, VupZmax ) );
214  //Intersection between Vup and Uleft:
215  if ( (VupZmin < UupZmin) and ( VupZmin > UdnZmin) )
216  WireIntersection.push_back( std::make_pair( zMin, VupZmin ) );
217  //Intersection between Vup and Udn:
218  zInt = (bUdn-bVup)/(slopeV-slopeU);
219  if ( (zInt > zMin) and (zInt < zMax) )
220  WireIntersection.push_back( std::make_pair( zInt, slopeV*zInt+bVup ) );
221 
222  //Check: Vdn and Uup, Uright, Uleft, Udn:
223  //Intersection between Vdn and Uup:
224  zInt = (bUup-bVdn)/(slopeV-slopeU);
225  if ( (zInt > zMin) and (zInt < zMax) )
226  WireIntersection.push_back( std::make_pair( zInt, slopeV*zInt+bVdn ) );
227  //Intersection between Vdn and Uright:
228  if ( (VdnZmax < UupZmax) and (VdnZmax > UdnZmax) )
229  WireIntersection.push_back( std::make_pair( zMax, VdnZmax ) );
230  //Intersection between Vdn and Uleft:
231  if ( (VdnZmin < UupZmin) and ( VdnZmin > UdnZmin) )
232  WireIntersection.push_back( std::make_pair( zMin, VdnZmin ) );
233  //Intersection between Vdn and Udn:
234  zInt = (bUdn-bVdn)/(slopeV-slopeU);
235  if ( (zInt > zMin) and (zInt < zMax) )
236  WireIntersection.push_back( std::make_pair( zInt, slopeV*zInt+bVdn ) );
237 
238  //Check: Vright and Uup, Udn:
239  //Intersection between Vright and Uup:
240  if ( (UupZmax < VupZmax) and ( UupZmax > VdnZmax) )
241  WireIntersection.push_back( std::make_pair( zMax, UupZmax ) );
242  //Intersection between Vright and Udn:
243  if ( (UdnZmax < VupZmax) and ( UdnZmax > VdnZmax) )
244  WireIntersection.push_back( std::make_pair( zMax, UdnZmax ) );
245 
246  //Check Vleft and Uup, Udn:
247  //Intersection between Vleft and Uup:
248  if ( (UupZmin < VupZmin) and ( UupZmin > VdnZmin) )
249  WireIntersection.push_back( std::make_pair( zMin, UupZmin ) );
250  //Intersection between Vleft and Udn:
251  if ( (UdnZmin < VupZmin) and ( UdnZmin > VdnZmin) )
252  WireIntersection.push_back( std::make_pair( zMin, UdnZmin ) );
253 
254  //If length is 0 then no intersection...return -1
255  if ( WireIntersection.size() == 0 ){
256  if (_verbose) { std::cout << "No intersection..." << std::endl << std::endl; }
257  return -1;
258  }
259 
260  //Now our polygon is complete...
261  //need to disentangle in case points added in incorrect order
262  //then calculate area
263  Polygon2D WirePolygon(WireIntersection);
264  //Variable to hold final output Area
265  double PolyArea = -1;
266  //Check order
267  WirePolygon.UntanglePolygon();
268 
269  //Create a Polygon for the Y-Z TPC Plane
270  std::vector< std::pair<float,float> > TPCCorners;
271  TPCCorners.push_back( std::make_pair(0., -geo->DetHalfHeight()) );
272  TPCCorners.push_back( std::make_pair(geo->DetLength(), -geo->DetHalfHeight()) );
273  TPCCorners.push_back( std::make_pair(geo->DetLength(), geo->DetHalfHeight()) );
274  TPCCorners.push_back( std::make_pair(0., geo->DetHalfHeight()) );
275  Polygon2D TPCPolygon(TPCCorners);
276  if (TPCPolygon.Contained(WirePolygon) ){
277  if (_verbose) {
278  std::cout << "Wire Overlap contained in TPC" << std::endl;
279  std::cout << "Intersection Polygon Coordinates [Z,Y]: " << std::endl;
280  for (unsigned int s=0; s < WirePolygon.Size(); s++)
281  std::cout << "\t\t[ " << WirePolygon.Point(s).first << ", " << WirePolygon.Point(s).second << "]" << std::endl;
282  std::cout << std::endl;
283  }
284  PolyArea = WirePolygon.Area();
285  }
286  else {
287  if (_verbose) {
288  std::cout << "Wire overlap not fully contained in TPC" << std::endl;
289  std::cout << "Intersection Polygon Coordinates [Z,Y]: " << std::endl;
290  for (unsigned int s=0; s < WirePolygon.Size(); s++)
291  std::cout << "\t\t[ " << WirePolygon.Point(s).first << ", " << WirePolygon.Point(s).second << "]" << std::endl;
292  std::cout << std::endl;
293  }
294  //product polygon should be the intersection of WirePolygon and TPCPolygon
295  Polygon2D IntersectionPolygon(TPCPolygon, WirePolygon);
296  PolyArea = IntersectionPolygon.Area();
297  }
298 
299  //return polygon area -> larger = better!
300  if (_verbose) { std::cout << "Intersection area: " << PolyArea << std::endl << std::endl; }
301  return PolyArea;
302  }
303 
304  //------------------------------
306  //------------------------------
307  {
308 
309  }
310 
311 }
312 #endif
Float_t s
Definition: plot.C:23
float Area() const
Definition: Polygon2D.cxx:96
CFAlgoWireOverlap()
Default constructor.
void SetUseAllPlanes(bool on)
Function to set if _UseAllPlanes is on/off.
bool Contained(const Polygon2D &poly2) const
Definition: Polygon2D.cxx:271
Class def header for a class CFAlgoWireOverlap.
Double_t TimeToCm() const
const std::pair< float, float > & Point(unsigned int p) const
Definition: Polygon2D.cxx:135
Double_t WireToCm() const
unsigned int Size() const
Create Intersection Polygon.
Definition: Polygon2D.h:47
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
Detector simulation of raw signals on wires.
virtual float Float(const std::vector< const cluster::ClusterParamsAlg * > &clusters)
art::PtrVector< recob::Hit > Hits
virtual void Reset()
Function to reset the algorithm instance, called together with manager&#39;s Reset()
void WireEndPoints(geo::WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
void SetDebug(bool on)
Function to set debug output.
Namespace collecting geometry-related classes utilities.
void SetVerbose(bool on)
Function to set verbose output.
void UntanglePolygon()
check if poly2 is inside poly1
Definition: Polygon2D.cxx:286