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