KHitMulti.cxx
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////
2 ///
3 /// \file KHitMulti.cxx
4 ///
5 /// \brief Compound Kalman Filter measurement.
6 ///
7 /// \author H. Greenlee
8 ///
9 ////////////////////////////////////////////////////////////////////////
10 
12 #include "cetlib_except/exception.h"
13 
14 namespace trkf {
15 
16  /// Default Constructor.
17  KHitMulti::KHitMulti() : fMeasDim(0), fChisq(0.) {}
18 
19  /// Initializing Constructor.
20  ///
21  /// Arguments:
22  ///
23  /// psurf - Measurement surface pointer.
24  ///
25  KHitMulti::KHitMulti(const std::shared_ptr<const Surface>& psurf)
26  : KHitBase(psurf), fMeasDim(0), fChisq(0.)
27  {}
28 
29  /// Destructor.
31 
32  /// Add a measurement.
33  ///
34  /// Arguments:
35  ///
36  /// pmeas - Measurement.
37  ///
38  /// This method tries to dynamic cast the measurement to a supported
39  /// type. If the dynamic cast fails, throw an exception.
40  ///
41  void
42  KHitMulti::addMeas(const std::shared_ptr<const KHitBase>& pmeas)
43  {
44  // It is an error to pass in a null pointer.
45 
46  if (pmeas.get() == 0)
47  throw cet::exception("KHitMulti") << "Attempt to add null measurement pointer.\n";
48 
49  // Do the dynamic cast.
50 
51  std::shared_ptr<const KHit<1>> pmeas1 =
52  std::dynamic_pointer_cast<const KHit<1>, const KHitBase>(pmeas);
53 
54  // Throw an exception if dynamic cast failed.
55 
56  if (pmeas1.get() == 0)
57  throw cet::exception("KHitMulti") << "Dynamic cast for KHitBase pointer failed.\n";
58  addMeas(pmeas1);
59  }
60 
61  /// Add a measurement.
62  ///
63  /// Arguments:
64  ///
65  /// pmeas - Measurement.
66  ///
67  void
68  KHitMulti::addMeas(const std::shared_ptr<const KHit<1>>& pmeas)
69  {
70  // It is an error to pass in a null pointer.
71 
72  if (pmeas.get() == 0)
73  throw cet::exception("KHitMulti") << "Attempt to add null measurement pointer.\n";
74 
75  // Add the measurement.
76 
77  ++fMeasDim;
78  fMeasVec.push_back(pmeas);
79  }
80 
81  /// Prediction method (return false if fail).
82  ///
83  /// Arguments:
84  ///
85  /// tre - Track hypothesis.
86  /// prop - Propagator.
87  /// ref - Reference track.
88  ///
89  /// Returns: True if success.
90  ///
91  /// This class calls the predict method of each underlying
92  /// measurement and updates the combined prediction attributes.
93  ///
94  bool
95  KHitMulti::predict(const KETrack& tre, const Propagator& prop, const KTrack* ref) const
96  {
97  // Resize and clear all linear algebra objects.
98 
99  fMvec.resize(fMeasDim, false);
100  fMvec.clear();
101 
102  fMerr.resize(fMeasDim, false);
103  fMerr.clear();
104 
105  fPvec.resize(fMeasDim, false);
106  fPvec.clear();
107 
108  fPerr.resize(fMeasDim, false);
109  fPerr.clear();
110 
111  fRvec.resize(fMeasDim, false);
112  fRvec.clear();
113 
114  fRerr.resize(fMeasDim, false);
115  fRerr.clear();
116 
117  fRinv.resize(fMeasDim, false);
118  fRinv.clear();
119 
120  fH.resize(fMeasDim, tre.getVector().size());
121  fH.clear();
122 
123  // Update the prediction surface to be the track surface.
124 
125  fPredSurf = tre.getSurface();
126  fPredDist = 0.;
127 
128  // Result.
129 
130  bool ok = true;
131 
132  // Loop over one-dimensional measurements.
133 
134  for (unsigned int im = 0; ok && im < fMeasVec.size(); ++im) {
135  const KHit<1>& meas = *(fMeasVec[im]);
136 
137  // Update prediction for this measurement.
138 
139  ok = meas.predict(tre, prop, ref);
140  if (!ok) break;
141 
142  //
143 
144  // Update objects that are concatenations of underlying measurements.
145 
146  fMvec(im) = meas.getMeasVector()(0); // Measurement vector.
147  fMerr(im, im) = meas.getMeasError()(0, 0); // Measurement error matrix.
148  fPvec(im) = meas.getPredVector()(0); // Prediction vector.
149 
150  // H-matrix.
151 
152  for (unsigned int j = 0; j < meas.getH().size2(); ++j)
153  fH(im, j) = meas.getH()(0, j);
154  }
155  if (ok) {
156 
157  // Calculate prediction error matrix.
158  // T = H C H^T.
159 
160  ublas::matrix<double> temp(fH.size2(), fMeasDim);
161  ublas::matrix<double> temp2(fMeasDim, fMeasDim);
162  temp = prod(tre.getError(), trans(fH));
163  temp2 = prod(fH, temp);
164  fPerr = ublas::symmetric_adaptor<ublas::matrix<double>>(temp2);
165 
166  // Update residual
167 
168  fRvec = fMvec - fPvec;
169  fRerr = fMerr + fPerr;
170  fRinv = fRerr;
171  ok = syminvert(fRinv);
172  if (ok) {
173 
174  // Calculate incremental chisquare.
175 
176  ublas::vector<double> rtemp = prod(fRinv, fRvec);
177  fChisq = inner_prod(fRvec, rtemp);
178  }
179  }
180 
181  // If a problem occured at any step, clear the prediction surface pointer.
182 
183  if (!ok) {
184  fPredSurf.reset();
185  fPredDist = 0.;
186  }
187 
188  // Done.
189 
190  return ok;
191  }
192 
193  /// Update track method.
194  ///
195  /// Arguments:
196  ///
197  /// tre - Track to be updated.
198  ///
199  /// This method is almost an exact copy of the update method in KHit<N>.
200  ///
201  void
203  {
204  // Make sure that the track surface and the prediction surface are the same.
205  // Throw an exception if they are not.
206 
207  if (!getPredSurface()->isEqual(*tre.getSurface()))
208  throw cet::exception("KHitMulti") << "Track surface not the same as prediction surface.\n";
209 
210  const TrackVector& tvec = tre.getVector();
211  const TrackError& terr = tre.getError();
212  TrackVector::size_type size = tvec.size();
213 
214  // Calculate gain matrix.
215 
216  ublas::matrix<double> temp(size, fMeasDim);
217  ublas::matrix<double> gain(size, fMeasDim);
218  temp = prod(trans(fH), fRinv);
219  gain = prod(terr, temp);
220 
221  // Calculate updated track state.
222 
223  TrackVector newvec = tre.getVector() + prod(gain, fRvec);
224 
225  // Calculate updated error matrix.
226 
227  TrackMatrix fact = ublas::identity_matrix<TrackVector::value_type>(size);
228  fact -= prod(gain, fH);
229  TrackMatrix errtemp1 = prod(terr, trans(fact));
230  TrackMatrix errtemp2 = prod(fact, errtemp1);
231  TrackError errtemp2s = ublas::symmetric_adaptor<TrackMatrix>(errtemp2);
232  ublas::matrix<double> errtemp3 = prod(fMerr, trans(gain));
233  TrackMatrix errtemp4 = prod(gain, errtemp3);
234  TrackError errtemp4s = ublas::symmetric_adaptor<TrackMatrix>(errtemp4);
235  TrackError newerr = errtemp2s + errtemp4s;
236 
237  // Update track.
238 
239  tre.setVector(newvec);
240  tre.setError(newerr);
241  }
242 
243  /// Printout
244  std::ostream&
245  KHitMulti::Print(std::ostream& out, bool doTitle) const
246  {
247  if (doTitle) out << "KHitMulti:\n";
248  return out;
249  }
250 
251 } // end namespace trkf
bool predict(const KETrack &tre, const Propagator &prop, const KTrack *ref=0) const
Prediction method (return false if fail).
Definition: KHit.h:252
const TrackError & getError() const
Track error matrix.
Definition: KETrack.h:53
ublas::vector< double > fPvec
Prediction vector.
Definition: KHitMulti.h:169
bool isEqual(float x1, float x2)
const std::shared_ptr< const Surface > & getSurface() const
Surface.
Definition: KTrack.h:55
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
Compound Kalman Filter measurement.
const KHMatrix< N >::type & getH() const
Kalman H-matrix.
Definition: KHit.h:159
std::vector< std::shared_ptr< const KHit< 1 > > > fMeasVec
Underlying measurements.
Definition: KHitMulti.h:166
void setError(const TrackError &err)
Set error matrix.
Definition: KETrack.h:67
const KVector< N >::type & getPredVector() const
Prediction vector.
Definition: KHit.h:124
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
std::shared_ptr< const Surface > fPredSurf
Prediction surface.
Definition: KHitBase.h:145
bool syminvert(ublas::symmetric_matrix< T, TRI, L, A > &m)
void addMeas(const std::shared_ptr< const KHitBase > &pmeas)
Add a measurement of unknown type.
Definition: KHitMulti.cxx:42
ublas::symmetric_matrix< double > fRinv
Residual inverse error matrix.
Definition: KHitMulti.h:173
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
virtual std::ostream & Print(std::ostream &out, bool doTitle=true) const
Printout.
Definition: KHitMulti.cxx:245
KHitMulti()
Default constructor.
Definition: KHitMulti.cxx:17
ublas::symmetric_matrix< double > fPerr
Prediction error matrix.
Definition: KHitMulti.h:170
double fPredDist
Prediction distance.
Definition: KHitBase.h:146
ublas::vector< double > fRvec
Residual vector.
Definition: KHitMulti.h:171
const TrackVector & getVector() const
Track state vector.
Definition: KTrack.h:56
bool predict(const KETrack &tre, const Propagator &prop, const KTrack *ref=0) const
Prediction method (return false if fail).
Definition: KHitMulti.cxx:95
const KVector< N >::type & getMeasVector() const
Measurement vector.
Definition: KHit.h:110
ublas::matrix< double > fH
Kalman H-matrix.
Definition: KHitMulti.h:174
KMatrix< 5, 5 >::type TrackMatrix
General 5x5 matrix.
ublas::symmetric_matrix< double > fRerr
Residual error matrix.
Definition: KHitMulti.h:172
ublas::symmetric_matrix< double > fMerr
Measurement error matrix.
Definition: KHitMulti.h:168
void update(KETrack &tre) const
Update track method.
Definition: KHitMulti.cxx:202
double fChisq
Incremental chisquare.
Definition: KHitMulti.h:175
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
ublas::vector< double > fMvec
Measurement vector.
Definition: KHitMulti.h:167
const std::shared_ptr< const Surface > & getPredSurface() const
Predition surface.
Definition: KHitBase.h:77
virtual ~KHitMulti()
Destructor.
Definition: KHitMulti.cxx:30
int fMeasDim
Measurement space dimension.
Definition: KHitMulti.h:165