25 #include "TDatabasePDG.h" 32 #include "cetlib_except/exception.h" 38 #define COVEXC "cov_is_zero" 41 genf::GFKalman::GFKalman():fInitialDirection(1),fNumIt(3),fBlowUpFactor(50.),fMomLow(-100.0),fMomHigh(100.0),fMaxUpdate(1.0),fErrScaleSTh(1.0),fErrScaleMTh(1.0), fGENfPRINT(false)
50 if ((direction != 1) && (direction != -1))
51 throw GFException(std::string(__func__) +
": wrong direction", __LINE__, __FILE__).
setFatal();
72 for(
int ipass=0; ipass<2*
fNumIt; ipass++){
90 throw cet::exception(
"GFKalman.cxx: ") <<
" Line " << __LINE__ <<
", " << __FILE__ <<
" ...Rethrow. \n";
96 for(
int i=0; i<nreps; ++i){
107 for(
int i=0; i<nreps; ++i){
118 if(direction==1) direction=-1;
129 for(
int i=0; i<nreps; ++i){
136 for(
int irep=0; irep<nreps; ++irep){
140 TMatrixT<Double_t> cov = arep->
getCov();
141 for(
int i=0;i<cov.GetNrows();++i){
142 for(
int j=0;j<cov.GetNcols();++j){
158 for(
int irep=0; irep<nreps; ++irep){
162 TMatrixT<Double_t> cov = arep->
getCov();
163 for(
int i=0;i<cov.GetNrows();++i){
164 for(
int j=0;j<cov.GetNcols();++j){
186 int ihit=(int)starthit;
189 for(
int i=0;i<nreps;++i){
198 while((ihit<(
int)nhits && direction==1) || (ihit>-1 && direction==-1)){
201 for(
int irep=0; irep<nreps; ++irep){
209 std::cerr << e.
what();
225 const TMatrixT<Double_t>& cov,
const TMatrixT<Double_t>& V){
228 TMatrixT<Double_t>
R(V);
229 TMatrixT<Double_t> covsum1(cov,TMatrixT<Double_t>::kMultTranspose,H);
230 TMatrixT<Double_t> covsum(H,TMatrixT<Double_t>::kMult,covsum1);
236 TMatrixT<Double_t> Rsave(R);
245 GFException e(
"Kalman Chi2Increment: R is not even invertible. But keep plowing on ... ",__LINE__,__FILE__);
249 if(TMath::IsNaN(det)) {
250 throw GFException(
"Kalman Chi2Increment: det of covsum is nan",__LINE__,__FILE__).
setFatal();
252 TMatrixT<Double_t> residTranspose(r);
254 TMatrixT<Double_t> chisq=residTranspose*(R*r);
255 assert(chisq.GetNoElements()==1);
257 if(TMath::IsNaN(chisq[0][0])){
260 std::vector<double> numbers;
261 numbers.push_back(det);
263 std::vector< TMatrixT<Double_t> > matrices;
264 matrices.push_back(r);
265 matrices.push_back(V);
266 matrices.push_back(Rsave);
267 matrices.push_back(R);
268 matrices.push_back(cov);
282 TMatrixT<Double_t> state(repDim,1);
283 TMatrixT<Double_t> cov(repDim,repDim);;
294 assert(r.GetNrows()>0);
296 r[0][0] = fabs(r[0][0]);
300 return chi2/r.GetNrows();
310 int repDim = rep->
getDim();
311 TMatrixT<Double_t> state(repDim,1);
312 TMatrixT<Double_t> cov(repDim,repDim);
313 static TMatrixT<Double_t> covFilt(cov);
314 const double pi2(10.0);
318 static TMatrixT<Double_t> oldState(5,1);
319 static std::vector<TVector3> pointsPrev;
321 const double eps(1.0
e-6);
322 if (direction>0 && ihit>0)
326 if (direction<0 && ihit<((
int)nhits-1))
341 Double_t thetaPlanes(0.0);
378 throw cet::exception(
"GFKalman.cxx: ") <<
" Line " << __LINE__ <<
", " << __FILE__ <<
" ...Rethrow. \n";
395 TVector3 u(pl.
getU());
396 TVector3 v(pl.
getV());
397 TVector3 wold(u.Cross(v));
401 TVector3 pTilde = direction * (wold + state[1][0] * u + state[2][0] * v);
402 TVector3
w(pTilde.Unit());
404 TVector3 rot(wold.Cross(
w));
405 Double_t ang(TMath::ACos(
w*wold));
406 ang = TMath::Min(ang,0.95*TMath::Pi()/2.0);
417 if(cov[0][0]<1.
E-50 || TMath::IsNaN(cov[0][0])){
421 if (
fGENfPRINT) std::cout<<
"GFKalman::processHit() 1. No longer throw exception. Force cov[0][0] to 0.01."<<std::endl;
445 TParticlePDG *
part = TDatabasePDG::Instance()->GetParticle(pdg);
446 Double_t mass = part->Mass();
448 Double_t dist = (pl.
getO()-plPrev.
getO()).Mag();
449 Double_t mom = fabs(1.0/state[0][0]);
450 Double_t
beta = mom/sqrt(mass*mass+mom*mom);
451 const Double_t lowerLim(0.01);
452 if (std::isnan(dist) || dist<=0.0) dist=lowerLim;
453 if (std::isnan(beta) || beta<0.01) beta=0.01;
454 TMatrixT<Double_t> H=hit->
getHMatrix(rep,beta,dist);
459 TMatrixT<Double_t> V=hit->
getHitCov(pl,plPrev,state,mass);
464 TMatrixT<Double_t> Gain(
calcGain(cov,V,H));
469 TMatrixT<Double_t> res=hit->
residualVector(rep,state,pl,plPrev,mass);
476 TVector3 point(rawcoord[0][0],rawcoord[1][0],rawcoord[2][0]);
478 TVector3 pointPrev(prevrawcoord[0][0],prevrawcoord[1][0],prevrawcoord[2][0]);
479 pointsPrev.push_back(pointPrev);
480 TMatrixT<Double_t> Hnew(H);
481 if ((ihit==((
int)nhits-1)&&direction==-1) || (ihit==0&&direction==1))
484 TVector3 pointer((point-pointPrev).Unit());
485 static TVector3 pointerPrev(pointer);
486 if (ihit==0&&direction==1 )
487 {pointer[0] = 0.0;pointer[1] = 0.0;pointer[2] = 1.0;}
488 if (ihit==((
int)nhits-1)&&direction==-1)
489 {pointer[0] = 0.0;pointer[1] = 0.0;pointer[2] = -1.0;}
490 double thetaMeas = TMath::Min(fabs(pointer.Angle(pointerPrev)),0.95*TMath::Pi()/2.0);
496 ang = (Hnew*state)[0][0];
500 thetaPlanes = gRandom->Gaus(0.0,ang*ang);
501 thetaPlanes = TMath::Min(sqrt(fabs(thetaPlanes)),0.95*TMath::Pi()/2.0);
503 Double_t dtheta = thetaMeas - thetaPlanes;
504 if (((ihit==((
int)nhits-1)||ihit==((
int)nhits-2))&&direction==-1) || ((ihit==0||ihit==1)&&direction==1))
510 pointerPrev = pointer;
516 res[0][0] = dtheta/Hnew[0][0];
521 TVector3 uPrev(plPrev.
getU());
522 TVector3 vPrev(plPrev.
getV());
523 TVector3 wPrev(u.Cross(v));
531 if (plFilt.getO().Mag()>eps)
533 uPrev = plFilt.
getU();
534 vPrev = plFilt.getV();
535 wPrev = plFilt.getNormal();
542 TMatrixT<Double_t> update=Gain*res;
565 TMatrixT<Double_t> GH(Gain*Hnew);
569 Hnew[0][0] = Hnew[0][0] - eps/Gain[0][0];
571 TMatrixT<Double_t> GHc(GH*cov);
573 cov-=Gain*(Hnew*cov);
579 if (cov[0][0] <= 0.0 || TMath::IsNaN(cov[0][0]))
581 cov[0][0]=pi2/Hnew[0][0];
595 if (fabs(1.0/state[0][0])<
fMomLow)
596 state[0][0] = 1.0/
fMomLow*fabs(state[0][0])/state[0][0];
598 state[0][0] = 1.0/
fMomHigh*fabs(state[0][0])/state[0][0];
605 TVector3 uf(pl.
getU());
606 TVector3 vf(pl.
getV());
607 TVector3 wf(uf.Cross(vf));
608 TVector3 Of(pl.
getO());
613 TVector3 pf = direction*(wf + state[1][0] * uf + state[2][0] * vf);
614 TVector3 pposf = Of + state[3][0] * uf + state[4][0] * vf;
615 Double_t angf = TMath::Min(fabs(pf.Angle(wf)),0.95*TMath::Pi()/2.0);
616 TVector3 rotf(wf.Cross(pf.Unit()));
618 uf.Rotate(angf,rotf);
619 vf.Rotate(angf,rotf);
621 plFilt.setU(uf.Unit());
622 plFilt.setV(vf.Unit());
624 plFilt.setNormal(pf.Unit());
632 TMatrixT<Double_t> r=hit->
residualVector(rep,state,plFilt,plPrev,mass);
633 if (direction==-1) wold.Rotate(TMath::Pi(),wold.Orthogonal());
634 dtheta = thetaMeas - TMath::Min(fabs(wold.Angle(plFilt.getNormal())),0.95*TMath::Pi()/2.);
635 r[0][0] = dtheta/Hnew[0][0];
642 int ndf = r.GetNrows();
643 if (update[0][0]==0.0) {chi2=0.0; ndf=0;};
646 pointerPrev = pointer;
676 TMatrixT<Double_t> jac(7,5);
678 TVector3 u=plane.
getU();
679 TVector3 v=plane.
getV();
680 TVector3
w=u.Cross(v);
686 double pTildeMag = pTilde.Mag();
701 jac[3][1] = 1.0/pTildeMag*(u.X()-pTilde.X()/(pTildeMag*pTildeMag)*u*pTilde);
702 jac[4][1] = 1.0/pTildeMag*(u.Y()-pTilde.Y()/(pTildeMag*pTildeMag)*u*pTilde);
703 jac[5][1] = 1.0/pTildeMag*(u.Z()-pTilde.Z()/(pTildeMag*pTildeMag)*u*pTilde);
705 jac[3][2] = 1.0/pTildeMag*(v.X()-pTilde.X()/(pTildeMag*pTildeMag)*v*pTilde);
706 jac[4][2] = 1.0/pTildeMag*(v.Y()-pTilde.Y()/(pTildeMag*pTildeMag)*v*pTilde);
707 jac[5][2] = 1.0/pTildeMag*(v.Z()-pTilde.Z()/(pTildeMag*pTildeMag)*v*pTilde);
712 TMatrixT<Double_t> jac_t(TMatrixT<Double_t>::kTransposed,jac);
713 TMatrixT<Double_t> jjInv(jac_t * jac);
723 throw GFException(
"GFKalman: Jac.T*Jac is not invertible. But keep plowing on ... ",__LINE__,__FILE__).
setFatal();
725 if(TMath::IsNaN(det)) {
729 TMatrixT<Double_t> j5x7 = jjInv*jac_t;
730 TMatrixT<Double_t> c7x7 = j5x7.T() * (cov * j5x7);
736 const TMatrixT<Double_t>& HitCov,
737 const TMatrixT<Double_t>& H){
745 TMatrixT<Double_t> covsum1(cov,TMatrixT<Double_t>::kMultTranspose,H);
747 TMatrixT<Double_t> covsum(H,TMatrixT<Double_t>::kMult,covsum1);
757 covsum.SetTol(1.0
e-23);
760 if(TMath::IsNaN(det)) {
765 GFException exc(
"cannot invert covsum in Kalman Gain - det=0",
768 std::vector< TMatrixT<Double_t> > matrices;
769 matrices.push_back(cov);
770 matrices.push_back(HitCov);
771 matrices.push_back(covsum1);
772 matrices.push_back(covsum);
773 exc.
setMatrices(
"cov, HitCov, covsum1 and covsum",matrices);
780 TMatrixT<Double_t> gain1(H,TMatrixT<Double_t>::kTransposeMult,covsum);
781 TMatrixT<Double_t> gain(cov,TMatrixT<Double_t>::kMult,gain1);
void clearRepAtHit()
clear the hit indices at which plane,state&cov of reps are defined
void setNDF(unsigned int n)
GFException & setNumbers(std::string, const std::vector< double > &)
set list of numbers with description
double getChi2Hit(GFAbsRecoHit *, GFAbsTrackRep *)
Calculates chi2 of a given hit with respect to a given track representation.
const GFDetPlane & getReferencePlane() const
void setNextHitToFit(unsigned int i)
Set next hit to be used in a fit.
void setRepAtHit(unsigned int irep, int ihit)
set the hit index at which plane,state&cov of rep irep is defined
void processHit(GFTrack *, int, int, int)
One Kalman step.
virtual const char * what() const
standard error message handling for exceptions. use like "std::cerr << e.what();" ...
TMatrixT< Double_t > calcGain(const TMatrixT< Double_t > &cov, const TMatrixT< Double_t > &HitCov, const TMatrixT< Double_t > &H)
Calculate Kalman Gain.
GFAbsTrackRep * getTrackRep(int id) const
Accessor for track representations.
void fittingPass(GFTrack *, int dir)
Performs fit on a GFTrack beginning with the current hit.
virtual TMatrixT< Double_t > getHMatrix(const GFAbsTrackRep *stateVector)=0
Get transformation matrix. Transformation between hit coordinates and track representation coordinate...
virtual const GFDetPlane & getDetPlane(GFAbsTrackRep *)=0
Get detector plane for a given track representation.
TMatrixT< Double_t > getRawHitCoord() const
Get raw hit coordinates.
const TMatrixT< Double_t > & getState() const
void blowUpCovs(GFTrack *trk)
this is needed to blow up the covariance matrix before a fitting pass drops off-diagonal elements and...
Base Class for genfit track representations. Defines interface for track parameterizations.
void setCov(const TMatrixT< Double_t > &aCov)
void setChiSqu(double aChiSqu)
void setHitState(TMatrixT< Double_t > mat)
void addNDF(unsigned int n)
void switchDirection(GFTrack *trk)
Used to switch between forward and backward filtering.
unsigned int getNumReps() const
Get number of track represenatations.
void setHitMeasuredCov(TMatrixT< Double_t > mat)
virtual void setData(const TMatrixT< Double_t > &st, const GFDetPlane &pl, const TMatrixT< Double_t > *cov=NULL)
double chi2Increment(const TMatrixT< Double_t > &r, const TMatrixT< Double_t > &H, const TMatrixT< Double_t > &cov, const TMatrixT< Double_t > &V)
this returns the reduced chi2 increment for a hit
void addFailedHit(unsigned int irep, unsigned int id)
virtual TMatrixT< Double_t > getHitCov(const GFDetPlane &)=0
Get hit covariances in a specific detector plane.
bool isFatal()
get fatal flag.
void addChiSqu(double aChiSqu)
GFAbsRecoHit * getHit(int id) const
int getRepAtHit(unsigned int irep)
get the hit index at which plane,state&cov of rep irep is defined
void setHitPlaneV(TVector3 pl)
void setHitPlaneUxUyUz(TVector3 pl)
virtual double extrapolate(const GFDetPlane &plane, TMatrixT< Double_t > &statePred)
returns the tracklength spanned in this extrapolation
void processTrack(GFTrack *)
Performs fit on a GFTrack.
void setHitChi2(Double_t mat)
const TMatrixT< Double_t > & getCov() const
GFBookkeeping * getBK(int index=-1)
get GFBookKeeping object for particular track rep (default is cardinal rep)
GFException & setMatrices(std::string, const std::vector< TMatrixT< Double_t > > &)
set list of matrices with description
void setHitCov7x7(TMatrixT< Double_t > mat)
void blowUpCovsDiag(GFTrack *trk)
Detector simulation of raw signals on wires.
void info()
print information in the exception object
unsigned int getNumHits() const
void setHitCov(TMatrixT< Double_t > mat)
Exception class for error handling in GENFIT (provides storage for diagnostic information) ...
void setStatusFlag(int _val)
void setHitUpdate(TMatrixT< Double_t > mat)
TMatrixT< Double_t > calcCov7x7(const TMatrixT< Double_t > &cov, const genf::GFDetPlane &plane)
GFException & setFatal(bool b=true)
set fatal flag. if this is true, the fit stops for this current track repr.
void setHitPlaneXYZ(TVector3 pl)
unsigned int getDim() const
returns dimension of state vector
unsigned int getNextHitToFit() const
Accessor for fNextHitToFit.
virtual TMatrixT< Double_t > residualVector(const GFAbsTrackRep *stateVector, const TMatrixT< Double_t > &state, const GFDetPlane &d)
Calculate residual with respect to a track representation.
virtual void switchDirection()=0
void setHitPlaneU(TVector3 pl)
cet::coded_exception< error, detail::translate > exception