23 #include "TDatabasePDG.h" 33 #include "art_root_io/TFileService.h" 34 #include "cetlib_except/exception.h" 36 #define COVEXC "cov_is_zero" 39 : fInitialDirection(1)
60 if ((direction != 1) && (direction != -1))
61 throw GFException(std::string(__func__) +
": wrong direction", __LINE__, __FILE__).
setFatal();
82 for (
int ipass = 0; ipass < 2 *
fNumIt; ipass++) {
96 <<
" Line " << __LINE__ <<
", " << __FILE__ <<
" ...Rethrow. \n";
100 if (direction == 1) {
102 for (
int i = 0; i < nreps; ++i) {
110 for (
int i = 0; i < nreps; ++i) {
130 for (
int i = 0; i < nreps; ++i) {
138 for (
int irep = 0; irep < nreps; ++irep) {
142 TMatrixT<Double_t> cov = arep->
getCov();
143 for (
int i = 0; i < cov.GetNrows(); ++i) {
144 for (
int j = 0; j < cov.GetNcols(); ++j) {
161 for (
int irep = 0; irep < nreps; ++irep) {
165 TMatrixT<Double_t> cov = arep->
getCov();
166 for (
int i = 0; i < cov.GetNrows(); ++i) {
167 for (
int j = 0; j < cov.GetNcols(); ++j) {
189 int ihit = (int)starthit;
192 for (
int i = 0; i < nreps; ++i) {
201 while ((ihit < (
int)nhits && direction == 1) || (ihit > -1 && direction == -1)) {
204 for (
int irep = 0; irep < nreps; ++irep) {
212 std::cerr << e.
what();
228 const TMatrixT<Double_t>& H,
229 const TMatrixT<Double_t>& cov,
230 const TMatrixT<Double_t>& V)
234 TMatrixT<Double_t> R(V);
235 TMatrixT<Double_t> covsum1(cov, TMatrixT<Double_t>::kMultTranspose, H);
236 TMatrixT<Double_t> covsum(H, TMatrixT<Double_t>::kMult, covsum1);
242 TMatrixT<Double_t> Rsave(R);
249 GFException e(
"Kalman Chi2Increment: R is not even invertible. But keep plowing on ... ",
255 if (TMath::IsNaN(det)) {
256 throw GFException(
"Kalman Chi2Increment: det of covsum is nan", __LINE__, __FILE__).
setFatal();
258 TMatrixT<Double_t> residTranspose(r);
260 TMatrixT<Double_t> chisq = residTranspose * (R *
r);
261 assert(chisq.GetNoElements() == 1);
263 if (TMath::IsNaN(chisq[0][0])) {
264 GFException exc(
"chi2 is nan", __LINE__, __FILE__);
266 std::vector<double> numbers;
267 numbers.push_back(det);
269 std::vector<TMatrixT<Double_t>> matrices;
270 matrices.push_back(r);
271 matrices.push_back(V);
272 matrices.push_back(Rsave);
273 matrices.push_back(R);
274 matrices.push_back(cov);
285 int repDim = rep->
getDim();
286 TMatrixT<Double_t> state(repDim, 1);
287 TMatrixT<Double_t> cov(repDim, repDim);
295 TMatrixT<Double_t> V = hit->
getHitCov(pl);
298 assert(r.GetNrows() > 0);
300 r[0][0] = fabs(r[0][0]);
304 return chi2 / r.GetNrows();
313 int repDim = rep->
getDim();
314 TMatrixT<Double_t> state(repDim, 1);
315 TMatrixT<Double_t> cov(repDim, repDim);
316 static TMatrixT<Double_t> covFilt(cov);
317 const double pi2(10.0);
321 static TMatrixT<Double_t> oldState(5, 1);
322 static std::vector<TVector3> pointsPrev;
324 const double eps(1.0
e-6);
325 if (direction > 0 && ihit > 0) { phit = ihit - 1; }
326 if (direction < 0 && ihit < ((
int)nhits - 1)) { phit = ihit + 1; }
337 Double_t thetaPlanes(0.0);
374 <<
" Line " << __LINE__ <<
", " << __FILE__ <<
" ...Rethrow. \n";
390 TVector3 u(pl.
getU());
391 TVector3 v(pl.
getV());
392 TVector3 wold(u.Cross(v));
396 TVector3 pTilde = direction * (wold + state[1][0] * u + state[2][0] * v);
397 TVector3
w(pTilde.Unit());
399 TVector3 rot(wold.Cross(
w));
400 Double_t ang(TMath::ACos(
w * wold));
401 ang = TMath::Min(ang, 0.95 * TMath::Pi() / 2.0);
412 if (cov[0][0] < 1.
E-50 || TMath::IsNaN(cov[0][0])) {
417 std::cout <<
"GFKalman::processHit() 1. No longer throw exception. Force cov[0][0] to 0.01." 441 TParticlePDG*
part = TDatabasePDG::Instance()->GetParticle(pdg);
442 Double_t mass = part->Mass();
445 Double_t mom = fabs(1.0 / state[0][0]);
446 Double_t beta = mom / sqrt(mass * mass + mom * mom);
447 const Double_t lowerLim(0.01);
448 if (std::isnan(dist) || dist <= 0.0) dist = lowerLim;
449 if (std::isnan(beta) || beta < 0.01) beta = 0.01;
450 TMatrixT<Double_t> H = hit->
getHMatrix(rep, beta, dist);
454 TMatrixT<Double_t> V = hit->
getHitCov(pl, plPrev, state, mass);
459 TMatrixT<Double_t> Gain(
calcGain(cov, V, H));
464 TMatrixT<Double_t> res = hit->
residualVector(rep, state, pl, plPrev, mass);
470 TVector3 point(rawcoord[0][0], rawcoord[1][0], rawcoord[2][0]);
472 TVector3 pointPrev(prevrawcoord[0][0], prevrawcoord[1][0], prevrawcoord[2][0]);
473 pointsPrev.push_back(pointPrev);
474 TMatrixT<Double_t> Hnew(H);
475 if ((ihit == ((
int)nhits - 1) && direction == -1) || (ihit == 0 && direction == 1))
478 TVector3 pointer((point - pointPrev).Unit());
479 static TVector3 pointerPrev(pointer);
480 if (ihit == 0 && direction == 1) {
485 if (ihit == ((
int)nhits - 1) && direction == -1) {
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) ||
505 ((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) {
532 uPrev = plFilt.
getU();
533 vPrev = plFilt.getV();
534 wPrev = plFilt.getNormal();
541 TMatrixT<Double_t> update = Gain * res;
563 TMatrixT<Double_t> GH(Gain * Hnew);
566 Hnew[0][0] = Hnew[0][0] - eps / Gain[0][0];
568 TMatrixT<Double_t> GHc(GH * cov);
570 cov -= Gain * (Hnew * cov);
576 if (cov[0][0] <= 0.0 || TMath::IsNaN(cov[0][0])) {
577 cov[0][0] = pi2 / Hnew[0][0];
590 if (fabs(1.0 / state[0][0]) <
fMomLow)
591 state[0][0] = 1.0 /
fMomLow * fabs(state[0][0]) / state[0][0];
592 if (fabs(1.0 / state[0][0]) >
fMomHigh)
593 state[0][0] = 1.0 /
fMomHigh * fabs(state[0][0]) / state[0][0];
599 TVector3 uf(pl.
getU());
600 TVector3 vf(pl.
getV());
601 TVector3 wf(uf.Cross(vf));
602 TVector3 Of(pl.
getO());
607 TVector3 pf = direction * (wf + state[1][0] * uf + state[2][0] * vf);
608 TVector3 pposf = Of + state[3][0] * uf + state[4][0] * vf;
609 Double_t angf = TMath::Min(fabs(pf.Angle(wf)), 0.95 * TMath::Pi() / 2.0);
610 TVector3 rotf(wf.Cross(pf.Unit()));
612 uf.Rotate(angf, rotf);
613 vf.Rotate(angf, rotf);
615 plFilt.setU(uf.Unit());
616 plFilt.setV(vf.Unit());
618 plFilt.setNormal(pf.Unit());
626 TMatrixT<Double_t>
r = hit->
residualVector(rep, state, plFilt, plPrev, mass);
627 if (direction == -1) wold.Rotate(TMath::Pi(), wold.Orthogonal());
628 dtheta = thetaMeas - TMath::Min(fabs(wold.Angle(plFilt.getNormal())), 0.95 * TMath::Pi() / 2.);
629 r[0][0] = dtheta / Hnew[0][0];
636 int ndf = r.GetNrows();
637 if (update[0][0] == 0.0) {
643 pointerPrev = pointer;
672 TMatrixT<Double_t> jac(7, 5);
674 TVector3 u = plane.
getU();
675 TVector3 v = plane.
getV();
676 TVector3
w = u.Cross(v);
682 double pTildeMag = pTilde.Mag();
697 jac[3][1] = 1.0 / pTildeMag * (u.X() - pTilde.X() / (pTildeMag * pTildeMag) * u * pTilde);
698 jac[4][1] = 1.0 / pTildeMag * (u.Y() - pTilde.Y() / (pTildeMag * pTildeMag) * u * pTilde);
699 jac[5][1] = 1.0 / pTildeMag * (u.Z() - pTilde.Z() / (pTildeMag * pTildeMag) * u * pTilde);
701 jac[3][2] = 1.0 / pTildeMag * (v.X() - pTilde.X() / (pTildeMag * pTildeMag) * v * pTilde);
702 jac[4][2] = 1.0 / pTildeMag * (v.Y() - pTilde.Y() / (pTildeMag * pTildeMag) * v * pTilde);
703 jac[5][2] = 1.0 / pTildeMag * (v.Z() - pTilde.Z() / (pTildeMag * pTildeMag) * v * pTilde);
708 TMatrixT<Double_t> jac_t(TMatrixT<Double_t>::kTransposed, jac);
709 TMatrixT<Double_t> jjInv(jac_t * jac);
719 "GFKalman: Jac.T*Jac is not invertible. But keep plowing on ... ", __LINE__, __FILE__)
722 if (TMath::IsNaN(det)) {
726 TMatrixT<Double_t> j5x7 = jjInv * jac_t;
727 TMatrixT<Double_t> c7x7 = j5x7.T() * (cov * j5x7);
732 const TMatrixT<Double_t>& HitCov,
733 const TMatrixT<Double_t>& H)
742 TMatrixT<Double_t> covsum1(cov, TMatrixT<Double_t>::kMultTranspose, H);
744 TMatrixT<Double_t> covsum(H, TMatrixT<Double_t>::kMult, covsum1);
754 covsum.SetTol(1.0
e-23);
757 if (TMath::IsNaN(det)) {
762 GFException exc(
"cannot invert covsum in Kalman Gain - det=0", __LINE__, __FILE__);
764 std::vector<TMatrixT<Double_t>> matrices;
765 matrices.push_back(cov);
766 matrices.push_back(HitCov);
767 matrices.push_back(covsum1);
768 matrices.push_back(covsum);
769 exc.
setMatrices(
"cov, HitCov, covsum1 and covsum", matrices);
775 TMatrixT<Double_t> gain1(H, TMatrixT<Double_t>::kTransposeMult, covsum);
776 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 setLastCov(const TMatrixT< Double_t > &aCov)
void processHit(GFTrack *, int, int, int)
One Kalman step.
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.
void setFirstPlane(const GFDetPlane &aPlane)
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)
void setFirstCov(const TMatrixT< Double_t > &aCov)
void setHitCov7x7(TMatrixT< Double_t > mat)
void setLastPlane(const GFDetPlane &aPlane)
void blowUpCovsDiag(GFTrack *trk)
Detector simulation of raw signals on wires.
void info()
print information in the exception object
const char * what() const noexcept override
standard error message handling for exceptions. use like "std::cerr << e.what();" ...
unsigned int getNumHits() const
void setLastState(const TMatrixT< Double_t > &aState)
GFException & setMatrices(std::string, const std::vector< TMatrixT< Double_t >> &)
set list of matrices with description
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 setFirstState(const TMatrixT< Double_t > &aState)
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