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