48 if (cache.m_solenoid) {
51 cache.m_fieldCache.getField(
R,
H);
56 getFieldGradient(Cache& cache,
61 if (cache.m_solenoid) {
62 cache.m_fieldCache.getFieldZR(
R,
H, dH);
64 cache.m_fieldCache.getField(
R,
H, dH);
74 rungeKuttaStep(Cache& cache,
bool Jac,
double S,
double*
ATH_RESTRICT P,
bool& InS)
79 const double Pi = 149.89626 *
P[6];
80 double dltm = cache.m_dlt * .03;
85 getField(cache,
R, f0);
87 f0[0] = cache.m_field[0];
88 f0[1] = cache.m_field[1];
89 f0[2] = cache.m_field[2];
93 if (std::abs(
S) < cache.m_helixStep)
97 const double S3 = (1. / 3.) *
S;
98 const double S4 = .25 *
S;
99 const double PS2 =
Pi *
S;
103 const double H0[3] = { f0[0] * PS2, f0[1] * PS2, f0[2] * PS2 };
104 const double A0 =
A[1] * H0[2] -
A[2] * H0[1];
105 const double B0 =
A[2] * H0[0] -
A[0] * H0[2];
106 const double C0 =
A[0] * H0[1] -
A[1] * H0[0];
107 const double A2 = A0 +
A[0];
108 const double B2 = B0 +
A[1];
109 const double C2 = C0 +
A[2];
110 const double A1 = A2 +
A[0];
111 const double B1 = B2 +
A[1];
112 const double C1 = C2 +
A[2];
117 const double gP[3] = {
R[0] + A1 * S4,
R[1] + B1 * S4,
R[2] + C1 * S4 };
118 getField(cache, gP,
f);
125 const double H1[3] = {
f[0] * PS2,
f[1] * PS2,
f[2] * PS2 };
126 const double A3 = (
A[0] + B2 * H1[2]) - C2 * H1[1];
127 const double B3 = (
A[1] + C2 * H1[0]) - A2 * H1[2];
128 const double C3 = (
A[2] + A2 * H1[1]) - B2 * H1[0];
129 const double A4 = (
A[0] + B3 * H1[2]) - C3 * H1[1];
130 const double B4 = (
A[1] + C3 * H1[0]) - A3 * H1[2];
131 const double C4 = (
A[2] + A3 * H1[1]) - B3 * H1[0];
132 const double A5 = 2. * A4 -
A[0];
133 const double B5 = 2. * B4 -
A[1];
134 const double C5 = 2. * C4 -
A[2];
139 const double gP[3] = {
R[0] +
S * A4,
R[1] +
S * B4,
R[2] +
S * C4 };
140 getField(cache, gP,
f);
147 const double H2[3] = {
f[0] * PS2,
f[1] * PS2,
f[2] * PS2 };
148 const double A6 = B5 *
H2[2] - C5 *
H2[1];
149 const double B6 = C5 *
H2[0] - A5 *
H2[2];
150 const double C6 = A5 *
H2[1] - B5 *
H2[0];
154 const double EST = std::abs((A1 + A6) - (A3 + A4)) +
155 std::abs((B1 + B6) - (B3 + B4)) +
156 std::abs((C1 + C6) - (C3 + C4));
157 if (EST > cache.m_dlt) {
162 EST < dltm ? InS = true : InS =
false;
166 const double A00 =
A[0];
167 const double A11 =
A[1];
168 const double A22 =
A[2];
170 const double Aarr[3]{ A00, A11, A22 };
171 const double A0arr[3]{ A0, B0, C0 };
172 const double A3arr[3]{ A3, B3, C3 };
173 const double A4arr[3]{ A4, B4, C4 };
174 const double A6arr[3]{ A6, B6, C6 };
176 A[0] = 2. * A3 + (A0 + A5 + A6);
177 A[1] = 2. * B3 + (B0 + B5 + B6);
178 A[2] = 2. * C3 + (C0 + C5 + C6);
180 double D = (
A[0] *
A[0] +
A[1] *
A[1]) + (
A[2] *
A[2] - 9.);
181 const double Sl = 2. /
S;
182 D = (1. / 3.) - ((1. / 648.) * D) * (12. - D);
184 R[0] += (A2 + A3 + A4) *
S3;
185 R[1] += (B2 + B3 + B4) *
S3;
186 R[2] += (C2 + C3 + C4) *
S3;
194 cache.m_field[0] =
f[0];
195 cache.m_field[1] =
f[1];
196 cache.m_field[2] =
f[2];
197 cache.m_newfield =
false;
217 const double*
A = &
P[3];
230 for (
int i = 7;
i < 42;
i += 7) {
233 const double* dA = &
P[
i + 3];
234 dR[0] += (dA[0] *
S);
235 dR[1] += (dA[1] *
S);
236 dR[2] += (dA[2] *
S);
238 sA[0] = sA[1] = sA[2] = 0.;
253 rungeKuttaStepWithGradient(Cache& cache,
double S,
double*
ATH_RESTRICT P,
bool& InS)
255 const double C33 = 1. / 3.;
259 const double Pi = 149.89626 *
P[6];
260 double dltm = cache.m_dlt * .03;
271 getFieldGradient(cache,
R, f0, g0);
275 const double S3 = C33 *
S;
276 const double S4 = .25 *
S;
277 const double PS2 =
Pi *
S;
284 const double A0 =
A[1] * H0[2] -
A[2] * H0[1];
285 const double B0 =
A[2] * H0[0] -
A[0] * H0[2];
286 const double C0 =
A[0] * H0[1] -
A[1] * H0[0];
287 const double A2 =
A[0] + A0;
288 const double B2 =
A[1] + B0;
289 const double C2 =
A[2] + C0;
290 const double A1 = A2 +
A[0];
291 const double B1 = B2 +
A[1];
292 const double C1 = C2 +
A[2];
296 const double gP1[3] = {
R[0] + A1 * S4,
R[1] + B1 * S4,
R[2] + C1 * S4 };
297 getFieldGradient(cache, gP1,
f1,
g1);
302 const double A3 = B2 * H1[2] - C2 * H1[1] +
A[0];
303 const double B3 = C2 * H1[0] - A2 * H1[2] +
A[1];
304 const double C3 = A2 * H1[1] - B2 * H1[0] +
A[2];
305 const double A4 = B3 * H1[2] - C3 * H1[1] +
A[0];
306 const double B4 = C3 * H1[0] - A3 * H1[2] +
A[1];
307 const double C4 = A3 * H1[1] - B3 * H1[0] +
A[2];
308 const double A5 = A4 -
A[0] + A4;
309 const double B5 = B4 -
A[1] + B4;
310 const double C5 = C4 -
A[2] + C4;
314 const double gP2[3] = {
R[0] +
S * A4,
R[1] +
S * B4,
R[2] +
S * C4 };
315 getFieldGradient(cache, gP2,
f2,
g2);
320 const double A6 = B5 *
H2[2] - C5 *
H2[1];
321 const double B6 = C5 *
H2[0] - A5 *
H2[2];
322 const double C6 = A5 *
H2[1] - B5 *
H2[0];
326 double EST = std::abs((A1 + A6) - (A3 + A4)) + std::abs((B1 + B6) - (B3 + B4)) +
327 std::abs((C1 + C6) - (C3 + C4));
328 if (EST > cache.m_dlt) {
333 EST < dltm ? InS = true : InS =
false;
337 const double A00 =
A[0];
338 const double A11 =
A[1];
339 const double A22 =
A[2];
340 R[0] += (A2 + A3 + A4) *
S3;
341 A[0] = ((A0 + 2. * A3) + (A5 + A6)) * C33;
342 R[1] += (B2 + B3 + B4) *
S3;
343 A[1] = ((B0 + 2. * B3) + (B5 + B6)) * C33;
344 R[2] += (C2 + C3 + C4) *
S3;
345 A[2] = ((C0 + 2. * C3) + (C5 + C6)) * C33;
346 const double CBA = 1. / std::sqrt(
A[0] *
A[0] +
A[1] *
A[1] +
A[2] *
A[2]);
351 const double Sl = 2. /
S;
358 for (
int i = 3;
i != 12; ++
i) {
359 H0[
i] = g0[
i - 3] * PS2;
360 H1[
i] =
g1[
i - 3] * PS2;
364 for (
int i = 7;
i < 35;
i += 7) {
367 double* dA = &
P[
i + 3];
368 double dH0 = H0[3] * dR[0] + H0[4] * dR[1] + H0[5] * dR[2];
369 double dH1 = H0[6] * dR[0] + H0[7] * dR[1] + H0[8] * dR[2];
370 double dH2 = H0[9] * dR[0] + H0[10] * dR[1] + H0[11] * dR[2];
372 const double dA0 = (H0[2] * dA[1] - H0[1] * dA[2]) + (
A[1] * dH2 -
A[2] * dH1);
373 const double dB0 = (H0[0] * dA[2] - H0[2] * dA[0]) + (
A[2] * dH0 -
A[0] * dH2);
374 const double dC0 = (H0[1] * dA[0] - H0[0] * dA[1]) + (
A[0] * dH1 -
A[1] * dH0);
375 const double dA2 = dA0 + dA[0];
376 double dX = dR[0] + (dA2 + dA[0]) * S4;
377 const double dB2 = dB0 + dA[1];
378 double dY = dR[1] + (dB2 + dA[1]) * S4;
379 const double dC2 = dC0 + dA[2];
380 double dZ = dR[2] + (dC2 + dA[2]) * S4;
381 dH0 = H1[3] * dX + H1[4] * dY + H1[5] * dZ;
382 dH1 = H1[6] * dX + H1[7] * dY + H1[8] * dZ;
383 dH2 = H1[9] * dX + H1[10] * dY + H1[11] * dZ;
385 const double dA3 = (dA[0] + dB2 * H1[2] - dC2 * H1[1]) + (B2 * dH2 - C2 * dH1);
386 const double dB3 = (dA[1] + dC2 * H1[0] - dA2 * H1[2]) + (C2 * dH0 - A2 * dH2);
387 const double dC3 = (dA[2] + dA2 * H1[1] - dB2 * H1[0]) + (A2 * dH1 - B2 * dH0);
388 const double dA4 = (dA[0] + dB3 * H1[2] - dC3 * H1[1]) + (B3 * dH2 - C3 * dH1);
389 const double dB4 = (dA[1] + dC3 * H1[0] - dA3 * H1[2]) + (C3 * dH0 - A3 * dH2);
390 const double dC4 = (dA[2] + dA3 * H1[1] - dB3 * H1[0]) + (A3 * dH1 - B3 * dH0);
391 const double dA5 = dA4 + dA4 - dA[0];
392 dX = dR[0] + dA4 *
S;
393 const double dB5 = dB4 + dB4 - dA[1];
394 dY = dR[1] + dB4 *
S;
395 const double dC5 = dC4 + dC4 - dA[2];
396 dZ = dR[2] + dC4 *
S;
397 dH0 =
H2[3] * dX +
H2[4] * dY +
H2[5] * dZ;
398 dH1 =
H2[6] * dX +
H2[7] * dY +
H2[8] * dZ;
399 dH2 =
H2[9] * dX +
H2[10] * dY +
H2[11] * dZ;
401 const double dA6 = (dB5 *
H2[2] - dC5 *
H2[1]) + (B5 * dH2 - C5 * dH1);
402 const double dB6 = (dC5 *
H2[0] - dA5 *
H2[2]) + (C5 * dH0 - A5 * dH2);
403 const double dC6 = (dA5 *
H2[1] - dB5 *
H2[0]) + (A5 * dH1 - B5 * dH0);
404 dR[0] += (dA2 + dA3 + dA4) *
S3;
405 dA[0] = ((dA0 + 2. * dA3) + (dA5 + dA6)) * C33;
406 dR[1] += (dB2 + dB3 + dB4) *
S3;
407 dA[1] = ((dB0 + 2. * dB3) + (dB5 + dB6)) * C33;
408 dR[2] += (dC2 + dC3 + dC4) *
S3;
409 dA[2] = ((dC0 + 2. * dC3) + (dC5 + dC6)) * C33;
415 double dH0 = H0[3] * dR[0] + H0[4] * dR[1] + H0[5] * dR[2];
416 double dH1 = H0[6] * dR[0] + H0[7] * dR[1] + H0[8] * dR[2];
417 double dH2 = H0[9] * dR[0] + H0[10] * dR[1] + H0[11] * dR[2];
418 const double dA0 = (H0[2] * dA[1] - H0[1] * dA[2]) + (
A[1] * dH2 -
A[2] * dH1 + A0);
419 const double dB0 = (H0[0] * dA[2] - H0[2] * dA[0]) + (
A[2] * dH0 -
A[0] * dH2 + B0);
420 const double dC0 = (H0[1] * dA[0] - H0[0] * dA[1]) + (
A[0] * dH1 -
A[1] * dH0 + C0);
421 const double dA2 = dA0 + dA[0];
422 double dX = dR[0] + (dA2 + dA[0]) * S4;
423 const double dB2 = dB0 + dA[1];
424 double dY = dR[1] + (dB2 + dA[1]) * S4;
425 const double dC2 = dC0 + dA[2];
426 double dZ = dR[2] + (dC2 + dA[2]) * S4;
427 dH0 = H1[3] * dX + H1[4] * dY + H1[5] * dZ;
428 dH1 = H1[6] * dX + H1[7] * dY + H1[8] * dZ;
429 dH2 = H1[9] * dX + H1[10] * dY + H1[11] * dZ;
432 (dA[0] + dB2 * H1[2] - dC2 * H1[1]) + ((B2 * dH2 - C2 * dH1) + (A3 - A00));
434 (dA[1] + dC2 * H1[0] - dA2 * H1[2]) + ((C2 * dH0 - A2 * dH2) + (B3 - A11));
436 (dA[2] + dA2 * H1[1] - dB2 * H1[0]) + ((A2 * dH1 - B2 * dH0) + (C3 - A22));
438 (dA[0] + dB3 * H1[2] - dC3 * H1[1]) + ((B3 * dH2 - C3 * dH1) + (A4 - A00));
440 (dA[1] + dC3 * H1[0] - dA3 * H1[2]) + ((C3 * dH0 - A3 * dH2) + (B4 - A11));
442 (dA[2] + dA3 * H1[1] - dB3 * H1[0]) + ((A3 * dH1 - B3 * dH0) + (C4 - A22));
443 const double dA5 = dA4 + dA4 - dA[0];
444 dX = dR[0] + dA4 *
S;
445 const double dB5 = dB4 + dB4 - dA[1];
446 dY = dR[1] + dB4 *
S;
447 const double dC5 = dC4 + dC4 - dA[2];
448 dZ = dR[2] + dC4 *
S;
449 dH0 =
H2[3] * dX +
H2[4] * dY +
H2[5] * dZ;
450 dH1 =
H2[6] * dX +
H2[7] * dY +
H2[8] * dZ;
451 dH2 =
H2[9] * dX +
H2[10] * dY +
H2[11] * dZ;
453 const double dA6 = (dB5 *
H2[2] - dC5 *
H2[1]) + (B5 * dH2 - C5 * dH1 + A6);
454 const double dB6 = (dC5 *
H2[0] - dA5 *
H2[2]) + (C5 * dH0 - A5 * dH2 + B6);
455 const double dC6 = (dA5 *
H2[1] - dB5 *
H2[0]) + (A5 * dH1 - B5 * dH0 + C6);
457 dR[0] += (dA2 + dA3 + dA4) *
S3;
458 dA[0] = ((dA0 + 2. * dA3) + (dA5 + dA6)) * C33;
459 dR[1] += (dB2 + dB3 + dB4) *
S3;
460 dA[1] = ((dB0 + 2. * dB3) + (dB5 + dB6)) * C33;
461 dR[2] += (dC2 + dC3 + dC4) *
S3;
462 dA[2] = ((dC0 + 2. * dC3) + (dC5 + dC6)) * C33;
476 const double pi = 3.1415927;
477 const double pi2 = 2. *
pi;
479 const double Ax[3] = {
T(0, 0),
T(1, 0),
T(2, 0) };
480 const double Ay[3] = {
T(0, 1),
T(1, 1),
T(2, 1) };
483 double x = Ro[0] -
T(0, 3);
484 double y = Ro[1] -
T(1, 3);
485 double z = Ro[2] -
T(2, 3);
487 double RC =
x * Ax[0] +
y * Ax[1] +
z * Ax[2];
488 double RS =
x * Ay[0] +
y * Ay[1] +
z * Ay[2];
490 if ((RC * RC + RS * RS) <= (
R *
R))
496 RC =
x * Ax[0] +
y * Ax[1] +
z * Ax[2];
497 RS =
x * Ay[0] +
y * Ay[1] +
z * Ay[2];
507 std::unique_ptr<Trk::TrackParameters>
511 Jac[0] = Jac[6] = Jac[12] = Jac[18] = Jac[20] = 1.;
512 Jac[1] = Jac[2] = Jac[3] = Jac[4] = Jac[5] = Jac[7] = Jac[8] = Jac[9] =
513 Jac[10] = Jac[11] = Jac[13] = Jac[14] = Jac[15] = Jac[16] = Jac[17] = Jac[19] = 0.;
514 return std::unique_ptr<Trk::TrackParameters>(Tp.
clone());
520 std::unique_ptr<Trk::NeutralParameters>
524 Jac[0] = Jac[6] = Jac[12] = Jac[18] = Jac[20] = 1.;
525 Jac[1] = Jac[2] = Jac[3] = Jac[4] = Jac[5] = Jac[7] = Jac[8] = Jac[9] =
526 Jac[10] = Jac[11] = Jac[13] = Jac[14] = Jac[15] = Jac[16] = Jac[17] = Jac[19] = 0.;
527 return std::unique_ptr<Trk::NeutralParameters>(Tp.
clone());
533 std::unique_ptr<Trk::TrackParameters>
535 std::vector<Trk::DestSurf>& SU,
536 std::vector<unsigned int>& So,
538 std::pair<double, int>& SN)
542 const double* SA = &
P[42];
543 double Step = SN.first;
549 As[0] =
A[0] + SA[0] * Step;
550 As[1] =
A[1] + SA[1] * Step;
551 As[2] =
A[2] + SA[2] * Step;
552 const double CBA = 1. / std::sqrt(As[0] * As[0] + As[1] * As[1] + As[2] * As[2]);
554 Rs[0] =
R[0] + Step * (As[0] - .5 * Step * SA[0]);
556 Rs[1] =
R[1] + Step * (As[1] - .5 * Step * SA[1]);
558 Rs[2] =
R[2] + Step * (As[2] - .5 * Step * SA[2]);
565 if (
ds.currentDistance(
false) > .010)
580 Tp.covariance() ? useJac = true : useJac =
false;
583 const double d = 1. /
P[6];
596 return SU[
N].first->createUniqueTrackParameters(
p[0],
p[1],
p[2],
p[3],
p[4], std::nullopt);
603 return SU[
N].first->createUniqueTrackParameters(
p[0],
p[1],
p[2],
p[3],
p[4],
611 stepEstimatorWithCurvature(Cache& cache,
621 const double AStep = std::abs(Step);
622 if (kind || AStep < cache.m_straightStep || !cache.m_mcondition)
625 const double* SA = &
P[42];
626 const double S = .5 * Step;
628 const double Ax =
P[3] +
S * SA[0];
629 const double Ay =
P[4] +
S * SA[1];
630 const double Az =
P[5] +
S * SA[2];
631 const double As = 1. / std::sqrt(Ax * Ax + Ay * Ay + Az * Az);
633 const double PN[6] = {
P[0],
P[1],
P[2], Ax * As, Ay * As, Az * As };
639 if (std::abs(StepN) < AStep)
648 propagateWithJacobian(Cache& cache,
655 const double Smax = 1000.;
656 double Wmax = cache.m_maxPath;
657 double Wwrong = 500.;
661 SA[0] = SA[1] = SA[2] = 0.;
662 cache.m_maxPathLimit =
false;
664 if (cache.m_mcondition && std::abs(
P[6]) > .1)
676 if (cache.m_mcondition && cache.m_direction && cache.m_direction * Step < 0.) {
681 Step > Smax ?
S = Smax : Step < -Smax ?
S = -Smax :
S = Step;
682 double So = std::abs(
S);
690 cache.m_newfield =
true;
691 while (std::abs(Step) > cache.m_straightStep) {
696 if (cache.m_mcondition) {
698 if (!cache.m_needgradient)
699 W += (
S = rungeKuttaStep(cache, Jac,
S,
P, InS));
701 W += (
S = rungeKuttaStepWithGradient(cache,
S,
P, InS));
703 W += (
S = straightLineStep(Jac,
S,
P));
706 Step = stepEstimatorWithCurvature(cache, kind, Su,
P, Q);
711 if (cache.m_direction && cache.m_direction * Step < 0.)
722 const double aS = std::abs(
S);
723 const double aStep = std::abs(Step);
726 else if (!iS && InS && aS * 2. < aStep)
728 if (!
dir && std::abs(
W) > Wwrong)
731 if (iS > 10 || (iS > 3 && std::abs(
S) >= So)) {
736 const double dW = Wmax - std::abs(
W);
737 if (std::abs(
S) > dW) {
738 S > 0. ?
S = dW :
S = -dW;
740 cache.m_maxPathLimit =
true;
749 if (std::abs(Step) < .001)
752 A[0] += (SA[0] * Step);
753 A[1] += (SA[1] * Step);
754 A[2] += (SA[2] * Step);
755 const double CBA = 1. / std::sqrt(
A[0] *
A[0] +
A[1] *
A[1] +
A[2] *
A[2]);
757 R[0] += Step * (
A[0] - .5 * Step * SA[0]);
759 R[1] += Step * (
A[1] - .5 * Step * SA[1]);
761 R[2] += Step * (
A[2] - .5 * Step * SA[2]);
766 bool propagateWithJacobianSwitch(Cache& cache,
778 double s[6] = {
T(0, 3),
T(1, 3),
T(2, 3),
T(0, 2),
T(1, 2),
T(2, 2)};
779 return propagateWithJacobian(cache, useJac, 0,
s,
P, Step);
785 T(0, 3) *
T(0, 2) +
T(1, 3) *
T(1, 2) +
T(2, 3) *
T(2, 2);
798 return propagateWithJacobian(cache, useJac, 1,
s,
P, Step);
804 const double r0[3] = {
P[0],
P[1],
P[2]};
805 double s[9] = {
T(0, 3),
T(1, 3),
T(2, 3),
806 T(0, 2),
T(1, 2),
T(2, 2),
807 cyl->
bounds().
r(), cache.m_direction, 0.};
809 bool status = propagateWithJacobian(cache, useJac, 2,
s,
P, Step);
812 newCrossPoint(*cyl,
r0,
P)) {
814 return propagateWithJacobian(cache, useJac, 2,
s,
P, Step);
821 double s[9] = {
T(0, 3),
T(1, 3),
T(2, 3),
T(0, 2),
T(1, 2),
822 T(2, 2),
k, cache.m_direction, 0.};
823 return propagateWithJacobian(cache, useJac, 3,
s,
P, Step);
834 std::unique_ptr<Trk::NeutralParameters>
835 propagateStraightLine(Cache& cache,
846 return buildTrackParametersWithoutPropagation(Tp, Jac);
849 cache.m_direction = D;
850 cache.m_mcondition =
false;
858 if (!propagateWithJacobianSwitch(cache,Su,useJac,
P,Step)){
862 if (cache.m_direction != 0. && (cache.m_direction * Step) < 0.) {
869 double p = 1. /
P[6];
878 if (cache.m_maxPathLimit)
900 if (!useJac || !Tp.covariance()) {
906 return std::make_unique<Trk::NeutralCurvilinearParameters>(gp,
p[2],
p[3],
p[4]);
920 return std::make_unique<Trk::NeutralCurvilinearParameters>(gp,
p[2],
p[3],
p[4], std::move(
e));
930 globalOneSidePositions(Cache& cache,
931 std::deque<Amg::Vector3D>& GP,
941 for (
int i = 0;
i != 7; ++
i)
945 double R2max =
CB.r() *
CB.r();
946 double Zmax =
CB.halflengthZ();
947 double R2 =
P[0] *
P[0] +
P[1] *
P[1];
948 double Dir =
P[0] *
P[3] +
P[1] *
P[4];
952 if (cache.m_mcondition && std::abs(
P[6]) > .1)
957 if (std::abs(
P[2]) >
Zmax || R2 > R2max)
964 if (std::abs(
Dir) < .00001)
970 for (
int s = 0;
s != 2; ++
s) {
972 cache.m_newfield =
true;
980 for (
int i = 0;
i != 7; ++
i)
982 p[42] =
p[43] =
p[44] = 0.;
984 while (
W < 100000. && ++niter < 1000) {
986 if (cache.m_mcondition) {
987 W += (
S = rungeKuttaStep(cache, 0,
S,
p, InS));
989 W += (
S = straightLineStep(0,
S,
p));
991 if (InS && std::abs(2. *
S) < mS)
1002 R2 =
p[0] *
p[0] +
p[1] *
p[1];
1014 if (std::abs(
p[2]) >
Zmax || R2 > R2max)
1016 if (!
s &&
P[3] *
p[3] +
P[4] *
p[4] < 0.)
1021 if ((
p[0] *
p[3] +
p[1] *
p[4]) *
Dir < 0.) {
1034 Pm[42] = Pm[43] = Pm[44] = 0.;
1037 for (
int s = 0;
s != 3; ++
s) {
1039 cache.m_newfield =
true;
1041 double A = (1. - Pm[5]) * (1. + Pm[5]);
1044 S = -(Pm[0] * Pm[3] + Pm[1] * Pm[4]) /
A;
1045 if (std::abs(
S) < 1. || ++niter > 1000)
1048 if (cache.m_mcondition) {
1049 W += rungeKuttaStep(cache, 0,
S, Pm, InS);
1051 W += straightLineStep(0,
S, Pm);
1065 const double x = GP.front().x();
1066 const double y = GP.front().y();
1067 if ((
x *
x +
y *
y) > (Pm[0] * Pm[0] + Pm[1] * Pm[1])) {
1082 globalTwoSidePositions(Cache& cache,
1083 std::deque<Amg::Vector3D>& GP,
1093 double R2max =
CB.r() *
CB.r();
1094 double Zmax =
CB.halflengthZ();
1095 double R2 =
P[0] *
P[0] +
P[1] *
P[1];
1098 if (cache.m_mcondition && std::abs(
P[6]) > .1)
1103 if (std::abs(
P[2]) >
Zmax || R2 > R2max)
1112 for (
int s = 0;
s != 2; ++
s) {
1114 cache.m_newfield =
true;
1120 for (
int i = 0;
i != 7; ++
i)
1122 p[42] =
p[43] =
p[44] = 0.;
1124 while (
W < 100000. && ++niter < 1000) {
1126 if (cache.m_mcondition) {
1127 W += (
S = rungeKuttaStep(cache, 0,
S,
p, InS));
1129 W += (
S = straightLineStep(0,
S,
p));
1131 if (InS && std::abs(2. *
S) < mS)
1142 R2 =
p[0] *
p[0] +
p[1] *
p[1];
1143 if (std::abs(
p[2]) >
Zmax || R2 > R2max)
1152 std::unique_ptr<Trk::TrackParameters>
1153 propagateRungeKutta(Cache& cache,
1165 cache.m_direction = D;
1168 : cache.m_solenoid =
false;
1169 (useJac && cache.m_usegradient) ? cache.m_needgradient =
true
1170 : cache.m_needgradient =
false;
1172 : cache.m_mcondition =
false;
1175 return buildTrackParametersWithoutPropagation(Tp, Jac);
1183 if (!propagateWithJacobianSwitch(cache,Su,useJac,
P,Step)){
1187 if (cache.m_direction && (cache.m_direction * Step) < 0.) {
1190 cache.m_step = Step;
1195 double p = 1. /
P[6];
1204 if (cache.m_maxPathLimit)
1224 if (!useJac || !Tp.covariance()) {
1228 p[0],
p[1],
p[2],
p[3],
p[4], std::nullopt);
1231 return std::make_unique<Trk::CurvilinearParameters>(gp,
p[2],
p[3],
p[4]);
1244 p[0],
p[1],
p[2],
p[3],
p[4], std::move(
e));
1247 return std::make_unique<Trk::CurvilinearParameters>(
1248 gp,
p[2],
p[3],
p[4], std::move(
e));
1257 propagateRungeKutta(Cache& cache,
1274 cache.m_direction = D;
1280 : cache.m_solenoid =
false;
1281 (useJac && cache.m_usegradient) ? cache.m_needgradient =
true
1282 : cache.m_needgradient =
false;
1284 : cache.m_mcondition =
false;
1292 if (!propagateWithJacobianSwitch(cache,Su,useJac,
P,Step)){
1296 if (cache.m_maxPathLimit ||
1297 (cache.m_direction && (cache.m_direction * Step) < 0.)){
1304 const double p = 1. /
P[6];
1322 Tb.setParametersWithCovariance(&Su,
p, newCov);
1336 globalPositionsImpl(
1339 std::vector<const Trk::Surface*>& SU,
1340 std::vector<std::pair<Amg::Vector3D, double>>& GP,
1343 cache.m_direction = 0.;
1344 cache.m_mcondition =
false;
1345 cache.m_maxPath = 10000.;
1346 cache.m_needgradient =
false;
1356 auto su = SU.begin();
1357 auto sue = SU.end();
1359 for (; su != sue; ++su) {
1361 if (!propagateWithJacobianSwitch(cache, **su,
false,
P, Step)) {
1365 if (cache.m_maxPathLimit) {
1370 GP.emplace_back(gp, Step);
1381 const std::string&
n,
1382 const IInterface*
t)
1386 m_straightStep(.01),
1387 m_usegradient(false) {
1389 declareInterface<Trk::IPropagator>(
this);
1390 declareInterface<Trk::IPatternParametersPropagator>(
this);
1401 ATH_CHECK(m_fieldCondObjInputKey.initialize());
1402 ATH_MSG_DEBUG(
"initialize() init key: " << m_fieldCondObjInputKey.key());
1403 return StatusCode::SUCCESS;
1409 std::unique_ptr<Trk::NeutralParameters>
1414 bool returnCurv)
const
1418 cache.
m_dlt = m_dlt;
1419 cache.m_helixStep = m_helixStep;
1420 cache.m_straightStep = m_straightStep;
1421 cache.m_usegradient = m_usegradient;
1422 return propagateStraightLine(cache,
true, Tp, Su, D, B, J, returnCurv);
1429 std::unique_ptr<Trk::TrackParameters>
1441 Cache cache = getInitializedCache(ctx);
1442 return propagateRungeKutta(cache,
true, Tp, Su, D, B, M, J, returnCurv);
1450 const ::EventContext& ctx,
1458 Cache cache = getInitializedCache(ctx);
1461 propagatedState.reserve(multiComponentState.size());
1464 Trk::MultiComponentState::const_iterator component =
1465 multiComponentState.begin();
1466 for (; component != multiComponentState.end(); ++component) {
1468 if (!currentParameters) {
1471 auto propagatedParameters =
1472 propagateRungeKutta(cache,
true, *currentParameters, surface, direction,
1473 boundaryCheck, fieldProperties, J,
false);
1475 if (!propagatedParameters) {
1478 sumw += component->weight;
1480 propagatedState.push_back({std::move(propagatedParameters),
1481 component->weight});
1484 constexpr
double minPropWeight = (1./12.);
1485 if (
sumw < minPropWeight) {
1486 propagatedState.clear();
1488 return propagatedState;
1495 std::unique_ptr<Trk::TrackParameters>
1502 std::optional<TransportJacobian>& Jac,
1509 Cache cache = getInitializedCache(ctx);
1510 pathLength < 0. ? cache.m_maxPath = 10000. : cache.m_maxPath = pathLength;
1511 auto Tpn = propagateRungeKutta(cache,
true, Tp, Su, D, B, M, J, returnCurv);
1512 pathLength = cache.m_step;
1520 Jac = std::make_optional<Trk::TransportJacobian>(J);
1529 std::unique_ptr<Trk::TrackParameters>
1532 std::vector<DestSurf>& DS,
1534 const MagneticFieldProperties& M,
1536 std::vector<unsigned int>& Sol,
1540 const TrackingVolume*)
const
1543 Cache cache = getInitializedCache(ctx);
1544 Sol.erase(Sol.begin(), Sol.end());
1548 cache.m_direction = D;
1553 Tp.covariance() ? useJac = true : useJac =
false;
1557 M.magneticFieldMode() ==
Trk::FastField ? cache.m_solenoid = true : cache.m_solenoid =
false;
1558 (useJac && m_usegradient) ? cache.m_needgradient =
true : cache.m_needgradient =
false;
1559 M.magneticFieldMode() !=
Trk::NoField ? cache.m_mcondition = true : cache.m_mcondition =
false;
1568 Po[42] = Po[43] = Po[44] = 0.;
1573 double S = cache.m_straightStep;
1576 S = straightLineStep(useJac,
S, Po);
1578 double Wmax = 50000.;
1584 Wmax = std::abs(Path);
1586 std::multimap<double, int> DN;
1595 if (D == 0 && std::abs(Scut[0]) < std::abs(Scut[1]))
1598 if (Smax < 0. && Scut[0] > Smax)
1600 if (Smax > 0. && Scut[1] < Smax)
1602 if (Wmax > 3. * Scut[2])
1603 Wmax = 3. * Scut[2];
1609 for (
int i = 0;
i != 45; ++
i)
1613 double last_St = 0.;
1614 bool last_InS = !InS;
1615 bool reverted_P =
false;
1618 cache.m_newfield =
true;
1627 constexpr
unsigned int max_back_forth_flips{ 100 };
1628 unsigned int flips{0};
1629 int last_surface{-1};
1631 while (std::abs(
W) < Wmax) {
1633 std::pair<double, int> SN;
1636 if (cache.m_mcondition) {
1639 if (reverted_P && std::abs(St - last_St) <= DBL_EPSILON &&
1648 if (!cache.m_needgradient)
1649 S = rungeKuttaStep(cache, useJac, St, Pn, InS);
1651 S = rungeKuttaStepWithGradient(cache, St, Pn, InS);
1655 if (reverted_P && std::abs(St - last_St) <= DBL_EPSILON) {
1663 S = straightLineStep(useJac, St, Pn);
1672 for (
int i = 0;
i != 45; ++
i)
1677 for (
int i = 0;
i != 45; ++
i)
1680 cache.m_newfield =
true;
1683 if (std::abs(
S) + 1. < std::abs(St))
1685 InS ? St = 2. *
S : St =
S;
1687 if (SN.second >= 0) {
1689 double Sa = std::abs(SN.first);
1694 flips += last_surface == SN.second ? std::abs(last_St + SN.first) < 1.e-6
1696 last_surface = SN.second;
1699 if (Sa > cache.m_straightStep) {
1700 if (std::abs(St) > Sa)
1703 Path =
W + SN.first;
1704 if (
auto To{ crossPoint(Tp, DS, Sol, Pn, SN) }; To){
1710 }
else if (std::abs(
S) < DBL_EPSILON){
1714 if (flips > max_back_forth_flips) {
1725 std::unique_ptr<Trk::TrackParameters>
1731 const MagneticFieldProperties& M,
1734 const TrackingVolume*)
const
1737 Cache cache = getInitializedCache(ctx);
1738 return propagateRungeKutta(cache,
false, Tp, Su, D, B, M, J, returnCurv);
1745 std::unique_ptr<Trk::TrackParameters>
1751 const MagneticFieldProperties& M,
1752 std::optional<TransportJacobian>& Jac,
1755 const TrackingVolume*)
const
1758 Cache cache = getInitializedCache(ctx);
1759 auto Tpn{ propagateRungeKutta(cache,
true, Tp, Su, D, B, M, J, returnCurv) };
1767 Jac = std::make_optional<Trk::TransportJacobian>(J);
1780 std::deque<Amg::Vector3D>& GP,
1782 const MagneticFieldProperties& M,
1783 const CylinderBounds& CB,
1786 const TrackingVolume*)
const
1791 Cache cache = getInitializedCache(ctx);
1793 cache.m_direction = std::abs(mS);
1795 globalOneSidePositions(cache, GP,
P, M, CB, mS);
1797 globalTwoSidePositions(cache, GP,
P, M, CB, -mS);
1803 std::optional<Trk::TrackSurfaceIntersection>
1813 Cache cache = getInitializedCache(ctx);
1822 return std::nullopt;
1825 if (!propagateWithJacobianSwitch(cache, (*su), nJ,
P, Step)) {
1826 return std::nullopt;
1831 return std::make_optional<Trk::TrackSurfaceIntersection>(Glo,
Dir, Step);
1848 Cache cache = getInitializedCache(ctx);
1849 return propagateRungeKutta(cache,
true, Ta, Su, Tb, D, M,
S);
1862 const MagneticFieldProperties& M,
1866 Cache cache = getInitializedCache(ctx);
1867 return propagateRungeKutta(cache,
true, Ta, Su, Tb, D, M,
S);
1880 const MagneticFieldProperties& M,
1884 Cache cache = getInitializedCache(ctx);
1885 return propagateRungeKutta(cache,
false, Ta, Su, Tb, D, M,
S);
1898 const MagneticFieldProperties& M,
1902 Cache cache = getInitializedCache(ctx);
1903 return propagateRungeKutta(cache,
false, Ta, Su, Tb, D, M,
S);
1911 const PatternTrackParameters& Tp,
1912 std::vector<const Trk::Surface*>& SU,
1913 std::vector<std::pair<Amg::Vector3D, double>>& GP,
1917 Cache cache = getInitializedCache(ctx);
1918 globalPositionsImpl(cache, Tp, SU, GP, M);
1928 fieldCondObj->getInitializedCache(cache.m_fieldCache);
1929 cache.
m_dlt = m_dlt;
1930 cache.m_helixStep = m_helixStep;
1931 cache.m_straightStep = m_straightStep;
1932 cache.m_usegradient = m_usegradient;