Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

KalmanFilter Class Reference

#include <KalmanFilter.h>

Inheritance diagram for KalmanFilter:

ITrackFitter List of all members.

Public Member Functions

 KalmanFilter (const std::string &type, const std::string &name, const IInterface *parent)
 Standard constructor.
virtual ~KalmanFilter ()
 Destructor.
StatusCode initialize ()
StatusCode fit (Track &track)
 fit the track (filter and smoother)
StatusCode fit (Track &track, const State &seed)
 fit the track (filter and smoother)
StatusCode filter (Track &track, const State &seed)
 filter the track (only filter)
StatusCode filter (State &state, Measurement &meas)
 filter/update state with this measurement

Protected Member Functions

StatusCode iniKalman (Track &track)
 initialize the filter to fit7/filter his track
StatusCode predict (FitNode &node, State &state)
 predict the state to this node
StatusCode filter (FitNode &node)
 filter this node
StatusCode smoother (Track &track)
 smooth the track
StatusCode smooth (FitNode &node0, FitNode &node1)
 smooth 2 nodes
void computeChiSq (Track &track)
 compute the chi2
StatusCode failure (const std::string &comment)
 print comment of failure
StatusCode checkInvertMatrix (HepSymMatrix &mat)
StatusCode checkPositiveMatrix (HepSymMatrix &mat)
StatusCode invertMatrix (HepSymMatrix &mat)
StatusCode cToG3 (HepSymMatrix &C)
 change of units to facilitate inversion
StatusCode cToG4 (HepSymMatrix &invC)
 change of units to facilitate inversion

Protected Attributes

Statem_state
 internal clone of the state (pointer onwer by Kalman)
std::vector< FitNode * > m_nodes
HepVector m_K
ITrackExtrapolatorm_extrapolator
 extrapolator
ITrackProjectorm_projector
 projector
std::string m_extrapolatorName
 name of the extrapolator in Gaudi
std::string m_projectorName
 name of the projector in Gaudi

Detailed Description

Author:
Jose Angel Hernando Morata
Date:
2005-04-15 reusing the previous code
Author:
Rutger van der Eijk 07-04-1999

Mattiew Needham

Definition at line 25 of file KalmanFilter.h.


Constructor & Destructor Documentation

KalmanFilter::KalmanFilter const std::string &  type,
const std::string &  name,
const IInterface *  parent
 

Standard constructor.

Definition at line 24 of file KalmanFilter.cpp.

References m_extrapolatorName, m_K, m_nodes, m_projectorName, and m_state.

00026                                                       :
00027   GaudiTool( type, name, parent)
00028 {
00029   declareInterface<ITrackFitter>( this );
00030 
00031   declareProperty("Extrapolator",m_extrapolatorName = "MasterExtrapolator");
00032 
00033   declareProperty("Projector",m_projectorName = "MasterProjector");
00034 
00035   m_state = NULL;
00036   m_nodes.clear();
00037   m_K = HepVector(5,0);
00038 }

KalmanFilter::~KalmanFilter  )  [virtual]
 

Destructor.

Definition at line 40 of file KalmanFilter.cpp.

00040                             {
00041 }


Member Function Documentation

StatusCode KalmanFilter::checkInvertMatrix HepSymMatrix &  mat  )  [protected]
 

Definition at line 363 of file KalmanFilter.cpp.

Referenced by smooth().

00364 {
00365   int nParam = (int) mat.num_row();
00366   for (int i=0; i<nParam; ++i){
00367     for (int j=0; j<nParam; ++j){
00368       if (mat[i][j] > 1e20)
00369         return Warning("covariance errors too big to invert");
00370     } // j
00371   }   // i
00372   return StatusCode::SUCCESS;
00373 }

StatusCode KalmanFilter::checkPositiveMatrix HepSymMatrix &  mat  )  [protected]
 

Definition at line 375 of file KalmanFilter.cpp.

Referenced by smooth().

00376 {
00377   int nParam = (int) mat.num_row();
00378   for (int i=0; i<nParam; ++i){
00379     if (mat[i][i] <= 0.)
00380       return Warning("covariance errors too big to convert");
00381   } 
00382  
00383 
00384  return StatusCode::SUCCESS;
00385 }

void KalmanFilter::computeChiSq Track track  )  [protected]
 

compute the chi2

Definition at line 151 of file KalmanFilter.cpp.

References Node::chi2(), m_nodes, m_state, and State::nParameters().

Referenced by filter(), and smoother().

00152 {
00153   double chi2 = 0.;
00154   for (std::vector<FitNode*>::iterator it = m_nodes.begin();
00155        it != m_nodes.end(); it++) 
00156     chi2 += (*it)->chi2();
00157   int ndof = -(m_state->nParameters());
00158   ndof += m_nodes.size();
00159   double chi2Norma = 0.;
00160   if (ndof != 0) chi2Norma = chi2 /((float) (ndof));
00161   track.setChi2PerDoF(chi2Norma);
00162   track.setNDoF(ndof);
00163 
00164   if (msgLevel(MSG::DEBUG)) {
00165     debug() << " track ndof \t" << track.chi2() << endreq;
00166     debug() << " track chi2, chi2/ndof \t " << track.chi2()  << ", "
00167             << track.chi2PerDoF() << endreq;
00168   }
00169   
00170 }

StatusCode KalmanFilter::cToG3 HepSymMatrix &  C  )  [protected]
 

change of units to facilitate inversion

Definition at line 423 of file KalmanFilter.cpp.

Referenced by invertMatrix().

00423                                              {
00424 
00425   // cov matrix
00426   C[0][0] /= cm2;
00427   C[0][1] /= cm2;
00428   C[0][2] /= cm;
00429   C[0][3] /= cm;
00430   C[0][4]  = C[0][4]*GeV/cm;
00431 
00432   C[1][1] /= cm2;
00433   C[1][2] /= cm;
00434   C[1][3] /= cm;
00435   C[1][4]  = C[1][4]*GeV/cm;
00436 
00437   C[2][4]  = C[2][4]*GeV;
00438 
00439   C[3][4]  = C[3][4]*GeV;
00440 
00441   C[4][4]  = C[4][4]*GeV*GeV;
00442 
00443   return StatusCode::SUCCESS;
00444 
00445 }

StatusCode KalmanFilter::cToG4 HepSymMatrix &  invC  )  [protected]
 

change of units to facilitate inversion

Definition at line 450 of file KalmanFilter.cpp.

Referenced by invertMatrix().

00450                                                 {
00451 
00452   // cov matrix
00453   invC[0][0] /= cm2;
00454   invC[0][1] /= cm2;
00455   invC[0][2] /= cm;
00456   invC[0][3] /= cm;
00457   invC[0][4]  = invC[0][4]*GeV/cm;
00458 
00459   invC[1][1] /= cm2;
00460   invC[1][2] /= cm;
00461   invC[1][3] /= cm;
00462   invC[1][4]  = invC[1][4]*GeV/cm;
00463 
00464   invC[2][4]  = invC[2][4]*GeV;
00465 
00466   invC[3][4]  = invC[3][4]*GeV;
00467 
00468   invC[4][4]  = invC[4][4]*GeV*GeV;
00469 
00470   return StatusCode::SUCCESS;
00471 }

StatusCode KalmanFilter::failure const std::string &  comment  )  [protected]
 

print comment of failure

Definition at line 52 of file KalmanFilter.cpp.

Referenced by filter(), fit(), predict(), smooth(), and smoother().

00052                                                         {
00053   info() << " Kalman Filter failure: " << comment << endreq;
00054   return StatusCode::FAILURE;
00055 }

StatusCode KalmanFilter::filter FitNode node  )  [protected]
 

filter this node

Definition at line 208 of file KalmanFilter.cpp.

References Measurement::errMeasure(), ITrackProjector::errResidual(), failure(), filter(), m_K, m_projector, ITrackProjector::projectionMatrix(), and ITrackProjector::residual().

00209 {
00210   
00211   Measurement& meas = node.measurement();
00212   State& state = node.state();
00213 
00214   StatusCode sc = filter(state, meas);
00215   if (sc.isFailure()) return failure("Not able to filter the node!");
00216 
00217   double tMeasureError = meas.errMeasure();
00218   double res = m_projector->residual();  
00219   const HepVector& H = m_projector->projectionMatrix();
00220 
00221   double HK = dot ( H, m_K);
00222   res     *= (1 - HK);
00223   double errorRes = (1 - HK) * pow(tMeasureError, 2.0);
00224   
00225   node.setResidual(res);
00226   node.setErrResidual(sqrt(errorRes));
00227   
00228   // save predicted state
00229   node.setFilteredState(state);
00230 
00231   if (msgLevel(MSG::DEBUG)) {
00232     debug() << " filtered residual and error \t" << node.residual() << ", "
00233             <<node.errResidual() << endreq;;
00234   } 
00235  
00236   return StatusCode::SUCCESS;
00237 }

StatusCode KalmanFilter::filter State state,
Measurement meas
[virtual]
 

filter/update state with this measurement

Implements ITrackFitter.

Definition at line 244 of file KalmanFilter.cpp.

References ITrackProjector::errResidual(), failure(), m_K, m_projector, ITrackProjector::project(), ITrackProjector::projectionMatrix(), and ITrackProjector::residual().

00244                                                                 {
00245   
00246   // check z position
00247   if ( fabs(meas.z() - state.z()) > 1e-6) {
00248     warning() << "z position of TrState (=" << state.z() 
00249               << ") and TrStateMeasurement (= " << meas.z() 
00250               << ") are not equal." << endreq;
00251   }
00252 
00253   // get reference to the state vector and cov
00254   HepVector&    tX = state.stateVector();
00255   HepSymMatrix& tC = state.covariance();
00256 
00257   // project the state into the measurement 
00258   StatusCode sc = m_projector->project(state,meas);
00259   if (sc.isFailure()) 
00260     return failure(" Not able to project a state into a measurement");
00261   
00262   // calculate predicted residuals
00263   double errorMeas = meas.errMeasure();
00264   double res = m_projector->residual();
00265   double errorRes = m_projector->errResidual();
00266   double errorRes2 = (errorRes*errorRes);
00267   const HepVector& H = m_projector->projectionMatrix();
00268 
00269   // calculate gain matrix K
00270   m_K = (tC * H)/errorRes2;
00271 
00272   // update state vector 
00273   tX += m_K * res;
00274 
00275   HepMatrix B  = HepDiagMatrix(tC.num_row(), 1) - ( m_K * H.T());
00276   tC.assign( B * tC * B.T() + ( m_K * pow(errorMeas, 2.0) * m_K.T()));
00277 
00278  if (msgLevel(MSG::DEBUG)) {
00279     debug() << " measure and error \t" << meas.measure() << ", " 
00280             << errorMeas << endreq;
00281     debug() << " residual and error \t" << res << ", " 
00282             << errorRes << endreq;
00283     debug() << " projection matrix \t" << H << endreq;
00284     debug() << " gain matrix \t" << m_K << endreq;
00285     debug() << " filter state vector \t" << tX << endreq;
00286     debug() << " filter state covariance \t"<< tC << endreq;
00287   }
00288   
00289   return sc;
00290 }

StatusCode KalmanFilter::filter Track track,
const State seed
[virtual]
 

filter the track (only filter)

Implements ITrackFitter.

Definition at line 103 of file KalmanFilter.cpp.

References State::clone(), computeChiSq(), failure(), iniKalman(), m_extrapolator, m_nodes, m_state, predict(), ITrackExtrapolator::propagate(), and State::z().

Referenced by filter(), and fit().

00104 {
00105   StatusCode sc = StatusCode::SUCCESS;
00106   sc = iniKalman(track);
00107   if (sc.isFailure()) return failure(" Not able to create Nodes");
00108 
00109   m_state = state.clone();
00110 
00111   std::vector<FitNode*>::iterator iNode = m_nodes.begin();
00112   double z = (*iNode)->measurement().z();
00113   // sc = m_extrapolator->propagate(*m_state,z,m_particleID);
00114   sc = m_extrapolator->propagate(*m_state,z);
00115   if (sc.isFailure()) 
00116     return failure(" Not able to extrapolate to 1st measurement");
00117 
00118   // TODO: handle different iterations
00119   for (iNode = m_nodes.begin(); iNode != m_nodes.end(); ++iNode) {
00120     FitNode& node = *(*iNode);
00121     sc = predict(node,*m_state);
00122     if (sc.isFailure()) return failure(" not able to predict at node");
00123     sc = filter(node);
00124     if (sc.isFailure()) return failure(" not able to filter node ");
00125   }  
00126 
00127   computeChiSq(track);
00128   return sc;
00129 }

StatusCode KalmanFilter::fit Track track,
const State seed
[virtual]
 

fit the track (filter and smoother)

Implements ITrackFitter.

Definition at line 61 of file KalmanFilter.cpp.

References failure(), filter(), and smoother().

00062 {
00063   StatusCode sc = filter(track,state);
00064   if (sc.isFailure()) return failure(" No able to filter the track");
00065   
00066   return sc = smoother(track);
00067   if (sc.isFailure()) return failure(" No able to smooth the track");
00068   
00069   return sc;
00070 }

StatusCode KalmanFilter::fit Track track  )  [inline, virtual]
 

fit the track (filter and smoother)

Implements ITrackFitter.

Definition at line 38 of file KalmanFilter.h.

00038                               {
00039     info() << " not implemented yet!" << track.nMeasurements() << endreq;
00040     return StatusCode::SUCCESS;
00041   }

StatusCode KalmanFilter::iniKalman Track track  )  [protected]
 

initialize the filter to fit7/filter his track

Definition at line 72 of file KalmanFilter.cpp.

References State::covariance(), m_nodes, m_state, and State::stateVector().

Referenced by filter().

00073 {
00074   // destroy the previous state if not null
00075   if (m_state != NULL) delete m_state;
00076   // Kalman has private copy of the nodes to acelerate the computations
00077   // remember that the track owns the Nodes, so it is responsability of the
00078   // Track destructor to delete them!
00079   m_nodes.clear();
00080   std::vector<Measurement*>& measures = track.measurements();
00081   std::vector<Node*>& nodes = track.nodes();
00082   if (nodes.size() > 0) 
00083     for (std::vector<Node*>::iterator it = nodes.begin(); it != nodes.end();
00084          it++) delete *it;  
00085   nodes.clear();
00086   for (std::vector<Measurement*>::iterator it = measures.begin(); 
00087        it != measures.end(); it++) {
00088     Measurement& meas = *(*it);
00089     FitNode* node = new FitNode(meas);
00090     m_nodes.push_back(node);
00091     track.addToNodes(node);
00092   }
00093 
00094   if (msgLevel(MSG::DEBUG)) {
00095     debug() << " seed state vector \t" << m_state->stateVector() << endreq;
00096     debug() << " seed state cov \t" << m_state->covariance() << endreq;
00097     debug() << " track nodes size \t" << m_nodes.size() << endreq;
00098   }
00099   
00100   return StatusCode::SUCCESS;
00101 }

StatusCode KalmanFilter::initialize  ) 
 

Definition at line 43 of file KalmanFilter.cpp.

References m_extrapolator, m_extrapolatorName, m_projector, and m_projectorName.

00044 {
00045   m_extrapolator = get<ITrackExtrapolator>(m_extrapolatorName);
00046 
00047   m_projector = get<ITrackProjector>(m_projectorName);
00048 
00049   return StatusCode::SUCCESS;
00050 }

StatusCode KalmanFilter::invertMatrix HepSymMatrix &  mat  )  [protected]
 

Definition at line 397 of file KalmanFilter.cpp.

References cToG3(), and cToG4().

Referenced by smooth().

00397                                                                {
00398 
00399   StatusCode sc = StatusCode::SUCCESS; 
00400 
00401   // G3 units
00402   cToG3(invPrevNodeC);
00403 
00404   HepSymMatrix tempMatrix = invPrevNodeC;
00405 
00406   int ifail;
00407   invPrevNodeC.invert(ifail);
00408 
00409   //G4 units
00410   cToG4(invPrevNodeC);
00411 
00412   if (ifail !=0){
00413     warning()
00414        <<"failed to invert covariance matrix, failure code " <<ifail<<endreq;
00415     sc = StatusCode::FAILURE;
00416   }
00417   return sc;
00418 }

StatusCode KalmanFilter::predict FitNode node,
State state
[protected]
 

predict the state to this node

Definition at line 175 of file KalmanFilter.cpp.

References failure(), m_extrapolator, Node::measurement(), ITrackExtrapolator::propagate(), ITrackExtrapolator::transportMatrix(), and Measurement::z().

Referenced by filter().

00175                                                               {
00176 
00177   Measurement& thisMeasure = aNode.measurement();
00178 
00179   // only use extrapolator in first iteration; else use stored parameters
00180   HepVector prevStateVec = aState.stateVector();
00181   HepSymMatrix prevStateCov = aState.covariance();
00182   double z = thisMeasure.z();
00183   // StatusCode sc = m_extrapolator->propagate(state,z,m_particleID);
00184   StatusCode sc = m_extrapolator->propagate(aState,z);
00185   if (sc.isFailure()) 
00186     return failure(" No able to predit state at next measurement");
00187 
00188   const HepMatrix& F = m_extrapolator->transportMatrix();
00189   aNode.setTransportMatrix( F );
00190   aNode.setTransportVector( aState.stateVector() - F * prevStateVec );
00191   aNode.setNoiseMatrix( aState.covariance() - prevStateCov.similarity(F) );
00192 
00193   // save predicted state
00194   aNode.setPredictedState(aState);
00195 
00196   if (msgLevel(MSG::DEBUG)) {
00197     debug() << " predicted  state at z \t" << z << endreq;
00198     debug() << " predicted  state vector  \t" << aState.stateVector() << endreq;
00199     debug() << " predicted  state cov \t" << aState.covariance() << endreq;
00200     debug() << " transport matrix \t" << aNode.transportMatrix() << endreq;
00201     debug() << " transport vector \t" << aNode.transportVector() << endreq;
00202     debug() << " noise matrix \t" << aNode.noiseMatrix() << endreq;
00203   } 
00204 
00205   return StatusCode::SUCCESS;  
00206 }

StatusCode KalmanFilter::smooth FitNode node0,
FitNode node1
[protected]
 

smooth 2 nodes

Definition at line 298 of file KalmanFilter.cpp.

References checkInvertMatrix(), checkPositiveMatrix(), ITrackProjector::chi2(), ITrackProjector::errResidual(), failure(), invertMatrix(), m_projector, ITrackProjector::project(), ITrackProjector::projectionMatrix(), and ITrackProjector::residual().

Referenced by smoother().

00298                                                                    {
00299 
00300   // preliminaries, first we need to invert the _predicted_ covariance
00301   // matrix at k+1
00302   HepVector&    prevNodeX = prevNode.predictedState().stateVector();
00303   HepSymMatrix& prevNodeC = prevNode.predictedState().covariance();
00304 
00305   // check that the elements are not too large else dsinv will crash
00306   StatusCode sc = checkInvertMatrix(prevNodeC);; 
00307   if ( sc.isFailure() ) return failure(" not valid matrix in smoother"); 
00308 
00309   //invert the covariance matrix
00310   HepSymMatrix  invPrevNodeC = prevNodeC;
00311   sc = invertMatrix(invPrevNodeC);
00312   if ( sc.isFailure() ) return failure(" inverting matrix in smoother");
00313 
00314   //references to _predicted_ state + cov of this node from the first step
00315   HepVector&    thisNodeX = thisNode.state().stateVector();
00316   HepSymMatrix& thisNodeC = thisNode.state().covariance();
00317 
00318   //transport
00319   const HepMatrix& F = prevNode.transportMatrix();
00320 
00321   //calculate gain matrix A
00322   HepMatrix A = thisNodeC * F.T() * invPrevNodeC;
00323 
00324   // best = smoothed state at prev Node
00325   HepVector&    prevNodeSmoothedX = prevNode.state().stateVector();
00326   HepSymMatrix& prevNodeSmoothedC = prevNode.state().covariance();
00327 
00328   //smooth state
00329   thisNodeX += A * (prevNodeSmoothedX - prevNodeX);
00330 
00331   // smooth covariance  matrix
00332   HepSymMatrix covDiff = prevNodeSmoothedC- prevNodeC;
00333   HepSymMatrix covUpDate = covDiff.similarity(A);
00334   thisNodeC += covUpDate;
00335 
00336   // check that the cov matrix is possitive
00337   sc = checkPositiveMatrix(thisNodeC);
00338   if (sc.isFailure()) return Warning(" not postive Matrix in smoother");
00339 
00340   // update = smooth the residuals
00341   const HepVector& H = thisNode.projectionMatrix();
00342   sc = m_projector->project(thisNode.state(),thisNode.measurement());
00343   if (sc.isFailure()) Warning(" unable to project the smooth node");
00344   double res = m_projector->residual();
00345   thisNode.setResidual(res);
00346   double errRes = thisNode.errResidual();
00347   double errRes2 = errRes*errRes -  covUpDate.similarity(H);
00348   if (errRes2 >0.) errRes = sqrt(errRes2);
00349   else return Warning(" negative error residuals in smoother");
00350   thisNode.setErrResidual(sqrt(errRes));
00351 
00352   if (msgLevel(MSG::DEBUG)) {
00353     debug() << " A matrix \t" << A << endreq;;
00354     debug() << " smooth state vector \t" << thisNodeX << endreq;
00355     debug() << " smooth state covariance \t"<< thisNodeC << endreq;
00356     debug() << " smooth residual, error and chi2 \t" << res << ", "
00357             << errRes << ", " << thisNode.chi2() << endreq;      
00358   }
00359 
00360   return StatusCode::SUCCESS;
00361 }

StatusCode KalmanFilter::smoother Track track  )  [protected]
 

smooth the track

Definition at line 131 of file KalmanFilter.cpp.

References computeChiSq(), failure(), m_nodes, and smooth().

Referenced by fit().

00132 {
00133   StatusCode sc = StatusCode::SUCCESS;
00134   // smoother loop - runs in opposite direction to filter
00135   std::vector<FitNode*>::reverse_iterator riNode = m_nodes.rbegin();
00136   FitNode* oldNode = *riNode;
00137   ++riNode;
00138   
00139   while (riNode != m_nodes.rend()) {
00140     sc = smooth( *(*riNode), *oldNode );
00141     if (sc.isFailure()) return failure(" not able to smooth node");      
00142     oldNode = *riNode;
00143     ++riNode;
00144   }
00145 
00146   computeChiSq(track);
00147 
00148   return StatusCode::SUCCESS;
00149 }


Member Data Documentation

ITrackExtrapolator* KalmanFilter::m_extrapolator [protected]
 

extrapolator

Definition at line 106 of file KalmanFilter.h.

Referenced by filter(), initialize(), and predict().

std::string KalmanFilter::m_extrapolatorName [protected]
 

name of the extrapolator in Gaudi

Definition at line 112 of file KalmanFilter.h.

Referenced by initialize(), and KalmanFilter().

HepVector KalmanFilter::m_K [protected]
 

Definition at line 101 of file KalmanFilter.h.

Referenced by filter(), and KalmanFilter().

std::vector<FitNode*> KalmanFilter::m_nodes [protected]
 

Definition at line 98 of file KalmanFilter.h.

Referenced by computeChiSq(), filter(), iniKalman(), KalmanFilter(), and smoother().

ITrackProjector* KalmanFilter::m_projector [protected]
 

projector

Definition at line 109 of file KalmanFilter.h.

Referenced by filter(), initialize(), and smooth().

std::string KalmanFilter::m_projectorName [protected]
 

name of the projector in Gaudi

Definition at line 115 of file KalmanFilter.h.

Referenced by initialize(), and KalmanFilter().

State* KalmanFilter::m_state [protected]
 

internal clone of the state (pointer onwer by Kalman)

Definition at line 95 of file KalmanFilter.h.

Referenced by computeChiSq(), filter(), iniKalman(), and KalmanFilter().


The documentation for this class was generated from the following files:
Generated on Fri May 27 13:59:43 2005 for New Track Event Model by doxygen 1.4.1