40 svBuf[
i].isComplete =
true;
41 svBuf[
i].isValid_ =
true;
45 svBuf[
i].r3 =
Point(0, 0, 0);
47 svBuf[
i].bfGradLoc =
Vector(0, 0, 0);
124 if ((pDest1 - pDest2).
mag() < 1
e-10) {
127 <<
"Can't propagate: the points should be at a bigger distance" << std::endl;
137 propagate(svBuf[0], pDest1, pDest2, svCurrent);
157 edm::LogWarning(
"SteppingHelixPropagator") <<
"Can't propagate: invalid input state" << std::endl;
163 const Plane* pDest = dynamic_cast<const Plane*>(&sDest);
164 if (pDest !=
nullptr) {
169 const Cylinder* cDest = dynamic_cast<const Cylinder*>(&sDest);
170 if (cDest !=
nullptr) {
183 edm::LogWarning(
"SteppingHelixPropagator") <<
"Can't propagate: invalid input state" << std::endl;
195 nPlane /= nPlane.mag();
197 double pars[6] = {rPlane.x(), rPlane.y(), rPlane.z(), nPlane.x(), nPlane.y(), nPlane.z()};
204 if (sStart.
path() < svBuf[
cIndex_(nPoints - 1)].path())
206 if (sStart.
path() > svBuf[
cIndex_(nPoints - 1)].path())
208 svBuf[
cIndex_(nPoints - 1)].dir = lDir;
219 edm::LogWarning(
"SteppingHelixPropagator") <<
"Can't propagate: invalid input state" << std::endl;
229 double pars[6] = {0, 0, 0, 0, 0, 0};
237 if (sStart.
path() < svBuf[
cIndex_(nPoints - 1)].path())
239 if (sStart.
path() > svBuf[
cIndex_(nPoints - 1)].path())
241 svBuf[
cIndex_(nPoints - 1)].dir = lDir;
251 edm::LogWarning(
"SteppingHelixPropagator") <<
"Can't propagate: invalid input state" << std::endl;
261 double pars[6] = {pDest.
x(), pDest.
y(), pDest.
z(), 0, 0, 0};
273 if ((pDest1 - pDest2).
mag() < 1
e-10 || !sStart.
isValid()) {
275 if ((pDest1 - pDest2).mag() < 1
e-10)
276 edm::LogWarning(
"SteppingHelixPropagator") <<
"Can't propagate: points are too close" << std::endl;
278 edm::LogWarning(
"SteppingHelixPropagator") <<
"Can't propagate: invalid input state" << std::endl;
288 double pars[6] = {pDest1.
x(), pDest1.
y(), pDest1.
z(), pDest2.
x(), pDest2.
y(), pDest2.
z()};
298 svBuf[
cIndex_(nPoints)] = sStart;
300 svBuf[
cIndex_(nPoints)] = sStart;
312 const double pars[6],
325 if (fabs(dist) > 1e6)
331 <<
" Failed after first refToDest check with status "
338 bool makeNextStep =
true;
345 double distMag = 1e12;
346 double tanDistMag = 1e12;
348 double distMat = 1e12;
349 double tanDistMat = 1e12;
351 double tanDistNextCheck = -0.1;
352 double tanDistMagNextCheck = -0.1;
353 double tanDistMatNextCheck = -0.1;
360 bool isFirstStep =
true;
361 bool expectNewMagVolume =
false;
364 while (makeNextStep) {
366 svCurrent = &svBuf[
cIndex_(nPoints - 1)];
367 double curZ = svCurrent->
r3.z();
368 double curR = svCurrent->
r3.perp();
369 if (fabs(curZ) < 440 && curR < 260)
376 if (!
useIsYokeFlag_ && fabs(curZ) < 667 && curR > 380 && curR < 850) {
377 dStep = 5 * (1 + 0.2 * svCurrent->
p3.mag());
383 tanDistNextCheck -= oldDStep;
384 tanDistMagNextCheck -= oldDStep;
385 tanDistMatNextCheck -= oldDStep;
387 if (tanDistNextCheck < 0) {
390 refToDest(
type, (*svCurrent), pars, dist, tanDist, refDirection);
392 if (fabs(tanDist) > 4. * (fabs(dist)))
393 tanDist *= tanDist == 0 ? 0 : fabs(dist / tanDist * 4.);
395 tanDistNextCheck = fabs(tanDist) * 0.5 - 0.5;
399 oldRefDirection = refDirection;
401 tanDist = tanDist > 0. ? tanDist - oldDStep : tanDist + oldDStep;
402 refDirection = oldRefDirection;
404 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
405 <<
"Skipped refToDest: guess tanDist = " << tanDist <<
" next check at " << tanDistNextCheck
409 double fastSkipDist = fabs(dist) > fabs(tanDist) ? tanDist : dist;
415 if (fabs(tanDist) < 0.1 && refDirection !=
dir) {
419 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
420 <<
"NOTE: overstepped last time: switch direction (can do it if within 1 mm)" << std::endl;
425 if (tanDistMagNextCheck < 0) {
427 (*svCurrent),
dir, distMag, tanDistMag, fabs(fastSkipDist), expectNewMagVolume, fabs(tanDist));
429 if (fabs(tanDistMag) > 4. * (fabs(distMag)))
430 tanDistMag *= tanDistMag == 0 ? 0 : fabs(distMag / tanDistMag * 4.);
432 tanDistMagNextCheck = fabs(tanDistMag) * 0.5 - 0.5;
434 if (tanDistMagNextCheck >
defaultStep_ * 20. || fabs(dist) < fabs(distMag) ||
438 tanDistMagNextCheck = -1;
441 tanDistMag = tanDistMag > 0. ? tanDistMag - oldDStep : tanDistMag + oldDStep;
443 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
444 <<
"Skipped refToMag: guess tanDistMag = " << tanDistMag <<
" next check at "
445 << tanDistMagNextCheck;
450 if (tanDistMatNextCheck < 0) {
451 resultToMat =
refToMatVolume((*svCurrent),
dir, distMat, tanDistMat, fabs(fastSkipDist));
453 if (fabs(tanDistMat) > 4. * (fabs(distMat)))
454 tanDistMat *= tanDistMat == 0 ? 0 : fabs(distMat / tanDistMat * 4.);
456 tanDistMatNextCheck = fabs(tanDistMat) * 0.5 - 0.5;
458 if (tanDistMatNextCheck >
defaultStep_ * 20. || fabs(dist) < fabs(distMat) ||
462 tanDistMatNextCheck = -1;
465 tanDistMat = tanDistMat > 0. ? tanDistMat - oldDStep : tanDistMat + oldDStep;
467 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
468 <<
"Skipped refToMat: guess tanDistMat = " << tanDistMat <<
" next check at "
469 << tanDistMatNextCheck;
473 double rDotP = svCurrent->
r3.dot(svCurrent->
p3);
474 if ((fabs(curZ) > 1.5
e3 || curR > 800.) &&
476 dStep = fabs(tanDist) - 1
e-12;
478 double tanDistMin = fabs(tanDist);
479 if (tanDistMin > fabs(tanDistMag) + 0.05 &&
481 tanDistMin = fabs(tanDistMag) + 0.05;
482 expectNewMagVolume =
true;
484 expectNewMagVolume =
false;
487 tanDistMin = fabs(tanDistMat) + 0.05;
488 if (expectNewMagVolume)
489 expectNewMagVolume =
false;
492 if (tanDistMin * fabs(svCurrent->
dEdx) > 0.5 * svCurrent->
p3.mag()) {
493 tanDistMin = 0.5 * svCurrent->
p3.mag() / fabs(svCurrent->
dEdx);
494 if (expectNewMagVolume)
495 expectNewMagVolume =
false;
498 double tanDistMinLazy = fabs(tanDistMin);
501 tanDistMinLazy = fabs(tanDistMin) * 0.5;
504 if (fabs(tanDistMinLazy) < dStep) {
505 dStep = fabs(tanDistMinLazy);
511 if (dStep > 1
e-10 && !(fabs(dist) < fabs(
epsilon))) {
527 svCurrent = &svBuf[
cIndex_(nPoints - 1)];
530 tanDistNextCheck = -1;
531 tanDistMagNextCheck = -1;
532 tanDistMatNextCheck = -1;
537 if (nOsc > 1 && fabs(dStep) >
epsilon) {
539 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Ooops" << std::endl;
542 if (fabs(dist) < fabs(
epsilon))
548 double nextTanDist = 0;
553 svCurrent = &svBuf[
cIndex_(nPoints - 1)];
554 refToDest(
type, (*svCurrent), pars, nextDist, nextTanDist, nextRefDirection);
555 if (fabs(nextDist) > fabs(dist)) {
557 svCurrent = &svBuf[
cIndex_(nPoints - 1)];
560 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
561 <<
"Found real local minimum in PCA" << std::endl;
567 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Found branch point in PCA"
576 if (svCurrent->
p3.mag() < 0.1)
579 curZ = svCurrent->
r3.z();
580 curR = svCurrent->
r3.perp();
581 if (curR > 20000 || fabs(curZ) > 20000)
599 <<
" Momentum at last point is too low (<0.1) p_last = " << svCurrent->
p3.mag()
603 <<
" Went too far: the last point is at " << svCurrent->
r3 << std::endl;
606 <<
" Infinite loop condidtion detected: going in cycles. Break after 6 cycles"
610 <<
" Tired to go farther. Made too many steps: more than "
617 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"going to radius "
621 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"going to z " << pars[
Z_P]
625 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"going to pathL "
629 Point rPlane(pars[0], pars[1], pars[2]);
630 Vector nPlane(pars[3], pars[4], pars[5]);
631 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"going to plane r0:" << rPlane
632 <<
" n:" << nPlane << std::endl;
635 Point rDest(pars[0], pars[1], pars[2]);
636 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"going to PCA to point "
637 << rDest << std::endl;
640 Point rDest1(pars[0], pars[1], pars[2]);
641 Point rDest2(pars[3], pars[4], pars[5]);
642 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"going to PCA to line "
643 << rDest1 <<
" - " << rDest2 << std::endl;
646 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"going to NOT IMPLEMENTED"
650 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Made " << nPoints - 1
651 <<
" steps and stopped at(cur step) " << svCurrent->
r3 <<
" nOsc " << nOsc << std::endl;
675 float gpmag = gPointNorZ.
mag2();
676 float pmag2 =
p3.mag2();
682 if (pmag2 < 1
e-18
f) {
687 if (!(gpmag == gpmag)) {
689 edm::LogWarning(
"SteppingHelixPropagatorNAN") <<
"Initial point is a nan";
693 if (!(pmag2 == pmag2)) {
695 edm::LogWarning(
"SteppingHelixPropagatorNAN") <<
"Initial momentum is a nan";
706 double curRad = svCurrent.
r3.perp();
707 if (curRad > 380 && curRad < 850 && fabs(svCurrent.
r3.z()) < 667) {
715 <<
"Failed to cast into VolumeBasedMagneticField: fall back to the default behavior"
717 svCurrent.
magVol =
nullptr;
720 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Got volume at "
721 << svCurrent.
magVol << 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
733 <<
" at " << lPoint << std::endl;
735 svCurrent.
bf.set(bf.
x(), bf.
y(), bf.
z());
739 svCurrent.
bf.set(bf.x(), bf.y(), bf.z());
741 if (svCurrent.
bf.mag2() < 1
e-32)
742 svCurrent.
bf.set(0., 0., 1
e-16);
744 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
745 <<
"Loaded bfield double: " << svCurrent.
bf <<
" from float: " << bf <<
" at float "
746 << gPointNorZ <<
" double " << svCurrent.
r3 << std::endl;
749 double dEdXPrime = 0;
753 dEdx =
getDeDx(svCurrent, dEdXPrime, radX0, rzLims);
756 svCurrent.
radX0 = radX0;
757 svCurrent.
rzLims = rzLims;
765 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
766 <<
"Loaded at path: " << svCurrent.
path() <<
" radPath: " << svCurrent.
radPath() <<
" p3 "
767 <<
" pt: " << svCurrent.
p3.perp() <<
" phi: " << svCurrent.
p3.phi()
768 <<
" eta: " << svCurrent.
p3.eta() <<
" " << svCurrent.
p3 <<
" r3: " << svCurrent.
r3
769 <<
" bField: " << svCurrent.
bf.mag() << std::endl;
770 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
771 <<
"Input Covariance in Curvilinear RF " << covCurv << std::endl;
784 svNext.
q = svPrevious.
q;
785 svNext.
dir = dS > 0.0 ? 1. : -1.;
787 svNext.
p3 *= (svPrevious.
p3.mag() - svNext.
dir * fabs(dP));
789 svNext.
r3 = svPrevious.
r3;
803 double curRad = svNext.
r3.perp();
804 if (curRad > 380 && curRad < 850 && fabs(svNext.
r3.z()) < 667) {
811 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
812 <<
"Failed to cast into VolumeBasedMagneticField" << std::endl;
816 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Got volume at "
817 << svNext.
magVol << std::endl;
823 svNext.
bf.set(bf.x(), bf.y(), bf.z());
827 svNext.
bf.set(bf.x(), bf.y(), bf.z());
829 if (svNext.
bf.mag2() < 1
e-32)
830 svNext.
bf.set(0., 0., 1
e-16);
832 double dEdXPrime = 0;
839 svNext.
radX0 = radX0;
847 ROOT::Math::AssignSym::Evaluate(svNext.
covCurv,
tmp * ROOT::Math::Transpose(dCovCurvTransform));
857 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Now at path: " << svNext.
path()
858 <<
" radPath: " << svNext.
radPath() <<
" p3 "
859 <<
" pt: " << svNext.
p3.perp() <<
" phi: " << svNext.
p3.phi() <<
" eta: " << svNext.
p3.eta()
860 <<
" " << svNext.
p3 <<
" r3: " << svNext.
r3
861 <<
" dPhi: " << acos(svNext.
p3.unit().dot(svPrevious.
p3.unit())) <<
" bField: " << svNext.
bf.mag()
862 <<
" dedx: " << svNext.
dEdx << std::endl;
863 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"New Covariance "
864 << svNext.
covCurv << std::endl;
865 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Transf by dCovTransform "
866 << dCovCurvTransform << std::endl;
875 rep.lY *= 1. /
tau.perp();
886 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Make atom step "
887 << svCurrent.
path() <<
" with step " << dS <<
" in direction " <<
dir << std::endl;
893 double curP = svCurrent.
p3.mag();
907 double p0Inv = 1. / p0;
908 double b0 = svCurrent.
bf.mag();
911 double phi = (2.99792458e-3 * svCurrent.
q *
b0 * p0Inv) * dS / 2.;
912 bool phiSmall = fabs(
phi) < 1
e-4;
917 double oneLessCosPhi = 0;
918 double oneLessCosPhiOPhi = 0;
919 double phiLessSinPhiOPhi = 0;
923 double phi3 = phi2 *
phi;
924 double phi4 = phi3 *
phi;
925 oneLessCosPhi = phi2 / 2. - phi4 / 24. + phi2 * phi4 / 720.;
926 oneLessCosPhiOPhi = 0.5 *
phi - phi3 / 24. + phi2 * phi3 / 720.;
927 phiLessSinPhiOPhi =
phi *
phi / 6. - phi4 / 120. + phi4 * phi2 / 5040.;
931 oneLessCosPhi = 1. - cosPhi;
932 oneLessCosPhiOPhi = oneLessCosPhi /
phi;
933 double sinPhiOPhi = sinPhi /
phi;
934 phiLessSinPhiOPhi = 1 - sinPhiOPhi;
942 double tauB =
tau.dot(bHat);
946 drVec = bbtVec * phiLessSinPhiOPhi;
947 drVec -= btVec * oneLessCosPhiOPhi;
953 radX0 = svCurrent.
radX0;
957 drVec += svCurrent.
r3;
962 bf.set(bfGV.
x(), bfGV.
y(), bfGV.
z());
965 bf.set(bfGV.
x(), bfGV.
y(), bfGV.
z());
971 bf.set(0., 0., 1
e-16);
974 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Improved b " <<
b0
975 <<
" at r3 " << drVec << std::endl;
978 if (fabs((
b0 - b0Init) * dS) > 1) {
981 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Large bf*dS change "
982 << fabs((
b0 - svCurrent.
bf.mag()) * dS) <<
" --> recalc dedx" << std::endl;
986 svNext.
p3 = svCurrent.
p3;
993 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"New dEdX= " <<
dEdx
994 <<
" dP= " << dP <<
" for p0 " << p0 << std::endl;
1003 phi = (2.99792458e-3 * svCurrent.
q *
b0 * p0Inv) * dS;
1004 phiSmall = fabs(
phi) < 1
e-4;
1008 double phi3 = phi2 *
phi;
1009 double phi4 = phi3 *
phi;
1010 sinPhi =
phi - phi3 / 6. + phi4 *
phi / 120.;
1011 cosPhi = 1. - phi2 / 2. + phi4 / 24.;
1012 oneLessCosPhi = phi2 / 2. - phi4 / 24. + phi2 * phi4 / 720.;
1013 oneLessCosPhiOPhi = 0.5 *
phi - phi3 / 24. + phi2 * phi3 / 720.;
1014 phiLessSinPhiOPhi =
phi *
phi / 6. - phi4 / 120. + phi4 * phi2 / 5040.;
1018 oneLessCosPhi = 1. - cosPhi;
1019 oneLessCosPhiOPhi = oneLessCosPhi /
phi;
1020 double sinPhiOPhi = sinPhi /
phi;
1021 phiLessSinPhiOPhi = 1. - sinPhiOPhi;
1027 btVec = bHat.cross(
tau);
1028 tauB =
tau.dot(bHat);
1029 bbtVec = bHat * tauB -
tau;
1031 tauNext = bbtVec * oneLessCosPhi;
1032 tauNext -= btVec * sinPhi;
1034 double tauNextPerpInv = 1. / tauNext.perp();
1035 drVec = bbtVec * phiLessSinPhiOPhi;
1036 drVec -= btVec * oneLessCosPhiOPhi;
1042 double dX0 = fabs(dS) / radX0;
1049 double x0 = fabs(svCurrent.
radPath());
1050 double alphaX0 = 13.6e-3 * p0Inv;
1052 double betaX0 = 0.038;
1053 double logx0p1 =
log(x0 + 1);
1054 theta02 = dX0 * alphaX0 * (1 + betaX0 * logx0p1) * (1 + betaX0 * logx0p1 + 2. * betaX0 * x0 / (x0 + 1));
1056 theta02 = 196
e-6 * p0Inv * p0Inv *
1060 double epsilonP0 = 1. + dP / (p0 - 0.5 * dP);
1079 double qbp = svCurrent.
q * p0Inv;
1084 double t11 =
tau.x();
1085 double t12 =
tau.y();
1086 double t13 =
tau.z();
1087 double t21 = tauNext.x();
1088 double t22 = tauNext.y();
1089 double t23 = tauNext.z();
1090 double cosl0 =
tau.perp();
1092 double cosecl1 = tauNextPerpInv;
1100 double q = -
phi / dS;
1102 double sint = -sinPhi;
1103 double cost = cosPhi;
1104 double hn1 = hn.x();
1105 double hn2 = hn.y();
1106 double hn3 = hn.z();
1107 double dx1 =
dx.x();
1108 double dx2 =
dx.y();
1109 double dx3 =
dx.z();
1112 double gamma = hn1 * t21 + hn2 * t22 + hn3 * t23;
1113 double an1 = hn2 * t23 - hn3 * t22;
1114 double an2 = hn3 * t21 - hn1 * t23;
1115 double an3 = hn1 * t22 - hn2 * t21;
1117 double auInv = cosl0;
1118 double au = auInv > 0 ? 1. / auInv : 1e24;
1120 double u11 = -au * t12;
1121 double u12 = au * t11;
1122 double v11 = -t13 * u12;
1123 double v12 = t13 * u11;
1125 auInv =
sqrt(1. - t23 * t23);
1126 au = auInv > 0 ? 1. / auInv : 1e24;
1128 double u21 = -au * t22;
1129 double u22 = au * t21;
1130 double v21 = -t23 * u22;
1131 double v22 = t23 * u21;
1139 double anv = -(hn1 * u21 + hn2 * u22);
1140 double anu = (hn1 * v21 + hn2 * v22 + hn3 * v23);
1141 double omcost = oneLessCosPhi;
1142 double tmsint = -
phi * phiLessSinPhiOPhi;
1144 double hu1 = -hn3 * u12;
1145 double hu2 = hn3 * u11;
1146 double hu3 = hn1 * u12 - hn2 * u11;
1148 double hv1 = hn2 * v13 - hn3 * v12;
1149 double hv2 = hn3 * v11 - hn1 * v13;
1150 double hv3 = hn1 * v12 - hn2 * v11;
1153 dCCurvTransform(0, 0) = 1. / (epsilonP0 * epsilonP0) * (1. + dS * dEdXPrime);
1157 dCCurvTransform(1, 0) =
phi * p0 / svCurrent.
q * cosecl1 * (sinPhi * bbtVec.z() - cosPhi * btVec.z());
1161 dCCurvTransform(1, 1) =
1162 cost * (v11 * v21 + v12 * v22 + v13 * v23) + sint * (hv1 * v21 + hv2 * v22 + hv3 * v23) +
1163 omcost * (hn1 * v11 + hn2 * v12 + hn3 * v13) * (hn1 * v21 + hn2 * v22 + hn3 * v23) +
1164 anv * (-sint * (v11 * t21 + v12 * t22 + v13 * t23) + omcost * (v11 * an1 + v12 * an2 + v13 * an3) -
1165 tmsint *
gamma * (hn1 * v11 + hn2 * v12 + hn3 * v13));
1167 dCCurvTransform(1, 2) = cost * (u11 * v21 + u12 * v22) + sint * (hu1 * v21 + hu2 * v22 + hu3 * v23) +
1168 omcost * (hn1 * u11 + hn2 * u12) * (hn1 * v21 + hn2 * v22 + hn3 * v23) +
1169 anv * (-sint * (u11 * t21 + u12 * t22) + omcost * (u11 * an1 + u12 * an2) -
1170 tmsint *
gamma * (hn1 * u11 + hn2 * u12));
1171 dCCurvTransform(1, 2) *= cosl0;
1181 dCCurvTransform(2, 0) = -
phi * p0 / svCurrent.
q * cosecl1 * cosecl1 *
1182 (oneLessCosPhi * bHat.z() * btVec.mag2() + sinPhi * btVec.z() + cosPhi * tbtVec.z());
1185 dCCurvTransform(2, 1) =
1186 cost * (v11 * u21 + v12 * u22) + sint * (hv1 * u21 + hv2 * u22) +
1187 omcost * (hn1 * v11 + hn2 * v12 + hn3 * v13) * (hn1 * u21 + hn2 * u22) +
1188 anu * (-sint * (v11 * t21 + v12 * t22 + v13 * t23) + omcost * (v11 * an1 + v12 * an2 + v13 * an3) -
1189 tmsint *
gamma * (hn1 * v11 + hn2 * v12 + hn3 * v13));
1190 dCCurvTransform(2, 1) *= cosecl1;
1192 dCCurvTransform(2, 2) = cost * (u11 * u21 + u12 * u22) + sint * (hu1 * u21 + hu2 * u22) +
1193 omcost * (hn1 * u11 + hn2 * u12) * (hn1 * u21 + hn2 * u22) +
1194 anu * (-sint * (u11 * t21 + u12 * t22) + omcost * (u11 * an1 + u12 * an2) -
1195 tmsint *
gamma * (hn1 * u11 + hn2 * u12));
1196 dCCurvTransform(2, 2) *= cosecl1 * cosl0;
1206 double pp = 1. / qbp;
1208 dCCurvTransform(3, 0) = -
pp * (u21 * dx1 + u22 * dx2);
1209 dCCurvTransform(4, 0) = -
pp * (v21 * dx1 + v22 * dx2 + v23 * dx3);
1211 dCCurvTransform(3, 1) = (sint * (v11 * u21 + v12 * u22) + omcost * (hv1 * u21 + hv2 * u22) +
1212 tmsint * (hn1 * u21 + hn2 * u22) * (hn1 * v11 + hn2 * v12 + hn3 * v13)) /
1215 dCCurvTransform(3, 2) = (sint * (u11 * u21 + u12 * u22) + omcost * (hu1 * u21 + hu2 * u22) +
1216 tmsint * (hn1 * u21 + hn2 * u22) * (hn1 * u11 + hn2 * u12)) *
1219 dCCurvTransform(3, 3) = (u11 * u21 + u12 * u22);
1221 dCCurvTransform(3, 4) = (v11 * u21 + v12 * u22);
1225 dCCurvTransform(4, 1) =
1226 (sint * (v11 * v21 + v12 * v22 + v13 * v23) + omcost * (hv1 * v21 + hv2 * v22 + hv3 * v23) +
1227 tmsint * (hn1 * v21 + hn2 * v22 + hn3 * v23) * (hn1 * v11 + hn2 * v12 + hn3 * v13)) /
1230 dCCurvTransform(4, 2) = (sint * (u11 * v21 + u12 * v22) + omcost * (hu1 * v21 + hu2 * v22 + hu3 * v23) +
1231 tmsint * (hn1 * v21 + hn2 * v22 + hn3 * v23) * (hn1 * u11 + hn2 * u12)) *
1234 dCCurvTransform(4, 3) = (u11 * v21 + u12 * v22);
1236 dCCurvTransform(4, 4) = (v11 * v21 + v12 * v22 + v13 * v23);
1243 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"rep X: " <<
rep.lX <<
" "
1244 <<
rep.lX.mag() <<
"\t Y: " <<
rep.lY <<
" " <<
rep.lY.mag() <<
"\t Z: " <<
rep.lZ <<
" "
1251 double mulRR = theta02 * dS * dS / 3.;
1252 double mulRP = theta02 * fabs(dS) * p0 / 2.;
1253 double mulPP = theta02 * p0 * p0;
1254 double losPP = dP * dP * 1.6 / fabs(dS) * (1.0 + p0 * 1
e-3);
1261 double sinThetaInv = tauNextPerpInv;
1264 double p0Mat2 = p0Mat * p0Mat;
1268 svCurrent.
matDCovCurv(0, 0) = losPP / (p0Mat2 * p0Mat2);
1282 svCurrent.
matDCovCurv(2, 2) = mulPP / p0Mat2 * (sinThetaInv * sinThetaInv);
1283 svCurrent.
matDCovCurv(2, 3) = mulRP / p0Mat * sinThetaInv;
1288 svCurrent.
matDCovCurv(3, 2) = mulRP / p0Mat * sinThetaInv;
1310 dP = -dP > pMag ? -pMag + 1
e-5 : dP;
1313 getNextState(svCurrent, svNext, dP, tauNext, drVec, dS, dS / radX0, dCCurvTransform);
1329 double lR =
sv.r3.perp();
1330 double lZ = fabs(
sv.r3.z());
1335 double dEdX_HCal = 0.95;
1336 double dEdX_ECal = 0.45;
1337 double dEdX_coil = 0.35;
1339 double dEdX_MCh = 0.053;
1340 double dEdX_Trk = 0.0114;
1341 double dEdX_Air = 2E-4;
1342 double dEdX_Vac = 0.0;
1344 double radX0_HCal = 1.44 / 0.8;
1345 double radX0_ECal = 0.89 / 0.7;
1346 double radX0_coil = 4.;
1347 double radX0_Fe = 1.76;
1348 double radX0_MCh = 1
e3;
1349 double radX0_Trk = 320.;
1350 double radX0_Air = 3.e4;
1351 double radX0_Vac = 3.e9;
1354 if (!(lR < 380 && lZ < 785)) {
1371 }
else if (lR < 129) {
1379 double lEtaDet = fabs(
sv.r3.eta());
1380 double scaleRadX = lEtaDet > 1.5 ? 0.7724 : 1. / cosh(0.5 * lEtaDet);
1381 scaleRadX *= scaleRadX;
1382 if (lEtaDet > 2 && lZ > 20)
1383 scaleRadX *= (lEtaDet - 1.);
1384 if (lEtaDet > 2.5 && lZ > 20)
1385 scaleRadX *= (lEtaDet - 1.);
1389 else if (lZ < 294 + ecShift) {
1391 rzLims =
MatBounds(2.9, 129, 294, 294 + ecShift);
1394 }
else if (lZ < 372 + ecShift) {
1395 rzLims =
MatBounds(2.9, 129, 294 + ecShift, 372 + ecShift);
1399 else if (lZ < 398 + ecShift) {
1401 MatBounds(2.9, 129, 372 + ecShift, 398 + ecShift);
1402 dEdx = dEdX_HCal * 0.05;
1405 else if (lZ < 555 + ecShift) {
1406 rzLims =
MatBounds(2.9, 129, 398 + ecShift, 555 + ecShift);
1407 dEdx = dEdX_HCal * 0.96;
1408 radX0 = radX0_HCal / 0.96;
1414 if (lZ < 568 + ecShift)
1415 rzLims =
MatBounds(2.9, 129, 555 + ecShift, 568 + ecShift);
1416 else if (lZ < 625 + ecShift) {
1417 if (lR < 85 + ecShift)
1418 rzLims =
MatBounds(2.9, 85, 568 + ecShift, 625 + ecShift);
1420 rzLims =
MatBounds(85, 129, 568 + ecShift, 625 + ecShift);
1421 }
else if (lZ < 785 + ecShift)
1422 rzLims =
MatBounds(2.9, 129, 625 + ecShift, 785 + ecShift);
1423 else if (lZ < 1500 + ecShift)
1424 rzLims =
MatBounds(2.9, 129, 785 + ecShift, 1500 + ecShift);
1426 rzLims =
MatBounds(2.9, 129, 1500 + ecShift, 1E4);
1429 if (!(lZ > 568 + ecShift && lZ < 625 + ecShift && lR > 85)
1430 && !(lZ > 785 + ecShift && lZ < 850 + ecShift && lR > 118)) {
1438 }
else if (lR < 287) {
1439 if (lZ < 372 + ecShift && lR < 177) {
1442 else if (lZ < 343) {
1445 else if (lR < 172) {
1456 }
else if (lZ < 343 + ecShift) {
1457 rzLims =
MatBounds(129, 177, 343, 343 + ecShift);
1460 rzLims =
MatBounds(129, 156, 343 + ecShift, 372 + ecShift);
1461 else if ((lZ - 343 - ecShift) > (lR - 156) * 1.38)
1462 rzLims =
MatBounds(156, 177, 127.72 + ecShift, 372 + ecShift, atan(1.38), 0);
1464 rzLims =
MatBounds(156, 177, 343 + ecShift, 127.72 + ecShift, 0, atan(1.38));
1467 if (!(lR > 135 && lZ < 343 + ecShift && lZ > 304) &&
1468 !(lR > 156 && lZ < 372 + ecShift && lZ > 343 + ecShift && ((lZ - 343. - ecShift) < (lR - 156.) * 1.38))) {
1470 double cosThetaEquiv = 0.8 /
sqrt(1. + lZ * lZ / lR / lR) + 0.2;
1473 dEdx = dEdX_ECal * cosThetaEquiv;
1474 radX0 = radX0_ECal / cosThetaEquiv;
1477 if ((lZ > 304 && lZ < 328 && lR < 177 && lR > 135) && !(lZ > 311 && lR < 172)) {
1481 else if (lZ > 343 && lZ < 343 + ecShift) {
1485 dEdx = dEdX_ECal * 0.2;
1489 }
else if (lZ < 554 + ecShift) {
1491 if (lZ > 372 + ecShift && lZ < 398 + ecShift)
1492 rzLims =
MatBounds(129, 177, 372 + ecShift, 398 + ecShift);
1493 else if (lZ < 548 + ecShift)
1494 rzLims =
MatBounds(129, 177, 398 + ecShift, 548 + ecShift);
1496 rzLims =
MatBounds(129, 177, 548 + ecShift, 554 + ecShift);
1497 }
else if (lR < 193) {
1498 if ((lZ - 307) < (lR - 177.) * 1.739)
1499 rzLims =
MatBounds(177, 193, 0, -0.803, 0, atan(1.739));
1501 rzLims =
MatBounds(177, 193, -0.803, 389, atan(1.739), 0.);
1502 else if (lZ < 389 + ecShift)
1503 rzLims =
MatBounds(177, 193, 389, 389 + ecShift);
1504 else if (lZ < 548 + ecShift)
1505 rzLims =
MatBounds(177, 193, 389 + ecShift, 548 + ecShift);
1507 rzLims =
MatBounds(177, 193, 548 + ecShift, 554 + ecShift);
1508 }
else if (lR < 264) {
1509 double anApex = 375.7278 - 193. / 1.327;
1510 if ((lZ - 375.7278) < (lR - 193.) / 1.327)
1511 rzLims =
MatBounds(193, 264, 0, anApex, 0, atan(1. / 1.327));
1512 else if ((lZ - 392.7278) < (lR - 193.) / 1.327)
1513 rzLims =
MatBounds(193, 264, anApex, anApex + 17., atan(1. / 1.327), atan(1. / 1.327));
1514 else if ((lZ - 392.7278 - ecShift) < (lR - 193.) / 1.327)
1518 anApex + 17. + ecShift,
1522 else if (lZ < 517 + ecShift)
1523 rzLims =
MatBounds(193, 264, anApex + 17. + ecShift, 517 + ecShift, atan(1. / 1.327), 0);
1524 else if (lZ < 548 + ecShift) {
1526 rzLims =
MatBounds(193, 246, 517 + ecShift, 548 + ecShift);
1528 rzLims =
MatBounds(246, 264, 517 + ecShift, 548 + ecShift);
1530 rzLims =
MatBounds(193, 264, 548 + ecShift, 554 + ecShift);
1531 }
else if (lR < 275) {
1537 rzLims =
MatBounds(264, 275, 554, 554 + ecShift);
1544 rzLims =
MatBounds(275, 287, 554, 554 + ecShift);
1547 if ((lZ < 433 || lR < 264) && (lZ < 402 || lR < 275) &&
1548 (lZ < 517 + ecShift || lR < 246)
1550 && lZ < 548 + ecShift && !(lZ < 389 + ecShift && lZ > 335 && lR < 193)
1551 && !(lZ > 307 && lZ < 335 && lR < 193 && ((lZ - 307) > (lR - 177.) * 1.739))
1552 && !(lR < 177 && lZ < 398 + ecShift)
1553 && !(lR < 264 && lR > 193 &&
1554 fabs(441.5 + 0.5 * ecShift - lZ + (lR - 269.) / 1.327) < (8.5 + ecShift * 0.5)))
1558 }
else if ((lR < 193 && lZ > 389 && lZ < 389 + ecShift) ||
1559 (lR > 264 && lR < 287 && lZ > 554 && lZ < 554 + ecShift) ||
1560 (lR < 264 && lR > 193 &&
1561 fabs(441.5 + 8.5 + 0.5 * ecShift - lZ + (lR - 269.) / 1.327) < ecShift * 0.5)) {
1565 dEdx = dEdX_HCal * 0.05;
1570 else if (lZ < 564 + ecShift) {
1572 rzLims =
MatBounds(129, 251, 554 + ecShift, 564 + ecShift);
1577 rzLims =
MatBounds(251, 287, 554 + ecShift, 564 + ecShift);
1581 }
else if (lZ < 625 + ecShift) {
1582 rzLims =
MatBounds(129, 287, 564 + ecShift, 625 + ecShift);
1585 }
else if (lZ < 785 + ecShift) {
1587 rzLims =
MatBounds(129, 275, 625 + ecShift, 785 + ecShift);
1589 if (lZ < 720 + ecShift)
1590 rzLims =
MatBounds(275, 287, 625 + ecShift, 720 + ecShift);
1592 rzLims =
MatBounds(275, 287, 720 + ecShift, 785 + ecShift);
1594 if (!(lR > 275 && lZ < 720 + ecShift)) {
1602 }
else if (lZ < 850 + ecShift) {
1603 rzLims =
MatBounds(129, 287, 785 + ecShift, 850 + ecShift);
1606 }
else if (lZ < 910 + ecShift) {
1607 rzLims =
MatBounds(129, 287, 850 + ecShift, 910 + ecShift);
1611 else if (lZ < 975 + ecShift) {
1612 rzLims =
MatBounds(129, 287, 910 + ecShift, 975 + ecShift);
1615 }
else if (lZ < 1000 + ecShift) {
1616 rzLims =
MatBounds(129, 287, 975 + ecShift, 1000 + ecShift);
1620 else if (lZ < 1063 + ecShift) {
1621 rzLims =
MatBounds(129, 287, 1000 + ecShift, 1063 + ecShift);
1624 }
else if (lZ < 1073 + ecShift) {
1625 rzLims =
MatBounds(129, 287, 1063 + ecShift, 1073 + ecShift);
1628 }
else if (lZ < 1E4) {
1629 rzLims =
MatBounds(129, 287, 1073 + ecShift, 1E4);
1636 }
else if (lR < 380 && lZ < 667) {
1658 bool isIron =
false;
1661 isIron =
sv.isYokeVol;
1663 double bMag =
sv.bf.mag();
1664 isIron = (bMag > 0.75 && !(lZ > 500 && lR < 500 && bMag < 1.15) && !(lZ < 450 && lR > 420 && bMag < 1.15));
1681 }
else if (lR > 750) {
1685 }
else if (lZ < 667 + ecShift) {
1686 rzLims =
MatBounds(287, 750, 667, 667 + ecShift);
1691 else if (lZ < 724 + ecShift) {
1693 rzLims =
MatBounds(287, 380, 667 + ecShift, 724 + ecShift);
1695 rzLims =
MatBounds(380, 750, 667 + ecShift, 724 + ecShift);
1698 }
else if (lZ < 785 + ecShift) {
1700 rzLims =
MatBounds(287, 380, 724 + ecShift, 785 + ecShift);
1702 rzLims =
MatBounds(380, 750, 724 + ecShift, 785 + ecShift);
1706 else if (lZ < 850 + ecShift) {
1707 rzLims =
MatBounds(287, 750, 785 + ecShift, 850 + ecShift);
1710 }
else if (lZ < 910 + ecShift) {
1711 rzLims =
MatBounds(287, 750, 850 + ecShift, 910 + ecShift);
1715 else if (lZ < 975 + ecShift) {
1716 rzLims =
MatBounds(287, 750, 910 + ecShift, 975 + ecShift);
1719 }
else if (lZ < 1000 + ecShift) {
1720 rzLims =
MatBounds(287, 750, 975 + ecShift, 1000 + ecShift);
1724 else if (lZ < 1063 + ecShift) {
1726 rzLims =
MatBounds(287, 360, 1000 + ecShift, 1063 + ecShift);
1732 rzLims =
MatBounds(360, 750, 1000 + ecShift, 1063 + ecShift);
1736 }
else if (lZ < 1073 + ecShift) {
1737 rzLims =
MatBounds(287, 750, 1063 + ecShift, 1073 + ecShift);
1741 }
else if (lZ < 1E4) {
1742 rzLims =
MatBounds(287, 750, 1073 + ecShift, 1E4);
1754 double p0 =
sv.p3.mag();
1755 double logp0 =
log(p0);
1756 double p0powN33 = 0;
1759 double xx = 1. / p0;
1764 double dEdX_mat = -(11.4 + 0.96 * fabs(logp0 +
log(2.8)) + 0.033 * p0 * (1.0 - p0powN33)) * 1
e-3;
1767 dEdXPrime =
dEdx == 0 ? 0 : -
dEdx * (0.96 / p0 + 0.033 - 0.022 * p0powN33) * 1
e-3;
1775 if (ind != 0 &&
result == 0) {
1783 const double pars[6],
1787 double fastSkipDist)
const {
1793 double curR =
sv.r3.perp();
1795 if (fabs(dist) > fastSkipDist) {
1799 double curP2 =
sv.p3.mag2();
1800 double curPtPos2 =
sv.p3.perp2();
1801 if (curPtPos2 < 1
e-16)
1805 (
sv.r3.x() *
sv.p3.x() +
sv.r3.y() *
sv.p3.y());
1807 tanDist = dist *
sqrt(curP2 / curPtPos2);
1811 double curZ =
sv.r3.z();
1812 dist = pars[
Z_P] - curZ;
1813 if (fabs(dist) > fastSkipDist) {
1817 double curP =
sv.p3.mag();
1819 tanDist = dist /
sv.p3.z() * curP;
1823 Point rPlane(pars[0], pars[1], pars[2]);
1824 Vector nPlane(pars[3], pars[4], pars[5]);
1829 double dRDotN = (
sv.r3.x() - rPlane.x()) * nPlane.x() + (
sv.r3.y() - rPlane.y()) * nPlane.y() +
1830 (
sv.r3.z() - rPlane.z()) * nPlane.z();
1832 dist = fabs(dRDotN);
1833 if (dist > fastSkipDist) {
1837 double curP =
sv.p3.mag();
1839 double p0Inv = 1. / p0;
1842 double tN =
tau.dot(nPlane);
1844 double b0 =
sv.bf.mag();
1845 if (fabs(tN) > 1
e-24) {
1846 tanDist = -dRDotN / tN;
1849 if (fabs(dRDotN) > 1
e-24)
1854 if (fabs(tanDist) > 1
e4)
1857 double b0Inv = 1. /
b0;
1858 double tNInv = 1. / tN;
1861 double bHatN = bHat.dot(nPlane);
1862 double cosPB = bHat.dot(
tau);
1863 double kVal = 2.99792458e-3 *
sv.q * p0Inv *
b0;
1864 double aVal = tanDist * kVal;
1866 double bVal = lVec.dot(nPlane) * tNInv;
1867 if (fabs(aVal * bVal) < 0.3) {
1869 1. - bHatN * cosPB * tNInv;
1870 double aacVal = cVal * aVal * aVal;
1871 if (fabs(aacVal) < 1) {
1872 double tanDCorr = bVal / 2. + (bVal * bVal / 2. + cVal / 6) * aVal;
1876 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific << tanDist <<
" vs "
1877 << tanDist * (1. + tanDCorr) <<
" corr " << tanDist * tanDCorr << std::endl;
1878 tanDist *= (1. + tanDCorr);
1881 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"AACVal "
1882 << fabs(aacVal) <<
" = " << aVal <<
"**2 * " << cVal <<
" too large:: will not converge"
1887 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"ABVal "
1888 << fabs(aVal * bVal) <<
" = " << aVal <<
" * " << bVal <<
" too large:: will not converge"
1895 Point cVertex(pars[0], pars[1], pars[2]);
1896 if (cVertex.perp2() < 1
e-10) {
1899 double relV3mag = relV3.mag();
1901 double theta(pars[3]);
1905 double cosV3Theta = relV3.z() / relV3mag;
1908 if (cosV3Theta < -1)
1910 double sinV3Theta =
sqrt(1. - cosV3Theta * cosV3Theta);
1912 double sinDTheta = sinTheta * cosV3Theta - cosTheta * sinV3Theta;
1913 double cosDTheta = cosTheta * cosV3Theta + sinTheta * sinV3Theta;
1914 bool isInside = sinTheta > sinV3Theta && cosTheta * cosV3Theta > 0;
1915 dist = isInside || cosDTheta > 0 ? relV3mag * sinDTheta : relV3mag;
1916 if (fabs(dist) > fastSkipDist) {
1921 double relV3phi = relV3.phi();
1922 double normPhi = isInside ?
Geom::pi() + relV3phi : relV3phi;
1927 norm.setRThetaPhi(fabs(dist), normTheta, normPhi);
1928 double curP =
sv.p3.mag();
1929 double cosp3theta =
sv.p3.z() / curP;
1932 if (cosp3theta < -1)
1934 double sineConeP = sinTheta * cosp3theta - cosTheta *
sqrt(1. - cosp3theta * cosp3theta);
1936 double sinSolid = norm.dot(
sv.p3) / (fabs(dist) * curP);
1937 tanDist = fabs(sinSolid) > fabs(sineConeP) ? dist / fabs(sinSolid) : dist / fabs(sineConeP);
1941 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Cone pars: theta " <<
theta
1942 <<
" normTheta " << norm.theta() <<
" p3Theta " <<
sv.p3.theta() <<
" sinD: " << sineConeP
1943 <<
" sinSolid " << sinSolid;
1946 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
1947 <<
"refToDest:toCone the point is " << (isInside ?
"in" :
"out") <<
"side the cone"
1956 double curS = fabs(
sv.path());
1958 if (fabs(dist) > fastSkipDist) {
1967 Point pDest(pars[0], pars[1], pars[2]);
1968 double curP =
sv.p3.mag();
1969 dist = (
sv.r3 - pDest).
mag() + 1
e-24;
1970 tanDist = (
sv.r3.dot(
sv.p3) - pDest.dot(
sv.p3)) / curP;
1972 double b0 =
sv.bf.mag();
1975 double kVal = 2.99792458e-3 *
sv.q / p0 *
b0;
1976 double aVal = fabs(dist * kVal);
1977 tanDist *= 1. / (1. + aVal);
1979 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"corrected by aVal " << aVal
1980 <<
" to " << tanDist;
1986 Point rLine(pars[0], pars[1], pars[2]);
1987 Vector dLine(pars[3], pars[4], pars[5]);
1988 dLine = (dLine - rLine);
1989 dLine *= 1. / dLine.mag();
1991 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"dLine " << dLine;
1994 double curP =
sv.p3.mag();
1995 Vector dRPerp =
dR - dLine * (
dR.dot(dLine));
1997 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"dRperp " << dRPerp;
1999 dist = dRPerp.mag() + 1
e-24;
2000 tanDist = dRPerp.dot(
sv.p3) / curP;
2002 double cosAlpha2 = dLine.dot(
sv.p3) / curP;
2003 cosAlpha2 *= cosAlpha2;
2004 tanDist *= 1. /
sqrt(fabs(1. - cosAlpha2) + 1
e-96);
2007 double b0 =
sv.bf.mag();
2010 double kVal = 2.99792458e-3 *
sv.q / p0 *
b0;
2011 double aVal = fabs(dist * kVal);
2012 tanDist *= 1. / (1. + aVal);
2014 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"corrected by aVal " << aVal
2015 <<
" to " << tanDist;
2029 double tanDistConstrained = tanDist;
2030 if (fabs(tanDist) > 4. * fabs(dist))
2031 tanDistConstrained *= tanDist == 0 ? 0 : fabs(dist / tanDist * 4.);
2034 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"refToDest input: dest" <<
dest
2036 for (
int i = 0;
i < 6;
i++) {
2037 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
", " <<
i <<
" " << pars[
i];
2039 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific << std::endl;
2040 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"refToDest output: "
2041 <<
"\t dist" << dist <<
"\t tanDist " << tanDist <<
"\t tanDistConstr " << tanDistConstrained
2042 <<
"\t refDirection " << refDirection << std::endl;
2044 tanDist = tanDistConstrained;
2053 double fastSkipDist,
2054 bool expectNewMagVolume,
2055 double maxStep)
const {
2060 if (cVol ==
nullptr)
2062 const std::vector<VolumeSide>& cVolFaces(cVol->
faces());
2064 double distToFace[6] = {0, 0, 0, 0, 0, 0};
2065 double tanDistToFace[6] = {0, 0, 0, 0, 0, 0};
2072 unsigned int iFDestSorted[6] = {0, 0, 0, 0, 0, 0};
2073 int nDestSorted = 0;
2074 unsigned int nearParallels = 0;
2076 double curP =
sv.p3.mag();
2079 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Trying volume "
2080 <<
" with " << cVolFaces.size() <<
" faces" << std::endl;
2083 unsigned int nFaces = cVolFaces.size();
2084 for (
unsigned int iFace = 0; iFace < nFaces; ++iFace) {
2086 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Too many faces" << std::endl;
2089 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Start with face " << iFace
2095 const Surface* cPlane =
nullptr;
2097 const Cone* cCone =
nullptr;
2098 auto& iSurface = cVolFaces[iFace].surface();
2099 if (
typeid(iSurface) ==
typeid(
const Plane&)) {
2100 cPlane = &cVolFaces[iFace].surface();
2101 }
else if (
typeid(iSurface) ==
typeid(
const Cylinder&)) {
2102 cCyl = dynamic_cast<const Cylinder*>(&cVolFaces[iFace].surface());
2103 }
else if (
typeid(iSurface) ==
typeid(
const Cone&)) {
2104 cCone = dynamic_cast<const Cone*>(&cVolFaces[iFace].surface());
2107 <<
"Could not cast a volume side surface to a known type" << std::endl;
2111 if (cPlane !=
nullptr)
2112 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"The face is a plane at "
2113 << cPlane << std::endl;
2114 if (cCyl !=
nullptr)
2115 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"The face is a cylinder at "
2116 << cCyl << std::endl;
2119 double pars[6] = {0, 0, 0, 0, 0, 0};
2121 if (cPlane !=
nullptr) {
2125 nPlane /= nPlane.mag();
2127 pars[0] = rPlane.x();
2128 pars[1] = rPlane.y();
2129 pars[2] = rPlane.z();
2130 pars[3] = nPlane.x();
2131 pars[4] = nPlane.y();
2132 pars[5] = nPlane.z();
2134 }
else if (cCyl !=
nullptr) {
2136 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Cylinder at "
2141 }
else if (cCone !=
nullptr) {
2143 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Cone at "
2144 << cCone->
position() <<
" rorated by " << cCone->
rotation() <<
" vertex at "
2147 pars[0] = cCone->
vertex().
x();
2148 pars[1] = cCone->
vertex().
y();
2149 pars[2] = cCone->
vertex().
z();
2153 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Unknown surface" << std::endl;
2157 resultToFace[iFace] =
2158 refToDest(dType,
sv, pars, distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2167 double invDTFPosiF = 1. / (1
e-32 + fabs(tanDistToFace[iFace]));
2168 double dSlope = fabs(distToFace[iFace]) * invDTFPosiF;
2169 double maxStepL = maxStep > 100 ? 100 : maxStep;
2172 bool isNearParallel =
2173 fabs(tanDistToFace[iFace]) + 100. * curP * dSlope < maxStepL
2176 if (refDirectionToFace[iFace] ==
dir || isNearParallel) {
2179 iFDestSorted[nDestSorted] = iFace;
2185 if (refDirectionToFace[iFace] ==
dir) {
2188 else if (fabs(distToFace[iFace]) < fabs(distToFace[iDistMin]))
2192 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific << cVol <<
" " << iFace <<
" "
2193 << tanDistToFace[iFace] <<
" " << distToFace[iFace] <<
" " << refDirectionToFace[iFace] <<
" "
2194 <<
dir << std::endl;
2197 for (
int i = 0;
i < nDestSorted; ++
i) {
2198 int iMax = nDestSorted -
i - 1;
2199 for (
int j = 0;
j < nDestSorted -
i; ++
j) {
2200 if (fabs(tanDistToFace[iFDestSorted[
j]]) > fabs(tanDistToFace[iFDestSorted[iMax]])) {
2204 int iTmp = iFDestSorted[nDestSorted -
i - 1];
2205 iFDestSorted[nDestSorted -
i - 1] = iFDestSorted[iMax];
2206 iFDestSorted[iMax] = iTmp;
2210 for (
int i = 0;
i < nDestSorted; ++
i) {
2211 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific << cVol <<
" " <<
i <<
" "
2212 << iFDestSorted[
i] <<
" " << tanDistToFace[iFDestSorted[
i]] << std::endl;
2219 for (
int i = 0;
i < nDestSorted; ++
i) {
2220 iFDest = iFDestSorted[
i];
2225 lDelta *=
sign / curP * fabs(distToFace[iFDest]);
2226 gPointEst += lDelta;
2228 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Linear est point " << gPointEst
2229 <<
" for iFace " << iFDest << std::endl;
2231 GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z());
2232 if (cVol->
inside(gPointEstNorZ)) {
2234 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2235 <<
"The point is inside the volume" << std::endl;
2239 dist = distToFace[iFDest];
2240 tanDist = tanDistToFace[iFDest];
2242 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2243 <<
"Got a point near closest boundary -- face " << iFDest << std::endl;
2253 if (nDestSorted - nearParallels > 0)
2258 double lDist = iDistMin == -1 ? fastSkipDist : fabs(distToFace[iDistMin]);
2259 if (lDist > fastSkipDist)
2260 lDist = fastSkipDist;
2262 lDelta *=
sign / curP * lDist;
2263 gPointEst += lDelta;
2265 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2266 <<
"Linear est point to shortest dist " << gPointEst <<
" for iFace " << iDistMin
2267 <<
" at distance " << lDist *
sign << std::endl;
2269 GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z());
2270 if (cVol->
inside(gPointEstNorZ)) {
2272 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2273 <<
"The point is inside the volume" << std::endl;
2283 tanDist = dist * 1.01;
2285 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2286 <<
"Wrong volume located: return small dist, tandist" << std::endl;
2293 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"All faces are too far"
2297 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Appear to be in a wrong volume"
2301 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Something else went wrong"
2312 double fastSkipDist)
const {
2316 double parLim[6] = {
sv.rzLims.rMin,
sv.rzLims.rMax,
sv.rzLims.zMin,
sv.rzLims.zMax,
sv.rzLims.th1,
sv.rzLims.th2};
2318 double distToFace[4] = {0, 0, 0, 0};
2319 double tanDistToFace[4] = {0, 0, 0, 0};
2324 double curP =
sv.p3.mag();
2326 for (
unsigned int iFace = 0; iFace < 4; iFace++) {
2328 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Start with mat face " << iFace
2332 double pars[6] = {0, 0, 0, 0, 0, 0};
2335 if (fabs(parLim[iFace + 2]) < 1
e-6) {
2336 if (
sv.r3.z() < 0) {
2339 pars[2] = -parLim[iFace];
2346 pars[2] = parLim[iFace];
2353 if (
sv.r3.z() > 0) {
2356 pars[2] = parLim[iFace];
2357 pars[3] =
Geom::pi() / 2. - parLim[iFace + 2];
2361 pars[2] = -parLim[iFace];
2362 pars[3] =
Geom::pi() / 2. + parLim[iFace + 2];
2371 resultToFace[iFace] =
2372 refToDest(dType,
sv, pars, distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2379 if (refDirectionToFace[iFace] ==
dir || fabs(distToFace[iFace]) < 2
e-2 * fabs(tanDistToFace[iFace])) {
2383 lDelta *=
sign * fabs(distToFace[iFace]) / curP;
2384 gPointEst += lDelta;
2386 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific <<
"Linear est point "
2387 << gPointEst << std::endl;
2389 double lZ = fabs(gPointEst.z());
2390 double lR = gPointEst.perp();
2391 double tan4 = parLim[4] == 0 ? 0 :
tan(parLim[4]);
2392 double tan5 = parLim[5] == 0 ? 0 :
tan(parLim[5]);
2393 if ((lZ - parLim[2]) > lR * tan4 && (lZ - parLim[3]) < lR * tan5 && lR > parLim[0] && lR < parLim[1]) {
2395 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2396 <<
"The point is inside the volume" << std::endl;
2402 if (fabs(tanDistToFace[iFDest]) > fabs(tanDistToFace[iFace])) {
2408 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2409 <<
"The point is NOT inside the volume" << std::endl;
2416 dist = distToFace[iFDest];
2417 tanDist = tanDistToFace[iFDest];
2419 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2420 <<
"Got a point near closest boundary -- face " << iFDest << std::endl;
2424 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2425 <<
"Failed to find a dest point inside the volume" << std::endl;
2460 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2461 <<
"Volume is magnetic, located at " << vol->
position() << std::endl;
2464 LogTrace(
metname) << std::setprecision(17) << std::setw(20) << std::scientific
2465 <<
"Volume is not magnetic, located at " << vol->
position() << std::endl;