152template <
typename value_T>
167 auto dx = xToGo - track.getX();
168 int dir = dx > 0.f ? 1 : -1;
174 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
175 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
179 auto x = track.getX() + step;
180 auto xyz0 = track.getXYZGlo();
181 getFieldXYZ(xyz0, &
b[0]);
183 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr,
this]() {
185 if (matCorr != MatCorrType::USEMatCorrNONE) {
186 auto xyz1 = track.getXYZGlo();
187 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
188 if (!track.correctForMaterial(mb.meanX2X0, mb.getXRho(signCorr))) {
192 tofInfo->addStep(mb.length, track.getP2Inv());
193 tofInfo->addX2X0(mb.meanX2X0);
194 tofInfo->addXRho(mb.getXRho(signCorr));
196 }
else if (tofInfo) {
197 auto xyz1 = track.getXYZGlo();
199 tofInfo->addStep(stepV.R(), track.getP2Inv());
204 if (!track.propagateTo(
x,
b)) {
207 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
214 dx = xToGo - track.getX();
221template <
typename value_T>
222GPUd() bool
PropagatorImpl<value_T>::PropagateToXBxByBz(TrackPar_t& track, value_type xToGo, value_type maxSnp, value_type maxStep,
236 auto dx = xToGo - track.getX();
237 int dir = dx > 0.f ? 1 : -1;
243 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
244 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
248 auto x = track.getX() +
step;
249 auto xyz0 = track.getXYZGlo();
250 getFieldXYZ(xyz0, &
b[0]);
252 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr,
this]() {
254 if (matCorr != MatCorrType::USEMatCorrNONE) {
255 auto xyz1 = track.getXYZGlo();
256 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
257 if (!track.correctForELoss(((signCorr < 0) ? -mb.length : mb.
length) * mb.meanRho)) {
261 tofInfo->addStep(mb.length, track.getP2Inv());
262 tofInfo->addX2X0(mb.meanX2X0);
263 tofInfo->addXRho(mb.getXRho(signCorr));
265 }
else if (tofInfo) {
266 auto xyz1 = track.getXYZGlo();
268 tofInfo->addStep(stepV.R(), track.getP2Inv());
273 if (!track.propagateParamTo(
x,
b)) {
276 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
283 dx = xToGo - track.getX();
290template <
typename value_T>
291GPUd() bool
PropagatorImpl<value_T>::propagateToX(TrackParCov_t& track, value_type xToGo, value_type bZ, value_type maxSnp, value_type maxStep,
305 auto dx = xToGo - track.getX();
306 int dir = dx > 0.f ? 1 : -1;
311 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
312 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
316 auto x = track.getX() +
step;
317 auto xyz0 = track.getXYZGlo();
318 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr,
this]() {
320 if (matCorr != MatCorrType::USEMatCorrNONE) {
321 auto xyz1 = track.getXYZGlo();
322 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
323 if (!track.correctForMaterial(mb.meanX2X0, mb.getXRho(signCorr))) {
327 tofInfo->addStep(mb.length, track.getP2Inv());
328 tofInfo->addX2X0(mb.meanX2X0);
329 tofInfo->addXRho(mb.getXRho(signCorr));
331 }
else if (tofInfo) {
332 auto xyz1 = track.getXYZGlo();
334 tofInfo->addStep(stepV.R(), track.getP2Inv());
338 if (!track.propagateTo(
x, bZ)) {
341 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
348 dx = xToGo - track.getX();
355template <
typename value_T>
356GPUd() bool
PropagatorImpl<value_T>::propagateToX(TrackPar_t& track, value_type xToGo, value_type bZ, value_type maxSnp, value_type maxStep,
370 auto dx = xToGo - track.getX();
371 int dir = dx > 0.f ? 1 : -1;
376 while (math_utils::detail::abs<value_type>(dx) > Epsilon) {
377 auto step = math_utils::detail::min<value_type>(math_utils::detail::abs<value_type>(dx), maxStep);
381 auto x = track.getX() +
step;
382 auto xyz0 = track.getXYZGlo();
384 auto correct = [&track, &xyz0, tofInfo, matCorr, signCorr,
this]() {
386 if (matCorr != MatCorrType::USEMatCorrNONE) {
387 auto xyz1 = track.getXYZGlo();
388 auto mb = this->getMatBudget(matCorr, xyz0, xyz1);
389 if (!track.correctForELoss(mb.getXRho(signCorr))) {
393 tofInfo->addStep(mb.length, track.getP2Inv());
394 tofInfo->addX2X0(mb.meanX2X0);
395 tofInfo->addXRho(mb.getXRho(signCorr));
397 }
else if (tofInfo) {
398 auto xyz1 = track.getXYZGlo();
400 tofInfo->addStep(stepV.R(), track.getP2Inv());
405 if (!track.propagateParamTo(
x, bZ)) {
408 if (maxSnp > 0 && math_utils::detail::abs<value_type>(track.getSnp()) >= maxSnp) {
415 dx = xToGo - track.getX();
422template <
typename value_T>
423template <
typename track_T>
424GPUd() bool
PropagatorImpl<value_T>::propagateToAlphaX(track_T& track, value_type
alpha, value_type
x,
bool bzOnly, value_type maxSnp, value_type maxStep,
int minSteps,
425 MatCorrType matCorr, track::TrackLTIntegral* tofInfo,
int signCorr)
const
428 auto snp = track.getSnpAt(
alpha,
x, getNominalBz());
430 if (math_utils::detail::abs<value_type>(snp) < maxSnp * 0.9 && track.rotate(
alpha)) {
431 auto dx = math_utils::detail::abs<value_type>(
x - track.getX());
435 return propagateTo(track,
x, bzOnly, maxSnp, math_utils::detail::min<value_type>(dx / minSteps, maxStep), matCorr, tofInfo, signCorr);
455template <
typename value_T>
456GPUd() bool
PropagatorImpl<value_T>::propagateToDCA(const
o2::dataformats::VertexBase& vtx, TrackParCov_t& track, value_type bZ,
458 o2::dataformats::DCA* dca, track::TrackLTIntegral* tofInfo,
459 int signCorr, value_type maxD)
const
462 value_type sn, cs, alp = track.getAlpha();
463 math_utils::detail::sincos<value_type>(alp, sn, cs);
464 value_type
x = track.getX(),
y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
465 value_type xv = vtx.getX() * cs + vtx.getY() * sn, yv = -vtx.getX() * sn + vtx.getY() * cs, zv = vtx.getZ();
469 value_type d = math_utils::detail::abs<value_type>(
x * snp -
y * csp);
473 value_type crv = track.getCurvature(bZ);
474 value_type tgfv = -(crv *
x - snp) / (crv *
y + csp);
475 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
476 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
479 x = xv * cs + yv * sn;
480 yv = -xv * sn + yv * cs;
484 alp += math_utils::detail::asin<value_type>(sn);
485 if (!tmpT.rotate(alp) || !propagateToX(tmpT, xv, bZ, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
486#ifndef GPUCA_ALIGPUCODE
487 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv << vtx <<
" | Track is: " << tmpT.asString();
488#elif !defined(GPUCA_NO_FMT)
489 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv << vtx;
495 math_utils::detail::sincos<value_type>(alp, sn, cs);
496 auto s2ylocvtx = vtx.getSigmaX2() * sn * sn + vtx.getSigmaY2() * cs * cs - 2. * vtx.getSigmaXY() * cs * sn;
497 dca->set(track.getY() - yv, track.getZ() - zv,
498 track.getSigmaY2() + s2ylocvtx, track.getSigmaZY(), track.getSigmaZ2() + vtx.getSigmaZ2());
504template <
typename value_T>
505GPUd() bool
PropagatorImpl<value_T>::propagateToDCABxByBz(const
o2::dataformats::VertexBase& vtx, TrackParCov_t& track,
507 o2::dataformats::DCA* dca, track::TrackLTIntegral* tofInfo,
508 int signCorr, value_type maxD)
const
511 value_type sn, cs, alp = track.getAlpha();
512 math_utils::detail::sincos<value_type>(alp, sn, cs);
513 value_type
x = track.getX(),
y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
514 value_type xv = vtx.getX() * cs + vtx.getY() * sn, yv = -vtx.getX() * sn + vtx.getY() * cs, zv = vtx.getZ();
518 value_type d = math_utils::detail::abs<value_type>(
x * snp -
y * csp);
522 value_type crv = track.getCurvature(mNominalBz);
523 value_type tgfv = -(crv *
x - snp) / (crv *
y + csp);
524 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
525 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
528 x = xv * cs + yv * sn;
529 yv = -xv * sn + yv * cs;
533 alp += math_utils::detail::asin<value_type>(sn);
534 if (!tmpT.rotate(alp) || !PropagateToXBxByBz(tmpT, xv, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
535#ifndef GPUCA_ALIGPUCODE
536 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv << vtx <<
" | Track is: " << tmpT.asString();
537#elif !defined(GPUCA_NO_FMT)
538 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv << vtx;
544 math_utils::detail::sincos<value_type>(alp, sn, cs);
545 auto s2ylocvtx = vtx.getSigmaX2() * sn * sn + vtx.getSigmaY2() * cs * cs - 2. * vtx.getSigmaXY() * cs * sn;
546 dca->set(track.getY() - yv, track.getZ() - zv,
547 track.getSigmaY2() + s2ylocvtx, track.getSigmaZY(), track.getSigmaZ2() + vtx.getSigmaZ2());
553template <
typename value_T>
554GPUd() bool
PropagatorImpl<value_T>::propagateToDCA(const math_utils::
Point3D<value_type>& vtx, TrackPar_t& track, value_type bZ,
556 gpu::gpustd::
array<value_type, 2>* dca, track::TrackLTIntegral* tofInfo,
557 int signCorr, value_type maxD)
const
560 value_type sn, cs, alp = track.getAlpha();
561 math_utils::detail::sincos<value_type>(alp, sn, cs);
562 value_type
x = track.getX(),
y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
563 value_type xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
567 value_type d = math_utils::detail::abs<value_type>(
x * snp -
y * csp);
571 value_type crv = track.getCurvature(bZ);
572 value_type tgfv = -(crv *
x - snp) / (crv *
y + csp);
573 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
574 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
577 x = xv * cs + yv * sn;
578 yv = -xv * sn + yv * cs;
582 alp += math_utils::detail::asin<value_type>(sn);
583 if (!tmpT.rotateParam(alp) || !propagateToX(tmpT, xv, bZ, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
584#ifndef GPUCA_ALIGPUCODE
585 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv <<
" for vertex "
586 << vtx.X() <<
' ' << vtx.Y() <<
' ' << vtx.Z() <<
" | Track is: " << tmpT.asString();
588 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv <<
" for vertex " << vtx.X() <<
' ' << vtx.Y() <<
' ' << vtx.Z();
594 (*dca)[0] = track.getY() - yv;
595 (*dca)[1] = track.getZ() - zv;
601template <
typename value_T>
604 gpu::gpustd::
array<value_type, 2>* dca, track::TrackLTIntegral* tofInfo,
605 int signCorr, value_type maxD)
const
608 value_type sn, cs, alp = track.getAlpha();
609 math_utils::detail::sincos<value_type>(alp, sn, cs);
610 value_type
x = track.getX(),
y = track.getY(), snp = track.getSnp(), csp = math_utils::detail::sqrt<value_type>((1.f - snp) * (1.f + snp));
611 value_type xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
615 value_type d = math_utils::detail::abs<value_type>(
x * snp -
y * csp);
619 value_type crv = track.getCurvature(mNominalBz);
620 value_type tgfv = -(crv *
x - snp) / (crv *
y + csp);
621 sn = tgfv / math_utils::detail::sqrt<value_type>(1.f + tgfv * tgfv);
622 cs = math_utils::detail::sqrt<value_type>((1. - sn) * (1. + sn));
625 x = xv * cs + yv * sn;
626 yv = -xv * sn + yv * cs;
630 alp += math_utils::detail::asin<value_type>(sn);
631 if (!tmpT.rotateParam(alp) || !PropagateToXBxByBz(tmpT, xv, 0.85, maxStep, matCorr, tofInfo, signCorr)) {
632#ifndef GPUCA_ALIGPUCODE
633 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv <<
" for vertex "
634 << vtx.X() <<
' ' << vtx.Y() <<
' ' << vtx.Z() <<
" | Track is: " << tmpT.asString();
636 LOG(
debug) <<
"failed to propagate to alpha=" << alp <<
" X=" << xv <<
" for vertex " << vtx.X() <<
' ' << vtx.Y() <<
' ' << vtx.Z();
642 (*dca)[0] = track.getY() - yv;
643 (*dca)[1] = track.getZ() - zv;
649template <
typename value_T>
650GPUd() float
PropagatorImpl<value_T>::estimateLTIncrement(const
o2::track::TrackParametrization<value_type>& trc,
651 const
o2::math_utils::
Point3D<value_type>& posStart,
652 const
o2::math_utils::
Point3D<value_type>& posEnd)
const
655 float dX = posEnd.X() - posStart.X(), dY = posEnd.Y() - posStart.Y(), dZ = posEnd.Z() - posStart.Z(), d2XY = dX * dX + dY * dY;
656 if (getNominalBz() != 0) {
659 getFieldXYZ(posAv,
b);
660 float curvH = math_utils::detail::abs<value_type>(0.5f * trc.getCurvature(
b[2])), asArg = curvH * math_utils::detail::sqrt<value_type>(d2XY);
666 return math_utils::detail::sqrt<value_type>(d2XY + dZ * dZ);
670template <
typename value_T>
671GPUd() value_T
PropagatorImpl<value_T>::estimateLTFast(
o2::track::TrackLTIntegral& lt, const
o2::track::TrackParametrization<value_type>& trc)
const
673 value_T xdca = 0., ydca = 0.,
length = 0.;
675 constexpr float TinyF = 1e-9;
676 auto straigh_line_approx = [&]() {
677 auto csp2 = (1.f - trc.getSnp()) * (1.f + trc.getSnp());
679 auto csp = math_utils::detail::sqrt<value_type>(csp2);
680 auto tgp = trc.getSnp() / csp,
f = trc.getX() * tgp - trc.getY();
681 xdca = tgp *
f * csp2;
683 auto dx = xdca - trc.getX(), dy = ydca - trc.getY(), dz = dx * trc.getTgl() / csp;
684 return math_utils::detail::sqrt<value_type>(dx * dx + dy * dy + dz * dz);
687 return math_utils::detail::abs<value_type>(trc.getY() * math_utils::detail::sqrt<value_type>(1. + trc.getTgl() * trc.getTgl()));
690 trc.getCircleParamsLoc(mNominalBz,
c);
692 auto distC = math_utils::detail::sqrt<value_type>(
c.getCenterD2());
694 auto nrm = (distC -
c.rC) / distC;
697 auto v0x = trc.getX() -
c.xC, v0y = trc.getY() -
c.yC, v1x = xdca -
c.xC, v1y = ydca -
c.yC;
698 auto angcos = (v0x * v1x + v0y * v1y) / (
c.rC *
c.rC);
699 if (math_utils::detail::abs<value_type>(angcos) < 1.f) {
700 auto ang = math_utils::detail::acos<value_type>(angcos);
701 if ((trc.getSign() > 0.f) == (mNominalBz > 0.f)) {
706 length = math_utils::detail::abs<value_type>(
c.rC * ang * math_utils::detail::sqrt<value_type>(1. + trc.getTgl() * trc.getTgl()));
708 length = straigh_line_approx();
715 length = straigh_line_approx();
718 value_T dcaT = math_utils::detail::sqrt<value_type>(xdca * xdca + ydca * ydca);
720 lt.addStep(
length, trc.getP2Inv());
725template <
typename value_T>
728#if !defined(GPUCA_STANDALONE) && !defined(GPUCA_GPUCODE)
729 if (corrType == MatCorrType::USEMatCorrTGeo) {
733 if (mTGeoFallBackAllowed) {
736 throw std::runtime_error(
"requested MatLUT is absent and fall-back to TGeo is disabled");
740 return mMatLUT->getMatBudget(
p0.X(),
p0.Y(),
p0.Z(),
p1.X(),
p1.Y(),
p1.Z());
743template <
typename value_T>
748#if defined(GPUCA_GPUCODE_DEVICE) && defined(GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM)
751 const auto*
f = mGPUField;
754 f->GetField(xyz.X(), xyz.Y(), xyz.Z(), bxyzF);
756 constexpr value_type kCLight1 = 1. / o2::gpu::gpu_common_constants::kCLight;
757 for (uint
i = 0;
i < 3; ++
i) {
758 bxyz[
i] =
static_cast<value_type
>(bxyzF[
i]) * kCLight1;
763 mFieldFast->Field(xyz, bxyz);
765#ifdef GPUCA_STANDALONE
766 LOG(fatal) <<
"Normal field cannot be used in standalone benchmark";
768 mField->field(xyz, bxyz);
775template <
typename value_T>
778 getFieldXYZImpl<float>(xyz, bxyz);
781template <
typename value_T>
784 getFieldXYZImpl<double>(xyz, bxyz);
789#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE)