CosmicTrackAlg.cxx
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////
2 /// \file CosmicTrackAlg.cxx
3 /// \brief Track finder for cosmic rays
4 /// \author brebel@fnal.gov, gsdavies@iastate.edu
5 /// \date
6 ///////////////////////////////////////////////////////////////////////
8 
9 // NOvASoft includes
10 #include "RecoBase/Track.h"
11 #include "Geometry/Geometry.h"
13 #include "GeometryObjects/Geo.h"
14 #include "Utilities/func/MathUtil.h"
15 
16 // ART includes
17 #include "fhiclcpp/ParameterSet.h"
20 
21 namespace trk {
22 
23  // Constructor
25  : TrackAlg(pset)
26  {
27  fDHitGood = pset.get<double>("DHitGood");
28  }
29 
30  // Destructor
32 
33  // MakeTrack
34  std::vector<rb::Track> CosmicTrackAlg::MakeTrack( const rb::Cluster* slice ) {
35 
36  std::vector<rb::Track> tracks;
37 
38  // We'll need some information about the
39  // cell locations. That comes from the Geometry object.
40  //
42 
43  // flags for failure modes
44  bool flagxz = true;
45  bool flagyz = true;
46 
47  // loop over all the hits for this slice and get the
48  // x or y positions for the views
49 
50  std::vector<double> xzViewX;
51  std::vector<double> xzViewZ;
52  std::vector<double> yzViewY;
53  std::vector<double> yzViewZ;
54  std::vector<double> xzViewW; // W = weight
55  std::vector<double> yzViewW; // W = weight
56  double xyz[3]; // xyz[0]=x, xyz[1]=y, xyz[2]=z
57  const int hitMax = slice->NCell();
58  for(int hitIdx = 0; hitIdx < hitMax; ++hitIdx){
59  art::Ptr<rb::CellHit> chit = slice->Cell(hitIdx);
60 
61  double sig = 1.;
62  geom->Plane(chit->Plane())->Cell(chit->Cell())->GetCenter(xyz);
63  if(chit->View() == geo::kX){
64  xzViewX.push_back(xyz[0]);
65  xzViewZ.push_back(xyz[2]);
66  xzViewW.push_back(sig);
67 
68  LOG_DEBUG("CosmicTrack")
69  << "x view " << xzViewZ[xzViewZ.size()-1]
70  << " " << xzViewX[xzViewX.size()-1]
71  << " " << chit->TNS();
72  }
73  if(chit->View() == geo::kY){
74  yzViewY.push_back(xyz[1]);
75  yzViewZ.push_back(xyz[2]);
76  yzViewW.push_back(sig);
77 
78  LOG_DEBUG("CosmicTrack")
79  << "y view " << yzViewZ[yzViewZ.size()-1]
80  << " " << yzViewY[yzViewY.size()-1]
81  << " " << chit->TNS();
82  }
83  }// end loop over hits in this track
84 
85  if(xzViewZ.size() < 2 && yzViewZ.size() < 2){
86  LOG_DEBUG("CosmicTrack")
87  << " Not enough hits in either view to fit for track";
88  return tracks;
89  }
90 
91  // Want to use the geo::LinFitMinDperp method to figure which hits are
92  // closest to the line. Need vectors of x/z, y/z and uncertainties for
93  // the positions and it outputs the start and end points for the line in
94  // each 2D view. Function returns the chi^2
95 
96  double xzChi2 = 0.;
97  double xzStart[2] = {0.};
98  double xzEnd[2] = {0.};
99  unsigned int xzNDrop = this->FitView(xzViewZ, xzViewX, xzViewW, xzChi2, xzStart, xzEnd);
100  if(xzEnd[0]==xzStart[0] && xzEnd[1]==xzStart[1] && xzViewW.size()>1) flagxz = false ;
101  if(xzViewZ.size() == 1){
102  xzStart[0] = xzEnd[0] = xzViewZ[0];
103  xzStart[1] = xzEnd[1] = xzViewX[0];
104  }
105 
106  double yzChi2 = 0.;
107  double yzStart[2] = {0.};
108  double yzEnd[2] = {0.};
109  unsigned int yzNDrop = this->FitView(yzViewZ, yzViewY, yzViewW, yzChi2, yzStart, yzEnd);
110  if(yzEnd[0]==yzStart[0] && yzEnd[1]==yzStart[1] && yzViewW.size()>1) flagyz = false ;
111  if(yzViewZ.size() == 1){
112  yzStart[0] = yzEnd[0] = yzViewZ[0];
113  yzStart[1] = yzEnd[1] = yzViewY[0];
114  }
115 
116  LOG_DEBUG("CosmicTrack")
117  << "# xz hits = " << xzViewZ.size()-xzNDrop
118  << " chi^2 = " << xzChi2 << std::endl
119  << " # yz hits = " << yzViewZ.size()-yzNDrop
120  << " chi^2 = " << yzChi2;
121 
122 
123  // Tracks with only plane in a view are going to give infinite gradients
124  // when we try to extend them later. Tilt them over as much as possible.
125  // Try to make line extrapolate into detector rather than towards the outside.
126  // Especially important for case of fits with no change in z in either view.
127 
128  if(fabs(xzEnd[0]-xzStart[0]) < 1){ // check xz view for 'verticalness'
129 
130  double ZaveY = yzEnd[0]-yzStart[0]/2.; // Center position of Z in yz view
131 
132  if( fabs(xzStart[1]) < fabs(xzEnd[1]) ) { // make sure to lean 'into' detector
133  if( xzStart[0] < ZaveY ) { // make sure to point it the right direction
134  xzStart[0] += geom->Plane(0)->Cell(0)->HalfD();
135  xzEnd[0] -= geom->Plane(0)->Cell(0)->HalfD(); }
136  if( xzStart[0] > ZaveY ) {
137  xzStart[0] -= geom->Plane(0)->Cell(0)->HalfD();
138  xzEnd[0] += geom->Plane(0)->Cell(0)->HalfD(); }
139  }
140  else { // other end is closer to center
141  if( xzEnd[0] > ZaveY ) {
142  xzStart[0] += geom->Plane(0)->Cell(0)->HalfD();
143  xzEnd[0] -= geom->Plane(0)->Cell(0)->HalfD(); }
144  if( xzEnd[0] < ZaveY ) {
145  xzStart[0] -= geom->Plane(0)->Cell(0)->HalfD();
146  xzEnd[0] += geom->Plane(0)->Cell(0)->HalfD(); }
147  }
148  }
149 
150  if(fabs(yzEnd[0]-yzStart[0]) < 1){ // check yz view for verticalness
151 
152  double ZaveX = xzEnd[0]-xzStart[0]/2.; // Center position of Z in xz view
153 
154  if( fabs(yzStart[1]) < fabs(yzEnd[1]) ) { // make sure to lean 'into' detector
155  if( yzStart[0] < ZaveX ) { // make sure to point it the right direction
156  yzStart[0] += geom->Plane(0)->Cell(0)->HalfD();
157  yzEnd[0] -= geom->Plane(0)->Cell(0)->HalfD(); }
158  if( yzStart[0] > ZaveX ) {
159  yzStart[0] -= geom->Plane(0)->Cell(0)->HalfD();
160  yzEnd[0] += geom->Plane(0)->Cell(0)->HalfD(); }
161  }
162  else { // other end is closer to center
163  if( yzEnd[0] > ZaveX ) {
164  yzStart[0] += geom->Plane(0)->Cell(0)->HalfD();
165  yzEnd[0] -= geom->Plane(0)->Cell(0)->HalfD(); }
166  if( yzEnd[0] < ZaveX ) {
167  yzStart[0] -= geom->Plane(0)->Cell(0)->HalfD();
168  yzEnd[0] += geom->Plane(0)->Cell(0)->HalfD(); }
169  }
170  }
171 
172  // which z values define the end points?
173  double startz = TMath::Min(yzStart[0], xzStart[0]);
174  double endz = TMath::Max(yzEnd[0], xzEnd[0]);
175 
176  // are there at least 2 hits in this view? if not, reset the start
177  // and end z positions to be based on the view with hits
178  if(xzViewZ.size() < 2){
179  // startz = yzStart[0];
180  // endz = yzEnd[0];
181  flagxz=false;
182  }
183  if(yzViewZ.size() < 2){
184  // startz = xzStart[0];
185  // endz = xzEnd[0];
186  flagyz=false;
187  }
188 
189  if(flagxz&&flagyz) {
190 
191  // Adjust the start and end points of each view to reflect how far the
192  // z extent got moved
193  const double xzSlope = (xzEnd[1]-xzStart[1])/(xzEnd[0]-xzStart[0]);
194  xzStart[1] += (startz-xzStart[0])*xzSlope;
195  xzEnd[1] += (endz-xzEnd[0])*xzSlope;
196 
197  const double yzSlope = (yzEnd[1]-yzStart[1])/(yzEnd[0]-yzStart[0]);
198  yzStart[1] += (startz-yzStart[0])*yzSlope;
199  yzEnd[1] += (endz-yzEnd[0])*yzSlope;
200 
201  // Now it's safe to update the z endpoints themselves
202  xzStart[0] = yzStart[0] = startz;
203  xzEnd[0] = yzEnd[0] = endz;
204 
205  LOG_DEBUG("CosmicTrack")
206  << startz << " " << endz << std::endl
207  << xzStart[0] << " " << xzStart[1] << " "
208  << xzEnd[0] << " " << xzEnd[1] << std::endl
209  << yzStart[0] << " " << yzStart[1] << " "
210  << yzEnd[0] << " " << yzEnd[1] << std::endl;
211 
212  // swap the start and end if timing indicates the track goes upstream
213  if(!IsTrackDownstreamFromTiming(slice)){
214  std::swap(xzStart[0], xzEnd[0]);
215  std::swap(xzStart[1], xzEnd[1]);
216  std::swap(yzStart[0], yzEnd[0]);
217  std::swap(yzStart[1], yzEnd[1]);
218  std::swap(startz, endz);
219  }
220 
221 
222  // now go through each view and only keep hits that lie near the line in
223  // that view (ie FitView hasn't set their weight to zero).
225 
226  //find min and max planes
227  int minPlane = 9999;
228  int maxPlane = -9999;
229 
230  for(unsigned int hitIdx = 0; hitIdx < slice->NXCell(); ++hitIdx){
231  if(xzViewW[hitIdx] != 0){
232  art::Ptr<rb::CellHit> ch = slice->XCell(hitIdx);
233  chits.push_back(ch);
234  if (ch->Plane() < minPlane) minPlane = ch->Plane();
235  if (ch->Plane() > maxPlane) maxPlane = ch->Plane();
236  }
237  }
238  for(unsigned int hitIdx = 0; hitIdx < slice->NYCell(); ++hitIdx){
239  if(yzViewW[hitIdx] != 0){
240  art::Ptr<rb::CellHit> ch = slice->YCell(hitIdx);
241  chits.push_back(ch);
242  if (ch->Plane() < minPlane) minPlane = ch->Plane();
243  if (ch->Plane() > maxPlane) maxPlane = ch->Plane();
244  }
245  }
246 
247  if(chits.empty()){
249  << "No hits left on the track after clean up stage ";
250  }
251 
252  //sort cells by plane, low to high before doing trajectory calculation
253  rb::SortByPlane(chits);
254  //if track is starting from the upstream end, reverse the sort
255  if (startz > endz) std::reverse(chits.begin(),chits.end());
256 
257  // We can write out a proper 3D track; assume downward going
258  TVector3 start(xzStart[1], yzStart[1], startz);
259  TVector3 stop(xzEnd[1], yzEnd[1], endz);
260 
261  if(start[1] < stop[1]) {
262  TVector3 temp = start;
263  start = stop;
264  stop = temp;
265  }
266 
267  //sort cells by plane, low to high before doing trajectory calculation
268  rb::SortByPlane(chits);
269  //if track is starting from the upstream end, reverse the sort
270  if (start[2] > stop[2]) std::reverse(chits.begin(),chits.end());
271 
272  //restrict track to exist inside detector; if this isn't possible, the track is no good, so don't write
273  if(geo::ClampRayToDetectorVolume(&start, &stop, &(*geom))) {
274 
275  rb::Track track(chits, start, stop-start);
276 
277  //find valid z range incase ends of tracks got clipped
278  double minZ = std::min(start[2],stop[2]);
279  double maxZ = std::max(start[2],stop[2]);
280 
281  // add a trajectory point for each plane - set
282  // the point based on the z position of each plane
283  // and the direction of the track
284  // the first and last planes are the start and stop
285  // points, presumably
286 
287  int prevPlane = chits.front()->Plane();
288  double xyz[3] = {0.};
289  for(size_t c = 1; c < chits.size()-1; ++c){
290  int plane = chits.at(c)->Plane();
291 
292  //check in case there are more then one hit in min/max plane not to add point multiple times
293  if ((plane == minPlane) || (plane == maxPlane)) continue;
294 
295  if(plane != prevPlane) {
296  geom->Plane(plane)->Cell(chits.at(c)->Cell())->GetCenter(xyz);
297  //make sure plane is within range of track if ends were clipped to the detector volume
298  if ((xyz[2] > minZ) && (xyz[2] < maxZ)){
299  TVector3 dir = track.Dir().Unit();
300  TVector3 point(start.X() + (xyz[2] - start.Z())*dir.X()/dir.Z(),
301  start.Y() + (xyz[2] - start.Z())*dir.Y()/dir.Z(),
302  xyz[2]);
303  track.AppendTrajectoryPoint(point);
304  }
305  }
306 
307  prevPlane = plane;
308  }
309 
310  track.AppendTrajectoryPoint(stop);
311 
312  tracks.push_back(track);
313  return tracks;
314  }
315  // if track isn't good in this case, just don't write it out
316 
317  }
318 
319  // if at least one of the views was bad, no 3-D track. Write out any 2-D tracks that are worthwhile
320  if(flagxz&&!flagyz) { //xz view track only
321 
323 
324  for(unsigned int hitIdx = 0; hitIdx < slice->NXCell(); ++hitIdx){
325  if(xzViewW[hitIdx] != 0) chits.push_back(slice->XCell(hitIdx));
326  }
327 
328  rb::Track track(chits, geo::kX, xzStart[1], xzStart[0], xzEnd[1]-xzStart[1], xzEnd[0]-xzStart[0]);
329  track.AppendTrajectoryPoint(xzEnd[1],xzEnd[0]);
330  tracks.push_back(track);
331  return tracks;
332  }
333 
334  if(flagyz&&!flagxz) { //yz view track only
336 
337  for(unsigned int hitIdx = 0; hitIdx < slice->NYCell(); ++hitIdx){
338  if(yzViewW[hitIdx] != 0) chits.push_back(slice->YCell(hitIdx));
339  }
340 
341  rb::Track track(chits, geo::kY, yzStart[1], yzStart[0], yzEnd[1]-yzStart[1], yzEnd[0]-yzStart[0]);
342  track.AppendTrajectoryPoint(yzEnd[1],yzEnd[0]);
343  tracks.push_back(track);
344  return tracks;
345  }
346 
347  return tracks;
348  } // End of MakeTrack
349 
350  //......................................................................
351  unsigned int CosmicTrackAlg::FitView(std::vector<double> &x,
352  std::vector<double> &y,
353  std::vector<double> &w_orig,
354  double &chiSqr,
355  double *start,
356  double *end)
357  {
358  // We need to store the original weights in case we need to restore them
359  std::vector<double> w = w_orig;
360 
361  const unsigned int nhit = w.size();
362 
363  chiSqr = -9999.;
364 
365  // First pass, drop hits that are clear outliers (more than 2x tolerance
366  // from anything else). If it turns out they really are good hits (eg
367  // surrounded by bad channels) they will be added back in by the last
368  // step. But this helps prevent distant noise hits from throwing off the
369  // original fit.
370  unsigned int ndrop = 0;
371  for(unsigned int i = 0; i < nhit; ++i){
372  double closest = 1e10;
373  for(unsigned int j = 0; j < nhit; ++j){
374  if(i == j) continue;
375 
376  const double dsq = util::sqr(x[i]-x[j])+util::sqr(y[i]-y[j]);
377  closest = std::min(closest, dsq);
378  }
379 
380  if(closest > util::sqr(fDHitGood*2)){
381  w[i] = 0;
382  ++ndrop;
383  }
384  }
385 
386  if(nhit-ndrop == 0) return 0;
387 
388  if(nhit-ndrop == 1){
389  start[0] = x[0]-.1;
390  end[0] = x[0]+.1;
391  start[1] = end[1] = y[0];
392  return 1;
393  }
394 
395  // check to see if there are only 2 points the fit is easy then
396  if(nhit-ndrop == 2){
397  start[0] = x[0];
398  start[1] = y[0];
399  end[0] = x[1];
400  end[1] = y[1];
401  if(start[0] > end[0]){
402  std::swap(start[0], end[0]);
403  std::swap(start[1], end[1]);
404  }
405  return 0;
406  }
407 
408  bool droppedAny = true;
409  while(droppedAny){
410  chiSqr = geo::LinFitMinDperp(x, y, w,
411  &start[0], &start[1],
412  &end[0], &end[1]);
413 
414  LOG_DEBUG("CosmicTrack") << "end points from fit "
415  << start[0] << " " << start[1] << " " << end[0] << " " << end[1];
416 
417  // loop over the hits and for the ones that are more than fDHitGood cm
418  // off the line set the weight to be 0 so that they do not contribute to
419  // future fits. Only drop the worst hit, and then iterate to get the next
420  // worst and so on. Otherwise we can end up dropping lots of hits we
421  // shouldn't due to one outlier.
422  double dSqMax = 0;
423  int dSqMaxIdx = -1;
424  for(unsigned int n = 0; n < nhit; ++n){
425  // Already dropped
426  if(w[n] == 0) continue;
427 
428  const double dSq = geo::DsqrToLine(x[n], y[n],
429  start[0], start[1],
430  end[0], end[1]);
431  if(dSq > dSqMax){
432  dSqMax = dSq;
433  dSqMaxIdx = n;
434  }
435  } // end for n
436 
437  droppedAny = false;
438  if(dSqMax > util::sqr(fDHitGood)){
439  LOG_DEBUG("CosmicTrack") << "dropping hit at ("
440  << x[dSqMaxIdx] << ", " << y[dSqMaxIdx] << ")"
441  << " dSq = " << dSqMax;
442 
443  w[dSqMaxIdx] = 0;
444  droppedAny = true;
445  ++ndrop;
446  assert(nhit-ndrop >= 2); // If we're down to 2, we should be done
447  }
448  }// end while
449 
450  bool addedAny = false;
451  // loop over the dropped points and see if any can be added back
452  for(unsigned int n = 0; n < nhit; ++n){
453  // Already part of the fit
454  if(w[n] != 0) continue;
455 
456  const double dSq = geo::DsqrToLine(x[n], y[n],
457  start[0], start[1],
458  end[0], end[1]);
459  if(dSq < util::sqr(fDHitGood)){
460  LOG_DEBUG("CosmicTrack")
461  << "adding back hit at (" << x[n] << ", " << y[n]
462  << ")" << " dSq = " << dSq;
463 
464  w[n] = w_orig[n];
465  --ndrop;
466  addedAny = true;
467  }
468  } // end for n
469 
470  if(addedAny){
471  // Fit with this final set of points
472  chiSqr = geo::LinFitMinDperp(x, y, w,
473  &start[0], &start[1],
474  &end[0], &end[1]);
475  }
476 
477  LOG_DEBUG("CosmicTrack") << "end points from fit "
478  << start[0] << " " << start[1] << " "
479  << end[0] << " " << end[1];
480 
481  // improve end point resolution by using distance of closest approach
482  // ignore cases with completely horizontal/vertical lines to prevent failures/ infinities
483 
484  if(fabs(start[0]-end[0])>0.01&&fabs(start[1]-end[1])>0.01) {
485 
486  const TVector3 slope(end[0]-start[0],end[1]-start[1],0);
487  const TVector3 intercept(0,(-end[0]/slope[0])*slope[1]+end[1],0); // define fit line
488  double tmin[2], tmax[2];
489  TVector3 closest; // will be point of closest approach on fit line
490  tmin[0] = 9999.;
491  tmax[0] = -9999.;
492  tmin[1] = 9999.;
493  tmax[1] = -9999.;
494 
495  for(unsigned int n = 0; n < nhit; ++n){
496  if(w[n] == 0) continue;
497 
498  TVector3 point(x[n],y[n],0);
499 
500  geo::ClosestApproach(point,intercept,slope,closest);
501 
502  // save extremum; will be new end points
503  if(closest[0]<tmin[0]) { // since no vertical lines allowed, can just use extremum in z
504  tmin[0] = closest[0];
505  tmin[1] = closest[1];
506  }
507  if(closest[0]>tmax[0]) {
508  tmax[0] = closest[0];
509  tmax[1] = closest[1];
510  }
511 
512  // check which end point each extremum is closer to, set new end points accordingly
513  if(fabs(tmin[0]-end[0])<fabs(tmin[0]-start[0])) {
514  end[0] = tmin[0];
515  end[1] = tmin[1];
516  start[0] = tmax[0];
517  start[1] = tmax[1];
518  }
519  else {
520  end[0] = tmax[0];
521  end[1] = tmax[1];
522  start[0] = tmin[0];
523  start[1] = tmin[1];
524  }
525  }
526  }
527  // Communicate back which points we dropped to the caller
528  w_orig = w;
529 
530  return ndrop;
531  }
532 
533  //......................................................................
535  {
537 
538  std::vector<double> zs, ts, ws;
539 
540  const int hitMax = slice->NCell();
541  for(int hitIdx = 0; hitIdx < hitMax; ++hitIdx){
542  art::Ptr<rb::CellHit> chit = slice->Cell(hitIdx);
543 
544  double xyz[3];
545  geom->Plane(chit->Plane())->Cell(chit->Cell())->GetCenter(xyz);
546  zs.push_back(xyz[2]);
547  ts.push_back(chit->TNS());
548  ws.push_back(1);
549  }
550 
551  // figure out the direction of the muon
552  double ztStart[2] = {0.};
553  double ztEnd[2] = {0.};
554  geo::LinFitMinDperp(zs, ts, ws,
555  &ztStart[0], &ztStart[1],
556  &ztEnd[0], &ztEnd[1]);
557 
558  // the slope should be positive if time increases with z, negative
559  // otherwise
560  const double ztSlope = (ztEnd[1]-ztStart[1])/(ztEnd[0]-ztStart[0]);
561 
562  return ztSlope > 0;
563  }
564 
565 }
float TNS() const
Definition: CellHit.h:46
T max(const caf::Proxy< T > &a, T b)
#define LOG_DEBUG(stream)
Definition: Messenger.h:149
An algorithm to perform cosmic ray track fitting.
Definition: TrackAlg.h:25
double HalfD() const
Definition: CellGeo.cxx:205
unsigned int NCell(geo::View_t view) const
Number of cells in view view.
Definition: Cluster.cxx:134
art::Ptr< rb::CellHit > XCell(unsigned int xIdx) const
Get the ith cell in the x-view.
Definition: Cluster.cxx:157
fvar< T > fabs(const fvar< T > &x)
Definition: fabs.hpp:15
unsigned short Plane() const
Definition: CellHit.h:39
iterator begin()
Definition: PtrVector.h:223
geo::View_t View() const
Definition: CellHit.h:41
const CellGeo * Cell(int icell) const
Definition: PlaneGeo.h:48
Vertical planes which measure X.
Definition: PlaneGeo.h:28
double fDHitGood
Maximum distance from the line for a hit to be considered part of it.
A collection of associated CellHits.
Definition: Cluster.h:47
nhit
Definition: demo1.py:25
A rb::Prong with full reconstructed trajectory.
Definition: Track.h:20
bool ClampRayToDetectorVolume(TVector3 *p0, TVector3 *p1, const GeometryBase *geom)
If either endpoint is outside the detector move it to the edge.
Definition: Geo.cxx:640
const PlaneGeo * Plane(unsigned int i) const
Track finder for cosmic rays.
CosmicTrackAlg(fhicl::ParameterSet const &pset)
T sqr(T x)
More efficient square function than pow(x,2)
Definition: MathUtil.h:23
Horizontal planes which measure Y.
Definition: PlaneGeo.h:29
void swap(art::HLTGlobalStatus &lhs, art::HLTGlobalStatus &rhs)
unsigned short Cell() const
Definition: CellHit.h:40
Track finder for cosmic rays.
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:441
double LinFitMinDperp(const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &w, double *x1, double *y1, double *x2, double *y2)
Find the best-fit line to a collection of points in 2-D by minimizing the squared perpendicular dista...
Definition: Geo.cxx:449
art::Ptr< rb::CellHit > YCell(unsigned int yIdx) const
Get the ith cell in the y-view.
Definition: Cluster.cxx:165
double DsqrToLine(double x0, double y0, double x1, double y1, double x2, double y2)
In two dimensions, return the perpendicular distance from a point (x0,y0) to a line defined by end po...
Definition: Geo.cxx:338
void AppendTrajectoryPoint(TVector3 pt)
Definition: Track.cxx:112
T get(std::string const &key) const
Definition: ParameterSet.h:231
virtual TVector3 Dir() const
Unit vector describing prong direction.
Definition: Prong.h:77
iterator end()
Definition: PtrVector.h:237
Collect Geo headers and supply basic geometry functions.
const double j
Definition: BetheBloch.cxx:29
reference at(size_type n)
Definition: PtrVector.h:365
unsigned int FitView(std::vector< double > &x, std::vector< double > &y, std::vector< double > &w, double &chiSqr, double *start, double *end)
bool empty() const
Definition: PtrVector.h:336
size_type size() const
Definition: PtrVector.h:308
unsigned int NYCell() const
Number of cells in the y-view.
Definition: Cluster.h:108
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
art::Ptr< rb::CellHit > Cell(geo::View_t view, unsigned int viewIdx) const
Get the ith cell from view view.
Definition: Cluster.cxx:145
reference front()
Definition: PtrVector.h:379
double ClosestApproach(const double point[], const double intercept[], const double slopes[], double closest[])
Find the distance of closest approach between point and line.
Definition: Geo.cxx:222
TDirectory * dir
Definition: macro.C:5
unsigned int NXCell() const
Number of cells in the x-view.
Definition: Cluster.h:106
void geom(int which=0)
Definition: geom.C:163
assert(nhit_max >=nhit_nbins)
bool IsTrackDownstreamFromTiming(const rb::Cluster *slice) const
T min(const caf::Proxy< T > &a, T b)
Float_t track
Definition: plot.C:35
Float_t w
Definition: plot.C:20
Encapsulate the geometry of one entire detector (near, far, ndos)
void SortByPlane(std::vector< art::Ptr< rb::CellHit > > &c)
Sort c in plane order (low to high).
Definition: CellHit.cxx:124
std::vector< rb::Track > MakeTrack(const rb::Cluster *slice)