From 61cf78a66de3d80a168caf4ba2f9b48b5de5d40f Mon Sep 17 00:00:00 2001 From: "se.gorbunov" <se.gorbunov@gsi.de> Date: Wed, 15 Feb 2023 00:08:34 +0000 Subject: [PATCH] L1 fit: unify track guess routines --- reco/L1/CbmL1Performance.cxx | 3 - reco/L1/L1Algo/L1Algo.h | 12 -- reco/L1/L1Algo/L1Fit.cxx | 129 ++++++++++++++++++ reco/L1/L1Algo/L1Fit.h | 3 + reco/L1/L1Algo/L1TrackFitter.cxx | 226 ++----------------------------- 5 files changed, 145 insertions(+), 228 deletions(-) diff --git a/reco/L1/CbmL1Performance.cxx b/reco/L1/CbmL1Performance.cxx index dad4eb24ed..4b9f07235f 100644 --- a/reco/L1/CbmL1Performance.cxx +++ b/reco/L1/CbmL1Performance.cxx @@ -54,9 +54,6 @@ #include <map> #include <vector> -#include <cmath> -#include <math.h> - #include "L1Algo/L1Algo.h" #include "L1Algo/L1Def.h" #include "L1Algo/L1Fit.h" diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h index 5a8d7177cf..006a21fc24 100644 --- a/reco/L1/L1Algo/L1Algo.h +++ b/reco/L1/L1Algo/L1Algo.h @@ -336,18 +336,6 @@ public: int istal, int istam, int istar, L1TrackPar* T_1, L1FieldRegion* fld_1, L1HitIndex_t* hitsl_1, Tindex& n_2, L1Vector<L1HitIndex_t>& i1_2, L1Vector<L1HitIndex_t>& hitsm_2); - - /// ------ Subroutines used by L1Algo::KFTrackFitter() ------ - - void GuessVec(L1TrackPar& t, fvec* xV, fvec* yV, fvec* zV, fvec* Sy, fmask* wV, int NHits, fvec* zCur = 0); - void GuessVec(L1Fit& t, fvec* xV, fvec* yV, fvec* zV, fvec* Sy, fmask* wV, int NHits, fvec* zCur = 0, fvec* timeV = 0, - fmask* w_time = 0); - void GuessVecNoField(L1Fit& t, fvec& x_last, fvec& x_2last, fvec& y_last, fvec& y_2last, fvec& z_end, fvec& z_2last, - fvec& time_last, fmask* w_time, fvec& dt2_last); - - void FilterFirst(L1Fit& track, fvec& x, fvec& y, fvec& t, fvec& dt2, fvec& dx2, fvec& dy2, fvec& dxy); - - #ifdef DRAW L1AlgoDraw* draw {nullptr}; void DrawRecoTracksTime(const L1Vector<CbmL1Track>& tracks); diff --git a/reco/L1/L1Algo/L1Fit.cxx b/reco/L1/L1Algo/L1Fit.cxx index 1b17d6982f..3a99d903db 100644 --- a/reco/L1/L1Algo/L1Fit.cxx +++ b/reco/L1/L1Algo/L1Fit.cxx @@ -1725,4 +1725,133 @@ void L1Fit::FilterChi2(const L1UMeasurementInfo& info, cnst& x, cnst& y, cnst& C chi2 += zeta * zeta / (du2 + HCH); } + +void L1Fit::GuessTrack(const fvec& trackZ, const fvec hitX[], const fvec hitY[], const fvec hitZ[], const fvec hitT[], + const fvec By[], const fmask hitW[], const fmask hitWtime[], int NHits) +{ + // gives nice initial approximation for x,y,tx,ty - almost same as KF fit. qp - is shifted by 4%, resid_ual - ~3.5% (KF fit resid_ual - 1%). + + const fvec c_light(0.000299792458), c_light_i(fvec(1.) / c_light); + + fvec A0 = 0., A1 = 0., A2 = 0., A3 = 0., A4 = 0., A5 = 0.; + fvec a0 = 0., a1 = 0., a2 = 0.; + fvec b0 = 0., b1 = 0., b2 = 0.; + + fvec time = 0.; + fmask isTimeSet = fmask::Zero(); + + fvec prevZ = 0.; + fvec sy = 0., Sy = 0.; // field integrals + + for (int i = 0; i < NHits; i++) { + + fvec w = iif(hitW[i], fvec::One(), fvec::Zero()); + + fmask setTime = (!isTimeSet) && hitWtime[i] && hitW[i]; + time(setTime) = hitT[i]; + isTimeSet = isTimeSet || setTime; + + fvec x = hitX[i]; + fvec y = hitY[i]; + fvec z = hitZ[i] - trackZ; + + { + fvec dZ = z - prevZ; + Sy(hitW[i]) += dZ * sy + fvec(0.5) * dZ * dZ * By[i]; + sy(hitW[i]) += dZ * By[i]; + prevZ(hitW[i]) = z; + } + + fvec S = Sy; + + fvec wz = w * z; + fvec wS = w * S; + + A0 += w; + A1 += wz; + A2 += wz * z; + A3 += wS; + A4 += wS * z; + A5 += wS * S; + + a0 += w * x; + a1 += wz * x; + a2 += wS * x; + + b0 += w * y; + b1 += wz * y; + b2 += wS * y; + } + + fvec m00 = A0; + fvec m01 = A1; + fvec m02 = A3; + + fvec m11 = A2; + fvec m12 = A4; + + fvec m22 = A5; + + fvec m21 = m12; + + // { m00 m01 m02 } ( a0 ) + // { m01 m11 m12 } = x * ( a1 ) + // { m02 m21 m22 } ( a2 ) + + { // triangulation row 0 + m11 = m00 * m11 - m01 * m01; + m12 = m00 * m12 - m01 * m02; + a1 = m00 * a1 - m01 * a0; + + m21 = m00 * m21 - m02 * m01; + m22 = m00 * m22 - m02 * m02; + a2 = m00 * a2 - m02 * a0; + } + + { // triangulation step row 1 + m22 = m11 * m22 - m21 * m12; + a2 = m11 * a2 - m21 * a1; + } + + fvec L = 0.; + { // diagonalization row 2 + L(abs(m22) > fvec(1.e-4)) = a2 / m22; + a1 -= L * m12; + a0 -= L * m02; + } + + { // diagonalization row 1 + fTr.tx = a1 / m11; + a0 -= fTr.tx * m01; + } + + { // diagonalization row 0 + fTr.x = a0 / m00; + } + + fvec txtx1 = fvec(1.) + fTr.tx * fTr.tx; + L = L / txtx1; + fvec L1 = L * fTr.tx; + + A1 = A1 + A3 * L1; + A2 = A2 + (A4 + A4 + A5 * L1) * L1; + b1 += b2 * L1; + + // { A0 A1 } = x * ( b0 ) + // { A1 A2 } ( b1 ) + + A2 = A0 * A2 - A1 * A1; + b1 = A0 * b1 - A1 * b0; + + fTr.ty = b1 / A2; + fTr.y = (b0 - A1 * fTr.ty) / A0; + + fTr.qp = -L * c_light_i / sqrt(txtx1 + fTr.ty * fTr.ty); + fTr.t = time; + fTr.z = trackZ; + fTr.vi = 0.; + fQp0 = fTr.qp; +} + + #undef cnst diff --git a/reco/L1/L1Algo/L1Fit.h b/reco/L1/L1Algo/L1Fit.h index 72fe29a978..6ca7a9b1f9 100644 --- a/reco/L1/L1Algo/L1Fit.h +++ b/reco/L1/L1Algo/L1Fit.h @@ -130,6 +130,9 @@ public: static void FilterChi2(const L1UMeasurementInfo& info, cnst& x, cnst& y, cnst& C00, cnst& C10, cnst& C11, fvec& chi2, cnst& u, cnst& du2); + void GuessTrack(const fvec& trackZ, const fvec hitX[], const fvec hitY[], const fvec hitZ[], const fvec hitT[], + const fvec By[], const fmask hitW[], const fmask hitWtime[], int NHits); + private: fmask fMask {fmask::One()}; // mask of active elements in simd vectors fvec fMaskF {fvec::One()}; // floating point representation of fMask diff --git a/reco/L1/L1Algo/L1TrackFitter.cxx b/reco/L1/L1Algo/L1TrackFitter.cxx index 4ed3a4b1dc..4676463254 100644 --- a/reco/L1/L1Algo/L1TrackFitter.cxx +++ b/reco/L1/L1Algo/L1TrackFitter.cxx @@ -75,8 +75,8 @@ void L1Algo::L1KFTrackFitter() fvec time_first; fvec dt2_first; - fvec x_last, x_2last; - fvec y_last, y_2last; + fvec x_last; + fvec y_last; fvec d_xx_lst; fvec d_yy_lst; fvec d_xy_lst; @@ -85,7 +85,7 @@ void L1Algo::L1KFTrackFitter() fvec dt2_last; // fvec dt2_lst; /// TODO: Why are there two different variables for the time error on the last station? - fvec Sy[L1Constants::size::kMaxNstations]; + fvec By[L1Constants::size::kMaxNstations]; fmask w[L1Constants::size::kMaxNstations]; fmask w_time[L1Constants::size::kMaxNstations]; // !!! @@ -95,7 +95,7 @@ void L1Algo::L1KFTrackFitter() fvec fldZ1; fvec fldZ2; fvec z_start; - fvec z_end, z_2last; + fvec z_end; L1FieldValue fB[L1Constants::size::kMaxNstations], fB_temp _fvecalignment; @@ -182,34 +182,16 @@ void L1Algo::L1KFTrackFitter() time_last[iVec] = time[ista][iVec]; dt2_last[iVec] = dt2[ista][iVec]; } - else if (ih == nHitsTrack - 2) { - z_2last[iVec] = z[ista][iVec]; - x_2last[iVec] = x[ista][iVec]; - y_2last[iVec] = y[ista][iVec]; - } } - fscal prevZ = z_end[iVec]; - fscal cursy = 0., curSy = 0.; for (int ih = nHitsTrack - 1; ih >= 0; ih--) { const int ista = iSta[ih]; const L1Station& st = fParameters.GetStation(ista); - const fscal curZ = z[ista][iVec]; - fscal dZ = curZ - prevZ; - fscal By = st.fieldSlice.cy[0][0]; - curSy += dZ * cursy + dZ * dZ * By / 2.; - cursy += dZ * By; - Sy[ista][iVec] = curSy; - prevZ = curZ; + By[ista][iVec] = st.fieldSlice.cy[0][0]; } } - if (kGlobal == fTrackingMode || kMcbm == fTrackingMode) { - GuessVecNoField(fit, x_last, x_2last, y_last, y_2last, z_end, z_2last, time_last, w_time, dt2_last); - } - else { - GuessVec(fit, x, y, z, Sy, w, nStations, &z_end, time, w_time); - } + fit.GuessTrack(z_end, x, y, z, time, By, w, w_time, nStations); if (kGlobal == fTrackingMode || kMcbm == fTrackingMode) { tr.qp = fvec(1. / 1.1); } @@ -233,7 +215,6 @@ void L1Algo::L1KFTrackFitter() tr.t = time_last; tr.NDF = -3.0; - fldZ1 = z[ista]; sta[ista].fieldSlice.GetFieldValue(tr.x, tr.y, fldB1); @@ -324,7 +305,13 @@ void L1Algo::L1KFTrackFitter() ista = 0; - FilterFirst(fit, x_first, y_first, time_first, dt2_first, d_xx_fst, d_yy_fst, d_xy_fst); + tr.ResetErrors(d_xx_fst, d_yy_fst, 0.1, 0.1, 1., dt2_first, 1.e2); + tr.C10 = d_xy_fst; + + tr.x = x_first; + tr.y = y_first; + tr.t = time_first; + tr.NDF = -3.0; fit.SetQp0(tr.qp); @@ -374,190 +361,3 @@ void L1Algo::L1KFTrackFitter() } // iter } } -void L1Algo::GuessVecNoField(L1Fit& track, fvec& x_last, fvec& x_2last, fvec& y_last, fvec& y_2last, fvec& z_end, - fvec& z_2last, fvec& time_last, fmask* /*w_time*/, fvec& dt2_last) -{ - L1TrackPar& tr = track.Tr(); - - fvec dzi = fvec(1.) / (z_end - z_2last); - - tr.x = x_last; - tr.y = y_last; - tr.tx = (x_last - x_2last) * dzi; - tr.ty = (y_last - y_2last) * dzi; - tr.t = time_last; - tr.z = z_end; - - tr.ResetErrors(1., 1., 1., 1., 1., dt2_last, 1.e2); - tr.NDF = fvec(2.); -} - - -void L1Algo::GuessVec(L1TrackPar& tr, fvec* xV, fvec* yV, fvec* zV, fvec* Sy, fmask* wV, int NHits, fvec* zCur) -// gives nice initial approximation for x,y,tx,ty - almost same as KF fit. qp - is shifted by 4%, resid_ual - ~3.5% (KF fit resid_ual - 1%). -{ - - fvec A0, A1 = 0., A2 = 0., A3 = 0., A4 = 0., A5 = 0., a0, a1 = 0., a2 = 0., b0, b1 = 0., b2 = 0.; - fvec z0, x, y, z, S, w, wz, wS; - - int i = NHits - 1; - if (zCur) z0 = *zCur; - else - z0 = zV[i]; - w = iif(wV[i], fvec::One(), fvec::Zero()); - A0 = w; - a0 = w * xV[i]; - b0 = w * yV[i]; - for (i = 0; i < NHits; i++) { - x = xV[i]; - y = yV[i]; - w = iif(wV[i], fvec::One(), fvec::Zero()); - z = zV[i] - z0; - S = Sy[i]; - wz = w * z; - wS = w * S; - A0 += w; - A1 += wz; - A2 += wz * z; - A3 += wS; - A4 += wS * z; - A5 += wS * S; - a0 += w * x; - a1 += wz * x; - a2 += wS * x; - b0 += w * y; - b1 += wz * y; - b2 += wS * y; - } - - fvec A3A3 = A3 * A3; - fvec A3A4 = A3 * A4; - fvec A1A5 = A1 * A5; - fvec A2A5 = A2 * A5; - fvec A4A4 = A4 * A4; - - fvec det = fvec::One() / (-A2 * A3A3 + A1 * (A3A4 + A3A4 - A1A5) + A0 * (A2A5 - A4A4)); - fvec Ai0 = (-A4A4 + A2A5); - fvec Ai1 = (A3A4 - A1A5); - fvec Ai2 = (-A3A3 + A0 * A5); - fvec Ai3 = (-A2 * A3 + A1 * A4); - fvec Ai4 = (A1 * A3 - A0 * A4); - fvec Ai5 = (-A1 * A1 + A0 * A2); - - fvec L, L1; - tr.x = (Ai0 * a0 + Ai1 * a1 + Ai3 * a2) * det; - tr.tx = (Ai1 * a0 + Ai2 * a1 + Ai4 * a2) * det; - fvec txtx1 = fvec(1.) + tr.tx * tr.tx; - L = (Ai3 * a0 + Ai4 * a1 + Ai5 * a2) * det / txtx1; - L1 = L * tr.tx; - A1 = A1 + A3 * L1; - A2 = A2 + (A4 + A4 + A5 * L1) * L1; - b1 += b2 * L1; - det = fvec::One() / (-A1 * A1 + A0 * A2); - - tr.y = (A2 * b0 - A1 * b1) * det; - tr.ty = (-A1 * b0 + A0 * b1) * det; - tr.qp = -L * c_light_i / sqrt(txtx1 + tr.ty * tr.ty); - tr.z = z0; -} - -void L1Algo::GuessVec(L1Fit& track, fvec* xV, fvec* yV, fvec* zV, fvec* Sy, fmask* wV, int NHits, fvec* zCur, - fvec* timeV, fmask* w_time) -// gives nice initial approximation for x,y,tx,ty - almost same as KF fit. qp - is shifted by 4%, resid_ual - ~3.5% (KF fit resid_ual - 1%). -{ - L1TrackPar& tr = track.Tr(); - - fvec A0, A1 = 0., A2 = 0., A3 = 0., A4 = 0., A5 = 0., a0, a1 = 0., a2 = 0., b0, b1 = 0., b2 = 0.; - fvec z0, x, y, z, S, w, wz, wS, time; - - time = fvec(0.); - - int i = NHits - 1; - if (zCur) { z0 = *zCur; } - else { - z0 = zV[i]; - } - - w = iif(wV[i], fvec::One(), fvec::Zero()); - A0 = w; - a0 = w * xV[i]; - b0 = w * yV[i]; - - fvec nhits = 0; - for (i = 0; i < NHits; i++) { - x = xV[i]; - y = yV[i]; - w = iif(wV[i], fvec::One(), fvec::Zero()); - ; - if (timeV) nhits(w_time[i]) += fvec::One(); - z = zV[i] - z0; - S = Sy[i]; - - wz = w * z; - wS = w * S; - - A0 += w; - A1 += wz; - A2 += wz * z; - A3 += wS; - A4 += wS * z; - A5 += wS * S; - a0 += w * x; - a1 += wz * x; - a2 += wS * x; - b0 += w * y; - b1 += wz * y; - b2 += wS * y; - if (timeV) { - fvec dx = xV[i] - fParameters.GetTargetPositionX(); - fvec dy = yV[i] - fParameters.GetTargetPositionY(); - fvec dz = zV[i] - fParameters.GetTargetPositionZ(); - time(w_time[i]) += (timeV[i] - sqrt(dx * dx + dy * dy + dz * dz) / fvec(30.)); - } - } - - fvec A3A3 = A3 * A3; - fvec A3A4 = A3 * A4; - fvec A1A5 = A1 * A5; - fvec A2A5 = A2 * A5; - fvec A4A4 = A4 * A4; - - fvec det = fvec::One() / (-A2 * A3A3 + A1 * (A3A4 + A3A4 - A1A5) + A0 * (A2A5 - A4A4)); - fvec Ai0 = (-A4A4 + A2A5); - fvec Ai1 = (A3A4 - A1A5); - fvec Ai2 = (-A3A3 + A0 * A5); - fvec Ai3 = (-A2 * A3 + A1 * A4); - fvec Ai4 = (A1 * A3 - A0 * A4); - fvec Ai5 = (-A1 * A1 + A0 * A2); - - fvec L, L1; - tr.x = (Ai0 * a0 + Ai1 * a1 + Ai3 * a2) * det; - tr.tx = (Ai1 * a0 + Ai2 * a1 + Ai4 * a2) * det; - fvec txtx1 = fvec(1.) + tr.tx * tr.tx; - L = (Ai3 * a0 + Ai4 * a1 + Ai5 * a2) * det / txtx1; - L1 = L * tr.tx; - A1 = A1 + A3 * L1; - A2 = A2 + (A4 + A4 + A5 * L1) * L1; - b1 += b2 * L1; - det = fvec::One() / (-A1 * A1 + A0 * A2); - tr.y = (A2 * b0 - A1 * b1) * det; - tr.ty = (-A1 * b0 + A0 * b1) * det; - tr.qp = -L * c_light_i / sqrt(txtx1 + tr.ty * tr.ty); - if (timeV) { tr.t = iif(nhits > fvec::Zero(), time / nhits, fvec::Zero()); } - - tr.z = z0; -} - - -void L1Algo::FilterFirst(L1Fit& track, fvec& x, fvec& y, fvec& t, fvec& dt2, fvec& d_xx, fvec& d_yy, fvec& d_xy) -{ - L1TrackPar& tr = track.Tr(); - - tr.ResetErrors(d_xx, d_yy, 0.1, 0.1, 1., dt2, 1.e2); - tr.C10 = d_xy; - - tr.x = x; - tr.y = y; - tr.t = t; - tr.NDF = -3.0; -} -- GitLab