LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
GeometryUtilities.cxx
Go to the documentation of this file.
1 // \file GeometryUtilities.cxx
3 //
4 // \brief Functions to calculate distances and angles in 3D and 2D
5 //
6 // andrzej.szelc@yale.edu
7 //
9 
10 
17 //#include "PxHitConverter.h"
18 
19 
20 namespace {
21  template <typename T>
22  inline T sqr(T v) { return v*v; }
23 
24  template <typename T>
25  inline T sum_sqr(T a, T b) { return sqr(a) + sqr(b); }
26 
27 } // local namespace
28 
29 
30 namespace util{
31 
33 
34  //--------------------------------------------------------------------
36  {
37  //_name = "GeometryUtilities";
38  geom = lar::providerFrom<geo::Geometry>();
39  detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
40 
41  Reconfigure();
42  }
43 
45  {
46  /*
47  geom = (util::Geometry*)(util::Geometry::GetME());
48  detp = (util::DetectorProperties*)(util::DetectorProperties::GetME());
49  */
50 
51  fNPlanes = geom->Nplanes();
52  vertangle.resize(fNPlanes);
53  for(UInt_t ip=0;ip<fNPlanes;ip++)
54  vertangle[ip]=geom->Plane(ip).Wire(0).ThetaZ(false)-TMath::Pi()/2.; // wire angle
55  //vertangle[ip]=geom->WireAngleToVertical(geom->PlaneToView(ip)) - TMath::Pi()/2; // wire angle
56 
58  fTimeTick=detp->SamplingRate()/1000.;
60 
64  }
65 
66 
67  //--------------------------------------------------------------------
69  {
70 
71  }
72 
73 
74  //-----------------------------------------------------------------------------
75  // omega0 and omega1 (calculated by CPAN in degrees):
76  // angle based on distances in wires and time - rescaled to cm.
77  // tan(angle)*fMean_wire_pitch/(fTimeTick*fDriftVelocity);
78  // as those calculated with Get2Dangle
79  // writes phi and theta in degrees.
81  Int_t GeometryUtilities::Get3DaxisN(Int_t iplane0,
82  Int_t iplane1,
83  Double_t omega0,
84  Double_t omega1,
85  Double_t &phi,
86  Double_t &theta) const
87  {
88 
89  //Double_t l(0),m(0),n(0);
90  //Double_t phin(0);//,phis(0),thetan(0);
91 
92  // y, z, x coordinates
93  Double_t ln(0),mn(0),nn(0);
94  Double_t phis(0),thetan(0);
95 
96  // Pretend collection and induction planes.
97  // "Collection" is the plane with the vertical angle equal to zero.
98  // If both are non-zero, collection is the one with the negative angle.
99  UInt_t Cplane=0,Iplane=1;
100 
101  // angleC and angleI are the respective angles to vertical in C/I
102  // planes and slopeC, slopeI are the tangents of the track.
103  Double_t angleC,angleI,slopeC,slopeI,omegaC,omegaI;
104  omegaC = kINVALID_DOUBLE;
105  omegaI = kINVALID_DOUBLE;
106 
107  // Don't know how to reconstruct these yet, so exit with error.
108  // In
109  if(omega0==0 || omega1==0){
110  phi=0;
111  theta=-999;
112  return -1;
113  }
114 
116 
117  //check if backwards going track
118  //Double_t backwards=0;
119  Double_t alt_backwards=0;
120 
122  /*
123  if(fabs(omega0)>(TMath::Pi()/2.0) && fabs(omega1)>(TMath::Pi()/2.0) ) {
124  backwards=1;
125  }
126  */
127 
128  if(fabs(omega0)>(TMath::Pi()/2.0) || fabs(omega1)>(TMath::Pi()/2.0) ) {
129  alt_backwards=1;
130  }
131 
132 
133 
134  if(vertangle[iplane0] == 0){
135  // first plane is at 0 degrees
136  Cplane=iplane0;
137  Iplane=iplane1;
138  omegaC=omega0;
139  omegaI=omega1;
140  }
141  else if(vertangle[iplane1] == 0){
142  // second plane is at 0 degrees
143  Cplane = iplane1;
144  Iplane = iplane0;
145  omegaC=omega1;
146  omegaI=omega0;
147  }
148  else if(vertangle[iplane0] != 0 && vertangle[iplane1] != 0){
149  //both planes are at non zero degree - find the one with deg<0
150  if(vertangle[iplane1] < vertangle[iplane0]){
151  Cplane = iplane1;
152  Iplane = iplane0;
153  omegaC=omega1;
154  omegaI=omega0;
155  }
156  else if(vertangle[iplane1] > vertangle[iplane0]){
157  Cplane = iplane0;
158  Iplane = iplane1;
159  omegaC=omega0;
160  omegaI=omega1;
161  }
162  else{
163  //throw error - same plane.
164  return -1;
165  }
166 
167  }
168 
169  slopeC=tan(omegaC);
170  slopeI=tan(omegaI);
171  angleC=vertangle[Cplane];
172  angleI=vertangle[Iplane];
173 
174 
175  // l = 1;
176  // m = (1/(2*sin(angleI)))*((cos(angleI)/(slopeC*cos(angleC)))-(1/slopeI)
177  // +nfact*( cos(angleI)/slopeC-1/slopeI ) );
178  // n = (1/(2*cos(angleC)))*((1/slopeC)+(1/slopeI) +nfact*((1/slopeC)-(1/slopeI)));
179 
180 
181  //0 -1 factor depending on if one of the planes is vertical.
182  bool nfact = !(vertangle[Cplane]);
183 
184  //ln represents y, omega is 2d angle -- in first 2 quadrants y is positive.
185  if(omegaC < TMath::Pi() && omegaC > 0 )
186  ln=1;
187  else
188  ln=-1;
189 
190  //calculate x and z using y ( ln )
191  mn = (ln/(2*sin(angleI)))*((cos(angleI)/(slopeC*cos(angleC)))-(1/slopeI)
192  +nfact*( cos(angleI)/(cos(angleC)*slopeC)-1/slopeI ) );
193 
194  nn = (ln/(2*cos(angleC)))*((1/slopeC)+(1/slopeI) +nfact*((1/slopeC)-(1/slopeI)));
195 
196  // std::cout << " slopes, C:"<< slopeC << " " << (omegaC) << " I:" << slopeI << " " << omegaI <<std::endl;
197  // std::cout << "omegaC, angleC " << omegaC << " " << angleC << "cond: " << omegaC-angleC << " ln: " << ln << std::endl;
198  // std::cout << " inverse slopes: " << (cos(angleI)/(slopeC*cos(angleC))) << " " << 1/slopeC << " 2: "<< 1/slopeI << std::endl;
199 
200  // float Phi;
201  // float alt_Phi;
202 
203 
204  // Direction angles
205  if(fabs(omegaC)>0.01) // catch numeric error values
206  {
207  //phi=atan(ln/nn);
208  phis=asin(ln/TMath::Sqrt(ln*ln+nn*nn));
209 
210  if(fabs(slopeC+slopeI) < 0.001)
211  phis=0;
212  else if( fabs(omegaI)>0.01 && (omegaI/fabs(omegaI) == -omegaC/fabs(omegaC) )
213  && ( fabs(omegaC) < 1*TMath::Pi()/180 || fabs(omegaC) > 179*TMath::Pi()/180 ) ) // angles have
214  phis = (fabs(omegaC) > TMath::Pi()/2) ? TMath::Pi() : 0; //angles are
215 
216 
217  if(nn<0 && phis>0 && !(!alt_backwards && fabs(phis)<TMath::Pi()/4 ) ) // do not go back if track looks forward and phi is forward
218  phis=(TMath::Pi())-phis;
219  else if(nn<0 && phis<0 && !(!alt_backwards && fabs(phis)<TMath::Pi()/4 ) )
220  phis=(-TMath::Pi())-phis;
221 
222 
223  phi=phis*180/TMath::Pi();
224 
225  // solve the ambiguities due to tangent periodicity
226 // Phi = phi > 0. ? (TMath::Pi()/2)-phi : fabs(phi)-(TMath::Pi()/2) ;
227 // alt_Phi = phi > 0. ? (TMath::Pi()/2)-phi : fabs(phi)-(TMath::Pi()/2) ;
228 //
229 // if(backwards==1){
230 // if(Phi<0){ Phi=Phi+TMath::Pi();}
231 // else if(Phi>0){Phi=Phi-TMath::Pi();}
232 // }
233 //
234 // bool alt_condition=( ( fabs(omegaC)>0.75*TMath::Pi() && fabs(omegaI)>0.166*TMath::Pi() )|| ( fabs(omegaI)>0.75*TMath::Pi() && fabs(omegaC)>0.166*TMath::Pi() ) );
235 //
236 //
237 // if((alt_backwards==1 && alt_condition) || backwards==1 ){
238 // if(alt_Phi<0){alt_Phi=alt_Phi+TMath::Pi();}
239 // else if(alt_Phi>0){alt_Phi=alt_Phi-TMath::Pi();}
240 // }
241 
242  }
243  //If plane2 (collection), phi = 2d angle (omegaC in this case)
244  else
245  {
246  phis = omegaC;
247  phi = omegaC;
248  }
249 
250  thetan = -asin ( mn / (sqrt(pow(ln,2)+pow(mn,2)+pow(nn,2)) ) ) ;
251  theta=thetan*180/TMath::Pi();
252 
253 // theta = acos( mn / (sqrt(pow(ln,2)+pow(mn,2)+pow(nn,2)) ) ) ;
254 // Double_t thetah = acos( mn / (sqrt(pow(l,2)+pow(mn,2)+pow(nn,2)) ) ) ;
255 // float Theta;
256 // float alt_Theta = 0.;
257 
258 // std::cout << " thetan " << mn << " " << (sqrt(pow(ln,2)+pow(mn,2)+pow(nn,2)) ) << " " << mn / (sqrt(pow(ln,2)+pow(mn,2)+pow(nn,2)) ) << std::endl;
259 // if(Phi < 0)Theta = (TMath::Pi()/2)-theta;
260 // if(Phi > 0)Theta = theta-(TMath::Pi()/2);
261 // if(alt_Phi < 0)alt_Theta = (TMath::Pi()/2)-theta;
262 // if(alt_Phi > 0)alt_Theta = theta-(TMath::Pi()/2);
263 
264  /*
265  std::cout << "++++++++ GeomUtil old " << Phi*180/TMath::Pi() << " " << Theta*180/TMath::Pi() << std::endl;
266  std::cout << "++++++++ GeomUtil_angles ALT: Phi: " << alt_Phi*180/TMath::Pi() << " Theta: " << alt_Theta*180/TMath::Pi() << std::endl;
267  std::cout << "++++++++ GeomUtil_new_angles Sine: Phi: " << phis*180/TMath::Pi() << " Theta: " << thetan*180/TMath::Pi() << std::endl;
268  */
269 
270  return 0;
271 
272 }
273 
275  //Calculate theta in case phi~0
276  //returns theta in angles
279  Int_t iplane1,
280  Double_t dw0,
281  Double_t dw1) const
282  {
283 
284  Double_t splane,lplane; // plane in which the track is shorter and longer.
285  Double_t sdw,ldw;
286 
287  if(dw0==0 && dw1==0)
288  return -1;
289 
290  if(dw0 >= dw1 ) {
291  lplane=iplane0;
292  splane=iplane1;
293  ldw=dw0;
294  sdw=dw1;
295  }
296  else {
297  lplane=iplane1;
298  splane=iplane0;
299  ldw=dw1;
300  sdw=dw0;
301  }
302 
303  Double_t top=(std::cos(vertangle[splane])-std::cos(vertangle[lplane])*sdw/ldw);
304  Double_t bottom = tan(vertangle[lplane]*std::cos(vertangle[splane]) );
305  bottom -= tan(vertangle[splane]*std::cos(vertangle[lplane]) )*sdw/ldw;
306 
307  Double_t tantheta=top/bottom;
308 
309  return atan(tantheta)*vertangle[lplane]/std::abs(vertangle[lplane])*180./TMath::Pi();
310  }
311 
313  //Calculate 3D pitch in beam coordinates
314  //
316  Double_t GeometryUtilities::CalculatePitch(UInt_t iplane,
317  Double_t phi,
318  Double_t theta) const
319  {
320 
321  Double_t pitch = -1.;
322 
323  if(geom->Plane(iplane).View() == geo::kUnknown ||
324  geom->Plane(iplane).View() == geo::k3D){
325  mf::LogError(
326  Form("Warning : no Pitch foreseen for view %d", geom->Plane(iplane).View()));
327  return pitch;
328  }
329  else{
330 
331  Double_t pi=TMath::Pi();
332 
333  Double_t fTheta=pi/2-theta;
334 
335  Double_t fPhi=-(phi+pi/2);
336  //Double_t fPhi=pi/2-phi;
337  //if(fPhi<0)
338  // fPhi=phi-pi/2;
339 
340  //fTheta=TMath::Pi()/2;
341 
342 
343 
344  for(UInt_t i = 0; i < geom->Nplanes(); ++i) {
345  if(i == iplane){
346  Double_t wirePitch = geom->WirePitch(i);
347  Double_t angleToVert =0.5*TMath::Pi() - geom->WireAngleToVertical(geom->Plane(i).View());
348 
349  // // //std::cout <<" %%%%%%%%%% " << i << " angle "
350  // << angleToVert*180/pi << " "
351  // << geom->Plane(i).Wire(0).ThetaZ(false)*180/pi
352  // <<" wirePitch " << wirePitch
353  // <<"\n %%%%%%%%%% " << fTheta << " " << fPhi<< std::endl;
354  //
355 
356  Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*TMath::Cos(fTheta)
357  +TMath::Cos(angleToVert)*TMath::Sin(fTheta)*TMath::Sin(fPhi));
358 
359  if (cosgamma>0) pitch = wirePitch/cosgamma;
360  } // end if the correct view
361  } // end loop over planes
362  } // end if a reasonable view
363 
364  return pitch;
365  }
366 
367 
368 
370  //Calculate 3D pitch in polar coordinates
371  //
374  Double_t phi,
375  Double_t theta) const
376  {
377 
378  Double_t pitch = -1.;
379 
380  if(geom->Plane(iplane).View() == geo::kUnknown ||
381  geom->Plane(iplane).View() == geo::k3D){
382  mf::LogError(
383  Form("Warning : no Pitch foreseen for view %d", geom->Plane(iplane).View()));
384  return pitch;
385  }
386  else{
387 
388  Double_t fTheta=theta;
389  Double_t fPhi=phi;
390 
391 
392  //fTheta=TMath::Pi()/2;
393 
394 
395 
396  for(UInt_t i = 0; i < geom->Nplanes(); ++i){
397  if(i == iplane){
398  Double_t wirePitch = geom->WirePitch(i);
399  Double_t angleToVert =0.5*TMath::Pi() - geom->WireAngleToVertical(geom->Plane(i).View());
400 
401  // //std::cout <<" %%%%%%%%%% " << i << " angle "
402  // << angleToVert*180/pi << " "
403  // << geom->Plane(i).Wire(0).ThetaZ(false)*180/pi
404  // <<" wirePitch " << wirePitch
405  // <<"\n %%%%%%%%%% " << fTheta << " " << fPhi<< std::endl;
406 
407 
408  Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*TMath::Cos(fTheta)
409  +TMath::Cos(angleToVert)*TMath::Sin(fTheta)*TMath::Sin(fPhi));
410 
411  if (cosgamma>0) pitch = wirePitch/cosgamma;
412  } // end if the correct view
413  } // end loop over planes
414  } // end if a reasonable view
415 
416  return pitch;
417  }
418 
419 
420 
421 
423  //Calculate 2D slope
424  // in "cm" "cm" coordinates
426  Double_t GeometryUtilities::Get2Dslope(Double_t wireend,
427  Double_t wirestart,
428  Double_t timeend,
429  Double_t timestart) const
430  {
431 
432  return GeometryUtilities::Get2Dslope((wireend-wirestart)*fWiretoCm,(timeend-timestart)*fTimetoCm);
433 
434  }
435 
437  //Calculate 2D slope
438  // in "cm" "cm" coordinates
441  const util::PxPoint *startpoint) const
442  {
443  return Get2Dslope(endpoint->w - startpoint->w,endpoint->t - startpoint->t);
444 
445  }
446 
448  //Calculate 2D slope
449  // in wire time coordinates coordinates
450  //
452  Double_t GeometryUtilities::Get2Dslope(Double_t dwire,
453  Double_t dtime) const
454  {
455 
456  //return omega;
457 
458  return tan(Get2Dangle(dwire,dtime))/fWireTimetoCmCm;
459 
460  }
461 
462 
464  //Calculate 2D angle
465  // in "cm" "cm" coordinates
467  Double_t GeometryUtilities::Get2Dangle(Double_t wireend,
468  Double_t wirestart,
469  Double_t timeend,
470  Double_t timestart) const
471  {
472 
473  return Get2Dangle((wireend-wirestart)*fWiretoCm,(timeend-timestart)*fTimetoCm);
474 
475  }
476 
478  //Calculate 2D angle
479  // in "cm" "cm" coordinates, endpoint and startpoint are assumed to be in cm/cm space
482  const util::PxPoint *startpoint) const
483  {
484  return Get2Dangle(endpoint->w - startpoint->w, endpoint->t - startpoint->t);
485 
486  }
487 
489  //Calculate 2D angle
490  // in "cm" "cm" coordinates
492  Double_t GeometryUtilities::Get2Dangle(Double_t dwire,
493  Double_t dtime) const
494  {
495 
496 
497  Double_t BC,AC;
498  Double_t omega;
499 
500  BC = ((Double_t)dwire); // in cm
501  AC = ((Double_t)dtime); //in cm
502  omega = std::asin( AC/std::sqrt(pow(AC,2)+pow(BC,2)) );
503  if(BC<0) // for the time being. Will check if it works for AC<0
504  {
505  if(AC>0){
506  omega= TMath::Pi()-std::abs(omega); //
507  }
508  else if(AC<0){
509  omega=-TMath::Pi()+std::abs(omega);
510  }
511  else {
512  omega=TMath::Pi();
513  }
514  }
515  //return omega;
516  return omega; //*fWirePitch/(fTimeTick*fDriftVelocity);
517 
518  }
519 
520  //accepting phi and theta in degrees
521  // returning in radians.
522 
523  double GeometryUtilities::Get2DangleFrom3D(unsigned int plane,double phi, double theta) const
524  {
525  TVector3 dummyvector(cos(theta*TMath::Pi()/180.)*sin(phi*TMath::Pi()/180.) ,sin(theta*TMath::Pi()/180.) , cos(theta*TMath::Pi()/180.)*cos(phi*TMath::Pi()/180.));
526 
527  return Get2DangleFrom3D(plane,dummyvector);
528 
529  }
530 
531 
532  // accepting TVector3
533  // returning in radians as is customary,
534 
535  double GeometryUtilities::Get2DangleFrom3D(unsigned int plane,TVector3 dir_vector) const
536  {
537  double alpha= 0.5*TMath::Pi()-geom->WireAngleToVertical(geom->Plane(plane).View());
538  // create dummy xyz point in middle of detector and another one in unit length.
539  // calculate correspoding points in wire-time space and use the differnces between those to return 2D a
540  // angle
541 
542 
543  TVector3 start(geom->DetHalfWidth(),0.,geom->DetLength()/2.);
544  TVector3 end=start+dir_vector;
545 
546 
547  //the wire coordinate is already in cm. The time needs to be converted.
548  util::PxPoint startp(plane,(geom->DetHalfHeight()*sin(fabs(alpha))+start[2]*cos(alpha)-start[1]*sin(alpha)),start[0]);
549 
550  util::PxPoint endp(plane,(geom->DetHalfHeight()*sin(fabs(alpha))+end[2]*cos(alpha)-end[1]*sin(alpha)),end[0]);
551 
552  double angle=Get2Dangle(&endp,&startp);
553 
554 
555  return angle;
556 
557  }
558 
559 
560 
561 
562 
564  //Calculate 2D distance
565  // in "cm" "cm" coordinates
567  Double_t GeometryUtilities::Get2DDistance(Double_t wire1,
568  Double_t time1,
569  Double_t wire2,
570  Double_t time2) const
571  {
572 
573  return TMath::Sqrt( pow((wire1-wire2)*fWiretoCm,2)+pow((time1-time2)*fTimetoCm,2) );
574 
575  }
576 
577 
579  const util::PxPoint *point2) const
580  {
581  return TMath::Sqrt(sum_sqr(point1->w - point2->w, point1->t - point2->t));
582  }
583 
584 
586  //Calculate 2D distance, using 2D angle
587  // in "cm" "cm" coordinates
589  Double_t GeometryUtilities::Get2DPitchDistance(Double_t angle,
590  Double_t inwire,
591  Double_t wire) const
592  {
593  Double_t radangle = TMath::Pi()*angle/180;
594  if(std::cos(radangle)==0)
595  return 9999;
596  return std::abs((wire-inwire)/std::cos(radangle))*fWiretoCm;
597  }
598 
599 
600  //----------------------------------------------------------------------------
602  Double_t inwire,
603  Double_t wire) const
604  {
605 
606  return std::abs(wire-inwire)*TMath::Sqrt(1+slope*slope)*fWiretoCm;
607 
608  }
609 
610 
611 
612 
614  //Calculate wire,time coordinates of the Hit projection onto a line
615  //
617  Int_t GeometryUtilities::GetPointOnLine(Double_t slope,
618  Double_t intercept,
619  Double_t wire1,
620  Double_t time1,
621  Double_t &wireout,
622  Double_t &timeout) const
623  {
624  Double_t invslope=0;
625 
626  if(slope)
627  {
628  invslope=-1./slope;
629  }
630 
631  Double_t ort_intercept=time1-invslope*(Double_t)wire1;
632 
633  if((slope-invslope)!=0)
634  wireout=(ort_intercept - intercept)/(slope-invslope);
635  else
636  wireout=wire1;
637  timeout=slope*wireout+intercept;
638 
639  return 0;
640  }
641 
643  //Calculate wire,time coordinates of the Hit projection onto a line
644  // all points are assumed to be in cm/cm space.
647  const util::PxPoint *startpoint,
648  const util::PxPoint *point1,
649  util::PxPoint &pointout) const
650  {
651 
652  double intercept=startpoint->t - slope * startpoint->w;
653 
654 
655  return GetPointOnLine(slope,intercept,point1,pointout);
656 
657  }
658 
659 
661  //Calculate wire,time coordinates of the Hit projection onto a line
662  // all points assumed to be in cm/cm space.
665  double intercept,
666  const util::PxPoint *point1,
667  util::PxPoint &pointout) const
668  {
669  double invslope=0;
670 
671  if(slope)
672  {
673 // invslope=-1./slope*fWireTimetoCmCm*fWireTimetoCmCm;
674  invslope=-1./slope;
675  }
676 
677  double ort_intercept=point1->t - invslope * point1->w;
678 
679  if((slope-invslope)!=0)
680  pointout.w = (ort_intercept - intercept)/(slope-invslope);
681  else
682  pointout.w = point1->w;
683 
684  pointout.t = slope * pointout.w + intercept;
685 
686  return 0;
687  }
688 
690  //Calculate wire,time coordinates of the Hit projection onto a line
691  //
693  Int_t GeometryUtilities::GetPointOnLine(Double_t slope,
694  Double_t wirestart,
695  Double_t timestart,
696  Double_t wire1,
697  Double_t time1,
698  Double_t &wireout,
699  Double_t &timeout) const
700  {
701  Double_t intercept=timestart-slope*(Double_t)wirestart;
702 
703  return GetPointOnLine(slope,intercept,wire1,time1,wireout,timeout);
704  }
705 
707  //Calculate wire,time coordinates of the Hit projection onto a line
708  //
711  Double_t intercept,
712  Double_t ort_intercept,
713  Double_t &wireout,
714  Double_t &timeout) const
715  {
716  Double_t invslope=0;
717 
718  if(slope)
719  {
720  invslope=-1./slope;
721  }
722 
724 
725  wireout=(ort_intercept - intercept)/(slope-invslope);
726  timeout=slope*wireout+intercept;
727 
728 
729  wireout/=fWiretoCm;
730  timeout/=fTimetoCm;
731 
732  return 0;
733  }
734 
735 
737  //Calculate wire,time coordinates of the Hit projection onto a line
738  // slope should be in cm/cm space. PxPoint should be in cm/cm space.
741  double intercept,
742  double ort_intercept,
743  util::PxPoint &pointonline) const
744  {
745  Double_t invslope=0;
746 
747  if(slope)
748  invslope=-1./slope;
749 
750 
751  // invslope *= fWireTimetoCmCm * fWireTimetoCmCm;
752 
753  pointonline.w = (ort_intercept - intercept)/(slope-invslope);
754  pointonline.t = slope * pointonline.w + intercept;
755  return 0;
756  }
757 
758 // //Find hit closest to wire,time coordinates
759 // //
760 // ////////////////////////////////////////////////
761 // art::Ptr< recob::Hit > GeometryUtilities::FindClosestHitEvdPtr(std::vector<art::Ptr< recob::Hit > > hitlist,
762 // UInt_t wirein,
763 // Double_t timein) const
764 // {
765 //
766 // Double_t min_length_from_start=99999;
767 // art::Ptr< recob::Hit > nearHit;
768 //
769 // UInt_t plane,tpc,wire,cstat;
770 //
771 //
772 // for(UInt_t ii=0; ii<hitlist.size();ii++){
773 // recob::Hit * theHit = const_cast<recob::Hit *>(hitlist[ii].get());
774 // Double_t time = theHit->PeakTime() ;
775 // GetPlaneAndTPC(theHit,plane,cstat,tpc,wire);
776 //
777 // Double_t dist_mod=Get2DDistance(wirein,timein,wire,time);
778 //
779 // if(dist_mod<min_length_from_start){
780 // //wire_start[plane]=wire;
781 // //time_start[plane]=time;
782 // nearHit=(hitlist[ii]);
783 // min_length_from_start=dist_mod;
784 // }
785 //
786 // }
787 //
788 // return nearHit;
789 // }
790 //
791 //
792 //
793 
794 
795 
798  const PxPoint *p1,
799  PxPoint &pN) const
800  {
801 
802  //determine third plane number
803  for(UInt_t i = 0; i < fNPlanes; ++i){
804  if(i == p0->plane || i == p1->plane)
805  continue;
806  pN.plane = i;
807  }
808 
809  // Assuming there is no problem ( and we found the best pair that comes close in time )
810  // we try to get the Y and Z coordinates for the start of the shower.
811  UInt_t chan1 = geom->PlaneWireToChannel(p0->plane,p0->w);
812  UInt_t chan2 = geom->PlaneWireToChannel(p1->plane,p1->w);
813  const double origin[3] = {0.};
814  Double_t pos[3]={0.};
815  //geom->PlaneOriginVtx(p0->plane, pos);
816  geom->Plane(p0->plane).LocalToWorld(origin, pos);
817  Double_t x=(p0->t - detp->TriggerOffset())*fTimetoCm+pos[0];
818 
819  Double_t y,z;
820  if(! geom->ChannelsIntersect(chan1,chan2,y,z) )
821  return -1;
822 
823  pos[0]=x;
824  pos[1]=y;
825  pos[2]=z;
826 
827  pN=Get2DPointProjection(pos, pN.plane);
828 
829  return 0;
830  }
831 
832 
835  const PxPoint *p1,
836  Double_t* yz) const
837  {
838  Double_t y,z;
839 
840  // Force to the closest wires if not in the range
841  int z0 = p0->w / fWiretoCm;
842  int z1 = p1-> w/ fWiretoCm;
843  if(z0 < 0) {
844  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
845  << " 2D wire position " << p0->w << " [cm] corresponds to negative wire number." << std::endl
846  << " Forcing it to wire=0..." << std::endl
847  << "\033[93mWarning ends...\033[00m"<<std::endl;
848  z0 = 0;
849  }
850  else if(z0 >= (int)(geom->Nwires(p0->plane))){
851  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
852  << " 2D wire position " << p0->w << " [cm] exceeds max wire number " << (geom->Nwires(p0->plane)-1) <<std::endl
853  << " Forcing it to the max wire number..." << std::endl
854  << "\033[93mWarning ends...\033[00m"<<std::endl;
855  z0 = geom->Nwires(p0->plane) - 1;
856  }
857  if(z1 < 0) {
858  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
859  << " 2D wire position " << p1->w << " [cm] corresponds to negative wire number." << std::endl
860  << " Forcing it to wire=0..." << std::endl
861  << "\033[93mWarning ends...\033[00m"<<std::endl;
862  z1 = 0;
863  }
864  if(z1 >= (int)(geom->Nwires(p1->plane))){
865  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
866  << " 2D wire position " << p1->w << " [cm] exceeds max wire number " << (geom->Nwires(p0->plane)-1) <<std::endl
867  << " Forcing it to the max wire number..." << std::endl
868  << "\033[93mWarning ends...\033[00m"<<std::endl;
869  z1 = geom->Nwires(p1->plane) - 1;
870  }
871 
872  UInt_t chan1 = geom->PlaneWireToChannel(p0->plane, z0);
873  UInt_t chan2 = geom->PlaneWireToChannel(p1->plane, z1);
874 
875  if(! geom->ChannelsIntersect(chan1,chan2,y,z) )
876  return -1;
877 
878 
879  yz[0]=y;
880  yz[1]=z;
881 
882  return 0;
883  }
884 
885 
886 
889  const PxPoint *p1,
890  Double_t* xyz) const
891  {
892  const double origin[3] = {0.};
893  Double_t pos[3]={0.};
894  //geom->PlaneOriginVtx(p0->plane, pos);
895  geom->Plane(p0->plane).LocalToWorld(origin, pos);
896  Double_t x=(p0->t) - detp->TriggerOffset()*fTimetoCm+pos[0];
897  double yz[2];
898 
899  GetYZ(p0,p1,yz);
900 
901 
902  xyz[0]=x;
903  xyz[1]=yz[0];
904  xyz[2]=yz[1];
905 
906  return 0;
907  }
908 
909 
911 
912  PxPoint GeometryUtilities::Get2DPointProjection(Double_t *xyz, Int_t plane) const{
913 
914  PxPoint pN(0,0,0);
915  const double origin[3] = {0.};
916  Double_t pos[3];
917  //geom->PlaneOriginVtx(plane,pos);
918  geom->Plane(plane).LocalToWorld(origin, pos);
919  Double_t drifttick=(xyz[0]/fDriftVelocity)*(1./fTimeTick);
920 
921  pos[1]=xyz[1];
922  pos[2]=xyz[2];
923 
925 
926  pN.w = geom->NearestWire(pos, plane);
927  pN.t=drifttick-(pos[0]/fDriftVelocity)*(1./fTimeTick)+detp->TriggerOffset();
928  pN.plane=plane;
929 
930  return pN;
931 
932  }
933 
934 
936  // for now this returns the vlause in CM/CM space.
937  // this will become the default, but don't want to break the code that depends on the
938  // previous version. A.S. 03/26/14
940 
941  PxPoint GeometryUtilities::Get2DPointProjectionCM(std::vector< double > xyz, int plane) const{
942 
943  PxPoint pN(0,0,0);
944 
945  Double_t pos[3]{0., xyz[1], xyz[2]};
946 
948 
949  pN.w = geom->NearestWire(pos, plane)*fWiretoCm;
950  pN.t=xyz[0];
951  pN.plane=plane;
952 
953  return pN;
954 
955  }
956 
957 
958  PxPoint GeometryUtilities::Get2DPointProjectionCM(double *xyz, int plane) const{
959 
960  PxPoint pN(0,0,0);
961 
962  Double_t pos[3]{0., xyz[1], xyz[2]};
963 
965 
966  pN.w = geom->NearestWire(pos, plane)*fWiretoCm;
967  pN.t=xyz[0];
968  pN.plane=plane;
969 
970  return pN;
971 
972  }
973 
974 
975 
976  PxPoint GeometryUtilities::Get2DPointProjectionCM(TLorentzVector *xyz, int plane) const{
977  double xyznew[3]={(*xyz)[0],(*xyz)[1],(*xyz)[2]};
978 
979  return Get2DPointProjectionCM(xyznew,plane);
980  }
981 
982 
983 
984  Double_t GeometryUtilities::GetTimeTicks(Double_t x, Int_t plane) const{
985 
986 
987  const double origin[3] = {0.};
988  Double_t pos[3];
989  //geom->PlaneOriginVtx(plane,pos);
990  geom->Plane(plane).LocalToWorld(origin, pos);
991  Double_t drifttick=(x/fDriftVelocity)*(1./fTimeTick);
992 
993  return drifttick-(pos[0]/fDriftVelocity)*(1./fTimeTick)+detp->TriggerOffset();
994 
995 
996  }
997 
998 
999 
1000 
1001  //----------------------------------------------------------------------
1002  // provide projected wire pitch for the view // copied from track.cxx and modified
1003  Double_t GeometryUtilities::PitchInView(UInt_t plane,
1004  Double_t phi,
1005  Double_t theta) const
1006  {
1007  Double_t dirs[3] = {0.};
1008  GetDirectionCosines(phi,theta,dirs);
1009 
1012  Double_t wirePitch = 0.;
1013  Double_t angleToVert = 0.;
1014 
1015  wirePitch = geom->WirePitch(plane);
1016  angleToVert = geom->WireAngleToVertical(geom->Plane(plane).View()) - 0.5*TMath::Pi();
1017 
1018  //(sin(angleToVert),std::cos(angleToVert)) is the direction perpendicular to wire
1019  //fDir.front() is the direction of the track at the beginning of its trajectory
1020  Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*dirs[1] +
1021  TMath::Cos(angleToVert)*dirs[2]);
1022 
1023 // std::cout << " ---- cosgamma: " << angleToVert*180/TMath::Pi() << " d's: " << dirs[1]
1024 // << " " << dirs[2] << " ph,th " << phi << " " << theta << std::endl;
1025 
1026  // std::cout << TMath::Sin(angleToVert)*dirs[1] << " " << TMath::Cos(angleToVert)*dirs[2] << " CGAMM: " << cosgamma << std::endl;
1027  if(cosgamma < 1.e-5)
1028  //throw UtilException("cosgamma is basically 0, that can't be right");
1029  {std::cout << " returning 100" << std::endl;
1030  return 100;
1031 
1032  }
1033 
1034  // std::cout << " returning " << wirePitch/cosgamma << std::endl;
1035  return wirePitch/cosgamma;
1036  }
1037 
1038 
1041  Double_t theta,
1042  Double_t *dirs) const
1043  {
1044  theta*=(TMath::Pi()/180);
1045  phi*=(TMath::Pi()/180); // working on copies, it's ok.
1046  dirs[0]=TMath::Cos(theta)*TMath::Sin(phi);
1047  dirs[1]=TMath::Sin(theta);
1048  dirs[2]=TMath::Cos(theta)*TMath::Cos(phi);
1049 
1050  }
1051 
1052 
1053  void GeometryUtilities::SelectLocalHitlist(const std::vector<util::PxHit> &hitlist,
1054  std::vector <const util::PxHit*> &hitlistlocal,
1055  util::PxPoint &startHit,
1056  Double_t& linearlimit,
1057  Double_t& ortlimit,
1058  Double_t& lineslopetest)
1059  {
1060  util::PxHit testHit;
1061  SelectLocalHitlist(hitlist, hitlistlocal, startHit, linearlimit, ortlimit, lineslopetest, testHit);
1062 
1063  }
1064 
1065 
1069 
1070  void GeometryUtilities::SelectLocalHitlist(const std::vector<util::PxHit> &hitlist,
1071  std::vector <const util::PxHit*> &hitlistlocal,
1072  util::PxPoint &startHit,
1073  Double_t& linearlimit,
1074  Double_t& ortlimit,
1075  Double_t& lineslopetest,
1076  util::PxHit &averageHit)
1077  {
1078 
1079  hitlistlocal.clear();
1080  std::vector< unsigned int > hitlistlocal_index;
1081 
1082  hitlistlocal_index.clear();
1083 
1084  SelectLocalHitlistIndex(hitlist,hitlistlocal_index,startHit,linearlimit,ortlimit,lineslopetest);
1085 
1086  double timesum = 0;
1087  double wiresum = 0;
1088  for(size_t i=0; i<hitlistlocal_index.size(); ++i) {
1089 
1090  hitlistlocal.push_back((const util::PxHit*)(&(hitlist.at(hitlistlocal_index.at(i)))));
1091  timesum += hitlist.at(hitlistlocal_index.at(i)).t;
1092  wiresum += hitlist.at(hitlistlocal_index.at(i)).w;
1093 
1094 
1095 
1096  }
1097 
1098  averageHit.plane = startHit.plane;
1099  if(hitlistlocal.size())
1100  {
1101  averageHit.w = wiresum/(double)hitlistlocal.size();
1102  averageHit.t = timesum/((double) hitlistlocal.size());
1103  }
1104  }
1105 
1106 
1107  void GeometryUtilities::SelectLocalHitlistIndex(const std::vector<util::PxHit> &hitlist,
1108  std::vector <unsigned int> &hitlistlocal_index,
1109  util::PxPoint &startHit,
1110  Double_t& linearlimit,
1111  Double_t& ortlimit,
1112  Double_t& lineslopetest)
1113  {
1114 
1115  hitlistlocal_index.clear();
1116  double locintercept=startHit.t - startHit.w * lineslopetest;
1117 
1118 
1119  for(size_t i=0; i<hitlist.size(); ++i) {
1120 
1121  util::PxPoint hitonline;
1122 
1123  GetPointOnLine( lineslopetest, locintercept, (const util::PxHit*)(&hitlist.at(i)), hitonline );
1124 
1125 
1126  //calculate linear distance from start point and orthogonal distance from axis
1127  Double_t lindist=Get2DDistance((const util::PxPoint*)(&hitonline),(const util::PxPoint*)(&startHit));
1128  Double_t ortdist=Get2DDistance((const util::PxPoint*)(&hitlist.at(i)),(const util::PxPoint*)(&hitonline));
1129 
1130 
1131  if(lindist<linearlimit && ortdist<ortlimit){
1132  hitlistlocal_index.push_back(i);
1133  }
1134 
1135 
1136  }
1137 
1138 
1139  }
1140 
1141 
1142 
1143 
1144 
1148 
1149 
1150  void GeometryUtilities::SelectPolygonHitList(const std::vector<util::PxHit> &hitlist,
1151  std::vector <const util::PxHit*> &hitlistlocal)
1152  {
1153  if(!(hitlist.size())) {
1154  throw UtilException("Provided empty hit list!");
1155  return;
1156  }
1157 
1158  hitlistlocal.clear();
1159  unsigned char plane = (*hitlist.begin()).plane;
1160 
1161  // Define subset of hits to define polygon
1162  std::map<double,const util::PxHit*> hitmap;
1163  double qtotal=0;
1164  for(auto const &h : hitlist){
1165 
1166  hitmap.insert(std::pair<double,const util::PxHit*>(h.charge,&h));
1167  qtotal += h.charge;
1168 
1169  }
1170  double qintegral=0;
1171  std::vector<const util::PxHit*> ordered_hits;
1172  ordered_hits.reserve(hitlist.size());
1173  for(auto hiter = hitmap.rbegin();
1174  qintegral < qtotal*0.95 && hiter != hitmap.rend();
1175  ++hiter) {
1176 
1177  qintegral += (*hiter).first;
1178  ordered_hits.push_back((*hiter).second);
1179 
1180  }
1181 
1182  // Define container to hold found polygon corner PxHit index & distance
1183  std::vector<size_t> hit_index(8,0);
1184  std::vector<double> hit_distance(8,1e9);
1185 
1186  // Loop over hits and find corner points in the plane view
1187  // Also fill corner edge points
1188  std::vector<util::PxPoint> edges(4,PxPoint(plane,0,0));
1189  double wire_max = geom->Nwires(plane) * fWiretoCm;
1190  double time_max = detp->NumberTimeSamples() * fTimetoCm;
1191 
1192  for(size_t index = 0; index<ordered_hits.size(); ++index) {
1193 
1194  if(ordered_hits.at(index)->t < 0 ||
1195  ordered_hits.at(index)->w < 0 ||
1196  ordered_hits.at(index)->t > time_max ||
1197  ordered_hits.at(index)->w > wire_max ) {
1198 
1199  throw UtilException(Form("Invalid wire/time (%g,%g) ... range is (0=>%g,0=>%g)",
1200  ordered_hits.at(index)->w,
1201  ordered_hits.at(index)->t,
1202  wire_max,
1203  time_max)
1204  );
1205  return;
1206  }
1207 
1208  double dist = 0;
1209 
1210  // Comparison w/ (Wire,0)
1211  dist = ordered_hits.at(index)->t;
1212  if(dist < hit_distance.at(1)) {
1213  hit_distance.at(1) = dist;
1214  hit_index.at(1) = index;
1215  edges.at(0).t = ordered_hits.at(index)->t;
1216  edges.at(1).t = ordered_hits.at(index)->t;
1217  }
1218 
1219  // Comparison w/ (WireMax,Time)
1220  dist = wire_max - ordered_hits.at(index)->w;
1221  if(dist < hit_distance.at(3)) {
1222  hit_distance.at(3) = dist;
1223  hit_index.at(3) = index;
1224  edges.at(1).w = ordered_hits.at(index)->w;
1225  edges.at(2).w = ordered_hits.at(index)->w;
1226  }
1227 
1228  // Comparison w/ (Wire,TimeMax)
1229  dist = time_max - ordered_hits.at(index)->t;
1230  if(dist < hit_distance.at(5)) {
1231  hit_distance.at(5) = dist;
1232  hit_index.at(5) = index;
1233  edges.at(2).t = ordered_hits.at(index)->t;
1234  edges.at(3).t = ordered_hits.at(index)->t;
1235  }
1236 
1237  // Comparison w/ (0,Time)
1238  dist = ordered_hits.at(index)->w;
1239  if(dist < hit_distance.at(7)) {
1240  hit_distance.at(7) = dist;
1241  hit_index.at(7) = index;
1242  edges.at(0).w = ordered_hits.at(index)->w;
1243  edges.at(3).w = ordered_hits.at(index)->w;
1244  }
1245  }
1246  /*
1247  std::cout
1248  << Form("Corner points: (%g,%g) (%g,%g) (%g,%g) (%g,%g)",
1249  edges.at(0).w, edges.at(0).t,
1250  edges.at(1).w, edges.at(1).t,
1251  edges.at(2).w, edges.at(2).t,
1252  edges.at(3).w, edges.at(3).t)
1253  <<std::endl;
1254  */
1255  for(size_t index = 0; index<ordered_hits.size(); ++index) {
1256 
1257  double dist = 0;
1258  // Comparison w/ (0,0)
1259  dist = pow((ordered_hits.at(index)->t - edges.at(0).t),2) + pow((ordered_hits.at(index)->w - edges.at(0).w),2);
1260  if(dist < hit_distance.at(0)) {
1261  hit_distance.at(0) = dist;
1262  hit_index.at(0) = index;
1263  }
1264 
1265  // Comparison w/ (WireMax,0)
1266  dist = pow((ordered_hits.at(index)->t - edges.at(1).t),2) + pow((ordered_hits.at(index)->w - edges.at(1).w),2);
1267  if(dist < hit_distance.at(2)) {
1268  hit_distance.at(2) = dist;
1269  hit_index.at(2) = index;
1270  }
1271 
1272  // Comparison w/ (WireMax,TimeMax)
1273  dist = pow((ordered_hits.at(index)->t - edges.at(2).t),2) + pow((ordered_hits.at(index)->w - edges.at(2).w),2);
1274  if(dist < hit_distance.at(4)) {
1275  hit_distance.at(4) = dist;
1276  hit_index.at(4) = index;
1277  }
1278 
1279  // Comparison w/ (0,TimeMax)
1280  dist = pow((ordered_hits.at(index)->t - edges.at(3).t),2) + pow((ordered_hits.at(index)->w - edges.at(3).w),2);
1281  if(dist < hit_distance.at(6)) {
1282  hit_distance.at(6) = dist;
1283  hit_index.at(6) = index;
1284  }
1285 
1286  }
1287 
1288  // Loop over the resulting hit indexes and append unique hits to define the polygon to the return hit list
1289  std::set<size_t> unique_index;
1290  std::vector<size_t> candidate_polygon;
1291  candidate_polygon.reserve(9);
1292  // std::cout << "Original polygon: " << std::endl;
1293  for(auto &index : hit_index) {
1294 
1295  if(unique_index.find(index) == unique_index.end()) {
1296  // hitlistlocal.push_back((const util::PxHit*)(ordered_hits.at(index)));
1297  //std::cout << "(" << ordered_hits.at(index)->w << ", " << ordered_hits.at(index)->t << ")" << std::endl;
1298  unique_index.insert(index);
1299  candidate_polygon.push_back(index);
1300  }
1301  }
1302  for (auto &index: hit_index){
1303  candidate_polygon.push_back(index);
1304  break;
1305  }
1306 
1307  if(unique_index.size()>8) throw UtilException("Size of the polygon > 8!");
1308 
1309  //Untangle Polygon
1310  candidate_polygon = PolyOverlap( ordered_hits, candidate_polygon);
1311 
1312  hitlistlocal.clear();
1313  for( unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1314  hitlistlocal.push_back((const util::PxHit*)(ordered_hits.at(candidate_polygon.at(i))));
1315  }
1316  //check that polygon does not have more than 8 sides
1317  if(unique_index.size()>8) throw UtilException("Size of the polygon > 8!");
1318  }
1319 
1320 
1321  std::vector<size_t> GeometryUtilities::PolyOverlap( std::vector<const util::PxHit*> ordered_hits ,
1322  std::vector<size_t> candidate_polygon) {
1323 
1324  //loop over edges
1325  for ( unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1326  double Ax = ordered_hits.at(candidate_polygon.at(i))->w;
1327  double Ay = ordered_hits.at(candidate_polygon.at(i))->t;
1328  double Bx = ordered_hits.at(candidate_polygon.at(i+1))->w;
1329  double By = ordered_hits.at(candidate_polygon.at(i+1))->t;
1330  //loop over edges that have not been checked yet...
1331  //only ones furhter down in polygon
1332  for ( unsigned int j=i+2; j<(candidate_polygon.size()-1); j++){
1333  //avoid consecutive segments:
1334  if ( candidate_polygon.at(i) == candidate_polygon.at(j+1) )
1335  continue;
1336  else{
1337  double Cx = ordered_hits.at(candidate_polygon.at(j))->w;
1338  double Cy = ordered_hits.at(candidate_polygon.at(j))->t;
1339  double Dx = ordered_hits.at(candidate_polygon.at(j+1))->w;
1340  double Dy = ordered_hits.at(candidate_polygon.at(j+1))->t;
1341 
1342  if ( (Clockwise(Ax,Ay,Cx,Cy,Dx,Dy) != Clockwise(Bx,By,Cx,Cy,Dx,Dy))
1343  and (Clockwise(Ax,Ay,Bx,By,Cx,Cy) != Clockwise(Ax,Ay,Bx,By,Dx,Dy)) ){
1344  size_t tmp = candidate_polygon.at(i+1);
1345  candidate_polygon.at(i+1) = candidate_polygon.at(j);
1346  candidate_polygon.at(j) = tmp;
1347  //check that last element is still first (to close circle...)
1348  candidate_polygon.at(candidate_polygon.size()-1) = candidate_polygon.at(0);
1349  //swapped polygon...now do recursion to make sure
1350  return PolyOverlap( ordered_hits, candidate_polygon);
1351  }//if crossing
1352  }
1353  }//second loop
1354  }//first loop
1355  //std::cout << std::endl;
1356  return candidate_polygon;
1357  }
1358 
1359  bool GeometryUtilities::Clockwise(double Ax,double Ay,double Bx,double By,double Cx,double Cy){
1360  return (Cy-Ay)*(Bx-Ax) > (By-Ay)*(Cx-Ax);
1361  }
1362 
1364  //Find hit closest to wire,time coordinates
1365  //
1367 
1368 // recob::Hit * GeometryUtilities::FindClosestHit(std::vector<art::Ptr< recob::Hit > > hitlist,
1369 // unsigned int wirein,
1370 // double timein) const
1371 // {
1372 // art::Ptr<recob::Hit> nearHit=FindClosestHitPtr(hitlist,wirein,timein);
1373 // // min_length_from_start=dist_mod;
1374 // return const_cast<recob::Hit *> (nearHit.get());
1375 //
1376 // }
1377 
1378 
1379 
1380  //Find hit closest to wire,time coordinates
1381  //
1383 
1384 // art::Ptr< recob::Hit > GeometryUtilities::FindClosestHitPtr(std::vector<art::Ptr< recob::Hit > > hitlist,
1385 // unsigned int wirein,
1386 // double timein) const
1387 //
1388 // {
1389 //
1390 // PxHitConverter PxC;
1391 // std::vector <util::PxHit> pxhits;
1392 // PxC.GeneratePxHit(hitlist,pxhits);
1393 //
1394 //
1395 //
1396 // return hitlist[FindClosestHitIndex(pxhits,wirein,timein)];
1397 //
1398 // }
1399 
1400 
1401  util::PxHit GeometryUtilities::FindClosestHit(std::vector<util::PxHit > hitlist,
1402  unsigned int wirein,
1403  double timein) const
1404  {
1405 
1406  return hitlist[FindClosestHitIndex(hitlist, wirein,timein)];
1407 
1408  }
1409 
1410 
1411 
1412  unsigned int GeometryUtilities::FindClosestHitIndex(std::vector<util::PxHit > hitlist,
1413  unsigned int wirein,
1414  double timein) const
1415  {
1416  double min_length_from_start=99999;
1417  util::PxHit nearHit;
1418 
1419  unsigned int wire;
1420  double time;
1421  unsigned int ret_ind=0;
1422 
1423  for(unsigned int ii=0; ii<hitlist.size();ii++){
1424 
1425  util::PxHit * theHit = &(hitlist[ii]);
1426  time = theHit->t ;
1427  wire=theHit->w;
1428  // plane=theHit->WireID().Plane;
1429 
1430  double dist_mod=Get2DDistance(wirein,timein,wire,time);
1431  if(dist_mod<min_length_from_start){
1432  //wire_start[plane]=wire;
1433  //time_start[plane]=time;
1434  nearHit=(hitlist[ii]);
1435  min_length_from_start=dist_mod;
1436  ret_ind=ii;
1437  }
1438  }
1439 
1440 
1441  return ret_ind;
1442  }
1443 
1444 
1445 
1446 
1447 
1448 
1449 
1450 /*
1451  void GeometryUtilities::SelectLocalHitlist(std::vector< art::Ptr < recob::Hit> > hitlist,
1452  std::vector < art::Ptr<recob::Hit> > &hitlistlocal,
1453  double wire_start,
1454  double time_start,
1455  double linearlimit,
1456  double ortlimit,
1457  double lineslopetest)
1458  {
1459  PxHitConverter PxC;
1460  std::vector <util::PxHit> pxhitlist;
1461  PxC.GeneratePxHit(hitlist,pxhitlist);
1462  std::vector< unsigned int > pxhitlist_local_index;
1463 
1464  util::PxHit startHit;
1465  startHit.plane=pxhitlist.at(0).plane;
1466  startHit.w=wire_start;
1467  startHit.t=time_start;
1468 
1469  SelectLocalHitlistIndex(pxhitlist, pxhitlist_local_index, startHit, linearlimit, ortlimit, lineslopetest);
1470 
1471 
1472  for(unsigned int idx=0;idx<pxhitlist_local_index.size();idx++)
1473  {
1474  hitlistlocal.push_back(hitlist.at(pxhitlist_local_index.at(idx)));
1475  //std::cout << " w,t: " << wire << " " << time << " calc time: " << wire*lineslopetest + locintercept << " ws,ts " << wonline << " "<< tonline <<" "<< lindist << " " << ortdist << " plane: " << plane << std::endl;
1476 
1477  }
1478  }
1479  */
1480 
1481 
1482 
1483 
1484 
1485 } // namespace
Float_t x
Definition: compare.C:6
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
Encapsulate the construction of a single cyostat.
virtual int TriggerOffset() const =0
Double_t Get2DDistance(Double_t wire1, Double_t time1, Double_t wire2, Double_t time2) const
WireGeo const & Wire(unsigned int iwire) const
Definition: PlaneGeo.cxx:506
bool Clockwise(double Ax, double Ay, double Bx, double By, double Cx, double Cy)
Double_t Get2Dangle(Double_t deltawire, Double_t deltatime) const
Unknown view.
Definition: geo_types.h:83
Float_t y
Definition: compare.C:6
static GeometryUtilities * _me
Double_t z
Definition: plot.C:279
bool ChannelsIntersect(raw::ChannelID_t c1, raw::ChannelID_t c2, double &y, double &z) const
Returns an intersection point of two channels.
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
Float_t tmp
Definition: plot.C:37
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double ThetaZ() const
Returns angle of wire with respect to z axis in the Y-Z plane in radians.
Definition: WireGeo.h:192
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
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.
Double_t PitchInView(UInt_t plane, Double_t phi, Double_t theta) const
3-dimensional objects, potentially hits, clusters, prongs, etc.
Definition: geo_types.h:82
Double_t Get2DPitchDistance(Double_t angle, Double_t inwire, Double_t wire) const
const detinfo::DetectorProperties * detp
T sqr(T v)
View_t View() const
Which coordinate does this plane measure.
Definition: PlaneGeo.h:171
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
double t
Definition: PxUtils.h:11
virtual double Temperature() const =0
geo::WireID::WireID_t NearestWire(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the index of wire closest to position in the specified TPC.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
Double_t Get3DSpecialCaseTheta(Int_t iplane0, Int_t iplane1, Double_t dw0, Double_t dw1) const
Double_t GetTimeTicks(Double_t x, Int_t plane) const
virtual unsigned int NumberTimeSamples() const =0
void SelectLocalHitlist(const std::vector< util::PxHit > &hitlist, std::vector< const util::PxHit * > &hitlistlocal, util::PxPoint &startHit, Double_t &linearlimit, Double_t &ortlimit, Double_t &lineslopetest)
~GeometryUtilities()
Default destructor.
std::vector< Double_t > vertangle
double w
Definition: PxUtils.h:10
Encapsulate the geometry of a wire.
Int_t GetPointOnLine(Double_t slope, Double_t intercept, Double_t wire1, Double_t time1, Double_t &wireout, Double_t &timeout) const
void SelectLocalHitlistIndex(const std::vector< util::PxHit > &hitlist, std::vector< unsigned int > &hitlistlocal_index, util::PxPoint &startHit, Double_t &linearlimit, Double_t &ortlimit, Double_t &lineslopetest)
Double_t Get2DPitchDistanceWSlope(Double_t slope, Double_t inwire, Double_t wire) const
Int_t GetYZ(const PxPoint *p0, const PxPoint *p1, Double_t *yz) const
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
GeometryUtilities()
Default constructor = private for singleton.
const geo::GeometryCore * geom
Encapsulate the construction of a single detector plane.
util::PxHit FindClosestHit(std::vector< util::PxHit > hitlist, unsigned int wirein, double timein) const
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
double Get2DangleFrom3D(unsigned int plane, double phi, double theta) const
Int_t GetProjectedPoint(const PxPoint *p0, const PxPoint *p1, PxPoint &pN) const
void GetDirectionCosines(Double_t phi, Double_t theta, Double_t *dirs) const
const double kINVALID_DOUBLE
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
PxPoint Get2DPointProjection(Double_t *xyz, Int_t plane) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
PxPoint Get2DPointProjectionCM(std::vector< double > xyz, int plane) const
Double_t CalculatePitch(UInt_t iplane0, Double_t phi, Double_t theta) const
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
Int_t GetPointOnLineWSlopes(Double_t slope, Double_t intercept, Double_t ort_intercept, Double_t &wireout, Double_t &timeout) const
Float_t e
Definition: plot.C:34
std::vector< size_t > PolyOverlap(std::vector< const util::PxHit * > ordered_hits, std::vector< size_t > candidate_polygon)
Float_t w
Definition: plot.C:23
Double_t Get2Dslope(Double_t deltawire, Double_t deltatime) const
Int_t GetXYZ(const PxPoint *p0, const PxPoint *p1, Double_t *xyz) const
Int_t Get3DaxisN(Int_t iplane0, Int_t iplane1, Double_t omega0, Double_t omega1, Double_t &phi, Double_t &theta) const
void SelectPolygonHitList(const std::vector< util::PxHit > &hitlist, std::vector< const util::PxHit * > &hitlistlocal)
void LocalToWorld(const double *plane, double *world) const
Transform point from local plane frame to world frame.
Definition: PlaneGeo.h:1124
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
unsigned int plane
Definition: PxUtils.h:12
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:230
Encapsulate the construction of a single detector plane.
Double_t CalculatePitchPolar(UInt_t iplane0, Double_t phi, Double_t theta) const
unsigned int FindClosestHitIndex(std::vector< util::PxHit > hitlist, unsigned int wirein, double timein) const