25 #include "TDatabasePDG.h"
32 #include "cetlib_except/exception.h"
33 #include "art/Framework/Services/Registry/ServiceHandle.h"
34 #include "art_root_io/TFileService.h"
36 #define COVEXC "cov_is_zero"
39 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)
41 art::ServiceHandle<art::TFileService const>
tfs;
47 int direction=fInitialDirection;
48 if ((direction != 1) && (direction != -1))
49 throw GFException(std::string(__func__) +
": wrong direction", __LINE__, __FILE__).
setFatal();
70 for(
int ipass=0; ipass<2*fNumIt; ipass++){
73 if(ipass>0) blowUpCovs(trk);
84 fittingPass(trk,direction);
88 throw cet::exception(
"GFKalman.cxx: ") <<
" Line " << __LINE__ <<
", " << __FILE__ <<
" ...Rethrow. \n";
94 for(
int i=0; i<nreps; ++i){
105 for(
int i=0; i<nreps; ++i){
116 if(direction==1) direction=-1;
118 switchDirection(trk);
127 for(
int i=0; i<nreps; ++i){
134 for(
int irep=0; irep<nreps; ++irep){
138 TMatrixT<Double_t> cov = arep->
getCov();
139 for(
int i=0;i<cov.GetNrows();++i){
140 for(
int j=0;j<cov.GetNcols();++j){
145 cov[i][j] = cov[i][j] * fBlowUpFactor;
156 for(
int irep=0; irep<nreps; ++irep){
160 TMatrixT<Double_t> cov = arep->
getCov();
161 for(
int i=0;i<cov.GetNrows();++i){
162 for(
int j=0;j<cov.GetNcols();++j){
167 cov[i][j] = cov[i][j] * fBlowUpFactor;
184 int ihit=(int)starthit;
187 for(
int i=0;i<nreps;++i){
196 while((ihit<(
int)nhits && direction==1) || (ihit>-1 && direction==-1)){
199 for(
int irep=0; irep<nreps; ++irep){
203 processHit(trk,ihit,irep,direction);
223 const TMatrixT<Double_t>& cov,
const TMatrixT<Double_t>&
V){
226 TMatrixT<Double_t> R(V);
227 TMatrixT<Double_t> covsum1(cov,TMatrixT<Double_t>::kMultTranspose,H);
228 TMatrixT<Double_t> covsum(H,TMatrixT<Double_t>::kMult,covsum1);
234 TMatrixT<Double_t> Rsave(R);
241 catch (cet::exception &)
243 GFException e(
"Kalman Chi2Increment: R is not even invertible. But keep plowing on ... ",__LINE__,__FILE__);
247 if(TMath::IsNaN(det)) {
248 throw GFException(
"Kalman Chi2Increment: det of covsum is nan",__LINE__,__FILE__).
setFatal();
250 TMatrixT<Double_t> residTranspose(r);
252 TMatrixT<Double_t> chisq=residTranspose*(R*
r);
253 assert(chisq.GetNoElements()==1);
255 if(TMath::IsNaN(chisq[0][0])){
258 std::vector<double> numbers;
259 numbers.push_back(det);
261 std::vector< TMatrixT<Double_t> > matrices;
262 matrices.push_back(r);
263 matrices.push_back(V);
264 matrices.push_back(Rsave);
265 matrices.push_back(R);
266 matrices.push_back(cov);
280 TMatrixT<Double_t>
state(repDim,1);
281 TMatrixT<Double_t> cov(repDim,repDim);;
290 V[0][0] *= fErrScaleMTh;
292 assert(r.GetNrows()>0);
294 r[0][0] = fabs(r[0][0]);
296 double chi2 = chi2Increment(r,H,cov,V);
298 return chi2/r.GetNrows();
308 int repDim = rep->
getDim();
309 TMatrixT<Double_t>
state(repDim,1);
310 TMatrixT<Double_t> cov(repDim,repDim);
311 static TMatrixT<Double_t> covFilt(cov);
312 const double pi2(10.0);
316 static TMatrixT<Double_t> oldState(5,1);
317 static std::vector<TVector3> pointsPrev;
319 const double eps(1.0
e-6);
320 if (direction>0 && ihit>0)
324 if (direction<0 && ihit<((
int)nhits-1))
339 Double_t thetaPlanes(0.0);
374 catch (cet::exception &)
376 throw cet::exception(
"GFKalman.cxx: ") <<
" Line " << __LINE__ <<
", " << __FILE__ <<
" ...Rethrow. \n";
393 TVector3 u(pl.
getU());
394 TVector3 v(pl.
getV());
395 TVector3 wold(u.Cross(v));
399 TVector3 pTilde = direction * (wold + state[1][0] * u + state[2][0] * v);
400 TVector3
w(pTilde.Unit());
402 TVector3 rot(wold.Cross(
w));
403 Double_t ang(TMath::ACos(
w*wold));
415 if(cov[0][0]<1.
E-50 || TMath::IsNaN(cov[0][0])){
418 if (fGENfPRINT) cov.Print();
419 if (fGENfPRINT)
std::cout<<
"GFKalman::processHit() 1. No longer throw exception. Force cov[0][0] to 0.01."<<std::endl;
443 TParticlePDG * part = TDatabasePDG::Instance()->GetParticle(pdg);
444 Double_t
mass = part->Mass();
447 Double_t mom = fabs(1.0/state[0][0]);
448 Double_t beta = mom/sqrt(mass*mass+mom*mom);
449 const Double_t lowerLim(0.01);
450 if (std::isnan(dist) || dist<=0.0) dist=lowerLim;
451 if (std::isnan(beta) || beta<0.01) beta=0.01;
452 TMatrixT<Double_t> H=hit->
getHMatrix(rep,beta,dist);
457 TMatrixT<Double_t>
V=hit->
getHitCov(pl,plPrev,state,mass);
458 V[0][0] *= fErrScaleMTh;
462 TMatrixT<Double_t> Gain(calcGain(cov,V,H));
467 TMatrixT<Double_t> res=hit->
residualVector(rep,state,pl,plPrev,mass);
474 TVector3 point(rawcoord[0][0],rawcoord[1][0],rawcoord[2][0]);
476 TVector3 pointPrev(prevrawcoord[0][0],prevrawcoord[1][0],prevrawcoord[2][0]);
477 pointsPrev.push_back(pointPrev);
478 TMatrixT<Double_t> Hnew(H);
479 if ((ihit==((
int)nhits-1)&&direction==-1) || (ihit==0&&direction==1))
482 TVector3 pointer((point-pointPrev).Unit());
483 static TVector3 pointerPrev(pointer);
484 if (ihit==0&&direction==1 )
485 {pointer[0] = 0.0;pointer[1] = 0.0;pointer[2] = 1.0;}
486 if (ihit==((
int)nhits-1)&&direction==-1)
487 {pointer[0] = 0.0;pointer[1] = 0.0;pointer[2] = -1.0;}
488 double thetaMeas =
TMath::Min(fabs(pointer.Angle(pointerPrev)),0.95*TMath::Pi()/2.0);
494 ang = (Hnew*
state)[0][0];
498 thetaPlanes = gRandom->Gaus(0.0,ang*ang);
499 thetaPlanes =
TMath::Min(sqrt(fabs(thetaPlanes)),0.95*TMath::Pi()/2.0);
501 Double_t dtheta = thetaMeas - thetaPlanes;
502 if (((ihit==((
int)nhits-1)||ihit==((
int)nhits-2))&&direction==-1) || ((ihit==0||ihit==1)&&direction==1))
508 pointerPrev = pointer;
514 res[0][0] = dtheta/Hnew[0][0];
519 TVector3 uPrev(plPrev.
getU());
520 TVector3 vPrev(plPrev.
getV());
521 TVector3 wPrev(u.Cross(v));
529 if (plFilt.getO().Mag()>eps)
531 uPrev = plFilt.
getU();
532 vPrev = plFilt.getV();
533 wPrev = plFilt.getNormal();
540 TMatrixT<Double_t> update=Gain*res;
551 if (fabs(update[0][0])>fMaxUpdate )
563 TMatrixT<Double_t> GH(Gain*Hnew);
567 Hnew[0][0] = Hnew[0][0] - eps/Gain[0][0];
569 TMatrixT<Double_t> GHc(GH*cov);
571 cov-=Gain*(Hnew*cov);
577 if (cov[0][0] <= 0.0 || TMath::IsNaN(cov[0][0]))
579 cov[0][0]=pi2/Hnew[0][0];
588 TMatrixT<double> cov7x7(calcCov7x7(cov,pl));
593 if (fabs(1.0/state[0][0])<fMomLow)
594 state[0][0] = 1.0/fMomLow*fabs(state[0][0])/state[0][0];
595 if (fabs(1.0/state[0][0])>fMomHigh)
596 state[0][0] = 1.0/fMomHigh*fabs(state[0][0])/state[0][0];
603 TVector3 uf(pl.
getU());
604 TVector3 vf(pl.
getV());
605 TVector3 wf(uf.Cross(vf));
606 TVector3 Of(pl.
getO());
611 TVector3 pf = direction*(wf + state[1][0] * uf + state[2][0] * vf);
612 TVector3 pposf = Of + state[3][0] * uf + state[4][0] * vf;
613 Double_t angf =
TMath::Min(fabs(pf.Angle(wf)),0.95*TMath::Pi()/2.0);
614 TVector3 rotf(wf.Cross(pf.Unit()));
616 uf.Rotate(angf,rotf);
617 vf.Rotate(angf,rotf);
619 plFilt.setU(uf.Unit());
620 plFilt.setV(vf.Unit());
622 plFilt.setNormal(pf.Unit());
630 TMatrixT<Double_t>
r=hit->
residualVector(rep,state,plFilt,plPrev,mass);
631 if (direction==-1) wold.Rotate(TMath::Pi(),wold.Orthogonal());
632 dtheta = thetaMeas -
TMath::Min(fabs(wold.Angle(plFilt.getNormal())),0.95*TMath::Pi()/2.);
633 r[0][0] = dtheta/Hnew[0][0];
639 double chi2 = chi2Increment(r,Hnew,cov,V);
640 int ndf = r.GetNrows();
641 if (update[0][0]==0.0) {chi2=0.0; ndf=0;};
644 pointerPrev = pointer;
674 TMatrixT<Double_t> jac(7,5);
676 TVector3 u=plane.
getU();
677 TVector3 v=plane.
getV();
678 TVector3
w=u.Cross(v);
684 double pTildeMag = pTilde.Mag();
699 jac[3][1] = 1.0/pTildeMag*(u.X()-pTilde.X()/(pTildeMag*pTildeMag)*u*pTilde);
700 jac[4][1] = 1.0/pTildeMag*(u.Y()-pTilde.Y()/(pTildeMag*pTildeMag)*u*pTilde);
701 jac[5][1] = 1.0/pTildeMag*(u.Z()-pTilde.Z()/(pTildeMag*pTildeMag)*u*pTilde);
703 jac[3][2] = 1.0/pTildeMag*(v.X()-pTilde.X()/(pTildeMag*pTildeMag)*v*pTilde);
704 jac[4][2] = 1.0/pTildeMag*(v.Y()-pTilde.Y()/(pTildeMag*pTildeMag)*v*pTilde);
705 jac[5][2] = 1.0/pTildeMag*(v.Z()-pTilde.Z()/(pTildeMag*pTildeMag)*v*pTilde);
710 TMatrixT<Double_t> jac_t(TMatrixT<Double_t>::kTransposed,jac);
711 TMatrixT<Double_t> jjInv(jac_t * jac);
719 catch (cet::exception &)
721 throw GFException(
"GFKalman: Jac.T*Jac is not invertible. But keep plowing on ... ",__LINE__,__FILE__).
setFatal();
723 if(TMath::IsNaN(det)) {
727 TMatrixT<Double_t> j5x7 = jjInv*jac_t;
728 TMatrixT<Double_t> c7x7 = j5x7.T() * (cov * j5x7);
734 const TMatrixT<Double_t>& HitCov,
735 const TMatrixT<Double_t>& H){
743 TMatrixT<Double_t> covsum1(cov,TMatrixT<Double_t>::kMultTranspose,H);
745 TMatrixT<Double_t> covsum(H,TMatrixT<Double_t>::kMult,covsum1);
755 covsum.SetTol(1.0
e-23);
758 if(TMath::IsNaN(det)) {
763 GFException exc(
"cannot invert covsum in Kalman Gain - det=0",
766 std::vector< TMatrixT<Double_t> > matrices;
767 matrices.push_back(cov);
768 matrices.push_back(HitCov);
769 matrices.push_back(covsum1);
770 matrices.push_back(covsum);
771 exc.
setMatrices(
"cov, HitCov, covsum1 and covsum",matrices);
778 TMatrixT<Double_t> gain1(H,TMatrixT<Double_t>::kTransposeMult,covsum);
779 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
BEGIN_PROLOG could also be cerr
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)
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) ...
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
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.
art::ServiceHandle< art::TFileService > tfs
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)
BEGIN_PROLOG could also be cout