LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
TrackLineFitAlg.cxx
Go to the documentation of this file.
1 
11 extern "C" {
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 }
15 #include <stdint.h>
16 #include <iostream>
17 #include <iomanip>
18 
20 
21 
22 namespace trkf{
23 
25 
27 
28 
29 //------------------------------------------------------------------------------
30  void TrackLineFitAlg::TrkLineFit(std::vector<geo::WireID>& hitWID, std::vector<double>& hitX, std::vector<double>& hitXErr,
31  double XOrigin, TVector3& Pos, TVector3& Dir, float& ChiDOF)
32  {
33  // Linear fit using X as the independent variable. Hits to be fitted
34  // are passed in the hits vector in a pair form (X, WireID). The
35  // fitted track position at XOrigin is returned in the Pos vector.
36  // The direction cosines are returned in the Dir vector.
37  //
38  // SVD fit adapted from $ROOTSYS/tutorials/matrix/solveLinear.C
39  // Fit equation is w = A(X)v, where w is a vector of hit wires, A is
40  // a matrix to calculate a track projected to a point at X, and v is
41  // a vector (Yo, Zo, dY/dX, dZ/dX).
42 
43  // assume failure
44  ChiDOF = -1;
45 
46  if(hitX.size() < 4) return;
47  if(hitX.size() != hitWID.size()) return;
48  if(hitX.size() != hitXErr.size()) return;
49 
50  const unsigned int nvars = 4;
51  unsigned int npts = hitX.size();
52 
53  TMatrixD A(npts, nvars);
54  // vector holding the Wire number
55  TVectorD w(npts);
56  unsigned short ninpl[3] = {0};
57  unsigned short nok = 0;
58  unsigned short iht;
59  unsigned int ipl, tpc, cstat;
60  double x, cw, sw, off, wght;
61  for(iht = 0; iht < hitX.size(); ++iht) {
62  cstat = hitWID[iht].Cryostat;
63  tpc = hitWID[iht].TPC;
64  ipl = hitWID[iht].Plane;
65  // get the wire plane offset
66  off = geom->WireCoordinate(0, 0, ipl, tpc, cstat);
67  // get the "cosine-like" component
68  cw = geom->WireCoordinate(1, 0, ipl, tpc, cstat) - off;
69  // the "sine-like" component
70  sw = geom->WireCoordinate(0, 1, ipl, tpc, cstat) - off;
71  x = hitX[iht] - XOrigin;
72  if(hitXErr[iht] > 0) {
73  wght = 1 / hitXErr[iht];
74  } else {
75  wght = 1;
76  }
77  A[iht][0] = wght * cw;
78  A[iht][1] = wght * sw;
79  A[iht][2] = wght * cw * x;
80  A[iht][3] = wght * sw * x;
81  w[iht] = wght * (hitWID[iht].Wire - off);
82  ++ninpl[ipl];
83  // need at least two points in a plane
84  if(ninpl[ipl] == 2) ++nok;
85  }
86 
87  // need at least 2 planes with at least two points
88  if(nok < 2) return;
89 
90  TDecompSVD svd(A);
91  bool ok;
92  TVectorD tVec = svd.Solve(w, ok);
93 
94  ChiDOF = 0;
95 
96  // not enough points to calculate Chisq
97  if(hitX.size() == 4) return;
98 
99  double ypr, zpr, diff;
100  for(iht = 0; iht < hitX.size(); ++iht) {
101  cstat = hitWID[iht].Cryostat;
102  tpc = hitWID[iht].TPC;
103  ipl = hitWID[iht].Plane;
104  off = geom->WireCoordinate(0, 0, ipl, tpc, cstat);
105  cw = geom->WireCoordinate(1, 0, ipl, tpc, cstat) - off;
106  sw = geom->WireCoordinate(0, 1, ipl, tpc, cstat) - off;
107  x = hitX[iht] - XOrigin;
108  ypr = tVec[0] + tVec[2] * x;
109  zpr = tVec[1] + tVec[3] * x;
110  if(hitXErr[iht] > 0) {
111  wght = 1 / hitXErr[iht];
112  } else {
113  wght = 1;
114  }
115  if(wght <= 0) wght = 1;
116  diff = (ypr * cw + zpr * sw - (hitWID[iht].Wire - off)) / wght;
117  ChiDOF += diff * diff;
118  }
119 
120  double werr2 = geom->WirePitch(0, tpc, cstat);
121  werr2 *= werr2;
122  ChiDOF /= werr2;
123  ChiDOF /= (double)(npts - 4);
124 
125  double norm = sqrt(1 + tVec[2] * tVec[2] + tVec[3] * tVec[3]);
126  Dir[0] = 1 / norm;
127  Dir[1] = tVec[2] / norm;
128  Dir[2] = tVec[3] / norm;
129 
130  Pos[0] = XOrigin;
131  Pos[1] = tVec[0];
132  Pos[2] = tVec[1];
133 /*
134  // covariance matrix
135  TMatrixD fV = svd.GetV();
136  PosCov(1, 1) = fV(0, 0);
137  PosCov(2, 1) = fV(1, 0);
138  PosCov(1, 2) = fV(0, 1);
139  PosCov(2, 2) = fV(1, 1);
140  // A conservative fake for Pos[0]
141  PosCov(0, 0) = PosCov(1,1);
142 */
143 
144  } // TrkLineFit()
145 
146 } // namespace trkf
Float_t x
Definition: compare.C:6
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
void TrkLineFit(std::vector< geo::WireID > &hitWID, std::vector< double > &hitX, std::vector< double > &hitXErr, double XOrigin, TVector3 &Pos, TVector3 &Dir, float &ChiDOF)
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
Float_t sw
Definition: plot.C:23
Float_t norm
art::ServiceHandle< geo::Geometry > geom
Float_t w
Definition: plot.C:23