diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx index db648d2fac120806c1cf81bccb51512f9917ad00..6600ee182325e1ca6a5960d746f811542e31182f 100644 --- a/reco/L1/L1Algo/L1CATrackFinder.cxx +++ b/reco/L1/L1Algo/L1CATrackFinder.cxx @@ -86,7 +86,18 @@ inline void L1Algo::findSingletsStep0( // input /// the data is orginesed in order to be used by SIMD const Tindex end_lh = start_lh + n1_l; - + const int lastV = (n1_l - 1) / fvecLen; + if (lastV >= 0) { + // set some positive errors to unfilled part of vectors in order to avoid nans + L1HitPoint& hitl = Hits_l[0]; + d_u[lastV] = hitl.dU(); + d_v[lastV] = hitl.dV(); + HitTimeEr[lastV] = hitl.timeEr; + u_front_l[lastV] = hitl.U(); + u_back_l[lastV] = hitl.V(); + HitTime_l[lastV] = hitl.time; + zPos_l[lastV] = hitl.Z(); + } for (Tindex ilh = start_lh, i1 = 0; ilh < end_lh; ++ilh, ++i1) { Tindex i1_V = i1 / fvecLen; @@ -159,6 +170,7 @@ inline void L1Algo::findSingletsStep1( /// input 1st stage of singlet search for (int i1_V = 0; i1_V < n1_V; i1_V++) { L1TrackPar& T = T_1[i1_V]; + L1FieldRegion& fld1 = fld_1[i1_V]; // by middle hit, left hit and "center" . Will be used for extrapolation to right hit @@ -214,7 +226,8 @@ inline void L1Algo::findSingletsStep1( /// input 1st stage of singlet search if (istac != istal) fld1.Set(m_B, zstam, l_B, zstal, centB, zstac); else fld1.Set(m_B, zstam, l_B, zstal, fTargB, fTargZ); -#else // if USE_3HITS -- the best now +#else + // if USE_3HITS -- the best now L1FieldValue r_B _fvecalignment; const L1Station& star = fParameters.GetStation(istam + 1); fvec zstar = star.z; @@ -241,7 +254,6 @@ inline void L1Algo::findSingletsStep1( /// input 1st stage of singlet search T.C44 = fMaxInvMom / 3. * fMaxInvMom / 3.; T.C55 = timeEr * timeEr; - if (fParameters.DevIsFitSingletsFromTarget()) { // TODO: doesn't work. Why? T.x = fTargX; @@ -301,6 +313,8 @@ inline void L1Algo::findSingletsStep1( /// input 1st stage of singlet search T.C11 = dy1 * dy1; } + //assert(T.IsConsistent(true, -1)); + // add the target if (istal < fNfieldStations) { fvec eX, eY, J04, J14; @@ -316,17 +330,41 @@ inline void L1Algo::findSingletsStep1( /// input 1st stage of singlet search J[5] = J14; L1FilterVtx(T, fTargX, fTargY, TargetXYInfo, eX, eY, J); } - else { - L1ExtrapolateLine(T, fTargZ); - L1FilterXY(T, fTargX, fTargY, TargetXYInfo); + else { //TODO: SG: take the field into account properly + fvec eX, eY, J04, J14; + fvec dz; + dz = fTargZ - zl; + eX = T.tx * dz; + eY = T.ty * dz; + J04 = 0.f; + J14 = 0.f; + L1ExtrapolateJXY0(T.tx, T.ty, dz, fld0, eX, eY, J04, J14); + fvec J[6]; + J[0] = dz; + J[1] = 0; + J[2] = J04; + J[3] = 0; + J[4] = dz; + J[5] = J14; + L1FilterVtx(T, fTargX, fTargY, TargetXYInfo, eX, eY, J); + // old code + //L1ExtrapolateLine(T, fTargZ); + //assert(T.IsConsistent(true, -1)); + //L1FilterXY(T, fTargX, fTargY, TargetXYInfo); + //assert(T.IsConsistent(true, -1)); } } + //assert(T.IsConsistent(true, -1)); + if constexpr (L1Constants::control::kIfUseRadLengthTable) { - if (kGlobal == fTrackingMode || kMcbm == fTrackingMode) { + if (kMcbm == fTrackingMode) { fit.L1AddThickMaterial(T, fParameters.GetMaterialThickness(istal, T.x, T.y), fMaxInvMom, 1, stal.materialInfo.thick, 1); } + else if (kGlobal == fTrackingMode) { + fit.L1AddMaterial(T, fParameters.GetMaterialThickness(istal, T.x, T.y), fMaxInvMom, 1); + } else { fit.L1AddMaterial(T, fParameters.GetMaterialThickness(istal, T.x, T.y), fMaxInvMom, 1); } @@ -338,14 +376,19 @@ inline void L1Algo::findSingletsStep1( /// input 1st stage of singlet search fit.L1AddPipeMaterial(T, fMaxInvMom, 1); } + //assert(T.IsConsistent(true, -1)); + fvec dz = zstam - zl; L1ExtrapolateTime(T, dz, stam.timeInfo); - // extrapolate to left hit + // extrapolate to the middle hit if (istam < fNfieldStations) { L1Extrapolate0(T, zstam, fld0); } else { L1ExtrapolateLine(T, zstam); // TODO: fld1 doesn't work! } + + // assert(T.IsConsistent(true, -1)); + } // i1_V } @@ -373,6 +416,9 @@ inline void L1Algo::findDoubletsStep0( const Tindex i1_4 = i1 % fvecLen; L1TrackPar& T1 = T_1[i1_V]; + // assert(T1.IsEntryConsistent(true, i1_4)); + // if (!T1.IsEntryConsistent(false, i1_4)) continue; + const int n2Saved = n2; const fvec Pick_m22 = (fDoubletChi2Cut - T1.chi2); @@ -392,7 +438,7 @@ inline void L1Algo::findDoubletsStep0( L1HitIndex_t imh = 0; int irm1 = -1; - while (true) { + while (true) { // loop over the hits in the area if (fParameters.DevIsIgnoreHitSearchAreas()) { irm1++; if ((L1HitIndex_t) irm1 >= (HitsUnusedStopIndex[iStaM] - HitsUnusedStartIndex[iStaM])) break; @@ -411,6 +457,7 @@ inline void L1Algo::findDoubletsStep0( } // check y-boundaries + //TODO: move hardcoded cuts to parameters if ((stam.timeInfo) && (stal.timeInfo)) { if (fabs(time - hitm.time) > sqrt(timeError + hitm.timeEr * hitm.timeEr) * 5) continue; if (fabs(time - hitm.time) > 30) continue; @@ -495,7 +542,6 @@ inline void L1Algo::findDoubletsStep0( // FilterTime(T1, hitm.time, hitm.timeEr); - #ifdef DO_NOT_SELECT_TRIPLETS if (isec != TRACKS_FROM_TRIPLETS_ITERATION) #endif // DO_NOT_SELECT_TRIPLETS @@ -521,8 +567,10 @@ inline void L1Algo::findDoubletsStep0( hitsm_2.reduce(hitsm_2.size() - Ndoublets); break; } - } + } // loop over the hits in the area + lmDuplets[hitsl_1[i1]] = (n2Saved < n2); + } // for i1 } @@ -542,10 +590,24 @@ inline void L1Algo::findTripletsStep0( // input nsL1::vector<fvec>::TSimd& dv_, nsL1::vector<fvec>::TSimd& du_, nsL1::vector<fvec>::TSimd& timeR, nsL1::vector<fvec>::TSimd& timeER) { + int iStaM = &stam - fParameters.GetStations().begin(); + int iStaR = &star - fParameters.GetStations().begin(); + L1HitIndex_t hitsl_2[fvecLen]; L1HitIndex_t hitsm_2_tmp[fvecLen]; - fvec fvec_0; + fvec fvec_0 = 0.f; + fvec fvec_1 = 1.f; L1TrackPar L1TrackPar_0; + // SG!! to avoid nans in unfilled part + //TODO: SG: investigate, it changes the results !! + /* + L1TrackPar_0.C00 = 1.f; + L1TrackPar_0.C11 = 1.f; + L1TrackPar_0.C22 = 1.f; + L1TrackPar_0.C33 = 1.f; + L1TrackPar_0.C44 = 1.f; + L1TrackPar_0.C55 = 1.f; + */ L1Fit fit; fit.SetParticleMass(fDefaultMass); @@ -556,307 +618,342 @@ inline void L1Algo::findTripletsStep0( // input u_front_3.push_back(fvec_0); u_back_3.push_back(fvec_0); z_Pos_3.push_back(fvec_0); - // dx_.push_back(fvec_0); - // dy_.push_back(fvec_0); - du_.push_back(fvec_0); - dv_.push_back(fvec_0); + du_.push_back(fvec_1); + dv_.push_back(fvec_1); timeR.push_back(fvec_0); - timeER.push_back(fvec_0); - + timeER.push_back(fvec_1); - L1TrackPar T2; - L1FieldRegion f2; - // pack the data - fvec u_front_2; - fvec u_back_2; - fvec dx2; - fvec dy2; - fvec du2; - fvec dv2; - fvec zPos_2; - fvec timeM; - fvec timeMEr; - fvec num; + assert(istar < fNstations); //TODO SG!!! check if it is needed + if (istar >= fNstations) return; // ---- Add the middle hits to parameters estimation. Propagate to right station. ---- - if (istar < fNstations) { - for (Tindex i2 = 0; i2 < n2;) { - Tindex n2_4 = 0; - for (; n2_4 < fvecLen && i2 < n2; n2_4++, i2++) { - // if (!mrDuplets[hitsm_2[i2]]) { - // n2_4--; - // continue; - // } - const Tindex& i1 = i1_2[i2]; - const Tindex i1_V = i1 / fvecLen; - const Tindex i1_4 = i1 % fvecLen; - - - const L1TrackPar& T1 = T_1[i1_V]; - const L1FieldRegion& f1 = fld_1[i1_V]; - T2.SetOneEntry(n2_4, T1, i1_4); - f2.SetOneEntry(n2_4, f1, i1_4); - - const Tindex& imh = hitsm_2[i2]; - const L1HitPoint& hitm = vHits_m[imh]; - u_front_2[n2_4] = hitm.U(); - u_back_2[n2_4] = hitm.V(); - zPos_2[n2_4] = hitm.Z(); - timeM[n2_4] = hitm.time; - timeMEr[n2_4] = hitm.timeEr; - // num[n2_4] = hitm.track; - du2[n2_4] = hitm.dU(); - dv2[n2_4] = hitm.dV(); - - hitsl_2[n2_4] = hitsl_1[i1]; - hitsm_2_tmp[n2_4] = hitsm_2[i2]; - } // n2_4 - - dUdV_to_dX(du2, dv2, dx2, stam); - dUdV_to_dY(du2, dv2, dy2, stam); - - fvec dz = zPos_2 - T2.z; - - L1ExtrapolateTime(T2, dz, stam.timeInfo); - // add middle hit - L1ExtrapolateLine(T2, zPos_2); + for (Tindex i2 = 0; i2 < n2;) { + L1TrackPar T2 = L1TrackPar_0; + L1FieldRegion f2; + // pack the data + fvec u_front_2 = 0.f; + fvec u_back_2 = 0.f; + fvec dx2 = 1.f; + fvec dy2 = 1.f; + fvec du2 = 1.f; + fvec dv2 = 1.f; + fvec zPos_2 = 0.f; + fvec timeM = 0.f; + fvec timeMEr = 1.f; + + Tindex n2_4 = 0; + for (; n2_4 < fvecLen && i2 < n2; i2++) { + // if (!mrDuplets[hitsm_2[i2]]) { + // n2_4--; + // continue; + // } + const Tindex& i1 = i1_2[i2]; + const Tindex i1_V = i1 / fvecLen; + const Tindex i1_4 = i1 % fvecLen; + + const L1TrackPar& T1 = T_1[i1_V]; + + //assert(T1.IsEntryConsistent(true, i1_4)); + //if (!T1.IsEntryConsistent(false, i1_4)) continue; + + const L1FieldRegion& f1 = fld_1[i1_V]; + T2.SetOneEntry(n2_4, T1, i1_4); + f2.SetOneEntry(n2_4, f1, i1_4); + + const Tindex& imh = hitsm_2[i2]; + const L1HitPoint& hitm = vHits_m[imh]; + u_front_2[n2_4] = hitm.U(); + u_back_2[n2_4] = hitm.V(); + zPos_2[n2_4] = hitm.Z(); + timeM[n2_4] = hitm.time; + timeMEr[n2_4] = hitm.timeEr; + // num[n2_4] = hitm.track; + du2[n2_4] = hitm.dU(); + dv2[n2_4] = hitm.dV(); - L1UMeasurementInfo info = stam.frontInfo; + hitsl_2[n2_4] = hitsl_1[i1]; + hitsm_2_tmp[n2_4] = hitsm_2[i2]; + n2_4++; + } // n2_4 - if (fUseHitErrors) info.sigma2 = du2 * du2; + dUdV_to_dX(du2, dv2, dx2, stam); + dUdV_to_dY(du2, dv2, dy2, stam); - if (istam < fNfieldStations) { L1Filter(T2, info, u_front_2); } - else { - L1FilterNoField(T2, info, u_front_2); - } + // assert(T2.IsConsistent(true, n2_4)); - info = stam.backInfo; - if (fUseHitErrors) info.sigma2 = dv2 * dv2; + fvec dz = zPos_2 - T2.z; - if (istam < fNfieldStations) { L1Filter(T2, info, u_back_2); } - else { - L1FilterNoField(T2, info, u_back_2); - } + L1ExtrapolateTime(T2, dz, stam.timeInfo); - FilterTime(T2, timeM, timeMEr, stam.timeInfo); - if constexpr (L1Constants::control::kIfUseRadLengthTable) { - if (kGlobal == fTrackingMode || kMcbm == fTrackingMode) { - fit.L1AddThickMaterial(T2, fParameters.GetMaterialThickness(istam, T2.x, T2.y), fMaxInvMom, 1, - stam.materialInfo.thick, 1); - } - else { - fit.L1AddMaterial(T2, fParameters.GetMaterialThickness(istam, T2.x, T2.y), T2.qp, 1); - } - } - else { - fit.L1AddMaterial(T2, stam.materialInfo, T2.qp, 1); - } - if ((istar >= fNstationsBeforePipe) && (istam <= fNstationsBeforePipe - 1)) { - fit.L1AddPipeMaterial(T2, T2.qp, 1); - } + // assert(T2.IsConsistent(true, n2_4)); + + // add middle hit + L1ExtrapolateLine(T2, zPos_2); + + // assert(T2.IsConsistent(true, n2_4)); + + L1UMeasurementInfo info = stam.frontInfo; + + if (fUseHitErrors) info.sigma2 = du2 * du2; + + // TODO: SG: L1FilterNoField is wrong. + // TODO: If the field was present before, + // TODO: the momentum is correlated with the position and corresponding + // TODO: matrix elements must be up[dated - fvec dz2 = star.z - T2.z; - L1ExtrapolateTime(T2, dz2, stam.timeInfo); + if (istam < fNfieldStations) { L1Filter(T2, info, u_front_2); } + else { + L1FilterNoField(T2, info, u_front_2); + } + + // assert(T2.IsConsistent(true, n2_4)); - // extrapolate to the right hit station + info = stam.backInfo; + if (fUseHitErrors) info.sigma2 = dv2 * dv2; + + if (istam < fNfieldStations) { L1Filter(T2, info, u_back_2); } + else { + L1FilterNoField(T2, info, u_back_2); + } - if (istar <= fNfieldStations) { - L1Extrapolate(T2, star.z, T2.qp, f2); // Full extrapolation in the magnetic field + // assert(T2.IsConsistent(true, n2_4)); + + FilterTime(T2, timeM, timeMEr, stam.timeInfo); + + // assert(T2.IsConsistent(true, n2_4)); + + if constexpr (L1Constants::control::kIfUseRadLengthTable) { + if (kMcbm == fTrackingMode) { + fit.L1AddThickMaterial(T2, fParameters.GetMaterialThickness(istam, T2.x, T2.y), fMaxInvMom, 1, + stam.materialInfo.thick, 1); + } + else if (kGlobal == fTrackingMode) { + fit.L1AddMaterial(T2, fParameters.GetMaterialThickness(istam, T2.x, T2.y), fMaxInvMom, 1); } else { - L1ExtrapolateLine(T2, star.z); // Extrapolation with line () + fit.L1AddMaterial(T2, fParameters.GetMaterialThickness(istam, T2.x, T2.y), T2.qp, 1); } + } + else { + fit.L1AddMaterial(T2, stam.materialInfo, T2.qp, 1); + } + if ((istar >= fNstationsBeforePipe) && (istam <= fNstationsBeforePipe - 1)) { fit.L1AddPipeMaterial(T2, T2.qp, 1); } + + // assert(T2.IsConsistent(true, n2_4)); + + fvec dz2 = star.z - T2.z; + L1ExtrapolateTime(T2, dz2, stam.timeInfo); + + // assert(T2.IsConsistent(true, n2_4)); + + // extrapolate to the right hit station + + if (istar <= fNfieldStations) { + L1Extrapolate(T2, star.z, T2.qp, f2); // Full extrapolation in the magnetic field + } + else { + L1ExtrapolateLine(T2, star.z); // Extrapolation with line () + } + + // assert(T2.IsConsistent(true, n2_4)); + + // ---- Find the triplets(right hit). Reformat data in the portion of triplets. ---- + for (Tindex i2_4 = 0; i2_4 < n2_4; ++i2_4) { - // ---- Find the triplets(right hit). Reformat data in the portion of triplets. ---- - for (Tindex i2_4 = 0; i2_4 < n2_4; ++i2_4) { - if (kSts == fTrackingMode && (T2.C44[i2_4] < 0)) { continue; } - if (T2.C00[i2_4] < 0 || T2.C11[i2_4] < 0 || T2.C22[i2_4] < 0 || T2.C33[i2_4] < 0 || T2.C55[i2_4] < 0) continue; + //if (!T2.IsEntryConsistent(false, i2_4)) { continue; } + if (kSts == fTrackingMode && (T2.C44[i2_4] < 0)) { continue; } + if (T2.C00[i2_4] < 0 || T2.C11[i2_4] < 0 || T2.C22[i2_4] < 0 || T2.C33[i2_4] < 0 || T2.C55[i2_4] < 0) continue; - if (fabs(T2.tx[i2_4]) > fMaxSlope) continue; - if (fabs(T2.ty[i2_4]) > fMaxSlope) continue; + if (fabs(T2.tx[i2_4]) > fMaxSlope) continue; + if (fabs(T2.ty[i2_4]) > fMaxSlope) continue; - const fvec Pick_r22 = (fTripletChi2Cut - T2.chi2); - const float& timeError = T2.C55[i2_4]; - const float& time = T2.t[i2_4]; - // find first possible hit + const fvec Pick_r22 = (fTripletChi2Cut - T2.chi2); + const float& timeError = T2.C55[i2_4]; + const float& time = T2.t[i2_4]; + // find first possible hit #ifdef DO_NOT_SELECT_TRIPLETS - if (isec == TRACKS_FROM_TRIPLETS_ITERATION) Pick_r22 = Pick_r2 + 1; + if (isec == TRACKS_FROM_TRIPLETS_ITERATION) { Pick_r22 = Pick_r2 + 1; } #endif // DO_NOT_SELECT_TRIPLETS - const fscal iz = 1.f / (T2.z[i2_4] - fParameters.GetTargetPositionZ()[0]); - L1HitAreaTime area(vGridTime[&star - fParameters.GetStations().begin()], T2.x[i2_4] * iz, T2.y[i2_4] * iz, - (sqrt(Pick_r22 * (T2.C00 + stam.XYInfo.C00)) + fMaxDZ * fabs(T2.tx))[i2_4] * iz, - (sqrt(Pick_r22 * (T2.C11 + stam.XYInfo.C11)) + fMaxDZ * fabs(T2.ty))[i2_4] * iz, time, - sqrt(timeError) * 5); + const fscal iz = 1.f / (T2.z[i2_4] - fParameters.GetTargetPositionZ()[0]); + L1HitAreaTime area(vGridTime[&star - fParameters.GetStations().begin()], T2.x[i2_4] * iz, T2.y[i2_4] * iz, + (sqrt(Pick_r22 * (T2.C00 + stam.XYInfo.C00)) + fMaxDZ * fabs(T2.tx))[i2_4] * iz, + (sqrt(Pick_r22 * (T2.C11 + stam.XYInfo.C11)) + fMaxDZ * fabs(T2.ty))[i2_4] * iz, time, + sqrt(timeError) * 5); + + L1HitIndex_t irh = 0; + L1HitIndex_t Ntriplets = 0; + int irh1 = -1; + while (true) { + if (fParameters.DevIsIgnoreHitSearchAreas()) { + irh1++; + if ((L1HitIndex_t) irh1 >= (HitsUnusedStopIndex[istar] - HitsUnusedStartIndex[istar])) break; + irh = irh1; + } + else { + if (!area.GetNext(irh)) break; + } - L1HitIndex_t irh = 0; - L1HitIndex_t Ntriplets = 0; - int irh1 = -1; - while (true) { - if (fParameters.DevIsIgnoreHitSearchAreas()) { - irh1++; - if ((L1HitIndex_t) irh1 >= (HitsUnusedStopIndex[istar] - HitsUnusedStartIndex[istar])) break; - irh = irh1; - } - else { - if (!area.GetNext(irh)) break; - } + // while (area.GetNext(irh)) { + //for (int irh = 0; irh < ( HitsUnusedStopIndex[istar] - HitsUnusedStartIndex[istar] ); irh++){ + const L1HitPoint& hitr = vHits_r[irh]; - // while (area.GetNext(irh)) { - //for (int irh = 0; irh < ( HitsUnusedStopIndex[istar] - HitsUnusedStartIndex[istar] ); irh++){ - const L1HitPoint& hitr = vHits_r[irh]; + if (fParameters.DevIsMatchTripletsViaMc()) { + int indM = HitsUnusedStartIndex[iStaM] + hitsm_2_tmp[i2_4]; + int indR = HitsUnusedStartIndex[iStaR] + irh; + if (GetMcTrackIdForUnusedHit(indM) != GetMcTrackIdForUnusedHit(indR)) { continue; } + } #ifdef USE_EVENT_NUMBER // NOTE: - if ((T2.n[i2_4] != hitr.n)) continue; + if ((T2.n[i2_4] != hitr.n)) continue; #endif // USE_EVENT_NUMBER - const fscal zr = hitr.Z(); - // const fscal yr = hitr.Y(); + const fscal zr = hitr.Z(); + // const fscal yr = hitr.Y(); - fvec xr, yr = 0; + fvec xr, yr = 0; - StripsToCoor(hitr.U(), hitr.V(), xr, yr, star); + StripsToCoor(hitr.U(), hitr.V(), xr, yr, star); - L1TrackPar T_cur = T2; + L1TrackPar T_cur = T2; + fvec dz3 = zr - T_cur.z; + L1ExtrapolateTime(T_cur, dz3, star.timeInfo); - fvec dz3 = zr - T_cur.z; - L1ExtrapolateTime(T_cur, dz3, star.timeInfo); + L1ExtrapolateLine(T_cur, zr); - L1ExtrapolateLine(T_cur, zr); + if ((star.timeInfo) && (stam.timeInfo)) + if (fabs(T_cur.t[i2_4] - hitr.time) > sqrt(T_cur.C55[i2_4] + hitr.timeEr) * 5) continue; - if ((star.timeInfo) && (stam.timeInfo)) - if (fabs(T_cur.t[i2_4] - hitr.time) > sqrt(T_cur.C55[i2_4] + hitr.timeEr) * 5) continue; + // TODO: SG: hardcoded cut of 30 ns + if ((star.timeInfo) && (stam.timeInfo)) + if (fabs(T_cur.t[i2_4] - hitr.time) > 30) continue; - if ((star.timeInfo) && (stam.timeInfo)) - if (fabs(T_cur.t[i2_4] - hitr.time) > 30) continue; + // - check whether hit belong to the window ( track position +\- errors ) - + // check lower boundary + fvec y, C11; + L1ExtrapolateYC11Line(T2, zr, y, C11); + // cout << "sta " << iStaR << " dy = " << sqrt(C11) << endl; + fscal dy_est2 = + (Pick_r22[i2_4] + * (fabs( + C11[i2_4] + + star.XYInfo.C11[i2_4]))); // TODO for FastPrim dx < dy - other sort is optimal. But not for doublets - // - check whether hit belong to the window ( track position +\- errors ) - - // check lower boundary - fvec y, C11; - L1ExtrapolateYC11Line(T2, zr, y, C11); - fscal dy_est2 = - (Pick_r22[i2_4] - * (fabs( - C11[i2_4] - + star.XYInfo.C11[i2_4]))); // TODO for FastPrim dx < dy - other sort is optimal. But not for doublets + if (fUseHitErrors) { + fvec dyr = 0; + dUdV_to_dY(hitr.dU(), hitr.dV(), dyr, star); + dy_est2 = (Pick_r22[i2_4] * (fabs(C11[i2_4] + dyr[0] * dyr[0]))); + } - if (fUseHitErrors) { - fvec dyr = 0; - dUdV_to_dY(hitr.dU(), hitr.dV(), dyr, star); - dy_est2 = (Pick_r22[i2_4] * (fabs(C11[i2_4] + dyr[0] * dyr[0]))); - } + const fscal dY = yr[i2_4] - y[i2_4]; + const fscal dY2 = dY * dY; - const fscal dY = yr[i2_4] - y[i2_4]; - const fscal dY2 = dY * dY; - if (dY2 > dy_est2 && dY2 < 0) continue; // if (yr < y_minus_new[i2_4]) continue; - // check upper boundary - if (dY2 > dy_est2) continue; // if (yr > y_plus_new [i2_4] ) continue; - // check x-boundaries - fvec x, C00; + if (dY2 > dy_est2) continue; // if (yr > y_plus_new [i2_4] ) continue; + // check x-boundaries + fvec x, C00; - L1ExtrapolateXC00Line(T2, zr, x, C00); + L1ExtrapolateXC00Line(T2, zr, x, C00); + // cout << "sta " << iStaR << " dx = " << sqrt(C00) << endl; - fscal dx_est2 = (Pick_r22[i2_4] * (fabs(C00[i2_4] + star.XYInfo.C00[i2_4]))); + fscal dx_est2 = (Pick_r22[i2_4] * (fabs(C00[i2_4] + star.XYInfo.C00[i2_4]))); - if (fUseHitErrors) { - fvec dxr = 0; - dUdV_to_dX(hitr.dU(), hitr.dV(), dxr, star); - dx_est2 = (Pick_r22[i2_4] * (fabs(C00[i2_4] + dxr[0] * dxr[0]))); - } + if (fUseHitErrors) { + fvec dxr = 0; + dUdV_to_dX(hitr.dU(), hitr.dV(), dxr, star); + dx_est2 = (Pick_r22[i2_4] * (fabs(C00[i2_4] + dxr[0] * dxr[0]))); + } - const fscal dX = xr[i2_4] - x[i2_4]; - if (dX * dX > dx_est2) continue; - // check chi2 // not effective - fvec C10; - L1ExtrapolateC10Line(T2, zr, C10); - fvec chi2 = T2.chi2; + const fscal dX = xr[i2_4] - x[i2_4]; + if (dX * dX > dx_est2) continue; + // check chi2 // not effective + fvec C10; + L1ExtrapolateC10Line(T2, zr, C10); + fvec chi2 = T2.chi2; - info = star.frontInfo; + info = star.frontInfo; - if (fUseHitErrors) info.sigma2 = hitr.dU() * hitr.dU(); + if (fUseHitErrors) info.sigma2 = hitr.dU() * hitr.dU(); - L1FilterChi2XYC00C10C11(info, x, y, C00, C10, C11, chi2, hitr.U()); - info = star.backInfo; + L1FilterChi2XYC00C10C11(info, x, y, C00, C10, C11, chi2, hitr.U()); + info = star.backInfo; - if (fUseHitErrors) info.sigma2 = hitr.dV() * hitr.dV(); + if (fUseHitErrors) info.sigma2 = hitr.dV() * hitr.dV(); - L1FilterChi2(info, x, y, C00, C10, C11, chi2, hitr.V()); + L1FilterChi2(info, x, y, C00, C10, C11, chi2, hitr.V()); - FilterTime(T_cur, hitr.time, hitr.timeEr, star.timeInfo); + FilterTime(T_cur, hitr.time, hitr.timeEr, star.timeInfo); #ifdef DO_NOT_SELECT_TRIPLETS - if (isec != TRACKS_FROM_TRIPLETS_ITERATION) + if (isec != TRACKS_FROM_TRIPLETS_ITERATION) #endif // DO_NOT_SELECT_TRIPLETS - if (chi2[i2_4] > fTripletChi2Cut || C00[i2_4] < 0 || C11[i2_4] < 0 || T_cur.C55[i2_4] < 0) - continue; // chi2_triplet < CHI2_CUT - - // pack triplet - L1TrackPar& T3 = T_3[n3_V]; - - hitsl_3.push_back(hitsl_2[i2_4]); - hitsm_3.push_back(hitsm_2_tmp[i2_4]); - hitsr_3.push_back(irh); - - - T3.SetOneEntry(n3_4, T2, i2_4); - u_front_3[n3_V][n3_4] = hitr.U(); - u_back_3[n3_V][n3_4] = hitr.V(); - //dx_[n3_V][n3_4] = hitr.dX(); - // dy_[n3_V][n3_4] = hitr.dY(); - du_[n3_V][n3_4] = hitr.dU(); - dv_[n3_V][n3_4] = hitr.dV(); - z_Pos_3[n3_V][n3_4] = zr; - timeR[n3_V][n3_4] = hitr.time; - timeER[n3_V][n3_4] = hitr.timeEr; - - n3++; - Ntriplets++; - - n3_V = n3 / fvecLen; - n3_4 = n3 % fvecLen; - - if (!n3_4) { - T_3.push_back(L1TrackPar_0); - u_front_3.push_back(fvec_0); - u_back_3.push_back(fvec_0); - z_Pos_3.push_back(fvec_0); - // dx_.push_back(fvec_0); - // dy_.push_back(fvec_0); - du_.push_back(fvec_0); - dv_.push_back(fvec_0); - timeR.push_back(fvec_0); - timeER.push_back(fvec_0); + if (chi2[i2_4] > fTripletChi2Cut || C00[i2_4] < 0 || C11[i2_4] < 0 || T_cur.C55[i2_4] < 0) { + continue; // chi2_triplet < CHI2_CUT } + //if (!T_cur.IsEntryConsistent(false, i2_4)) { continue; } + + // pack triplet + L1TrackPar& T3 = T_3[n3_V]; + + hitsl_3.push_back(hitsl_2[i2_4]); + hitsm_3.push_back(hitsm_2_tmp[i2_4]); + hitsr_3.push_back(irh); + + T3.SetOneEntry(n3_4, T2, i2_4); + u_front_3[n3_V][n3_4] = hitr.U(); + u_back_3[n3_V][n3_4] = hitr.V(); + du_[n3_V][n3_4] = hitr.dU(); + dv_[n3_V][n3_4] = hitr.dV(); + z_Pos_3[n3_V][n3_4] = zr; + timeR[n3_V][n3_4] = hitr.time; + timeER[n3_V][n3_4] = hitr.timeEr; + + n3++; + Ntriplets++; + + n3_V = n3 / fvecLen; + n3_4 = n3 % fvecLen; + + if (!n3_4) { + T_3.push_back(L1TrackPar_0); + u_front_3.push_back(fvec_0); + u_back_3.push_back(fvec_0); + z_Pos_3.push_back(fvec_0); + // TODO: SG: use of fvec_1 here changes the results + du_.push_back(fvec_0); + dv_.push_back(fvec_0); + timeR.push_back(fvec_0); + timeER.push_back(fvec_0); + } + #ifndef FAST_CODE //TODO: optimise triplet portion limit and put a warning // assert(Ntriplets < fParameters.GetMaxTripletPerDoublets()); #endif // FAST_CODE - if (Ntriplets >= fParameters.GetMaxTripletPerDoublets()) { - - n3 = n3 - Ntriplets; - - T_3.resize(n3 / fvecLen); - u_front_3.resize(n3 / fvecLen); - u_back_3.resize(n3 / fvecLen); - z_Pos_3.resize(n3 / fvecLen); - du_.resize(n3 / fvecLen); - dv_.resize(n3 / fvecLen); - timeR.resize(n3 / fvecLen); - timeER.resize(n3 / fvecLen); - - break; - } + if (Ntriplets >= fParameters.GetMaxTripletPerDoublets()) { + + n3 = n3 - Ntriplets; + + T_3.resize(n3 / fvecLen); + u_front_3.resize(n3 / fvecLen); + u_back_3.resize(n3 / fvecLen); + z_Pos_3.resize(n3 / fvecLen); + du_.resize(n3 / fvecLen); + dv_.resize(n3 / fvecLen); + timeR.resize(n3 / fvecLen); + timeER.resize(n3 / fvecLen); + cout << "SG:: GetMaxTripletPerDoublets==" << fParameters.GetMaxTripletPerDoublets() << " reached" << endl; + //assert(0); + break; } + } - - } // i2_4 - } // i2_V - } // if istar + } // i2_4 + } // i2_V } /// Add the right hits to parameters estimation. @@ -871,13 +968,20 @@ inline void L1Algo::findTripletsStep1( // input // L1TrackPar *T_3 nsL1::vector<L1TrackPar>::TSimd& T_3) { + for (Tindex i3_V = 0; i3_V < n3_V; ++i3_V) { fvec dz = z_Pos[i3_V] - T_3[i3_V].z; - L1ExtrapolateTime(T_3[i3_V], dz, star.timeInfo); - L1ExtrapolateLine(T_3[i3_V], z_Pos[i3_V]); + L1TrackPar& T3 = T_3[i3_V]; + + // assert(T3.IsConsistent(true, -1)); + + L1ExtrapolateTime(T3, dz, star.timeInfo); + L1ExtrapolateLine(T3, z_Pos[i3_V]); + + // assert(T3.IsConsistent(true, -1)); L1UMeasurementInfo info = star.frontInfo; @@ -885,24 +989,29 @@ inline void L1Algo::findTripletsStep1( // input bool noField = (&star - fParameters.GetStations().begin() >= fNfieldStations); - if (noField) { L1FilterNoField(T_3[i3_V], info, u_front_[i3_V]); } + if (noField) { L1FilterNoField(T3, info, u_front_[i3_V]); } else { - L1Filter(T_3[i3_V], info, u_front_[i3_V]); + L1Filter(T3, info, u_front_[i3_V]); } + // assert(T3.IsConsistent(true, -1)); + info = star.backInfo; if (fUseHitErrors) info.sigma2 = dv_[i3_V] * dv_[i3_V]; - if (noField) { L1FilterNoField(T_3[i3_V], info, u_back_[i3_V]); } + if (noField) { L1FilterNoField(T3, info, u_back_[i3_V]); } else { - L1Filter(T_3[i3_V], info, u_back_[i3_V]); + L1Filter(T3, info, u_back_[i3_V]); } + // assert(T3.IsConsistent(true, -1)); + if (kGlobal != fTrackingMode && kMcbm != fTrackingMode) { - FilterTime(T_3[i3_V], timeR[i3_V], timeER[i3_V], star.timeInfo); + FilterTime(T3, timeR[i3_V], timeER[i3_V], star.timeInfo); } + // assert(T3.IsConsistent(true, -1)); // FilterTime(T_3[i3_V], timeR[i3_V], timeER[i3_V]); } } @@ -918,6 +1027,8 @@ inline void L1Algo::findTripletsStep2( // input // TODO not updated after gaps const int NHits = 3; // triplets + // TODO: SG: middle and right station numbers might be different for different triplets!!! + // prepare data int ista[NHits] = {istal, istal + 1, istal + 2}; @@ -931,13 +1042,23 @@ inline void L1Algo::findTripletsStep2( // input // TODO not updated after gaps int i3_4 = i3 % fvecLen; L1TrackPar& T3 = T_3[i3_V]; - fscal& qp0 = T3.qp[i3_4]; + + //if (!T3.IsEntryConsistent(false, i3_4)) continue; + + fscal& qp0 = T3.qp[i3_4]; // prepare data L1HitIndex_t ihit[NHits] = {(*RealIHitP)[hitsl_3[i3] + HitsUnusedStartIndex[ista[0]]], (*RealIHitP)[hitsm_3[i3] + HitsUnusedStartIndex[ista[1]]], (*RealIHitP)[hitsr_3[i3] + HitsUnusedStartIndex[ista[2]]]}; + if (fParameters.DevIsMatchTripletsViaMc()) { + int mc1 = GetMcTrackIdForUnusedHit(ihit[0]); + int mc2 = GetMcTrackIdForUnusedHit(ihit[1]); + int mc3 = GetMcTrackIdForUnusedHit(ihit[2]); + if ((mc1 != mc2) || (mc1 != mc3)) { continue; } + } + fscal u[NHits], v[NHits], x[NHits], y[NHits], z[NHits]; for (int ih = 0; ih < NHits; ++ih) { const L1Hit& hit = (*vHits)[ihit[ih]]; @@ -1079,14 +1200,29 @@ inline void L1Algo::findTripletsStep3( // input // output Tindex& nstaltriplets) { + /// Selects good triplets and saves them into fTriplets. + /// Finds neighbouring triplets at the next station. + /// + /// \param n3 Number of triplets to process + /// \param istal index of the left station + /// \param istam index of the middle station + /// \param istar index of the right station + /// \param T_3 fitted trajectories of triplets + /// \param hitsl_3 index of the left triplet hit in unused hits on the left station + /// \param hitsm_3 index of the middle triplet hit in unused hits on the middle station + /// \param hitsr_3 index of the right triplet hit in unused hits on the right station + /// + /// Output: + /// + /// \param nstaltriplets updated number of triplets in fTriplets[istal][Thread] - /// Select good triplets and save them into fTriplets. Find neighbouring triplets at the next station. + // TODO: SG: remove nstaltriplets parameter #ifdef _OPENMP unsigned int Thread = omp_get_thread_num(); -#else // not _OPENMP +#else unsigned int Thread = 0; -#endif // _OPENMP +#endif L1HitIndex_t ihitl_priv = 0; @@ -1096,6 +1232,8 @@ inline void L1Algo::findTripletsStep3( // input L1TrackPar& T3 = T_3[i3_V]; + //if (!T3.IsEntryConsistent(false, i3_4)) continue; + // select fscal& chi2 = T3.chi2[i3_4]; @@ -1118,7 +1256,11 @@ inline void L1Algo::findTripletsStep3( // input #ifdef DO_NOT_SELECT_TRIPLETS if (isec != TRACKS_FROM_TRIPLETS_ITERATION) #endif // DO_NOT_SELECT_TRIPLETS - if (!finite(chi2) || chi2 < 0 || chi2 > fTripletChi2Cut) continue; + + // assert(finite(chi2) && chi2 > 0); + + if (!finite(chi2) || chi2 < 0) { continue; } + if (chi2 > fTripletChi2Cut) { continue; } fscal qp = T3.qp[i3_4]; @@ -1162,6 +1304,7 @@ inline void L1Algo::findTripletsStep3( // input unsigned int neighTriplet = TripletId2Triplet(neighLocation); if (nNeighbours > 0) { assert((int) neighStation == istal + 1 || (int) neighStation == istal + 2); } + unsigned char level = 0; for (unsigned int iN = 0; iN < nNeighbours; ++iN, ++neighTriplet, ++neighLocation) { @@ -1506,7 +1649,7 @@ inline void L1Algo::TripletsStaPort( /// creates triplets: #else fL1Eff_triplets->AddOne(iHits); #endif - if (T_3[i_V].chi2[i_4] < fTripletChi2Cut) fL1Eff_triplets2->AddOne(iHits); + if (T_3[i_V].chi2[i_4] < fTripletChi2Cut) { fL1Eff_triplets2->AddOne(iHits); } } #endif // TRIP_PERFORMANCE @@ -1515,9 +1658,7 @@ inline void L1Algo::TripletsStaPort( /// creates triplets: findTripletsStep3( // input n3, istal, istam, istar, T_3, hitsl_3, hitsm_3, hitsr_3, // output - nstaltriplets - - ); + nstaltriplets); } } @@ -1796,6 +1937,7 @@ void L1Algo::CATrackFinder() // --- SET PARAMETERS FOR THE ITERATION --- fFirstCAstation = caIteration.GetFirstStationIndex(); + fTrackChi2Cut = caIteration.GetTrackChi2Cut(); fDoubletChi2Cut = caIteration.GetDoubletChi2Cut(); //11.3449 * 2.f / 3.f; // prob = 0.1 fTripletChi2Cut = caIteration.GetTripletChi2Cut(); //21.1075; // prob = 0.01% fPickGather = caIteration.GetPickGather(); //3.0; @@ -1937,7 +2079,7 @@ void L1Algo::CATrackFinder() i1G_2) //schedule(dynamic, 2) #endif for (Tindex ip = fDupletPortionStopIndex[istal + 1]; ip < fDupletPortionStopIndex[istal]; ++ip) { - Tindex n_2; /// number of doublets in portion + Tindex n_2 = 0; /// number of doublets in portion int NHitsSta = HitsStopIndex[istal] - HitsStartIndex[istal]; lmDuplets[istal].reset(NHitsSta); lmDupletsG[istal].reset(NHitsSta); @@ -1945,7 +2087,6 @@ void L1Algo::CATrackFinder() hitsm_2.clear(); i1_2.clear(); - DupletsStaPort(istal, istal + 1, ip, fDupletPortionSize, fDupletPortionStopIndex, // output @@ -1971,7 +2112,6 @@ void L1Algo::CATrackFinder() Tindex nG_2; hitsmG_2.clear(); i1G_2.clear(); - if ((fMissingHits && ((istal == 0) || (istal == 1))) || !fMissingHits) DupletsStaPort( // input istal, istal + 2, ip, fDupletPortionSize, fDupletPortionStopIndex, @@ -2291,84 +2431,63 @@ void L1Algo::CATrackFinder() #endif for (Tindex iCandidate = 0; iCandidate < (Tindex) fTrackCandidates[i].size(); ++iCandidate) { L1Branch& tr = fTrackCandidates[i][iCandidate]; - - bool check = 1; - - if (fTrackCandidates[i][iCandidate].fID != -1) { - for (L1Vector<L1HitIndex_t>::iterator phIt = tr.fHits.begin(); /// used strips are marked - phIt != tr.fHits.end(); ++phIt) { - const L1Hit& h = (((*vHits))[*phIt]); - if (((fStripToTrack)[h.b] != tr.fID) || ((fStripToTrack)[h.f] != tr.fID)) { - check = 0; - break; - } - } - - if (kMcbm == fTrackingMode) { - if (tr.NHits <= 3) { check = 0; } - } - else if (kGlobal == fTrackingMode) { - if (tr.NHits <= 3) { check = 0; } - } - else { - if (tr.NHits < 3) { check = 0; } - } - - if (check) { + if (!tr.fIsAlive) continue; + if (kMcbm == fTrackingMode) { + if (tr.NHits <= 3) { continue; } + } + else if (kGlobal == fTrackingMode) { + if (tr.NHits <= 3) { continue; } + } + else { + if (tr.NHits < 3) { continue; } + } #ifdef EXTEND_TRACKS - if (kGlobal != fTrackingMode && kMcbm != fTrackingMode) { - if (tr.NHits != fNstations) BranchExtender(tr); - } + if (kGlobal != fTrackingMode && kMcbm != fTrackingMode) { + if (tr.NHits != fNstations) BranchExtender(tr); + } #endif - float sumTime = 0; - + float sumTime = 0; #ifdef _OPENMP - - int num_thread = omp_get_thread_num(); - + int num_thread = omp_get_thread_num(); #else - - int num_thread = 0; - + int num_thread = 0; #endif + for (L1Vector<L1HitIndex_t>::iterator phIt = tr.fHits.begin(); /// used strips are marked + phIt != tr.fHits.end(); ++phIt) { + L1Hit& h = (*vHits)[*phIt]; - if (kGlobal == fTrackingMode) { //SGtrd2d!! - if (tr.fHits.size() < 4) continue; - } - for (L1Vector<L1HitIndex_t>::iterator phIt = tr.fHits.begin(); /// used strips are marked - phIt != tr.fHits.end(); ++phIt) { - L1Hit& h = (*vHits)[*phIt]; - + SetFUsed((*fStripFlag)[h.f]); + SetFUsed((*fStripFlag)[h.b]); - SetFUsed((*fStripFlag)[h.f]); - SetFUsed((*fStripFlag)[h.b]); + fRecoHits_local[num_thread].push_back(*phIt); + const L1Hit& hit = (*vHits)[*phIt]; + L1HitPoint tempPoint = CreateHitPoint(hit); //TODO take number of station from hit - fRecoHits_local[num_thread].push_back(*phIt); + float xcoor, ycoor = 0; + L1Station stah = fParameters.GetStation(0); // TODO: Why is it a copy? + StripsToCoor(tempPoint.U(), tempPoint.V(), xcoor, ycoor, stah); + float zcoor = tempPoint.Z() - fParameters.GetTargetPositionZ()[0]; - const L1Hit& hit = (*vHits)[*phIt]; - - - L1HitPoint tempPoint = CreateHitPoint(hit); //TODO take number of station from hit - - float xcoor, ycoor = 0; - L1Station stah = fParameters.GetStation(0); // TODO: Why is it a copy? - StripsToCoor(tempPoint.U(), tempPoint.V(), xcoor, ycoor, stah); - float zcoor = tempPoint.Z() - fParameters.GetTargetPositionZ()[0]; - - float timeFlight = sqrt(xcoor * xcoor + ycoor * ycoor + zcoor * zcoor) / 30.f; // c = 30[cm/ns] - sumTime += (hit.t - timeFlight); - } + float timeFlight = sqrt(xcoor * xcoor + ycoor * ycoor + zcoor * zcoor) / 30.f; // c = 30[cm/ns] + sumTime += (hit.t - timeFlight); + } - t.NHits = tr.NHits; - // t.Momentum = tr.Momentum; - t.fTrackTime = sumTime / t.NHits; - fTracks_local[num_thread].push_back(t); + t.NHits = tr.NHits; + // t.Momentum = tr.Momentum; + t.fTrackTime = sumTime / t.NHits; + fTracks_local[num_thread].push_back(t); + if (0) { // SG debug + cout << "store track " << iCandidate << " chi2= " << tr.chi2 << endl; + cout << " hits: "; + for (unsigned int ih = 0; ih < tr.fHits.size(); ih++) { + cout << GetMcTrackIdForHit(tr.fHits[ih]) << " "; } + cout << endl; } - } - } + } // tracks + } // threads #ifdef XXX Time.Stop(); @@ -2405,7 +2524,7 @@ void L1Algo::CATrackFinder() fRecoHits[offset_hits[i] + iH] = fRecoHits_local[i][iH]; } } - } //istaf + } // firstTripletLevel #ifdef XXX c_timer.Stop(); @@ -2624,8 +2743,11 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best } //if( curr_L < min_best_l - 1 ) return; // suppouse that only one hit can be added by extender - if (curr_chi2 > fTrackChi2Cut * (curr_L * 2 - 5.0)) return; + int ndf = curr_L * 2 - 5; + if (kGlobal == fTrackingMode || kMcbm == fTrackingMode) { ndf = curr_L * 2 - 4; } + + if (curr_chi2 > fTrackChi2Cut * ndf) return; // // try to find more hits // #ifdef EXTEND_TRACKS @@ -2692,14 +2814,19 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best fscal Cty = curr_trip->GetCty(); Cty += new_trip.GetCty(); + assert(std::isfinite(dtx)); + assert(std::isfinite(dty)); + assert(std::isfinite(Ctx)); + assert(std::isfinite(Cty)); + if (kMcbm == fTrackingMode) { if (dty > 3 * Cty) continue; if (dtx > 3 * Ctx) continue; } if (kGlobal == fTrackingMode) { - if (dty > 6 * sqrt(Cty)) continue; //SGtrd2d - if (dtx > 7 * sqrt(Ctx)) continue; + if (dty > fPickNeighbour * sqrt(Cty)) continue; //SGtrd2d + if (dtx > fPickNeighbour * sqrt(Ctx)) continue; } if (GetFUsed((*fStripFlag)[(*vHitsUnused)[new_trip.GetLHit()].f] @@ -2712,18 +2839,11 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best best_L = curr_L; } } - else { // if hits are used add new triplet to the current track + else { // hit is not used: add the left hit from the new triplet to the current track - new_tr[ista] = curr_tr; - - unsigned char new_L = curr_L; + unsigned char new_L = curr_L + 1; fscal new_chi2 = curr_chi2; - // add new hit - new_tr[ista].fHits.push_back((*RealIHitP)[new_trip.GetLHit()]); - new_tr[ista].NHits++; - new_L += 1; - dqp = dqp / Cqp; if (kGlobal == fTrackingMode) { //SGtrd2d!!! @@ -2735,6 +2855,9 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best dty = dty / Cty; // TODO: SG: it must be /sqrt(Cty); } + assert(std::isfinite(dtx)); + assert(std::isfinite(dty)); + if (kGlobal == fTrackingMode || kMcbm == fTrackingMode) { new_chi2 += dtx * dtx; new_chi2 += dty * dty; @@ -2743,12 +2866,35 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best new_chi2 += dqp * dqp; } + if (0) { //SGtrd2d debug!! + int mc01 = GetMcTrackIdForUnusedHit(curr_trip->GetLHit()); + int mc02 = GetMcTrackIdForUnusedHit(curr_trip->GetMHit()); + int mc03 = GetMcTrackIdForUnusedHit(curr_trip->GetRHit()); + int mc11 = GetMcTrackIdForUnusedHit(new_trip.GetLHit()); + int mc12 = GetMcTrackIdForUnusedHit(new_trip.GetMHit()); + int mc13 = GetMcTrackIdForUnusedHit(new_trip.GetRHit()); + if ((mc01 == mc02) && (mc02 == mc03)) { + cout << " sta " << ista << " mc0 " << mc01 << " " << mc02 << " " << mc03 << " mc1 " << mc11 << " " << mc12 + << " " << mc13 << " chi2 " << curr_chi2 / (2 * (curr_L + 2) - 4) << " new " + << new_chi2 / (2 * (new_L + 2) - 4) << endl; + cout << " hits " << curr_trip->GetLHit() << " " << curr_trip->GetMHit() << " " << curr_trip->GetRHit() + << " " << new_trip.GetLHit() << endl; + } + } + if (kGlobal == fTrackingMode) { //SGtrd2d!!! - if (new_chi2 > fTrackChi2Cut * 2 * new_L) continue; + // nHits in chi2 calculation == new_L+2, ndf == 4 + if (new_chi2 > fTrackChi2Cut * (2 * (new_L + 2) - 4)) continue; } else { if (new_chi2 > fTrackChi2Cut * new_L) continue; // TODO: SG: it must be ( 2 * new_L ) } + + // add new hit + new_tr[ista] = curr_tr; + new_tr[ista].fHits.push_back((*RealIHitP)[new_trip.GetLHit()]); + new_tr[ista].NHits++; + const int new_ista = ista + new_trip.GetMSta() - new_trip.GetLSta(); CAFindTrack(new_ista, best_tr, best_L, best_chi2, &new_trip, new_tr[ista], new_L, new_chi2, min_best_l, new_tr);