118 std::pair<TrajectoryStateOnSurface, double>
120 const Plane& pDest)
const {
129 std::pair<TrajectoryStateOnSurface, double>
141 std::pair<FreeTrajectoryState, double>
154 std::pair<FreeTrajectoryState, double>
158 if ((pDest1-pDest2).
mag() < 1
e-10){
160 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: the points should be at a bigger distance"
176 std::pair<FreeTrajectoryState, double>
181 pDest1.y() + beamSpot.
dydz()*1e3,
192 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
198 const Plane* pDest =
dynamic_cast<const Plane*
>(&sDest);
199 if (pDest != 0)
return propagate(sStart, *pDest);
202 if (cDest != 0)
return propagate(sStart, *cDest);
210 const Plane& pDest)
const {
214 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
224 double pars[6] = { rPlane.x(), rPlane.y(), rPlane.z(),
225 nPlane.x(), nPlane.y(), nPlane.z() };
244 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
251 double pars[6] = {0,0,0,0,0,0};
272 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
279 double pars[6] = {pDest.
x(), pDest.
y(), pDest.
z(), 0, 0, 0};
291 if ((pDest1-pDest2).
mag() < 1
e-10 || !sStart.
isValid()){
293 if ((pDest1-pDest2).mag() < 1
e-10)
294 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: points are too close"
297 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
304 double pars[6] = {pDest1.
x(), pDest1.
y(), pDest1.
z(),
305 pDest2.
x(), pDest2.
y(), pDest2.
z()};
328 const double pars[6],
double epsilon)
const{
330 static const std::string
metname =
"SteppingHelixPropagator";
345 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Failed after first refToDest check with status "
353 bool makeNextStep =
true;
360 double distMag = 1e12;
361 double tanDistMag = 1e12;
363 double distMat = 1e12;
364 double tanDistMat = 1e12;
366 double tanDistNextCheck = -0.1;
367 double tanDistMagNextCheck = -0.1;
368 double tanDistMatNextCheck = -0.1;
375 bool isFirstStep =
true;
376 bool expectNewMagVolume =
false;
379 while (makeNextStep){
382 double curZ = svCurrent->
r3.z();
383 double curR = svCurrent->
r3.perp();
384 if ( fabs(curZ) < 440 && curR < 260) dStep =
defaultStep_*2;
390 if (!
useIsYokeFlag_ && fabs(curZ) < 667 && curR > 380 && curR < 850){
391 dStep = 5*(1+0.2*svCurrent->
p3.mag());
397 tanDistNextCheck -= oldDStep;
398 tanDistMagNextCheck -= oldDStep;
399 tanDistMatNextCheck -= oldDStep;
401 if (tanDistNextCheck < 0){
403 if (! isFirstStep)
refToDest(type, (*svCurrent), pars, dist, tanDist, refDirection);
405 if (fabs(tanDist) > 4.*(fabs(dist)) ) tanDist *= tanDist == 0 ? 0 :fabs(dist/tanDist*4.);
407 tanDistNextCheck = fabs(tanDist)*0.5 - 0.5;
410 oldRefDirection = refDirection;
412 tanDist = tanDist > 0. ? tanDist - oldDStep : tanDist + oldDStep;
413 refDirection = oldRefDirection;
414 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Skipped refToDest: guess tanDist = "<<tanDist
415 <<
" next check at "<<tanDistNextCheck<<std::endl;
418 double fastSkipDist = fabs(dist) > fabs(tanDist) ? tanDist : dist;
424 if (fabs(tanDist)<0.1 && refDirection != dir ){
427 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"NOTE: overstepped last time: switch direction (can do it if within 1 mm)"<<std::endl;
432 if (tanDistMagNextCheck < 0){
433 resultToMag =
refToMagVolume((*svCurrent), dir, distMag, tanDistMag, fabs(fastSkipDist), expectNewMagVolume, fabs(tanDist));
435 if (fabs(tanDistMag) > 4.*(fabs(distMag)) ) tanDistMag *= tanDistMag == 0 ? 0 : fabs(distMag/tanDistMag*4.);
437 tanDistMagNextCheck = fabs(tanDistMag)*0.5-0.5;
440 || fabs(dist) < fabs(distMag)
447 tanDistMag = tanDistMag > 0. ? tanDistMag - oldDStep : tanDistMag + oldDStep;
448 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Skipped refToMag: guess tanDistMag = "<<tanDistMag
449 <<
" next check at "<<tanDistMagNextCheck;
454 if (tanDistMatNextCheck < 0){
455 resultToMat =
refToMatVolume((*svCurrent), dir, distMat, tanDistMat, fabs(fastSkipDist));
457 if (fabs(tanDistMat) > 4.*(fabs(distMat)) ) tanDistMat *= tanDistMat == 0 ? 0 : fabs(distMat/tanDistMat*4.);
459 tanDistMatNextCheck = fabs(tanDistMat)*0.5-0.5;
462 || fabs(dist) < fabs(distMat)
469 tanDistMat = tanDistMat > 0. ? tanDistMat - oldDStep : tanDistMat + oldDStep;
470 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Skipped refToMat: guess tanDistMat = "<<tanDistMat
471 <<
" next check at "<<tanDistMatNextCheck;
475 double rDotP = svCurrent->
r3.dot(svCurrent->
p3);
476 if ((fabs(curZ) > 1.5e3 || curR >800.)
480 dStep = fabs(tanDist) -1
e-12;
482 double tanDistMin = fabs(tanDist);
483 if (tanDistMin > fabs(tanDistMag)+0.05 &&
485 tanDistMin = fabs(tanDistMag)+0.05;
486 expectNewMagVolume =
true;
487 }
else expectNewMagVolume =
false;
490 tanDistMin = fabs(tanDistMat)+0.05;
491 if (expectNewMagVolume) expectNewMagVolume =
false;
494 if (tanDistMin*fabs(svCurrent->
dEdx) > 0.5*svCurrent->
p3.mag()){
495 tanDistMin = 0.5*svCurrent->
p3.mag()/fabs(svCurrent->
dEdx);
496 if (expectNewMagVolume) expectNewMagVolume =
false;
501 double tanDistMinLazy = fabs(tanDistMin);
503 && fabs(tanDist) < 2.*fabs(tanDistMin) ){
505 tanDistMinLazy = fabs(tanDistMin)*0.5;
508 if (fabs(tanDistMinLazy) < dStep){
509 dStep = fabs(tanDistMinLazy);
515 if (dStep > 1
e-10 && ! (fabs(dist) < fabs(epsilon))){
533 tanDistNextCheck = -1;
534 tanDistMagNextCheck = -1;
535 tanDistMatNextCheck = -1;
540 if (nOsc>1 && fabs(dStep)>epsilon){
541 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Ooops"<<std::endl;
547 && fabs(dStep) < fabs(epsilon) ){
550 double nextTanDist = 0;
555 refToDest(type, (*svCurrent), pars, nextDist, nextTanDist, nextRefDirection);
556 if ( fabs(nextDist) > fabs(dist)){
560 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Found real local minimum in PCA"<<std::endl;
566 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Found branch point in PCA"<<std::endl;
576 curZ = svCurrent->
r3.z();
577 curR = svCurrent->
r3.perp();
590 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Propagation failed with status "
594 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Momentum at last point is too low (<0.1) p_last = "
595 <<svCurrent->
p3.mag()
598 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Went too far: the last point is at "<<svCurrent->
r3
601 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Infinite loop condidtion detected: going in cycles. Break after 6 cycles"
604 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Tired to go farther. Made too many steps: more than "
613 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to radius "<<pars[
RADIUS_P]<<std::endl;
616 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to z "<<pars[
Z_P]<<std::endl;
619 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to pathL "<<pars[
PATHL_P]<<std::endl;
623 Point rPlane(pars[0], pars[1], pars[2]);
624 Vector nPlane(pars[3], pars[4], pars[5]);
625 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to plane r0:"<<rPlane<<
" n:"<<nPlane<<std::endl;
630 Point rDest(pars[0], pars[1], pars[2]);
631 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to PCA to point "<<rDest<<std::endl;
636 Point rDest1(pars[0], pars[1], pars[2]);
637 Point rDest2(pars[3], pars[4], pars[5]);
638 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to PCA to line "<<rDest1<<
" - "<<rDest2<<std::endl;
642 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to NOT IMPLEMENTED"<<std::endl;
645 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Made "<<
nPoints_-1<<
" steps and stopped at(cur step) "<<svCurrent->
r3<<
" nOsc "<<nOsc<<std::endl;
656 static const std::string
metname =
"SteppingHelixPropagator";
666 GlobalPoint gPointNegZ(svCurrent.
r3.x(), svCurrent.
r3.y(), -fabs(svCurrent.
r3.z()));
669 float gpmag = gPointNegZ.
mag2();
670 float pmag2 = p3.mag2();
671 if (gpmag > 1e20f ) {
672 LogTrace(metname)<<
"Initial point is too far";
676 if (! (gpmag == gpmag) ) {
677 LogTrace(metname)<<
"Initial point is a nan";
678 edm::LogWarning(
"SteppingHelixPropagatorNAN")<<
"Initial point is a nan";
682 if (! (pmag2 == pmag2) ) {
683 LogTrace(metname)<<
"Initial momentum is a nan";
684 edm::LogWarning(
"SteppingHelixPropagatorNAN")<<
"Initial momentum is a nan";
699 double curRad = svCurrent.
r3.perp();
700 if (curRad > 380 && curRad < 850 && fabs(svCurrent.
r3.z()) < 667){
707 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Failed to cast into VolumeBasedMagneticField: fall back to the default behavior"<<std::endl;
711 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got volume at "<<svCurrent.
magVol<<std::endl;
719 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Loaded bfield float: "<<bf
720 <<
" at global float "<< gPointNegZ<<
" double "<< svCurrent.
r3<<std::endl;
723 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"\t cf in local locF: "<<lbf<<
" at "<<lPoint<<std::endl;
728 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Loaded bfield float: "<<bf
729 <<
" at global float "<< gPointNorZ<<
" double "<< svCurrent.
r3<<std::endl;
732 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"\t cf in local locF: "<<lbf<<
" at "<<lPoint<<std::endl;
736 svCurrent.
bf.set(-bf.
x(), -bf.
y(), bf.
z());
738 svCurrent.
bf.set(bf.
x(), bf.
y(), bf.
z());
743 svCurrent.
bf.set(bf.x(), bf.y(), bf.z());
745 if (svCurrent.
bf.mag2() < 1
e-32) svCurrent.
bf.set(0., 0., 1
e-16);
747 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific
748 <<
"Loaded bfield double: "<<svCurrent.
bf<<
" from float: "<<bf
749 <<
" at float "<< gPointNorZ<<
" "<<gPointNegZ<<
" double "<< svCurrent.
r3<<std::endl;
754 double dEdXPrime = 0;
758 dEdx =
getDeDx(svCurrent, dEdXPrime, radX0, rzLims);
760 svCurrent.
radX0 = radX0;
761 svCurrent.
rzLims = rzLims;
769 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Loaded at path: "<<svCurrent.
path()<<
" radPath: "<<svCurrent.
radPath()
770 <<
" p3 "<<
" pt: "<<svCurrent.
p3.perp()<<
" phi: "<<svCurrent.
p3.phi()
771 <<
" eta: "<<svCurrent.
p3.eta()
773 <<
" r3: "<<svCurrent.
r3
774 <<
" bField: "<<svCurrent.
bf.mag()
776 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Input Covariance in Curvilinear RF "<<covCurv<<std::endl;
785 static const std::string
metname =
"SteppingHelixPropagator";
786 svNext.
q = svPrevious.
q;
787 svNext.
dir = dS > 0.0 ? 1.: -1.;
788 svNext.
p3 =
tau; svNext.
p3*=(svPrevious.
p3.mag() - svNext.
dir*fabs(dP));
790 svNext.
r3 = svPrevious.
r3; svNext.
r3 += drVec;
808 double curRad = svNext.
r3.perp();
809 if (curRad > 380 && curRad < 850 && fabs(svNext.
r3.z()) < 667){
816 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Failed to cast into VolumeBasedMagneticField"<<std::endl;
820 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got volume at "<<svNext.
magVol<<std::endl;
831 svNext.
bf.set(-bf.x(), -bf.y(), bf.z());
833 svNext.
bf.set(bf.x(), bf.y(), bf.z());
838 svNext.
bf.set(bf.x(), bf.y(), bf.z());
840 if (svNext.
bf.mag2() < 1
e-32) svNext.
bf.set(0., 0., 1
e-16);
843 double dEdXPrime = 0;
847 dEdx =
getDeDx(svNext, dEdXPrime, radX0, rzLims);
849 svNext.
radX0 = radX0;
857 ROOT::Math::AssignSym::Evaluate(svNext.
covCurv, tmp*ROOT::Math::Transpose(dCovCurvTransform));
867 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Now at path: "<<svNext.
path()<<
" radPath: "<<svNext.
radPath()
868 <<
" p3 "<<
" pt: "<<svNext.
p3.perp()<<
" phi: "<<svNext.
p3.phi()
869 <<
" eta: "<<svNext.
p3.eta()
872 <<
" dPhi: "<<acos(svNext.
p3.unit().dot(svPrevious.
p3.unit()))
873 <<
" bField: "<<svNext.
bf.mag()
874 <<
" dedx: "<<svNext.
dEdx
876 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"New Covariance "<<svNext.
covCurv<<std::endl;
877 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Transf by dCovTransform "<<dCovCurvTransform<<std::endl;
885 rep.
lY = zRep.cross(tau); rep.
lY *= 1./tau.perp();
886 rep.
lZ = rep.
lX.cross(rep.
lY);
894 static const std::string
metname =
"SteppingHelixPropagator";
896 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Make atom step "<<svCurrent.
path()<<
" with step "<<dS<<
" in direction "<<dir<<std::endl;
900 double curP = svCurrent.
p3.mag();
914 double p0Inv = 1./p0;
915 double b0 = svCurrent.
bf.mag();
918 double phi = (2.99792458e-3*svCurrent.
q*b0*p0Inv)*dS/2.;
919 bool phiSmall = fabs(phi) < 1
e-4;
924 double oneLessCosPhi=0;
925 double oneLessCosPhiOPhi=0;
927 double phiLessSinPhiOPhi=0;
930 double phi2 = phi*
phi;
931 double phi3 = phi2*
phi;
932 double phi4 = phi3*
phi;
933 sinPhi = phi - phi3/6. + phi4*phi/120.;
934 cosPhi = 1. -phi2/2. + phi4/24.;
935 oneLessCosPhi = phi2/2. - phi4/24. + phi2*phi4/720.;
936 oneLessCosPhiOPhi = 0.5*phi - phi3/24. + phi2*phi3/720.;
937 sinPhiOPhi = 1. - phi*phi/6. + phi4/120.;
938 phiLessSinPhiOPhi = phi*phi/6. - phi4/120. + phi4*phi2/5040.;
942 oneLessCosPhi = 1.-cosPhi;
943 oneLessCosPhiOPhi = oneLessCosPhi/
phi;
944 sinPhiOPhi = sinPhi/
phi;
945 phiLessSinPhiOPhi = 1 - sinPhiOPhi;
948 Vector bHat = svCurrent.
bf; bHat *= 1./b0;
951 Vector btVec(bHat.cross(tau));
952 double tauB = tau.dot(bHat);
953 Vector bbtVec(bHat*tauB - tau);
956 drVec = bbtVec*phiLessSinPhiOPhi; drVec -= btVec*oneLessCosPhiOPhi; drVec +=
tau;
959 double dEdx = svCurrent.
dEdx;
961 radX0 = svCurrent.
radX0;
965 drVec += svCurrent.
r3;
977 bf.set(-bfGV.
x(), -bfGV.
y(), bfGV.
z());
979 bf.set(bfGV.
x(), bfGV.
y(), bfGV.
z());
983 bf.set(bfGV.
x(), bfGV.
y(), bfGV.
z());
989 bf.set(0., 0., 1
e-16);
992 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Improved b "<<b0
993 <<
" at r3 "<<drVec<<std::endl;
996 if (fabs((b0-b0Init)*dS) > 1){
999 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Large bf*dS change "<<fabs((b0-svCurrent.
bf.mag())*dS)
1000 <<
" --> recalc dedx"<<std::endl;
1004 svNext.
p3 = svCurrent.
p3;
1007 dEdx =
getDeDx(svNext, dEdXPrime, radX0, rzTmp);
1010 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"New dEdX= "<<dEdx
1012 <<
" for p0 "<<p0<<std::endl;
1016 p0 += dP/2.;
if (p0 < 1
e-2) p0 = 1
e-2;
1019 phi = (2.99792458e-3*svCurrent.
q*b0*p0Inv)*dS;
1020 phiSmall = fabs(phi) < 1
e-4;
1023 double phi2 = phi*
phi;
1024 double phi3 = phi2*
phi;
1025 double phi4 = phi3*
phi;
1026 sinPhi = phi - phi3/6. + phi4*phi/120.;
1027 cosPhi = 1. -phi2/2. + phi4/24.;
1028 oneLessCosPhi = phi2/2. - phi4/24. + phi2*phi4/720.;
1029 oneLessCosPhiOPhi = 0.5*phi - phi3/24. + phi2*phi3/720.;
1030 sinPhiOPhi = 1. - phi*phi/6. + phi4/120.;
1031 phiLessSinPhiOPhi = phi*phi/6. - phi4/120. + phi4*phi2/5040.;
1035 oneLessCosPhi = 1.-cosPhi;
1036 oneLessCosPhiOPhi = oneLessCosPhi/
phi;
1037 sinPhiOPhi = sinPhi/
phi;
1038 phiLessSinPhiOPhi = 1. - sinPhiOPhi;
1041 bHat = bf; bHat *= 1./b0;
1043 btVec = bHat.cross(tau);
1044 tauB = tau.dot(bHat);
1045 bbtVec = bHat*tauB -
tau;
1047 tauNext = bbtVec*oneLessCosPhi; tauNext -= btVec*sinPhi; tauNext +=
tau;
1048 double tauNextPerpInv = 1./tauNext.perp();
1049 drVec = bbtVec*phiLessSinPhiOPhi; drVec -= btVec*oneLessCosPhiOPhi; drVec +=
tau;
1055 double dX0 = fabs(dS)/radX0;
1062 double x0 = fabs(svCurrent.
radPath());
1063 double alphaX0 = 13.6e-3*p0Inv; alphaX0 *= alphaX0;
1064 double betaX0 = 0.038;
1065 double logx0p1 =
log(x0+1);
1066 theta02 = dX0*alphaX0*(1+betaX0*logx0p1)*(1 + betaX0*logx0p1 + 2.*betaX0*x0/(x0+1) );
1068 theta02 = 196
e-6* p0Inv * p0Inv * dX0;
1071 double epsilonP0 = 1.+ dP/(p0-0.5*dP);
1075 Vector tbtVec(bHat - tauB*tau);
1091 double qbp = svCurrent.
q*p0Inv;
1096 double t11 = tau.x();
double t12 = tau.y();
double t13 = tau.z();
1097 double t21 = tauNext.x();
double t22 = tauNext.y();
double t23 = tauNext.z();
1098 double cosl0 = tau.perp();
1100 double cosecl1 = tauNextPerpInv;
1110 double sint = -sinPhi;
double cost = cosPhi;
1111 double hn1 = hn.x();
double hn2 = hn.y();
double hn3 = hn.z();
1112 double dx1 = dx.x();
double dx2 = dx.y();
double dx3 = dx.z();
1115 double gamma = hn1*t21 + hn2*t22 + hn3*t23;
1116 double an1 = hn2*t23 - hn3*t22;
1117 double an2 = hn3*t21 - hn1*t23;
1118 double an3 = hn1*t22 - hn2*t21;
1120 double auInv = cosl0;
double au = auInv>0 ? 1./auInv : 1e24;
1122 double u11 = -au*t12;
double u12 = au*t11;
1123 double v11 = -t13*u12;
double v12 = t13*u11;
double v13 = auInv;
1124 auInv =
sqrt(1. - t23*t23); au = auInv>0 ? 1./auInv : 1e24;
1126 double u21 = -au*t22;
double u22 = au*t21;
1127 double v21 = -t23*u22;
double v22 = t23*u21;
double v23 = auInv;
1134 double anv = -(hn1*u21 + hn2*u22 );
1135 double anu = (hn1*v21 + hn2*v22 + hn3*v23);
1136 double omcost = oneLessCosPhi;
double tmsint = -phi*phiLessSinPhiOPhi;
1138 double hu1 = - hn3*u12;
1139 double hu2 = hn3*u11;
1140 double hu3 = hn1*u12 - hn2*u11;
1142 double hv1 = hn2*v13 - hn3*v12;
1143 double hv2 = hn3*v11 - hn1*v13;
1144 double hv3 = hn1*v12 - hn2*v11;
1152 (sinPhi*bbtVec.z() - cosPhi*btVec.z());
1157 sint*(hv1*v21 + hv2*v22 + hv3*v23) +
1158 omcost*(hn1*v11 + hn2*v12 + hn3*v13) * (hn1*v21 + hn2*v22 + hn3*v23) +
1159 anv*(-sint*(v11*t21 + v12*t22 + v13*t23) +
1160 omcost*(v11*an1 + v12*an2 + v13*an3) -
1161 tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
1164 sint*(hu1*v21 + hu2*v22 + hu3*v23) +
1165 omcost*(hn1*u11 + hn2*u12 ) * (hn1*v21 + hn2*v22 + hn3*v23) +
1166 anv*(-sint*(u11*t21 + u12*t22 ) +
1167 omcost*(u11*an1 + u12*an2 ) -
1168 tmsint*gamma*(hn1*u11 + hn2*u12 ) );
1180 (oneLessCosPhi*bHat.z()*btVec.mag2() + sinPhi*btVec.z() + cosPhi*tbtVec.z()) ;
1184 sint*(hv1*u21 + hv2*u22 ) +
1185 omcost*(hn1*v11 + hn2*v12 + hn3*v13) *
1186 (hn1*u21 + hn2*u22 ) +
1187 anu*(-sint*(v11*t21 + v12*t22 + v13*t23) +
1188 omcost*(v11*an1 + v12*an2 + v13*an3) -
1189 tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
1193 sint*(hu1*u21 + hu2*u22 ) +
1194 omcost*(hn1*u11 + hn2*u12 ) *
1195 (hn1*u21 + hn2*u22 ) +
1196 anu*(-sint*(u11*t21 + u12*t22 ) +
1197 omcost*(u11*an1 + u12*an2 ) -
1198 tmsint*gamma*(hn1*u11 + hn2*u12 ) );
1216 omcost*(hv1*u21 + hv2*u22 ) +
1217 tmsint*(hn1*u21 + hn2*u22 ) *
1218 (hn1*v11 + hn2*v12 + hn3*v13))/q;
1221 omcost*(hu1*u21 + hu2*u22 ) +
1222 tmsint*(hn1*u21 + hn2*u22 ) *
1223 (hn1*u11 + hn2*u12 ))*cosl0/q;
1232 omcost*(hv1*v21 + hv2*v22 + hv3*v23) +
1233 tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
1234 (hn1*v11 + hn2*v12 + hn3*v13))/q;
1237 omcost*(hu1*v21 + hu2*v22 + hu3*v23) +
1238 tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
1239 (hn1*u11 + hn2*u12 ))*cosl0/q;
1249 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"rep X: "<<rep.
lX<<
" "<<rep.
lX.mag()
1250 <<
"\t Y: "<<rep.
lY<<
" "<<rep.
lY.mag()
1251 <<
"\t Z: "<<rep.
lZ<<
" "<<rep.
lZ.mag();
1257 double mulRR = theta02*dS*dS/3.;
1258 double mulRP = theta02*fabs(dS)*p0/2.;
1259 double mulPP = theta02*p0*p0;
1260 double losPP = dP*dP*1.6/fabs(dS)*(1.0 + p0*1
e-3);
1267 double sinThetaInv = tauNextPerpInv;
1268 double p0Mat = p0+ 0.5*dP;
1269 double p0Mat2 = p0Mat*p0Mat;
1273 svCurrent.
matDCovCurv(0,0) = losPP/(p0Mat2*p0Mat2);
1287 svCurrent.
matDCovCurv(2,2) = mulPP/p0Mat2*(sinThetaInv*sinThetaInv);
1288 svCurrent.
matDCovCurv(2,3) = mulRP/p0Mat*sinThetaInv;
1293 svCurrent.
matDCovCurv(3,2) = mulRP/p0Mat*sinThetaInv;
1314 dP = -dP > pMag ? -pMag+1
e-5 : dP;
1317 getNextState(svCurrent, svNext, dP, tauNext, drVec, dS, dS/radX0,
1323 double& dEdXPrime,
double& radX0,
1332 double lR = sv.
r3.perp();
1333 double lZ = fabs(sv.
r3.z());
1338 double dEdX_HCal = 0.95;
1339 double dEdX_ECal = 0.45;
1340 double dEdX_coil = 0.35;
1342 double dEdX_MCh = 0.053;
1343 double dEdX_Trk = 0.0114;
1344 double dEdX_Air = 2E-4;
1345 double dEdX_Vac = 0.0;
1347 double radX0_HCal = 1.44/0.8;
1348 double radX0_ECal = 0.89/0.7;
1349 double radX0_coil = 4.;
1350 double radX0_Fe = 1.76;
1351 double radX0_MCh = 1e3;
1352 double radX0_Trk = 320.;
1353 double radX0_Air = 3.e4;
1354 double radX0_Vac = 3.e9;
1358 if (! (lR < 380 && lZ < 785)){
1359 if (lZ > 785 ) rzLims =
MatBounds(0, 1e4, 785, 1e4);
1360 if (lZ < 785 ) rzLims =
MatBounds(380, 1e4, 0, 785);
1370 dEdx = dEdX_Vac; radX0 = radX0_Vac;
1376 dEdx = dEdX_Trk; radX0 = radX0_Trk;
1380 double lEtaDet = fabs(sv.
r3.eta());
1381 double scaleRadX = lEtaDet > 1.5 ? 0.7724 : 1./cosh(0.5*lEtaDet);
1382 scaleRadX *= scaleRadX;
1383 if (lEtaDet > 2 && lZ > 20) scaleRadX *= (lEtaDet-1.);
1384 if (lEtaDet > 2.5 && lZ > 20) scaleRadX *= (lEtaDet-1.);
1388 else if ( lZ < 294 + ecShift ){
1390 rzLims =
MatBounds(2.9, 129, 294, 294 + ecShift);
1391 dEdx = dEdX_Air; radX0 = radX0_Air;
1393 else if (lZ < 372 + ecShift){
1394 rzLims =
MatBounds(2.9, 129, 294 + ecShift, 372 + ecShift);
1395 dEdx = dEdX_ECal; radX0 = radX0_ECal;
1397 else if (lZ < 398 + ecShift){
1398 rzLims =
MatBounds(2.9, 129, 372 + ecShift, 398 + ecShift);
1399 dEdx = dEdX_HCal*0.05; radX0 = radX0_Air;
1401 else if (lZ < 555 + ecShift){
1402 rzLims =
MatBounds(2.9, 129, 398 + ecShift, 555 + ecShift);
1403 dEdx = dEdX_HCal*0.96; radX0 = radX0_HCal/0.96;
1409 if (lZ < 568 + ecShift) rzLims =
MatBounds(2.9, 129, 555 + ecShift, 568 + ecShift);
1410 else if (lZ < 625 + ecShift){
1411 if (lR < 85 + ecShift) rzLims =
MatBounds(2.9, 85, 568 + ecShift, 625 + ecShift);
1412 else rzLims =
MatBounds(85, 129, 568 + ecShift, 625 + ecShift);
1413 }
else if (lZ < 785 + ecShift) rzLims =
MatBounds(2.9, 129, 625 + ecShift, 785 + ecShift);
1414 else if (lZ < 1500 + ecShift) rzLims =
MatBounds(2.9, 129, 785 + ecShift, 1500 + ecShift);
1415 else rzLims =
MatBounds(2.9, 129, 1500 + ecShift, 1E4);
1418 if (! (lZ > 568 + ecShift && lZ < 625 + ecShift && lR > 85 )
1419 && ! (lZ > 785 + ecShift && lZ < 850 + ecShift && lR > 118)) {dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1420 else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1424 if (lZ < 372 + ecShift && lR < 177){
1425 if (lZ < 304) rzLims =
MatBounds(129, 177, 0, 304);
1427 if (lR < 135 ) rzLims =
MatBounds(129, 135, 304, 343);
1428 else if (lR < 172 ){
1429 if (lZ < 311 ) rzLims =
MatBounds(135, 172, 304, 311);
1430 else rzLims =
MatBounds(135, 172, 311, 343);
1432 if (lZ < 328) rzLims =
MatBounds(172, 177, 304, 328);
1433 else rzLims =
MatBounds(172, 177, 328, 343);
1436 else if ( lZ < 343 + ecShift){
1437 rzLims =
MatBounds(129, 177, 343, 343 + ecShift);
1440 if (lR < 156 ) rzLims =
MatBounds(129, 156, 343 + ecShift, 372 + ecShift);
1441 else if ( (lZ - 343 - ecShift) > (lR - 156)*1.38 )
1442 rzLims =
MatBounds(156, 177, 127.72 + ecShift, 372 + ecShift, atan(1.38), 0);
1443 else rzLims =
MatBounds(156, 177, 343 + ecShift, 127.72 + ecShift, 0, atan(1.38));
1446 if (!(lR > 135 && lZ <343 + ecShift && lZ > 304 )
1447 && ! (lR > 156 && lZ < 372 + ecShift && lZ > 343 + ecShift && ((lZ-343. - ecShift )< (lR-156.)*1.38)))
1450 double cosThetaEquiv = 0.8/
sqrt(1.+lZ*lZ/lR/lR) + 0.2;
1451 if (lZ > 343) cosThetaEquiv = 1.;
1452 dEdx = dEdX_ECal*cosThetaEquiv; radX0 = radX0_ECal/cosThetaEquiv;
1455 if ( (lZ > 304 && lZ < 328 && lR < 177 && lR > 135)
1456 && ! (lZ > 311 && lR < 172) ) {dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1457 else if ( lZ > 343 && lZ < 343 + ecShift) { dEdx = dEdX_Air; radX0 = radX0_Air; }
1458 else {dEdx = dEdX_ECal*0.2; radX0 = radX0_Air;}
1461 else if (lZ < 554 + ecShift){
1463 if ( lZ > 372 + ecShift && lZ < 398 + ecShift )rzLims =
MatBounds(129, 177, 372 + ecShift, 398 + ecShift);
1464 else if (lZ < 548 + ecShift) rzLims =
MatBounds(129, 177, 398 + ecShift, 548 + ecShift);
1465 else rzLims =
MatBounds(129, 177, 548 + ecShift, 554 + ecShift);
1468 if ((lZ - 307) < (lR - 177.)*1.739) rzLims =
MatBounds(177, 193, 0, -0.803, 0, atan(1.739));
1469 else if ( lZ < 389) rzLims =
MatBounds(177, 193, -0.803, 389, atan(1.739), 0.);
1470 else if ( lZ < 389 + ecShift) rzLims =
MatBounds(177, 193, 389, 389 + ecShift);
1471 else if ( lZ < 548 + ecShift ) rzLims =
MatBounds(177, 193, 389 + ecShift, 548 + ecShift);
1472 else rzLims =
MatBounds(177, 193, 548 + ecShift, 554 + ecShift);
1475 double anApex = 375.7278 - 193./1.327;
1476 if ( (lZ - 375.7278) < (lR - 193.)/1.327) rzLims =
MatBounds(193, 264, 0, anApex, 0, atan(1./1.327));
1477 else if ( (lZ - 392.7278 ) < (lR - 193.)/1.327)
1478 rzLims =
MatBounds(193, 264, anApex, anApex+17., atan(1./1.327), atan(1./1.327));
1479 else if ( (lZ - 392.7278 - ecShift ) < (lR - 193.)/1.327)
1480 rzLims =
MatBounds(193, 264, anApex+17., anApex+17. + ecShift, atan(1./1.327), atan(1./1.327));
1482 else if ( lZ < 517 + ecShift ) rzLims =
MatBounds(193, 264, anApex+17. + ecShift, 517 + ecShift, atan(1./1.327), 0);
1483 else if (lZ < 548 + ecShift){
1484 if (lR < 246 ) rzLims =
MatBounds(193, 246, 517 + ecShift, 548 + ecShift);
1485 else rzLims =
MatBounds(246, 264, 517 + ecShift, 548 + ecShift);
1487 else rzLims =
MatBounds(193, 264, 548 + ecShift, 554 + ecShift);
1489 else if ( lR < 275){
1490 if (lZ < 433) rzLims =
MatBounds(264, 275, 0, 433);
1491 else if (lZ < 554 ) rzLims =
MatBounds(264, 275, 433, 554);
1492 else rzLims =
MatBounds(264, 275, 554, 554 + ecShift);
1495 if (lZ < 402) rzLims =
MatBounds(275, 287, 0, 402);
1496 else if (lZ < 554) rzLims =
MatBounds(275, 287, 402, 554);
1497 else rzLims =
MatBounds(275, 287, 554, 554 + ecShift);
1500 if ((lZ < 433 || lR < 264) && (lZ < 402 || lR < 275) && (lZ < 517 + ecShift || lR < 246)
1502 && lZ < 548 + ecShift
1503 && ! (lZ < 389 + ecShift && lZ > 335 && lR < 193 )
1504 && ! (lZ > 307 && lZ < 335 && lR < 193 && ((lZ - 307) > (lR - 177.)*1.739))
1505 && ! (lR < 177 && lZ < 398 + ecShift)
1506 && ! (lR < 264 && lR > 193 && fabs(441.5+0.5*ecShift - lZ + (lR - 269.)/1.327) < (8.5 + ecShift*0.5)) )
1507 { dEdx = dEdX_HCal; radX0 = radX0_HCal;
1509 else if( (lR < 193 && lZ > 389 && lZ < 389 + ecShift ) || (lR > 264 && lR < 287 && lZ > 554 && lZ < 554 + ecShift)
1510 ||(lR < 264 && lR > 193 && fabs(441.5+8.5+0.5*ecShift - lZ + (lR - 269.)/1.327) < ecShift*0.5) ) {
1511 dEdx = dEdX_Air; radX0 = radX0_Air;
1513 else {dEdx = dEdX_HCal*0.05; radX0 = radX0_Air; }
1516 else if (lZ < 564 + ecShift){
1518 rzLims =
MatBounds(129, 251, 554 + ecShift, 564 + ecShift);
1519 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1522 rzLims =
MatBounds(251, 287, 554 + ecShift, 564 + ecShift);
1523 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1526 else if (lZ < 625 + ecShift){
1527 rzLims =
MatBounds(129, 287, 564 + ecShift, 625 + ecShift);
1528 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1530 else if (lZ < 785 + ecShift){
1531 if (lR < 275) rzLims =
MatBounds(129, 275, 625 + ecShift, 785 + ecShift);
1533 if (lZ < 720 + ecShift) rzLims =
MatBounds(275, 287, 625 + ecShift, 720 + ecShift);
1534 else rzLims =
MatBounds(275, 287, 720 + ecShift, 785 + ecShift);
1536 if (! (lR > 275 && lZ < 720 + ecShift)) { dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1537 else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1539 else if (lZ < 850 + ecShift){
1540 rzLims =
MatBounds(129, 287, 785 + ecShift, 850 + ecShift);
1541 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1543 else if (lZ < 910 + ecShift){
1544 rzLims =
MatBounds(129, 287, 850 + ecShift, 910 + ecShift);
1545 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1547 else if (lZ < 975 + ecShift){
1548 rzLims =
MatBounds(129, 287, 910 + ecShift, 975 + ecShift);
1549 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1551 else if (lZ < 1000 + ecShift){
1552 rzLims =
MatBounds(129, 287, 975 + ecShift, 1000 + ecShift);
1553 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1555 else if (lZ < 1063 + ecShift){
1556 rzLims =
MatBounds(129, 287, 1000 + ecShift, 1063 + ecShift);
1557 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1559 else if ( lZ < 1073 + ecShift){
1560 rzLims =
MatBounds(129, 287, 1063 + ecShift, 1073 + ecShift);
1561 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1563 else if (lZ < 1E4 ) {
1564 rzLims =
MatBounds(129, 287, 1073 + ecShift, 1E4);
1565 dEdx = dEdX_Air; radX0 = radX0_Air;
1569 dEdx = dEdX_Air; radX0 = radX0_Air;
1572 else if (lR <380 && lZ < 667){
1574 if (lR < 315) rzLims =
MatBounds(287, 315, 0, 630);
1575 else if (lR < 341 ) rzLims =
MatBounds(315, 341, 0, 630);
1576 else rzLims =
MatBounds(341, 380, 0, 630);
1577 }
else rzLims =
MatBounds(287, 380, 630, 667);
1579 if (lZ < 630) { dEdx = dEdX_coil; radX0 = radX0_coil; }
1580 else {dEdx = dEdX_Air; radX0 = radX0_Air; }
1585 bool isIron =
false;
1590 double bMag = sv.
bf.mag();
1591 isIron = (bMag > 0.75 && ! (lZ > 500 && lR <500 && bMag < 1.15)
1592 && ! (lZ < 450 && lR > 420 && bMag < 1.15 ) );
1596 if (isIron) { dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1597 else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1600 dEdx = dEdX_Air; radX0 = radX0_Air;
1603 else if (lR > 750 ){
1605 dEdx = dEdX_Air; radX0 = radX0_Air;
1607 else if (lZ < 667 + ecShift){
1608 rzLims =
MatBounds(287, 750, 667, 667 + ecShift);
1609 dEdx = dEdX_Air; radX0 = radX0_Air;
1612 else if (lZ < 724 + ecShift){
1613 if (lR < 380 ) rzLims =
MatBounds(287, 380, 667 + ecShift, 724 + ecShift);
1614 else rzLims =
MatBounds(380, 750, 667 + ecShift, 724 + ecShift);
1615 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1617 else if (lZ < 785 + ecShift){
1618 if (lR < 380 ) rzLims =
MatBounds(287, 380, 724 + ecShift, 785 + ecShift);
1619 else rzLims =
MatBounds(380, 750, 724 + ecShift, 785 + ecShift);
1620 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1622 else if (lZ < 850 + ecShift){
1623 rzLims =
MatBounds(287, 750, 785 + ecShift, 850 + ecShift);
1624 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1626 else if (lZ < 910 + ecShift){
1627 rzLims =
MatBounds(287, 750, 850 + ecShift, 910 + ecShift);
1628 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1630 else if (lZ < 975 + ecShift){
1631 rzLims =
MatBounds(287, 750, 910 + ecShift, 975 + ecShift);
1632 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1634 else if (lZ < 1000 + ecShift){
1635 rzLims =
MatBounds(287, 750, 975 + ecShift, 1000 + ecShift);
1636 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1638 else if (lZ < 1063 + ecShift){
1640 rzLims =
MatBounds(287, 360, 1000 + ecShift, 1063 + ecShift);
1641 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1645 rzLims =
MatBounds(360, 750, 1000 + ecShift, 1063 + ecShift);
1646 dEdx = dEdX_Air; radX0 = radX0_Air;
1649 else if ( lZ < 1073 + ecShift){
1650 rzLims =
MatBounds(287, 750, 1063 + ecShift, 1073 + ecShift);
1652 dEdx = dEdX_Air; radX0 = radX0_Air;
1654 else if (lZ < 1E4 ) {
1655 rzLims =
MatBounds(287, 750, 1073 + ecShift, 1E4);
1656 dEdx = dEdX_Air; radX0 = radX0_Air;
1658 else {dEdx = dEdX_Air; radX0 = radX0_Air; }
1664 double p0 = sv.
p3.mag();
1665 double logp0 =
log(p0);
1666 double p0powN33 = 0;
1672 double dEdX_mat = -(11.4 + 0.96*fabs(logp0+
log(2.8)) + 0.033*p0*(1.0 - p0powN33) )*1
e-3;
1675 dEdXPrime = dEdx == 0 ? 0 : -dEdx*(0.96/p0 + 0.033 - 0.022*p0powN33)*1
e-3;
1684 if (ind != 0 && result == 0){
1693 const double pars[6],
1694 double& dist,
double& tanDist,
1696 double fastSkipDist)
const{
1697 static const std::string
metname =
"SteppingHelixPropagator";
1703 double curR = sv.
r3.perp();
1705 if (fabs(dist) > fastSkipDist){
1709 double curP2 = sv.
p3.mag2();
1710 double curPtPos2 = sv.
p3.perp2();
if(curPtPos2< 1
e-16) curPtPos2=1
e-16;
1712 double cosDPhiPR = (sv.
r3.x()*sv.
p3.x()+sv.
r3.y()*sv.
p3.y());
1713 refDirection = dist*cosDPhiPR > 0 ?
1715 tanDist = dist*
sqrt(curP2/curPtPos2);
1721 double curZ = sv.
r3.z();
1722 dist = pars[
Z_P] - curZ;
1723 if (fabs(dist) > fastSkipDist){
1727 double curP = sv.
p3.mag();
1728 refDirection = sv.
p3.z()*dist > 0. ?
1730 tanDist = dist/sv.
p3.z()*curP;
1736 Point rPlane(pars[0], pars[1], pars[2]);
1737 Vector nPlane(pars[3], pars[4], pars[5]);
1743 double dRDotN = (sv.
r3.x()-rPlane.x())*nPlane.x() + (sv.
r3.y()-rPlane.y())*nPlane.y() + (sv.
r3.z()-rPlane.z())*nPlane.z();
1745 dist = fabs(dRDotN);
1746 if (dist > fastSkipDist){
1750 double curP = sv.
p3.mag();
1752 double p0Inv = 1./p0;
1754 double tN = tau.dot(nPlane);
1755 refDirection = tN*dRDotN < 0. ?
1757 double b0 = sv.
bf.mag();
1758 if (fabs(tN)>1
e-24){
1759 tanDist = -dRDotN/tN;
1762 if (fabs(dRDotN)>1
e-24) tanDist = 1e6;
1765 if (fabs(tanDist) > 1e4) tanDist = 1e4;
1767 double b0Inv = 1./b0;
1768 double tNInv = 1./tN;
1770 double bHatN = bHat.dot(nPlane);
1771 double cosPB = bHat.dot(tau);
1772 double kVal = 2.99792458e-3*sv.
q*p0Inv*b0;
1773 double aVal = tanDist*kVal;
1774 Vector lVec = bHat.cross(tau);
1775 double bVal = lVec.dot(nPlane)*tNInv;
1776 if (fabs(aVal*bVal)< 0.3){
1777 double cVal = 1. - bHatN*cosPB*tNInv;
1778 double aacVal = cVal*aVal*aVal;
1779 if (fabs(aacVal)<1){
1780 double tanDCorr = bVal/2. + (bVal*bVal/2. + cVal/6)*aVal;
1783 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<tanDist<<
" vs "
1784 <<tanDist*(1.+tanDCorr)<<
" corr "<<tanDist*tanDCorr<<std::endl;
1785 tanDist *= (1.+tanDCorr);
1787 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"AACVal "<< fabs(aacVal)
1788 <<
" = "<<aVal<<
"**2 * "<<cVal<<
" too large:: will not converge"<<std::endl;
1791 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"ABVal "<< fabs(aVal*bVal)
1792 <<
" = "<<aVal<<
" * "<<bVal<<
" too large:: will not converge"<<std::endl;
1800 Point cVertex(pars[0], pars[1], pars[2]);
1801 if (cVertex.perp2() < 1
e-10){
1804 double relV3mag = relV3.mag();
1806 double theta(pars[3]);
1808 double sinTheta =
sin(theta);
1809 double cosTheta =
cos(theta);
1810 double cosV3Theta = relV3.z()/relV3mag;
1811 if (cosV3Theta>1) cosV3Theta=1;
1812 if (cosV3Theta<-1) cosV3Theta=-1;
1813 double sinV3Theta =
sqrt(1.-cosV3Theta*cosV3Theta);
1815 double sinDTheta = sinTheta*cosV3Theta - cosTheta*sinV3Theta;
1816 double cosDTheta = cosTheta*cosV3Theta + sinTheta*sinV3Theta;
1817 bool isInside = sinTheta > sinV3Theta && cosTheta*cosV3Theta > 0;
1818 dist = isInside || cosDTheta > 0 ? relV3mag*sinDTheta : relV3mag;
1819 if (fabs(dist) > fastSkipDist){
1824 double relV3phi=relV3.phi();
1825 double normPhi = isInside ?
1827 double normTheta = theta >
Geom::pi()/2. ?
1831 Vector norm; norm.setRThetaPhi(fabs(dist), normTheta, normPhi);
1832 double curP = sv.
p3.mag();
double cosp3theta = sv.
p3.z()/curP;
1833 if (cosp3theta>1) cosp3theta=1;
1834 if (cosp3theta<-1) cosp3theta=-1;
1835 double sineConeP = sinTheta*cosp3theta - cosTheta*
sqrt(1.-cosp3theta*cosp3theta);
1837 double sinSolid = norm.dot(sv.
p3)/(fabs(dist)*curP);
1838 tanDist = fabs(sinSolid) > fabs(sineConeP) ? dist/fabs(sinSolid) : dist/fabs(sineConeP);
1841 refDirection = sinSolid > 0 ?
1844 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Cone pars: theta "<<theta
1845 <<
" normTheta "<<norm.theta()
1846 <<
" p3Theta "<<sv.
p3.theta()
1847 <<
" sinD: "<< sineConeP
1848 <<
" sinSolid "<<sinSolid;
1851 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"refToDest:toCone the point is "
1852 <<(isInside?
"in" :
"out")<<
"side the cone"
1863 double curS = fabs(sv.
path());
1865 if (fabs(dist) > fastSkipDist){
1869 refDirection = pars[
PATHL_P] > 0 ?
1877 Point pDest(pars[0], pars[1], pars[2]);
1878 double curP = sv.
p3.mag();
1879 dist = (sv.
r3 - pDest).
mag()+ 1
e-24;
1880 tanDist = (sv.
r3.dot(sv.
p3) - pDest.dot(sv.
p3))/curP;
1882 double b0 = sv.
bf.mag();
1885 double kVal = 2.99792458e-3*sv.
q/p0*b0;
1886 double aVal = fabs(dist*kVal);
1887 tanDist *= 1./(1.+ aVal);
1888 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"corrected by aVal "<<aVal<<
" to "<<tanDist;
1890 refDirection = tanDist < 0 ?
1897 Point rLine(pars[0], pars[1], pars[2]);
1898 Vector dLine(pars[3], pars[4], pars[5]);
1899 dLine = (dLine - rLine);
1900 dLine *= 1./dLine.mag();
if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"dLine "<<dLine;
1903 double curP = sv.
p3.mag();
1904 Vector dRPerp = dR - dLine*(dR.dot(dLine));
1905 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"dRperp "<<dRPerp;
1907 dist = dRPerp.mag() + 1
e-24;
1908 tanDist = dRPerp.dot(sv.
p3)/curP;
1910 double cosAlpha2 = dLine.dot(sv.
p3)/curP; cosAlpha2 *= cosAlpha2;
1911 tanDist *= 1./
sqrt(fabs(1.-cosAlpha2)+1
e-96);
1914 double b0 = sv.
bf.mag();
1917 double kVal = 2.99792458e-3*sv.
q/p0*b0;
1918 double aVal = fabs(dist*kVal);
1919 tanDist *= 1./(1.+ aVal);
1920 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"corrected by aVal "<<aVal<<
" to "<<tanDist;
1922 refDirection = tanDist < 0 ?
1938 double tanDistConstrained = tanDist;
1939 if (fabs(tanDist) > 4.*fabs(dist) ) tanDistConstrained *= tanDist == 0 ? 0 : fabs(dist/tanDist*4.);
1942 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"refToDest input: dest"<<dest<<
" pars[]: ";
1943 for (
int i = 0;
i < 6;
i++){
1944 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
", "<<
i<<
" "<<pars[
i];
1946 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<std::endl;
1947 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"refToDest output: "
1949 <<
"\t tanDist "<< tanDist
1950 <<
"\t tanDistConstr "<< tanDistConstrained
1951 <<
"\t refDirection "<< refDirection
1954 tanDist = tanDistConstrained;
1962 double& dist,
double& tanDist,
1963 double fastSkipDist,
bool expectNewMagVolume,
double maxStep)
const{
1965 static const std::string
metname =
"SteppingHelixPropagator";
1969 if (cVol == 0)
return result;
1970 const std::vector<VolumeSide>& cVolFaces(cVol->
faces());
1972 double distToFace[6] = {0,0,0,0,0,0};
1973 double tanDistToFace[6] = {0,0,0,0,0,0};
1979 unsigned int iFDestSorted[6] = {0,0,0,0,0,0};
1980 unsigned int nDestSorted =0;
1981 unsigned int nearParallels = 0;
1983 double curP = sv.
p3.mag();
1987 <<
" with "<<cVolFaces.size()<<
" faces"<<std::endl;
1990 unsigned int nFaces = cVolFaces.size();
1991 for (
unsigned int iFace = 0; iFace < nFaces; ++iFace){
1993 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Too many faces"<<std::endl;
1996 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Start with face "<<iFace<<std::endl;
2003 const Cone* cCone = 0;
2004 if (
typeid(cVolFaces[iFace].surface()) ==
typeid(
const Plane&)){
2005 cPlane = &cVolFaces[iFace].surface();
2006 }
else if (
typeid(cVolFaces[iFace].surface()) ==
typeid(
const Cylinder&)){
2007 cCyl =
dynamic_cast<const Cylinder*
>(&cVolFaces[iFace].surface());
2008 }
else if (
typeid(cVolFaces[iFace].surface()) ==
typeid(
const Cone&)){
2009 cCone =
dynamic_cast<const Cone*
>(&cVolFaces[iFace].surface());
2011 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Could not cast a volume side surface to a known type"<<std::endl;
2015 if (cPlane!=0)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The face is a plane at "<<cPlane<<std::endl;
2016 if (cCyl!=0)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The face is a cylinder at "<<cCyl<<std::endl;
2019 double pars[6] = {0,0,0,0,0,0};
2027 pars[0] = rPlane.x(); pars[1] = rPlane.y(); pars[2] = rPlane.z();
2028 pars[3] = nPlane.x(); pars[4] = nPlane.y(); pars[5] = nPlane.z();
2030 pars[0] = rPlane.x(); pars[1] = rPlane.y(); pars[2] = -rPlane.z();
2031 pars[3] = nPlane.x(); pars[4] = nPlane.y(); pars[5] = -nPlane.z();
2034 }
else if (cCyl != 0){
2036 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Cylinder at "<<cCyl->
position()
2042 }
else if (cCone != 0){
2044 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Cone at "<<cCone->
position()
2045 <<
" rorated by "<<cCone->
rotation()
2046 <<
" vertex at "<<cCone->
vertex()
2052 pars[2] = cCone->
vertex().
z();
2056 pars[2] = -cCone->
vertex().
z();
2061 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Unknown surface"<<std::endl;
2065 resultToFace[iFace] =
2067 distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2078 double invDTFPosiF = 1./(1
e-32+fabs(tanDistToFace[iFace]));
2079 double dSlope = fabs(distToFace[iFace])*invDTFPosiF;
2080 double maxStepL = maxStep> 100 ? 100 : maxStep;
if (maxStepL < 10) maxStepL = 10.;
2081 bool isNearParallel = fabs(tanDistToFace[iFace]) + 100.*curP*dSlope < maxStepL
2084 if (refDirectionToFace[iFace] == dir || isNearParallel){
2085 if (isNearParallel) nearParallels++;
2086 iFDestSorted[nDestSorted] = iFace;
2092 if (refDirectionToFace[iFace] == dir){
2093 if (iDistMin == -1) iDistMin = iFace;
2094 else if (fabs(distToFace[iFace]) < fabs(distToFace[iDistMin])) iDistMin = iFace;
2097 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<cVol<<
" "<<iFace<<
" "
2098 <<tanDistToFace[iFace]<<
" "<<distToFace[iFace]<<
" "<<refDirectionToFace[iFace]<<
" "<<dir<<std::endl;
2102 for (
unsigned int i = 0;
i<nDestSorted; ++
i){
2103 unsigned int iMax = nDestSorted-
i-1;
2104 for (
unsigned int j=0;
j<nDestSorted-
i; ++
j){
2105 if (fabs(tanDistToFace[iFDestSorted[
j]]) > fabs(tanDistToFace[iFDestSorted[iMax]]) ){
2109 unsigned int iTmp = iFDestSorted[nDestSorted-i-1];
2110 iFDestSorted[nDestSorted-i-1] = iFDestSorted[iMax];
2111 iFDestSorted[iMax] = iTmp;
2115 for (
unsigned int i=0;
i<nDestSorted;++
i){
2116 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<cVol<<
" "<<
i<<
" "<<iFDestSorted[
i]<<
" "<<tanDistToFace[iFDestSorted[
i]]<<std::endl;
2123 for (
unsigned int i=0;
i<nDestSorted;++
i){
2124 iFDest = iFDestSorted[
i];
2128 Vector lDelta(sv.
p3); lDelta *= sign/curP*fabs(distToFace[iFDest]);
2129 gPointEst += lDelta;
2131 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Linear est point "<<gPointEst
2132 <<
" for iFace "<<iFDest<<std::endl;
2134 GlobalPoint gPointEstNegZ(gPointEst.x(), gPointEst.y(), -fabs(gPointEst.z()));
2135 GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z() );
2139 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is inside the volume"<<std::endl;
2143 dist = distToFace[iFDest];
2144 tanDist = tanDistToFace[iFDest];
2146 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got a point near closest boundary -- face "<<iFDest<<std::endl;
2160 double lDist = iDistMin == -1 ? fastSkipDist : fabs(distToFace[iDistMin]);
2161 if (lDist > fastSkipDist) lDist = fastSkipDist;
2162 Vector lDelta(sv.
p3); lDelta *= sign/curP*lDist;
2163 gPointEst += lDelta;
2165 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Linear est point to shortest dist "<<gPointEst
2166 <<
" for iFace "<<iDistMin<<
" at distance "<<lDist*sign<<std::endl;
2168 GlobalPoint gPointEstNegZ(gPointEst.x(), gPointEst.y(), -fabs(gPointEst.z()));
2169 GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z() );
2173 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is inside the volume"<<std::endl;
2183 tanDist = dist*1.01;
2185 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Wrong volume located: return small dist, tandist"<<std::endl;
2191 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"All faces are too far"<<std::endl;
2193 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Appear to be in a wrong volume"<<std::endl;
2195 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Something else went wrong"<<std::endl;
2206 double& dist,
double& tanDist,
2207 double fastSkipDist)
const{
2209 static const std::string
metname =
"SteppingHelixPropagator";
2216 double distToFace[4] = {0,0,0,0};
2217 double tanDistToFace[4] = {0,0,0,0};
2222 double curP = sv.
p3.mag();
2224 for (
unsigned int iFace = 0; iFace < 4; iFace++){
2226 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Start with mat face "<<iFace<<std::endl;
2229 double pars[6] = {0,0,0,0,0,0};
2232 if (fabs(parLim[iFace+2])< 1
e-6){
2234 pars[0] = 0; pars[1] = 0; pars[2] = -parLim[iFace];
2235 pars[3] = 0; pars[4] = 0; pars[5] = 1;
2237 pars[0] = 0; pars[1] = 0; pars[2] = parLim[iFace];
2238 pars[3] = 0; pars[4] = 0; pars[5] = 1;
2243 pars[0] = 0; pars[1] = 0;
2244 pars[2] = parLim[iFace];
2245 pars[3] =
Geom::pi()/2. - parLim[iFace+2];
2247 pars[0] = 0; pars[1] = 0;
2248 pars[2] = - parLim[iFace];
2249 pars[3] =
Geom::pi()/2. + parLim[iFace+2];
2258 resultToFace[iFace] =
2260 distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2266 if (refDirectionToFace[iFace] == dir || fabs(distToFace[iFace]) < 2
e-2*fabs(tanDistToFace[iFace]) ){
2269 Vector lDelta(sv.
p3); lDelta *= sign*fabs(distToFace[iFace])/curP;
2270 gPointEst += lDelta;
2272 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Linear est point "<<gPointEst
2275 double lZ = fabs(gPointEst.z());
2276 double lR = gPointEst.perp();
2277 double tan4 = parLim[4] == 0 ? 0 :
tan(parLim[4]);
2278 double tan5 = parLim[5] == 0 ? 0 :
tan(parLim[5]);
2279 if ( (lZ - parLim[2]) > lR*tan4
2280 && (lZ - parLim[3]) < lR*tan5
2281 && lR > parLim[0] && lR < parLim[1]){
2283 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is inside the volume"<<std::endl;
2289 if (fabs(tanDistToFace[iFDest]) > fabs(tanDistToFace[iFace])){
2295 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is NOT inside the volume"<<std::endl;
2303 dist = distToFace[iFDest];
2304 tanDist = tanDistToFace[iFDest];
2306 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got a point near closest boundary -- face "<<iFDest<<std::endl;
2310 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Failed to find a dest point inside the volume"<<std::endl;
2319 static const std::string
metname =
"SteppingHelixPropagator";
2320 if (vol == 0)
return false;
2344 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Volume is magnetic, located at "<<vol->
position()<<std::endl;
2346 if (
debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Volume is not magnetic, located at "<<vol->
position()<<std::endl;
double z0() const
z coordinate
DDSolidShape shapeType() const
virtual PropagationDirection propagationDirection() const
Result refToDest(DestType dest, const SteppingHelixPropagator::StateInfo &sv, const double pars[6], double &dist, double &tanDist, PropagationDirection &refDirection, double fastSkipDist=1e12) const
(Internals) determine distance and direction from the current position to the plane ...
const std::string metname
AlgebraicMatrix55 covCurvRot_
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
bool applyRadX0Correction_
void getFreeState(FreeTrajectoryState &fts) const
convert internal structure into the fts
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
ROOT::Math::SMatrixIdentity AlgebraicMatrixID
bool isYokeVolume(const MagVolume *vol) const
check if it's a yoke/iron based on this MagVol internals
Sin< T >::type sin(const T &t)
static const int MAX_STEPS
Global3DPoint GlobalPoint
SteppingHelixStateInfo::VolumeBounds MatBounds
Geom::Theta< T > theta() const
AlgebraicSymMatrix55 covCurv
const MagVolume * findVolume(const GlobalPoint &gp) const
std::pair< TrajectoryStateOnSurface, double > TsosPP
int cIndex_(int ind) const
(Internals) circular index for array of transients
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
double getDeDx(const SteppingHelixPropagator::StateInfo &sv, double &dEdXPrime, double &radX0, MatBounds &rzLims) const
estimate average (in fact smth. close to MPV and median) energy loss per unit path length ...
bool isZSymmetric() const
std::pair< FreeTrajectoryState, double > FtsPP
Result refToMatVolume(const SteppingHelixPropagator::StateInfo &sv, PropagationDirection dir, double &dist, double &tanDist, double fastSkipDist=1e12) const
bool useInTeslaFromMagField_
void loadState(SteppingHelixPropagator::StateInfo &svCurrent, const SteppingHelixPropagator::Vector &p3, const SteppingHelixPropagator::Point &r3, int charge, PropagationDirection dir, const AlgebraicSymMatrix55 &covCurv) const
AlgebraicMatrix55 dCCurvTransform_
virtual ::GlobalVector inTesla(const ::GlobalPoint &gp) const
double dydz() const
dydz slope
GlobalPoint vertex() const
Global position of the cone vertex.
virtual bool inside(const GlobalPoint &gp, double tolerance=0.) const =0
Scalar radius() const
Radius of the cylinder.
static const char * name(DDSolidShape s)
SteppingHelixPropagator()
Constructors.
TrajectoryStateOnSurface getStateOnSurface(const Surface &surf, bool returnTangentPlane=false) const
LocalPoint toLocal(const GlobalPoint &gp) const
const VolumeBasedMagneticField * vbField_
Cos< T >::type cos(const T &t)
Tan< T >::type tan(const T &t)
AlgebraicSymMatrix55 matDCovCurv
virtual TrajectoryStateOnSurface propagate(const FreeTrajectoryState &ftsStart, const Plane &pDest) const
Propagate to Plane given a starting point.
double dxdz() const
dxdz slope
const MagneticField * field
bool isIron() const
Temporary hack to pass information on material. Will eventually be replaced!
static const int MAX_POINTS
bool useTuningForL2Speed_
bool makeAtomStep(SteppingHelixPropagator::StateInfo &svCurrent, SteppingHelixPropagator::StateInfo &svNext, double dS, PropagationDirection dir, SteppingHelixPropagator::Fancy fancy) const
main stepping function: compute next state vector after a step of length dS
Result refToMagVolume(const SteppingHelixPropagator::StateInfo &sv, PropagationDirection dir, double &dist, double &tanDist, double fastSkipDist=1e12, bool expectNewMagVolume=false, double maxStep=1e12) const
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &ftsStart, const Plane &pDest) const
virtual const std::vector< VolumeSide > & faces() const =0
Access to volume faces.
const AlgebraicSymMatrix55 unit55_
void setRep(SteppingHelixPropagator::Basis &rep, const SteppingHelixPropagator::Vector &tau) const
Set/compute basis vectors for local coordinates at current step (called by incrementState) ...
LocalVector fieldInTesla(const LocalPoint &lp) const
std::vector< std::vector< double > > tmp
StateInfo svBuf_[MAX_POINTS+1]
double y0() const
y coordinate
void setIState(const SteppingHelixStateInfo &sStart) const
(Internals) Init starting point
const RotationType & rotation() const
void getNextState(const SteppingHelixPropagator::StateInfo &svPrevious, SteppingHelixPropagator::StateInfo &svNext, double dP, const SteppingHelixPropagator::Vector &tau, const SteppingHelixPropagator::Vector &drVec, double dS, double dX0, const AlgebraicMatrix55 &dCovCurv) const
const PositionType & position() const
const MagneticField * field_
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepStd< double, 5, 5 > > AlgebraicMatrix55
static const std::string ResultName[MAX_RESULT]
Geom::Theta< float > openingAngle() const
Angle of the cone.
double x0() const
x coordinate