LArSoft  v06_85_00
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 
824  pos[1]=y;
825  pos[2]=z;
826  pos[0]=x;
827 
828  pN=Get2DPointProjection(pos, pN.plane);
829 
830  return 0;
831  }
832 
833 
836  const PxPoint *p1,
837  Double_t* yz) const
838  {
839  Double_t y,z;
840 
841  // Force to the closest wires if not in the range
842  int z0 = p0->w / fWiretoCm;
843  int z1 = p1-> w/ fWiretoCm;
844  if(z0 < 0) {
845  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
846  << " 2D wire position " << p0->w << " [cm] corresponds to negative wire number." << std::endl
847  << " Forcing it to wire=0..." << std::endl
848  << "\033[93mWarning ends...\033[00m"<<std::endl;
849  z0 = 0;
850  }
851  else if(z0 >= (int)(geom->Nwires(p0->plane))){
852  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
853  << " 2D wire position " << p0->w << " [cm] exceeds max wire number " << (geom->Nwires(p0->plane)-1) <<std::endl
854  << " Forcing it to the max wire number..." << std::endl
855  << "\033[93mWarning ends...\033[00m"<<std::endl;
856  z0 = geom->Nwires(p0->plane) - 1;
857  }
858  if(z1 < 0) {
859  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
860  << " 2D wire position " << p1->w << " [cm] corresponds to negative wire number." << std::endl
861  << " Forcing it to wire=0..." << std::endl
862  << "\033[93mWarning ends...\033[00m"<<std::endl;
863  z1 = 0;
864  }
865  if(z1 >= (int)(geom->Nwires(p1->plane))){
866  std::cout << "\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
867  << " 2D wire position " << p1->w << " [cm] exceeds max wire number " << (geom->Nwires(p0->plane)-1) <<std::endl
868  << " Forcing it to the max wire number..." << std::endl
869  << "\033[93mWarning ends...\033[00m"<<std::endl;
870  z1 = geom->Nwires(p1->plane) - 1;
871  }
872 
873  UInt_t chan1 = geom->PlaneWireToChannel(p0->plane, z0);
874  UInt_t chan2 = geom->PlaneWireToChannel(p1->plane, z1);
875 
876  if(! geom->ChannelsIntersect(chan1,chan2,y,z) )
877  return -1;
878 
879 
880  yz[0]=y;
881  yz[1]=z;
882 
883  return 0;
884  }
885 
886 
887 
890  const PxPoint *p1,
891  Double_t* xyz) const
892  {
893  const double origin[3] = {0.};
894  Double_t pos[3]={0.};
895  //geom->PlaneOriginVtx(p0->plane, pos);
896  geom->Plane(p0->plane).LocalToWorld(origin, pos);
897  Double_t x=(p0->t) - detp->TriggerOffset()*fTimetoCm+pos[0];
898  double yz[2];
899 
900  GetYZ(p0,p1,yz);
901 
902 
903  xyz[0]=x;
904  xyz[1]=yz[0];
905  xyz[2]=yz[1];
906 
907  return 0;
908  }
909 
910 
912 
913  PxPoint GeometryUtilities::Get2DPointProjection(Double_t *xyz, Int_t plane) const{
914 
915  PxPoint pN(0,0,0);
916  const double origin[3] = {0.};
917  Double_t pos[3];
918  //geom->PlaneOriginVtx(plane,pos);
919  geom->Plane(plane).LocalToWorld(origin, pos);
920  Double_t drifttick=(xyz[0]/fDriftVelocity)*(1./fTimeTick);
921 
922  pos[1]=xyz[1];
923  pos[2]=xyz[2];
924 
926 
927  pN.w = geom->NearestWire(pos, plane);
928  pN.t=drifttick-(pos[0]/fDriftVelocity)*(1./fTimeTick)+detp->TriggerOffset();
929  pN.plane=plane;
930 
931  return pN;
932 
933  }
934 
935 
937  // for now this returns the vlause in CM/CM space.
938  // this will become the default, but don't want to break the code that depends on the
939  // previous version. A.S. 03/26/14
941 
942  PxPoint GeometryUtilities::Get2DPointProjectionCM(std::vector< double > xyz, int plane) const{
943 
944  PxPoint pN(0,0,0);
945 
946  Double_t pos[3];
947 
948 
949  pos[1]=xyz[1];
950  pos[2]=xyz[2];
951 
953 
954  pN.w = geom->NearestWire(pos, plane)*fWiretoCm;
955  pN.t=xyz[0];
956  pN.plane=plane;
957 
958  return pN;
959 
960  }
961 
962 
963  PxPoint GeometryUtilities::Get2DPointProjectionCM(double *xyz, int plane) const{
964 
965  PxPoint pN(0,0,0);
966 
967  Double_t pos[3];
968 
969 
970  pos[1]=xyz[1];
971  pos[2]=xyz[2];
972 
974 
975  pN.w = geom->NearestWire(pos, plane)*fWiretoCm;
976  pN.t=xyz[0];
977  pN.plane=plane;
978 
979  return pN;
980 
981  }
982 
983 
984 
985  PxPoint GeometryUtilities::Get2DPointProjectionCM(TLorentzVector *xyz, int plane) const{
986  double xyznew[3]={(*xyz)[0],(*xyz)[1],(*xyz)[2]};
987 
988  return Get2DPointProjectionCM(xyznew,plane);
989  }
990 
991 
992 
993  Double_t GeometryUtilities::GetTimeTicks(Double_t x, Int_t plane) const{
994 
995 
996  const double origin[3] = {0.};
997  Double_t pos[3];
998  //geom->PlaneOriginVtx(plane,pos);
999  geom->Plane(plane).LocalToWorld(origin, pos);
1000  Double_t drifttick=(x/fDriftVelocity)*(1./fTimeTick);
1001 
1002  return drifttick-(pos[0]/fDriftVelocity)*(1./fTimeTick)+detp->TriggerOffset();
1003 
1004 
1005  }
1006 
1007 
1008 
1009 
1010  //----------------------------------------------------------------------
1011  // provide projected wire pitch for the view // copied from track.cxx and modified
1012  Double_t GeometryUtilities::PitchInView(UInt_t plane,
1013  Double_t phi,
1014  Double_t theta) const
1015  {
1016  Double_t dirs[3] = {0.};
1017  GetDirectionCosines(phi,theta,dirs);
1018 
1021  Double_t wirePitch = 0.;
1022  Double_t angleToVert = 0.;
1023 
1024  wirePitch = geom->WirePitch(plane);
1025  angleToVert = geom->WireAngleToVertical(geom->Plane(plane).View()) - 0.5*TMath::Pi();
1026 
1027  //(sin(angleToVert),std::cos(angleToVert)) is the direction perpendicular to wire
1028  //fDir.front() is the direction of the track at the beginning of its trajectory
1029  Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*dirs[1] +
1030  TMath::Cos(angleToVert)*dirs[2]);
1031 
1032 // std::cout << " ---- cosgamma: " << angleToVert*180/TMath::Pi() << " d's: " << dirs[1]
1033 // << " " << dirs[2] << " ph,th " << phi << " " << theta << std::endl;
1034 
1035  // std::cout << TMath::Sin(angleToVert)*dirs[1] << " " << TMath::Cos(angleToVert)*dirs[2] << " CGAMM: " << cosgamma << std::endl;
1036  if(cosgamma < 1.e-5)
1037  //throw UtilException("cosgamma is basically 0, that can't be right");
1038  {std::cout << " returning 100" << std::endl;
1039  return 100;
1040 
1041  }
1042 
1043  // std::cout << " returning " << wirePitch/cosgamma << std::endl;
1044  return wirePitch/cosgamma;
1045  }
1046 
1047 
1050  Double_t theta,
1051  Double_t *dirs) const
1052  {
1053  theta*=(TMath::Pi()/180);
1054  phi*=(TMath::Pi()/180); // working on copies, it's ok.
1055  dirs[0]=TMath::Cos(theta)*TMath::Sin(phi);
1056  dirs[1]=TMath::Sin(theta);
1057  dirs[2]=TMath::Cos(theta)*TMath::Cos(phi);
1058 
1059  }
1060 
1061 
1062  void GeometryUtilities::SelectLocalHitlist(const std::vector<util::PxHit> &hitlist,
1063  std::vector <const util::PxHit*> &hitlistlocal,
1064  util::PxPoint &startHit,
1065  Double_t& linearlimit,
1066  Double_t& ortlimit,
1067  Double_t& lineslopetest)
1068  {
1069  util::PxHit testHit;
1070  SelectLocalHitlist(hitlist, hitlistlocal, startHit, linearlimit, ortlimit, lineslopetest, testHit);
1071 
1072  }
1073 
1074 
1078 
1079  void GeometryUtilities::SelectLocalHitlist(const std::vector<util::PxHit> &hitlist,
1080  std::vector <const util::PxHit*> &hitlistlocal,
1081  util::PxPoint &startHit,
1082  Double_t& linearlimit,
1083  Double_t& ortlimit,
1084  Double_t& lineslopetest,
1085  util::PxHit &averageHit)
1086  {
1087 
1088  hitlistlocal.clear();
1089  std::vector< unsigned int > hitlistlocal_index;
1090 
1091  hitlistlocal_index.clear();
1092 
1093  SelectLocalHitlistIndex(hitlist,hitlistlocal_index,startHit,linearlimit,ortlimit,lineslopetest);
1094 
1095  double timesum = 0;
1096  double wiresum = 0;
1097  for(size_t i=0; i<hitlistlocal_index.size(); ++i) {
1098 
1099  hitlistlocal.push_back((const util::PxHit*)(&(hitlist.at(hitlistlocal_index.at(i)))));
1100  timesum += hitlist.at(hitlistlocal_index.at(i)).t;
1101  wiresum += hitlist.at(hitlistlocal_index.at(i)).w;
1102 
1103 
1104 
1105  }
1106 
1107  averageHit.plane = startHit.plane;
1108  if(hitlistlocal.size())
1109  {
1110  averageHit.w = wiresum/(double)hitlistlocal.size();
1111  averageHit.t = timesum/((double) hitlistlocal.size());
1112  }
1113  }
1114 
1115 
1116  void GeometryUtilities::SelectLocalHitlistIndex(const std::vector<util::PxHit> &hitlist,
1117  std::vector <unsigned int> &hitlistlocal_index,
1118  util::PxPoint &startHit,
1119  Double_t& linearlimit,
1120  Double_t& ortlimit,
1121  Double_t& lineslopetest)
1122  {
1123 
1124  hitlistlocal_index.clear();
1125  double locintercept=startHit.t - startHit.w * lineslopetest;
1126 
1127 
1128  for(size_t i=0; i<hitlist.size(); ++i) {
1129 
1130  util::PxPoint hitonline;
1131 
1132  GetPointOnLine( lineslopetest, locintercept, (const util::PxHit*)(&hitlist.at(i)), hitonline );
1133 
1134 
1135  //calculate linear distance from start point and orthogonal distance from axis
1136  Double_t lindist=Get2DDistance((const util::PxPoint*)(&hitonline),(const util::PxPoint*)(&startHit));
1137  Double_t ortdist=Get2DDistance((const util::PxPoint*)(&hitlist.at(i)),(const util::PxPoint*)(&hitonline));
1138 
1139 
1140  if(lindist<linearlimit && ortdist<ortlimit){
1141  hitlistlocal_index.push_back(i);
1142  }
1143 
1144 
1145  }
1146 
1147 
1148  }
1149 
1150 
1151 
1152 
1153 
1157 
1158 
1159  void GeometryUtilities::SelectPolygonHitList(const std::vector<util::PxHit> &hitlist,
1160  std::vector <const util::PxHit*> &hitlistlocal)
1161  {
1162  if(!(hitlist.size())) {
1163  throw UtilException("Provided empty hit list!");
1164  return;
1165  }
1166 
1167  hitlistlocal.clear();
1168  unsigned char plane = (*hitlist.begin()).plane;
1169 
1170  // Define subset of hits to define polygon
1171  std::map<double,const util::PxHit*> hitmap;
1172  double qtotal=0;
1173  for(auto const &h : hitlist){
1174 
1175  hitmap.insert(std::pair<double,const util::PxHit*>(h.charge,&h));
1176  qtotal += h.charge;
1177 
1178  }
1179  double qintegral=0;
1180  std::vector<const util::PxHit*> ordered_hits;
1181  ordered_hits.reserve(hitlist.size());
1182  for(auto hiter = hitmap.rbegin();
1183  qintegral < qtotal*0.95 && hiter != hitmap.rend();
1184  ++hiter) {
1185 
1186  qintegral += (*hiter).first;
1187  ordered_hits.push_back((*hiter).second);
1188 
1189  }
1190 
1191  // Define container to hold found polygon corner PxHit index & distance
1192  std::vector<size_t> hit_index(8,0);
1193  std::vector<double> hit_distance(8,1e9);
1194 
1195  // Loop over hits and find corner points in the plane view
1196  // Also fill corner edge points
1197  std::vector<util::PxPoint> edges(4,PxPoint(plane,0,0));
1198  double wire_max = geom->Nwires(plane) * fWiretoCm;
1199  double time_max = detp->NumberTimeSamples() * fTimetoCm;
1200 
1201  for(size_t index = 0; index<ordered_hits.size(); ++index) {
1202 
1203  if(ordered_hits.at(index)->t < 0 ||
1204  ordered_hits.at(index)->w < 0 ||
1205  ordered_hits.at(index)->t > time_max ||
1206  ordered_hits.at(index)->w > wire_max ) {
1207 
1208  throw UtilException(Form("Invalid wire/time (%g,%g) ... range is (0=>%g,0=>%g)",
1209  ordered_hits.at(index)->w,
1210  ordered_hits.at(index)->t,
1211  wire_max,
1212  time_max)
1213  );
1214  return;
1215  }
1216 
1217  double dist = 0;
1218 
1219  // Comparison w/ (Wire,0)
1220  dist = ordered_hits.at(index)->t;
1221  if(dist < hit_distance.at(1)) {
1222  hit_distance.at(1) = dist;
1223  hit_index.at(1) = index;
1224  edges.at(0).t = ordered_hits.at(index)->t;
1225  edges.at(1).t = ordered_hits.at(index)->t;
1226  }
1227 
1228  // Comparison w/ (WireMax,Time)
1229  dist = wire_max - ordered_hits.at(index)->w;
1230  if(dist < hit_distance.at(3)) {
1231  hit_distance.at(3) = dist;
1232  hit_index.at(3) = index;
1233  edges.at(1).w = ordered_hits.at(index)->w;
1234  edges.at(2).w = ordered_hits.at(index)->w;
1235  }
1236 
1237  // Comparison w/ (Wire,TimeMax)
1238  dist = time_max - ordered_hits.at(index)->t;
1239  if(dist < hit_distance.at(5)) {
1240  hit_distance.at(5) = dist;
1241  hit_index.at(5) = index;
1242  edges.at(2).t = ordered_hits.at(index)->t;
1243  edges.at(3).t = ordered_hits.at(index)->t;
1244  }
1245 
1246  // Comparison w/ (0,Time)
1247  dist = ordered_hits.at(index)->w;
1248  if(dist < hit_distance.at(7)) {
1249  hit_distance.at(7) = dist;
1250  hit_index.at(7) = index;
1251  edges.at(0).w = ordered_hits.at(index)->w;
1252  edges.at(3).w = ordered_hits.at(index)->w;
1253  }
1254  }
1255  /*
1256  std::cout
1257  << Form("Corner points: (%g,%g) (%g,%g) (%g,%g) (%g,%g)",
1258  edges.at(0).w, edges.at(0).t,
1259  edges.at(1).w, edges.at(1).t,
1260  edges.at(2).w, edges.at(2).t,
1261  edges.at(3).w, edges.at(3).t)
1262  <<std::endl;
1263  */
1264  for(size_t index = 0; index<ordered_hits.size(); ++index) {
1265 
1266  double dist = 0;
1267  // Comparison w/ (0,0)
1268  dist = pow((ordered_hits.at(index)->t - edges.at(0).t),2) + pow((ordered_hits.at(index)->w - edges.at(0).w),2);
1269  if(dist < hit_distance.at(0)) {
1270  hit_distance.at(0) = dist;
1271  hit_index.at(0) = index;
1272  }
1273 
1274  // Comparison w/ (WireMax,0)
1275  dist = pow((ordered_hits.at(index)->t - edges.at(1).t),2) + pow((ordered_hits.at(index)->w - edges.at(1).w),2);
1276  if(dist < hit_distance.at(2)) {
1277  hit_distance.at(2) = dist;
1278  hit_index.at(2) = index;
1279  }
1280 
1281  // Comparison w/ (WireMax,TimeMax)
1282  dist = pow((ordered_hits.at(index)->t - edges.at(2).t),2) + pow((ordered_hits.at(index)->w - edges.at(2).w),2);
1283  if(dist < hit_distance.at(4)) {
1284  hit_distance.at(4) = dist;
1285  hit_index.at(4) = index;
1286  }
1287 
1288  // Comparison w/ (0,TimeMax)
1289  dist = pow((ordered_hits.at(index)->t - edges.at(3).t),2) + pow((ordered_hits.at(index)->w - edges.at(3).w),2);
1290  if(dist < hit_distance.at(6)) {
1291  hit_distance.at(6) = dist;
1292  hit_index.at(6) = index;
1293  }
1294 
1295  }
1296 
1297  // Loop over the resulting hit indexes and append unique hits to define the polygon to the return hit list
1298  std::set<size_t> unique_index;
1299  std::vector<size_t> candidate_polygon;
1300  candidate_polygon.reserve(9);
1301  // std::cout << "Original polygon: " << std::endl;
1302  for(auto &index : hit_index) {
1303 
1304  if(unique_index.find(index) == unique_index.end()) {
1305  // hitlistlocal.push_back((const util::PxHit*)(ordered_hits.at(index)));
1306  //std::cout << "(" << ordered_hits.at(index)->w << ", " << ordered_hits.at(index)->t << ")" << std::endl;
1307  unique_index.insert(index);
1308  candidate_polygon.push_back(index);
1309  }
1310  }
1311  for (auto &index: hit_index){
1312  candidate_polygon.push_back(index);
1313  break;
1314  }
1315 
1316  if(unique_index.size()>8) throw UtilException("Size of the polygon > 8!");
1317 
1318  //Untangle Polygon
1319  candidate_polygon = PolyOverlap( ordered_hits, candidate_polygon);
1320 
1321  hitlistlocal.clear();
1322  for( unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1323  hitlistlocal.push_back((const util::PxHit*)(ordered_hits.at(candidate_polygon.at(i))));
1324  }
1325  //check that polygon does not have more than 8 sides
1326  if(unique_index.size()>8) throw UtilException("Size of the polygon > 8!");
1327  }
1328 
1329 
1330  std::vector<size_t> GeometryUtilities::PolyOverlap( std::vector<const util::PxHit*> ordered_hits ,
1331  std::vector<size_t> candidate_polygon) {
1332 
1333  //loop over edges
1334  for ( unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1335  double Ax = ordered_hits.at(candidate_polygon.at(i))->w;
1336  double Ay = ordered_hits.at(candidate_polygon.at(i))->t;
1337  double Bx = ordered_hits.at(candidate_polygon.at(i+1))->w;
1338  double By = ordered_hits.at(candidate_polygon.at(i+1))->t;
1339  //loop over edges that have not been checked yet...
1340  //only ones furhter down in polygon
1341  for ( unsigned int j=i+2; j<(candidate_polygon.size()-1); j++){
1342  //avoid consecutive segments:
1343  if ( candidate_polygon.at(i) == candidate_polygon.at(j+1) )
1344  continue;
1345  else{
1346  double Cx = ordered_hits.at(candidate_polygon.at(j))->w;
1347  double Cy = ordered_hits.at(candidate_polygon.at(j))->t;
1348  double Dx = ordered_hits.at(candidate_polygon.at(j+1))->w;
1349  double Dy = ordered_hits.at(candidate_polygon.at(j+1))->t;
1350 
1351  if ( (Clockwise(Ax,Ay,Cx,Cy,Dx,Dy) != Clockwise(Bx,By,Cx,Cy,Dx,Dy))
1352  and (Clockwise(Ax,Ay,Bx,By,Cx,Cy) != Clockwise(Ax,Ay,Bx,By,Dx,Dy)) ){
1353  size_t tmp = candidate_polygon.at(i+1);
1354  candidate_polygon.at(i+1) = candidate_polygon.at(j);
1355  candidate_polygon.at(j) = tmp;
1356  //check that last element is still first (to close circle...)
1357  candidate_polygon.at(candidate_polygon.size()-1) = candidate_polygon.at(0);
1358  //swapped polygon...now do recursion to make sure
1359  return PolyOverlap( ordered_hits, candidate_polygon);
1360  }//if crossing
1361  }
1362  }//second loop
1363  }//first loop
1364  //std::cout << std::endl;
1365  return candidate_polygon;
1366  }
1367 
1368  bool GeometryUtilities::Clockwise(double Ax,double Ay,double Bx,double By,double Cx,double Cy){
1369  return (Cy-Ay)*(Bx-Ax) > (By-Ay)*(Cx-Ax);
1370  }
1371 
1373  //Find hit closest to wire,time coordinates
1374  //
1376 
1377 // recob::Hit * GeometryUtilities::FindClosestHit(std::vector<art::Ptr< recob::Hit > > hitlist,
1378 // unsigned int wirein,
1379 // double timein) const
1380 // {
1381 // art::Ptr<recob::Hit> nearHit=FindClosestHitPtr(hitlist,wirein,timein);
1382 // // min_length_from_start=dist_mod;
1383 // return const_cast<recob::Hit *> (nearHit.get());
1384 //
1385 // }
1386 
1387 
1388 
1389  //Find hit closest to wire,time coordinates
1390  //
1392 
1393 // art::Ptr< recob::Hit > GeometryUtilities::FindClosestHitPtr(std::vector<art::Ptr< recob::Hit > > hitlist,
1394 // unsigned int wirein,
1395 // double timein) const
1396 //
1397 // {
1398 //
1399 // PxHitConverter PxC;
1400 // std::vector <util::PxHit> pxhits;
1401 // PxC.GeneratePxHit(hitlist,pxhits);
1402 //
1403 //
1404 //
1405 // return hitlist[FindClosestHitIndex(pxhits,wirein,timein)];
1406 //
1407 // }
1408 
1409 
1410  util::PxHit GeometryUtilities::FindClosestHit(std::vector<util::PxHit > hitlist,
1411  unsigned int wirein,
1412  double timein) const
1413  {
1414 
1415  return hitlist[FindClosestHitIndex(hitlist, wirein,timein)];
1416 
1417  }
1418 
1419 
1420 
1421  unsigned int GeometryUtilities::FindClosestHitIndex(std::vector<util::PxHit > hitlist,
1422  unsigned int wirein,
1423  double timein) const
1424  {
1425  double min_length_from_start=99999;
1426  util::PxHit nearHit;
1427 
1428  unsigned int wire;
1429  double time;
1430  unsigned int ret_ind=0;
1431 
1432  for(unsigned int ii=0; ii<hitlist.size();ii++){
1433 
1434  util::PxHit * theHit = &(hitlist[ii]);
1435  time = theHit->t ;
1436  wire=theHit->w;
1437  // plane=theHit->WireID().Plane;
1438 
1439  double dist_mod=Get2DDistance(wirein,timein,wire,time);
1440  if(dist_mod<min_length_from_start){
1441  //wire_start[plane]=wire;
1442  //time_start[plane]=time;
1443  nearHit=(hitlist[ii]);
1444  min_length_from_start=dist_mod;
1445  ret_ind=ii;
1446  }
1447  }
1448 
1449 
1450  return ret_ind;
1451  }
1452 
1453 
1454 
1455 
1456 
1457 
1458 
1459 /*
1460  void GeometryUtilities::SelectLocalHitlist(std::vector< art::Ptr < recob::Hit> > hitlist,
1461  std::vector < art::Ptr<recob::Hit> > &hitlistlocal,
1462  double wire_start,
1463  double time_start,
1464  double linearlimit,
1465  double ortlimit,
1466  double lineslopetest)
1467  {
1468  PxHitConverter PxC;
1469  std::vector <util::PxHit> pxhitlist;
1470  PxC.GeneratePxHit(hitlist,pxhitlist);
1471  std::vector< unsigned int > pxhitlist_local_index;
1472 
1473  util::PxHit startHit;
1474  startHit.plane=pxhitlist.at(0).plane;
1475  startHit.w=wire_start;
1476  startHit.t=time_start;
1477 
1478  SelectLocalHitlistIndex(pxhitlist, pxhitlist_local_index, startHit, linearlimit, ortlimit, lineslopetest);
1479 
1480 
1481  for(unsigned int idx=0;idx<pxhitlist_local_index.size();idx++)
1482  {
1483  hitlistlocal.push_back(hitlist.at(pxhitlist_local_index.at(idx)));
1484  //std::cout << " w,t: " << wire << " " << time << " calc time: " << wire*lineslopetest + locintercept << " ws,ts " << wonline << " "<< tonline <<" "<< lindist << " " << ortdist << " plane: " << plane << std::endl;
1485 
1486  }
1487  }
1488  */
1489 
1490 
1491 
1492 
1493 
1494 } // namespace
1495 
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