KHit.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file KHit.h
4 ///
5 /// \brief Kalman filter measurement class template.
6 ///
7 /// \author H. Greenlee
8 ///
9 /// Class KHit represents a general measurement on a surface. It is
10 /// specialized compared to base class KHitBase by specifying the
11 /// dimension of the measurement vector by an integer template
12 /// parameter N.
13 ///
14 /// KHit class inherits the following attribute from KHitBase.
15 ///
16 /// 1. Measurement surface.
17 /// 2. Prediction surface.
18 ///
19 /// KHit adds the following attributes.
20 ///
21 /// 3. Measurement vector.
22 /// 4. Measurement error matrix.
23 /// 5. Prediction vector.
24 /// 6. Prediction error matrix.
25 /// 7. Residual vector.
26 /// 8. Residual error matrix.
27 /// 9. Inverse of residual error matrix.
28 /// 10. Kalman H-matrix.
29 /// 11. Incremental chisquare.
30 ///
31 /// The first two attributes (measurement vector + error matrix) are
32 /// filled during construction, and the remaining attributes are left
33 /// in a default state.
34 ///
35 /// The remaining attributes (also prediction surface attribute of
36 /// base class) are filled by the prediction method. The attributes
37 /// that are filled in by the prediction method are mutable, and
38 /// prediction method is const. The actual calculation of the
39 /// prediction vector, prediction error matrix, and H-matrix are left
40 /// to be implemented by a derived class, which must override the pure
41 /// virtual method subpredict. The remaining unfilled attributes are
42 /// calculated locally in this class in the prediction method
43 /// inherited from KHitBase.
44 ///
45 /// The measurement and prediction surfaces are not required to be the
46 /// same. If they are different, the method predict is required to
47 /// make an internal propagation from the prediction surface to the
48 /// measurement surface, which propagation influeces the calculated
49 /// H-matrix, as well as the prediction vector and error.
50 ///
51 /// The intended use case is as follows.
52 ///
53 /// 1. Track (KETrack) is propagated to measurement surface.
54 /// Methods predict and update will throw an exception of track
55 /// surface does not match measurement surface.
56 /// 2. Prediction is updated by calling method KHit::predict.
57 /// 3. At this point the calling program can make a cut on the
58 /// incremental chisquare, returned by method KHit::chisq.
59 /// 4. If the chisquare cut passes, update track by calling method
60 /// KHit::update.
61 ///
62 ////////////////////////////////////////////////////////////////////////
63 
64 #ifndef KHIT_H
65 #define KHIT_H
66 
67 #include "cetlib_except/exception.h"
70 
71 namespace trkf {
72 
73  template <int N>
74  class KHit : public KHitBase {
75  public:
76  /// Default constructor.
77  KHit();
78 
79  /// Initializing Constructor -- surface only.
80  KHit(const std::shared_ptr<const Surface>& psurf);
81 
82  /// Fully Initializing Constructor.
83  KHit(const std::shared_ptr<const Surface>& psurf,
84  const typename KVector<N>::type& mvec,
85  const typename KSymMatrix<N>::type& merr);
86 
87  /// Destructor.
88  virtual ~KHit();
89 
90  // Modifiers.
91 
92  /// Set measurement vector.
93  void
94  setMeasVector(const typename KVector<N>::type& mvec)
95  {
96  fMvec = mvec;
97  }
98 
99  /// Set measurement error.
100  void
101  setMeasError(const typename KSymMatrix<N>::type& merr)
102  {
103  fMerr = merr;
104  }
105 
106  // Accessors.
107 
108  /// Measurement vector.
109  const typename KVector<N>::type&
111  {
112  return fMvec;
113  }
114 
115  /// Measurement error matrix.
116  const typename KSymMatrix<N>::type&
117  getMeasError() const
118  {
119  return fMerr;
120  }
121 
122  /// Prediction vector.
123  const typename KVector<N>::type&
125  {
126  return fPvec;
127  }
128 
129  /// Prediction matrix.
130  const typename KSymMatrix<N>::type&
131  getPredError() const
132  {
133  return fPerr;
134  }
135 
136  /// Residual vector.
137  const typename KVector<N>::type&
138  getResVector() const
139  {
140  return fRvec;
141  }
142 
143  /// Residual error matrix.
144  const typename KSymMatrix<N>::type&
145  getResError() const
146  {
147  return fRerr;
148  }
149 
150  /// Residual inv. error matrix.
151  const typename KSymMatrix<N>::type&
153  {
154  return fRinv;
155  }
156 
157  /// Kalman H-matrix.
158  const typename KHMatrix<N>::type&
159  getH() const
160  {
161  return fH;
162  }
163 
164  /// Incremental chisquare.
165  double
166  getChisq() const
167  {
168  return fChisq;
169  }
170 
171  // Overrides.
172  // Implementation of overrides is found at the bottom of this header.
173 
174  /// Prediction method (return false if fail).
175  bool predict(const KETrack& tre, const Propagator& prop, const KTrack* ref = 0) const;
176 
177  /// Update track method.
178  void update(KETrack& tre) const;
179 
180  // Pure virtual methods.
181 
182  /// Calculate prediction function (return via arguments).
183  virtual bool subpredict(const KETrack& tre,
184  typename KVector<N>::type& pvec,
185  typename KSymMatrix<N>::type& perr,
186  typename KHMatrix<N>::type& hmatrix) const = 0;
187 
188  /// Printout
189  virtual std::ostream& Print(std::ostream& out, bool doTitle = true) const;
190 
191  private:
192  // Attributes.
193 
194  typename KVector<N>::type fMvec; ///< Measurement vector.
195  typename KSymMatrix<N>::type fMerr; ///< Measurement error matrix.
196  mutable typename KVector<N>::type fPvec; ///< Prediction vector.
197  mutable typename KSymMatrix<N>::type fPerr; ///< Prediction error matrix.
198  mutable typename KVector<N>::type fRvec; ///< Residual vector.
199  mutable typename KSymMatrix<N>::type fRerr; ///< Residual error matrix.
200  mutable typename KSymMatrix<N>::type fRinv; ///< Residual inverse error matrix.
201  mutable typename KHMatrix<N>::type fH; ///< Kalman H-matrix.
202  mutable double fChisq; ///< Incremental chisquare.
203  };
204 
205  // Method implementations.
206 
207  /// Default constructor.
208  template <int N>
210  {}
211 
212  /// Initializing Constructor -- surface only.
213  ///
214  /// Arguments:
215  ///
216  /// psurf - Surface pointer.
217  ///
218  template <int N>
219  KHit<N>::KHit(const std::shared_ptr<const Surface>& psurf) : KHitBase(psurf), fChisq(0.)
220  {}
221 
222  /// Fully Initializing Constructor.
223  ///
224  /// Arguments:
225  ///
226  /// psurf - Surface pointer.
227  /// mvec - Measurement vector.
228  /// merr - Measurement error.
229  ///
230  template <int N>
231  KHit<N>::KHit(const std::shared_ptr<const Surface>& psurf,
232  const typename KVector<N>::type& mvec,
233  const typename KSymMatrix<N>::type& merr)
234  : KHitBase(psurf), fMvec(mvec), fMerr(merr), fChisq(0.)
235  {}
236 
237  /// Destructor.
238  template <int N>
240  {}
241 
242  /// Prediction method.
243  ///
244  /// Arguments;
245  ///
246  /// tre - Track prediction.
247  /// prop - Propagator.
248  /// ref - Reference track.
249  ///
250  template <int N>
251  bool
252  KHit<N>::predict(const KETrack& tre, const Propagator& prop, const KTrack* ref) const
253  {
254  // Update the prediction surface to be the track surface.
255 
256  fPredSurf = tre.getSurface();
257  fPredDist = 0.;
258 
259  // Default result.
260 
261  bool ok = false;
262 
263  // Update prediction vector, error matrox, and H-matrix.
264 
265  // First test whether the prediction surface matches the
266  // measurement surface.
267 
268  if (getMeasSurface()->isEqual(*fPredSurf)) {
269 
270  // Prediction and measurement surfaces agree.
271  //Just call subpredict method (don't do propagation).
272 
273  ok = subpredict(tre, fPvec, fPerr, fH);
274  }
275  else {
276 
277  // Track surface does not match the prediction surface, so an
278  // internal propagation will be required. Throw an exception if
279  // no propagator was provided.
280 
281  // First make a copy of the original KETrack.
282 
283  KETrack treprop(tre);
284 
285  // Also make a copy of the reference track (if specified).
286 
287  KTrack refprop;
288  KTrack* prefprop = 0;
289  if (ref != 0) {
290  refprop = *ref;
291  prefprop = &refprop;
292  }
293 
294  // Make a no-noise, no-dE/dx propagation to the measurement
295  // surface. But do calculate the propagation matrix, which we
296  // will use to update the H-matrix calculated in the derived
297  // class.
298 
299  TrackMatrix prop_matrix;
300  std::optional<double> dist = prop.err_prop(
301  treprop, getMeasSurface(), Propagator::UNKNOWN, false, prefprop, &prop_matrix);
302  if (dist) {
303 
304  // Update prediction distance.
305 
306  fPredDist = *dist;
307 
308  // Now we are ready to calculate the prediction on the
309  // measurement surface.
310 
311  typename KHMatrix<N>::type hmatrix;
312  ok = subpredict(treprop, fPvec, fPerr, hmatrix);
313  if (ok) {
314 
315  // Use the propagation matrix to transform the H-matrix back
316  // to the prediction surface.
317 
318  fH = prod(hmatrix, prop_matrix);
319  }
320  }
321  }
322  if (ok) {
323 
324  // Update residual
325 
326  fRvec = fMvec - fPvec;
327  fRerr = fMerr + fPerr;
328  fRinv = fRerr;
329  ok = syminvert(fRinv);
330  if (ok) {
331 
332  // Calculate incremental chisquare.
333 
334  // (workaround: if we use the copy constructor, gcc emits a spurious warning)
335  // typename KVector<N>::type rtemp = prod(fRinv, fRvec);
336  fChisq = inner_prod(fRvec, prod(fRinv, fRvec));
337  }
338  }
339 
340  // If a problem occured at any step, clear the prediction surface pointer.
341 
342  if (!ok) {
343  fPredSurf.reset();
344  fPredDist = 0.;
345  }
346 
347  // Done.
348 
349  return ok;
350  }
351 
352  /// Update track method.
353  ///
354  /// Arguments:
355  ///
356  /// tre - Track to be updated.
357  ///
358  template <int N>
359  void
361  {
362  // Make sure that the track surface and the prediction surface are the same.
363  // Throw an exception if they are not.
364 
365  if (!getPredSurface()->isEqual(*tre.getSurface()))
366  throw cet::exception("KHit") << "Track surface not the same as prediction surface.\n";
367 
368  const TrackVector& tvec = tre.getVector();
369  const TrackError& terr = tre.getError();
370  TrackVector::size_type size = tvec.size();
371 
372  // Calculate gain matrix.
373 
374  typename KGMatrix<N>::type temp(size, N);
375  typename KGMatrix<N>::type gain(size, N);
376  temp = prod(trans(fH), fRinv);
377  gain = prod(terr, temp);
378 
379  // Calculate updated track state.
380 
381  TrackVector newvec = tre.getVector() + prod(gain, fRvec);
382 
383  // Calculate updated error matrix.
384 
385  TrackMatrix fact = ublas::identity_matrix<TrackVector::value_type>(size);
386  fact -= prod(gain, fH);
387  TrackMatrix errtemp1 = prod(terr, trans(fact));
388  TrackMatrix errtemp2 = prod(fact, errtemp1);
389  TrackError errtemp2s = ublas::symmetric_adaptor<TrackMatrix>(errtemp2);
390  typename KHMatrix<N>::type errtemp3 = prod(fMerr, trans(gain));
391  TrackMatrix errtemp4 = prod(gain, errtemp3);
392  TrackError errtemp4s = ublas::symmetric_adaptor<TrackMatrix>(errtemp4);
393  TrackError newerr = errtemp2s + errtemp4s;
394 
395  // Update track.
396 
397  tre.setVector(newvec);
398  tre.setError(newerr);
399  }
400 
401  /// Printout
402  template <int N>
403  std::ostream&
404  KHit<N>::Print(std::ostream& out, bool doTitle) const
405  {
406  if (doTitle) out << "KHit<" << N << ">:\n";
407 
408  // Print base class.
409 
410  KHitBase::Print(out, false);
411 
412  // Print measurement vector.
413 
414  out << " Measurement vector:\n"
415  << " [";
416  for (unsigned int i = 0; i < fMvec.size(); ++i) {
417  if (i != 0) out << ", ";
418  out << fMvec(i);
419  }
420  out << "]\n";
421 
422  // Print diagonal measurement errors.
423 
424  out << " Diagonal measurement errors:\n"
425  << " [";
426  for (unsigned int i = 0; i < fMerr.size1(); ++i) {
427  if (i != 0) out << ", ";
428  double err = fMerr(i, i);
429  err = (err >= 0. ? std::sqrt(err) : -std::sqrt(-err));
430  out << err;
431  }
432  out << "]\n";
433 
434  // Print measurement correlations.
435 
436  if (fMerr.size1() > 1) {
437  out << " Measurement correlation matrix:";
438  for (unsigned int i = 0; i < fMerr.size1(); ++i) {
439  if (i == 0)
440  out << "\n [";
441  else
442  out << "\n ";
443  for (unsigned int j = 0; j <= i; ++j) {
444  if (j != 0) out << ", ";
445  if (i == j)
446  out << 1.;
447  else {
448  double eiijj = fMerr(i, i) * fMerr(j, j);
449  double eij = fMerr(i, j);
450  if (eiijj != 0.)
451  eij /= std::sqrt(std::abs(eiijj));
452  else
453  eij = 0.;
454  out << eij;
455  }
456  }
457  }
458  out << "]\n";
459  }
460 
461  // Print prediction vector.
462 
463  out << " Prediction vector:\n"
464  << " [";
465  for (unsigned int i = 0; i < fPvec.size(); ++i) {
466  if (i != 0) out << ", ";
467  out << fPvec(i);
468  }
469  out << "]\n";
470 
471  // Print diagonal prediction errors.
472 
473  out << " Diagonal prediction errors:\n"
474  << " [";
475  for (unsigned int i = 0; i < fPerr.size1(); ++i) {
476  if (i != 0) out << ", ";
477  double err = fPerr(i, i);
478  err = (err >= 0. ? std::sqrt(err) : -std::sqrt(-err));
479  out << err;
480  }
481  out << "]\n";
482 
483  // Print prediction correlations.
484 
485  if (fPerr.size1() > 1) {
486  out << " Prediction correlation matrix:";
487  for (unsigned int i = 0; i < fPerr.size1(); ++i) {
488  if (i == 0)
489  out << "\n [";
490  else
491  out << "\n ";
492  for (unsigned int j = 0; j <= i; ++j) {
493  if (j != 0) out << ", ";
494  if (i == j)
495  out << 1.;
496  else {
497  double eiijj = fPerr(i, i) * fPerr(j, j);
498  double eij = fPerr(i, j);
499  if (eiijj != 0.)
500  eij /= std::sqrt(std::abs(eiijj));
501  else
502  eij = 0.;
503  out << eij;
504  }
505  }
506  }
507  out << "]\n";
508  }
509 
510  // Print residual vector.
511 
512  out << " Residual vector:\n"
513  << " [";
514  for (unsigned int i = 0; i < fRvec.size(); ++i) {
515  if (i != 0) out << ", ";
516  out << fRvec(i);
517  }
518  out << "]\n";
519 
520  // Print diagonal residual errors.
521 
522  out << " Diagonal residual errors:\n"
523  << " [";
524  for (unsigned int i = 0; i < fRerr.size1(); ++i) {
525  if (i != 0) out << ", ";
526  double err = fRerr(i, i);
527  err = (err >= 0. ? std::sqrt(err) : -std::sqrt(-err));
528  out << err;
529  }
530  out << "]\n";
531 
532  // Print residual correlations.
533 
534  if (fRerr.size1() > 1) {
535  out << " Residual correlation matrix:";
536  for (unsigned int i = 0; i < fRerr.size1(); ++i) {
537  if (i == 0)
538  out << "\n [";
539  else
540  out << "\n ";
541  for (unsigned int j = 0; j <= i; ++j) {
542  if (j != 0) out << ", ";
543  if (i == j)
544  out << 1.;
545  else {
546  double eiijj = fRerr(i, i) * fRerr(j, j);
547  double eij = fRerr(i, j);
548  if (eiijj != 0.)
549  eij /= std::sqrt(std::abs(eiijj));
550  else
551  eij = 0.;
552  out << eij;
553  }
554  }
555  }
556  out << "]\n";
557  }
558 
559  // Print incremental chisquare.
560 
561  out << " Incremental chisquare = " << fChisq << "\n";
562 
563  // Done.
564 
565  return out;
566  }
567 }
568 
569 #endif
bool predict(const KETrack &tre, const Propagator &prop, const KTrack *ref=0) const
Prediction method (return false if fail).
Definition: KHit.h:252
ublas::symmetric_matrix< double, ublas::lower, ublas::row_major, ublas::bounded_array< double, N *(N+1)/2 > > type
const TrackError & getError() const
Track error matrix.
Definition: KETrack.h:53
virtual bool subpredict(const KETrack &tre, typename KVector< N >::type &pvec, typename KSymMatrix< N >::type &perr, typename KHMatrix< N >::type &hmatrix) const =0
Calculate prediction function (return via arguments).
bool isEqual(float x1, float x2)
const std::shared_ptr< const Surface > & getSurface() const
Surface.
Definition: KTrack.h:55
void update(KETrack &tre) const
Update track method.
Definition: KHit.h:360
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
void setVector(const TrackVector &vec)
Set state vector.
Definition: KTrack.h:67
const KSymMatrix< N >::type & getMeasError() const
Measurement error matrix.
Definition: KHit.h:117
virtual std::ostream & Print(std::ostream &out, bool doTitle=true) const
Printout.
Definition: KHit.h:404
const KHMatrix< N >::type & getH() const
Kalman H-matrix.
Definition: KHit.h:159
const KVector< N >::type & getResVector() const
Residual vector.
Definition: KHit.h:138
virtual std::ostream & Print(std::ostream &out, bool doTitle=true) const
Printout.
Definition: KHitBase.cxx:32
void setError(const TrackError &err)
Set error matrix.
Definition: KETrack.h:67
const KVector< N >::type & getPredVector() const
Prediction vector.
Definition: KHit.h:124
const KSymMatrix< N >::type & getPredError() const
Prediction matrix.
Definition: KHit.h:131
KVector< N >::type fPvec
Prediction vector.
Definition: KHit.h:196
KHit()
Default constructor.
Definition: KHit.h:209
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
KMatrix< N, 5 >::type type
KVector< N >::type fMvec
Measurement vector.
Definition: KHit.h:194
KVector< N >::type fRvec
Residual vector.
Definition: KHit.h:198
void setMeasVector(const typename KVector< N >::type &mvec)
Set measurement vector.
Definition: KHit.h:94
T abs(T value)
std::shared_ptr< const Surface > fPredSurf
Prediction surface.
Definition: KHitBase.h:145
const KSymMatrix< N >::type & getResError() const
Residual error matrix.
Definition: KHit.h:145
ublas::vector< double, ublas::bounded_array< double, N > > type
bool syminvert(ublas::symmetric_matrix< T, TRI, L, A > &m)
KHMatrix< N >::type fH
Kalman H-matrix.
Definition: KHit.h:201
const KSymMatrix< N >::type & getResInvError() const
Residual inv. error matrix.
Definition: KHit.h:152
double getChisq() const
Incremental chisquare.
Definition: KHit.h:166
std::optional< double > err_prop(KETrack &tre, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0, TrackMatrix *prop_matrix=0) const
Propagate with error, but without noise.
Definition: Propagator.cxx:346
KSymMatrix< N >::type fRinv
Residual inverse error matrix.
Definition: KHit.h:200
Base class for Kalman filter track propagator.
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
void setMeasError(const typename KSymMatrix< N >::type &merr)
Set measurement error.
Definition: KHit.h:101
void err(const char *fmt,...)
Definition: message.cpp:226
double fPredDist
Prediction distance.
Definition: KHitBase.h:146
const TrackVector & getVector() const
Track state vector.
Definition: KTrack.h:56
KSymMatrix< N >::type fRerr
Residual error matrix.
Definition: KHit.h:199
const KVector< N >::type & getMeasVector() const
Measurement vector.
Definition: KHit.h:110
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
KSymMatrix< N >::type fPerr
Prediction error matrix.
Definition: KHit.h:197
KMatrix< 5, N >::type type
virtual ~KHit()
Destructor.
Definition: KHit.h:239
KSymMatrix< N >::type fMerr
Measurement error matrix.
Definition: KHit.h:195
Base class for Kalman filter measurement.
const std::shared_ptr< const Surface > & getMeasSurface() const
Measurement surface.
Definition: KHitBase.h:91
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double fChisq
Incremental chisquare.
Definition: KHit.h:202
const std::shared_ptr< const Surface > & getPredSurface() const
Predition surface.
Definition: KHitBase.h:77