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