File indexing completed on 2025-07-13 08:04:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <algorithm>
0010 #include <cmath>
0011 #include <numeric>
0012 #include <type_traits>
0013
0014 namespace Acts {
0015
0016 template <typename external_spacepoint_t, typename grid_t, typename platform_t>
0017 SeedFinder<external_spacepoint_t, grid_t, platform_t>::SeedFinder(
0018 const Acts::SeedFinderConfig<external_spacepoint_t>& config)
0019 : m_config(config) {
0020 if (!config.isInInternalUnits) {
0021 throw std::runtime_error(
0022 "SeedFinderConfig not in ACTS internal units in SeedFinder");
0023 }
0024 if (std::isnan(config.deltaRMaxTopSP)) {
0025 throw std::runtime_error("Value of deltaRMaxTopSP was not initialised");
0026 }
0027 if (std::isnan(config.deltaRMinTopSP)) {
0028 throw std::runtime_error("Value of deltaRMinTopSP was not initialised");
0029 }
0030 if (std::isnan(config.deltaRMaxBottomSP)) {
0031 throw std::runtime_error("Value of deltaRMaxBottomSP was not initialised");
0032 }
0033 if (std::isnan(config.deltaRMinBottomSP)) {
0034 throw std::runtime_error("Value of deltaRMinBottomSP was not initialised");
0035 }
0036 }
0037
0038 template <typename external_spacepoint_t, typename grid_t, typename platform_t>
0039 template <typename container_t, typename sp_range_t>
0040 void SeedFinder<external_spacepoint_t, grid_t, platform_t>::createSeedsForGroup(
0041 const Acts::SeedFinderOptions& options, SeedingState& state,
0042 const grid_t& grid, container_t& outputCollection,
0043 const sp_range_t& bottomSPsIdx, const std::size_t middleSPsIdx,
0044 const sp_range_t& topSPsIdx,
0045 const Acts::Range1D<float>& rMiddleSPRange) const {
0046 if (!options.isInInternalUnits) {
0047 throw std::runtime_error(
0048 "SeedFinderOptions not in ACTS internal units in SeedFinder");
0049 }
0050
0051
0052 const std::size_t max_num_seeds_per_spm =
0053 m_config.seedFilter->getSeedFilterConfig().maxSeedsPerSpMConf;
0054 const std::size_t max_num_quality_seeds_per_spm =
0055 m_config.seedFilter->getSeedFilterConfig().maxQualitySeedsPerSpMConf;
0056
0057 state.candidates_collector.setMaxElements(max_num_seeds_per_spm,
0058 max_num_quality_seeds_per_spm);
0059
0060
0061 if (bottomSPsIdx.size() == 0 || topSPsIdx.size() == 0) {
0062 return;
0063 }
0064
0065
0066 const auto& middleSPs = grid.at(middleSPsIdx);
0067
0068 if (middleSPs.size() == 0) {
0069 return;
0070 }
0071
0072
0073
0074 state.bottomNeighbours.clear();
0075 state.topNeighbours.clear();
0076
0077
0078
0079 for (const std::size_t idx : bottomSPsIdx) {
0080
0081 if (grid.at(idx).size() == 0) {
0082 continue;
0083 }
0084 state.bottomNeighbours.emplace_back(
0085 grid, idx, middleSPs.front()->radius() - m_config.deltaRMaxBottomSP);
0086 }
0087
0088 if (state.bottomNeighbours.size() == 0) {
0089 return;
0090 }
0091
0092
0093 for (const std::size_t idx : topSPsIdx) {
0094
0095 if (grid.at(idx).size() == 0) {
0096 continue;
0097 }
0098 state.topNeighbours.emplace_back(
0099 grid, idx, middleSPs.front()->radius() + m_config.deltaRMinTopSP);
0100 }
0101
0102 if (state.topNeighbours.size() == 0) {
0103 return;
0104 }
0105
0106 for (const auto& spM : middleSPs) {
0107 float rM = spM->radius();
0108
0109
0110 if (m_config.useVariableMiddleSPRange) {
0111 if (rM < rMiddleSPRange.min()) {
0112 continue;
0113 }
0114 if (rM > rMiddleSPRange.max()) {
0115
0116 break;
0117 }
0118 } else if (!m_config.rRangeMiddleSP.empty()) {
0119
0120 auto pVal = std::lower_bound(m_config.zBinEdges.begin(),
0121 m_config.zBinEdges.end(), spM->z());
0122 int zBin = std::distance(m_config.zBinEdges.begin(), pVal);
0123
0124 zBin == 0 ? zBin : --zBin;
0125 if (rM < m_config.rRangeMiddleSP[zBin][0]) {
0126 continue;
0127 }
0128 if (rM > m_config.rRangeMiddleSP[zBin][1]) {
0129
0130 break;
0131 }
0132 } else {
0133 if (rM < m_config.rMinMiddle) {
0134 continue;
0135 }
0136 if (rM > m_config.rMaxMiddle) {
0137
0138 break;
0139 }
0140 }
0141
0142 const float zM = spM->z();
0143 const float uIP = -1. / rM;
0144 const float cosPhiM = -spM->x() * uIP;
0145 const float sinPhiM = -spM->y() * uIP;
0146 const float uIP2 = uIP * uIP;
0147
0148
0149 getCompatibleDoublets<Acts::SpacePointCandidateType::eTop>(
0150 state.spacePointData, options, grid, state.topNeighbours, *spM.get(),
0151 state.linCircleTop, state.compatTopSP, m_config.deltaRMinTopSP,
0152 m_config.deltaRMaxTopSP, uIP, uIP2, cosPhiM, sinPhiM);
0153
0154
0155 if (state.compatTopSP.empty()) {
0156 continue;
0157 }
0158
0159
0160 SeedFilterState seedFilterState;
0161 if (m_config.seedConfirmation) {
0162
0163 SeedConfirmationRangeConfig seedConfRange =
0164 (zM > m_config.centralSeedConfirmationRange.zMaxSeedConf ||
0165 zM < m_config.centralSeedConfirmationRange.zMinSeedConf)
0166 ? m_config.forwardSeedConfirmationRange
0167 : m_config.centralSeedConfirmationRange;
0168
0169
0170 seedFilterState.nTopSeedConf = rM > seedConfRange.rMaxSeedConf
0171 ? seedConfRange.nTopForLargeR
0172 : seedConfRange.nTopForSmallR;
0173
0174 seedFilterState.rMaxSeedConf = seedConfRange.rMaxSeedConf;
0175
0176 if (state.compatTopSP.size() < seedFilterState.nTopSeedConf) {
0177 continue;
0178 }
0179 }
0180
0181
0182 getCompatibleDoublets<Acts::SpacePointCandidateType::eBottom>(
0183 state.spacePointData, options, grid, state.bottomNeighbours, *spM.get(),
0184 state.linCircleBottom, state.compatBottomSP, m_config.deltaRMinBottomSP,
0185 m_config.deltaRMaxBottomSP, uIP, uIP2, cosPhiM, sinPhiM);
0186
0187
0188 if (state.compatBottomSP.empty()) {
0189 continue;
0190 }
0191
0192
0193 if (m_config.useDetailedDoubleMeasurementInfo) {
0194 filterCandidates<Acts::DetectorMeasurementInfo::eDetailed>(
0195 state.spacePointData, *spM.get(), options, seedFilterState, state);
0196 } else {
0197 filterCandidates<Acts::DetectorMeasurementInfo::eDefault>(
0198 state.spacePointData, *spM.get(), options, seedFilterState, state);
0199 }
0200
0201 m_config.seedFilter->filterSeeds_1SpFixed(
0202 state.spacePointData, state.candidates_collector, outputCollection);
0203
0204 }
0205 }
0206
0207 template <typename external_spacepoint_t, typename grid_t, typename platform_t>
0208 template <Acts::SpacePointCandidateType candidateType, typename out_range_t>
0209 inline void
0210 SeedFinder<external_spacepoint_t, grid_t, platform_t>::getCompatibleDoublets(
0211 Acts::SpacePointData& spacePointData,
0212 const Acts::SeedFinderOptions& options, const grid_t& grid,
0213 boost::container::small_vector<Acts::Neighbour<grid_t>,
0214 Acts::detail::ipow(3, grid_t::DIM)>&
0215 otherSPsNeighbours,
0216 const InternalSpacePoint<external_spacepoint_t>& mediumSP,
0217 std::vector<LinCircle>& linCircleVec, out_range_t& outVec,
0218 const float deltaRMinSP, const float deltaRMaxSP, const float uIP,
0219 const float uIP2, const float cosPhiM, const float sinPhiM) const {
0220 float impactMax = m_config.impactMax;
0221
0222 constexpr bool isBottomCandidate =
0223 candidateType == Acts::SpacePointCandidateType::eBottom;
0224
0225 if constexpr (isBottomCandidate) {
0226 impactMax = -impactMax;
0227 }
0228
0229 outVec.clear();
0230 linCircleVec.clear();
0231
0232
0233 std::size_t nsp = 0;
0234 for (const auto& otherSPCol : otherSPsNeighbours) {
0235 nsp += grid.at(otherSPCol.index).size();
0236 }
0237
0238 linCircleVec.reserve(nsp);
0239 outVec.reserve(nsp);
0240
0241 const float rM = mediumSP.radius();
0242 const float xM = mediumSP.x();
0243 const float yM = mediumSP.y();
0244 const float zM = mediumSP.z();
0245 const float varianceRM = mediumSP.varianceR();
0246 const float varianceZM = mediumSP.varianceZ();
0247
0248 float vIPAbs = 0;
0249 if (m_config.interactionPointCut) {
0250
0251 vIPAbs = impactMax * uIP2;
0252 }
0253
0254 float deltaR = 0.;
0255 float deltaZ = 0.;
0256
0257 for (auto& otherSPCol : otherSPsNeighbours) {
0258 const auto& otherSPs = grid.at(otherSPCol.index);
0259 if (otherSPs.size() == 0) {
0260 continue;
0261 }
0262
0263
0264
0265 auto min_itr = otherSPCol.itr;
0266
0267
0268
0269 for (; min_itr != otherSPs.end(); ++min_itr) {
0270 const auto& otherSP = *min_itr;
0271 if constexpr (isBottomCandidate) {
0272
0273 if ((rM - otherSP->radius()) <= deltaRMaxSP) {
0274 break;
0275 }
0276 } else {
0277
0278 if ((otherSP->radius() - rM) >= deltaRMinSP) {
0279 break;
0280 }
0281 }
0282 }
0283
0284
0285
0286 otherSPCol.itr = min_itr;
0287
0288 for (; min_itr != otherSPs.end(); ++min_itr) {
0289 const auto& otherSP = *min_itr;
0290
0291 if constexpr (isBottomCandidate) {
0292 deltaR = (rM - otherSP->radius());
0293
0294
0295 if (deltaR < deltaRMinSP) {
0296 break;
0297 }
0298 } else {
0299 deltaR = (otherSP->radius() - rM);
0300
0301
0302 if (deltaR > deltaRMaxSP) {
0303 break;
0304 }
0305 }
0306
0307 if constexpr (isBottomCandidate) {
0308 deltaZ = (zM - otherSP->z());
0309 } else {
0310 deltaZ = (otherSP->z() - zM);
0311 }
0312
0313
0314
0315
0316
0317 const float zOriginTimesDeltaR = (zM * deltaR - rM * deltaZ);
0318
0319 if (zOriginTimesDeltaR < m_config.collisionRegionMin * deltaR ||
0320 zOriginTimesDeltaR > m_config.collisionRegionMax * deltaR) {
0321 continue;
0322 }
0323
0324
0325
0326
0327
0328 if (!m_config.interactionPointCut) {
0329
0330
0331
0332 if (deltaZ > m_config.cotThetaMax * deltaR ||
0333 deltaZ < -m_config.cotThetaMax * deltaR) {
0334 continue;
0335 }
0336
0337 if (deltaZ > m_config.deltaZMax || deltaZ < -m_config.deltaZMax) {
0338 continue;
0339 }
0340
0341
0342 const float deltaX = otherSP->x() - xM;
0343 const float deltaY = otherSP->y() - yM;
0344
0345 const float xNewFrame = deltaX * cosPhiM + deltaY * sinPhiM;
0346 const float yNewFrame = deltaY * cosPhiM - deltaX * sinPhiM;
0347
0348 const float deltaR2 = (deltaX * deltaX + deltaY * deltaY);
0349 const float iDeltaR2 = 1. / deltaR2;
0350
0351 const float uT = xNewFrame * iDeltaR2;
0352 const float vT = yNewFrame * iDeltaR2;
0353
0354 const float iDeltaR = std::sqrt(iDeltaR2);
0355 const float cotTheta = deltaZ * iDeltaR;
0356
0357 const float Er =
0358 ((varianceZM + otherSP->varianceZ()) +
0359 (cotTheta * cotTheta) * (varianceRM + otherSP->varianceR())) *
0360 iDeltaR2;
0361
0362
0363 linCircleVec.emplace_back(cotTheta, iDeltaR, Er, uT, vT, xNewFrame,
0364 yNewFrame);
0365 spacePointData.setDeltaR(otherSP->index(),
0366 std::sqrt(deltaR2 + (deltaZ * deltaZ)));
0367 outVec.push_back(otherSP.get());
0368 continue;
0369 }
0370
0371
0372 const float deltaX = otherSP->x() - xM;
0373 const float deltaY = otherSP->y() - yM;
0374
0375 const float xNewFrame = deltaX * cosPhiM + deltaY * sinPhiM;
0376 const float yNewFrame = deltaY * cosPhiM - deltaX * sinPhiM;
0377
0378 const float deltaR2 = (deltaX * deltaX + deltaY * deltaY);
0379 const float iDeltaR2 = 1. / deltaR2;
0380
0381 const float uT = xNewFrame * iDeltaR2;
0382 const float vT = yNewFrame * iDeltaR2;
0383
0384
0385
0386 if (std::abs(rM * yNewFrame) <= impactMax * xNewFrame) {
0387
0388
0389
0390 if (deltaZ > m_config.cotThetaMax * deltaR ||
0391 deltaZ < -m_config.cotThetaMax * deltaR) {
0392 continue;
0393 }
0394
0395 const float iDeltaR = std::sqrt(iDeltaR2);
0396 const float cotTheta = deltaZ * iDeltaR;
0397
0398
0399
0400 if constexpr (isBottomCandidate) {
0401 if (!m_config.experimentCuts(otherSP->radius(), cotTheta)) {
0402 continue;
0403 }
0404 }
0405
0406 const float Er =
0407 ((varianceZM + otherSP->varianceZ()) +
0408 (cotTheta * cotTheta) * (varianceRM + otherSP->varianceR())) *
0409 iDeltaR2;
0410
0411
0412 linCircleVec.emplace_back(cotTheta, iDeltaR, Er, uT, vT, xNewFrame,
0413 yNewFrame);
0414 spacePointData.setDeltaR(otherSP->index(),
0415 std::sqrt(deltaR2 + (deltaZ * deltaZ)));
0416 outVec.emplace_back(otherSP.get());
0417 continue;
0418 }
0419
0420
0421
0422 const float vIP = (yNewFrame > 0.) ? -vIPAbs : vIPAbs;
0423
0424
0425
0426
0427 const float aCoef = (vT - vIP) / (uT - uIP);
0428 const float bCoef = vIP - aCoef * uIP;
0429
0430
0431
0432 if ((bCoef * bCoef) * options.minHelixDiameter2 > (1 + aCoef * aCoef)) {
0433 continue;
0434 }
0435
0436
0437
0438
0439 if (deltaZ > m_config.cotThetaMax * deltaR ||
0440 deltaZ < -m_config.cotThetaMax * deltaR) {
0441 continue;
0442 }
0443
0444 const float iDeltaR = std::sqrt(iDeltaR2);
0445 const float cotTheta = deltaZ * iDeltaR;
0446
0447
0448
0449 if constexpr (isBottomCandidate) {
0450 if (!m_config.experimentCuts(otherSP->radius(), cotTheta)) {
0451 continue;
0452 }
0453 }
0454
0455 const float Er =
0456 ((varianceZM + otherSP->varianceZ()) +
0457 (cotTheta * cotTheta) * (varianceRM + otherSP->varianceR())) *
0458 iDeltaR2;
0459
0460
0461 linCircleVec.emplace_back(cotTheta, iDeltaR, Er, uT, vT, xNewFrame,
0462 yNewFrame);
0463 spacePointData.setDeltaR(otherSP->index(),
0464 std::sqrt(deltaR2 + (deltaZ * deltaZ)));
0465 outVec.emplace_back(otherSP.get());
0466 }
0467 }
0468 }
0469
0470 template <typename external_spacepoint_t, typename grid_t, typename platform_t>
0471 template <Acts::DetectorMeasurementInfo detailedMeasurement>
0472 inline void
0473 SeedFinder<external_spacepoint_t, grid_t, platform_t>::filterCandidates(
0474 Acts::SpacePointData& spacePointData,
0475 const InternalSpacePoint<external_spacepoint_t>& spM,
0476 const Acts::SeedFinderOptions& options, SeedFilterState& seedFilterState,
0477 SeedingState& state) const {
0478 float rM = spM.radius();
0479 float cosPhiM = spM.x() / rM;
0480 float sinPhiM = spM.y() / rM;
0481 float varianceRM = spM.varianceR();
0482 float varianceZM = spM.varianceZ();
0483
0484 std::size_t numTopSP = state.compatTopSP.size();
0485
0486
0487 std::vector<std::size_t> sorted_bottoms(state.linCircleBottom.size());
0488 for (std::size_t i(0); i < sorted_bottoms.size(); ++i) {
0489 sorted_bottoms[i] = i;
0490 }
0491
0492 std::vector<std::size_t> sorted_tops(state.linCircleTop.size());
0493 for (std::size_t i(0); i < sorted_tops.size(); ++i) {
0494 sorted_tops[i] = i;
0495 }
0496
0497 if constexpr (detailedMeasurement ==
0498 Acts::DetectorMeasurementInfo::eDefault) {
0499 std::sort(sorted_bottoms.begin(), sorted_bottoms.end(),
0500 [&state](const std::size_t a, const std::size_t b) -> bool {
0501 return state.linCircleBottom[a].cotTheta <
0502 state.linCircleBottom[b].cotTheta;
0503 });
0504
0505 std::sort(sorted_tops.begin(), sorted_tops.end(),
0506 [&state](const std::size_t a, const std::size_t b) -> bool {
0507 return state.linCircleTop[a].cotTheta <
0508 state.linCircleTop[b].cotTheta;
0509 });
0510 }
0511
0512
0513 state.topSpVec.reserve(numTopSP);
0514 state.curvatures.reserve(numTopSP);
0515 state.impactParameters.reserve(numTopSP);
0516
0517 std::size_t t0 = 0;
0518
0519
0520 state.candidates_collector.clear();
0521
0522 for (const std::size_t b : sorted_bottoms) {
0523
0524 if (t0 == numTopSP) {
0525 break;
0526 }
0527
0528 auto lb = state.linCircleBottom[b];
0529 float cotThetaB = lb.cotTheta;
0530 float Vb = lb.V;
0531 float Ub = lb.U;
0532 float ErB = lb.Er;
0533 float iDeltaRB = lb.iDeltaR;
0534
0535
0536 float iSinTheta2 = (1. + cotThetaB * cotThetaB);
0537 float sigmaSquaredPtDependent = iSinTheta2 * options.sigmapT2perRadius;
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547 float scatteringInRegion2 = options.multipleScattering2 * iSinTheta2;
0548
0549 float sinTheta = 1 / std::sqrt(iSinTheta2);
0550 float cosTheta = cotThetaB * sinTheta;
0551
0552
0553 state.topSpVec.clear();
0554 state.curvatures.clear();
0555 state.impactParameters.clear();
0556
0557
0558
0559 float rotationTermsUVtoXY[2] = {0, 0};
0560 if constexpr (detailedMeasurement ==
0561 Acts::DetectorMeasurementInfo::eDetailed) {
0562 rotationTermsUVtoXY[0] = cosPhiM * sinTheta;
0563 rotationTermsUVtoXY[1] = sinPhiM * sinTheta;
0564 }
0565
0566
0567
0568
0569 std::size_t minCompatibleTopSPs = 2;
0570 if (!m_config.seedConfirmation ||
0571 state.compatBottomSP[b]->radius() > seedFilterState.rMaxSeedConf) {
0572 minCompatibleTopSPs = 1;
0573 }
0574 if (m_config.seedConfirmation &&
0575 state.candidates_collector.nHighQualityCandidates()) {
0576 minCompatibleTopSPs++;
0577 }
0578
0579 for (std::size_t index_t = t0; index_t < numTopSP; index_t++) {
0580 const std::size_t t = sorted_tops[index_t];
0581
0582 auto lt = state.linCircleTop[t];
0583
0584 float cotThetaT = lt.cotTheta;
0585 float rMxy = 0.;
0586 float ub = 0.;
0587 float vb = 0.;
0588 float ut = 0.;
0589 float vt = 0.;
0590 double rMTransf[3];
0591 float xB = 0.;
0592 float yB = 0.;
0593 float xT = 0.;
0594 float yT = 0.;
0595 float iDeltaRB2 = 0.;
0596 float iDeltaRT2 = 0.;
0597
0598 if constexpr (detailedMeasurement ==
0599 Acts::DetectorMeasurementInfo::eDetailed) {
0600
0601 float dU = lt.U - Ub;
0602 if (dU == 0.) {
0603 continue;
0604 }
0605
0606
0607 float A0 = (lt.V - Vb) / dU;
0608
0609 float zPositionMiddle = cosTheta * std::sqrt(1 + A0 * A0);
0610
0611
0612
0613 double positionMiddle[3] = {
0614 rotationTermsUVtoXY[0] - rotationTermsUVtoXY[1] * A0,
0615 rotationTermsUVtoXY[0] * A0 + rotationTermsUVtoXY[1],
0616 zPositionMiddle};
0617
0618 if (!xyzCoordinateCheck(spacePointData, m_config, spM, positionMiddle,
0619 rMTransf)) {
0620 continue;
0621 }
0622
0623
0624 float B0 = 2. * (Vb - A0 * Ub);
0625 float Cb = 1. - B0 * lb.y;
0626 float Sb = A0 + B0 * lb.x;
0627 double positionBottom[3] = {
0628 rotationTermsUVtoXY[0] * Cb - rotationTermsUVtoXY[1] * Sb,
0629 rotationTermsUVtoXY[0] * Sb + rotationTermsUVtoXY[1] * Cb,
0630 zPositionMiddle};
0631
0632 auto spB = state.compatBottomSP[b];
0633 double rBTransf[3];
0634 if (!xyzCoordinateCheck(spacePointData, m_config, *spB, positionBottom,
0635 rBTransf)) {
0636 continue;
0637 }
0638
0639
0640 float Ct = 1. - B0 * lt.y;
0641 float St = A0 + B0 * lt.x;
0642 double positionTop[3] = {
0643 rotationTermsUVtoXY[0] * Ct - rotationTermsUVtoXY[1] * St,
0644 rotationTermsUVtoXY[0] * St + rotationTermsUVtoXY[1] * Ct,
0645 zPositionMiddle};
0646
0647 auto spT = state.compatTopSP[t];
0648 double rTTransf[3];
0649 if (!xyzCoordinateCheck(spacePointData, m_config, *spT, positionTop,
0650 rTTransf)) {
0651 continue;
0652 }
0653
0654
0655 xB = rBTransf[0] - rMTransf[0];
0656 yB = rBTransf[1] - rMTransf[1];
0657 float zB = rBTransf[2] - rMTransf[2];
0658 xT = rTTransf[0] - rMTransf[0];
0659 yT = rTTransf[1] - rMTransf[1];
0660 float zT = rTTransf[2] - rMTransf[2];
0661
0662 iDeltaRB2 = 1. / (xB * xB + yB * yB);
0663 iDeltaRT2 = 1. / (xT * xT + yT * yT);
0664
0665 cotThetaB = -zB * std::sqrt(iDeltaRB2);
0666 cotThetaT = zT * std::sqrt(iDeltaRT2);
0667 }
0668
0669
0670 float cotThetaAvg2 = cotThetaB * cotThetaT;
0671 if constexpr (detailedMeasurement ==
0672 Acts::DetectorMeasurementInfo::eDetailed) {
0673
0674 float averageCotTheta = 0.5 * (cotThetaB + cotThetaT);
0675 cotThetaAvg2 = averageCotTheta * averageCotTheta;
0676 } else if (cotThetaAvg2 <= 0) {
0677 continue;
0678 }
0679
0680
0681
0682 float error2 =
0683 lt.Er + ErB +
0684 2 * (cotThetaAvg2 * varianceRM + varianceZM) * iDeltaRB * lt.iDeltaR;
0685
0686 float deltaCotTheta = cotThetaB - cotThetaT;
0687 float deltaCotTheta2 = deltaCotTheta * deltaCotTheta;
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699 if (deltaCotTheta2 > (error2 + scatteringInRegion2)) {
0700
0701 if constexpr (detailedMeasurement ==
0702 Acts::DetectorMeasurementInfo::eDetailed) {
0703 continue;
0704 }
0705
0706
0707 if (cotThetaB - cotThetaT < 0) {
0708 break;
0709 }
0710 t0 = index_t + 1;
0711 continue;
0712 }
0713
0714 if constexpr (detailedMeasurement ==
0715 Acts::DetectorMeasurementInfo::eDetailed) {
0716 rMxy = std::sqrt(rMTransf[0] * rMTransf[0] + rMTransf[1] * rMTransf[1]);
0717 double irMxy = 1 / rMxy;
0718 float Ax = rMTransf[0] * irMxy;
0719 float Ay = rMTransf[1] * irMxy;
0720
0721 ub = (xB * Ax + yB * Ay) * iDeltaRB2;
0722 vb = (yB * Ax - xB * Ay) * iDeltaRB2;
0723 ut = (xT * Ax + yT * Ay) * iDeltaRT2;
0724 vt = (yT * Ax - xT * Ay) * iDeltaRT2;
0725 }
0726
0727 float dU = 0;
0728 float A = 0;
0729 float S2 = 0;
0730 float B = 0;
0731 float B2 = 0;
0732
0733 if constexpr (detailedMeasurement ==
0734 Acts::DetectorMeasurementInfo::eDetailed) {
0735 dU = ut - ub;
0736
0737 if (dU == 0.) {
0738 continue;
0739 }
0740 A = (vt - vb) / dU;
0741 S2 = 1. + A * A;
0742 B = vb - A * ub;
0743 B2 = B * B;
0744 } else {
0745 dU = lt.U - Ub;
0746
0747 if (dU == 0.) {
0748 continue;
0749 }
0750
0751
0752 A = (lt.V - Vb) / dU;
0753 S2 = 1. + A * A;
0754 B = Vb - A * Ub;
0755 B2 = B * B;
0756 }
0757
0758
0759
0760 if (S2 < B2 * options.minHelixDiameter2) {
0761 continue;
0762 }
0763
0764
0765
0766
0767 float iHelixDiameter2 = B2 / S2;
0768
0769
0770 float p2scatterSigma = iHelixDiameter2 * sigmaSquaredPtDependent;
0771 if (!std::isinf(m_config.maxPtScattering)) {
0772
0773
0774
0775
0776 if (B2 == 0 || options.pTPerHelixRadius * std::sqrt(S2 / B2) >
0777 2. * m_config.maxPtScattering) {
0778 float pTscatterSigma =
0779 (m_config.highland / m_config.maxPtScattering) *
0780 m_config.sigmaScattering;
0781 p2scatterSigma = pTscatterSigma * pTscatterSigma * iSinTheta2;
0782 }
0783 }
0784
0785
0786 if (deltaCotTheta2 > (error2 + p2scatterSigma)) {
0787 if constexpr (detailedMeasurement ==
0788 Acts::DetectorMeasurementInfo::eDetailed) {
0789 continue;
0790 }
0791 if (cotThetaB - cotThetaT < 0) {
0792 break;
0793 }
0794 t0 = index_t;
0795 continue;
0796 }
0797
0798
0799
0800 float Im = 0;
0801 if constexpr (detailedMeasurement ==
0802 Acts::DetectorMeasurementInfo::eDetailed) {
0803 Im = std::abs((A - B * rMxy) * rMxy);
0804 } else {
0805 Im = std::abs((A - B * rM) * rM);
0806 }
0807
0808 if (Im > m_config.impactMax) {
0809 continue;
0810 }
0811
0812 state.topSpVec.push_back(state.compatTopSP[t]);
0813
0814
0815 state.curvatures.push_back(B / std::sqrt(S2));
0816 state.impactParameters.push_back(Im);
0817 }
0818
0819
0820 if (state.topSpVec.size() < minCompatibleTopSPs) {
0821 continue;
0822 }
0823
0824 seedFilterState.zOrigin = spM.z() - rM * lb.cotTheta;
0825
0826 m_config.seedFilter->filterSeeds_2SpFixed(
0827 state.spacePointData, *state.compatBottomSP[b], spM, state.topSpVec,
0828 state.curvatures, state.impactParameters, seedFilterState,
0829 state.candidates_collector);
0830 }
0831 }
0832
0833 }