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