//----------------------------------------------------------- // File and Version Information: // $Id$ // // Description: // Implementation of class Kalman // see Kalman.hh for details // // Environment: // Software developed for the PANDA Detector at FAIR. // // Author List: // Sebastian Neubert TUM (original author) // // //----------------------------------------------------------- // Panda Headers ---------------------- // This Class' Header ------------------ #include "Kalman.h" // C/C++ Headers ---------------------- #include "assert.h" #include #include #include "TMath.h" // Collaborating Class Headers -------- #include "Track.h" #include "AbsRecoHit.h" #include "AbsTrackRep.h" #include "FitParams.h" #include "FitterExceptions.h" // Class Member definitions ----------- Kalman::Kalman(){;} Kalman::~Kalman(){;} void Kalman::processTrack(Track* trk){ trk->setNextHitToFit(0); continueTrack(trk); } void Kalman::continueTrack(Track* trk){ //loop over hits //std::cout<<"Kalman::processTrack::Starting track"<getNumHits(); unsigned int starthit=trk->getNextHitToFit(); if(starthit==nhits) { std::cout<<"Kalman::processTrack::Already at end of Track!"<getNumReps(); // for(int i=0;igetTrackRep(i)->Print(); for(int ihit=starthit; ihitgetHit(ihit); //ahit->Print(); // loop over reps for(int irep=0; irepgetTrackRep(irep); if(arep->getStatusFlag()==0) { try { //std::cout<<"."; processHit(ahit,arep,ihit); } catch(FitterException& e) { std::cout << e.what() << std::endl; e.info(); arep->setStatusFlag(1); continue; // go to next rep immediately // throw e; //rethrow } } } } trk->setNextHitToFit(nhits); //std::cout<<"Track finished"<getTrackRep(0)->getFitParams(); std::cout << "ABC" << i << std::endl; TMatrixT mat; par->getfJacobian(i,mat); mat.Print(); } */ // smoothing(trk); // std::cout<<"Final state and cov fro trkRep[0]:"; // trk->getTrackRep(0)->getState().Print(); // trk->getTrackRep(0)->getCov().Print(); } double Kalman::getChi2Hit(AbsRecoHit* hit, AbsTrackRep* rep) { // get prototypes for matrices int repDim=rep->getDim(); TMatrixT state(repDim,1); TMatrixT cov(repDim,repDim);; TMatrixT jacobian(repDim,repDim); DetPlane pl=hit->getDetPlane(rep); rep->predict(pl,state,cov,jacobian); hit->setHMatrix(rep,state); //hit->setHMatrix(s,pred,); TMatrixT H=hit->getHMatrix(); // get hit covariances TMatrixT V=hit->getHitCov(pl); TMatrixT r=hit->residualVector(rep,state); // residuals covariances:R=(V - HCH^T) TMatrixT R(V); TMatrixT covsum1(cov,TMatrixT::kMultTranspose,H); TMatrixT covsum(H,TMatrixT::kMult,covsum1); R+=covsum; // note minus sign! // chisq= r^TR^(-1)r double det=0; TMatrixT Rsave(R); R.Invert(&det); if(TMath::IsNaN(det))std::cout<<"predicted residual: det nan!"< chisq=r.T()*(R*r); // note: .T() will change r! assert(chisq.GetNoElements()==1); return chisq[0][0]; } void Kalman::processHit(AbsRecoHit* hit, AbsTrackRep* rep,int hitIndex){ //get fitParamsObject from trackRep in order to fill statePre,stateFilt, //covPred,covFilt for this hit FitParams* params = rep->getFitParams(); // make prediction ------------------------------------ // get prototypes for matrices int repDim=rep->getDim(); TMatrixT state(repDim,1); TMatrixT cov(repDim,repDim);; TMatrixT jacobian(repDim,repDim); //double s=0; //rep->getState().Print(); //rep->getCov().Print(); //hit->getHitCoord(s,rep).Print(); //hit->getHitCov(s,rep).Print(); //std::cout << hit->getS() << std::endl; // get the virtual detector plane DetPlane pl=hit->getDetPlane(rep); //pl.Print(); // let the rep do the prediction //std::cout<<"++++++++++++++ do prediction: ++++++++++++++++"<predict(pl,state,cov,jacobian); //state.Print(); //cov.Print(); //std::cout<<"++++++++++++++++++++++++++++++++++++++++++++++"<addfStatePred(hitIndex,state); params->addfCovPred(hitIndex,cov); params->addfJacobian(hitIndex,jacobian); // create a predicted trackrep // AbsTrackRep* pred=rep->prototype(); // pred->setState(state); // pred->setCov(cov); //pred->setS(s); // get H Matrix at prediction hit->setHMatrix(rep,state); //hit->setHMatrix(s,pred,); TMatrixT H=hit->getHMatrix(); // get hit covariances TMatrixT V=hit->getHitCov(pl); // calculate kalman gain ------------------------------ TMatrixT Gain(gain(cov,V,H)); //Gain.Print(); //hit->residualVector(s,rep,state).Print(); // calculate update ----------------------------------- state+=Gain*hit->residualVector(rep,state); // prediction overwritten! //std::cout<<"++++++++after update++++++++++++++++++++++++++++++++++++"<setState(state); rep->setCov(cov); rep->setReferencePlane(pl); params->addfStateFilt(hitIndex,state); params->addfCovFilt(hitIndex,cov); // calculate filtered chisq // filtered residual TMatrixT r=hit->residualVector(rep,state); // residuals covariances:R=(V - HCH^T) TMatrixT R(V); TMatrixT covsum1(cov,TMatrixT::kMultTranspose,H); TMatrixT covsum(H,TMatrixT::kMult,covsum1); R+=covsum; // note minus sign! // chisq= r^TR^(-1)r double det=0; TMatrixT Rsave(R); R.Invert(&det); if(TMath::IsNaN(det))std::cout<<"filtered residual: det nan!"< chisq=r.T()*(R*r); // note: .T() will change r! assert(chisq.GetNoElements()==1); // cov.Print(); //std::cout << "chi2 incr: " << chisq[0][0] << std::endl; rep->addChiSqu(chisq[0][0]); if(TMath::IsNaN(chisq[0][0])){ FitterException exc("chi2 is nan",__LINE__,__FILE__); std::vector numbers; numbers.push_back(det); exc.setNumbers("det",numbers); std::vector< TMatrixT > matrices; matrices.push_back(r); matrices.push_back(V); matrices.push_back(Rsave); matrices.push_back(R); matrices.push_back(state); matrices.push_back(cov); matrices.push_back(Gain); exc.setMatrices("r, V, Rsave, R, state, cov and Gain",matrices); throw exc; } } TMatrixT Kalman::gain(const TMatrixT& cov, const TMatrixT& HitCov, const TMatrixT& H){ // calculate covsum (V + HCH^T) TMatrixT covsum1(cov,TMatrixT::kMultTranspose,H); TMatrixT covsum(H,TMatrixT::kMult,covsum1); //TMatrixT covsum=H*(cov*H.T()); covsum+=HitCov; // invert double det=0; covsum.Invert(&det); if(TMath::IsNaN(det)) throw FitterException("Kalman Gain: det of covum is nan",__LINE__,__FILE__); if(det==0){ FitterException exc("cannot invert covsum in Kalman Gain - det=0", __LINE__,__FILE__); std::vector< TMatrixT > matrices; matrices.push_back(cov); matrices.push_back(HitCov); matrices.push_back(covsum1); matrices.push_back(covsum); exc.setMatrices("cov, HitCov, covsum1 and covsum",matrices); throw exc; } // calculate gain TMatrixT gain1(H,TMatrixT::kTransposeMult,covsum); TMatrixT gain(cov,TMatrixT::kMult,gain1); return gain; } void Kalman::smoothing(Track* trk) { std::cout<<"Kalman::smoothing"<getNumHits(); int nreps=trk->getNumReps(); //for the last hit set the fin state and cov to the filt values for(int irep=0; irepgetTrackRep(irep); FitParams* par = rep->getFitParams(); TMatrixT lastStateFilt; TMatrixT lastCovFilt; par->getfStateFilt(nhits-1,lastStateFilt); par->getfCovFilt(nhits-1,lastCovFilt); par->addStateFin(nhits-1,lastStateFilt); par->addCovFin(nhits-1,lastCovFilt); } //go backwards over all the hit indices from n-1 to 0 for(int k=nhits-2; k>=0; k--){ for(int irep=0; irepgetTrackRep(irep); int repDim = rep->getDim(); FitParams* par = rep->getFitParams(); TMatrixT p_k_k; TMatrixT p_kplus1_k; TMatrixT p_kplus1_n; TMatrixT C_k_k; TMatrixT C_kplus1_k; TMatrixT C_kplus1_n; TMatrixT F_kplus1; par->getfStatePred(k+1,p_kplus1_k); par->getfStateFilt(k,p_k_k); par->getStateFin(k+1,p_kplus1_n); par->getfCovPred(k+1,C_kplus1_k); par->getfCovFilt(k,C_k_k); par->getCovFin(k+1,C_kplus1_n); par->getfJacobian(k+1,F_kplus1); TMatrixT C_kplus1_k_inv(C_kplus1_k); double det = 0.; // std::cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << std::endl; // C_kplus1_k_inv.Print(); C_kplus1_k_inv.Invert(&det); // C_kplus1_k_inv.Print(); // C_kplus1_k_inv.Invert(&det); // C_kplus1_k_inv.Print(); // C_kplus1_k_inv.Invert(&det); TMatrixT A1(F_kplus1, TMatrixT::kTransposeMult, C_kplus1_k_inv); TMatrixT A(C_k_k,TMatrixT::kMult,A1); TMatrixT stateFin(p_k_k-A* (p_kplus1_k-p_kplus1_n) ); TMatrixT covFin2( C_kplus1_k-C_kplus1_n, TMatrixT::kMultTranspose, A ); TMatrixT covFin( C_k_k-(A*covFin2) ); par->addStateFin(k,stateFin); par->addCovFin(k,covFin); } } }