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