20#include "RKTrackRep.h"
23#include <FieldManager.h>
24#include <MaterialEffects.h>
39 const bool useInvertFast =
false;
47 lastStartState_(this),
62 lastStartState_(this),
85 const TVector3 & point,
const TVector3 & dir,
87 bool calcJacobianNoise)
const {
100 bool calcJacobianNoise)
const {
103 std::cout <<
"RKTrackRep::extrapolateToPlane()\n";
109 std::cout <<
"state is already defined at plane. Do nothing! \n";
120 TMatrixDSym* covPtr(NULL);
121 bool fillExtrapSteps(
false);
124 fillExtrapSteps =
true;
126 else if (calcJacobianNoise)
127 fillExtrapSteps =
true;
130 bool isAtBoundary(
false);
131 double coveredDistance =
Extrap(*(state.
getPlane()), *plane,
getCharge(state), isAtBoundary, state7, fillExtrapSteps, covPtr,
false, stopAtBoundary);
133 if (stopAtBoundary && isAtBoundary) {
135 TVector3(state7[3], state7[4], state7[5]))));
146 return coveredDistance;
151 const TVector3& linePoint,
152 const TVector3& lineDirection,
154 bool calcJacobianNoise)
const {
157 std::cout <<
"RKTrackRep::extrapolateToLine()\n";
162 static const unsigned int maxIt(1000);
168 bool fillExtrapSteps(
false);
170 fillExtrapSteps =
true;
172 else if (calcJacobianNoise)
173 fillExtrapSteps =
true;
175 double step(0.), lastStep(0.), maxStep(1.E99), angle(0), distToPoca(0), tracklength(0);
177 TVector3 dir(state7[3], state7[4], state7[5]);
178 TVector3 lastDir(0,0,0);
179 TVector3 poca, poca_onwire;
180 bool isAtBoundary(
false);
184 unsigned int iterations(0);
187 if(++iterations == maxIt) {
188 Exception exc(
"RKTrackRep::extrapolateToLine ==> extrapolation to line failed, maximum number of iterations reached",__LINE__,__FILE__);
196 step = this->
Extrap(startPlane, *plane, charge, isAtBoundary, state7,
false, NULL,
true, stopAtBoundary, maxStep);
199 dir.SetXYZ(state7[3], state7[4], state7[5]);
200 poca.SetXYZ(state7[0], state7[1], state7[2]);
201 poca_onwire =
pocaOnLine(linePoint, lineDirection, poca);
204 if (stopAtBoundary && isAtBoundary) {
205 plane->setON(dir, poca);
209 angle = fabs(dir.Angle((poca_onwire-poca))-TMath::PiOver2());
210 distToPoca = (poca_onwire-poca).Mag();
211 if (angle*distToPoca < 0.1*
MINSTEP)
break;
215 if (lastStep*step < 0){
217 maxStep = 0.5*fabs(lastStep);
221 plane->
setU(dir.Cross(lineDirection));
224 if (fillExtrapSteps) {
237 std::cout <<
"RKTrackRep::extrapolateToLine(): Reached POCA after " << iterations+1 <<
" iterations. Distance: " << (poca_onwire-poca).Mag() <<
" cm. Angle deviation: " << dir.Angle((poca_onwire-poca))-TMath::PiOver2() <<
" rad \n";
247 const TVector3& point,
248 const TMatrixDSym* G,
250 bool calcJacobianNoise)
const {
253 std::cout <<
"RKTrackRep::extrapolateToPoint()\n";
258 static const unsigned int maxIt(1000);
264 bool fillExtrapSteps(
false);
266 fillExtrapSteps =
true;
268 else if (calcJacobianNoise)
269 fillExtrapSteps =
true;
271 double step(0.), lastStep(0.), maxStep(1.E99), angle(0), distToPoca(0), tracklength(0);
272 TVector3 dir(state7[3], state7[4], state7[5]);
274 if(G->GetNrows() != 3) {
275 Exception exc(
"RKTrackRep::extrapolateToLine ==> G is not 3x3",__LINE__,__FILE__);
279 dir = TMatrix(*G) * dir;
281 TVector3 lastDir(0,0,0);
284 bool isAtBoundary(
false);
288 unsigned int iterations(0);
291 if(++iterations == maxIt) {
292 Exception exc(
"RKTrackRep::extrapolateToPoint ==> extrapolation to point failed, maximum number of iterations reached",__LINE__,__FILE__);
300 step = this->
Extrap(startPlane, *plane,
getCharge(state), isAtBoundary, state7,
false, NULL,
true, stopAtBoundary, maxStep);
303 dir.SetXYZ(state7[3], state7[4], state7[5]);
305 dir = TMatrix(*G) * dir;
307 poca.SetXYZ(state7[0], state7[1], state7[2]);
310 if (stopAtBoundary && isAtBoundary) {
311 plane->setON(dir, poca);
315 angle = fabs(dir.Angle((point-poca))-TMath::PiOver2());
316 distToPoca = (point-poca).Mag();
317 if (angle*distToPoca < 0.1*
MINSTEP)
break;
321 if (lastStep*step < 0){
323 maxStep = 0.5*fabs(lastStep);
330 if (fillExtrapSteps) {
344 std::cout <<
"RKTrackRep::extrapolateToPoint(): Reached POCA after " << iterations+1 <<
" iterations. Distance: " << (point-poca).Mag() <<
" cm. Angle deviation: " << dir.Angle((point-poca))-TMath::PiOver2() <<
" rad \n";
355 const TVector3& linePoint,
356 const TVector3& lineDirection,
358 bool calcJacobianNoise)
const {
361 std::cout <<
"RKTrackRep::extrapolateToCylinder()\n";
366 static const unsigned int maxIt(1000);
372 bool fillExtrapSteps(
false);
374 fillExtrapSteps =
true;
376 else if (calcJacobianNoise)
377 fillExtrapSteps =
true;
379 double tracklength(0.), maxStep(1.E99);
381 TVector3 dest, pos, dir;
383 bool isAtBoundary(
false);
387 unsigned int iterations(0);
390 if(++iterations == maxIt) {
391 Exception exc(
"RKTrackRep::extrapolateToCylinder ==> maximum number of iterations reached",__LINE__,__FILE__);
396 pos.SetXYZ(state7[0], state7[1], state7[2]);
397 dir.SetXYZ(state7[3], state7[4], state7[5]);
400 TVector3 AO = (pos - linePoint);
401 TVector3 AOxAB = (AO.Cross(lineDirection));
402 TVector3 VxAB = (dir.Cross(lineDirection));
403 float ab2 = (lineDirection * lineDirection);
404 float a = (VxAB * VxAB);
405 float b = 2 * (VxAB * AOxAB);
406 float c = (AOxAB * AOxAB) - (radius*radius * ab2);
407 double arg = b*b - 4.*a*c;
409 Exception exc(
"RKTrackRep::extrapolateToCylinder ==> cannot solve",__LINE__,__FILE__);
413 double term = sqrt(arg);
416 k1 = (-b + term)/(2.*a);
417 k2 = 2.*c/(-b + term);
420 k1 = 2.*c/(-b - term);
421 k2 = (-b - term)/(2.*a);
426 if (fabs(k2)<fabs(k))
430 std::cout <<
"RKTrackRep::extrapolateToCylinder(); k = " << k <<
"\n";
433 dest = pos + k * dir;
436 plane->setUV((dest-linePoint).Cross(lineDirection), lineDirection);
438 tracklength += this->
Extrap(startPlane, *plane,
getCharge(state), isAtBoundary, state7,
false, NULL,
true, stopAtBoundary, maxStep);
441 if (stopAtBoundary && isAtBoundary) {
442 pos.SetXYZ(state7[0], state7[1], state7[2]);
443 dir.SetXYZ(state7[3], state7[4], state7[5]);
445 plane->setUV((pos-linePoint).Cross(lineDirection), lineDirection);
455 if (fillExtrapSteps) {
475 const TVector3& point,
477 bool calcJacobianNoise)
const {
480 std::cout <<
"RKTrackRep::extrapolateToSphere()\n";
485 static const unsigned int maxIt(1000);
491 bool fillExtrapSteps(
false);
493 fillExtrapSteps =
true;
495 else if (calcJacobianNoise)
496 fillExtrapSteps =
true;
498 double tracklength(0.), maxStep(1.E99);
500 TVector3 dest, pos, dir;
502 bool isAtBoundary(
false);
506 unsigned int iterations(0);
509 if(++iterations == maxIt) {
510 Exception exc(
"RKTrackRep::extrapolateToSphere ==> maximum number of iterations reached",__LINE__,__FILE__);
515 pos.SetXYZ(state7[0], state7[1], state7[2]);
516 dir.SetXYZ(state7[3], state7[4], state7[5]);
519 TVector3 AO = (pos - point);
520 double dirAO = dir * AO;
521 double arg = dirAO*dirAO - AO*AO + radius*radius;
523 Exception exc(
"RKTrackRep::extrapolateToSphere ==> cannot solve",__LINE__,__FILE__);
527 double term = sqrt(arg);
534 if (fabs(k2)<fabs(k))
538 std::cout <<
"RKTrackRep::extrapolateToSphere(); k = " << k <<
"\n";
541 dest = pos + k * dir;
543 plane->setON(dest, dest-point);
545 tracklength += this->
Extrap(startPlane, *plane,
getCharge(state), isAtBoundary, state7,
false, NULL,
true, stopAtBoundary, maxStep);
548 if (stopAtBoundary && isAtBoundary) {
549 pos.SetXYZ(state7[0], state7[1], state7[2]);
550 dir.SetXYZ(state7[3], state7[4], state7[5]);
551 plane->setON(pos, pos-point);
561 if (fillExtrapSteps) {
582 bool calcJacobianNoise)
const {
585 std::cout <<
"RKTrackRep::extrapolateBy()\n";
590 static const unsigned int maxIt(1000);
596 bool fillExtrapSteps(
false);
598 fillExtrapSteps =
true;
600 else if (calcJacobianNoise)
601 fillExtrapSteps =
true;
603 double tracklength(0.);
605 TVector3 dest, pos, dir;
607 bool isAtBoundary(
false);
611 unsigned int iterations(0);
614 if(++iterations == maxIt) {
615 Exception exc(
"RKTrackRep::extrapolateBy ==> maximum number of iterations reached",__LINE__,__FILE__);
620 pos.SetXYZ(state7[0], state7[1], state7[2]);
621 dir.SetXYZ(state7[3], state7[4], state7[5]);
623 dest = pos + 1.5*(step-tracklength) * dir;
625 plane->setON(dest, dir);
627 tracklength += this->
Extrap(startPlane, *plane,
getCharge(state), isAtBoundary, state7,
false, NULL,
true, stopAtBoundary, (step-tracklength));
630 if (stopAtBoundary && isAtBoundary) {
631 pos.SetXYZ(state7[0], state7[1], state7[2]);
632 dir.SetXYZ(state7[3], state7[4], state7[5]);
633 plane->setON(pos, dir);
637 if (fabs(tracklength-step) <
MINSTEP) {
639 std::cout <<
"RKTrackRep::extrapolateBy(): reached after " << iterations <<
" iterations. \n";
641 pos.SetXYZ(state7[0], state7[1], state7[2]);
642 dir.SetXYZ(state7[3], state7[4], state7[5]);
643 plane->setON(pos, dir);
651 if (fillExtrapSteps) {
673 return TVector3(state7[0], state7[1], state7[2]);
681 TVector3 mom(state7[3], state7[4], state7[5]);
691 pos.SetXYZ(state7[0], state7[1], state7[2]);
692 mom.SetXYZ(state7[3], state7[4], state7[5]);
715 Exception exc(
"RKTrackRep::getCharge - cannot get charge from MeasurementOnPlane",__LINE__,__FILE__);
723 if (state.
getState()(0) * pdgCharge < 0)
741 Exception exc(
"RKTrackRep::getMomVar - cannot get momVar from MeasurementOnPlane",__LINE__,__FILE__);
761 Exception exc(
"RKTrackRep::getSpu - cannot get spu from MeasurementOnPlane",__LINE__,__FILE__);
767 if (auxInfo.GetNrows() == 1)
775 const M1x7& destState7,
const DetPlane& destPlane)
const {
778 std::cout <<
"RKTrackRep::calcForwardJacobianAndNoise " << std::endl;
782 Exception exc(
"RKTrackRep::calcForwardJacobianAndNoise ==> cache is empty. Extrapolation must run with a MeasuredStateOnPlane.",__LINE__,__FILE__);
787 TMatrixD jac(TMatrixD::kTransposed, TMatrixD(7, 7,
ExtrapSteps_.back().jac7_));
790 noise += TMatrixDSym(7,
ExtrapSteps_[i].noise7_).Similarity(jac);
791 jac *= TMatrixD(TMatrixD::kTransposed, TMatrixD(7, 7,
ExtrapSteps_[i].jac7_));
795 M1x3 pTilde = {startState7[3], startState7[4], startState7[5]};
796 const TVector3& normal = startPlane.
getNormal();
797 double pTildeW = pTilde[0] * normal.X() + pTilde[1] * normal.Y() + pTilde[2] * normal.Z();
798 double spu = pTildeW > 0 ? 1 : -1;
799 for (
unsigned int i=0; i<3; ++i) {
800 pTilde[i] *= spu/pTildeW;
813 std::cout <<
"total jacobian : ";
fJacobian_.Print();
814 std::cout <<
"total noise : ";
fNoise_.Print();
822 jacobian.ResizeTo(5,5);
829 deltaState.ResizeTo(5);
833 deltaState *= jacobian;
839 std::cout <<
"delta state : "; deltaState.Print();
847 std::cout <<
"RKTrackRep::getBackwardJacobianAndNoise " << std::endl;
851 Exception exc(
"RKTrackRep::getBackwardJacobianAndNoise ==> cache is empty. Extrapolation must run with a MeasuredStateOnPlane.",__LINE__,__FILE__);
855 jacobian.ResizeTo(5,5);
857 if (!useInvertFast) {
858 TDecompLU invertAlgo(jacobian);
859 bool status = invertAlgo.Invert(jacobian);
861 Exception e(
"cannot invert matrix, status = 0", __LINE__,__FILE__);
867 jacobian.InvertFast(&det);
869 Exception e(
"cannot invert matrix, status = 0", __LINE__,__FILE__);
877 noise.Similarity(jacobian);
880 deltaState.ResizeTo(5);
890 Exception exc(
"RKTrackRep::getSteps ==> cache is empty.",__LINE__,__FILE__);
894 std::vector<MatStep> retVal;
897 for (
unsigned int i = 0; i<
RKSteps_.size(); ++i) {
898 retVal.push_back(
RKSteps_[i].matStep_);
910 Exception exc(
"RKTrackRep::getRadiationLenght ==> cache is empty.",__LINE__,__FILE__);
916 for (
unsigned int i = 0; i<
RKSteps_.size(); ++i) {
917 radLen +=
RKSteps_.at(i).matStep_.stepSize_ /
RKSteps_.at(i).matStep_.materialProperties_.getRadLen();
929 Exception exc(
"RKTrackRep::getTOF ==> cache is empty.",__LINE__,__FILE__);
935 static const double c = TMath::Ccgs();
936 double p1(0), p2(0), trackLen(0), beta(0);
942 for (
unsigned int i = 0; i<
RKSteps_.size(); ++i) {
943 trackLen =
RKSteps_[i].matStep_.stepSize_;
946 if (fabs(p1-p2) < 1E-6) {
947 double p = (p1+p2)/2.;
948 beta = p / sqrt(m2 + p*p);
949 tof += 1.E9 * trackLen / (c*beta);
953 tof += 1.E9 / c / (p1 - p2) * trackLen *
954 (sqrt(m2 + p1*p1) - sqrt(m2 + p2*p2) +
955 m * log( p1/p2 * (
m + sqrt(m2 + p2*p2)) / (
m + sqrt(m2 + p1*p1)) ) );
967 if (state.
getRep() !=
this){
968 Exception exc(
"RKTrackRep::setPosMom ==> state is defined wrt. another TrackRep",__LINE__,__FILE__);
973 Exception exc(
"RKTrackRep::setPosMom - cannot set pos/mom of a MeasurementOnPlane",__LINE__,__FILE__);
980 if (auxInfo.GetNrows() != 1) {
998 double norm = 1. / sqrt(state7[3]*state7[3] + state7[4]*state7[4] + state7[5]*state7[5]);
999 for (
unsigned int i=3; i<6; ++i)
1013 TVectorD& state5(state.
getState());
1028 if (state6.GetNrows()!=6){
1029 Exception exc(
"RKTrackRep::setPosMom ==> state has to be 6d (x, y, z, px, py, pz)",__LINE__,__FILE__);
1032 setPosMom(state, TVector3(state6(0), state6(1), state6(2)), TVector3(state6(3), state6(4), state6(5)));
1042 const TVector3& U(state.
getPlane()->getU());
1043 const TVector3& V(state.
getPlane()->getV());
1044 TVector3 W(state.
getPlane()->getNormal());
1046 double pw = mom * W;
1047 double pu = mom * U;
1048 double pv = mom * V;
1050 TMatrixDSym& cov(state.
getCov());
1052 cov(0,0) = pow(
getCharge(state), 2) / pow(mom.Mag(), 6) *
1053 (mom.X()*mom.X() * momErr.X()*momErr.X()+
1054 mom.Y()*mom.Y() * momErr.Y()*momErr.Y()+
1055 mom.Z()*mom.Z() * momErr.Z()*momErr.Z());
1057 cov(1,1) = pow((U.X()/pw - W.X()*pu/(pw*pw)),2.) * momErr.X()*momErr.X() +
1058 pow((U.Y()/pw - W.Y()*pu/(pw*pw)),2.) * momErr.Y()*momErr.Y() +
1059 pow((U.Z()/pw - W.Z()*pu/(pw*pw)),2.) * momErr.Z()*momErr.Z();
1061 cov(2,2) = pow((V.X()/pw - W.X()*pv/(pw*pw)),2.) * momErr.X()*momErr.X() +
1062 pow((V.Y()/pw - W.Y()*pv/(pw*pw)),2.) * momErr.Y()*momErr.Y() +
1063 pow((V.Z()/pw - W.Z()*pv/(pw*pw)),2.) * momErr.Z()*momErr.Z();
1065 cov(3,3) = posErr.X()*posErr.X() * U.X()*U.X() +
1066 posErr.Y()*posErr.Y() * U.Y()*U.Y() +
1067 posErr.Z()*posErr.Z() * U.Z()*U.Z();
1069 cov(4,4) = posErr.X()*posErr.X() * V.X()*V.X() +
1070 posErr.Y()*posErr.Y() * V.Y()*V.Y() +
1071 posErr.Z()*posErr.Z() * V.Z()*V.Z();
1080 if (cov6x6.GetNcols()!=6 || cov6x6.GetNrows()!=6){
1081 Exception exc(
"RKTrackRep::setPosMomCov ==> cov has to be 6x6 (x, y, z, px, py, pz)",__LINE__,__FILE__);
1090 const M6x6& cov6x6_( *((
M6x6*) cov6x6.GetMatrixArray()) );
1098 if (state6.GetNrows()!=6){
1099 Exception exc(
"RKTrackRep::setPosMomCov ==> state has to be 6d (x, y, z, px, py, pz)",__LINE__,__FILE__);
1103 if (cov6x6.GetNcols()!=6 || cov6x6.GetNrows()!=6){
1104 Exception exc(
"RKTrackRep::setPosMomCov ==> cov has to be 6x6 (x, y, z, px, py, pz)",__LINE__,__FILE__);
1108 TVector3 pos(state6(0), state6(1), state6(2));
1109 TVector3 mom(state6(3), state6(4), state6(5));
1115 const M6x6& cov6x6_( *((
M6x6*) cov6x6.GetMatrixArray()) );
1125 Exception exc(
"RKTrackRep::setChargeSign - cannot set charge of a MeasurementOnPlane",__LINE__,__FILE__);
1130 if (state.
getState()(0) * charge < 0) {
1148 bool calcOnlyLastRowOfJ)
const {
1151 static const double EC = 0.000149896229;
1152 static const double P3 = 1./3.;
1153 static const double DLT = .0002;
1154 static const double par = 1./3.081615;
1158 double S3(0), S4(0), PS2(0);
1159 M1x3 H0 = {0.,0.,0.}, H1 = {0.,0.,0.}, H2 = {0.,0.,0.};
1160 M1x3 r = {0.,0.,0.};
1162 double A0(0), A1(0), A2(0), A3(0), A4(0), A5(0), A6(0);
1163 double B0(0), B1(0), B2(0), B3(0), B4(0), B5(0), B6(0);
1164 double C0(0), C1(0), C2(0), C3(0), C4(0), C5(0), C6(0);
1171 PS2 = state7[6]*EC * S;
1174 r[0] = R[0]; r[1] = R[1]; r[2]=R[2];
1176 H0[0] *= PS2; H0[1] *= PS2; H0[2] *= PS2;
1177 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];
1178 A2 = A[0]+A0 ; B2 = A[1]+B0 ; C2 = A[2]+C0 ;
1179 A1 = A2+A[0] ; B1 = B2+A[1] ; C1 = C2+A[2] ;
1183 r[0] += A1*S4; r[1] += B1*S4; r[2] += C1*S4;
1185 H1[0] *= PS2; H1[1] *= PS2; H1[2] *= PS2;
1187 else { H1[0] = H0[0]; H1[1] = H0[1]; H1[2] = H0[2]; };
1188 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];
1189 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];
1190 A5 = A4-A[0]+A4 ; B5 = B4-A[1]+B4 ; C5 = C4-A[2]+C4 ;
1194 r[0]=R[0]+S*A4; r[1]=R[1]+S*B4; r[2]=R[2]+S*C4;
1196 H2[0] *= PS2; H2[1] *= PS2; H2[2] *= PS2;
1198 else { H2[0] = H0[0]; H2[1] = H0[1]; H2[2] = H0[2]; };
1199 A6 = B5*H2[2]-C5*H2[1]; B6 = C5*H2[0]-A5*H2[2]; C6 = A5*H2[1]-B5*H2[0];
1205 if(jacobianT != NULL){
1216 double dA0(0), dA2(0), dA3(0), dA4(0), dA5(0), dA6(0);
1217 double dB0(0), dB2(0), dB3(0), dB4(0), dB5(0), dB6(0);
1218 double dC0(0), dC2(0), dC3(0), dC4(0), dC5(0), dC6(0);
1222 if (!calcOnlyLastRowOfJ) {
1226 (*jacobianT)[0] = 1; (*jacobianT)[8] = 1; (*jacobianT)[16] = 1;
1232 for(
int i=start*7; i<42; i+=7) {
1235 dA0 = H0[2]*(*jacobianT)[i+4]-H0[1]*(*jacobianT)[i+5];
1236 dB0 = H0[0]*(*jacobianT)[i+5]-H0[2]*(*jacobianT)[i+3];
1237 dC0 = H0[1]*(*jacobianT)[i+3]-H0[0]*(*jacobianT)[i+4];
1239 dA2 = dA0+(*jacobianT)[i+3];
1240 dB2 = dB0+(*jacobianT)[i+4];
1241 dC2 = dC0+(*jacobianT)[i+5];
1244 dA3 = (*jacobianT)[i+3]+dB2*H1[2]-dC2*H1[1];
1245 dB3 = (*jacobianT)[i+4]+dC2*H1[0]-dA2*H1[2];
1246 dC3 = (*jacobianT)[i+5]+dA2*H1[1]-dB2*H1[0];
1248 dA4 = (*jacobianT)[i+3]+dB3*H1[2]-dC3*H1[1];
1249 dB4 = (*jacobianT)[i+4]+dC3*H1[0]-dA3*H1[2];
1250 dC4 = (*jacobianT)[i+5]+dA3*H1[1]-dB3*H1[0];
1253 dA5 = dA4+dA4-(*jacobianT)[i+3];
1254 dB5 = dB4+dB4-(*jacobianT)[i+4];
1255 dC5 = dC4+dC4-(*jacobianT)[i+5];
1257 dA6 = dB5*H2[2]-dC5*H2[1];
1258 dB6 = dC5*H2[0]-dA5*H2[2];
1259 dC6 = dA5*H2[1]-dB5*H2[0];
1262 (*jacobianT)[i] += (dA2+dA3+dA4)*S3; (*jacobianT)[i+3] = ((dA0+2.*dA3)+(dA5+dA6))*P3;
1263 (*jacobianT)[i+1] += (dB2+dB3+dB4)*S3; (*jacobianT)[i+4] = ((dB0+2.*dB3)+(dB5+dB6))*P3;
1264 (*jacobianT)[i+2] += (dC2+dC3+dC4)*S3; (*jacobianT)[i+5] = ((dC0+2.*dC3)+(dC5+dC6))*P3;
1269 unsigned int i = 42;
1271 (*jacobianT)[i+3] *= state7[6]; (*jacobianT)[i+4] *= state7[6]; (*jacobianT)[i+5] *= state7[6];
1274 dA0 = H0[2]*(*jacobianT)[i+4]-H0[1]*(*jacobianT)[i+5] + A0;
1275 dB0 = H0[0]*(*jacobianT)[i+5]-H0[2]*(*jacobianT)[i+3] + B0;
1276 dC0 = H0[1]*(*jacobianT)[i+3]-H0[0]*(*jacobianT)[i+4] + C0;
1278 dA2 = dA0+(*jacobianT)[i+3];
1279 dB2 = dB0+(*jacobianT)[i+4];
1280 dC2 = dC0+(*jacobianT)[i+5];
1283 dA3 = (*jacobianT)[i+3]+dB2*H1[2]-dC2*H1[1] + (A3-A[0]);
1284 dB3 = (*jacobianT)[i+4]+dC2*H1[0]-dA2*H1[2] + (B3-A[1]);
1285 dC3 = (*jacobianT)[i+5]+dA2*H1[1]-dB2*H1[0] + (C3-A[2]);
1287 dA4 = (*jacobianT)[i+3]+dB3*H1[2]-dC3*H1[1] + (A4-A[0]);
1288 dB4 = (*jacobianT)[i+4]+dC3*H1[0]-dA3*H1[2] + (B4-A[1]);
1289 dC4 = (*jacobianT)[i+5]+dA3*H1[1]-dB3*H1[0] + (C4-A[2]);
1292 dA5 = dA4+dA4-(*jacobianT)[i+3];
1293 dB5 = dB4+dB4-(*jacobianT)[i+4];
1294 dC5 = dC4+dC4-(*jacobianT)[i+5];
1296 dA6 = dB5*H2[2]-dC5*H2[1] + A6;
1297 dB6 = dC5*H2[0]-dA5*H2[2] + B6;
1298 dC6 = dA5*H2[1]-dB5*H2[0] + C6;
1301 (*jacobianT)[i] += (dA2+dA3+dA4)*S3/state7[6]; (*jacobianT)[i+3] = ((dA0+2.*dA3)+(dA5+dA6))*P3/state7[6];
1302 (*jacobianT)[i+1] += (dB2+dB3+dB4)*S3/state7[6]; (*jacobianT)[i+4] = ((dB0+2.*dB3)+(dB5+dB6))*P3/state7[6];
1303 (*jacobianT)[i+2] += (dC2+dC3+dC4)*S3/state7[6]; (*jacobianT)[i+5] = ((dC0+2.*dC3)+(dC5+dC6))*P3/state7[6];
1310 R[0] += (A2+A3+A4)*S3; A[0] += (SA[0]=((A0+2.*A3)+(A5+A6))*P3-A[0]);
1311 R[1] += (B2+B3+B4)*S3; A[1] += (SA[1]=((B0+2.*B3)+(B5+B6))*P3-A[1]);
1312 R[2] += (C2+C3+C4)*S3; A[2] += (SA[2]=((C0+2.*C3)+(C5+C6))*P3-A[2]);
1315 double CBA = 1./sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
1316 A[0] *= CBA; A[1] *= CBA; A[2] *= CBA;
1320 double EST = fabs((A1+A6)-(A3+A4)) +
1321 fabs((B1+B6)-(B3+B4)) +
1322 fabs((C1+C6)-(C3+C4));
1323 if (EST < 1.E-7) EST = 1.E-7;
1325 std::cout <<
" RKTrackRep::RKPropagate. Step = "<< S <<
"; quality EST = " << EST <<
" \n";
1327 return pow(DLT/EST, par);
1335 for (
unsigned int i=0; i<7; ++i)
1337 memset(
J_MMT_, 0x00, 7*7*
sizeof(
double));
1354 Exception exc(
"RKTrackRep::getState7 - cannot get pos or mom from a MeasurementOnPlane",__LINE__,__FILE__);
1359 const TVector3& U(state.
getPlane()->getU());
1360 const TVector3& V(state.
getPlane()->getV());
1361 const TVector3& O(state.
getPlane()->getO());
1362 const TVector3& W(state.
getPlane()->getNormal());
1364 assert(state.
getState().GetNrows() == 5);
1365 const double* state5 = state.
getState().GetMatrixArray();
1367 double spu =
getSpu(state);
1369 state7[0] = O.X() + state5[3]*U.X() + state5[4]*V.X();
1370 state7[1] = O.Y() + state5[3]*U.Y() + state5[4]*V.Y();
1371 state7[2] = O.Z() + state5[3]*U.Z() + state5[4]*V.Z();
1373 state7[3] = spu * (W.X() + state5[1]*U.X() + state5[2]*V.X());
1374 state7[4] = spu * (W.Y() + state5[1]*U.Y() + state5[2]*V.Y());
1375 state7[5] = spu * (W.Z() + state5[1]*U.Z() + state5[2]*V.Z());
1378 double norm = 1. / sqrt(state7[3]*state7[3] + state7[4]*state7[4] + state7[5]*state7[5]);
1379 for (
unsigned int i=3; i<6; ++i) state7[i] *= norm;
1381 state7[6] = state5[0];
1391 const TVector3& O(state.
getPlane()->getO());
1392 const TVector3& U(state.
getPlane()->getU());
1393 const TVector3& V(state.
getPlane()->getV());
1394 const TVector3& W(state.
getPlane()->getNormal());
1396 TVector3 posShift(state7[0], state7[1], state7[2]);
1397 posShift -= state.
getPlane()->getO();
1400 double AtW = state7[3]*W.X() + state7[4]*W.Y() + state7[5]*W.Z();
1407 TVectorD& state5 = state.
getState();
1409 state5(0) = state7[6];
1410 state5(1) = (state7[3]*U.X() + state7[4]*U.Y() + state7[5]*U.Z()) / AtW;
1411 state5(2) = (state7[3]*V.X() + state7[4]*V.Y() + state7[5]*V.Z()) / AtW;
1412 state5(3) = ((state7[0]-O.X())*U.X() +
1413 (state7[1]-O.Y())*U.Y() +
1414 (state7[2]-O.Z())*U.Z());
1415 state5(4) = ((state7[0]-O.X())*V.X() +
1416 (state7[1]-O.Y())*V.Y() +
1417 (state7[2]-O.Z())*V.Z());
1426 M7x7& out7x7)
const {
1429 const TVector3& U(state.
getPlane()->getU());
1430 const TVector3& V(state.
getPlane()->getV());
1431 const TVector3& W(state.
getPlane()->getNormal());
1433 const TVectorD& state5(state.
getState());
1434 double spu(
getSpu(state));
1437 pTilde[0] = spu * (W.X() + state5(1)*U.X() + state5(2)*V.X());
1438 pTilde[1] = spu * (W.Y() + state5(1)*U.Y() + state5(2)*V.Y());
1439 pTilde[2] = spu * (W.Z() + state5(1)*U.Z() + state5(2)*V.Z());
1461 memset(J_pM, 0,
sizeof(
M5x7));
1463 const double pTildeMag = sqrt(pTilde[0]*pTilde[0] + pTilde[1]*pTilde[1] + pTilde[2]*pTilde[2]);
1464 const double pTildeMag2 = pTildeMag*pTildeMag;
1466 const double utpTildeOverpTildeMag2 = (U.X()*pTilde[0] + U.Y()*pTilde[1] + U.Z()*pTilde[2]) / pTildeMag2;
1467 const double vtpTildeOverpTildeMag2 = (V.X()*pTilde[0] + V.Y()*pTilde[1] + V.Z()*pTilde[2]) / pTildeMag2;
1482 double fact = spu / pTildeMag;
1483 J_pM[10] = fact * ( U.X() - pTilde[0]*utpTildeOverpTildeMag2 );
1484 J_pM[11] = fact * ( U.Y() - pTilde[1]*utpTildeOverpTildeMag2 );
1485 J_pM[12] = fact * ( U.Z() - pTilde[2]*utpTildeOverpTildeMag2 );
1487 J_pM[17] = fact * ( V.X() - pTilde[0]*vtpTildeOverpTildeMag2 );
1488 J_pM[18] = fact * ( V.Y() - pTilde[1]*vtpTildeOverpTildeMag2 );
1489 J_pM[19] = fact * ( V.Z() - pTilde[2]*vtpTildeOverpTildeMag2 );
1498 M6x6& out6x6)
const {
1501 const TVector3& U(state.
getPlane()->getU());
1502 const TVector3& V(state.
getPlane()->getV());
1503 const TVector3& W(state.
getPlane()->getNormal());
1505 const TVectorD& state5(state.
getState());
1506 double spu(
getSpu(state));
1509 pTilde[0] = spu * (W.X() + state5(1)*U.X() + state5(2)*V.X());
1510 pTilde[1] = spu * (W.Y() + state5(1)*U.Y() + state5(2)*V.Y());
1511 pTilde[2] = spu * (W.Z() + state5(1)*U.Z() + state5(2)*V.Z());
1513 const double pTildeMag = sqrt(pTilde[0]*pTilde[0] + pTilde[1]*pTilde[1] + pTilde[2]*pTilde[2]);
1514 const double pTildeMag2 = pTildeMag*pTildeMag;
1516 const double utpTildeOverpTildeMag2 = (U.X()*pTilde[0] + U.Y()*pTilde[1] + U.Z()*pTilde[2]) / pTildeMag2;
1517 const double vtpTildeOverpTildeMag2 = (V.X()*pTilde[0] + V.Y()*pTilde[1] + V.Z()*pTilde[2]) / pTildeMag2;
1521 const double qop = state5(0);
1525 memset(J_pM_5x6, 0,
sizeof(
M5x6));
1528 double fact = -1. * p / (pTildeMag * qop);
1529 J_pM_5x6[3] = fact * pTilde[0];
1530 J_pM_5x6[4] = fact * pTilde[1];
1531 J_pM_5x6[5] = fact * pTilde[2];
1533 fact = p * spu / pTildeMag;
1534 J_pM_5x6[9] = fact * ( U.X() - pTilde[0]*utpTildeOverpTildeMag2 );
1535 J_pM_5x6[10] = fact * ( U.Y() - pTilde[1]*utpTildeOverpTildeMag2 );
1536 J_pM_5x6[11] = fact * ( U.Z() - pTilde[2]*utpTildeOverpTildeMag2 );
1538 J_pM_5x6[15] = fact * ( V.X() - pTilde[0]*vtpTildeOverpTildeMag2 );
1539 J_pM_5x6[16] = fact * ( V.Y() - pTilde[1]*vtpTildeOverpTildeMag2 );
1540 J_pM_5x6[17] = fact * ( V.Z() - pTilde[2]*vtpTildeOverpTildeMag2 );
1542 J_pM_5x6[18] = U.X();
1543 J_pM_5x6[19] = U.Y();
1544 J_pM_5x6[20] = U.Z();
1546 J_pM_5x6[24] = V.X();
1547 J_pM_5x6[25] = V.Y();
1548 J_pM_5x6[26] = V.Z();
1564 const TVector3& U(state.
getPlane()->getU());
1565 const TVector3& V(state.
getPlane()->getV());
1566 const TVector3& W(state.
getPlane()->getNormal());
1592 memset(J_Mp, 0,
sizeof(
M7x5));
1594 const double AtU = A[0]*U.X() + A[1]*U.Y() + A[2]*U.Z();
1595 const double AtV = A[0]*V.X() + A[1]*V.Y() + A[2]*V.Z();
1596 const double AtW = A[0]*W.X() + A[1]*W.Y() + A[2]*W.Z();
1601 double fact = 1./(AtW*AtW);
1602 J_Mp[16] = fact * (U.X()*AtW - W.X()*AtU);
1603 J_Mp[21] = fact * (U.Y()*AtW - W.Y()*AtU);
1604 J_Mp[26] = fact * (U.Z()*AtW - W.Z()*AtU);
1606 J_Mp[17] = fact * (V.X()*AtW - W.X()*AtV);
1607 J_Mp[22] = fact * (V.Y()*AtW - W.Y()*AtV);
1608 J_Mp[27] = fact * (V.Z()*AtW - W.Z()*AtV);
1632 const TVector3& U(state.
getPlane()->getU());
1633 const TVector3& V(state.
getPlane()->getV());
1634 const TVector3& W(state.
getPlane()->getNormal());
1636 const double AtU = state7[3]*U.X() + state7[4]*U.Y() + state7[5]*U.Z();
1637 const double AtV = state7[3]*V.X() + state7[4]*V.Y() + state7[5]*V.Z();
1638 const double AtW = state7[3]*W.X() + state7[4]*W.Y() + state7[5]*W.Z();
1642 const double qop = state7[6];
1646 memset(J_Mp_6x5, 0,
sizeof(
M6x5));
1649 J_Mp_6x5[3] = U.X();
1650 J_Mp_6x5[8] = U.Y();
1651 J_Mp_6x5[13] = U.Z();
1653 J_Mp_6x5[4] = V.X();
1654 J_Mp_6x5[9] = V.Y();
1655 J_Mp_6x5[14] = V.Z();
1657 double fact = (-1.) * qop / p;
1658 J_Mp_6x5[15] = fact * state7[3];
1659 J_Mp_6x5[20] = fact * state7[4];
1660 J_Mp_6x5[25] = fact * state7[5];
1662 fact = 1./(p*AtW*AtW);
1663 J_Mp_6x5[16] = fact * (U.X()*AtW - W.X()*AtU);
1664 J_Mp_6x5[21] = fact * (U.Y()*AtW - W.Y()*AtU);
1665 J_Mp_6x5[26] = fact * (U.Z()*AtW - W.Z()*AtU);
1667 J_Mp_6x5[17] = fact * (V.X()*AtW - W.X()*AtV);
1668 J_Mp_6x5[22] = fact * (V.Y()*AtW - W.Y()*AtV);
1669 J_Mp_6x5[27] = fact * (V.Z()*AtW - W.Z()*AtV);
1710 double& coveredDistance,
1712 M7x7& noiseProjection,
1715 bool calcOnlyLastRowOfJ)
const {
1718 static const double Wmax = 6000.;
1719 static const double AngleMax = 6.3;
1720 static const double Pmin = 4.E-3;
1721 static const unsigned int maxNumIt = 1000;
1725 M1x3 SA = {0.,0.,0.};
1727 double momentum = fabs(charge/state7[6]);
1728 double relMomLoss = 0;
1729 double deltaAngle = 0.;
1730 double An(0), S(0), Sl(0), CBA(0);
1734 std::cout <<
"RKTrackRep::RKutta \n";
1735 std::cout <<
"position: "; TVector3(R[0], R[1], R[2]).Print();
1736 std::cout <<
"direction: "; TVector3(A[0], A[1], A[2]).Print();
1737 std::cout <<
"momentum: " << momentum <<
" GeV\n";
1738 std::cout <<
"destination: "; plane.
Print();
1741 checkJacProj =
false;
1744 if(momentum < Pmin){
1745 std::ostringstream sstream;
1746 sstream <<
"RKTrackRep::RKutta ==> momentum too low: " << momentum*1000. <<
" MeV";
1747 Exception exc(sstream.str(),__LINE__,__FILE__);
1755 S =
estimateStep(state7, SU, plane, charge, relMomLoss, limits);
1763 Exception exc(
"RKTrackRep::RKutta ==> maximum number of iterations exceeded",__LINE__,__FILE__);
1769 std::cout <<
"------ RKutta main loop nr. " <<
counter-1 <<
" ------\n";
1772 M1x3 ABefore = { A[0], A[1], A[2] };
1773 RKPropagate(state7, jacobianT, SA, S,
true, calcOnlyLastRowOfJ);
1776 coveredDistance += S;
1781 std::ostringstream sstream;
1782 sstream <<
"RKTrackRep::RKutta ==> Total extrapolation length is longer than length limit : " << Way <<
" cm !";
1783 Exception exc(sstream.str(),__LINE__,__FILE__);
1788 if (onlyOneStep)
return(
true);
1793 std::cout<<
" momLossExceeded -> return(true); \n";
1801 std::cout<<
" at boundary -> return(true); \n";
1813 S =
estimateStep(state7, SU, plane, charge, relMomLoss, limits);
1818 std::cout<<
" (at Plane && fabs(S) < MINSTEP) -> break and do linear extrapolation \n";
1825 std::cout<<
" (momLossExceeded && fabs(S) < MINSTEP) -> return(true), no linear extrapolation; \n";
1833 deltaAngle += acos(ABefore[0]*A[0] + ABefore[1]*A[1] + ABefore[2]*A[2]);
1834 if (fabs(deltaAngle) > AngleMax){
1835 std::ostringstream sstream;
1836 sstream <<
"RKTrackRep::RKutta ==> Do not get to an active plane! Already extrapolated " << deltaAngle * 180 / TMath::Pi() <<
"°.";
1837 Exception exc(sstream.str(),__LINE__,__FILE__);
1847 Exception exc(
"RKTrackRep::RKutta ==> Do not get closer to plane!",__LINE__,__FILE__);
1861 if (fabs(Sl) > 0.001*
MINSTEP){
1863 std::cout <<
" RKutta - linear extrapolation to surface\n";
1868 SA[0]*=Sl; SA[1]*=Sl; SA[2]*=Sl;
1876 CBA = 1./sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
1877 A[0] *= CBA; A[1] *= CBA; A[2] *= CBA;
1879 R[0] += S*(A[0]-0.5*S*SA[0]);
1880 R[1] += S*(A[1]-0.5*S*SA[1]);
1881 R[2] += S*(A[2]-0.5*S*SA[2]);
1884 coveredDistance += S;
1888 std::cout <<
" RKutta - last stepsize too small -> can't do linear extrapolation! \n";
1894 if (jacobianT != NULL) {
1905 if (checkJacProj &&
RKSteps_.size()>0){
1906 Exception exc(
"RKTrackRep::Extrap ==> covariance is projected onto destination plane again",__LINE__,__FILE__);
1913 std::cout <<
" Project Jacobian of extrapolation onto destination plane\n";
1915 An = A[0]*SU[0] + A[1]*SU[1] + A[2]*SU[2];
1916 An = (fabs(An) > 1.E-7 ? 1./An : 0);
1919 if (calcOnlyLastRowOfJ)
1923 double* jacPtr = *jacobianT;
1924 norm = (jacPtr[i]*SU[0] + jacPtr[i+1]*SU[1] + jacPtr[i+2]*SU[2]) * An;
1925 jacPtr[i] -= norm*A [0]; jacPtr[i+1] -= norm*A [1]; jacPtr[i+2] -= norm*A [2];
1926 jacPtr[i+3] -= norm*SA[0]; jacPtr[i+4] -= norm*SA[1]; jacPtr[i+5] -= norm*SA[2];
1928 checkJacProj =
true;
1936 if (!calcOnlyLastRowOfJ) {
1937 for (
int iRow = 0; iRow < 3; ++iRow) {
1938 for (
int iCol = 0; iCol < 3; ++iCol) {
1939 noiseProjection[iRow*7 + iCol] = (iRow == iCol) - An * SU[iCol] * A[iRow];
1940 noiseProjection[(iRow + 3)*7 + iCol] = - An * SU[iCol] * SA[iRow];
1966 const double& charge,
1982 std::cout <<
" RKTrackRep::estimateStep: use stepSize " <<
cachePos_ <<
" from cache: " <<
RKSteps_.at(
cachePos_).matStep_.stepSize_ <<
"\n";
1995 std::cout <<
" RKTrackRep::estimateStep \n";
1996 std::cout <<
" position: "; TVector3(state7[0], state7[1], state7[2]).Print();
1997 std::cout <<
" direction: "; TVector3(state7[3], state7[4], state7[5]).Print();
2001 double Dist = SU[3] - (state7[0]*SU[0] +
2004 double An = state7[3]*SU[0] +
2009 if (fabs(An) > 1.E-10)
2012 SLDist = Dist*1.E10;
2013 if (An<0) SLDist *= -1.;
2020 std::cout <<
" Distance to plane: " << Dist <<
"\n";
2021 std::cout <<
" SL distance to plane: " << SLDist <<
"\n";
2023 std::cout <<
" Direction is pointing towards surface.\n";
2025 std::cout <<
" Direction is pointing away from surface.\n";
2034 std::pair<double, double> distVsStep (9.E99, 9.E99);
2036 static const unsigned int maxNumIt = 10;
2039 while (fabs(fieldCurvLimit) >
MINSTEP) {
2045 fieldCurvLimit *= 0.5;
2049 M1x7 state7_temp = { state7[0], state7[1], state7[2], state7[3], state7[4], state7[5], state7[6] };
2052 double q =
RKPropagate(state7_temp, NULL, SA, fieldCurvLimit,
true);
2054 std::cout <<
" maxStepArg = " << fieldCurvLimit <<
"; q = " << q <<
" \n";
2059 Dist = SU[3] - (state7_temp[0] * SU[0] +
2060 state7_temp[1] * SU[1] +
2061 state7_temp[2] * SU[2]);
2063 An = state7_temp[3] * SU[0] +
2064 state7_temp[4] * SU[1] +
2065 state7_temp[5] * SU[2];
2067 if (fabs(Dist/An) < fabs(distVsStep.first)) {
2068 distVsStep.first = Dist/An;
2069 distVsStep.second = fieldCurvLimit;
2076 fieldCurvLimit *= 2;
2080 fieldCurvLimit *= q * 0.95;
2082 if (fabs(q-1) < 0.25 ||
2086 if (fabs(fieldCurvLimit) <
MINSTEP)
2092 if (fabs(distVsStep.first) < 8.E99) {
2093 stepToPlane = distVsStep.first + distVsStep.second;
2104 std::cout <<
" auto select direction";
2105 if (!plane.
isFinite()) std::cout <<
", plane is not finite";
2112 std::cout <<
" straight line approximation is fine.\n";
2116 if( plane.
isInActive(state7[0], state7[1], state7[2], state7[3], state7[4], state7[5]) ) {
2118 std::cout <<
" direction is pointing to active part of surface. \n";
2126 std::cout <<
" we are near the plane, but not pointing to the active area. make a big step! \n";
2136 std::cout <<
" invert Step according to propDir_ and make a big step. \n";
2143 static const RKStep defaultRKStep;
2144 RKSteps_.push_back( defaultRKStep );
2145 std::vector<RKStep>::iterator lastStep =
RKSteps_.end() - 1;
2147 for(
int n = 0; n < 1*7; ++n) lastStep->
state7_[n] = state7[n];
2152 M1x7 state7_temp = { state7[0], state7[1], state7[2], state7[3], state7[4], state7[5], state7[6] };
2159 lastStep->matStep_.materialProperties_,
2165 lastStep->matStep_.materialProperties_ = (lastStep - 1)->matStep_.materialProperties_;
2171 std::cout <<
" final limits:\n";
2177 lastStep->matStep_.stepSize_ = finalStep;
2178 lastStep->limits_ = limits;
2181 std::cout <<
" --> Step to be used: " << finalStep <<
"\n";
2191 TVector3 retVal(lineDirection);
2193 double t = 1./(retVal.Mag2()) * ((point*retVal) - (linePoint*retVal));
2195 retVal += linePoint;
2206 bool fillExtrapSteps,
2209 bool stopAtBoundary,
2210 double maxStep)
const {
2212 static const unsigned int maxNumIt(500);
2213 unsigned int numIt(0);
2215 double coveredDistance(0.);
2218 const TVector3 W(destPlane.
getNormal());
2219 M1x4 SU = {W.X(), W.Y(), W.Z(), destPlane.
distance(0., 0., 0.)};
2222 if (W*destPlane.
getO() < 0) {
2230 memcpy(startState7, state7,
sizeof(
M1x7));
2235 std::cout <<
"\n============ RKTrackRep::Extrap loop nr. " << numIt <<
" ============\n";
2236 std::cout <<
"Start plane: "; startPlane.
Print();
2237 std::cout <<
"fillExtrapSteps " << fillExtrapSteps <<
"\n";
2240 if(++numIt > maxNumIt){
2241 Exception exc(
"RKTrackRep::Extrap ==> maximum number of iterations exceeded",__LINE__,__FILE__);
2247 for(
int i = 0; i < 7*7; ++i)
J_MMT_[i] = 0;
2248 for(
int i=0; i<7; ++i)
J_MMT_[8*i] = 1.;
2251 isAtBoundary =
false;
2255 memcpy(oldState7, state7,
sizeof(
M1x7));
2258 bool checkJacProj =
false;
2264 limits_, onlyOneStep, !fillExtrapSteps) ) {
2265 Exception exc(
"RKTrackRep::Extrap ==> Runge Kutta propagation failed",__LINE__,__FILE__);
2272 isAtBoundary =
true;
2276 std::cout<<
"RKSteps \n";
2277 for (std::vector<RKStep>::iterator it =
RKSteps_.begin(); it !=
RKSteps_.end(); ++it){
2278 std::cout <<
"stepSize = " << it->matStep_.stepSize_ <<
"\t";
2279 it->matStep_.materialProperties_.Print();
2287 if(fillExtrapSteps) {
2298 fabs(charge/state7[6]),
2305 std::cout <<
"momLoss: " << momLoss <<
" GeV; relative: " << momLoss/fabs(charge/state7[6]) <<
"\n";
2307 std::cout <<
"7D noise: \n";
2313 if(fabs(state7[6])>1.E-10) {
2314 double qop = charge/(fabs(charge/state7[6])-momLoss);
2315 dqop = qop - state7[6];
2320 std::cout <<
"correct state7 with dx/dqop, dy/dqop ...\n";
2322 for (
unsigned int i=0; i<6; ++i) {
2323 state7[i] += 0.5 * dqop *
J_MMT_[6*7 + i];
2330 if (fillExtrapSteps) {
2333 std::vector<ExtrapStep>::iterator lastStep =
ExtrapSteps_.end() - 1;
2336 memcpy(lastStep->jac7_,
J_MMT_,
sizeof(
M7x7));
2338 if( checkJacProj ==
true ){
2343 std::cout <<
"7D noise projected onto plane: \n";
2352 std::cout<<
"ExtrapSteps \n";
2364 if (stopAtBoundary) {
2366 std::cout <<
"stopAtBoundary -> break; \n ";
2373 std::cout <<
"onlyOneStep -> break; \n ";
2381 std::cout <<
"arrived at destPlane with a distance of " << destPlane.
distance(state7[0], state7[1], state7[2]) <<
" cm left. ";
2382 if (destPlane.
isInActive(state7[0], state7[1], state7[2], state7[3], state7[4], state7[5]))
2383 std::cout <<
"In active area of destPlane. \n";
2385 std::cout <<
"NOT in active area of plane. \n";
2392 if (fillExtrapSteps) {
2403 std::cout <<
"final covariance matrix after Extrap: "; cov->Print();
2408 return coveredDistance;
2414 if (state.
getRep() !=
this){
2415 Exception exc(
"RKTrackRep::checkCache ==> state is defined wrt. another TrackRep",__LINE__,__FILE__);
2421 Exception exc(
"RKTrackRep::checkCache - cannot extrapolate MeasurementOnPlane",__LINE__,__FILE__);
2433 if (plane != NULL &&
2442 double firstStep(0);
2443 for (
unsigned int i=0; i<
RKSteps_.size(); ++i) {
2445 firstStep =
RKSteps_.at(0).matStep_.stepSize_;
2448 if (
RKSteps_.at(i).matStep_.stepSize_ * firstStep < 0) {
2449 if (
RKSteps_.at(i-1).matStep_.materialProperties_ ==
RKSteps_.at(i).matStep_.materialProperties_) {
2457 std::cout <<
"RKTrackRep::checkCache: use cached material and step values.\n";
2463 std::cout <<
"RKTrackRep::checkCache: can NOT use cached material and step values.\n";
2465 if (plane != NULL) {
2467 std::cout <<
"state.getPlane() != lastStartState_.getPlane()\n";
2471 std::cout <<
"state.getState() != lastStartState_.getState()\n";
2489 double momMag2 = state7[3]*state7[3] + state7[4]*state7[4] + state7[5]*state7[5];
2490 return sqrt(momMag2);
2495 if (
dynamic_cast<const RKTrackRep*
>(other) == NULL)
2510void RKTrackRep::Streamer(TBuffer &R__b)
2517 if (R__b.IsReading()) {
2518 ::genfit::AbsTrackRep::Streamer(R__b);
2519 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v) { }
2520 R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
2524 ::genfit::AbsTrackRep::Streamer(R__b);
2525 R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
2526 R__b.SetByteCount(R__c, kTRUE);
Abstract base class for a track representation.
int pdgCode_
Particle code.
int getPDG() const
Get the pdg code.
double getMass(const StateOnPlane &state) const
Get tha particle mass in GeV/c^2.
double getPDGCharge() const
Get the charge of the particle of the pdg code.
char propDir_
propagation direction (-1, 0, 1) -> (backward, auto, forward)
TVector3 getNormal() const
const TVector3 & getU() const
double distance(const TVector3 &point) const
absolute distance from a point to the plane
const TVector3 & getO() const
void Print(const Option_t *="") const
void setU(const TVector3 &u)
bool isInActive(const TVector3 &point, const TVector3 &dir) const
intersect in the active area? C.f. AbsFinitePlane
const TVector3 & getV() const
void setNormal(const TVector3 &n)
Exception class for error handling in GENFIT (provides storage for diagnostic information)
void setFatal(bool b=true)
Set fatal flag.
TVector3 getFieldVal(const TVector3 &position)
This does NOT use the cache!
static FieldManager * getInstance()
Get singleton instance.
static MaterialEffects * getInstance()
double effects(const std::vector< genfit::RKStep > &steps, int materialsFXStart, int materialsFXStop, const double &mom, const int &pdg, M7x7 *noise=nullptr)
Calculates energy loss in the traveled path, optional calculation of noise matrix.
void stepper(const RKTrackRep *rep, M1x7 &state7, const double &mom, double &relMomLoss, const int &pdg, MaterialProperties ¤tMaterial, StepLimits &limits, bool varField=true)
Returns maximum length so that a specified momentum loss will not be exceeded.
StateOnPlane with additional covariance matrix.
const TMatrixDSym & getCov() const
Measured coordinates on a plane.
AbsTrackRep with 5D track parameterization in plane coordinates: (q/p, u', v', u, v)
virtual TVector3 getMom(const StateOnPlane &state) const
Get the cartesian momentum vector of a state.
std::vector< RKStep > RKSteps_
state where the last extrapolation has ended
virtual void setPosMomErr(MeasuredStateOnPlane &state, const TVector3 &pos, const TVector3 &mom, const TVector3 &posErr, const TVector3 &momErr) const
Set position and momentum and error of state.
void calcJ_Mp_7x5(M7x5 &J_Mp, const TVector3 &U, const TVector3 &V, const TVector3 &W, const M1x3 &A) const
std::vector< ExtrapStep > ExtrapSteps_
double getSpu(const StateOnPlane &state) const
virtual void getBackwardJacobianAndNoise(TMatrixD &jacobian, TMatrixDSym &noise, TVectorD &deltaState) const
Get the jacobian and noise matrix of the last extrapolation if it would have been done in opposite di...
M7x7 noiseProjection_
noise matrix of the last extrapolation
virtual void setChargeSign(StateOnPlane &state, double charge) const
Set the sign of the charge according to charge.
int RKStepsFXStart_
RungeKutta steps made in the last extrapolation.
double estimateStep(const M1x7 &state7, const M1x4 &SU, const DetPlane &plane, const double &charge, double &relMomLoss, StepLimits &limits) const
void setSpu(StateOnPlane &state, double spu) const
virtual double getCharge(const StateOnPlane &state) const
Get the (fitted) charge of a state. This is not always equal the pdg charge (e.g. if the charge sign ...
virtual void getPosMom(const StateOnPlane &state, TVector3 &pos, TVector3 &mom) const
Get cartesian position and momentum vector of a state.
void calcForwardJacobianAndNoise(const M1x7 &startState7, const DetPlane &startPlane, const M1x7 &destState7, const DetPlane &destPlane) const
double Extrap(const DetPlane &startPlane, const DetPlane &destPlane, double charge, bool &isAtBoundary, M1x7 &state7, bool fillExtrapSteps, TMatrixDSym *cov=nullptr, bool onlyOneStep=false, bool stopAtBoundary=false, double maxStep=1.E99) const
Handles propagation and material effects.
bool RKutta(const M1x4 &SU, const DetPlane &plane, double charge, M1x7 &state7, M7x7 *jacobianT, double &coveredDistance, bool &checkJacProj, M7x7 &noiseProjection, StepLimits &limits, bool onlyOneStep=false, bool calcOnlyLastRowOfJ=false) const
Propagates the particle through the magnetic field.
double momMag(const M1x7 &state7) const
virtual double extrapolateToSphere(StateOnPlane &state, double radius, const TVector3 &point=TVector3(0., 0., 0.), bool stopAtBoundary=false, bool calcJacobianNoise=false) const
Extrapolates the state to the sphere surface, and returns the extrapolation length and,...
void transformPM7(const MeasuredStateOnPlane &state, M7x7 &out7x7) const
virtual TMatrixDSym get6DCov(const MeasuredStateOnPlane &state) const
Get the 6D covariance.
void getState7(const StateOnPlane &state, M1x7 &state7) const
void transformM7P(const M7x7 &in7x7, const M1x7 &state7, MeasuredStateOnPlane &state) const
virtual double extrapolateBy(StateOnPlane &state, double step, bool stopAtBoundary=false, bool calcJacobianNoise=false) const
Extrapolates the state by step (cm) and returns the extrapolation length and, via reference,...
std::vector< genfit::MatStep > getSteps() const
Get stepsizes and material properties of crossed materials of the last extrapolation.
virtual double extrapToPoint(StateOnPlane &state, const TVector3 &point, const TMatrixDSym *G=NULL, bool stopAtBoundary=false, bool calcJacobianNoise=false) const
virtual void setPosMom(StateOnPlane &state, const TVector3 &pos, const TVector3 &mom) const
Set position and momentum of state.
virtual double getTOF() const
Get the time of flight [ns] of the last extrapolation.
virtual double extrapolateToCylinder(StateOnPlane &state, double radius, const TVector3 &linePoint=TVector3(0., 0., 0.), const TVector3 &lineDirection=TVector3(0., 0., 1.), bool stopAtBoundary=false, bool calcJacobianNoise=false) const
Extrapolates the state to the cylinder surface, and returns the extrapolation length and,...
void transformPM6(const MeasuredStateOnPlane &state, M6x6 &out6x6) const
void checkCache(const StateOnPlane &state, const SharedPlanePtr *plane) const
virtual void setPosMomCov(MeasuredStateOnPlane &state, const TVector3 &pos, const TVector3 &mom, const TMatrixDSym &cov6x6) const
Set position, momentum and covariance of state.
StateOnPlane lastStartState_
virtual bool isSame(const AbsTrackRep *other)
check if other is of same type (e.g. RKTrackRep) and has same pdg code.
virtual void getForwardJacobianAndNoise(TMatrixD &jacobian, TMatrixDSym &noise, TVectorD &deltaState) const
Get the jacobian and noise matrix of the last extrapolation.
SharedPlanePtr makePlane(const TVector3 &o, const TVector3 &u, const TVector3 &v)
virtual double getRadiationLenght() const
Get the accumulated X/X0 (path / radiation length) of the material crossed in the last extrapolation.
TMatrixD fJacobian_
steps made in Extrap during last extrapolation
virtual double getMomVar(const MeasuredStateOnPlane &state) const
get the variance of the absolute value of the momentum .
unsigned int cachePos_
use cached RKSteps_ for extrapolation
void calcJ_pM_5x7(M5x7 &J_pM, const TVector3 &U, const TVector3 &V, const M1x3 &pTilde, double spu) const
virtual double getMomMag(const StateOnPlane &state) const
get the magnitude of the momentum in GeV.
void getState5(StateOnPlane &state, const M1x7 &state7) const
virtual void getPosMomCov(const MeasuredStateOnPlane &state, TVector3 &pos, TVector3 &mom, TMatrixDSym &cov) const
Translates MeasuredStateOnPlane into 3D position, momentum and 6x6 covariance.
TVector3 pocaOnLine(const TVector3 &linePoint, const TVector3 &lineDirection, const TVector3 &point) const
virtual double extrapolateToPlane(StateOnPlane &state, const SharedPlanePtr &plane, bool stopAtBoundary=false, bool calcJacobianNoise=false) const
Extrapolates the state to plane, and returns the extrapolation length and, via reference,...
virtual TVector3 getPos(const StateOnPlane &state) const
Get the cartesian position of a state.
void transformM6P(const M6x6 &in6x6, const M1x7 &state7, MeasuredStateOnPlane &state) const
StateOnPlane lastEndState_
state where the last extrapolation has started
virtual bool isSameType(const AbsTrackRep *other)
check if other is of same type (e.g. RKTrackRep).
virtual double extrapolateToLine(StateOnPlane &state, const TVector3 &linePoint, const TVector3 &lineDirection, bool stopAtBoundary=false, bool calcJacobianNoise=false) const
Extrapolates the state to the POCA to a line, and returns the extrapolation length and,...
double RKPropagate(M1x7 &state7, M7x7 *jacobian, M1x3 &SA, double S, bool varField=true, bool calcOnlyLastRowOfJ=false) const
The actual Runge Kutta propagation.
A state with arbitrary dimension defined in a DetPlane.
void setPlane(const SharedPlanePtr &plane)
const TVectorD & getState() const
void setRep(const AbsTrackRep *rep)
void setStatePlane(const TVectorD &state, const SharedPlanePtr &plane)
const AbsTrackRep * getRep() const
const TVectorD & getAuxInfo() const
const SharedPlanePtr & getPlane() const
Helper to store different limits on the stepsize for the RKTRackRep.
void setLimit(StepLimitType type, double value)
absolute of value will be taken! If limit is already lower, it will be set to value anyway.
std::pair< StepLimitType, double > getLowestLimit(double margin=1.E-3) const
Get the lowest limit.
double getLowestLimitSignedVal(double margin=1.E-3) const
Get the numerical value of the lowest limit, signed with stepSign_.
std::vector< double > limits_
double getLimit(StepLimitType type) const
Get limit of type. If that limit has not yet been set, return max double value.
void setStepSign(char signedVal)
sets stepSign_ to sign of signedVal
double getLimitSigned(StepLimitType type) const
void removeLimit(StepLimitType type)
double getLowestLimitVal(double margin=1.E-3) const
Get the unsigned numerical value of the lowest limit.
boost::shared_ptr< genfit::DetPlane > SharedPlanePtr
Shared Pointer to a DetPlane.