25 #include "TDatabasePDG.h" 32 #include "cetlib_except/exception.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)
48 if ((direction != 1) && (direction != -1))
70 for(
int ipass=0; ipass<2*
fNumIt; ipass++){
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;
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){
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){
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){
207 std::cerr << e.
what();
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);
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);;
292 assert(r.GetNrows()>0);
294 r[0][0] = fabs(r[0][0]);
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);
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));
404 ang = TMath::Min(ang,0.95*TMath::Pi()/2.0);
415 if(cov[0][0]<1.
E-50 || TMath::IsNaN(cov[0][0])){
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);
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;
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];
593 if (fabs(1.0/state[0][0])<
fMomLow)
594 state[0][0] = 1.0/
fMomLow*fabs(state[0][0])/state[0][0];
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];
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);
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.
double beta(double KE, const simb::MCParticle *part)
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) ...
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.
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
QTextStream & endl(QTextStream &s)