LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
BezierTrack.cxx
Go to the documentation of this file.
2 
8 #include "larcorealg/Geometry/geo_vectors_utils.h" // geo::vect namespace
15 
17 
18 #include "cetlib_except/exception.h"
19 
20 #include <utility> // std::forward()
21 #include <cassert>
22 
23 
24 namespace trkf {
25 
26  //----------------------------------------------------------------------
27  // Constructor from Base object (for analysis)
28  //
30  : fTraj(traj)
31  // Clang: private field 'fID' is not used
32  // , fID(id)
33  {
34  fBezierResolution=1000;
36  }
37 
38 
39  //----------------------------------------------------------------------
41  : BezierTrack(track.ID(), track.Trajectory().Trajectory()) {}
42 
43  //----------------------------------------------------------------------
44  // Constructor from seed vector (for production)
45  //
46  BezierTrack::BezierTrack(std::vector<recob::Seed> const& SeedCol )
47  : fTraj()
48  {
49  if(SeedCol.size()>0)
50  {
51  double Pt[3], Dir[3], PtErr[3], DirErr[3];
52  double FirstPt[3];
53  double FirstDir[3];
54  SeedCol.at(0).GetPoint( Pt, PtErr );
55  SeedCol.at(0).GetDirection( Dir, DirErr );
56  for(int i=0; i!=3; ++i)
57  {
58  double BigN=1000;
59  FirstPt[i]=Pt[i]-((1.+1./BigN) * Dir[i]);
60  FirstDir[i]=Dir[i]/BigN;
61  }
62  fSeedCollection.push_back(recob::Seed(FirstPt, FirstDir, PtErr, DirErr));
63  }
64  for(size_t i=0; i!=SeedCol.size(); ++i)
65  {
66  fSeedCollection.push_back(SeedCol.at(i));
67  }
68  if(SeedCol.size()>0)
69  {
70  double Pt[3], Dir[3], PtErr[3], DirErr[3];
71  double LastPt[3], LastDir[3];
72  SeedCol.at(SeedCol.size()-1).GetPoint( Pt, PtErr );
73  SeedCol.at(SeedCol.size()-1).GetDirection( Dir, DirErr );
74  for(int i=0; i!=3; ++i)
75  {
76  double BigN=1000;
77  LastPt[i]=Pt[i]+((1.+1./BigN) * Dir[i]);
78  LastDir[i]=Dir[i]/BigN;
79  }
80  fSeedCollection.push_back(recob::Seed(LastPt, LastDir, PtErr, DirErr));
81  }
82 
84  fBezierResolution=1000;
85  }
86 
87 
88  //----------------------------------------------------------------------
89  // Constructor from track coordinates
90  //
91  BezierTrack::BezierTrack(std::vector<TVector3> const& Pos,
92  std::vector<TVector3> const& Dir,
93  std::vector<std::vector<double> > const& dQdx,
94  int id)
95  : fTraj(geo::vect::convertCollToPoint(Pos), geo::vect::convertCollToVector(Dir), false)
96  // Clang: private field 'fID' is not used
97  // , fID(id)
98  , fdQdx(dQdx)
99  {
100  fBezierResolution=1000;
102  }
103 
104 
105  //----------------------------------------------------------------------
106  // Return the seed collection (with spurious end seeds cut off
107  //
108  std::vector<recob::Seed> BezierTrack::GetSeedVector()
109  {
110  std::vector<recob::Seed> ReturnVector=fSeedCollection;
111  if(fSeedCollection.size()>2)
112  {
113  ReturnVector.erase(ReturnVector.begin());
114  ReturnVector.pop_back();
115  return ReturnVector;
116  }
117  else
118  return std::vector<recob::Seed>();
119 
120  }
121 
122 
123 
124  //----------------------------------------------------------------------
125  // Get the track pitch at some s for a particular view
126  //
127 
128  double BezierTrack::GetTrackPitch(geo::View_t view, double s, double /* WirePitch */, unsigned int c, unsigned int t)
129  {
130  static std::map<geo::View_t, bool> DoneCalc;
131  static std::map<geo::View_t, TVector3> PitchVecs;
132 
133  if(!(DoneCalc[view]))
134  {
135  unsigned int p;
136  unsigned int pTop;
137 
139 
140  pTop=geom->Cryostat(c).TPC(t).Nplanes();
141  for(p=0; p!=pTop; ++p)
142  if(geom->Cryostat(c).TPC(t).Plane(p).View() == view) break;
143 
144  double WireEnd1[3], WireEnd2[3];
145 
146  geom->WireEndPoints(c, t, p, 0, WireEnd1, WireEnd2);
147 
148  double WirePitch = geom->WirePitch(view);
149 
150  TVector3 WireVec;
151  for(size_t i=0; i!=3; ++i)
152  WireVec[i]= WireEnd2[i] -WireEnd1[i];
153  PitchVecs[view] = (1.0 / WirePitch) * WireVec.Cross(TVector3(1,0,0)).Unit();
154 
155  DoneCalc[view]=true;
156  }
157 
158  TVector3 TrackDir = GetTrackDirectionV(s).Unit();
159 
160  return 1. / (PitchVecs[view].Dot(TrackDir));
161  }
162 
163 
164  //------------------------------------------------------
165  // Build an anab::Calorimetry object for this track (wrapper for
166  // vector<art::Ptr>
167 
169  {
171  for(size_t i=0; i!=Hitv.size(); ++i)
172  {
173  Hitv.push_back(Hits.at(i));
174  }
175  Hitv.clear();
176 
177  return GetCalorimetryObject(Hitv, sigtype, calalg);
178  }
179 
180  //------------------------------------------------------
181  // Build an anab::Calorimetry object for this track
182 
184  {
185 
186 
188 
189  std::vector<float> dEdx;
190  std::vector<float> dQdx;
191  std::vector<float> resRange;
192  std::vector<float> deadwire;
193  float Range = GetLength();
194  std::vector<float> TrkPitch;
195 
196 
197 
198  double s, d;
199 
200  bool do_now=true;
201  geo::PlaneID planeID;
202 
203  if(Hits.size()>0)
204  {
205  for(size_t i=0; i!=Hits.size(); ++i)
206  {
207  if(Hits.at(i)->SignalType()==sigtype)
208  {
209  geo::View_t view = Hits.at(i)->View();
210  double WirePitch = geom->WirePitch(view);
211  GetClosestApproach(Hits.at(i),s,d);
212  double ThisPitch = GetTrackPitch( view, s, WirePitch );
213  TrkPitch.push_back(ThisPitch);
214  resRange.push_back(Range - s*Range);
215  dQdx.push_back(Hits.at(i)->Integral()/ThisPitch);
216  dEdx.push_back( calalg.dEdx_AMP(Hits.at(i), ThisPitch) );
217 
218  if(do_now) {
219  planeID = Hits.at(i)->WireID().planeID();
220  do_now=false;
221  }
222  }
223 
224  }
225  }
226 
227 
228  double KineticEnergy = 0.;
229 
230  for(size_t i=0; i!=dEdx.size(); ++i)
231  KineticEnergy+=dEdx.at(i)*TrkPitch.at(i);
232 
233  return anab::Calorimetry(KineticEnergy, dEdx, dQdx, resRange, deadwire, Range, TrkPitch,planeID);
234 
235 
236  }
237 
238 
239  //------------------------------------------------------
240  // Build an anab::Calorimetry object for this track
241 
243  {
244 
245 
247 
248  std::vector<float> dEdx;
249  std::vector<float> dQdx;
250  std::vector<float> resRange;
251  std::vector<float> deadwire;
252  float Range = GetLength();
253  std::vector<float> TrkPitch;
254 
255  double WirePitch = geom->WirePitch(view);
256 
257  double KineticEnergy = 0;
258 
259  double s, d;
260 
261  bool do_now=true;
262  geo::PlaneID planeID;
263 
264  if(Hits.size()>0)
265  {
266  for(size_t i=0; i!=Hits.size(); ++i)
267  {
268  if(Hits.at(i)->View()==view)
269  {
270  GetClosestApproach(Hits.at(i),s,d);
271  double ThisPitch = GetTrackPitch( view, s, WirePitch );
272  TrkPitch.push_back(ThisPitch);
273  resRange.push_back( (1.-s) * Range);
274  dQdx.push_back(Hits.at(i)->Integral()/ThisPitch);
275  double ThisdEdx = calalg.dEdx_AMP(Hits.at(i), ThisPitch);
276  dEdx.push_back( ThisdEdx);
277  KineticEnergy+=ThisdEdx*ThisPitch;
278 
279  if(do_now) {
280  planeID = Hits.at(i)->WireID().planeID();
281  do_now=false;
282  }
283 
284  }
285 
286  }
287  }
288 
289 
290  return anab::Calorimetry(KineticEnergy, dEdx, dQdx, resRange, deadwire, Range, TrkPitch, planeID);
291 
292  }
293 
294 
295  //----------------------------------------------------------------------
296  // Given track points, fill the seed vector. The seeds are then used
297  // for geomtry calculations / bezier fitting
298  //
300  {
301  int NSeg=NSegments();
302 
303 
304 
305  double Pt[3], Dir[3];
306  for(int i=0; i!=NSeg; i++)
307  {
308 
309  auto const& pos = fTraj.LocationAtPoint(i);
310  Pt[0]=pos.X();
311  Pt[1]=pos.Y();
312  Pt[2]=pos.Z();
313 
314  auto const& dir = fTraj.DirectionAtPoint(i);
315  Dir[0]=dir.X();
316  Dir[1]=dir.Y();
317  Dir[2]=dir.Z();
318 
319  fSeedCollection.push_back(recob::Seed(Pt,Dir));
320  }
321 
322  }
323 
324 
325 
326 
327  //----------------------------------------------------------------------
329  {
331  int NPlanes = geom->Nplanes();
332  fdQdx.resize(NPlanes) ;
333  double Pt[3], Dir[3], ErrPt[3], ErrDir[3];
335  recob::Trajectory::Momenta_t directions;
337  it!=fSeedCollection.end(); ++it)
338  {
339 
340  it->GetPoint(Pt,ErrPt);
341  it->GetDirection(Dir, ErrDir);
342  recob::Track::Point_t Point(Pt[0],Pt[1],Pt[2]);
343  recob::Track::Vector_t Direction(Dir[0],Dir[1],Dir[2]);
344 
345  for(int i=0; i!=NPlanes; ++i)
346  fdQdx.at(i).push_back(0);
347 
348  positions.push_back(Point);
349  directions.push_back(Direction);
350  }
351 
352  fTraj
353  = recob::Trajectory(std::move(positions), std::move(directions), false);
354 
355  }
356 
357 
358  //----------------------------------------------------------------------
359  // Calculate the lengths of each bezier segment and fill useful
360  // calculational data members
361  //
362 
364  {
365 
366  if(fSeedCollection.size()==0)
367  {
368  if(NSegments()!=0) FillSeedVector();
369  else
370  {
371  throw cet::exception("no points in track")
372  <<"CalculateSegments method of Bezier track called with no"
373  <<" track information loaded. You must fill track with "
374  <<"poisition and direction data before calling this method."
375  <<"\n";
376  }
377  }
378  if(NSegments()==0)
379  {
380  if(fSeedCollection.size()!=0) FillTrajectoryVectors();
381  }
382 
383  BezierCurveHelper bhlp(100);
384 
385  int Segments = NSegments();
386 
387  fTrackLength=0;
388  bool FirstSeg=true;
389  for(int i=0; i!=Segments; ++i)
390  {
391  if(!FirstSeg)
392  {
393  float SegmentLength=bhlp.GetSegmentLength(fSeedCollection.at(i-1),fSeedCollection.at(i));
394 
395  fTrackLength+=SegmentLength;
396  fSegmentLength.push_back(SegmentLength);
397  }
398  FirstSeg=false;
399  fCumulativeLength.push_back(fTrackLength);
400  }
401  }
402 
403 
404  //----------------------------------------------------------------------
405  // Find the point which is fraction s along the track and return
406  // as a double[3]
407  //
408  void BezierTrack::GetTrackPoint(double s, double * xyz) const
409  {
410  if((s>=1.)||(s<=0.))
411  {
412  // catch these easy floating point errors
413  if((s>0.9999)&&(s<1.00001))
414  {
415  auto End1 = fTraj.End();
416  xyz[0]=End1.X();
417  xyz[1]=End1.Y();
418  xyz[2]=End1.Z();
419 
420  return;
421  }
422  else if((s<0.0001)&&(s>-0.00001))
423  {
424  auto End0 = fTraj.Start();
425  xyz[0]=End0.X();
426  xyz[1]=End0.Y();
427  xyz[2]=End0.Z();
428 
429  return;
430  }
431 
432  // otherwise complain about the mistake
433  else
434  throw cet::exception("track point out of range")<<" s = "<<s <<" out of range \n";
435  }
436  else
437  {
438  BezierCurveHelper bhlp;
439  for(unsigned int i=1; i!=fCumulativeLength.size(); i++)
440  {
441  if( ( (fCumulativeLength.at(i-1) / fTrackLength) <= s)
442  &&( (fCumulativeLength.at(i) / fTrackLength) > s))
443  {
444  double locals = (s * fTrackLength - fCumulativeLength[i-1])/fSegmentLength[i-1];
445 
446 
447  bhlp.GetBezierPointXYZ(fSeedCollection.at(i-1),fSeedCollection.at(i),locals, xyz);
448  }
449 
450  }
451  }
452  }
453 
454 
455 
456 
457 
458  //----------------------------------------------------------------------
459  // Find the point which is fraction s along the track and get its
460  // projected point in the wire view, in system uvwx
461  //
462 
463  void BezierTrack::GetProjectedPointUVWX(double s, double *uvw, double*x, int t=0, int c=0) const
464  {
465 
467 
468  double xyz[3];
469 
470  // Get point in 3D space
471  GetTrackPoint(s , xyz);
472 
473  int NPlanes=geo->Cryostat(c).TPC(t).Nplanes();
474 
475  for(int p=0; p!=NPlanes; p++)
476  {
477  uvw[p]= geo->NearestWire(xyz,p,t,c);
478  }
479  x[0]=xyz[0];
480  }
481 
482 
483 
484 
485 
486 
487  //----------------------------------------------------------------------
488  // Find the point which is fraction s along the track and get its
489  // projected point in the wire view, in system uvwt
490  //
491 
492  void BezierTrack::GetProjectedPointUVWT(double s, double *uvw, double*ticks, int t=0, int c=0) const
493  {
496 
497  double xyz[3];
498 
499  // Get point in 3D space
500  GetTrackPoint(s , xyz);
501 
502  int NPlanes=geo->Cryostat(c).TPC(t).Nplanes();
503 
504  for(int p=0; p!=NPlanes; p++)
505  {
506  uvw[p]= geo->NearestWire(xyz,p,t,c);
507  ticks[p]=det->ConvertXToTicks(xyz[0],p,t,c);
508  }
509  }
510 
511 
512 
513  //----------------------------------------------------------------------
514  // Calculate the closest approach of this track to a given hit
515  // - this fast version is for ennumerating which members of a hit
516  // collection are within d, how far each is and where the closest
517  // approach occurs. This version is optimized for speed for this
518  // application
519  void BezierTrack::GetClosestApproaches( art::PtrVector<recob::Hit> const & hits , std::vector<double>& s, std::vector<double>& Distances) const
520  {
521 
524 
525  s.clear();
526  Distances.clear();
527 
528 
529  // Pull all the relevant information out of hits and into simple vectors
530 
531  std::vector<TVector3> HitEnd1s, HitEnd2s;
532  std::vector<double> WireLengths;
533 
534  HitEnd1s.resize(hits.size());
535  HitEnd2s.resize(hits.size());
536  WireLengths.resize(hits.size());
537 
538  //unsigned int c1, t1, p1, w1;
539  double End1[3], End2[3];
540 
541  size_t NHits = hits.size();
542 
543  for(size_t i=0; i!=NHits; i++)
544  {
545  Distances.push_back(10000);
546  s.push_back(-1);
547 
548  geo::WireID hitWireID = hits.at(i)->WireID();
549 
550  geo->WireEndPoints(hitWireID.Cryostat,hitWireID.TPC,hitWireID.Plane,hitWireID.Wire,End1,End2);
551 
552  HitEnd1s.at(i)[0]= HitEnd2s.at(i)[0]= det->ConvertTicksToX(hits.at(i)->PeakTime(),hitWireID.Plane,hitWireID.TPC,hitWireID.Cryostat);
553  HitEnd1s.at(i)[1]= End1[1];
554  HitEnd2s.at(i)[1]= End2[1];
555  HitEnd1s.at(i)[2]= End1[2];
556  HitEnd2s.at(i)[2]= End2[2];
557 
558  WireLengths.at(i)=((HitEnd1s.at(i)-HitEnd2s.at(i)).Mag());
559  }
560 
561 
562  double iS;
563 
564  for(int ipt=0; ipt<=fBezierResolution; ++ipt)
565  {
566  iS=float(ipt)/fBezierResolution;
567  TVector3 trackpt = GetTrackPointV(iS);
568 
569  for(size_t ihit=0; ihit!=NHits; ++ihit)
570  {
571  float d = ((trackpt-HitEnd1s.at(ihit)).Cross(trackpt-HitEnd2s.at(ihit))).Mag()/WireLengths.at(ihit);
572 
573  if(d<Distances.at(ihit))
574  {
575  Distances.at(ihit)=d;
576  s.at(ihit)=iS;
577  }
578  }
579  }
580 
581 
582  }
583 
584  //--------------------------------------------------------
585 
586  void BezierTrack::GetClosestApproaches( std::vector< art::Ptr<recob::Hit> > const & hits, std::vector<double>& s, std::vector<double>& Distances) const
587  {
589  for(size_t h = 0; h < hits.size(); ++h) hitv.push_back(hits[h]);
590  this->GetClosestApproaches(hitv, s, Distances);
591  hitv.clear();
592  }
593 
594 
595 
596 
597  //----------------------------------------------------------------------
598  // Calculate the closest approach of this track to a given hit
599  // and also the point where this occurs
600  //
601 
602  void BezierTrack::GetClosestApproach( recob::Hit const & hit, double& s, double& Distance) const
603  {
605 
607 
608  //unsigned int c1, t1, p1, w1;
609 
610  double xyzend1[3], xyzend2[3];
611 
612  geo::WireID hitWireID = hit.WireID();
613  geo->WireEndPoints(hitWireID.Cryostat,hitWireID.TPC,hitWireID.Plane,hitWireID.Wire,xyzend1,xyzend2);
614 
615  xyzend1[0] = xyzend2[0] = det->ConvertTicksToX(hit.PeakTime(),hitWireID.Plane,hitWireID.TPC,hitWireID.Cryostat);
616 
617  double iS, xyz[3], MinDistanceToPoint=10000, MinS=0;
618 
619  for(int i=0; i<=fBezierResolution; ++i)
620  {
621  iS=float(i)/fBezierResolution;
622  GetTrackPoint(iS, xyz);
623  // calculate line to point distance in 3D
624  TVector3 end1(xyzend1[0],xyzend1[1],xyzend1[2]);
625  TVector3 end2(xyzend2[0],xyzend2[1],xyzend2[2]);
626  TVector3 trackpt(xyz[0],xyz[1],xyz[2]);
627 
628  float d = ((trackpt-end1).Cross(trackpt-end2)).Mag()/(end2-end1).Mag();
629 
630  if(d<MinDistanceToPoint)
631  {
632  MinDistanceToPoint=d;
633  MinS=iS;
634  }
635  }
636 
637  s = MinS;
638  Distance = MinDistanceToPoint;
639 
640  }
641 
642 
643 
644 
645  //----------------------------------------------------------------------
646  // Calculate the closest approach of this track to a given hit
647  // and also the point where this occurs
648  //
649 
650  void BezierTrack::GetClosestApproach( art::Ptr<recob::Hit> const& hit, double& s, double& Distance) const
651  {
654 
655  //unsigned int c1, t1, p1, w1;
656 
657  double xyzend1[3], xyzend2[3];
658 
659  geo::WireID hitWireID = hit->WireID();
660  geo->WireEndPoints(hitWireID.Cryostat,hitWireID.TPC,hitWireID.Plane,hitWireID.Wire,xyzend1,xyzend2);
661 
662  xyzend1[0] = xyzend2[0] = det->ConvertTicksToX(hit->PeakTime(),hitWireID.Plane,hitWireID.TPC,hitWireID.Cryostat);
663 
664  double iS, xyz[3], MinDistanceToPoint=10000, MinS=0;
665 
666  for(int i=0; i<=fBezierResolution; ++i)
667  {
668  iS=float(i)/fBezierResolution;
669  GetTrackPoint(iS, xyz);
670  // calculate line to point distance in 3D
671  TVector3 end1(xyzend1[0],xyzend1[1],xyzend1[2]);
672  TVector3 end2(xyzend2[0],xyzend2[1],xyzend2[2]);
673  TVector3 trackpt(xyz[0],xyz[1],xyz[2]);
674 
675  float d = ((trackpt-end1).Cross(trackpt-end2)).Mag()/(end2-end1).Mag();
676 
677  if(d<MinDistanceToPoint)
678  {
679  MinDistanceToPoint=d;
680  MinS=iS;
681  }
682  }
683 
684  s = MinS;
685  Distance = MinDistanceToPoint;
686 
687  }
688 
689 
690 
691  //----------------------------------------------------------------------
692  // Calculate the closest approach of this track to a given hit
693  // and also the point where this occurs
694  //
695 
696  void BezierTrack::GetClosestApproach( uint32_t w, int p, int t, int c, float x, double& s, double& Distance) const
697  {
698  // const detinfo::DetectorProperties* det = art::ServiceHandle<detinfo::DetectorPropertiesService>()->provider();
700 
701 
702  double xyzend1[3], xyzend2[3];
703 
704  geo->WireEndPoints(c,t,p,w,xyzend1,xyzend2);
705 
706  xyzend1[0] = xyzend2[0] = x;
707 
708  double iS, xyz[3], MinDistanceToPoint=10000, MinS=0;
709 
710  for(int i=0; i<=fBezierResolution; ++i)
711  {
712  iS=float(i)/fBezierResolution;
713  GetTrackPoint(iS, xyz);
714  // calculate line to point distance in 3D
715  TVector3 end1(xyzend1[0],xyzend1[1],xyzend1[2]);
716  TVector3 end2(xyzend2[0],xyzend2[1],xyzend2[2]);
717  TVector3 trackpt(xyz[0],xyz[1],xyz[2]);
718 
719  float d = ((trackpt-end1).Cross(trackpt-end2)).Mag()/(end2-end1).Mag();
720 
721  if(d<MinDistanceToPoint)
722  {
723  MinDistanceToPoint=d;
724  MinS=iS;
725  }
726  }
727 
728  s = MinS;
729  Distance = MinDistanceToPoint;
730 
731  }
732 
733 
734 
735  //----------------------------------------------------------------------
736  // Calculate the closest approach of this track to a given spacepoint
737  // and also the point where this occurs
738 
739  void BezierTrack::GetClosestApproach( recob::SpacePoint* sp, double& s, double& Distance) const
740  {
741  const double* xyz = sp->XYZ();
742  TVector3 Vec(xyz[0],xyz[1],xyz[2]);
743  GetClosestApproach(Vec, s, Distance);
744  }
745 
746  //----------------------------------------------------------------------
747  // Calculate the closest approach of this track to a given seed
748  // and also the point where this occurs
749 
750  void BezierTrack::GetClosestApproach( recob::Seed const& seed, double& s, double& Distance) const
751  {
752  double SeedPt[3], SeedErr[3];
753  seed.GetPoint(SeedPt,SeedErr);
754  TVector3 Vec(SeedPt[0],SeedPt[1],SeedPt[2]);
755  GetClosestApproach(Vec, s, Distance);
756  }
757 
758 
759 
760  //----------------------------------------------------------------------
761  // Calculate the closest approach of this track to a given position
762  // and also the point where this occurs
763 
764  void BezierTrack::GetClosestApproach( TVector3 vec, double& s, double& Distance) const
765  {
766  // const detinfo::DetectorProperties* det = art::ServiceHandle<detinfo::DetectorPropertiesService>()->provider();
768 
769  double iS, xyz[3], MinDistanceToPoint=10000, MinS=0;
770 
771  for(int i=0; i<=fBezierResolution; ++i)
772  {
773  iS=float(i)/fBezierResolution;
774  GetTrackPoint(iS, xyz);
775  TVector3 trackpt(xyz[0],xyz[1],xyz[2]);
776 
777  float d = (vec-trackpt).Mag();
778 
779  if(d<MinDistanceToPoint)
780  {
781  MinDistanceToPoint=d;
782  MinS=iS;
783  }
784  }
785 
786  s = MinS;
787  Distance = MinDistanceToPoint;
788 
789 
790  }
791 
792 
793 
794  //----------------------------------------------------------------------
795  // Calculate the direction of the track by finding the difference
796  // in position between two points. Dir is normalized to 1
797  //
798 
799  void BezierTrack::GetTrackDirection(double s, double * xyz) const
800  {
801 
802  if((s<0.5/fBezierResolution)||(s>(1.-0.5/fBezierResolution)))
803  {
804  if (( s < 0.5 / fBezierResolution ) && ( s > -0.00001 ) )
805  s = 0.5 / fBezierResolution;
806  else if((s>(1.-0.5/fBezierResolution)) && ( s < 1.00001)) s = 1.-0.5/fBezierResolution;
807  else
808  throw cet::exception("BezierTrack error: s out of range")<<
809  " cannot query gradient within "<< 0.5/fBezierResolution<<
810  " of track end. You asked for s = "<<s <<
811  ", which is out of range \n";
812  }
813  double xyz1[3], xyz2[3];
814  GetTrackPoint(s - 0.5/fBezierResolution, xyz1);
815  GetTrackPoint(s + 0.5/fBezierResolution, xyz2);
816 
817  double dx = pow(pow(xyz1[0]-xyz2[0],2)+
818  pow(xyz1[1]-xyz2[1],2)+
819  pow(xyz1[2]-xyz2[2],2),0.5);
820 
821  for(int i=0; i!=3; ++i)
822  {
823  xyz[i] = (xyz2[i]-xyz1[i])/dx;
824  }
825 
826  }
827 
828 
829  //----------------------------------------------------------------------
830  // Friendly versions returning TVector3's
831  //
832 
833 
834  //----------------------------------------------------------------------
835  TVector3 BezierTrack::GetTrackPointV(double s) const
836  {
837  double xyz[3];
838  GetTrackPoint(s,xyz);
839  TVector3 ReturnVec(xyz[0],xyz[1],xyz[2]);
840  return ReturnVec;
841  }
842 
843  //----------------------------------------------------------------------
844  TVector3 BezierTrack::GetTrackDirectionV(double s) const
845  {
846  double xyz[3];
847  GetTrackDirection(s,xyz);
848  TVector3 ReturnVec(xyz[0],xyz[1],xyz[2]);
849  return ReturnVec;
850  }
851 
852 
853 
854  //----------------------------------------------------------------------
855  // Method for finding rate at which the track direction changes
856  // (output is local dtheta/dx)
857 
858  double BezierTrack::GetCurvature(double s) const
859  {
860  if((s<1./fBezierResolution)||(s>(1.-1./fBezierResolution)))
861  {
862  throw cet::exception("BezierTrack error: s out of range")<<
863  " cannot query curvature within "<< 1./fBezierResolution<<
864  " of track end. You asked for s = "<<s <<
865  ", which is out of range \n";
866  }
867 
868  TVector3 Pos1 = GetTrackPointV(s - 0.5/fBezierResolution);
869  TVector3 Pos2 = GetTrackPointV(s );
870  TVector3 Pos3 = GetTrackPointV(s + 0.5/fBezierResolution);
871 
872  double dx = (1./fBezierResolution)*fTrackLength;
873  double dtheta = (Pos3-Pos2).Angle(Pos2-Pos1);
874 
875  return (dtheta/dx);
876  }
877 
878 
879  //----------------------------------------------------------------------
880  // Find the RMS curvature along the entire track
881  // (possible measure of multiple scattering)
882 
884  {
885  double RMS =0.;
886  for(int i=1; i!=(fBezierResolution-1); ++i)
887  {
888  RMS += pow(GetCurvature( float(i)/fBezierResolution),2);
889  }
890  return (pow(RMS/(fBezierResolution-2),0.5));
891  }
892 
893 
894 
895  //----------------------------------------------------------------------
896  // return the track length (already calculated, so easy!)
897  //
898 
899  double BezierTrack::GetLength() const
900  {
901  return fTrackLength;
902  }
903 
904  //--------------------------------------------
905 
906  BezierTrack BezierTrack::GetPartialTrack(double LowS, double HighS)
907  {
908  if(!((LowS>=0)&&(HighS<=1.0)&&(LowS<HighS)))
909  {
910  mf::LogError("BezierTrack")<<"Error in partial track calc - S out of range";
911  }
912 
913  int LowSegment = WhichSegment(LowS);
914  int HighSegment = WhichSegment(HighS);
915 
916  TVector3 HighEnd = GetTrackPointV(HighS);
917  TVector3 LowEnd = GetTrackPointV(LowS);
918 
919  if(LowSegment!=HighSegment)
920  {
921 
922  std::vector<recob::Seed> NewSeedCollection;
923  for(int seg=LowSegment+1; seg<=HighSegment; ++seg)
924  {
925  NewSeedCollection.push_back(fSeedCollection.at(seg));
926  }
927 
928  double PtLow[3], DirLow[3], Err[3];
929  double PtHigh[3], DirHigh[3];
930  double LengthLow, LengthHigh;
931 
932  NewSeedCollection.at(0).GetPoint(PtLow,Err);
933  NewSeedCollection.at(0).GetDirection(DirLow,Err);
934  LengthLow = NewSeedCollection.at(0).GetLength();
935 
936  NewSeedCollection.at(NewSeedCollection.size()-1).GetPoint(PtHigh,Err);
937  NewSeedCollection.at(NewSeedCollection.size()-1).GetDirection(DirHigh,Err);
938  LengthHigh = NewSeedCollection.at(NewSeedCollection.size()-1).GetLength();
939 
940  double LowScale = fabs((TVector3(PtLow[0],PtLow[1],PtLow[2]) - LowEnd).Dot(TVector3(DirLow[0],DirLow[1],DirLow[2]).Unit()));
941 
942  double HighScale = fabs((TVector3(PtHigh[0],PtHigh[1],PtHigh[2]) - HighEnd).Dot(TVector3(DirHigh[0],DirHigh[1],DirHigh[2]).Unit()));
943 
944 
945  for(size_t n=0; n!=3; ++n)
946  {
947  DirLow[n] *= LowScale / LengthLow;
948  DirHigh[n] *= HighScale / LengthHigh;
949  Err[n] = 0;
950  }
951 
952  NewSeedCollection.at(0).SetDirection(DirLow, Err);
953  NewSeedCollection.at(NewSeedCollection.size()-1).SetDirection(DirHigh, Err);
954  return trkf::BezierTrack(NewSeedCollection);
955  }
956  else
957  {
958  double Pt[3], Dir[3], Err[3];
959  for(size_t n=0; n!=3; ++n)
960  {
961  Pt[n] = 0.5*(HighEnd[n] + LowEnd[n]);
962  Dir[n] = 0.5*(HighEnd[n] - LowEnd[n]);
963  Err[n] = 0;
964  }
965  recob::Seed OneSeed(Pt, Dir, Err, Err);
966  std::vector<recob::Seed> NewSeedCollection;
967  NewSeedCollection.push_back(OneSeed);
968 
969  return trkf::BezierTrack(NewSeedCollection);
970  }
971 
972  }
973 
974  //----------------------------------------------------------------------
975  // Fill the dQdx vector for the track, based on a set of hits
976  // provided
977 
979  {
980  fdQdx.clear();
981 
982  std::map<int, std::map<int, double> > hitmap;
983  // ^ ^ ^
984  // view seg charge
985 
986  for(size_t i=0; i!=Hits.size(); ++i)
987  {
988  double Distance, S;
989  GetClosestApproach(Hits.at(i), S, Distance);
990 
991  (hitmap[Hits.at(i)->View()])[WhichSegment(S)] += Hits.at(i)->Integral();
992  }
993 
994  int NSeg = NSegments();
995 
996  for(std::map<int,std::map<int,double> >::const_iterator itview=hitmap.begin();
997  itview!=hitmap.end(); ++itview)
998  {
999  std::vector<double> ThisViewdQdx;
1000  ThisViewdQdx.resize(NSeg);
1001  for(std::map<int,double>::const_iterator itseg=itview->second.begin();
1002  itseg!=itview->second.end(); ++itseg)
1003  {
1004  int seg = itseg->first;
1005 
1006  // need to nudge hits which fell outside the track
1007 
1008  if((seg>-1) && (seg<NSeg))
1009  ThisViewdQdx[seg] = (itseg->second / fSegmentLength[seg]);
1010  }
1011  fdQdx.push_back(ThisViewdQdx);
1012  }
1013 
1014  }
1015 
1016 
1017 
1018  //----------------------------------------------------------------------
1019  // Fill the dQdx vector for the track, based on a set of hits
1020  // provided - optimized version
1021 
1022  void BezierTrack::CalculatedQdx(art::PtrVector<recob::Hit> const& Hits, std::vector<double> const& SValues)
1023  {
1024  fdQdx.clear();
1025 
1026  std::map<int, std::map<int, double> > hitmap;
1027  // ^ ^ ^
1028  // view seg charge
1029 
1030  for(size_t i=0; i!=Hits.size(); ++i)
1031  {
1032 
1033  (hitmap[Hits.at(i)->View()])[WhichSegment(SValues.at(i))] += Hits.at(i)->Integral();
1034  }
1035 
1036  int NSeg = NSegments();
1037 
1038  for(std::map<int,std::map<int,double> >::const_iterator itview=hitmap.begin();
1039  itview!=hitmap.end(); ++itview)
1040  {
1041  std::vector<double> ThisViewdQdx;
1042  ThisViewdQdx.resize(NSeg);
1043  for(std::map<int,double>::const_iterator itseg=itview->second.begin();
1044  itseg!=itview->second.end(); ++itseg)
1045  {
1046 
1047  int seg = itseg->first;
1048 
1049  // need to nudge hits which fell outside the track
1050 
1051  if((seg>-1) && (seg<NSeg))
1052  ThisViewdQdx[seg] = (itseg->second / fSegmentLength[seg]);
1053  }
1054  fdQdx.push_back(ThisViewdQdx);
1055  }
1056 
1057 
1058  }
1059 
1060 
1061  //----------------------------------------------------------------------
1062  // Get dQdx for a particular S value
1063  //
1064 
1065  double BezierTrack::GetdQdx(double s, unsigned int view) const
1066  {
1067  view++;
1068  if((s<0.)||(s>1.))
1069  {
1070  throw cet::exception("Bezier dQdx: S out of range")
1071  <<"Bezier track S value of " << s <<" is not in the range 0<S<1"
1072  <<"\n";
1073  }
1074  if( /* (view<0)|| */ view>(fdQdx.size()-1))
1075  {
1076  throw cet::exception("Bezier dQdx: view out of range")
1077  <<"Bezier track view value of " << view <<" is not in the range "
1078  <<"of stored views, 0 < view < " << fdQdx.size()
1079  <<"\n";
1080  }
1081  int Segment = WhichSegment(s);
1082  // if((Segment>=fdQdx[view].size())||(Segment<0))
1083  // {
1084  // throw cet::exception("Bezier dQdx: segment of range")
1085  // <<"Bezier track segment value of " << Segment <<" is not in the range "
1086  // <<"of stored segments, 0 < seg < " << fdQdx[view].size()
1087  // <<"\n";
1088  // }
1089  if( ( Segment < (int)fdQdx[view].size() ) && (Segment>1))
1090  return fdQdx[view][Segment];
1091  else
1092  {
1093  mf::LogVerbatim("BezierTrack")<<"GetdQdx : Bad s " <<s<<", " <<Segment<<std::endl;
1094  return 0;
1095  }
1096  }
1097 
1098 
1099 
1100 
1101  //----------------------------------------------------------------------
1102  // Get RMS dQdx for a particular view
1103  //
1104 
1105  double BezierTrack::GetViewdQdx(unsigned int view) const
1106  {
1107  view++;
1108  if(/* (view<0)|| */ view>fdQdx.size()-1)
1109  {
1110  throw cet::exception("view out of range")
1111  <<"Bezier track view value of " << view <<" is not in the range "
1112  <<"of stored views, 0 < view < " << fdQdx.size()
1113  <<"\n";
1114  }
1115 
1116  size_t NSeg = NSegments();
1117  double TotaldQdx = 0.;
1118  for(size_t i=0; i!=NSeg; ++i)
1119  {
1120  TotaldQdx+=fdQdx.at(view).at(i)*fSegmentLength[i];
1121  }
1122  return TotaldQdx / fTrackLength;
1123  }
1124 
1125 
1126 
1127  //----------------------------------------------------------------------
1128  // Get total charge for a particular view
1129  //
1130 
1131  double BezierTrack::GetTotalCharge(unsigned int View) const
1132  {
1133  View++;
1134  return GetViewdQdx(View) * fTrackLength;
1135  }
1136 
1137 
1138 
1139  //----------------------------------------------------------------------
1140  // Find which track segment a particular S lies in
1141  //
1142  int BezierTrack::WhichSegment(double s) const
1143  {
1144  int ReturnVal=-1;
1145  for(size_t i=0; i!=fCumulativeLength.size()-1; i++)
1146  {
1147  if( (fCumulativeLength.at(i)/fTrackLength <= s)
1148  &&(fCumulativeLength.at(i+1)/fTrackLength >= s))
1149  ReturnVal=i;
1150  }
1151  if( ( s<(fCumulativeLength.at(0)/fTrackLength)) && (s>-0.0001)) ReturnVal=0;
1152  return ReturnVal;
1153  }
1154 
1155 
1156  //----------------------------------------------------------------------
1157  // Return the number of track segments
1158  //
1159 
1161  {
1162  return fTraj.NumberTrajectoryPoints();
1163  }
1164 
1165 
1166  //----------------------------------------------------------------------
1167 
1168  std::vector<recob::SpacePoint> BezierTrack::GetSpacePointTrajectory(int N)
1169  {
1170  std::vector<recob::SpacePoint> spts(N);
1171  for(int i=0; i!=N; ++i)
1172  {
1173  double xyz[3];
1174  double ErrXYZ[3]={0.1,0.1,0.1};
1175  GetTrackPoint(float(i)/N,xyz);
1176  recob::SpacePoint TheSP(xyz, ErrXYZ, util::kBogusD, i);
1177 
1178  spts[i] = TheSP;
1179 
1180  }
1181 
1182  return spts;
1183  }
1184 
1185 
1186  //-----------------------------------------
1188  {
1189  std::vector<recob::Seed> SeedCol = GetSeedVector();
1190  std::reverse(SeedCol.begin(), SeedCol.end());
1191  for(size_t i=0; i!=SeedCol.size(); ++i)
1192  {
1193  SeedCol.at(i)=SeedCol.at(i).Reverse();
1194  }
1195  return BezierTrack(SeedCol);
1196  }
1197 
1198  //-----------------------------------------
1199  void BezierTrack::FillTrackVectors(std::vector<TVector3>& xyzVector,
1200  std::vector<TVector3>& dirVector,
1201  double const ds) const
1202  {
1203  const double s = ds / GetLength();
1204  const size_t n_traj_pts = (size_t)(GetLength()/ds);
1205 
1206  //+2: evenly space points, plus one for start and one for end
1207  xyzVector.resize(n_traj_pts+2);
1208  dirVector.resize(n_traj_pts+2);
1209 
1210  for(size_t i_traj=0; i_traj<=n_traj_pts; i_traj++){
1211  xyzVector[i_traj] = this->GetTrackPointV(i_traj*s);
1212  dirVector[i_traj] = this->GetTrackDirectionV(i_traj*s);
1213  }
1214 
1215  xyzVector[n_traj_pts+1] = this->GetTrackPointV(1.);
1216  dirVector[n_traj_pts+1] = this->GetTrackDirectionV(1.);
1217 
1218 
1219  }
1220 
1221 }
1222 
1223 
1224 
1225 
Float_t x
Definition: compare.C:6
recob::Trajectory fTraj
Internal trajectory representation.
Definition: BezierTrack.h:105
Float_t s
Definition: plot.C:23
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Encapsulate the construction of a single cyostat.
std::vector< recob::Seed > GetSeedVector()
int WhichSegment(double S) const
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:145
double GetTrackPitch(geo::View_t view, double s, double WirePitch, unsigned int c=0, unsigned int t=0)
Declaration of signal hit object.
double GetRMSCurvature() const
void GetPoint(double *Pt, double *Err) const
Definition: Seed.cxx:112
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
Point_t const & End() const
Returns the position of the last point of the trajectory [cm].
Definition: Trajectory.h:232
TVector3 GetTrackDirectionV(double s) const
std::vector< recob::Seed > fSeedCollection
Definition: BezierTrack.h:115
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:130
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
int NSegments() const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::vector< double > fSegmentLength
Definition: BezierTrack.h:112
BezierTrack GetPartialTrack(double LowS, double HighS)
void GetProjectedPointUVWX(double s, double *uvw, double *x, int c, int t) const
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
void FillTrajectoryVectors()
void GetTrackPoint(double s, double *xyz) const
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
void CalculatedQdx(art::PtrVector< recob::Hit >const &)
Vector_t DirectionAtPoint(size_t i) const
Computes and returns the direction of the trajectory at a point.
Definition: Trajectory.cxx:118
tracking::Vector_t Vector_t
Definition: Track.h:57
void GetClosestApproaches(art::PtrVector< recob::Hit > const &hits, std::vector< double > &s, std::vector< double > &Distances) const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
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.
void hits()
Definition: readHits.C:15
std::vector< double > fCumulativeLength
Definition: BezierTrack.h:113
intermediate_table::const_iterator const_iterator
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:441
long seed
Definition: chem4.cc:68
std::vector< geo::Point_t > convertCollToPoint(std::vector< Point > const &coll)
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:34
Service for finding 3D track seeds.
double GetTotalCharge(unsigned int View) const
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.
Utilities to extend the interface of geometry vectors.
Float_t d
Definition: plot.C:237
Point_t const & LocationAtPoint(size_t i) const
Returns the position at the specified trajectory point.
Definition: Trajectory.h:242
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
void GetProjectedPointUVWT(double s, double *uvw, double *ticks, int c, int t) const
const Double32_t * XYZ() const
Definition: SpacePoint.h:65
BezierTrack(int id, const recob::Trajectory &traj)
Definition: BezierTrack.cxx:29
reference at(size_type n)
Definition: PtrVector.h:365
tracking::Positions_t Positions_t
Type of trajectory point list.
Definition: Trajectory.h:85
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
double GetSegmentLength(recob::Seed const &s1, recob::Seed const &s2)
size_t NumberTrajectoryPoints() const
Returns the number of stored trajectory points.
Definition: Trajectory.h:162
Definition of data types for geometry description.
BezierTrack Reverse()
tracking::Momenta_t Momenta_t
Type of momentum list.
Definition: Trajectory.h:88
size_type size() const
Definition: PtrVector.h:308
Detector simulation of raw signals on wires.
double GetCurvature(double s) const
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
A trajectory in space reconstructed from hits.
Definition: Trajectory.h:73
void GetTrackDirection(double s, double *xyz) const
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
anab::Calorimetry GetCalorimetryObject(std::vector< art::Ptr< recob::Hit > > const &Hits, geo::SigType_t sigtype, calo::CalorimetryAlg const &)
Encapsulate the construction of a single detector plane.
std::vector< std::vector< double > > fdQdx
Definition: BezierTrack.h:109
TDirectory * dir
Definition: macro.C:5
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
std::vector< geo::Vector_t > convertCollToVector(std::vector< Vector > const &coll)
std::vector< recob::SpacePoint > GetSpacePointTrajectory(int N)
void FillTrackVectors(std::vector< TVector3 > &xyzVector, std::vector< TVector3 > &dirVector, double const ds=0.1) const
tracking::Point_t Point_t
Definition: Track.h:56
void GetBezierPointXYZ(recob::Seed const &s1, recob::Seed const &s2, float t, double *xyz)
void WireEndPoints(geo::WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
TVector3 GetTrackPointV(double s) const
Char_t n[5]
double GetdQdx(double s, unsigned int View) const
Direction
Definition: AssnsIter.h:24
constexpr double kBogusD
obviously bogus double value
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:299
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:49
void GetClosestApproach(recob::Hit const &hit, double &s, double &Distance) const
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
Point_t const & Start() const
Returns the position of the first point of the trajectory [cm].
Definition: Trajectory.h:228
double GetLength() const
Namespace collecting geometry-related classes utilities.
Float_t track
Definition: plot.C:34
void clear()
Definition: PtrVector.h:537
Float_t w
Definition: plot.C:23
double dEdx_AMP(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
art framework interface to geometry description
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:52
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.
double GetViewdQdx(unsigned int View) const