147 return {float(
m(0, 0)), float(
m(1, 0)), float(
m(1, 1)), float(
m(2, 0)), float(
m(2, 1)), float(
m(2, 2))};
166 mUseMatBudget =
true;
173 float getMaxR()
const {
return std::sqrt(mMaxR2); }
179 double getHz(
double b)
const {
return std::copysign(1,
b); }
185 template <
class... Tr>
233 const auto& trc = mCandTr[mOrder[cand]][
i];
235 mat(0, 0) = trc.getSigma2X();
236 mat(1, 1) = trc.getSigma2Y();
237 mat(1, 0) = trc.getSigmaXY();
238 mat(2, 2) = trc.getSigma2Y() * ZerrFactor;
243 template <
class T,
class... Tr>
244 void assign(
int i,
const T& t,
const Tr&... args)
246 static_assert(std::is_convertible<T, Track>(),
"Wrong track type");
254 mAllowAltPreference =
true;
266 std::array<std::array<Vec3D, N>, N> mDResidDz;
268 std::array<std::array<Vec3D, N>, N> mD2ResidDz2;
272 std::array<const Track*, N> mOrigTrPtr;
273 std::array<TrackAuxPar, N> mTrAux;
274 CrossInfo mCrossings;
276 std::array<ArrTrackCovI, MAXHYP> mTrcEInv;
277 std::array<ArrTrack, MAXHYP> mCandTr;
278 std::array<ArrTrCoef, MAXHYP> mTrCFVT;
279 std::array<ArrTrDer, MAXHYP> mTrDer;
280 std::array<ArrTrPos, MAXHYP> mTrPos;
281 std::array<ArrTrPos, MAXHYP> mTrRes;
282 std::array<Vec3D, MAXHYP> mPCA;
283 std::array<float, MAXHYP> mChi2 = {0};
284 std::array<int, MAXHYP> mNIters;
285 std::array<bool, MAXHYP> mTrPropDone;
287 std::array<int, MAXHYP> mOrder{0};
290 int mCrossIDAlt = -1;
291 bool mAllowAltPreference =
true;
292 bool mUseAbsDCA =
false;
293 bool mPropagateToPCA =
true;
294 bool mUseMatBudget =
false;
295 bool mTGeoFallBackAllowed =
true;
298 float mMaxR2 = 200. * 200.;
299 float mMaxDXIni = 4.;
300 float mMinParamChange = 1e-5;
301 float mMinRelChi2Change = 0.98;
302 float mMaxChi2 = 100;
303 float mMaxDist2ToMergeSeeds = 1.;
310template <
int N,
typename... Args>
311template <
class... Tr>
315 static_assert(
sizeof...(args) == N,
"incorrect number of input tracks");
319 for (
int i = 0;
i < N;
i++) {
320 mTrAux[
i].set(*mOrigTrPtr[
i], mBz);
323 if (!mCrossings.set(mTrAux[0], *mOrigTrPtr[0], mTrAux[1], *mOrigTrPtr[1])) {
327 if (mCrossings.nDCA == MAXHYP) {
328 auto dst2 = (mCrossings.xDCA[0] - mCrossings.xDCA[1]) * (mCrossings.xDCA[0] - mCrossings.xDCA[1]) +
329 (mCrossings.yDCA[0] - mCrossings.yDCA[1]) * (mCrossings.yDCA[0] - mCrossings.yDCA[1]);
331 if (dst2 < mMaxDist2ToMergeSeeds) {
333 mCrossings.xDCA[0] = 0.5 * (mCrossings.xDCA[0] + mCrossings.xDCA[1]);
334 mCrossings.yDCA[0] = 0.5 * (mCrossings.yDCA[0] + mCrossings.yDCA[1]);
339 for (
int ic = 0; ic < mCrossings.nDCA; ic++) {
341 if (mCrossings.xDCA[ic] * mCrossings.xDCA[ic] + mCrossings.yDCA[ic] * mCrossings.yDCA[ic] > mMaxR2) {
346 mCrossIDAlt = (mCrossings.nDCA == 2 && mAllowAltPreference) ? 1 - ic : -1;
347 mNIters[mCurHyp] = 0;
348 mTrPropDone[mCurHyp] =
false;
349 mChi2[mCurHyp] = -1.;
351 findZatXY_mid(mCurHyp);
353 if (mUseAbsDCA ? minimizeChi2NoErr() : minimizeChi2()) {
354 mOrder[mCurHyp] = mCurHyp;
355 if (mPropagateToPCA && !FwdpropagateTracksToVertex(mCurHyp)) {
362 for (
int i = mCurHyp;
i--;) {
363 for (
int j =
i;
j--;) {
364 if (mChi2[mOrder[
i]] < mChi2[mOrder[
j]]) {
365 std::swap(mOrder[
i], mOrder[
j]);
374template <
int N,
typename... Args>
378 if (!FwdcalcInverseWeight()) {
381 for (
int i = N;
i--;) {
382 const auto& tcov = mTrcEInv[mCurHyp][
i];
385 miei[0][0] = tcov.sxx;
386 miei[0][1] = tcov.sxy;
387 miei[1][0] = tcov.sxy;
388 miei[1][1] = tcov.syy;
389 miei[2][2] = tcov.szz;
391 mTrCFVT[mCurHyp][
i] = mWeightInv * miei;
397template <
int N,
typename... Args>
401 auto* arrmat = mWeightInv.Array();
402 memset(arrmat, 0,
sizeof(mWeightInv));
409 for (
int i = N;
i--;) {
410 const auto& tcov = mTrcEInv[mCurHyp][
i];
411 arrmat[XX] += tcov.sxx;
412 arrmat[XY] += tcov.sxy;
414 arrmat[YY] += tcov.syy;
416 arrmat[ZZ] += tcov.szz;
420 return mWeightInv.Invert();
424template <
int N,
typename... Args>
429 for (
int i = N;
i--;) {
431 for (
int j = N;
j--;) {
432 const auto& matT = mTrCFVT[mCurHyp][
j];
433 const auto& trDz = mTrDer[mCurHyp][
j];
434 auto& dr1 = mDResidDz[
i][
j];
435 auto& dr2 = mD2ResidDz2[
i][
j];
437 matMT[0][0] = matT[0][0];
438 matMT[0][1] = matT[0][1];
439 matMT[0][2] = matT[0][2];
440 matMT[1][0] = matT[1][0];
441 matMT[1][1] = matT[1][1];
442 matMT[1][2] = matT[1][2];
443 matMT[2][0] = matT[2][0];
444 matMT[2][1] = matT[2][1];
445 matMT[2][2] = matT[2][2];
448 dr1[0] = -(matMT[0][0] * trDz.dxdz + matMT[0][1] * trDz.dydz + matMT[0][2]);
449 dr1[1] = -(matMT[1][0] * trDz.dxdz + matMT[1][1] * trDz.dydz + matMT[1][2]);
450 dr1[2] = -(matMT[2][0] * trDz.dxdz + matMT[2][1] * trDz.dydz + matMT[2][2]);
453 dr2[0] = -(matMT[0][1] * trDz.d2ydz2 + matMT[0][0] * trDz.d2xdz2);
454 dr2[1] = -(matMT[1][1] * trDz.d2ydz2 + matMT[1][0] * trDz.d2xdz2);
455 dr2[2] = -(matMT[2][1] * trDz.d2ydz2 + matMT[2][0] * trDz.d2xdz2);
462 dr2[0] += trDz.d2xdz2;
463 dr2[1] += trDz.d2ydz2;
470template <
int N,
typename... Args>
474 constexpr double NInv1 = 1. - NInv;
475 for (
int i = N;
i--;) {
476 const auto& trDzi = mTrDer[mCurHyp][
i];
477 auto& dr1ii = mDResidDz[
i][
i];
478 auto& dr2ii = mD2ResidDz2[
i][
i];
480 dr1ii[0] = NInv1 * trDzi.dxdz;
481 dr1ii[1] = NInv1 * trDzi.dydz;
484 dr2ii[0] = NInv1 * trDzi.d2xdz2;
485 dr2ii[1] = NInv1 * trDzi.d2ydz2;
488 for (
int j =
i;
j--;) {
489 auto& dr1ij = mDResidDz[
i][
j];
490 auto& dr1ji = mDResidDz[
j][
i];
491 const auto& trDzj = mTrDer[mCurHyp][
j];
494 dr1ij[0] = -trDzj.dxdz * NInv;
495 dr1ij[1] = -trDzj.dydz * NInv;
496 dr1ij[2] = -1 * NInv;
499 dr1ji[0] = -trDzi.dxdz * NInv;
500 dr1ji[1] = -trDzi.dydz * NInv;
501 dr1ji[2] = -1 * NInv;
503 auto& dr2ij = mD2ResidDz2[
i][
j];
504 auto& dr2ji = mD2ResidDz2[
j][
i];
507 dr2ij[0] = -trDzj.d2xdz2 * NInv;
508 dr2ij[1] = -trDzj.d2ydz2 * NInv;
512 dr2ji[0] = -trDzi.d2xdz2 * NInv;
513 dr2ji[1] = -trDzi.d2ydz2 * NInv;
521template <
int N,
typename... Args>
525 std::array<std::array<Vec3D, N>, N> covIDrDz;
528 for (
int i = N;
i--;) {
529 auto& dchi1 = mDChi2Dz[
i];
531 for (
int j = N;
j--;) {
532 const auto&
res = mTrRes[mCurHyp][
j];
533 const auto& covI = mTrcEInv[mCurHyp][
j];
534 const auto& dr1 = mDResidDz[
j][
i];
535 auto& cidr = covIDrDz[
i][
j];
536 cidr[0] = covI.sxx * dr1[0] + covI.sxy * dr1[1];
537 cidr[1] = covI.sxy * dr1[0] + covI.syy * dr1[1];
538 cidr[2] = covI.szz * dr1[2];
540 dchi1 += ROOT::Math::Dot(
res, cidr);
545 for (
int i = N;
i--;) {
546 for (
int j =
i + 1;
j--;) {
547 auto& dchi2 = mD2Chi2Dz2[
i][
j];
549 for (
int k = N; k--;) {
550 const auto& dr1j = mDResidDz[k][
j];
551 const auto& cidrkj = covIDrDz[
i][k];
552 dchi2 += ROOT::Math::Dot(dr1j, cidrkj);
554 const auto&
res = mTrRes[mCurHyp][k];
555 const auto& covI = mTrcEInv[mCurHyp][k];
556 const auto& dr2ij = mD2ResidDz2[k][
j];
557 dchi2 +=
res[0] * (covI.sxx * dr2ij[0] + covI.sxy * dr2ij[1]) +
res[1] * (covI.sxy * dr2ij[0] + covI.syy * dr2ij[1]) +
res[2] * covI.szz * dr2ij[2];
565template <
int N,
typename... Args>
569 for (
int i = N;
i--;) {
570 auto& dchi1 = mDChi2Dz[
i];
572 for (
int j = N;
j--;) {
573 const auto&
res = mTrRes[mCurHyp][
j];
574 const auto& dr1 = mDResidDz[
j][
i];
575 dchi1 += ROOT::Math::Dot(
res, dr1);
578 auto& dchi2 = mD2Chi2Dz2[
i][
j];
579 dchi2 = ROOT::Math::Dot(mTrRes[mCurHyp][
i], mD2ResidDz2[
i][
j]);
580 for (
int k = N; k--;) {
581 dchi2 += ROOT::Math::Dot(mDResidDz[k][
i], mDResidDz[k][
j]);
589template <
int N,
typename... Args>
594 mPCA[mCurHyp] = mTrCFVT[mCurHyp][N - 1] * mTrPos[mCurHyp][N - 1];
595 for (
int i = N - 1;
i--;) {
596 mPCA[mCurHyp] += mTrCFVT[mCurHyp][
i] * mTrPos[mCurHyp][
i];
601template <
int N,
typename... Args>
605 auto& pca = mPCA[mCurHyp];
607 pca[0] = mTrPos[mCurHyp][N - 1][0];
608 pca[1] = mTrPos[mCurHyp][N - 1][1];
609 pca[2] = mTrPos[mCurHyp][N - 1][2];
611 for (
int i = N - 1;
i--;) {
612 pca[0] += mTrPos[mCurHyp][
i][0];
613 pca[1] += mTrPos[mCurHyp][
i][1];
614 pca[2] += mTrPos[mCurHyp][
i][2];
622template <
int N,
typename... Args>
627 for (
int i = N;
i--;) {
628 covm += ROOT::Math::Similarity(mUseAbsDCA ? getTrackRotMatrix(
i) : mTrCFVT[mOrder[cand]][
i], getTrackCovMatrix(
i, cand));
634template <
int N,
typename... Args>
639 for (
int i = N;
i--;) {
640 mTrRes[mCurHyp][
i] = mTrPos[mCurHyp][
i];
641 vtxLoc = mPCA[mCurHyp];
642 mTrRes[mCurHyp][
i] -= vtxLoc;
647template <
int N,
typename... Args>
651 for (
int i = N;
i--;) {
652 mTrDer[mCurHyp][
i].set(mCandTr[mCurHyp][
i], mBz);
657template <
int N,
typename... Args>
662 for (
int i = N;
i--;) {
663 const auto&
res = mTrRes[mCurHyp][
i];
664 const auto& covI = mTrcEInv[mCurHyp][
i];
665 chi2 +=
res[0] *
res[0] * covI.sxx +
res[1] *
res[1] * covI.syy +
res[2] *
res[2] * covI.szz + 2. *
res[0] *
res[1] * covI.sxy;
671template <
int N,
typename... Args>
676 for (
int i = N;
i--;) {
677 const auto&
res = mTrRes[mCurHyp][
i];
684template <
int N,
typename... Args>
688 for (
int i = N;
i--;) {
689 const auto& trDer = mTrDer[mCurHyp][
i];
690 auto dz2h = 0.5 * corrZ[
i] * corrZ[
i];
691 mTrPos[mCurHyp][
i][0] -= trDer.dxdz * corrZ[
i] - dz2h * trDer.d2xdz2;
692 mTrPos[mCurHyp][
i][1] -= trDer.dydz * corrZ[
i] - dz2h * trDer.d2ydz2;
693 mTrPos[mCurHyp][
i][2] -= corrZ[
i];
700template <
int N,
typename... Args>
704 int ord = mOrder[icand];
705 if (mTrPropDone[ord]) {
708 const Vec3D& pca = mPCA[ord];
709 std::array<float, 6> covMatrixPCA = calcPCACovMatrixFlat(ord);
710 std::array<float, 2> cov = {covMatrixPCA[0], covMatrixPCA[2]};
711 for (
int i = N;
i--;) {
712 mCandTr[ord][
i] = *mOrigTrPtr[
i];
713 auto& trc = mCandTr[ord][
i];
714 const std::array<float, 3> p = {(
float)pca[0], (
float)pca[1], (
float)pca[2]};
715 if (!propagateToVtx(trc, p, cov)) {
720 mTrPropDone[ord] =
true;
725template <
int N,
typename... Args>
730 double startPoint = 20.;
732 double z[2] = {startPoint, startPoint};
733 double newX[2], newY[2];
735 double X = mPCA[mCurHyp][0];
736 double Y = mPCA[mCurHyp][1];
738 mCandTr[mCurHyp][0] = *mOrigTrPtr[0];
739 mCandTr[mCurHyp][1] = *mOrigTrPtr[1];
741 double dstXY[2][3] = {{999., 999., 999.}, {999., 999., 999.}};
748 for (
int i = 0;
i < 2;
i++) {
752 mCandTr[mCurHyp][
i].propagateParamToZquadratic(
z[
i], mBz);
753 newX[
i] = mCandTr[mCurHyp][
i].getX();
754 newY[
i] = mCandTr[mCurHyp][
i].getY();
756 newDstXY = std::sqrt((newX[
i] - X) * (newX[
i] - X) +
757 (newY[
i] - Y) * (newY[
i] - Y));
760 dstXY[
i][0] = dstXY[
i][1];
761 dstXY[
i][1] = dstXY[
i][2];
762 dstXY[
i][2] = newDstXY;
764 if (dstXY[
i][2] > dstXY[
i][1] && dstXY[
i][1] < dstXY[
i][0]) {
773 float rez = 0.5 * (finalZ[0] + finalZ[1]);
778template <
int N,
typename... Args>
783 double startPoint = -40.;
784 double endPoint = 50.;
785 double midPoint = 0.5 * (startPoint + endPoint);
787 double z[2][2] = {{startPoint, endPoint}, {startPoint, endPoint}};
789 double DeltaZ = std::abs(endPoint - startPoint);
794 double epsilon = 0.0001;
796 double X = mPCA[mCurHyp][0];
797 double Y = mPCA[mCurHyp][1];
799 mCandTr[mCurHyp][0] = *mOrigTrPtr[0];
800 mCandTr[mCurHyp][1] = *mOrigTrPtr[1];
806 while (DeltaZ > epsilon) {
808 midPoint = 0.5 * (startPoint + endPoint);
810 for (
int i = 0;
i < 2;
i++) {
811 mCandTr[mCurHyp][
i].propagateParamToZquadratic(startPoint, mBz);
812 newX[
i][0] = mCandTr[mCurHyp][
i].getX();
813 newY[
i][0] = mCandTr[mCurHyp][
i].getY();
815 mCandTr[mCurHyp][
i].propagateParamToZquadratic(endPoint, mBz);
816 newX[
i][1] = mCandTr[mCurHyp][
i].getX();
817 newY[
i][1] = mCandTr[mCurHyp][
i].getY();
820 dstXY[0] = (newX[0][0] - newX[1][0]) * (newX[0][0] - newX[1][0]) +
821 (newY[0][0] - newY[1][0]) * (newY[0][0] - newY[1][0]);
823 dstXY[1] = (newX[0][1] - newX[1][1]) * (newX[0][1] - newX[1][1]) +
824 (newY[0][1] - newY[1][1]) * (newY[0][1] - newY[1][1]);
826 DeltaZ = std::abs(endPoint - startPoint);
828 if (DeltaZ < epsilon) {
829 finalZ = 0.5 * (startPoint + endPoint);
834 if (dstXY[1] > dstXY[0]) {
837 startPoint = midPoint;
841 mPCA[mCurHyp][2] = finalZ;
845template <
int N,
typename... Args>
850 double startPoint = 1.;
851 double endPoint = 50.;
853 double X = mPCA[mCurHyp][0];
854 double Y = mPCA[mCurHyp][1];
856 mCandTr[mCurHyp][0] = *mOrigTrPtr[0];
857 mCandTr[mCurHyp][1] = *mOrigTrPtr[1];
872 for (
int i = 0;
i < 2;
i++) {
874 mCandTr[mCurHyp][
i].propagateToZquadratic(startPoint, mBz);
876 z[
i][0] = startPoint;
877 y[
i][0] = mCandTr[mCurHyp][
i].getY();
878 x[
i][0] = mCandTr[mCurHyp][
i].getX();
880 mCandTr[mCurHyp][
i].propagateToZquadratic(endPoint, mBz);
883 y[
i][1] = mCandTr[mCurHyp][
i].getY();
884 x[
i][1] = mCandTr[mCurHyp][
i].getX();
886 bYZ[
i] = (
y[
i][1] -
y[
i][0] *
z[
i][1] /
z[
i][0]) / (1 -
z[
i][1] /
z[
i][0]);
887 aYZ[
i] = (
y[
i][0] - bYZ[
i]) /
z[
i][0];
889 bXZ[
i] = (
x[
i][1] -
x[
i][0] *
z[
i][1] /
z[
i][0]) / (1 -
z[
i][1] /
z[
i][0]);
890 aXZ[
i] = (
x[
i][0] - bXZ[
i]) /
z[
i][0];
894 finalZ = 0.5 * ((bYZ[0] - bYZ[1]) / (aYZ[1] - aYZ[0]) + (bXZ[0] - bXZ[1]) / (aXZ[1] - aXZ[0]));
896 mPCA[mCurHyp][2] = finalZ;
900template <
int N,
typename... Args>
903 double startPoint = 0.;
904 double endPoint = 40.;
906 double X = mPCA[mCurHyp][0];
907 double Y = mPCA[mCurHyp][1];
909 mCandTr[mCurHyp][0] = *mOrigTrPtr[0];
910 mCandTr[mCurHyp][1] = *mOrigTrPtr[1];
922 double Ax[2], Bx[2], Cx[2];
923 double Ay[2], By[2], Cy[2];
925 double deltaX[2], deltaY[2];
927 bool posX[2], nulX[2], negX[2];
928 double z1X[2], z2X[2], z12X[2];
930 bool posY[2], nulY[2], negY[2];
931 double z1Y[2], z2Y[2], z12Y[2];
939 for (
int i = 0;
i < 2;
i++) {
940 mCandTr[mCurHyp][
i].propagateToZquadratic(startPoint, mBz);
941 x[
i] = mCandTr[mCurHyp][
i].getX();
942 y[
i] = mCandTr[mCurHyp][
i].getY();
943 sinPhi0[
i] = mCandTr[mCurHyp][
i].getSnp();
944 cosPhi0[
i] = std::sqrt((1. - sinPhi0[
i]) * (1. + sinPhi0[
i]));
945 tanL0[
i] = mCandTr[mCurHyp][
i].getTanl();
946 qpt0[
i] = mCandTr[mCurHyp][
i].getInvQPt();
950 Ax[
i] = qpt0[
i] * Hz[
i] * k[
i] * sinPhi0[
i] / (2 * tanL0[
i] * tanL0[
i]);
951 Bx[
i] = cosPhi0[
i] / tanL0[
i];
954 Ay[
i] = -qpt0[
i] * Hz[
i] * k[
i] * cosPhi0[
i] / (2 * tanL0[
i] * tanL0[
i]);
955 By[
i] = sinPhi0[
i] / tanL0[
i];
958 deltaX[
i] = Bx[
i] * Bx[
i] - 4 * Ax[
i] * Cx[
i];
959 deltaY[
i] = By[
i] * By[
i] - 4 * Ay[
i] * Cy[
i];
963 z1X[
i] = (-Bx[
i] - std::sqrt(deltaX[
i])) / (2 * Ax[
i]);
964 z2X[
i] = (-Bx[
i] + std::sqrt(deltaX[
i])) / (2 * Ax[
i]);
965 }
else if (deltaX[
i] == 0) {
967 z12X[
i] = -Bx[
i] / (2 * Ax[
i]);
975 z1Y[
i] = (-By[
i] - std::sqrt(deltaY[
i])) / (2 * Ay[
i]);
976 z2Y[
i] = (-By[
i] + std::sqrt(deltaY[
i])) / (2 * Ay[
i]);
977 }
else if (deltaX[
i] == 0) {
979 z12Y[
i] = -By[
i] / (2 * Ay[
i]);
987 if (z1X[
i] < endPoint && z1X[
i] > startPoint) {
995 if (z1Y[
i] < endPoint && z1Y[
i] > startPoint) {
1002 finalZ[
i] = 0.5 * (z12X[
i] + z12Y[
i]);
1005 mPCA[mCurHyp][2] = 0.5 * (finalZ[0] + finalZ[1]);
1009template <
int N,
typename... Args>
1013 double startPoint = 0.;
1015 double X = mPCA[mCurHyp][0];
1016 double Y = mPCA[mCurHyp][1];
1018 mCandTr[mCurHyp][0] = *mOrigTrPtr[0];
1019 mCandTr[mCurHyp][1] = *mOrigTrPtr[1];
1027 double Ax[2], Bx[2];
1028 double Ay[2], By[2];
1039 for (
int i = 0;
i < 2;
i++) {
1040 mCandTr[mCurHyp][
i].propagateToZlinear(startPoint);
1041 x[
i] = mCandTr[mCurHyp][
i].getX();
1042 y[
i] = mCandTr[mCurHyp][
i].getY();
1043 sinPhi0[
i] = mCandTr[mCurHyp][
i].getSnp();
1044 cosPhi0[
i] = std::sqrt((1. - sinPhi0[
i]) * (1. + sinPhi0[
i]));
1045 tanL0[
i] = mCandTr[mCurHyp][
i].getTanl();
1047 Ax[
i] = cosPhi0[
i] / tanL0[
i];
1050 Ay[
i] = sinPhi0[
i] / tanL0[
i];
1053 z12X[
i] = -Bx[
i] / Ax[
i];
1054 z12Y[
i] = -By[
i] / Ay[
i];
1056 finalZ[
i] = 0.5 * (z12X[
i] + z12Y[
i]);
1059 mPCA[mCurHyp][2] = 0.5 * (finalZ[0] + finalZ[1]);
1063template <
int N,
typename... Args>
1067 int ord = mOrder[icand];
1069 if (!mTrPropDone[ord]) {
1070 auto z = mPCA[ord][2];
1071 trc.propagateParamToZquadratic(
z, mBz);
1078template <
int N,
typename... Args>
1082 for (
int i = N;
i--;) {
1083 auto vai = std::abs(
v[
i]);
1092template <
int N,
typename... Args>
1100 for (
int i = N;
i--;) {
1101 mCandTr[mCurHyp][
i] = *mOrigTrPtr[
i];
1102 auto z = mPCA[mCurHyp][2];
1104 mCandTr[mCurHyp][
i].propagateToZquadratic(
z, mBz);
1106 x[
i] = mCandTr[mCurHyp][
i].getX();
1107 y[
i] = mCandTr[mCurHyp][
i].getY();
1109 setTrackPos(mTrPos[mCurHyp][
i], mCandTr[mCurHyp][
i]);
1110 mTrcEInv[mCurHyp][
i].set(mCandTr[mCurHyp][
i], ZerrFactor);
1116 mPCA[mCurHyp][0] = sumX / N;
1117 mPCA[mCurHyp][1] = sumY / N;
1119 if (mMaxDXIni > 0 && !roughDXCut()) {
1123 if (!FwdcalcPCACoefs()) {
1127 FwdcalcTrackResiduals();
1128 float chi2Upd, chi2 = FwdcalcChi2();
1130 calcTrackDerivatives();
1131 FwdcalcResidDerivatives();
1132 FwdcalcChi2Derivatives();
1135 if (!mD2Chi2Dz2.Invert()) {
1139 VecND dz = mD2Chi2Dz2 * mDChi2Dz;
1141 if (!FwdcorrectTracks(dz)) {
1146 if (mCrossIDAlt >= 0 && closerToAlternative()) {
1147 mAllowAltPreference =
false;
1151 FwdcalcTrackResiduals();
1152 chi2Upd = FwdcalcChi2();
1154 if (getAbsMax(dz) < mMinParamChange || chi2Upd > chi2 * mMinRelChi2Change) {
1160 }
while (++mNIters[mCurHyp] < mMaxIter);
1162 mChi2[mCurHyp] = chi2 * NInv;
1163 return mChi2[mCurHyp] < mMaxChi2;
1167template <
int N,
typename... Args>
1175 for (
int i = N;
i--;) {
1177 mCandTr[mCurHyp][
i] = *mOrigTrPtr[
i];
1179 auto z = mPCA[mCurHyp][2];
1180 mCandTr[mCurHyp][
i].propagateParamToZquadratic(
z, mBz);
1182 x[
i] = mCandTr[mCurHyp][
i].getX();
1183 y[
i] = mCandTr[mCurHyp][
i].getY();
1185 mPCA[mCurHyp][2] =
z;
1187 setTrackPos(mTrPos[mCurHyp][
i], mCandTr[mCurHyp][
i]);
1193 mPCA[mCurHyp][0] = sumX / N;
1194 mPCA[mCurHyp][1] = sumY / N;
1196 if (mMaxDXIni > 0 && !roughDXCut()) {
1201 FwdcalcTrackResiduals();
1202 float chi2Upd, chi2 = FwdcalcChi2NoErr();
1204 calcTrackDerivatives();
1205 FwdcalcResidDerivativesNoErr();
1206 FwdcalcChi2DerivativesNoErr();
1209 if (!mD2Chi2Dz2.Invert()) {
1212 VecND dz = mD2Chi2Dz2 * mDChi2Dz;
1214 if (!FwdcorrectTracks(dz)) {
1218 if (mCrossIDAlt >= 0 && closerToAlternative()) {
1219 mAllowAltPreference =
false;
1222 FwdcalcTrackResiduals();
1223 chi2Upd = FwdcalcChi2NoErr();
1224 if (getAbsMax(dz) < mMinParamChange || chi2Upd > chi2 * mMinRelChi2Change) {
1229 }
while (++mNIters[mCurHyp] < mMaxIter);
1231 mChi2[mCurHyp] = chi2 * NInv;
1232 return mChi2[mCurHyp] < mMaxChi2;
1236template <
int N,
typename... Args>
1242 for (
int i = N; accept &&
i--;) {
1243 for (
int j =
i;
j--;) {
1244 if (std::abs(mCandTr[mCurHyp][
i].
getX() - mCandTr[mCurHyp][
j].
getX()) > mMaxDXIni) {
1254template <
int N,
typename... Args>
1258 auto dxCur = mPCA[mCurHyp][0] - mCrossings.xDCA[mCrossIDCur], dyCur = mPCA[mCurHyp][1] - mCrossings.yDCA[mCrossIDCur];
1259 auto dxAlt = mPCA[mCurHyp][0] - mCrossings.xDCA[mCrossIDAlt], dyAlt = mPCA[mCurHyp][1] - mCrossings.yDCA[mCrossIDAlt];
1260 return dxCur * dxCur + dyCur * dyCur > dxAlt * dxAlt + dyAlt * dyAlt;
1264template <
int N,
typename... Args>
1267 LOG(info) << N <<
"-prong vertex fitter in " << (mUseAbsDCA ?
"abs." :
"weighted") <<
" distance minimization mode";
1268 LOG(info) <<
"Bz: " << mBz <<
" MaxIter: " << mMaxIter <<
" MaxChi2: " << mMaxChi2;
1269 LOG(info) <<
"Stopping condition: Max.param change < " << mMinParamChange <<
" Rel.Chi2 change > " << mMinRelChi2Change;
1270 LOG(info) <<
"Discard candidates for : Rvtx > " << getMaxR() <<
" DZ between tracks > " << mMaxDXIni;
1273template <
int N,
typename... Args>
1278 if (mUseMatBudget) {
1279 auto mb = mMatLUT->getMatBudget(t.
getX(), t.
getY(), t.
getZ(), p[0], p[1], p[2]);
1280 x2x0 = (
float)mb.meanX2X0;
1282 }
else if (mTGeoFallBackAllowed) {
1284 x2x0 = (
float)geoMan.meanX2X0;
1292using FwdDCAFitter2 = FwdDCAFitterN<2, o2::track::TrackParCovFwd>;
1293using FwdDCAFitter3 = FwdDCAFitterN<3, o2::track::TrackParCovFwd>;