SND@LHC Software
Loading...
Searching...
No Matches
genfit::KalmanFitter Class Reference

Simple Kalman filter implementation. More...

#include <KalmanFitter.h>

Inheritance diagram for genfit::KalmanFitter:
Collaboration diagram for genfit::KalmanFitter:

Public Member Functions

 KalmanFitter (unsigned int maxIterations=4, double deltaPval=1e-3, double blowUpFactor=1e3, bool squareRootFormalism=false)
 
 ~KalmanFitter ()
 
void processTrackWithRep (Track *tr, const AbsTrackRep *rep, bool resortHits=false)
 Hit resorting currently NOT supported.
 
void processTrackPartially (Track *tr, const AbsTrackRep *rep, int startId=0, int endId=-1)
 
void useSquareRootFormalism (bool squareRootFormalism=true)
 
- Public Member Functions inherited from genfit::AbsKalmanFitter
 AbsKalmanFitter (unsigned int maxIterations=4, double deltaPval=1e-3, double blowUpFactor=1e3)
 
virtual ~AbsKalmanFitter ()
 
void getChiSquNdf (const Track *tr, const AbsTrackRep *rep, double &bChi2, double &fChi2, double &bNdf, double &fNdf) const
 
double getChiSqu (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
double getNdf (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
double getRedChiSqu (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
double getPVal (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
eMultipleMeasurementHandling getMultipleMeasurementHandling () const
 
virtual void setMinIterations (unsigned int n)
 Set the minimum number of iterations.
 
virtual void setMaxIterations (unsigned int n)
 Set the maximum number of iterations.
 
void setDeltaPval (double deltaPval)
 Set Convergence criterion.
 
void setRelChi2Change (double relChi2Change)
 
void setMultipleMeasurementHandling (eMultipleMeasurementHandling mmh)
 How should multiple measurements be handled?
 
virtual void setMaxFailedHits (int val)
 
bool isTrackPrepared (const Track *tr, const AbsTrackRep *rep) const
 
bool isTrackFitted (const Track *tr, const AbsTrackRep *rep) const
 
bool canIgnoreWeights () const
 returns if the fitter can ignore the weights and handle the MeasurementOnPlanes as if they had weight 1.
 
- Public Member Functions inherited from genfit::AbsFitter
 AbsFitter ()
 
virtual ~AbsFitter ()
 
void processTrack (Track *, bool resortHits=true)
 
virtual void setDebugLvl (unsigned int lvl=1)
 

Private Member Functions

 KalmanFitter (const KalmanFitter &)
 
KalmanFitteroperator= (KalmanFitter const &)
 
bool fitTrack (Track *tr, const AbsTrackRep *rep, double &chi2, double &ndf, int startId, int endId, int &nFailedHits)
 
void processTrackPoint (TrackPoint *tp, const AbsTrackRep *rep, double &chi2, double &ndf, int direction)
 

Private Attributes

boost::scoped_ptr< MeasuredStateOnPlanecurrentState_
 
bool squareRootFormalism_
 

Additional Inherited Members

- Protected Member Functions inherited from genfit::AbsKalmanFitter
const std::vector< MeasurementOnPlane * > getMeasurements (const KalmanFitterInfo *fi, const TrackPoint *tp, int direction) const
 get the measurementsOnPlane taking the multipleMeasurementHandling_ into account
 
- Protected Attributes inherited from genfit::AbsKalmanFitter
unsigned int minIterations_
 Minimum number of iterations to attempt. Forward and backward are counted as one iteration.
 
unsigned int maxIterations_
 Maximum number of iterations to attempt. Forward and backward are counted as one iteration.
 
double deltaPval_
 Convergence criterion.
 
double relChi2Change_
 
double blowUpFactor_
 Blow up the covariance of the forward (backward) fit by this factor before seeding the backward (forward) fit.
 
eMultipleMeasurementHandling multipleMeasurementHandling_
 How to handle if there are multiple MeasurementsOnPlane.
 
int maxFailedHits_
 
- Protected Attributes inherited from genfit::AbsFitter
unsigned int debugLvl_
 

Detailed Description

Simple Kalman filter implementation.

Definition at line 42 of file KalmanFitter.h.

Constructor & Destructor Documentation

◆ KalmanFitter() [1/2]

genfit::KalmanFitter::KalmanFitter ( const KalmanFitter )
private

◆ KalmanFitter() [2/2]

genfit::KalmanFitter::KalmanFitter ( unsigned int  maxIterations = 4,
double  deltaPval = 1e-3,
double  blowUpFactor = 1e3,
bool  squareRootFormalism = false 
)
inline

Definition at line 52 of file KalmanFitter.h.

53 : AbsKalmanFitter(maxIterations, deltaPval, blowUpFactor), currentState_(NULL),
54 squareRootFormalism_(squareRootFormalism)
55 {}
AbsKalmanFitter(unsigned int maxIterations=4, double deltaPval=1e-3, double blowUpFactor=1e3)
boost::scoped_ptr< MeasuredStateOnPlane > currentState_

◆ ~KalmanFitter()

genfit::KalmanFitter::~KalmanFitter ( )
inline

Definition at line 57 of file KalmanFitter.h.

57{}

Member Function Documentation

◆ fitTrack()

bool KalmanFitter::fitTrack ( Track tr,
const AbsTrackRep rep,
double &  chi2,
double &  ndf,
int  startId,
int  endId,
int &  nFailedHits 
)
private

Definition at line 42 of file KalmanFitter.cc.

45{
46
51 Exception exc("KalmanFitter::fitTrack ==> cannot use (un)weightedClosestToReference(Wire) as multiple measurement handling.",__LINE__,__FILE__);
52 exc.setFatal();
53 throw exc;
54 }
55
56 if (startId < 0)
57 startId += tr->getNumPointsWithMeasurement();
58 if (endId < 0)
59 endId += tr->getNumPointsWithMeasurement();
60
61 int direction(1);
62 if (endId < startId)
63 direction = -1;
64
65 chi2 = 0;
66 ndf = -1. * rep->getDim();
67
68 nFailedHits = 0;
69
70 if (debugLvl_ > 0) {
71 std::cout << tr->getNumPointsWithMeasurement() << " TrackPoints w/ measurement in this track." << std::endl;
72 }
73 for (int i = startId; ; i+=direction) {
75 assert(direction == +1 || direction == -1);
76
77 if (debugLvl_ > 0) {
78 std::cout << " process TrackPoint nr. " << i << " (" << tp << ")\n";
79 }
80
81 try {
82 processTrackPoint(tp, rep, chi2, ndf, direction);
83 }
84 catch (Exception& e) {
85 std::cerr << e.what();
86
87 ++nFailedHits;
88 if (maxFailedHits_<0 || nFailedHits <= maxFailedHits_) {
89 tr->getPoint(i)->deleteFitterInfo(rep);
90
91 if (i == endId)
92 break;
93
94 if (debugLvl_ > 0)
95 std::cout << "There was an exception, try to continue with next TrackPoint " << i+direction << " \n";
96
97 continue;
98 }
99
100 return false;
101 }
102
103 if (i == endId)
104 break;
105 }
106
107 return true;
108}
unsigned int debugLvl_
Definition AbsFitter.h:55
eMultipleMeasurementHandling multipleMeasurementHandling_
How to handle if there are multiple MeasurementsOnPlane.
virtual unsigned int getDim() const =0
Get the dimension of the state vector used by the track representation.
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition Exception.h:48
virtual const char * what() const
Standard error message handling for exceptions. use like "std::cerr << e.what();".
Definition Exception.cc:51
void processTrackPoint(TrackPoint *tp, const AbsTrackRep *rep, double &chi2, double &ndf, int direction)
Object containing AbsMeasurement and AbsFitterInfo objects.
Definition TrackPoint.h:50
void deleteFitterInfo(const AbsTrackRep *rep)
Definition TrackPoint.h:117
TrackPoint * getPoint(int id) const
Definition Track.cc:201
TrackPoint * getPointWithMeasurement(int id) const
Definition Track.cc:209
unsigned int getNumPointsWithMeasurement() const
Definition Track.h:112
int i
Definition ShipAna.py:86
@ weightedClosestToReference
@ weightedClosestToReferenceWire
@ unweightedClosestToReference
@ unweightedClosestToReferenceWire

◆ operator=()

KalmanFitter & genfit::KalmanFitter::operator= ( KalmanFitter const &  )
private

◆ processTrackPartially()

void KalmanFitter::processTrackPartially ( Track tr,
const AbsTrackRep rep,
int  startId = 0,
int  endId = -1 
)

process only a part of the track. Can also be used to process the track only in backward direction. Does not alter the FitStatus and does not do multiple iterations.

Definition at line 302 of file KalmanFitter.cc.

302 {
303
304 if (tr->getFitStatus(rep) != NULL && tr->getFitStatus(rep)->isTrackPruned()) {
305 Exception exc("KalmanFitter::processTrack: Cannot process pruned track!", __LINE__,__FILE__);
306 throw exc;
307 }
308
309 if (startId < 0)
310 startId += tr->getNumPointsWithMeasurement();
311 if (endId < 0)
312 endId += tr->getNumPointsWithMeasurement();
313
314 int direction(1);
315 if (endId < startId)
316 direction = -1;
317
318
319 TrackPoint* trackPoint = tr->getPointWithMeasurement(startId);
320 TrackPoint* prevTrackPoint(NULL);
321
322
323 if (direction == 1 && startId > 0)
324 prevTrackPoint = tr->getPointWithMeasurement(startId - 1);
325 else if (direction == -1 && startId < (int)tr->getNumPointsWithMeasurement() - 1)
326 prevTrackPoint = tr->getPointWithMeasurement(startId + 1);
327
328
329 if (prevTrackPoint != NULL &&
330 prevTrackPoint->hasFitterInfo(rep) &&
331 dynamic_cast<KalmanFitterInfo*>(prevTrackPoint->getFitterInfo(rep)) != NULL &&
332 static_cast<KalmanFitterInfo*>(prevTrackPoint->getFitterInfo(rep))->hasUpdate(direction)) {
333 currentState_.reset(new MeasuredStateOnPlane(*(static_cast<KalmanFitterInfo*>(prevTrackPoint->getFitterInfo(rep))->getUpdate(direction))));
334 if (debugLvl_ > 0)
335 std::cout << "take update of previous fitter info as seed \n";
336 }
337 else if (rep != tr->getCardinalRep() &&
338 trackPoint->hasFitterInfo(tr->getCardinalRep()) &&
339 dynamic_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(tr->getCardinalRep())) != NULL &&
340 static_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(tr->getCardinalRep()))->hasPredictionsAndUpdates() ) {
341 if (debugLvl_ > 0)
342 std::cout << "take smoothed state of cardinal rep fit as seed \n";
343 TVector3 pos, mom;
344 TMatrixDSym cov;
345 const MeasuredStateOnPlane& fittedState = static_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(tr->getCardinalRep()))->getFittedState(true);
346 tr->getCardinalRep()->getPosMomCov(fittedState, pos, mom, cov);
347 currentState_.reset(new MeasuredStateOnPlane(rep));
348 rep->setPosMomCov(*currentState_, pos, mom, cov);
349 rep->setQop(*currentState_, tr->getCardinalRep()->getQop(fittedState));
350 }
351 else {
352 currentState_.reset(new MeasuredStateOnPlane(rep));
354 if (debugLvl_ > 0)
355 std::cout << "take seed of track as seed \n";
356 }
357
358 // if at first or last hit, blow up
359 if (startId == 0 || startId == (int)tr->getNumPointsWithMeasurement() - 1) {
360 currentState_->blowUpCov(blowUpFactor_);
361 if (debugLvl_ > 0)
362 std::cout << "blow up seed \n";
363 }
364
365 if (debugLvl_ > 0) {
366 std::cout << "\033[1;21mstate pre" << std::endl;
367 currentState_->Print();
368 std::cout << "\033[0mfitting" << std::endl;
369 }
370
371 double chi2, ndf;
372 int nFailedHits;
373 fitTrack(tr, rep, chi2, ndf, startId, endId, nFailedHits); // return value has no consequences here
374
375}
double blowUpFactor_
Blow up the covariance of the forward (backward) fit by this factor before seeding the backward (forw...
virtual double getQop(const StateOnPlane &state) const =0
Get charge over momentum.
virtual void setPosMomCov(MeasuredStateOnPlane &state, const TVector3 &pos, const TVector3 &mom, const TMatrixDSym &cov6x6) const =0
Set position, momentum and covariance of state.
virtual void setQop(StateOnPlane &state, double qop) const =0
Set charge/momentum.
virtual void getPosMomCov(const MeasuredStateOnPlane &state, TVector3 &pos, TVector3 &mom, TMatrixDSym &cov) const =0
Translates MeasuredStateOnPlane into 3D position, momentum and 6x6 covariance.
bool isTrackPruned() const
Has the track been pruned after the fit?
Definition FitStatus.h:70
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
bool hasPredictionsAndUpdates() const
KalmanFittedStateOnPlane * getUpdate(int direction) const
bool hasUpdate(int direction) const
bool fitTrack(Track *tr, const AbsTrackRep *rep, double &chi2, double &ndf, int startId, int endId, int &nFailedHits)
StateOnPlane with additional covariance matrix.
bool hasFitterInfo(const AbsTrackRep *rep) const
Definition TrackPoint.h:103
AbsFitterInfo * getFitterInfo(const AbsTrackRep *rep=NULL) const
Get fitterInfo for rep. Per default, use cardinal rep.
const TVectorD & getStateSeed() const
Definition Track.h:158
const TMatrixDSym & getCovSeed() const
Definition Track.h:162
FitStatus * getFitStatus(const AbsTrackRep *rep=NULL) const
Get FitStatus for a AbsTrackRep. Per default, return FitStatus for cardinalRep.
Definition Track.h:149
AbsTrackRep * getCardinalRep() const
Get cardinal track representation.
Definition Track.h:140

◆ processTrackPoint()

void KalmanFitter::processTrackPoint ( TrackPoint tp,
const AbsTrackRep rep,
double &  chi2,
double &  ndf,
int  direction 
)
private

Definition at line 379 of file KalmanFitter.cc.

381{
382 assert(direction == -1 || direction == +1);
383
384 if (!tp->hasRawMeasurements())
385 return;
386
387 bool newFi(false);
388
390 if (! tp->hasFitterInfo(rep)) {
391 fi = new KalmanFitterInfo(tp, rep);
392 tp->setFitterInfo(fi);
393 newFi = true;
394 }
395 else
396 fi = static_cast<KalmanFitterInfo*>(tp->getFitterInfo(rep));
397
398 SharedPlanePtr plane;
399 bool oldWeightsFixed(false);
400 std::vector<double> oldWeights;
401
402 // construct measurementsOnPlane if forward fit
403 if (newFi) {
404 // remember old weights
405 oldWeights = fi->getWeights();
406 oldWeightsFixed = fi->areWeightsFixed();
407
408 // delete outdated stuff
409 fi->deleteForwardInfo();
410 fi->deleteBackwardInfo();
412
413 // construct plane with first measurement
414 const std::vector< genfit::AbsMeasurement* >& rawMeasurements = tp->getRawMeasurements();
415 plane = rawMeasurements[0]->constructPlane(*currentState_);
416 }
417 else
418 plane = fi->getPlane();
419
420
421
422 // Extrapolate
424 double extLen = rep->extrapolateToPlane(*state, plane);
425
426 if (debugLvl_ > 0) {
427 std::cout << "extrapolated by " << extLen << std::endl;
428 }
429 //std::cout << "after extrap: " << std::endl;
430 //state.Print();
431
432 // unique_ptr takes care of disposing of the old prediction, takes ownership of state.
433 fi->setPrediction(state, direction);
434
435
436 // construct new MeasurementsOnPlane
437 if (newFi) {
438 const std::vector< genfit::AbsMeasurement* >& rawMeasurements = tp->getRawMeasurements();
439 for (std::vector< genfit::AbsMeasurement* >::const_iterator it = rawMeasurements.begin(); it != rawMeasurements.end(); ++it) {
440 fi->addMeasurementsOnPlane((*it)->constructMeasurementsOnPlane(*state));
441 }
442 if (oldWeights.size() == fi->getNumMeasurements()) {
443 fi->setWeights(oldWeights);
444 fi->fixWeights(oldWeightsFixed);
445 if (debugLvl_ > 0) {
446 std::cout << "set old weights \n";
447 }
448 }
449 assert(fi->getPlane() == plane);
450 assert(fi->checkConsistency());
451 }
452
453 if (debugLvl_ > 0) {
454 std::cout << "its plane is at R = " << plane->getO().Perp()
455 << " with normal pointing along (" << plane->getNormal().X() << ", " << plane->getNormal().Y() << ", " << plane->getNormal().Z() << ")" << std::endl;
456 }
457
458
459 // update(s)
460 TVectorD stateVector(state->getState());
461 TMatrixDSym cov(state->getCov());
462
463 double chi2inc = 0;
464 double ndfInc = 0;
465 const std::vector<MeasurementOnPlane *> measurements = getMeasurements(fi, tp, direction);
466 for (std::vector<MeasurementOnPlane *>::const_iterator it = measurements.begin(); it != measurements.end(); ++it) {
467 const MeasurementOnPlane& mOnPlane = **it;
468 const double weight = mOnPlane.getWeight();
469
470 if (debugLvl_ > 0) {
471 std::cout << "Weight of measurement: " << weight << "\n";
472 }
473
474 if (!canIgnoreWeights() && weight <= 1.01E-10) {
475 if (debugLvl_ > 0) {
476 std::cout << "Weight of measurement is almost 0, continue ... \n";
477 }
478 continue;
479 }
480
481 const TVectorD& measurement(mOnPlane.getState());
482 const AbsHMatrix* H(mOnPlane.getHMatrix());
483 // (weighted) cov
484 const TMatrixDSym& V((!canIgnoreWeights() && weight < 0.99999) ?
485 1./weight * mOnPlane.getCov() :
486 mOnPlane.getCov());
487 if (debugLvl_ > 1) {
488 std::cout << "\033[31m";
489 std::cout << "State prediction: "; stateVector.Print();
490 std::cout << "Cov prediction: "; state->getCov().Print();
491 std::cout << "\033[0m";
492 std::cout << "\033[34m";
493 std::cout << "measurement: "; measurement.Print();
494 std::cout << "measurement covariance V: "; V.Print();
495 //cov.Print();
496 //measurement.Print();
497 }
498
499 TVectorD res(measurement - H->Hv(stateVector));
500 if (debugLvl_ > 1) {
501 std::cout << "Residual = (" << res(0);
502 if (res.GetNrows() > 1)
503 std::cout << ", " << res(1);
504 std::cout << ")" << std::endl;
505 std::cout << "\033[0m";
506 }
507 // If hit, do Kalman algebra.
508
510 {
511 // Square Root formalism, Anderson & Moore, 6.5.12 gives the
512 // formalism for combined update and prediction in that
513 // sequence. We need the opposite sequence. Therefore, this
514 // is my own invention. This is not optimized for speed
515 // outside the QR decomposition code (which would be faster if
516 // it were to work on the transposed matrix). First step
517 // would be replacing the use of TMatrixDSymEigen with an LDLt
518 // transformation.
519 TMatrixD F;
520 TMatrixDSym noise;
521 TVectorD deltaState;
522 rep->getForwardJacobianAndNoise(F, noise, deltaState);
523 const TMatrixDSym& oldCov(currentState_->getCov());
524
525 // Square Roots:
526 //
527 // The noise matrix is only positive semi-definite, for instance
528 // no noise on q/p. A Cholesky decomposition is therefore not
529 // possible. Hence we pull out the eigenvalues, viz noise = z d
530 // z^T (with z orthogonal, d diagonal) and then construct the
531 // square root according to Q^T = sqrt(d) z where sqrt is
532 // applied element-wise and negative eigenvalues are forced to
533 // zero. We then reduce the matrix such that the zero
534 // eigenvalues don't appear in the remainder of the calculation.
535 TMatrixDSymEigen eig(noise);
536 TMatrixD Q(eig.GetEigenVectors());
537 const TVectorD& evs(eig.GetEigenValues());
538 // Multiplication with a diagonal matrix ... eigenvalues are
539 // sorted in descending order.
540 int iCol = 0;
541 for (; iCol < Q.GetNcols(); ++iCol) {
542 double ev = evs(iCol) > 0 ? sqrt(evs(iCol)) : 0;
543 if (ev == 0)
544 break;
545 for (int j = 0; j < Q.GetNrows(); ++j)
546 Q(j,iCol) *= ev;
547 }
548 if (iCol < Q.GetNrows()) {
549 // Hit zero eigenvalue, resize matrix ...
550 Q.ResizeTo(iCol, Q.GetNcols());
551 }
552 // This gives the original matrix:
553 // TMatrixDSym(TMatrixDSym::kAtA,TMatrixD(TMatrixD::kTransposed,Q)).Print();
554 // i.e., we now have the transposed we need.
555
556 TDecompChol oldCovDecomp(oldCov);
557 oldCovDecomp.Decompose();
558 const TMatrixD& S(oldCovDecomp.GetU()); // this actually the transposed we want.
559
560 TDecompChol decompR(V);
561 decompR.Decompose();
562
563 TMatrixD pre(S.GetNrows() + Q.GetNrows() + V.GetNrows(),
564 S.GetNcols() + V.GetNcols());
565 TMatrixD SFt(S, TMatrixD::kMultTranspose, F);
566 pre.SetSub( 0, 0,decompR.GetU());/* upper right block is zero */
567 pre.SetSub( V.GetNrows(), 0,H->MHt(SFt)); pre.SetSub(V.GetNrows(), V.GetNcols(),SFt);
568 if (Q.GetNrows() > 0) { // needed to suppress warnings when inserting an empty Q
569 pre.SetSub(S.GetNrows()+V.GetNrows(),0,H->MHt(Q)); pre.SetSub(S.GetNrows()+V.GetNrows(),V.GetNcols(), Q);
570 }
571
572 tools::QR(pre);
573 const TMatrixD& r = pre;
574
575 TMatrixD R(r.GetSub(0, V.GetNrows()-1, 0, V.GetNcols()-1));
576 //R.Print();
577 TMatrixD K(TMatrixD::kTransposed, r.GetSub(0, V.GetNrows()-1, V.GetNcols(), pre.GetNcols()-1));
578 //K.Print();
579 //(K*R).Print();
580 TMatrixD Snew(r.GetSub(V.GetNrows(), V.GetNrows() + S.GetNrows() - 1,
581 V.GetNcols(), pre.GetNcols()-1));
582 //Snew.Print();
583 // No need for matrix inversion.
584 TVectorD update(res);
586 update *= K;
587 stateVector += update;
588 cov = TMatrixDSym(TMatrixDSym::kAtA, Snew); // Note that this is transposed in just the right way.
589 }
590 else
591 {
592 // calculate kalman gain ------------------------------
593 // calculate covsum (V + HCH^T) and invert
594 TMatrixDSym covSumInv(cov);
595 H->HMHt(covSumInv);
596 covSumInv += V;
597 tools::invertMatrix(covSumInv);
598
599 TMatrixD CHt(H->MHt(cov));
600 TVectorD update(TMatrixD(CHt, TMatrixD::kMult, covSumInv) * res);
601 //TMatrixD(CHt, TMatrixD::kMult, covSumInv).Print();
602
603 if (debugLvl_ > 1) {
604 //std::cout << "STATUS:" << std::endl;
605 //stateVector.Print();
606 std::cout << "\033[32m";
607 std::cout << "Update: "; update.Print();
608 std::cout << "\033[0m";
609 //cov.Print();
610 }
611
612 stateVector += update;
613 covSumInv.Similarity(CHt); // with (C H^T)^T = H C^T = H C (C is symmetric)
614 cov -= covSumInv;
615 }
616
617 if (debugLvl_ > 1) {
618 std::cout << "\033[32m";
619 std::cout << "updated state: "; stateVector.Print();
620 std::cout << "updated cov: "; cov.Print();
621 }
622
623 TVectorD resNew(measurement - H->Hv(stateVector));
624 if (debugLvl_ > 1) {
625 std::cout << "Residual New = (" << resNew(0);
626
627 if (resNew.GetNrows() > 1)
628 std::cout << ", " << resNew(1);
629 std::cout << ")" << std::endl;
630 std::cout << "\033[0m";
631 }
632
633 /*TDecompChol dec(cov);
634 TMatrixDSym mist(cov);
635 bool status = dec.Invert(mist);
636 if (!status) {
637 if (debugLvl_ > 0) {
638 std::cout << "new cov not pos. def." << std::endl;
639 }
640 }*/
641
642 // Calculate chi²
643 TMatrixDSym HCHt(cov);
644 H->HMHt(HCHt);
645 HCHt -= V;
646 HCHt *= -1;
647
649
650 chi2inc += HCHt.Similarity(resNew);
651
652 if (!canIgnoreWeights()) {
653 ndfInc += weight * measurement.GetNrows();
654 }
655 else
656 ndfInc += measurement.GetNrows();
657
658 if (debugLvl_ > 0) {
659 std::cout << "chi² increment = " << chi2inc << std::endl;
660 }
661 } // end loop over measurements
662
663 currentState_->setStateCovPlane(stateVector, cov, plane);
664 currentState_->setAuxInfo(state->getAuxInfo());
665
666 chi2 += chi2inc;
667 ndf += ndfInc;
668
669 // set update
670 KalmanFittedStateOnPlane* updatedSOP = new KalmanFittedStateOnPlane(*currentState_, chi2inc, ndfInc);
671 fi->setUpdate(updatedSOP, direction);
672}
const SharedPlanePtr & getPlane() const
HMatrix for projecting from AbsTrackRep parameters to measured parameters in a DetPlane.
Definition AbsHMatrix.h:37
bool canIgnoreWeights() const
returns if the fitter can ignore the weights and handle the MeasurementOnPlanes as if they had weight...
const std::vector< MeasurementOnPlane * > getMeasurements(const KalmanFitterInfo *fi, const TrackPoint *tp, int direction) const
get the measurementsOnPlane taking the multipleMeasurementHandling_ into account
virtual double extrapolateToPlane(StateOnPlane &state, const genfit::SharedPlanePtr &plane, bool stopAtBoundary=false, bool calcJacobianNoise=false) const =0
Extrapolates the state to plane, and returns the extrapolation length and, via reference,...
virtual void getForwardJacobianAndNoise(TMatrixD &jacobian, TMatrixDSym &noise, TVectorD &deltaState) const =0
Get the jacobian and noise matrix of the last extrapolation.
MeasuredStateOnPlane with additional info produced by a Kalman filter or DAF.
virtual bool checkConsistency() const
void setWeights(const std::vector< double > &)
Set weights of measurements.
void addMeasurementsOnPlane(const std::vector< genfit::MeasurementOnPlane * > &measurementsOnPlane)
std::vector< double > getWeights() const
Get weights of measurements.
void setPrediction(MeasuredStateOnPlane *prediction, int direction)
unsigned int getNumMeasurements() const
void fixWeights(bool arg=true)
bool areWeightsFixed() const
Are the weights fixed?
void setUpdate(KalmanFittedStateOnPlane *update, int direction)
const TMatrixDSym & getCov() const
Measured coordinates on a plane.
const AbsHMatrix * getHMatrix() const
const TVectorD & getState() const
const TVectorD & getAuxInfo() const
dict S
Definition MufiCTR.py:12
void QR(TMatrixD &A)
Replaces A with an upper right matrix connected to A by an orthongonal transformation....
Definition Tools.cc:249
bool transposedForwardSubstitution(const TMatrixD &R, TVectorD &b)
Solves R^t x = b, replacing b with the solution for x. R is assumed to be upper diagonal.
Definition Tools.cc:199
void invertMatrix(const TMatrixDSym &mat, TMatrixDSym &inv, double *determinant=NULL)
Invert a matrix, throwing an Exception when inversion fails. Optional calculation of determinant.
Definition Tools.cc:38
boost::shared_ptr< genfit::DetPlane > SharedPlanePtr
Shared Pointer to a DetPlane.

◆ processTrackWithRep()

void KalmanFitter::processTrackWithRep ( Track tr,
const AbsTrackRep rep,
bool  resortHits = false 
)
virtual

Hit resorting currently NOT supported.

Implements genfit::AbsFitter.

Definition at line 111 of file KalmanFitter.cc.

112{
113
114 if (tr->getFitStatus(rep) != NULL && tr->getFitStatus(rep)->isTrackPruned()) {
115 Exception exc("KalmanFitter::processTrack: Cannot process pruned track!", __LINE__,__FILE__);
116 throw exc;
117 }
118
119 TrackPoint* trackPoint = tr->getPointWithMeasurement(0);
120
121 if (trackPoint->hasFitterInfo(rep) &&
122 dynamic_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(rep)) != NULL &&
123 static_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(rep))->hasUpdate(-1)) {
124 MeasuredStateOnPlane* update = static_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(rep))->getUpdate(-1);
125 currentState_.reset(new MeasuredStateOnPlane(*update));
126 if (debugLvl_ > 0)
127 std::cout << "take backward update of previous iteration as seed \n";
128 }
129 if (rep != tr->getCardinalRep() &&
130 trackPoint->hasFitterInfo(tr->getCardinalRep()) &&
131 dynamic_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(tr->getCardinalRep())) != NULL &&
132 static_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(tr->getCardinalRep()))->hasPredictionsAndUpdates() ) {
133 if (debugLvl_ > 0)
134 std::cout << "take smoothed state of cardinal rep fit as seed \n";
135 TVector3 pos, mom;
136 TMatrixDSym cov;
137 const MeasuredStateOnPlane& fittedState = static_cast<KalmanFitterInfo*>(trackPoint->getFitterInfo(tr->getCardinalRep()))->getFittedState(true);
138 tr->getCardinalRep()->getPosMomCov(fittedState, pos, mom, cov);
139 currentState_.reset(new MeasuredStateOnPlane(rep));
140 rep->setPosMomCov(*currentState_, pos, mom, cov);
141 rep->setQop(*currentState_, tr->getCardinalRep()->getQop(fittedState));
142 }
143 else {
144 currentState_.reset(new MeasuredStateOnPlane(rep));
146 if (debugLvl_ > 0)
147 std::cout << "take seed state of track as seed \n";
148 }
149
150 // Only after we have linearly propagated the error into the TrackRep can we
151 // blow up the error in good faith.
152 currentState_->blowUpCov(blowUpFactor_);
153
154 double oldChi2FW(1.e6);
155 double oldChi2BW(1.e6);
156 double oldPvalFW(0.);
157
158 double oldPvalBW = 0.;
159 double chi2FW(0), ndfFW(0);
160 double chi2BW(0), ndfBW(0);
161
162 int nFailedHitsForward(0), nFailedHitsBackward(0);
163
164
166 tr->setFitStatus(status, rep);
167
168 unsigned int nIt = 0;
169 for(;;) {
170 try {
171 if (debugLvl_ > 0) {
172 std::cout << "\033[1;21mstate pre" << std::endl;
173 currentState_->Print();
174 std::cout << "\033[0mfitting" << std::endl;
175 }
176
177 if (!fitTrack(tr, rep, chi2FW, ndfFW, 0, -1, nFailedHitsForward)) {
178 status->setIsFitted(false);
179 status->setIsFitConvergedFully(false);
180 status->setIsFitConvergedPartially(false);
181 status->setNFailedPoints(nFailedHitsForward);
182 return;
183 }
184
185 if (debugLvl_ > 0) {
186 std::cout << "\033[1;21mstate post forward" << std::endl;
187 currentState_->Print();
188 std::cout << "\033[0m";
189 }
190
191 // Backwards iteration:
192 currentState_->blowUpCov(blowUpFactor_); // blow up cov
193
194 if (!fitTrack(tr, rep, chi2BW, ndfBW, -1, 0, nFailedHitsBackward)) {
195 status->setIsFitted(false);
196 status->setIsFitConvergedFully(false);
197 status->setIsFitConvergedPartially(false);
198 status->setNFailedPoints(nFailedHitsBackward);
199 return;
200 }
201
202 if (debugLvl_ > 0) {
203 std::cout << "\033[1;21mstate post backward" << std::endl;
204 currentState_->Print();
205 std::cout << "\033[0m";
206
207 std::cout << "old chi2s: " << oldChi2BW << ", " << oldChi2FW
208 << " new chi2s: " << chi2BW << ", " << chi2FW
209 << " oldPvals " << oldPvalFW << ", " << oldPvalBW << std::endl;
210 }
211 ++nIt;
212
213 double PvalBW = ROOT::Math::chisquared_cdf_c(chi2BW, ndfBW);
214 double PvalFW = (debugLvl_ > 0) ? ROOT::Math::chisquared_cdf_c(chi2FW, ndfFW) : 0; // Don't calculate if not debugging as this function potentially takes a lot of time.
215 // See if p-value only changed little. If the initial
216 // parameters are very far off, initial chi^2 and the chi^2
217 // after the first iteration will be both very close to zero, so
218 // we need to force at least two iterations here. Convergence
219 // doesn't make much sense before running twice anyway.
220 bool converged(false);
221 bool finished(false);
222 if (nIt >= minIterations_ && fabs(oldPvalBW - PvalBW) < deltaPval_) {
223 // if pVal ~ 0, check if chi2 has changed significantly
224 if (chi2BW == 0) {
225 finished = false;
226 }
227 else if (fabs(1 - fabs(oldChi2BW / chi2BW)) > relChi2Change_) {
228 finished = false;
229 }
230 else {
231 finished = true;
232 converged = true;
233 }
234
235 if (PvalBW == 0.)
236 converged = false;
237 }
238
239 if (finished) {
240 if (debugLvl_ > 0) {
241 std::cout << "Fit is finished! ";
242 if(converged)
243 std::cout << "Fit is converged! ";
244 std::cout << "\n";
245 }
246
247 if (nFailedHitsForward == 0 && nFailedHitsBackward == 0)
248 status->setIsFitConvergedFully(converged);
249 else
250 status->setIsFitConvergedFully(false);
251
252 status->setIsFitConvergedPartially(converged);
253
254 status->setNFailedPoints(std::max(nFailedHitsForward, nFailedHitsBackward));
255
256 break;
257 }
258 else {
259 oldPvalBW = PvalBW;
260 oldChi2BW = chi2BW;
261 if (debugLvl_ > 0) {
262 oldPvalFW = PvalFW;
263 oldChi2FW = chi2FW;
264 }
265 currentState_->blowUpCov(blowUpFactor_); // blow up cov
266 }
267
268 if (nIt >= maxIterations_) {
269 if (debugLvl_ > 0)
270 std::cout << "KalmanFitter::number of max iterations reached!\n";
271 break;
272 }
273 }
274 catch(Exception& e) { // should not happen, but I leave it in for safety
275 std::cerr << e.what();
276 status->setIsFitted(false);
277 status->setIsFitConvergedFully(false);
278 status->setIsFitConvergedPartially(false);
279 status->setNFailedPoints(std::max(nFailedHitsForward, nFailedHitsBackward));
280 return;
281 }
282 }
283
284 status->setIsFitted();
285 double charge(0);
287 if (tp != NULL) {
288 if (static_cast<KalmanFitterInfo*>(tp->getFitterInfo(rep))->hasBackwardUpdate())
289 charge = static_cast<KalmanFitterInfo*>(tp->getFitterInfo(rep))->getBackwardUpdate()->getCharge();
290 }
291 status->setNFailedPoints(std::max(nFailedHitsForward, nFailedHitsBackward));
292 status->setCharge(charge);
293 status->setNumIterations(nIt);
294 status->setForwardChi2(chi2FW);
295 status->setBackwardChi2(chi2BW);
296 status->setForwardNdf(std::max(0., ndfFW));
297 status->setBackwardNdf(std::max(0., ndfBW));
298}
unsigned int maxIterations_
Maximum number of iterations to attempt. Forward and backward are counted as one iteration.
double deltaPval_
Convergence criterion.
unsigned int minIterations_
Minimum number of iterations to attempt. Forward and backward are counted as one iteration.
FitStatus for use with AbsKalmanFitter implementations.
const MeasuredStateOnPlane & getFittedState(bool biased=true) const
Get unbiased or biased (default) smoothed state.
TrackPoint * getPointWithMeasurementAndFitterInfo(int id, const AbsTrackRep *rep) const
Definition Track.cc:217
void setFitStatus(FitStatus *fitStatus, const AbsTrackRep *rep)
Definition Track.cc:285

◆ useSquareRootFormalism()

void genfit::KalmanFitter::useSquareRootFormalism ( bool  squareRootFormalism = true)
inline

Definition at line 66 of file KalmanFitter.h.

66{squareRootFormalism_ = squareRootFormalism;}

Member Data Documentation

◆ currentState_

boost::scoped_ptr<MeasuredStateOnPlane> genfit::KalmanFitter::currentState_
private

Definition at line 74 of file KalmanFitter.h.

◆ squareRootFormalism_

bool genfit::KalmanFitter::squareRootFormalism_
private

Definition at line 79 of file KalmanFitter.h.


The documentation for this class was generated from the following files: