#ifndef DAFBase_H #define DAFBase_H /// Common functions which is used to implement SmootherFitFunctional in every KF-approach. #include #include #include "FitFunctional.h" cnst INF_p = 10000.f; static const int NIterDAF = 4; static const int NIterDAF_tabl = 6; cnst T_DAF [NIterDAF_tabl] = {9, 4, 1, 0.1, 1, 0.1}; cnst T_DAFi[NIterDAF_tabl] = {ONE/(2.*T_DAF[0]), ONE/(2.*T_DAF[1]), ONE/(2.*T_DAF[2]), ONE/(2.*T_DAF[3]), ONE/(2.*T_DAF[4]), ONE/(2.*T_DAF[5])}; cnst chi2_cut[NIterDAF_tabl] = {16., 16., 16., 16., 16., 16.}; class DAFBase: public virtual FitFunctional { // base class for all approaches public: void Smooth(TrackV &t, Station vStations[], int NStations, bool EmptyHit = 1, bool useWeights = 0) const; void SmoothHit(int iHit, TrackV &t, Station vStations[], int NStations, bool EmptyHit = 1) const; void RunDAF(TrackV &t, Station vStations[], int NStations) const; protected: // combain two tracks into one virtual void FilterTracks(Fvec_t *r, CovV &C, const Fvec_t *m, const CovV &V, Fvec_t *chi2 = 0) const = 0; void UpdateWeights(TrackV &t, Station vStations[], int NStations, int const &IterDAF) const; #if defined(UD_FILTERING_S) || defined(SQUARE_ROOT1S) || defined(SQUARE_ROOT1) void Diagonalize(const CovVConventional& C, Fvec_t D[5], Fvec_t V[5][5]) const; #endif #if defined(UD_FILTERING_V) || defined(CONVENTIONAL) void InvertCholetsky(CovVConventional &CM) const; void Multiply(const CovVConventional &C, const Fvec_t *r_in, Fvec_t *r_out) const; #endif }; inline void DAFBase::Smooth(TrackV &t, Station vStations[], int NStations, bool EmptyHit, bool useWeights) const { Fvec_t ws[MaxNStations]; if (useWeights) { for( int i = 0; i < NStations; ++i ) ws[i] = t.vHits[i].w * t.w[i]; for(int iT=0; iT<6; iT++) // used in DAF, so should be already initialized t.T[iT] = t.Ts[NStations-1][iT]; t.C = t.Cs[NStations-1]; } else { for( int i = 0; i < NStations; ++i ) ws[i] = t.vHits[i].w; GuessVec( t, vStations, NStations, 0 ); } // downstream FieldRegion f; Fvec_t z0,z1,z2, dz; FieldVector H0, H1, H2; Fvec_t qp0 = t.T[4]; Int_t i= NStations-1; HitV *h = &t.vHits[i]; FilterFirst( t, *h, vStations[i] ); AddMaterial( t, vStations[ i ], qp0 ); z1 = vStations[ i ].z; vStations[i].Map.GetField(t.T[0],t.T[1], H1); H1.Combine( h->H, h->w ); z2 = vStations[ i-2 ].z; dz = z2-z1; vStations[ i-2 ].Map.GetField(t.T[0]+t.T[2]*dz,t.T[1]+t.T[3]*dz,H2); h = &t.vHits[i-2]; H2.Combine( h->H, h->w ); for( --i; i>=0; i-- ){ h = &t.vHits[i]; Station &st = vStations[i]; z0 = st.z; dz = (z1-z0); st.Map.GetField(t.T[0]-t.T[2]*dz,t.T[1]-t.T[3]*dz,H0); H0.Combine( h->H, h->w ); f.Set( H0, z0, H1, z1, H2, z2); ExtrapolateALight( t.T, t.C, st.zhit, qp0, f ); if (i == 1) { AddMaterial( t, st, qp0, true ); // pipe } else AddMaterial( t, st, qp0 ); if(EmptyHit) { for(int iT=0; iT<6; iT++) t.Ts[i][iT] = t.T[iT]; t.Cs[i] = t.C; // t.Chi2s[i] = t.Chi2; // t.NDFs[i] = t.NDF; } Fvec_t u = h->x*st.UInfo.cos_phi + h->y*st.UInfo.sin_phi; Fvec_t v = h->x*st.VInfo.cos_phi + h->y*st.VInfo.sin_phi; Filter( t, st.UInfo, u, ws[i] ); Filter( t, st.VInfo, v, ws[i] ); H2 = H1; z2 = z1; H1 = H0; z1 = z0; if(!EmptyHit) { for(int iT=0; iT<6; iT++) t.Ts[i][iT] = t.T[iT]; t.Cs[i] = t.C; } } t.fs[0] = f; // upstream qp0 = t.T[4]; i = 0; h = &t.vHits[i]; FilterFirst( t, *h, vStations[i] ); AddMaterial( t, vStations[ i ], qp0 ); z1 = vStations[ i ].z; vStations[i].Map.GetField(t.T[0],t.T[1], H1); H1.Combine( h->H, h->w ); z2 = vStations[ i+2 ].z; dz = z2-z1; vStations[ i+2 ].Map.GetField(t.T[0]+t.T[2]*dz,t.T[1]+t.T[3]*dz,H2); h = &t.vHits[i+2]; H2.Combine( h->H, h->w ); for( ++i; i1) continue; h = &t.vHits[i]; Station &st = vStations[i]; z0 = st.z; dz = (z1-z0); st.Map.GetField(t.T[0]-t.T[2]*dz,t.T[1]-t.T[3]*dz,H0); H0.Combine( h->H, h->w ); f.Set( H0, z0, H1, z1, H2, z2); t.fs[i] = f; ExtrapolateALight( t.T, t.C, st.zhit, qp0, f ); if (i < NStations-1) if ( i >= NStations/2 ) // add short to longer FilterTracks(t.Ts[i], t.Cs[i], t.T, t.C, &t.Chi2s[i]); else { Fvec_t T[6]; CovV C = t.C; for( int k = 0; k < 5; k++) T[k] = t.T[k]; FilterTracks(T, C, t.Ts[i], t.Cs[i], &t.Chi2s[i]); for( int k = 0; k < 5; k++) t.Ts[i][k] = T[k]; t.Cs[i] = C; } else if (EmptyHit) { for(int iT=0; iT<6; iT++) t.Ts[NStations-1][iT] = t.T[iT]; t.Cs[NStations-1] = t.C; } if (i == 1) AddMaterial( t, st, qp0, true ); // pipe else AddMaterial( t, st, qp0 ); Fvec_t u = h->x*st.UInfo.cos_phi + h->y*st.UInfo.sin_phi; Fvec_t v = h->x*st.VInfo.cos_phi + h->y*st.VInfo.sin_phi; Filter( t, st.UInfo, u, ws[i] ); Filter( t, st.VInfo, v, ws[i] ); H2 = H1; z2 = z1; H1 = H0; z1 = z0; } if (!EmptyHit) { for(int iT=0; iT<6; iT++) t.Ts[NStations-1][iT] = t.T[iT]; t.Cs[NStations-1] = t.C; } } // inline void DAFBase::Smooth inline void DAFBase::SmoothHit(int iHit, TrackV &t, Station vStations[], int NStations, bool EmptyHit) const { GuessVec( t, vStations,NStations ); // fit downstream to the hit we are interested in FieldRegion f; Fvec_t z0,z1,z2, dz; FieldVector H0, H1, H2; Fvec_t qp0 = t.T[4]; Int_t i= NStations-1; HitV *h = &t.vHits[i]; FilterFirst( t, *h, vStations[i] ); AddMaterial( t, vStations[ i ], qp0 ); z1 = vStations[ i ].z; vStations[i].Map.GetField(t.T[0],t.T[1], H1); H1.Combine( h->H, h->w ); z2 = vStations[ i-2 ].z; dz = z2-z1; vStations[ i-2 ].Map.GetField(t.T[0]+t.T[2]*dz,t.T[1]+t.T[3]*dz,H2); h = &t.vHits[i-2]; H2.Combine( h->H, h->w ); for( --i; i>=iHit; i-- ){ h = &t.vHits[i]; Station &st = vStations[i]; z0 = st.z; dz = (z1-z0); st.Map.GetField(t.T[0]-t.T[2]*dz,t.T[1]-t.T[3]*dz,H0); H0.Combine( h->H, h->w ); f.Set( H0, z0, H1, z1, H2, z2); ExtrapolateALight( t.T, t.C, st.zhit, qp0, f ); if(i == 1) AddPipeMaterial( t, qp0 ); AddMaterial( t, st, qp0 ); if(EmptyHit && i==iHit) continue; Fvec_t u = h->x*st.UInfo.cos_phi + h->y*st.UInfo.sin_phi; Fvec_t v = h->x*st.VInfo.cos_phi + h->y*st.VInfo.sin_phi; Filter( t, st.UInfo, u, h->w ); Filter( t, st.VInfo, v, h->w ); H2 = H1; z2 = z1; H1 = H0; z1 = z0; } for(int iT=0; iT<6; iT++) t.Ts[iHit][iT] = t.T[iT]; t.Cs[iHit] = t.C; t.fs[iHit] = t.f; if(iHit==0) return; // fit upstream to the hit, that is previous to the hit we are interested in GuessVec( t, vStations,NStations, 1); qp0 = t.T[4]; i= 0; h = &t.vHits[i]; FilterFirst( t, *h, vStations[i] ); AddMaterial( t, vStations[ i ], qp0 ); z1 = vStations[ i ].z; vStations[i].Map.GetField(t.T[0],t.T[1], H1); H1.Combine( h->H, h->w ); z2 = vStations[ i+2 ].z; dz = z2-z1; vStations[ i+2 ].Map.GetField(t.T[0]+t.T[2]*dz,t.T[1]+t.T[3]*dz,H2); h = &t.vHits[i+2]; H2.Combine( h->H, h->w ); for( ++i; iH, h->w ); f.Set( H0, z0, H1, z1, H2, z2); ExtrapolateALight( t.T, t.C, st.zhit, qp0, f ); if(i == 2) AddPipeMaterial( t, qp0 ); AddMaterial( t, st, qp0 ); Fvec_t u = h->x*st.UInfo.cos_phi + h->y*st.UInfo.sin_phi; Fvec_t v = h->x*st.VInfo.cos_phi + h->y*st.VInfo.sin_phi; Filter( t, st.UInfo, u, h->w ); Filter( t, st.VInfo, v, h->w ); H2 = H1; z2 = z1; H1 = H0; z1 = z0; } // extrapolate obtained parameters to the hit we are interested in h = &t.vHits[iHit]; Station &st = vStations[iHit]; z0 = st.z; dz = (z1-z0); st.Map.GetField(t.T[0]-t.T[2]*dz,t.T[1]-t.T[3]*dz,H0); H0.Combine( h->H, h->w ); f.Set( H0, z0, H1, z1, H2, z2); ExtrapolateALight( t.T, t.C, st.zhit, qp0, f ); if(iHit == 2) AddPipeMaterial( t, qp0 ); if(EmptyHit && iHit ==NStations-1) { for(int iT=0; iT<6; iT++) t.Ts[iHit][iT] = t.T[iT]; t.Cs[iHit] = t.C; t.fs[iHit] = t.f; return; } if ( iHit >= NStations/2 ) // add short to longer FilterTracks(t.Ts[iHit], t.Cs[iHit], t.T, t.C, &t.Chi2s[iHit]); else { FilterTracks(t.T, t.C, t.Ts[iHit], t.Cs[iHit], &t.Chi2s[iHit]); for( int k = 0; k < 5; k++) t.Ts[iHit][k] = t.T[k]; t.Cs[iHit] = t.C; } for(int iT=0; iT<6; iT++) t.T[iT] = t.Ts[iHit][iT]; t.C = t.Cs[iHit]; t.f = t.fs[iHit]; } // void DAFBase::SmoothHit inline void DAFBase::UpdateWeights(TrackV &t, Station vStations[], int NStations, int const &IterDAF) const { #ifdef VC float_m Check; #else Fvec_t Check; #endif for(int iSt=0; iSt(exp(p[iexp])); } P.load(mem); #else P = exp( P ); #endif P += ONE; t.w[iSt] = 1.f/min( P, INF_p ); } } // SmoothDAF inline void DAFBase::RunDAF(TrackV &t, Station vStations[], int NStations) const { Smooth(t, vStations, NStations, 1); for(int i=0; i 4 // After four sweeps, skip the rotation if the off-diagonal element is small. TODO // && (fabs(d[ip])+g == fabs(d[ip])) // && (fabs(d[iq])+g == fabs(d[iq])) ) // a[ip][iq]=0.0; // else // if ( NotEmpty(fabs(a[ip][iq]) > tresh) ) { Fvec_t h = d[iq] - d[ip]; Fvec_t t; // tangens(theta) // if (fabs(h)+g == fabs(h))// TODO // t = (a[ip][iq])/h; // t = 1/(2theta) // else { const Fvec_t theta = 0.5*h/(a[ip][iq]); t = 1.0/( fabs(theta)+sqrt(1.0+theta*theta) ); t = if3( theta < 0.0, -t, t ); } const Fvec_t c = 1.f/sqrt(1.f + t*t); const Fvec_t s = t*c; const Fvec_t tau = s/(1.f + c); h = t*a[ip][iq]; z[ip] -= h; z[iq] += h; d[ip] -= h; d[iq] += h; a[ip][iq]=0.0; for (j=0;j<=ip-1;j++) { // Case of rotations 1 <= j < p. ROTATE(a,j,ip,j,iq); } for (j=ip+1;j<=iq-1;j++) { // Case of rotations p < j < q. ROTATE(a,ip,j,j,iq); } for (j=iq+1;j a[j*(j+1)/2+i]; a[i][i] -> a[i*(i+3)/2] Fvec_t d[5], uud, u[5][5]; for(int i=0; i<5; i++) { d[i]=ZERO; for(int j=0; j<5; j++) u[i][j]=0.; } for(int i=0; i<5; i++) { uud=0.; for(int j=0; j