#include <KalmanFilter.h>
Inheritance diagram for KalmanFilter:
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 | |
State * | m_state |
internal clone of the state (pointer onwer by Kalman) | |
std::vector< FitNode * > | m_nodes |
HepVector | m_K |
ITrackExtrapolator * | m_extrapolator |
extrapolator | |
ITrackProjector * | m_projector |
projector | |
std::string | m_extrapolatorName |
name of the extrapolator in Gaudi | |
std::string | m_projectorName |
name of the projector in Gaudi |
Mattiew Needham
Definition at line 25 of file KalmanFilter.h.
|
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 }
|
|
Destructor.
Definition at line 40 of file KalmanFilter.cpp. 00040 { 00041 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
extrapolator
Definition at line 106 of file KalmanFilter.h. Referenced by filter(), initialize(), and predict(). |
|
name of the extrapolator in Gaudi
Definition at line 112 of file KalmanFilter.h. Referenced by initialize(), and KalmanFilter(). |
|
Definition at line 101 of file KalmanFilter.h. Referenced by filter(), and KalmanFilter(). |
|
Definition at line 98 of file KalmanFilter.h. Referenced by computeChiSq(), filter(), iniKalman(), KalmanFilter(), and smoother(). |
|
projector
Definition at line 109 of file KalmanFilter.h. Referenced by filter(), initialize(), and smooth(). |
|
name of the projector in Gaudi
Definition at line 115 of file KalmanFilter.h. Referenced by initialize(), and KalmanFilter(). |
|
internal clone of the state (pointer onwer by Kalman)
Definition at line 95 of file KalmanFilter.h. Referenced by computeChiSq(), filter(), iniKalman(), and KalmanFilter(). |