ATLAS Offline Software
Loading...
Searching...
No Matches
KalmanUpdator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// KalmanUpdator.cxx
7// Source file for class KalmanUpdator
8// The main updating calculations can be found in calculateFilterStep().
10// (c) ATLAS Detector software
12// Markus.Elsing@cern.ch
13// Wolfgang Liebig <http://consult.cern.ch/xwho/people/54608>
15
17
19
21
22
23// constructor
24Trk::KalmanUpdator::KalmanUpdator(const std::string& t,const std::string& n,const IInterface* p) :
25 AthAlgTool (t,n,p),
26 m_cov0{250., 250.,0.25, 0.25, 0.000001}, // set defaults _before_ reading from job options
29{
30 // AlgTool stuff
31 declareProperty("InitialCovariances",m_cov0,"default covariance to be used at start of filter");
32 declareProperty("FastTrackStateCovCalculation",m_useFruehwirth8a=false,"toggles which formula to use for updated cov");
33 declareInterface<IUpdator>( this );
34}
35
36// destructor
38= default;
39
40// initialize
42{
43 // pass individual outputlevel to message stream
44 m_outputlevel = msg().level()-MSG::DEBUG;
45 if (m_cov0.size() < 5) {
46 ATH_MSG_WARNING( "Wrong-sized initial covariance given, so set to default: " );
47 m_cov0 = {250.,250,0.25,0.25, 0.000001};
48 }
49 return StatusCode::SUCCESS;
50}
51
52// finalize
54{
55 return StatusCode::SUCCESS;
56}
57
58// updator #1 for Kalman Fitter - version with Amg::Vector2D (for example for PrepRawData)
59std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::addToState (const Trk::TrackParameters& trkPar,
60 const Amg::Vector2D& measmtPos,
61 const Amg::MatrixX& measmtErr) const {
62 if (m_outputlevel <= 0) logStart("addToState(TP,LPOS,ERR)",trkPar);
63 FitQualityOnSurface* fitQoS = nullptr;
64 return calculateFilterStep (trkPar, measmtPos, measmtErr,1,fitQoS,false);
65}
66
67// updator #2 for Kalman Fitter - version with LocalParameters (for example for RIO_OnTrack)
68std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::addToState (const Trk::TrackParameters& trkPar,
69 const LocalParameters& measmtPar,
70 const Amg::MatrixX& measmtErr) const {
71 if (m_outputlevel <= 0) logStart("addToState(TP,LPAR,ERR)",trkPar);
72 FitQualityOnSurface* fitQoS = nullptr;
73 return calculateFilterStep (trkPar, measmtPar, measmtErr,1,fitQoS, false);
74}
75// updator #3 for Kalman Fitter - version with Amg::Vector2D (for example for PrepRawData)
76std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::addToState (const Trk::TrackParameters& trkPar,
77 const Amg::Vector2D& measmtPos,
78 const Amg::MatrixX& measmtErr,
79 FitQualityOnSurface*& fitQoS) const {
80 if (m_outputlevel <= 0) logStart("addToState(TP,LPOS,ERR,FQ)",trkPar);
81 if (fitQoS) {
82 ATH_MSG_WARNING( "expect nil FitQuality pointer, refuse operation to avoid mem leak!" );
83 return nullptr;
84 }
85 return calculateFilterStep (trkPar, measmtPos, measmtErr, 1, fitQoS, true);
86
87}
88
89// updator #4 for Kalman Fitter - version with LocalParameters (for example for RIO_OnTrack)
90std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::addToState (const Trk::TrackParameters& trkPar,
91 const LocalParameters& measmtPar,
92 const Amg::MatrixX& measmtErr,
93 FitQualityOnSurface*& fitQoS) const {
94 if (m_outputlevel <= 0) logStart("addToState(TP,LPAR,ERR,FQ)",trkPar);
95 if (fitQoS) {
96 ATH_MSG_WARNING( "expect nil FitQuality pointer, refuse operation to avoid mem leak!" );
97 return nullptr;
98 }
99 return calculateFilterStep (trkPar, measmtPar, measmtErr, 1, fitQoS, true);
100
101}
102
103// inverse updator #1 for Kalman Fitter - version with Amg::Vector2D (for example for PrepRawData)
104std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::removeFromState (const Trk::TrackParameters& trkPar,
105 const Amg::Vector2D& measmtPos,
106 const Amg::MatrixX& measmtErr) const {
107 if (m_outputlevel<=0) logStart("removeFromState(TP,LPOS,ERR)",trkPar);
108 FitQualityOnSurface* fitQoS = nullptr;
109 return calculateFilterStep (trkPar, measmtPos, measmtErr,-1,fitQoS, false);
110}
111
112// inverse updator #2 for Kalman Fitter - version with LocalParameters (for example for RIO_OnTrack)
113std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::removeFromState (const Trk::TrackParameters& trkPar,
114 const LocalParameters& measmtPar,
115 const Amg::MatrixX& measmtErr) const {
116 if (m_outputlevel) logStart("removeFromState(TP,LPAR,ERR)",trkPar);
117 FitQualityOnSurface* fitQoS = nullptr;
118 return calculateFilterStep (trkPar, measmtPar, measmtErr,-1,fitQoS, false);
119}
120
121// inverse updator #3 for Kalman Fitter - version with Amg::Vector2D (for example for PrepRawData)
122std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::removeFromState (const Trk::TrackParameters& trkPar,
123 const Amg::Vector2D& measmtPos,
124 const Amg::MatrixX& measmtErr,
125 FitQualityOnSurface*& fitQoS) const {
126 if (m_outputlevel<=0) logStart("removeFromState(TP,LPOS,ERR,FQ)",trkPar);
127 if (fitQoS) {
128 ATH_MSG_WARNING( "expect nil FitQuality pointer, refuse operation to"
129 << " avoid mem leak!" );
130 return nullptr;
131 }
132 return calculateFilterStep (trkPar, measmtPos, measmtErr, -1, fitQoS, true);
133
134}
135
136// inverse updator #4 for Kalman Fitter - version with LocalParameters (for example for RIO_OnTrack)
137std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::removeFromState (const Trk::TrackParameters& trkPar,
138 const LocalParameters& measmtPar,
139 const Amg::MatrixX& measmtErr,
140 FitQualityOnSurface*& fitQoS) const {
141 if (m_outputlevel<=0) logStart("removeFromState(TP,LPAR,ERR,FQ)",trkPar);
142 if (fitQoS) {
143 ATH_MSG_WARNING( "expect nil FitQuality pointer, refuse operation to"
144 << " avoid mem leak!" );
145 return nullptr;
146 }
147 return calculateFilterStep (trkPar, measmtPar, measmtErr, -1, fitQoS, true);
148}
149
150// state-to-state updator, trajectory combination - version without fitQuality
151std::unique_ptr<Trk::TrackParameters>
153 const Trk::TrackParameters& two) const
154{
155 // remember, either one OR two might have no error, but not both !
156 if (!one.covariance() && !two.covariance()) {
157 ATH_MSG_WARNING( "both parameters have no errors, invalid "
158 << "use of Updator::combineStates()" );
159 return nullptr;
160 }
161 // if only one of two has an error, return that one
162 if (!one.covariance()) {
163 if (m_outputlevel<=0) logResult("combineStates(TP,TP)",two.parameters(),
164 *two.covariance());
165 return std::unique_ptr<Trk::TrackParameters>(two.clone());
166 }
167 if (!two.covariance()) {
168 if (m_outputlevel<=0) logResult("combineStates(TP,TP)",one.parameters(),
169 *one.covariance());
170 return std::unique_ptr<Trk::TrackParameters>(one.clone());
171 }
172
173 // ... FIXME - TRT is so difficult, need to check that both parameters are in the same frame
174 // otherwise go into frame of one !
175 // ok, normal, let's combine using gain matrix formalism
176 const AmgSymMatrix(5)& covTrkOne = (*one.covariance());
177 const AmgSymMatrix(5)& covTrkTwo = (*two.covariance());
178
179 AmgSymMatrix(5) sumCov = covTrkOne + covTrkTwo;
180 AmgSymMatrix(5) K = covTrkOne * sumCov.inverse();
181
182 Amg::VectorX r = two.parameters() - one.parameters();
183 // catch [-pi,pi] phi boundary problems
185 Amg::VectorX par = one.parameters() + K * r;
186 AmgSymMatrix(5) covPar = AmgSymMatrix(5)( K * covTrkTwo );
187 if ( (!thetaPhiWithinRange(par)) ? !correctThetaPhiRange(par,covPar,false) : false ) {
188 ATH_MSG_WARNING( "combineStates(TP,TP): could not combine angular values." );
189 return nullptr;
190 }
191
192 // return cloned version of Track Parameters (MeasuredPerigee, MeasuredAtA...)
193 auto comb =
194 one.associatedSurface().createUniqueTrackParameters(par[Trk::loc1],
195 par[Trk::loc2],
196 par[Trk::phi],
197 par[Trk::theta],
198 par[Trk::qOverP],
199 covPar);
200 if (m_outputlevel <= 0){
201 logResult("combineStates(TP,TP)", par, covPar);
202 }
203 return comb;
204}
205
206// state-to-state updator, trajectory combination - version with fitQuality
207std::unique_ptr<Trk::TrackParameters> Trk::KalmanUpdator::combineStates (const Trk::TrackParameters& one,
209 FitQualityOnSurface*& fitQoS) const {
210 // try if both Track Parameters are measured ones ?
211 // remember, either one OR two might have no error, but not both !
212 if (!one.covariance() && !two.covariance()) {
213 ATH_MSG_WARNING( "both parameters have no errors, invalid use of Updator::combineStates()" );
214 return nullptr;
215 }
216 if (fitQoS) {
217 ATH_MSG_WARNING( "expect nil FitQuality pointer, refuse operation to avoid mem leak!" );
218 return nullptr;
219 }
220 // if only one of two has an error, return that one
221 if (!one.covariance()) {
222 fitQoS = new FitQualityOnSurface(0.f, 5);
223 if (m_outputlevel<=0) logResult("combineStates(TP,TP,FQ)", one.parameters(),
224 (*two.covariance()));
225 return std::unique_ptr<Trk::TrackParameters>(two.clone());
226 }
227 if (!two.covariance()) {
228 fitQoS = new FitQualityOnSurface(0.f, 5);
229 if (m_outputlevel<=0) logResult("combineStates(TP,TP,FQ)", one.parameters(),
230 (*one.covariance()));
231 return std::unique_ptr<Trk::TrackParameters>(one.clone());
232 }
233
234 // covariance matrix for prediction and the state to be added
235 const AmgSymMatrix(5)& covTrkOne = (*one.covariance());
236 const AmgSymMatrix(5)& covTrkTwo = (*two.covariance());
237
238 // chi2 calculation and Kalman Gain preparation
239 Amg::VectorX r = two.parameters() - one.parameters();
240 AmgSymMatrix(5) R = covTrkOne + covTrkTwo;
241 // catch [-pi,pi] phi boundary problems to keep chi2 under control
243 AmgSymMatrix(5) R_inv = R.inverse();
244 AmgSymMatrix(5) K = covTrkOne * R_inv;
245 Amg::VectorX par = one.parameters() + K * r;
246 AmgSymMatrix(5) covPar = AmgSymMatrix(5)(K * covTrkTwo);
247 if ( (!thetaPhiWithinRange(par)) ? !correctThetaPhiRange(par,covPar) : false ) {
248 ATH_MSG_WARNING( "combineStates(TP,TP,FQ): could not combine angular values." );
249 return nullptr;
250 }
251
252 // compute fit quality
253 fitQoS = new FitQualityOnSurface(Amg::chi2(R_inv, r), 5);
254
255 // return cloned version of Track Parameters (MeasuredPerigee, MeasuredAtA...)
256 auto comb =
257 one.associatedSurface().createUniqueTrackParameters(par[Trk::loc1],
258 par[Trk::loc2],
259 par[Trk::phi],
260 par[Trk::theta],
261 par[Trk::qOverP],
262 covPar);
263 if (m_outputlevel <= 0){
264 logResult("combineStates(TP,TP,FQ)", par, covPar);
265 }
266 return comb;
267
268}
269
270
271// estimator for FitQuality on Surface (allows for setting of LR for straws)
274 const Amg::Vector2D& locPos,
275 const Amg::MatrixX& rioErr) const {
276 ATH_MSG_DEBUG( "--> entered KalmanUpdator::fullStateFitQuality(TP,LPOS,ERR)" );
277
278 // try if Track Parameters are measured ones ?
279 if (!trkPar.covariance()) {
280 ATH_MSG_ERROR( "updated smoother/trajectory has no error matrix" );
281 return {};
282 }
283 // covariance matrix for prediction
284 const AmgSymMatrix(5)& covTrk = (*trkPar.covariance());
285
286 // For the Amg::Vector2D version, need to know # meas. coord. from covariance matrix.
287 int nLocCoord = rioErr.cols();
288 Amg::VectorX rioPar(nLocCoord);
289 for (int iLocCoord=0; iLocCoord < nLocCoord; iLocCoord++) {
290 rioPar[iLocCoord] = locPos[iLocCoord];
291 }
292
293 // measurement Matrix ( n x m )
294 Amg::MatrixX H(rioErr.cols(),covTrk.cols());
295 H.setZero();
296 for (int i=0; i < nLocCoord; i++) H(i,i)=1.f;
297
298 // residuals
299 Amg::VectorX r = rioPar - H * trkPar.parameters();
300
301 // all the rest is outsourced to a common chi2 routine
302 return makeChi2Object(r,covTrk,rioErr,-1,(nLocCoord==1?1:3));
303}
304
305
306// estimator for FitQuality on Surface (allows for setting of LR for straws)
309 const Trk::LocalParameters& rioPar,
310 const Amg::MatrixX& rioErr) const {
311 ATH_MSG_VERBOSE( "--> entered KalmanUpdator::fullStateFitQuality(TP,LPAR,ERR)" );
312
313 // try if Track Parameters are measured ones ?
314 if (!trkPar.covariance()) {
315 ATH_MSG_ERROR( "updated smoother/trajectory has no error matrix" );
316 return {};
317 }
318 if ( !consistentParamDimensions(rioPar,rioErr.cols()) ) return {};
319
320 // covariance matrix for prediction
321 const AmgSymMatrix(5)& covTrk = (*trkPar.covariance());
322
323 // State to measurement dimensional reduction Matrix ( n x m )
324 const Amg::MatrixX& H(rioPar.expansionMatrix());
325
326 // residuals
327 Amg::VectorX r = rioPar;
328 if( rioPar.parameterKey()==31 ) r -= trkPar.parameters();
329 else r -= H*trkPar.parameters();
330
331 // all the rest is outsourced to a common chi2 routine
332 return makeChi2Object(r,covTrk,rioErr,-1,rioPar.parameterKey());
333}
334
335// estimator for FitQuality on Surface (allows for setting of LR for straws)
338 const Amg::Vector2D& rioLocPos,
339 const Amg::MatrixX& rioLocErr) const {
340 ATH_MSG_VERBOSE( "--> entered KalmanUpdator::predictedStateFitQuality(TP,LPOS,ERR)" );
341 // try if Track Parameters are measured ones ?
342 if (predPar.covariance() == nullptr) {
343 ATH_MSG_WARNING( "input state has no error matrix in predictedStateFitQuality()" );
344 return {};
345 }
346 // covariance matrix for prediction
347 const AmgSymMatrix(5)& covPred = (*predPar.covariance());
348
349 // For the Amg::Vector2D version, need to know # meas. coord. from covariance matrix.
350 int nLocCoord = rioLocErr.cols();
351 Amg::VectorX rioPar(nLocCoord);
352 for (int iLocCoord=0; iLocCoord < nLocCoord; iLocCoord++) {
353 rioPar[iLocCoord] = rioLocPos[iLocCoord];
354 }
355
356 // measurement Matrix ( n x m )
357 Amg::MatrixX H(rioLocErr.cols(),covPred.cols());
358 H.setZero();
359 for (int i=0; i < nLocCoord; i++) H(i,i)=1.f;
360
361 // residuals
362 Amg::VectorX r = rioPar - H * predPar.parameters();
363
364 // all the rest is outsourced to a common chi2 routine
365 return makeChi2Object(r,covPred,rioLocErr,+1,(nLocCoord==1?1:3));
366}
367
368// estimator for FitQuality on Surface (allows for setting of LR for straws)
371 const Trk::LocalParameters& rioPar,
372 const Amg::MatrixX& rioErr) const {
373 ATH_MSG_VERBOSE( "--> entered KalmanUpdator::predictedStateFitQuality(TP,LPAR,ERR)" );
374
375 // try if Track Parameters are measured ones ?
376 if (predPar.covariance() == nullptr) {
377 ATH_MSG_WARNING( "input state has no error matrix in predictedStateFitQuality()" );
378 return {};
379 }
380
381 if ( ! consistentParamDimensions(rioPar,rioErr.cols()) ) return {};
382
383 // covariance matrix for prediction
384 const AmgSymMatrix(5)& covPred = (*predPar.covariance());
385
386 // State to measurement dimensional reduction Matrix ( n x m )
387 const Amg::MatrixX& H(rioPar.expansionMatrix());
388
389 // residuals
390 Amg::VectorX r = rioPar;
391 if(rioPar.parameterKey()==31) r -= predPar.parameters();
392 else r -= H * predPar.parameters();
393
394 // all the rest is outsourced to a common chi2 routine
395 return makeChi2Object(r,covPred,rioErr,+1,rioPar.parameterKey());
396}
397
398// estimator for FitQuality on Surface (allows for setting of LR for straws)
401 const Trk::TrackParameters& two) const {
402 ATH_MSG_VERBOSE( "--> entered KalmanUpdator::predictedStateFitQuality(TP,TP)" );
403 // remember, either one OR two might have no error, but not both !
404 if (!one.covariance() && !two.covariance()) {
405 ATH_MSG_WARNING( "both parameters have no errors, invalid "
406 << "use of Updator::fitQuality()" );
407 return {};
408 }
409 // if only one of two has an error, place a message.
410 if (!one.covariance() || !two.covariance()) {
411 ATH_MSG_DEBUG( "One parameter does not have uncertainties, "
412 << "assume initial state and return chi2=0.0" );
413 return {0.f, 5};
414 }
415
416 // covariance matrix for prediction and the state to be added
417 const AmgSymMatrix(5)& covTrkOne = (*one.covariance());
418 const AmgSymMatrix(5)& covTrkTwo = (*two.covariance());
419 // residuals
420 Amg::VectorX r = two.parameters() - one.parameters();
421 AmgSymMatrix(5) R = (covTrkOne + covTrkTwo).inverse();
422 // chi2 calculation
423 return {Amg::chi2(R, r), 5};
424}
425
426std::vector<double> Trk::KalmanUpdator::initialErrors() const {
427 std::vector<double> E(5);
428 for (int i=0; i<5; ++i) E[i] = std::sqrt(m_cov0[i]);
429 return E;
430}
431
432// mathematics for Kalman updator and inverse Kalman filter
433std::unique_ptr<Trk::TrackParameters>
435 const Amg::Vector2D& locPos,
436 const Amg::MatrixX& covRio,
437 const int sign,
439 bool createFQoS) const
440{
441
442 // try if Track Parameters are measured ones ?
443 AmgSymMatrix(5) covTrk;
444 if (!trkPar.covariance()) {
445 if (sign<0) {
446 ATH_MSG_WARNING( "MeasuredTrackParameters == Null, can not calculate updated parameter state" );
447 return nullptr;
448 }
449 // no error given - use a huge error matrix for the time
450 // covTrk = Amg::MatrixX(5, 1) * 1000.f;
451 ATH_MSG_VERBOSE( "-U- no covTrk at input - assign large error matrix for the time being." );
452 covTrk(0,0) = m_cov0[0];
453 covTrk(1,1) = m_cov0[1];
454 covTrk(2,2) = m_cov0[2];
455 covTrk(3,3) = m_cov0[3];
456 covTrk(4,4) = m_cov0[4];
457
458 }else {
459 covTrk = (*trkPar.covariance());
460 }
461
462
463 // covariance matrix and parameters of track
464 Amg::VectorX parTrk = trkPar.parameters();
465 if (!thetaPhiWithinRange(parTrk)) {
466 ATH_MSG_WARNING( (sign>0?"addToState(TP,LPOS,ERR..)":"removeFromState(TP,LPOS,ERR..)")
467 << ": undefined phi,theta range in input parameters." );
468 return nullptr;
469 }
470
471 // measurement vector of RIO_OnTrack - needs more care for # local par?
472 int nLocCoord = covRio.cols();
473 if ( (nLocCoord < 1) || (nLocCoord > 2 ) ) {
474 ATH_MSG_WARNING( " number of local coordinates must be 1 or 2, but it is "
475 << nLocCoord );
476 }
477 Amg::VectorX rioPar(nLocCoord);
478 for (int iLocCoord=0; iLocCoord < nLocCoord; iLocCoord++) {
479 rioPar[iLocCoord] = locPos[iLocCoord];
480 }
481 if (m_outputlevel<0) logInputCov(covTrk,rioPar,covRio);
482
483 // measurement Matrix ( n x m )
484 Amg::MatrixX H(covRio.cols(),covTrk.cols());
485 H.setZero();
486 for (int i=0; i < nLocCoord; i++) H(i,i)=1.f;
487
488 // residual from reconstructed hit wrt. predicted state
489 Amg::VectorX r = rioPar - H * parTrk;
490
491 // compute covariance on of residual R = +/- covRIO + H * covTrk * H.T()
492 Amg::MatrixX R = (sign * covRio) + projection(covTrk,(nLocCoord==1 ? 1 : 3) ); // .similarity(H);
493 // compute Kalman gain matrix
494 Amg::MatrixX K = covTrk * H.transpose() * R.inverse();
495 AmgSymMatrix(5) I; // 5x5 unit matrix
496 I.setIdentity();
497 AmgSymMatrix(5) M = I - K * H;
498 if (m_outputlevel<0) {logGainForm (nLocCoord,r,R.inverse(),K,M);}
499
500 // compute local filtered state
501 Amg::VectorX par = parTrk + K * r;
502
503 // compute covariance matrix of local filteres state:
504 AmgSymMatrix(5) covPar;
505 if (m_useFruehwirth8a) {
506 // one can use as well: covPar = M * covTrk; see A.Gelb why.
507 covPar = AmgSymMatrix(5)(M*covTrk);
508 } else {
509 // C = M*covTrk*M.T() +/- K*covRio*K.T(), supposedly more robust Gelb form.
510 // bad_alloc: covPar = new AmgSymMatrix(5)(covTrk.similarity(M) + (sign * covRio.similarity(K)));
511 covPar = AmgSymMatrix(5)(M*covTrk*M.transpose() + sign*K*covRio*K.transpose());
512 }
513 if ( (!thetaPhiWithinRange(par)) ? !correctThetaPhiRange(par,covPar) : false ) {
514 ATH_MSG_WARNING( "calculateFS(TP,LPOS,ERR): bad angles in filtered state!" );
515 return nullptr;
516 }
517 if (m_outputlevel<=0) logResult(createFQoS?
518 (sign>0?"addToState(TP,LPOS,ERR,FQ)":"removeFromState(TP,LPOS,ERR,FQ)"):
519 (sign>0?"addToState(TP,LPOS,ERR)":"removeFromState(TP,LPOS,ERR)"),
520 par,covPar);
521
522 // if a pointer is given, compute chi2
523 if (createFQoS) {
524 if (sign<0) {
525 // when removing, the input are updated par
526 fitQoS = new Trk::FitQualityOnSurface(makeChi2Object(r,covTrk,covRio,-1,(nLocCoord==1?1:3)));
527 } else {
528 // when adding chi2 is made from the updated par
529 const Amg::VectorX r_upd = rioPar - H * par;
530 fitQoS = new FitQualityOnSurface(makeChi2Object(r_upd,covPar,covRio,-1,(nLocCoord==1?1:3)));
531 }
532 }
533 // return cloned version of Track Parameters (MeasuredPerigee, MeasuredAtA...)
534 auto updated =
536 par[Trk::loc2],
537 par[Trk::phi],
538 par[Trk::theta],
539 par[Trk::qOverP],
540 std::move(covPar));
541 return updated;
542}
543
544// mathematics for Kalman updator and inverse Kalman filter
545std::unique_ptr<Trk::TrackParameters>
547 const Trk::LocalParameters& rioPar,
548 const Amg::MatrixX& covRio,
549 const int sign,
551 bool createFQoS) const
552{
553
554 // try if Track Parameters are measured ones ?
555 AmgSymMatrix(5) covTrk;
556 if (!trkPar.covariance()) {
557 if (sign<0) {
558 ATH_MSG_WARNING( "MeasuredTrackParameters == Null, can not calculate "
559 << "updated parameter state." );
560 return nullptr;
561 }
562 // no error given - use a huge error matrix for the time
563 // covTrk = Amg::MatrixX(5, 1) * 1000.f;
564 ATH_MSG_VERBOSE( "-U- no covTrk at input - "
565 << "assign large error matrix for the time being." );
566 covTrk(0,0) = m_cov0[0];
567 covTrk(1,1) = m_cov0[1];
568 covTrk(2,2) = m_cov0[2];
569 covTrk(3,3) = m_cov0[3];
570 covTrk(4,4) = m_cov0[4];
571
572 } else {
573 covTrk = (*trkPar.covariance());
574 }
575
576 // LocalParameters parTrk = trkPar.parameters();
577 Amg::VectorX parTrk = trkPar.parameters();
578 if (!thetaPhiWithinRange(parTrk)) {
579 ATH_MSG_WARNING( (sign>0?"addToState(TP,LPAR,ERR..)":"removeFromState(TP,LPAR,ERR..)")
580 << ": undefined phi,theta range in input parameters." );
581 return nullptr;
582 }
583 if (!thetaPhiWithinRange(rioPar,rioPar.parameterKey())) {
584 ATH_MSG_WARNING( (sign>0?"addToState(TP,LPAR,ERR..)":"removeFromState(TP,LPAR,ERR..)")
585 << ": undefined phi,theta range in input measurement !!" );
586 return nullptr;
587 }
588
589 // measurement vector of RIO_OnTrack - needs more care for # local par?
590 int nLocCoord = covRio.cols();
591 if ( ! consistentParamDimensions(rioPar,covRio.cols()) ) return nullptr;
592 if (m_outputlevel<0) logInputCov(covTrk,rioPar,covRio);
593
594 // State to measurement dimensional reduction Matrix ( n x m )
596
597 // residual from reconstructed hit wrt. predicted state
598 Amg::VectorX r = rioPar - H * parTrk;
599 // compute covariance of residual R = +/- covRIO + H * covTrk * H.T()
600 Amg::MatrixX R = (sign * covRio) + projection(covTrk,rioPar.parameterKey()); // .similarity(H);
601 // catch [-pi,pi] phi boundary problems to keep chi2 under control
602 if (!diffThetaPhiWithinRange(r,rioPar.parameterKey()) )
603 correctThetaPhiRange(r,R,true,rioPar.parameterKey());
604
605 // compute Kalman gain matrix
606 if (R.determinant()==0.) return nullptr;
607 Amg::MatrixX K = covTrk * H.transpose() * R.inverse();
608 AmgSymMatrix(5) I; // 5x5 unit matrix
609 I.setIdentity();
610 AmgSymMatrix(5) M = I - K * H;
611 if (m_outputlevel<0) {logGainForm (nLocCoord,r,R.inverse(),K,M);}
612 // compute local filtered state
613 Amg::VectorX par = parTrk + K * r;
614
615 // compute covariance matrix of local filteres state
616 AmgSymMatrix(5) covPar;
617 if (m_useFruehwirth8a) {
618 // one can use as well: covPar = M * covTrk; see A.Gelb why.
619 covPar = AmgSymMatrix(5)(M*covTrk);
620 } else {
621 covPar = AmgSymMatrix(5)(M*covTrk*M.transpose() + sign*K*covRio*K.transpose());
622 }
623 if ( (!thetaPhiWithinRange(par)) ? !correctThetaPhiRange(par,covPar) : false ) {
624 ATH_MSG_WARNING( "calculateFS(TP,LPAR,ERR): bad angles in filtered state!" );
625 return nullptr;
626 }
627 if (m_outputlevel<=0) logResult(createFQoS?
628 (sign>0?"addToState(TP,LPAR,ERR,FQ)":"removeFromState(TP,LPAR,ERR,FQ)"):
629 (sign>0?"addToState(TP,LPAR,ERR)":"removeFromState(TP,LPAR,ERR)"),
630 par,covPar);
631
632 // if a pointer is given, compute chi2
633 if (createFQoS) {
634 if (sign<0) {
635 // when removing, the input are updated par
636 fitQoS = new Trk::FitQualityOnSurface(makeChi2Object(r,covTrk,covRio,-1,rioPar.parameterKey()));
637 } else {
638 // when adding chi2 is made from the updated par
639 Amg::VectorX r_upd = rioPar - H * par;
640 fitQoS = new Trk::FitQualityOnSurface(makeChi2Object(r_upd,covPar,covRio,-1,rioPar.parameterKey()));
641 }
642 }
643 // return cloned version of Track Parameters (MeasuredPerigee, MeasuredAtA...)
645 par[Trk::loc1],
646 par[Trk::loc2],
647 par[Trk::phi],
648 par[Trk::theta],
649 par[Trk::qOverP],
650 std::move(covPar));
651}
652
654{
655 // ATH_MSG_DEBUG( "projection("<<M[0][0]<<", "<<key<<")" );
656 if (key == 31) return M;
657 // reduction matrix
658 const Amg::MatrixX& redMatrix = m_projectionMatrices.reductionMatrix(key);
659 Amg::MatrixX R = redMatrix.transpose()*M*redMatrix;
660 return R;
661
662}
663
664
665
667 int dimCov) const {
668 if (P.dimension() != dimCov ) {
669 ATH_MSG_WARNING( "Inconsistency in dimension of local coord - problem with LocalParameters object?" );
670 ATH_MSG_WARNING( "dim of local parameters: "<< P.dimension()<< " vs. dim of error matrix: "<<dimCov );
671 return false;
672 }
673 if ( (dimCov < 1) || (dimCov > 5 ) ) {
674 ATH_MSG_WARNING( "invalid dimension for local coordinates: " << dimCov );
675 return false;
676 }
677 return true;
678}
679
680
682 const bool isDifference, const int key) const
683{
684 // get phi and theta coordinate
685 int jphi = -1;
686 int jtheta = -1;
687 double thetaMin = (isDifference ? -M_PI : 0);
688 if (key == 31) jphi = Trk::phi;
689 else if (key & 4) { // phi is within localParameter and a measured coordinate
690 for (int itag = 0, ipos=1 ; itag<Trk::phi; ++itag, ipos*=2) if (key & ipos) ++jphi;
691 }
692 if (key == 31) jtheta = Trk::theta;
693 else if (key & 8) { // theta is within localParameter and a measured coordinate
694 for (int itag = 0, ipos=1 ; itag<Trk::theta; ++itag, ipos*=2) if (key & ipos) ++jtheta;
695 }
696
697 // correct theta and phi coordinate
698 if ((jtheta>=0) && (V[jtheta]<thetaMin || V[jtheta]> M_PI) ) {
699 if (m_outputlevel <= 0 ) {
700 if (key !=31) ATH_MSG_WARNING( "-U- key: "<<key << " jphi: "<<jphi << " jtheta: "<<jtheta );
701 msg() << MSG::WARNING << "-U- " << (isDifference?"diff. ":" ") << "angles out of range, phi = ";
702 if (jphi>=0) msg() << V[jphi]; else msg() <<"free";
703 msg() << " theta = " << V[jtheta] <<endmsg;
704 }
705 // absolute theta: repair if between -pi and +2pi.
706 // differential theta: repair if between -pi and +pi
707 if ( ( V(jtheta) < -M_PI ) ||
708 ( V(jtheta) > (isDifference? M_PI : 2*M_PI) )
709 ) {
710 ATH_MSG_WARNING( "-U- track theta too far from defined range, stop update." );
711 msg() << MSG::WARNING << "-U- " << (isDifference?"diff. ":" ") << "angles out of range, phi = ";
712 if (jphi>=0) msg() << V[jphi]; else msg() <<"free";
713 msg() << " theta = " << V[jtheta] <<endmsg;
714 return false;
715 }
716 if (V[jtheta] > M_PI) {
717 V[jtheta] = 2*M_PI - V[jtheta];
718 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -M_PI : M_PI;
719 }
720 if (V[jtheta] < 0.0) {
721 V[jtheta] = -V[jtheta];
722 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -M_PI : M_PI;
723 }
724 if (jtheta==0 && key==24) C(jtheta,1) = -C(jtheta,1);
725 if (jtheta==1) {
726 C(0,jtheta) = -C(0,jtheta);
727 if (key>15) C(2,1) = -C(2,1);
728 }
729 if (jtheta==2) {
730 C(0,jtheta) = -C(0,jtheta);
731 C(1,jtheta) = -C(1,jtheta);
732 if (key>15) C(3,jtheta) = -C(3,jtheta);
733 }
734 if (jtheta==3) {
735 C(0,jtheta) = -C(0,jtheta);
736 C(1,jtheta) = -C(1,jtheta);
737 C(2,jtheta) = -C(2,jtheta);
738 if (key>15) C(4,jtheta) = -C(4,jtheta);
739 }
740
741 if (m_outputlevel <=0) {
742 msg() << MSG::DEBUG << "-U- now use corrected " << (isDifference?"diff. ":" ") << "value phi= ";
743 if (jphi>=0) msg() << V[jphi]; else msg() <<"free";
744 msg() << " theta = " << V[jtheta] <<endmsg;
745 }
746 }
747
748 // correct phi coordinate if necessary
749 if ((jphi>=0) && (V[jphi] > M_PI) ) {
750 ATH_MSG_DEBUG("-U- phi= " << V[jphi]);
751 V[jphi] = std::fmod(V[jphi]+M_PI,2*M_PI)-M_PI;
752 ATH_MSG_DEBUG( " out of range, now corrected to " << V[jphi]);
753 } else if ((jphi>=0) && (V[jphi] < -M_PI) ) {
754 ATH_MSG_DEBUG( "-U- phi= " << V[jphi]);
755 V[jphi] = std::fmod(V[jphi]-M_PI,2*M_PI)+M_PI;
756 ATH_MSG_DEBUG( " out of range, now corrected to " << V[jphi] );
757 }
758 return true;
759}
760
761
764 const bool isDifference, const int key) const
765{
766 // get phi and theta coordinate
767 int jphi = -1;
768 int jtheta = -1;
769 double thetaMin = (isDifference ? -M_PI : 0);
770 if (key == 31) jphi = Trk::phi;
771 else if (key & 4) { // phi is within localParameter and a measured coordinate
772 for (int itag = 0, ipos=1 ; itag<Trk::phi; ++itag, ipos*=2) if (key & ipos) ++jphi;
773 }
774 if (key == 31) jtheta = Trk::theta;
775 else if (key & 8) { // theta is within localParameter and a measured coordinate
776 for (int itag = 0, ipos=1 ; itag<Trk::theta; ++itag, ipos*=2) if (key & ipos) ++jtheta;
777 }
778
779 // correct theta and phi coordinate
780 if ((jtheta>=0) && (V[jtheta]<thetaMin || V[jtheta]> M_PI) ) {
781 if (m_outputlevel <= 0 ) {
782 if (key !=31) ATH_MSG_WARNING( "-U- key: "<<key << " jphi: "<<jphi << " jtheta: "<<jtheta );
783 msg() << MSG::WARNING << "-U- " << (isDifference?"diff. ":" ") << "angles out of range, phi = ";
784 if (jphi>=0) msg() << V[jphi]; else msg() <<"free";
785 msg() << " theta = " << V[jtheta] <<endmsg;
786 }
787 // absolute theta: repair if between -pi and +2pi.
788 // differential theta: repair if between -pi and +pi
789 if ( ( V(jtheta) < -M_PI ) ||
790 ( V(jtheta) > (isDifference? M_PI : 2*M_PI) )
791 ) {
792 ATH_MSG_WARNING( "-U- track theta too far from defined range, stop update." );
793 msg() << MSG::WARNING << "-U- " << (isDifference?"diff. ":" ") << "angles out of range, phi = ";
794 if (jphi>=0) msg() << V[jphi]; else msg() <<"free";
795 msg() << " theta = " << V[jtheta] <<endmsg;
796 return false;
797 }
798 if (V[jtheta] > M_PI) {
799 V[jtheta] = 2*M_PI - V[jtheta];
800 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -M_PI : M_PI;
801 }
802 if (V[jtheta] < 0.0) {
803 V[jtheta] = -V[jtheta];
804 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -M_PI : M_PI;
805 }
806 if (jtheta==0 && key==24) C(jtheta,1) = -C(jtheta,1);
807 if (jtheta==1) {
808 C(0,jtheta) = -C(0,jtheta);
809 if (key>15) C(2,1) = -C(2,1);
810 }
811 if (jtheta==2) {
812 C(0,jtheta) = -C(0,jtheta);
813 C(1,jtheta) = -C(1,jtheta);
814 if (key>15) C(3,jtheta) = -C(3,jtheta);
815 }
816 if (jtheta==3) {
817 C(0,jtheta) = -C(0,jtheta);
818 C(1,jtheta) = -C(1,jtheta);
819 C(2,jtheta) = -C(2,jtheta);
820 if (key>15) C(4,jtheta) = -C(4,jtheta);
821 }
822
823 if (m_outputlevel <=0) {
824 msg() << MSG::DEBUG << "-U- now use corrected " << (isDifference?"diff. ":" ") << "value phi= ";
825 if (jphi>=0) msg() << V[jphi]; else msg() <<"free";
826 msg() << " theta = " << V[jtheta] <<endmsg;
827 }
828 }
829
830 // correct phi coordinate if necessary
831 if ((jphi>=0) && (V[jphi] > M_PI) ) {
832 if (m_outputlevel <=0) msg() << MSG::DEBUG << "-U- phi= " << V[jphi];
833 V[jphi] = std::fmod(V[jphi]+M_PI,2*M_PI)-M_PI;
834 if (m_outputlevel <=0) ATH_MSG_DEBUG( " out of range, now "
835 << "corrected to " << V[jphi] );
836 } else if ((jphi>=0) && (V[jphi] < -M_PI) ) {
837 if (m_outputlevel <=0) msg() << MSG::DEBUG << "-U- phi= " << V[jphi];
838 V[jphi] = std::fmod(V[jphi]-M_PI,2*M_PI)+M_PI;
839 if (m_outputlevel <=0) ATH_MSG_DEBUG( " out of range, now "
840 << "corrected to " << V[jphi] );
841 }
842 return true;
843}
844
845void Trk::KalmanUpdator::logStart(const std::string& IDstring,
846 const Trk::TrackParameters& tp) const
847{
848 ATH_MSG_DEBUG( "--> entered KalmanUpdator::" << IDstring );
849 ATH_MSG_VERBOSE( "-U- TrkPar:" << std::setiosflags(std::ios::right)<<std::setprecision(4)
850 << std::setw( 9)<<tp.parameters()[0]<< std::setw(10)<<tp.parameters()[1]<<std::setprecision(5)
851 << std::setw(10)<<tp.parameters()[2]<< std::setw(10)<<tp.parameters()[3]<<std::setprecision(4)
852 << std::setw(10)<<tp.parameters()[4] );
853}
854
856 const Amg::VectorX& rioPar, const Amg::MatrixX& covRio) const
857{
858 msg() << MSG::VERBOSE << "-U- cov "<<std::setiosflags(std::ios::right)<<std::setprecision(3)
859 << std::setw(9)<<covTrk(0,0)<<" "<< std::setw(9)<<covTrk(0,1)<<" "
860 << std::setw(9)<<covTrk(0,2)<<" "<< std::setw(9)<<covTrk(0,3)<<" "
861 << std::setw(9)<<covTrk(0,4)<<"\n";
862 msg() << " " << " " << " "
863 << std::setw(9)<<covTrk(1,1)<<" "<< std::setw(9)<<covTrk(1,2)<<" "
864 << std::setw(9)<<covTrk(1,3)<<" "<< std::setw(9)<<covTrk(1,4)<<"\n";
865 msg() << " covariance matrix " << " " << " "
866 << std::setw(9)<<covTrk(2,2)<<" "<< std::setw(9)<<covTrk(2,3)<<" "
867 << std::setw(9)<<covTrk(2,4)<< "\n" ;
868 msg() << " of the PREDICTED track pars " << " " << " "
869 << std::setw(9)<<covTrk(3,3)<<" "<< std::setw(9)<<covTrk(3,4)<<"\n" ;
870 msg() << " " << " " << " "
871 << std::setw(9)<<covTrk(4,4)<<std::setprecision(6)<< endmsg;
872
873 int nLocCoord = covRio.cols();
874 msg() << MSG::VERBOSE << "-U- measurement locPos: ";
875 for (int i=0; i<nLocCoord; i++) msg() << rioPar[i] << " ";
876 msg() << endmsg;
877 msg() << MSG::VERBOSE << "-U- measurement (err)^2: " <<std::setprecision(4)<<covRio(0,0);
878 for (int i=1; i<nLocCoord; i++) msg() << ", "<<covRio(i,i);
879 msg() << std::setprecision(6)<<endmsg;
880}
881
883 const Amg::MatrixX& K, const Amg::MatrixX& M) const
884{
885 // again some verbose debug output showing internals of updating
886 msg() << MSG::VERBOSE << "-U- residual: r=("<<r[0];
887 for (int i=1; i<nc; i++) msg() <<","<<r[i];
888 msg() << ")" << endmsg;
889 msg() << MSG::VERBOSE << "-U- inv. sigmaR=("<< R(0,0);
890 for (int i=1; i<nc; i++) msg() << "," << R(i,i);
891 msg() << ")" << endmsg;
892 for (int i=0; i<nc; i++) msg() << MSG::VERBOSE // K is a row x col = 5 x nc matrix.
893 << ( i==0 ? "-U- gain mtx K=(" : " (" )
894 << std::setiosflags(std::ios::fixed | std::ios::showpoint | std::ios::right )
895 << std::setw(7) << std::setprecision(4) << K(0,i)<<", "
896 << std::setw(7) << std::setprecision(4) << K(1,i)<<", "
897 << std::setw(7) << std::setprecision(4) << K(2,i)<<", "
898 << std::setw(7) << std::setprecision(4) << K(3,i)<<", "
899 << std::setw(7) << std::setprecision(4) << K(4,i)<<")"
900 << std::resetiosflags(std::ios::fixed) << endmsg;
901 msg() << MSG::VERBOSE << "-U- matrix M: diag=("
902 << M(0,0)<<"," << M(1,1)<<","
903 << M(2,2)<<"," << M(3,3)<<","
904 << M(4,4) <<")" << endmsg;
905}
906
907void Trk::KalmanUpdator::logResult(const std::string& methodName,
908 const Amg::VectorX& par, const Amg::MatrixX& covPar) const
909{
910 // again some verbose debug output
911 msg() << MSG::VERBOSE << "-U- ==> result for KalmanUpdator::"<<methodName<<endmsg;
912 msg() << MSG::VERBOSE << "-U- new par"<<std::setiosflags(std::ios::right)<<std::setprecision(4)
913 << std::setw( 9)<<par[0]<< std::setw(10)<<par[1]<<std::setprecision(5)
914 << std::setw(10)<<par[2]<< std::setw(10)<<par[3]<<std::setprecision(4)
915 << std::setw(10)<<par[4] <<endmsg;
916 msg() << MSG::VERBOSE << "-U- new cov" <<std::setiosflags(std::ios::right)<<std::setprecision(3)
917 << std::setw(9)<<(covPar)(0,0)<<" "<< std::setw(9)<<(covPar)(0,1)<<" "
918 << std::setw(9)<<(covPar)(0,2)<<" "<< std::setw(9)<<(covPar)(0,3)
919 << " " << std::setw(9)<<(covPar)(0,4)<< "\n";
920 msg() << " " << " " << " "
921 << std::setw(9)<<(covPar)(1,1)<<" "<< std::setw(9)<<(covPar)(1,2)<<" "
922 << std::setw(9)<<(covPar)(1,3)<<" "<< std::setw(9)<<(covPar)(1,4)<< "\n";
923 msg() << " covariance matrix " << " " << " "
924 << std::setw(9)<<(covPar)(2,2)<<" "<< std::setw(9)<<(covPar)(2,3)<<" "
925 << std::setw(9)<<(covPar)(2,4)<< "\n";
926 msg() << " of the UPDATED track pars " << " "
927 << " " <<std::setw(9)<<(covPar)(3,3)<< " "
928 << std::setw(9)<<(covPar)(3,4)<< "\n";
929 msg() << " " << " "
930 << " "
931 << std::setw(9)<<(covPar)(4,4)<<std::setprecision(6)<< endmsg;
932}
#define M_PI
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
static Double_t P(Double_t *tt, Double_t *par)
#define I(x, y, z)
Definition MD5.cxx:116
#define H(x, y, z)
Definition MD5.cxx:114
int sign(int a)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
KalmanUpdator(const std::string &, const std::string &, const IInterface *)
AlgTool standard constuctor.
bool diffThetaPhiWithinRange(const Amg::VectorX &, const int key=31) const
tests if ranges of phi (-pi, pi) and theta (0, pi) residuals are correct *‍/
virtual FitQualityOnSurface fullStateFitQuality(const TrackParameters &, const Amg::Vector2D &, const Amg::MatrixX &) const override final
estimator for FitQuality on Surface from a full track state, that is a state
Amg::MatrixX projection(const Amg::MatrixX &, const int) const
avoid CLHEP's empty math operations (H-matrix) by copying members out
virtual std::unique_ptr< TrackParameters > addToState(const TrackParameters &, const Amg::Vector2D &, const Amg::MatrixX &) const override final
measurement updator for the KalmanFitter getting the meas't coord'
virtual FitQualityOnSurface predictedStateFitQuality(const TrackParameters &, const Amg::Vector2D &, const Amg::MatrixX &) const override final
estimator for FitQuality on Surface from a predicted track state, that is a state
void logInputCov(const Amg::MatrixX &, const Amg::VectorX &, const Amg::MatrixX &) const
internal structuring: common logfile output of the inputs
ProjectionMatricesSet m_projectionMatrices
get the correct projection matrix
FitQualityOnSurface makeChi2Object(const Amg::VectorX &, const Amg::MatrixX &, const Amg::MatrixX &, const int, const int) const
also the chi2 calculation and FitQuality object creation is combined in an extra method.
std::vector< double > m_cov0
job option: initial covariance matrix
virtual StatusCode initialize() override final
AlgTool initialisation.
virtual std::unique_ptr< TrackParameters > combineStates(const TrackParameters &, const TrackParameters &) const override final
trajectory state updator which combines two parts of a trajectory on a common surface.
void logGainForm(int, const Amg::VectorX &, const Amg::MatrixX &, const Amg::MatrixX &, const Amg::MatrixX &) const
internal structuring: common logfile output during calculation
virtual StatusCode finalize() override final
AlgTool termination.
bool consistentParamDimensions(const LocalParameters &, int) const
method testing correct use of LocalParameters *‍/
int m_outputlevel
MsgStream output level cached.
bool thetaPhiWithinRange(const Amg::VectorX &, const int key=31) const
tests if ranges of abolute phi (-pi, pi) and theta (0, pi) are correct *‍/
bool correctThetaPhiRange(Amg::VectorX &, AmgSymMatrix(5) &, const bool isDifference=false, const int key=31) const
brings phi/theta back into valid range using 2pi periodicity
virtual std::unique_ptr< TrackParameters > removeFromState(const TrackParameters &, const Amg::Vector2D &, const Amg::MatrixX &) const override final
reverse update eg for track property analysis (unbiased residuals)
bool m_useFruehwirth8a
job option: formula for cov update
virtual std::vector< double > initialErrors() const override final
gives back how updator is configured for inital covariances
std::unique_ptr< TrackParameters > calculateFilterStep(const TrackParameters &, const Amg::Vector2D &, const Amg::MatrixX &, const int, FitQualityOnSurface *&, bool) const
Common maths calculation code for addToState and removeFromState - Amg::Vector2D interface.
void logStart(const std::string &, const TrackParameters &) const
internal structuring: debugging output for start of method.
void logResult(const std::string &, const Amg::VectorX &, const Amg::MatrixX &) const
internal structuring: common logfile output after calculation
int parameterKey() const
Identifier key for matrix expansion/reduction.
const Amg::MatrixX & expansionMatrix() const
Expansion matrix from 5x5 to the [dimension()]x[dimension()].
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
virtual ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theat, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const =0
Use the Surface as a ParametersBase constructor, from local parameters - charged.
int r
Definition globals.cxx:22
struct color C
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
double chi2(const T &precision, const U &residual, const int sign=1)
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ loc2
generic first and second local coordinate
Definition ParamDefs.h:35
@ phi
Definition ParamDefs.h:75
@ loc1
Definition ParamDefs.h:34
ParametersBase< TrackParametersDim, Charged > TrackParameters
MsgStream & msg
Definition testRead.cxx:32