34 #include"TGeoManager.h"
35 #include"TDatabasePDG.h"
40 #define MINSTEP 0.001 // minimum step [cm] for Runge Kutta and iteration to POCA
48 std::cerr <<
"RKTrackRep::setData() - a fatal error ocurred! It was called with a reference plane which is not the same as the one from the last extrapolate(plane,state,cov)-> abort in line " << __LINE__ << std::endl;
60 std::cerr <<
"RKTrackRep::getAuxInfo() - Fatal error: Trying to get auxillary information with planes mismatch (Information returned does not belong to requested plane)! -> abort in line " << __LINE__ << std::endl;
80 const TVector3& poserr,
81 const TVector3& momerr,
83 GFAbsTrackRep(5), fDirection(true), fCachePlane(), fCacheSpu(1), fAuxInfo(1,1) {
103 TVector3 w=u.Cross(v);
108 fCov[3][3] = poserr.X()*poserr.X() * u.X()*u.X() +
109 poserr.Y()*poserr.Y() * u.Y()*u.Y() +
110 poserr.Z()*poserr.Z() * u.Z()*u.Z();
111 fCov[4][4] = poserr.X()*poserr.X() * v.X()*v.X() +
112 poserr.Y()*poserr.Y() * v.Y()*v.Y() +
113 poserr.Z()*poserr.Z() * v.Z()*v.Z();
115 (mom.X()*mom.X() * momerr.X()*momerr.X()+
116 mom.Y()*mom.Y() * momerr.Y()*momerr.Y()+
117 mom.Z()*mom.Z() * momerr.Z()*momerr.Z());
118 fCov[1][1] = pow((u.X()/pw - w.X()*pu/(pw*pw)),2.)*momerr.X()*momerr.X() +
119 pow((u.Y()/pw - w.Y()*pu/(pw*pw)),2.)*momerr.Y()*momerr.Y() +
120 pow((u.Z()/pw - w.Z()*pu/(pw*pw)),2.)*momerr.Z()*momerr.Z();
121 fCov[2][2] = pow((v.X()/pw - w.X()*pv/(pw*pw)),2.)*momerr.X()*momerr.X() +
122 pow((v.Y()/pw - w.Y()*pv/(pw*pw)),2.)*momerr.Y()*momerr.Y() +
123 pow((v.Z()/pw - w.Z()*pv/(pw*pw)),2.)*momerr.Z()*momerr.Z();
129 GFAbsTrackRep(5), fDirection(true), fCachePlane(), fCacheSpu(1), fAuxInfo(1,1) {
149 TVector3 w=u.Cross(v);
155 fCov[3][3] = poserr.X()*poserr.X() * u.X()*u.X() +
156 poserr.Y()*poserr.Y() * u.Y()*u.Y() +
157 poserr.Z()*poserr.Z() * u.Z()*u.Z();
158 fCov[4][4] = poserr.X()*poserr.X() * v.X()*v.X() +
159 poserr.Y()*poserr.Y() * v.Y()*v.Y() +
160 poserr.Z()*poserr.Z() * v.Z()*v.Z();
162 (mom.X()*mom.X() * momerr.X()*momerr.X()+
163 mom.Y()*mom.Y() * momerr.Y()*momerr.Y()+
164 mom.Z()*mom.Z() * momerr.Z()*momerr.Z());
165 fCov[1][1] = pow((u.X()/pw - w.X()*pu/(pw*pw)),2.)*momerr.X()*momerr.X() +
166 pow((u.Y()/pw - w.Y()*pu/(pw*pw)),2.)*momerr.Y()*momerr.Y() +
167 pow((u.Z()/pw - w.Z()*pu/(pw*pw)),2.)*momerr.Z()*momerr.Z();
168 fCov[2][2] = pow((v.X()/pw - w.X()*pv/(pw*pw)),2.)*momerr.X()*momerr.X() +
169 pow((v.Y()/pw - w.Y()*pv/(pw*pw)),2.)*momerr.Y()*momerr.Y() +
170 pow((v.Z()/pw - w.Z()*pv/(pw*pw)),2.)*momerr.Z()*momerr.Z();
176 const int& PDGCode) :
177 GFAbsTrackRep(5),fDirection(true), fCachePlane(), fCacheSpu(1), fAuxInfo(1,1){
197 TVector3 w=u.Cross(v);
202 static const TVector3 stdPosErr(1.,1.,1.);
203 static const TVector3 stdMomErr(1.,1.,1.);
205 fCov[3][3] = stdPosErr.X()*stdPosErr.X() * u.X()*u.X() +
206 stdPosErr.Y()*stdPosErr.Y() * u.Y()*u.Y() +
207 stdPosErr.Z()*stdPosErr.Z() * u.Z()*u.Z();
208 fCov[4][4] = stdPosErr.X()*stdPosErr.X() * v.X()*v.X() +
209 stdPosErr.Y()*stdPosErr.Y() * v.Y()*v.Y() +
210 stdPosErr.Z()*stdPosErr.Z() * v.Z()*v.Z();
212 (mom.X()*mom.X() * stdMomErr.X()*stdMomErr.X()+
213 mom.Y()*mom.Y() * stdMomErr.Y()*stdMomErr.Y()+
214 mom.Z()*mom.Z() * stdMomErr.Z()*stdMomErr.Z());
215 fCov[1][1] = pow((u.X()/pw - w.X()*pu/(pw*pw)),2.)*stdMomErr.X()*stdMomErr.X() +
216 pow((u.Y()/pw - w.Y()*pu/(pw*pw)),2.)*stdMomErr.Y()*stdMomErr.Y() +
217 pow((u.Z()/pw - w.Z()*pu/(pw*pw)),2.)*stdMomErr.Z()*stdMomErr.Z();
218 fCov[2][2] = pow((v.X()/pw - w.X()*pv/(pw*pw)),2.)*stdMomErr.X()*stdMomErr.X() +
219 pow((v.Y()/pw - w.Y()*pv/(pw*pw)),2.)*stdMomErr.Y()*stdMomErr.Y() +
220 pow((v.Z()/pw - w.Z()*pv/(pw*pw)),2.)*stdMomErr.Z()*stdMomErr.Z();
226 const int& PDGCode) :
227 GFAbsTrackRep(5),fDirection(true), fCachePlane(), fCacheSpu(1), fAuxInfo(1,1){
235 TVector3 w=u.Cross(v);
251 static const TVector3 stdPosErr2(1.,1.,1.);
252 static const TVector3 stdMomErr2(1.,1.,1.);
254 fCov[3][3] = stdPosErr2.X()*stdPosErr2.X() * u.X()*u.X() +
255 stdPosErr2.Y()*stdPosErr2.Y() * u.Y()*u.Y() +
256 stdPosErr2.Z()*stdPosErr2.Z() * u.Z()*u.Z();
257 fCov[4][4] = stdPosErr2.X()*stdPosErr2.X() * v.X()*v.X() +
258 stdPosErr2.Y()*stdPosErr2.Y() * v.Y()*v.Y() +
259 stdPosErr2.Z()*stdPosErr2.Z() * v.Z()*v.Z();
261 (mom.X()*mom.X() * stdMomErr2.X()*stdMomErr2.X()+
262 mom.Y()*mom.Y() * stdMomErr2.Y()*stdMomErr2.Y()+
263 mom.Z()*mom.Z() * stdMomErr2.Z()*stdMomErr2.Z());
264 fCov[1][1] = pow((u.X()/pw - w.X()*pu/(pw*pw)),2.)*stdMomErr2.X()*stdMomErr2.X() +
265 pow((u.Y()/pw - w.Y()*pu/(pw*pw)),2.)*stdMomErr2.Y()*stdMomErr2.Y() +
266 pow((u.Z()/pw - w.Z()*pu/(pw*pw)),2.)*stdMomErr2.Z()*stdMomErr2.Z();
267 fCov[2][2] = pow((v.X()/pw - w.X()*pv/(pw*pw)),2.)*stdMomErr2.X()*stdMomErr2.X() +
268 pow((v.Y()/pw - w.Y()*pv/(pw*pw)),2.)*stdMomErr2.Y()*stdMomErr2.Y() +
269 pow((v.Z()/pw - w.Z()*pv/(pw*pw)),2.)*stdMomErr2.Z()*stdMomErr2.Z();
276 TParticlePDG * part = TDatabasePDG::Instance()->GetParticle(
fPdg);
278 std::cerr <<
"RKTrackRep::setPDG particle " << i
279 <<
" not known to TDatabasePDG -> abort" << std::endl;
282 fMass = part->Mass();
289 TMatrixT<double>
s(5,1);
298 TMatrixT<double> statePred(
fState);
307 retmom.SetMag(1./
fabs(statePred[0][0]));
314 TMatrixT<double> statePred(
fState);
322 mom.SetMag(1./
fabs(statePred[0][0]));
323 pos = pl.
getO()+(statePred[3][0]*pl.
getU())+(statePred[4][0]*pl.
getV());
331 TVector3& dirInPoca){
333 static const int maxIt(30);
338 TVector3 w=u.Cross(v);
345 TMatrixT<double> state7(7,1);
346 state7[0][0] = point.X();
347 state7[1][0] = point.Y();
348 state7[2][0] = point.Z();
349 state7[3][0] = pTilde.X();
350 state7[4][0] = pTilde.Y();
351 state7[5][0] = pTilde.Z();
352 state7[6][0] =
fState[0][0];
354 double coveredDistance(0.);
360 pl.
setON(pos,TVector3(state7[3][0],state7[4][0],state7[5][0]));
361 coveredDistance = this->
Extrap(pl,&state7);
364 if(++iterations == maxIt) {
365 GFException exc(
"RKTrackRep::extrapolateToPoint ==> extrapolation to point failed, maximum number of iterations reached",__LINE__,__FILE__);
369 poca.SetXYZ(state7[0][0],state7[1][0],state7[2][0]);
370 dirInPoca.SetXYZ(state7[3][0],state7[4][0],state7[5][0]);
378 TVector3 theWire = extr2-extr1;
379 if(theWire.Mag()<1.E-8){
380 GFException exc(
"RKTrackRep::poca2Line ==> try to find poca between line and point, but the line is really just a point",__LINE__,__FILE__);
383 double t = 1./(theWire*theWire)*(point*theWire+extr1*extr1-extr1*extr2);
384 return (extr1+t*theWire);
391 const TVector3& point2,
394 TVector3& poca_onwire){
395 static const int maxIt(30);
400 TVector3 w=u.Cross(v);
407 TMatrixT<double> state7(7,1);
408 state7[0][0] = point.X();
409 state7[1][0] = point.Y();
410 state7[2][0] = point.Z();
411 state7[3][0] = pTilde.X();
412 state7[4][0] = pTilde.Y();
413 state7[5][0] = pTilde.Z();
414 state7[6][0] =
fState[0][0];
416 double coveredDistance(0.);
423 TVector3 currentDir(state7[3][0],state7[4][0],state7[5][0]);
424 pl.
setU(currentDir.Cross(point2-point1));
425 pl.
setV(point2-point1);
426 coveredDistance = this->
Extrap(pl,&state7);
429 if(++iterations == maxIt) {
430 GFException exc(
"RKTrackRep::extrapolateToLine ==> extrapolation to line failed, maximum number of iterations reached",__LINE__,__FILE__);
434 poca.SetXYZ(state7[0][0],state7[1][0],state7[2][0]);
435 dirInPoca.SetXYZ(state7[3][0],state7[4][0],state7[5][0]);
436 poca_onwire =
poca2Line(point1,point2,poca);
443 TMatrixT<double>& statePred,
444 TMatrixT<double>& covPred){
446 TMatrixT<double> cov7x7(7,7);
447 TMatrixT<double> J_pM(7,5);
452 TVector3 w=u.Cross(v);
454 J_pM[0][3] = u.X();J_pM[0][4]=v.X();
455 J_pM[1][3] = u.Y();J_pM[1][4]=v.Y();
456 J_pM[2][3] = u.Z();J_pM[2][4]=v.Z();
459 double pTildeMag = pTilde.Mag();
464 J_pM[3][1] =
fSpu/pTildeMag*(u.X()-pTilde.X()/(pTildeMag*pTildeMag)*u*pTilde);
465 J_pM[4][1] =
fSpu/pTildeMag*(u.Y()-pTilde.Y()/(pTildeMag*pTildeMag)*u*pTilde);
466 J_pM[5][1] =
fSpu/pTildeMag*(u.Z()-pTilde.Z()/(pTildeMag*pTildeMag)*u*pTilde);
468 J_pM[3][2] =
fSpu/pTildeMag*(v.X()-pTilde.X()/(pTildeMag*pTildeMag)*v*pTilde);
469 J_pM[4][2] =
fSpu/pTildeMag*(v.Y()-pTilde.Y()/(pTildeMag*pTildeMag)*v*pTilde);
470 J_pM[5][2] =
fSpu/pTildeMag*(v.Z()-pTilde.Z()/(pTildeMag*pTildeMag)*v*pTilde);
474 TMatrixT<double> J_pM_transp(J_pM);
477 cov7x7 = J_pM*(
fCov*J_pM_transp);
480 TMatrixT<double> state7(7,1);
481 state7[0][0] = pos.X();
482 state7[1][0] = pos.Y();
483 state7[2][0] = pos.Z();
484 state7[3][0] = pTilde.X()/pTildeMag;;
485 state7[4][0] = pTilde.Y()/pTildeMag;;
486 state7[5][0] = pTilde.Z()/pTildeMag;;
487 state7[6][0] =
fState[0][0];
489 double coveredDistance = this->
Extrap(pl,&state7,&cov7x7);
491 TVector3 O = pl.
getO();
492 TVector3 U = pl.
getU();
493 TVector3 V = pl.
getV();
496 double X = state7[0][0];
497 double Y = state7[1][0];
498 double Z = state7[2][0];
499 double AX = state7[3][0];
500 double AY = state7[4][0];
501 double AZ = state7[5][0];
502 double QOP = state7[6][0];
503 TVector3 A(AX,AY,AZ);
504 TVector3 Point(X,Y,Z);
505 TMatrixT<double> J_Mp(5,7);
511 J_Mp[1][3] = (U.X()*(AtW)-W.X()*(A*U))/(AtW*AtW);
512 J_Mp[1][4] = (U.Y()*(AtW)-W.Y()*(A*U))/(AtW*AtW);
513 J_Mp[1][5] = (U.Z()*(AtW)-W.Z()*(A*U))/(AtW*AtW);
515 J_Mp[2][3] = (V.X()*(AtW)-W.X()*(A*V))/(AtW*AtW);
516 J_Mp[2][4] = (V.Y()*(AtW)-W.Y()*(A*V))/(AtW*AtW);
517 J_Mp[2][5] = (V.Z()*(AtW)-W.Z()*(A*V))/(AtW*AtW);
527 TMatrixT<double> J_Mp_transp(J_Mp);
530 covPred.ResizeTo(5,5);
532 covPred = J_Mp*(cov7x7*J_Mp_transp);
534 statePred.ResizeTo(5,1);
535 statePred[0][0] = QOP;
536 statePred[1][0] = (A*U)/(A*W);
537 statePred[2][0] = (A*V)/(A*W);
538 statePred[3][0] = (Point-O)*U;
539 statePred[4][0] = (Point-O)*V;
544 return coveredDistance;
551 TMatrixT<double>& statePred){
556 TVector3 w=u.Cross(v);
560 double pTildeMag = pTilde.Mag();
564 TMatrixT<double> state7(7,1);
565 state7[0][0] = pos.X();
566 state7[1][0] = pos.Y();
567 state7[2][0] = pos.Z();
568 state7[3][0] = pTilde.X()/pTildeMag;
569 state7[4][0] = pTilde.Y()/pTildeMag;
570 state7[5][0] = pTilde.Z()/pTildeMag;
571 state7[6][0] =
fState[0][0];
573 TVector3 O = pl.
getO();
574 TVector3 U = pl.
getU();
575 TVector3 V = pl.
getV();
578 double coveredDistance = this->
Extrap(pl,&state7);
580 double X = state7[0][0];
581 double Y = state7[1][0];
582 double Z = state7[2][0];
583 double AX = state7[3][0];
584 double AY = state7[4][0];
585 double AZ = state7[5][0];
586 double QOP = state7[6][0];
587 TVector3 A(AX,AY,AZ);
588 TVector3 Point(X,Y,Z);
590 statePred.ResizeTo(5,1);
591 statePred[0][0] = QOP;
592 statePred[1][0] = (A*U)/(A*W);
593 statePred[2][0] = (A*V)/(A*W);
594 statePred[3][0] = (Point-O)*U;
595 statePred[4][0] = (Point-O)*V;
597 return coveredDistance;
642 double& coveredDistance,
643 std::vector<TVector3>& points,
644 std::vector<double>& pointPaths,
646 bool calcCov)
const {
648 static const double EC = .000149896229;
649 static const double DLT = .0002;
650 static const double DLT32 = DLT/32.;
651 static const double P3 = 1./3.;
652 static const double Smax = 100.;
653 static const double Wmax = 3000.;
654 static const double Pmin = 4.E-3;
655 static const int ND = 56;
656 static const int ND1 = ND-7;
659 double SA[3] = {0.,0.,0.};
660 double Pinv = P[6]*EC;
664 bool stopBecauseOfMaterial =
false;
672 std::cerr <<
"RKTrackRep::RKutta ==> momentum too low: " <<
fabs(
fCharge/P[6])*1000. <<
" MeV" << std::endl;
677 TVector3 O = plane.
getO();
694 double Step,An,Dist,Dis,S,Sl=0;
696 points.push_back(TVector3(R[0],R[1],R[2]));
697 pointPaths.push_back(0.);
699 An=A[0]*SU[0]+A[1]*SU[1]+A[2]*SU[2];
700 if(
fabs(An) < 1.E-6) {
701 std::cerr <<
"RKTrackRep::RKutta ==> cannot propagate perpendicular to plane " << std::endl;
704 if( plane.
inActive(TVector3(R[0],R[1],R[2]),TVector3(A[0],A[1],A[2]))) {
705 Dist=SU[3]-R[0]*SU[0]-R[1]*SU[1]-R[2]*SU[2];
709 if( (O.X()-R[0])*A[0] + (O.Y()-R[1])*A[1] + (O.Z()-R[2])*A[2] >0 ){
710 Dist =
sqrt((R[0]-O.X())*(R[0]-O.X())+
711 (R[1]-O.Y())*(R[1]-O.Y())+
712 (R[2]-O.Z())*(R[2]-O.Z()));
715 Dist = -1.*
sqrt((R[0]-O.X())*(R[0]-O.X())+
716 (R[1]-O.Y())*(R[1]-O.Y())+
717 (R[2]-O.Z())*(R[2]-O.Z()));
722 if(
fabs(Step)>Wmax) {
723 std::cerr<<
"RKTrackRep::RKutta ==> Too long extrapolation requested : "<<Step<<
" cm !"<<std::endl;
724 std::cerr<<
"X = "<<R[0]<<
" Y = "<<R[1]<<
" Z = "<<R[2]
725 <<
" COSx = "<<A[0]<<
" COSy = "<<A[1]<<
" COSz = "<<A[2]<<std::endl;
726 std::cout<<
"Destination X = "<<SU[0]*SU[3]<<std::endl;
731 Step>Smax ? S=Smax : Step<-Smax ? S=-Smax : S=Step;
741 while(
fabs(Step)>
MINSTEP && !stopBecauseOfMaterial) {
747 Ssign*A[0],Ssign*A[1],Ssign*A[2],
751 if (S > stepperLen) {
753 stopBecauseOfMaterial =
true;
755 else if (S < -stepperLen) {
757 stopBecauseOfMaterial =
true;
760 double H0[12],H1[12],H2[12],
r[3];
761 double S3=P3*S, S4=.25*S, PS2=Pinv*S;
766 r[0]=R[0] ; r[1]=R[1] ; r[2]=R[2] ;
767 TVector3
pos(r[0],r[1],r[2]);
769 H0[0]=PS2*H0vect.X(); H0[1]=PS2*H0vect.Y(); H0[2]=PS2*H0vect.Z();
770 double A0=A[1]*H0[2]-A[2]*H0[1], B0=A[2]*H0[0]-A[0]*H0[2], C0=A[0]*H0[1]-A[1]*H0[0];
771 double A2=A[0]+A0 , B2=A[1]+B0 , C2=A[2]+C0 ;
772 double A1=A2+A[0] , B1=B2+A[1] , C1=C2+A[2] ;
777 r[0]+=A1*S4 ; r[1]+=B1*S4 ; r[2]+=C1*S4 ;
778 pos.SetXYZ(r[0],r[1],r[2]);
780 H1[0]=H1vect.X()*PS2; H1[1]=H1vect.Y()*PS2;H1[2]=H1vect.Z()*PS2;
781 double A3,B3,C3,A4,B4,C4,A5,B5,C5;
782 A3 = B2*H1[2]-C2*H1[1]+A[0]; B3=C2*H1[0]-A2*H1[2]+A[1]; C3=A2*H1[1]-B2*H1[0]+A[2];
783 A4 = B3*H1[2]-C3*H1[1]+A[0]; B4=C3*H1[0]-A3*H1[2]+A[1]; C4=A3*H1[1]-B3*H1[0]+A[2];
784 A5 = A4-A[0]+A4 ; B5=B4-A[1]+B4 ; C5=C4-A[2]+C4 ;
789 r[0]=R[0]+S*A4 ; r[1]=R[1]+S*B4 ; r[2]=R[2]+S*C4 ;
790 pos.SetXYZ(r[0],r[1],r[2]);
792 H2[0]=H2vect.X()*PS2; H2[1]=H2vect.Y()*PS2;H2[2]=H2vect.Z()*PS2;
793 double A6=B5*H2[2]-C5*H2[1], B6=C5*H2[0]-A5*H2[2], C6=A5*H2[1]-B5*H2[0];
798 double EST =
fabs((A1+A6)-(A3+A4))+
fabs((B1+B6)-(B3+B4))+
fabs((C1+C6)-(C3+C4));
801 stopBecauseOfMaterial =
false;
809 for(
int i=7;
i!=ND;
i+=7) {
812 double* dA = &P[
i+3];
815 double dA0 = H0[ 2]*dA[1]-H0[ 1]*dA[2];
816 double dB0 = H0[ 0]*dA[2]-H0[ 2]*dA[0];
817 double dC0 = H0[ 1]*dA[0]-H0[ 0]*dA[1];
819 if(
i==ND1) {dA0+=A0; dB0+=B0; dC0+=C0;}
821 double dA2 = dA0+dA[0];
822 double dB2 = dB0+dA[1];
823 double dC2 = dC0+dA[2];
826 double dA3 = dA[0]+dB2*H1[2]-dC2*H1[1];
827 double dB3 = dA[1]+dC2*H1[0]-dA2*H1[2];
828 double dC3 = dA[2]+dA2*H1[1]-dB2*H1[0];
830 if(
i==ND1) {dA3+=A3-A[0]; dB3+=B3-A[1]; dC3+=C3-A[2];}
832 double dA4 = dA[0]+dB3*H1[2]-dC3*H1[1];
833 double dB4 = dA[1]+dC3*H1[0]-dA3*H1[2];
834 double dC4 = dA[2]+dA3*H1[1]-dB3*H1[0];
836 if(
i==ND1) {dA4+=A4-A[0]; dB4+=B4-A[1]; dC4+=C4-A[2];}
839 double dA5 = dA4+dA4-dA[0];
840 double dB5 = dB4+dB4-dA[1];
841 double dC5 = dC4+dC4-dA[2];
843 double dA6 = dB5*H2[2]-dC5*H2[1];
844 double dB6 = dC5*H2[0]-dA5*H2[2];
845 double dC6 = dA5*H2[1]-dB5*H2[0];
847 if(
i==ND1) {dA6+=A6; dB6+=B6; dC6+=C6;}
849 dR[0]+=(dA2+dA3+dA4)*S3; dA[0] = (dA0+dA3+dA3+dA5+dA6)*P3;
850 dR[1]+=(dB2+dB3+dB4)*S3; dA[1] = (dB0+dB3+dB3+dB5+dB6)*P3;
851 dR[2]+=(dC2+dC3+dC4)*S3; dA[2] = (dC0+dC3+dC3+dC5+dC6)*P3;
856 if((Way+=
fabs(S))>Wmax){
857 std::cerr<<
"RKTrackRep::RKutta ==> Trajectory is longer than length limit : "<<Way<<
" cm !"
858 <<
" p/q = "<<1./P[6]<<
" GeV"<<std::endl;
865 R[0]+=(A2+A3+A4)*S3; A[0]+=(SA[0]=(A0+A3+A3+A5+A6)*P3-A[0]);
866 R[1]+=(B2+B3+B4)*S3; A[1]+=(SA[1]=(B0+B3+B3+B5+B6)*P3-A[1]);
867 R[2]+=(C2+C3+C4)*S3; A[2]+=(SA[2]=(C0+C3+C3+C5+C6)*P3-A[2]);
873 pointPaths.at(pointPaths.size()-1)+=S;
874 points.erase(points.end());
877 pointPaths.push_back(S);
880 points.push_back(TVector3(R[0],R[1],R[2]));
882 double CBA = 1./
sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
883 A[0]*=CBA; A[1]*=CBA; A[2]*=CBA;
886 if(
fabs(Way2)>Wmax) {
895 An=A[0]*SU[0]+A[1]*SU[1]+A[2]*SU[2];
897 if(
fabs(An) < 1.E-6) {
903 if( plane.
inActive(TVector3(R[0],R[1],R[2]),TVector3(A[0],A[1],A[2]))) {
904 Dis=SU[3]-R[0]*SU[0]-R[1]*SU[1]-R[2]*SU[2];
908 if( (O.X()-R[0])*A[0] + (O.Y()-R[1])*A[1] + (O.Z()-R[2])*A[2] >0 ){
909 Dis =
sqrt((R[0]-O.X())*(R[0]-O.X())+
910 (R[1]-O.Y())*(R[1]-O.Y())+
911 (R[2]-O.Z())*(R[2]-O.Z()));
914 Dis = -1.*
sqrt((R[0]-O.X())*(R[0]-O.X())+
915 (R[1]-O.Y())*(R[1]-O.Y())+
916 (R[2]-O.Z())*(R[2]-O.Z()));
921 if (Dis*Dist>0 &&
fabs(Dis)>
fabs(Dist)) {
932 if (S*Step<0. ||
fabs(S)>
fabs(Step)) S=Step;
933 else if (EST<DLT32 &&
fabs(2.*S)<=Smax) S*=2.;
941 if (!stopBecauseOfMaterial) {
942 if(
fabs(Sl) > 1.E-12) Sl=1./Sl;
943 A [0]+=(SA[0]*=Sl)*Step;
944 A [1]+=(SA[1]*=Sl)*Step;
945 A [2]+=(SA[2]*=Sl)*Step;
947 P[0] = R[0]+Step*(A[0]-.5*Step*SA[0]);
948 P[1] = R[1]+Step*(A[1]-.5*Step*SA[1]);
949 P[2] = R[2]+Step*(A[2]-.5*Step*SA[2]);
951 points.push_back(TVector3(P[0],P[1],P[2]));
952 pointPaths.push_back(Step);
955 double CBA = 1./
sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
964 An = A[0]*SU[0]+A[1]*SU[1]+A[2]*SU[2];
965 fabs(An) < 1.E-6 ? An=1./An : An = 0;
967 if(calcCov && !stopBecauseOfMaterial){
968 for(
int i=7;
i!=ND;
i+=7) {
969 double* dR = &P[
i];
double* dA = &P[
i+3];
970 S = (dR[0]*SU[0]+dR[1]*SU[1]+dR[2]*SU[2])*An;
971 dR[0]-=S*A [0]; dR[1]-=S*A [1]; dR[2]-=S*A [2];
972 dA[0]-=S*SA[0]; dA[1]-=S*SA[1]; dA[2]-=S*SA[2];
977 std::cerr <<
"RKTrackRep::RKutta ==> Do not get closer. Path = " << Way <<
" cm" <<
" p/q = " << 1./P[6] <<
" GeV" << std::endl;
982 if (!stopBecauseOfMaterial) coveredDistance=Way2+Step;
983 else coveredDistance=Way2;
993 static const int maxNumIt(2000);
996 if(cov==NULL) calcCov=
false;
999 if(calcCov) {P =
new double[56]; memset(P,0x00,56*
sizeof(
double));}
1000 else {P =
new double[7];}
1002 for(
int i=0;
i<7;++
i){
1003 P[
i] = (*state)[
i][0];
1006 TMatrixT<double> jac(7,7);
1007 TMatrixT<double> jacT(7,7);
1008 TMatrixT<double> oldCov(7,7);
1009 if(calcCov) oldCov=(*cov);
1010 double coveredDistance(0.);
1011 double sumDistance(0.);
1014 if(numIt++ > maxNumIt){
1015 GFException exc(
"RKTrackRep::Extrap ==> maximum number of iterations exceeded",
1023 memset(&P[7],0x00,49*
sizeof(
double));
1024 for(
int i=0;
i<6; ++
i){
1027 P[55] = (*state)[6][0];
1032 TVector3 Pvect(P[0],P[1],P[2]);
1033 TVector3 Avect(P[3],P[4],P[5]);
1034 TVector3 dist = plane.
dist(Pvect);
1038 TVector3 directionBefore(P[3],P[4],P[5]);
1039 directionBefore.SetMag(1.);
1042 std::vector<TVector3> points;
1043 std::vector<double> pointPaths;
1044 if( ! this->
RKutta(plane, P, coveredDistance, points, pointPaths, -1., calcCov) ) {
1045 GFException exc(
"RKTrackRep::Extrap ==> Runge Kutta propagation failed",__LINE__,__FILE__);
1051 TVector3 directionAfter(P[3],P[4],P[5]);
1052 directionAfter.SetMag(1.);
1054 sumDistance+=coveredDistance;
1057 std::vector<TVector3> pointsFilt(1, points.at(0));
1058 std::vector<double> pointPathsFilt(1, 0.);
1060 for(
unsigned int i=1;
i<points.size();++
i){
1061 if (pointPaths.at(
i) * coveredDistance > 0.) {
1062 pointsFilt.push_back(points.at(
i));
1063 pointPathsFilt.push_back(pointPaths.at(
i));
1066 pointsFilt.back() = points.at(
i);
1067 pointPathsFilt.back() += pointPaths.at(
i);
1070 int position = pointsFilt.size()-1;
1071 if (
fabs(pointPathsFilt.back()) <
MINSTEP && position > 1) {
1072 pointsFilt.at(position-1) = pointsFilt.at(position);
1073 pointsFilt.pop_back();
1074 pointPathsFilt.at(position-1) += pointPathsFilt.at(position);
1075 pointPathsFilt.pop_back();
1080 double checkSum(0.);
1081 for(
unsigned int i=0;
i<pointPathsFilt.size();++
i){
1082 checkSum+=pointPathsFilt.at(
i);
1084 if(
fabs(checkSum-coveredDistance)>1.E-7){
1085 GFException exc(
"RKTrackRep::Extrap ==> fabs(checkSum-coveredDistance)>1.E-7",__LINE__,__FILE__);
1092 for(
int i=0;
i<7;++
i){
1093 for(
int j=0;j<7;++j){
1094 if(
i<6) jac[
i][j] = P[ (
i+1)*7+j ];
1095 else jac[
i][j] = P[ (
i+1)*7+j ]/P[6];
1102 TMatrixT<double>
noise(7,7);
1117 if(
fabs(P[6])>1.E-10){
1122 if(!(oldCov < 1.E200)){
1123 GFException exc(
"RKTrackRep::Extrap ==> covariance matrix exceeds numerical limits",__LINE__,__FILE__);
1129 *cov = jacT*((oldCov)*jac)+
noise;
1135 if( plane.
inActive(TVector3(P[0],P[1],P[2]),TVector3(P[3],P[4],P[5]))) {
1139 (*state)[0][0] = P[0]; (*state)[1][0] = P[1];
1140 (*state)[2][0] = P[2]; (*state)[3][0] = P[3];
1141 (*state)[4][0] = P[4]; (*state)[5][0] = P[5];
1142 (*state)[6][0] = P[6];
1150 const TVector3 U=pl.
getU();
1151 const TVector3 V=pl.
getV();
1152 const TVector3
W=U.Cross(V);
1154 TMatrixT<double> statePred=
fState;
1155 TMatrixT<double> covPred=
fCov;
1163 const double p=
fCharge/statePred[0][0];
1164 const TVector3 pTilde=spu*(W+statePred[1][0]*U+statePred[2][0]*V);
1165 const double pTildeMagnitude=pTilde.Mag();
1167 TMatrixT<double> jacobian(6, 5);
1168 jacobian[0][3]=U.X();
1169 jacobian[0][4]=V.X();
1170 jacobian[1][3]=U.Y();
1171 jacobian[1][4]=V.Y();
1172 jacobian[2][3]=U.Z();
1173 jacobian[2][4]=V.Z();
1174 jacobian[3][1]=p*spu/pTildeMagnitude*(U.X()-pTilde.X()*(U*pTilde)/(pTildeMagnitude*pTildeMagnitude));
1175 jacobian[3][2]=p*spu/pTildeMagnitude*(V.X()-pTilde.X()*(V*pTilde)/(pTildeMagnitude*pTildeMagnitude));
1176 jacobian[4][1]=p*spu/pTildeMagnitude*(U.Y()-pTilde.Y()*(U*pTilde)/(pTildeMagnitude*pTildeMagnitude));
1177 jacobian[4][2]=p*spu/pTildeMagnitude*(V.Y()-pTilde.Y()*(V*pTilde)/(pTildeMagnitude*pTildeMagnitude));
1178 jacobian[5][1]=p*spu/pTildeMagnitude*(U.Z()-pTilde.Z()*(U*pTilde)/(pTildeMagnitude*pTildeMagnitude));
1179 jacobian[5][2]=p*spu/pTildeMagnitude*(V.Z()-pTilde.Z()*(V*pTilde)/(pTildeMagnitude*pTildeMagnitude));
1181 TMatrixT<double> transposedJacobian=jacobian;
1182 transposedJacobian.T();
1186 pos=pl.
getO()+statePred[3][0]*U+statePred[4][0]*V;
1187 mom=p/pTildeMagnitude*pTilde;
1188 cov=jacobian*covPred*transposedJacobian;
1196 static const int maxIt(30);
1201 TVector3 w=u.Cross(v);
1208 TMatrixT<double> state7(7,1);
1209 state7[0][0] = point.X();
1210 state7[1][0] = point.Y();
1211 state7[2][0] = point.Z();
1212 state7[3][0] = pTilde.X();
1213 state7[4][0] = pTilde.Y();
1214 state7[5][0] = pTilde.Z();
1215 state7[6][0] =
fState[0][0];
1217 double coveredDistance(0.);
1223 pos.SetXYZ(state7[0][0], state7[1][0], state7[2][0]);
1224 dir.SetXYZ(state7[3][0], state7[4][0], state7[5][0]);
1227 dest = pos + (h - coveredDistance) * dir;
1229 pl.
setON(dest, dir);
1230 coveredDistance += this->
Extrap(pl,&state7);
1233 if(++iterations == maxIt) {
1234 GFException exc(
"RKTrackRep::stepalong ==> maximum number of iterations reached",__LINE__,__FILE__);
1239 pos.SetXYZ(state7[0][0], state7[1][0], state7[2][0]);
1240 dir.SetXYZ(state7[3][0], state7[4][0], state7[5][0]);
1243 return coveredDistance;
Base Class for genfit track representations. Defines interface for track parameterizations.
void setData(const TMatrixT< double > &st, const GFDetPlane &pl, const TMatrixT< double > *cov=NULL, const TMatrixT< double > *aux=NULL)
Sets state, plane and (optionally) covariance.
double Extrap(const GFDetPlane &plane, TMatrixT< double > *state, TMatrixT< double > *cov=NULL) const
Handles propagation and material effects.
Detector plane genfit geometry class.
void getPosMom(const GFDetPlane &, TVector3 &pos, TVector3 &mom)
Gets position and momentum in the plane.
void setU(const TVector3 &u)
friend F32vec4 sqrt(const F32vec4 &a)
void setON(const TVector3 &o, const TVector3 &n)
void setO(const TVector3 &o)
double distance(TVector3 &) const
static TVector3 getFieldVal(const TVector3 &x)
void extrapolateToLine(const TVector3 &point1, const TVector3 &point2, TVector3 &poca, TVector3 &dirInPoca, TVector3 &poca_onwire)
This method extrapolates to the point of closest approach to a line.
static void error(int no)
bool RKutta(const GFDetPlane &plane, double *P, double &coveredDistance, std::vector< TVector3 > &points, std::vector< double > &pointLengths, const double &maxLen=-1, bool calcCov=true) const
Propagates the particle through the magnetic field.
void setNormal(TVector3 n)
TVector3 getPosSeed() const
get the seed value for track: pos
int fPdg
PDG particle code.
TVector3 getDirSeed() const
get the seed value for track: direction
Track Representation module based on a Runge-Kutta algorithm including a full material model...
double fMass
Mass (in GeV)
void getPosMomCov(const GFDetPlane &pl, TVector3 &pos, TVector3 &mom, TMatrixT< double > &cov)
method which gets position, momentum and 6x6 covariance matrix
TVector3 getDirError() const
get the seed value for track: error on direction (standard deviation)
Track candidate – a list of cluster indices.
TMatrixT< double > fAuxInfo
friend F32vec4 fabs(const F32vec4 &a)
TVector3 getPosError() const
get the seed value for track: error on pos (standard deviation)
double stepalong(double h, TVector3 &point, TVector3 &dir)
make step of h cm along the track, returns the tracklength spanned in this extrapolation ...
void extrapolateToPoint(const TVector3 &pos, TVector3 &poca, TVector3 &dirInPoca)
This method is to extrapolate the track to point of closest approach to a point in space...
int getPdgCode() const
get the PDG code
double stepper(const double &maxDist, const double &posx, const double &posy, const double &posz, const double &dirx, const double &diry, const double &dirz, const double &mom, const int &pdg)
Returns maximum length so that a specified momentum loss will not be exceeded.
void setV(const TVector3 &v)
TVector3 poca2Line(const TVector3 &extr1, const TVector3 &extr2, const TVector3 &point) const
Exception class for error handling in GENFIT (provides storage for diagnostic information) ...
void setFatal(bool b=true)
set fatal flag. if this is true, the fit stops for this current track repr.
bool inActive(const TVector3 &point, const TVector3 &dir) const
intersect in the active area? C.f. GFAbsFinitePlane
TMatrixT< double > fState
The vector of track parameters.
virtual void setData(const TMatrixT< double > &st, const GFDetPlane &pl, const TMatrixT< double > *cov=NULL, const TMatrixT< double > *aux=NULL)
Puts the track representation in a given state.
void setPDG(int)
Set PDG particle code.
static GFMaterialEffects * getInstance()
TVector3 getNormal() const
double extrapolate(const GFDetPlane &, TMatrixT< double > &statePred, TMatrixT< double > &covPred)
returns the tracklength spanned in this extrapolation
double effects(const std::vector< TVector3 > &points, const std::vector< double > &pointPaths, const double &mom, const int &pdg, const bool &doNoise=false, TMatrixT< double > *noise=NULL, const TMatrixT< double > *jacobian=NULL, const TVector3 *directionBefore=NULL, const TVector3 *directionAfter=NULL)
Calculates energy loss in the travelled path, optional calculation of noise matrix.
const TMatrixT< double > * getAuxInfo(const GFDetPlane &pl)
Get auxillary information from the track representation.
TMatrixT< double > fCov
The covariance matrix.
TVector3 dist(const TVector3 &point) const