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