KETrack.cxx
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////
2 ///
3 /// \file KETrack.cxx
4 ///
5 /// \brief Basic Kalman filter track class, with error.
6 ///
7 /// \author H. Greenlee
8 ///
9 ////////////////////////////////////////////////////////////////////////
10 
12 #include "cetlib_except/exception.h"
13 #include <cmath>
14 
15 namespace trkf {
16 
17  /// Default constructor.
19 
20  /// Constructor - specify surface only.
21  ///
22  /// Arguments:
23  ///
24  /// psurf - Surface pointer.
25  ///
26  KETrack::KETrack(const std::shared_ptr<const Surface>& psurf) : KTrack(psurf) {}
27 
28  /// Constructor - surface + track parameters + error matrix.
29  ///
30  /// Arguments:
31  ///
32  /// psurf - Surface pointer.
33  /// vec - Track state vector.
34  /// err - Track error matrix.
35  /// dir - Track direction.
36  /// pdg - Pdg code.
37  ///
38  KETrack::KETrack(const std::shared_ptr<const Surface>& psurf,
39  const TrackVector& vec,
40  const TrackError& err,
42  int pdg)
43  : KTrack(psurf, vec, dir, pdg), fErr(err)
44  {}
45 
46  /// Constructor - KTrack + error matrix.
47  ///
48  /// Arguments:
49  ///
50  /// trk - KTrack.
51  /// err - Track error matrix.
52  ///
53  KETrack::KETrack(const KTrack& trk, const TrackError& err) : KTrack(trk), fErr(err) {}
54 
55  /// Destructor.
57 
58  /// Calculate track pointing error (sigma, in radians).
59  ///
60  /// This method calculates a single pointing error (sigma, in
61  /// radians) based on the track parameters and error matrix. The
62  /// actual calculation is done by the similarly names method of the
63  /// surface class, since this class doesn't know what the track
64  /// parameters mean.
65  ///
66  double
68  {
69  if (!isValid())
70  throw cet::exception("KETrack") << "Pointing error requested for invalid track.\n";
71  return getSurface()->PointingError(getVector(), fErr);
72  }
73 
74  /// Combine two tracks.
75  ///
76  /// Arguments:
77  ///
78  /// tre - Another track.
79  ///
80  /// Returns: Chisquare + success flag.
81  ///
82  /// This method updates the current track to be the weighted average
83  /// of itself and another track. The chisquare of the combination
84  /// is returned as the result value. The combination can fail
85  /// because the sum of the two error matrices is singular, in which
86  /// case the success flag embedded in the return value is false.
87  ///
88  std::optional<double>
90  {
91  // Make sure that the two track surfaces are the same.
92  // Throw an exception if they are not.
93 
94  if (!getSurface()->isEqual(*tre.getSurface()))
95  throw cet::exception("KETrack") << "Track combination surfaces are not the same.\n";
96 
97  // Default result is failure.
98 
99  std::optional<double> result{std::nullopt};
100 
101  // We will use asymmetric versions of the updating formulas, such
102  // that the result is calculated as a perturbation on the
103  // better-measured track. We define the better measured track as
104  // the one with the smaller error matrix trace.
105 
106  // Extract the two state vectors and error matrices as pointers.
107 
108  const TrackVector* vec1 = &getVector();
109  const TrackError* err1 = &getError();
110  const TrackVector* vec2 = &tre.getVector();
111  const TrackError* err2 = &tre.getError();
112 
113  // Calculate the traces of the error matrices.
114 
115  double tr1 = 0;
116  for (unsigned int i = 0; i < err1->size1(); ++i)
117  tr1 += (*err1)(i, i);
118 
119  double tr2 = 0;
120  for (unsigned int i = 0; i < err2->size1(); ++i)
121  tr2 += (*err2)(i, i);
122 
123  // Define vec1, err1 as belong to the better measured track.
124  // Swap if necessary.
125 
126  if (tr1 > tr2) {
127  const TrackVector* tvec = vec1;
128  vec1 = vec2;
129  vec2 = tvec;
130  const TrackError* terr = err1;
131  err1 = err2;
132  err2 = terr;
133  }
134 
135  // Calculate the difference vector and difference error matrix.
136 
137  TrackVector dvec = *vec1 - *vec2;
138  TrackError derr = *err1 + *err2;
139 
140  // Invert the difference error matrix.
141  // This is the only place where a detectable failure can occur.
142 
143  bool ok = syminvert(derr);
144  if (ok) {
145 
146  // Calculate updated state vector.
147  // vec1 = vec1 - err1 * derr * dvec
148 
149  TrackVector tvec1 = prod(derr, dvec);
150  TrackVector tvec2 = prod(*err1, tvec1);
151  TrackVector tvec3 = *vec1 - tvec2;
152  setVector(tvec3);
153 
154  // Calculate updated error matrix.
155  // err1 = err1 - err1 * derr * err1
156 
157  TrackMatrix terr1 = prod(derr, *err1);
158  TrackMatrix terr2 = prod(*err1, terr1);
159  TrackError terr2s = ublas::symmetric_adaptor<TrackMatrix>(terr2);
160  TrackError terr3 = *err1 - terr2s;
161  setError(terr3);
162 
163  // Calculate chisquare.
164  // chisq = dvec^T * derr * dvec
165 
166  TrackVector dvec1 = prod(derr, dvec);
167  double chisq = inner_prod(dvec, dvec1);
168  result = std::make_optional(chisq);
169  }
170 
171  // Final validity check.
172 
173  if (!isValid()) result = std::nullopt;
174 
175  // Done.
176 
177  return result;
178  }
179 
180  /// Printout
181  std::ostream&
182  KETrack::Print(std::ostream& out, bool doTitle) const
183  {
184  if (doTitle) out << "KETrack:\n";
185 
186  // Print base class.
187 
188  KTrack::Print(out, false);
189 
190  // Print diagonal errors.
191 
192  out << " Diagonal errors:\n"
193  << " [";
194  for (unsigned int i = 0; i < fErr.size1(); ++i) {
195  if (i != 0) out << ", ";
196  double err = fErr(i, i);
197  err = (err >= 0. ? std::sqrt(err) : -std::sqrt(-err));
198  out << err;
199  }
200  out << "]\n";
201 
202  // Print correlations.
203 
204  out << " Correlation matrix:";
205  for (unsigned int i = 0; i < fErr.size1(); ++i) {
206  if (i == 0)
207  out << "\n [";
208  else
209  out << "\n ";
210  for (unsigned int j = 0; j <= i; ++j) {
211  if (j != 0) out << ", ";
212  if (i == j)
213  out << 1.;
214  else {
215  double eiijj = fErr(i, i) * fErr(j, j);
216  double eij = fErr(i, j);
217  if (eiijj != 0.)
218  eij /= std::sqrt(std::abs(eiijj));
219  else
220  eij = 0.;
221  out << eij;
222  }
223  }
224  }
225  out << "]\n";
226  out << " Pointing error = " << PointingError() << "\n";
227  return out;
228  }
229 
230 } // end namespace trkf
const TrackError & getError() const
Track error matrix.
Definition: KETrack.h:53
TrackDirection
Track direction enum.
Definition: Surface.h:56
bool isEqual(float x1, float x2)
const std::shared_ptr< const Surface > & getSurface() const
Surface.
Definition: KTrack.h:55
static QCString result
double PointingError() const
Pointing error (radians).
Definition: KETrack.cxx:67
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
void setVector(const TrackVector &vec)
Set state vector.
Definition: KTrack.h:67
KETrack()
Default constructor.
Definition: KETrack.cxx:18
string dir
void setError(const TrackError &err)
Set error matrix.
Definition: KETrack.h:67
T abs(T value)
virtual ~KETrack()
Destructor.
Definition: KETrack.cxx:56
bool syminvert(ublas::symmetric_matrix< T, TRI, L, A > &m)
std::optional< double > combineTrack(const KETrack &tre)
Combine two tracks.
Definition: KETrack.cxx:89
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
virtual std::ostream & Print(std::ostream &out, bool doTitle=true) const
Printout.
Definition: KTrack.cxx:227
void err(const char *fmt,...)
Definition: message.cpp:226
const TrackVector & getVector() const
Track state vector.
Definition: KTrack.h:56
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
TrackError fErr
Track error matrix.
Definition: KETrack.h:81
virtual std::ostream & Print(std::ostream &out, bool doTitle=true) const
Printout.
Definition: KETrack.cxx:182
Basic Kalman filter track class, with error.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool isValid() const
Test if track is valid.
Definition: KTrack.cxx:91