File indexing completed on 2025-01-18 09:11:02
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/Extent.hpp"
0010 #include "Acts/Seeding/SeedFilter.hpp"
0011 #include "Acts/Seeding/SeedFinder.hpp"
0012 #include "Acts/Seeding/SeedFinderOrthogonalConfig.hpp"
0013 #include "Acts/Seeding/SeedFinderUtils.hpp"
0014 #include "Acts/Utilities/AxisDefinitions.hpp"
0015
0016 #include <algorithm>
0017 #include <cmath>
0018 #include <functional>
0019 #include <numeric>
0020 #include <type_traits>
0021
0022 namespace Acts {
0023 template <typename external_spacepoint_t>
0024 auto SeedFinderOrthogonal<external_spacepoint_t>::validTupleOrthoRangeLH(
0025 const external_spacepoint_t &low) const -> typename tree_t::range_t {
0026 float colMin = m_config.collisionRegionMin;
0027 float colMax = m_config.collisionRegionMax;
0028 float pL = low.phi();
0029 float rL = low.radius();
0030 float zL = low.z();
0031
0032 typename tree_t::range_t res;
0033
0034
0035
0036
0037
0038 res[DimPhi].shrinkMin(m_config.phiMin);
0039 res[DimPhi].shrinkMax(m_config.phiMax);
0040
0041
0042
0043
0044
0045 res[DimR].shrinkMax(m_config.rMax);
0046
0047
0048
0049
0050
0051 res[DimZ].shrinkMin(m_config.zMin);
0052 res[DimZ].shrinkMax(m_config.zMax);
0053
0054
0055
0056
0057
0058 res[DimR].shrinkMin(rL + m_config.deltaRMinTopSP);
0059 res[DimR].shrinkMax(rL + m_config.deltaRMaxTopSP);
0060
0061
0062
0063
0064
0065 float zMax = (res[DimR].max() / rL) * (zL - colMin) + colMin;
0066 float zMin = colMax - (res[DimR].max() / rL) * (colMax - zL);
0067
0068
0069
0070
0071 if (zL > colMin) {
0072 res[DimZ].shrinkMax(zMax);
0073 } else if (zL < colMax) {
0074 res[DimZ].shrinkMin(zMin);
0075 }
0076
0077
0078
0079
0080 res[DimZ].shrinkMin(zL - m_config.cotThetaMax * (res[DimR].max() - rL));
0081 res[DimZ].shrinkMax(zL + m_config.cotThetaMax * (res[DimR].max() - rL));
0082
0083
0084
0085
0086 res[DimPhi].shrinkMin(pL - m_config.deltaPhiMax);
0087 res[DimPhi].shrinkMax(pL + m_config.deltaPhiMax);
0088
0089
0090 res[DimZ].shrinkMin(zL - m_config.deltaZMax);
0091 res[DimZ].shrinkMax(zL + m_config.deltaZMax);
0092
0093 return res;
0094 }
0095
0096 template <typename external_spacepoint_t>
0097 auto SeedFinderOrthogonal<external_spacepoint_t>::validTupleOrthoRangeHL(
0098 const external_spacepoint_t &high) const -> typename tree_t::range_t {
0099 float pM = high.phi();
0100 float rM = high.radius();
0101 float zM = high.z();
0102
0103 typename tree_t::range_t res;
0104
0105
0106
0107
0108
0109 res[DimPhi].shrinkMin(m_config.phiMin);
0110 res[DimPhi].shrinkMax(m_config.phiMax);
0111
0112
0113
0114
0115
0116 res[DimR].shrinkMax(m_config.rMax);
0117
0118
0119
0120
0121
0122 res[DimZ].shrinkMin(m_config.zMin);
0123 res[DimZ].shrinkMax(m_config.zMax);
0124
0125
0126
0127
0128
0129 res[DimR].shrinkMin(rM - m_config.deltaRMaxBottomSP);
0130 res[DimR].shrinkMax(rM - m_config.deltaRMinBottomSP);
0131
0132
0133
0134
0135
0136 float fracR = res[DimR].min() / rM;
0137
0138 float zMin =
0139 (zM - m_config.collisionRegionMin) * fracR + m_config.collisionRegionMin;
0140 float zMax =
0141 (zM - m_config.collisionRegionMax) * fracR + m_config.collisionRegionMax;
0142
0143 res[DimZ].shrinkMin(std::min(zMin, zM));
0144 res[DimZ].shrinkMax(std::max(zMax, zM));
0145
0146
0147
0148
0149 res[DimPhi].shrinkMin(pM - m_config.deltaPhiMax);
0150 res[DimPhi].shrinkMax(pM + m_config.deltaPhiMax);
0151
0152
0153 res[DimZ].shrinkMin(zM - m_config.deltaZMax);
0154 res[DimZ].shrinkMax(zM + m_config.deltaZMax);
0155
0156 return res;
0157 }
0158
0159 template <typename external_spacepoint_t>
0160 bool SeedFinderOrthogonal<external_spacepoint_t>::validTuple(
0161 const SeedFinderOptions &options, const external_spacepoint_t &low,
0162 const external_spacepoint_t &high, bool isMiddleInverted) const {
0163 float rL = low.radius();
0164 float rH = high.radius();
0165
0166 float zL = low.z();
0167 float zH = high.z();
0168
0169 float deltaR = rH - rL;
0170
0171 float deltaZ = (zH - zL);
0172 float cotTheta = deltaZ / deltaR;
0173
0174
0175
0176
0177 float zOrigin = zL - rL * cotTheta;
0178 if (zOrigin < m_config.collisionRegionMin ||
0179 zOrigin > m_config.collisionRegionMax) {
0180 return false;
0181 }
0182
0183
0184
0185
0186
0187
0188
0189 if (m_config.interactionPointCut) {
0190 float xVal = (high.x() - low.x()) * (low.x() / rL) +
0191 (high.y() - low.y()) * (low.y() / rL);
0192 float yVal = (high.y() - low.y()) * (low.x() / rL) -
0193 (high.x() - low.x()) * (low.y() / rL);
0194
0195 const int sign = isMiddleInverted ? -1 : 1;
0196
0197 if (std::abs(rL * yVal) > sign * m_config.impactMax * xVal) {
0198
0199
0200
0201
0202 float uT = xVal / (xVal * xVal + yVal * yVal);
0203 float vT = yVal / (xVal * xVal + yVal * yVal);
0204
0205
0206 float uIP = -1. / rL;
0207 float vIP = m_config.impactMax / (rL * rL);
0208 if (sign * yVal > 0.) {
0209 vIP = -vIP;
0210 }
0211
0212
0213
0214 float aCoef = (vT - vIP) / (uT - uIP);
0215 float bCoef = vIP - aCoef * uIP;
0216
0217
0218
0219 if ((bCoef * bCoef) > (1 + aCoef * aCoef) / options.minHelixDiameter2) {
0220 return false;
0221 }
0222 }
0223 }
0224
0225
0226
0227
0228
0229 if (std::abs(cotTheta) > m_config.cotThetaMax) {
0230 return false;
0231 }
0232
0233
0234
0235
0236
0237 const float rInner = (isMiddleInverted) ? rH : rL;
0238 if (!m_config.experimentCuts(rInner, cotTheta)) {
0239 return false;
0240 }
0241
0242 return true;
0243 }
0244
0245 template <typename external_spacepoint_t>
0246 SeedFinderOrthogonal<external_spacepoint_t>::SeedFinderOrthogonal(
0247 const SeedFinderOrthogonalConfig<external_spacepoint_t> &config,
0248 std::unique_ptr<const Acts::Logger> logger)
0249 : m_config(config), m_logger(std::move(logger)) {
0250 if (!config.isInInternalUnits) {
0251 throw std::runtime_error(
0252 "SeedFinderOrthogonalConfig not in ACTS internal units in "
0253 "SeedFinderOrthogonal");
0254 }
0255 }
0256
0257 template <typename external_spacepoint_t>
0258 void SeedFinderOrthogonal<external_spacepoint_t>::filterCandidates(
0259 const SeedFinderOptions &options, Acts::SpacePointMutableData &mutableData,
0260 const external_spacepoint_t &middle,
0261 const std::vector<const external_spacepoint_t *> &bottom,
0262 const std::vector<const external_spacepoint_t *> &top,
0263 SeedFilterState seedFilterState,
0264 CandidatesForMiddleSp<const external_spacepoint_t> &candidates_collector)
0265 const {
0266 float rM = middle.radius();
0267 float zM = middle.z();
0268 float varianceRM = middle.varianceR();
0269 float varianceZM = middle.varianceZ();
0270
0271
0272 if (m_config.seedConfirmation == true) {
0273
0274 SeedConfirmationRangeConfig seedConfRange =
0275 (zM > m_config.centralSeedConfirmationRange.zMaxSeedConf ||
0276 zM < m_config.centralSeedConfirmationRange.zMinSeedConf)
0277 ? m_config.forwardSeedConfirmationRange
0278 : m_config.centralSeedConfirmationRange;
0279
0280
0281 seedFilterState.nTopSeedConf = rM > seedConfRange.rMaxSeedConf
0282 ? seedConfRange.nTopForLargeR
0283 : seedConfRange.nTopForSmallR;
0284
0285 seedFilterState.rMaxSeedConf = seedConfRange.rMaxSeedConf;
0286
0287 if (top.size() < seedFilterState.nTopSeedConf) {
0288 return;
0289 }
0290 }
0291
0292 std::vector<const external_spacepoint_t *> top_valid;
0293 std::vector<float> curvatures;
0294 std::vector<float> impactParameters;
0295
0296
0297
0298 std::vector<LinCircle> linCircleBottom;
0299
0300 std::vector<LinCircle> linCircleTop;
0301
0302
0303 transformCoordinates(mutableData, bottom, middle, true, linCircleBottom);
0304 transformCoordinates(mutableData, top, middle, false, linCircleTop);
0305
0306
0307 std::vector<std::size_t> sorted_bottoms(linCircleBottom.size());
0308 for (std::size_t i(0); i < sorted_bottoms.size(); ++i) {
0309 sorted_bottoms[i] = i;
0310 }
0311
0312 std::vector<std::size_t> sorted_tops(linCircleTop.size());
0313 for (std::size_t i(0); i < sorted_tops.size(); ++i) {
0314 sorted_tops[i] = i;
0315 }
0316
0317 std::ranges::sort(sorted_bottoms, {},
0318 [&linCircleBottom](const std::size_t s) {
0319 return linCircleBottom[s].cotTheta;
0320 });
0321
0322 std::ranges::sort(sorted_tops, {}, [&linCircleTop](const std::size_t s) {
0323 return linCircleTop[s].cotTheta;
0324 });
0325
0326 std::vector<float> tanMT;
0327 tanMT.reserve(top.size());
0328
0329 std::size_t numTopSP = top.size();
0330 for (std::size_t t = 0; t < numTopSP; t++) {
0331 tanMT.push_back(
0332 std::atan2(top[t]->radius() - middle.radius(), top[t]->z() - zM));
0333 }
0334
0335 std::size_t t0 = 0;
0336
0337 for (const std::size_t b : sorted_bottoms) {
0338
0339 if (t0 == numTopSP) {
0340 break;
0341 }
0342
0343 auto lb = linCircleBottom[b];
0344
0345
0346 float iSinTheta2 = (1. + lb.cotTheta * lb.cotTheta);
0347 float sigmaSquaredPtDependent = iSinTheta2 * options.sigmapT2perRadius;
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 float scatteringInRegion2 = options.multipleScattering2 * iSinTheta2;
0358
0359
0360
0361
0362 std::size_t minCompatibleTopSPs = 2;
0363 if (!m_config.seedConfirmation ||
0364 bottom[b]->radius() > seedFilterState.rMaxSeedConf) {
0365 minCompatibleTopSPs = 1;
0366 }
0367 if (m_config.seedConfirmation &&
0368 candidates_collector.nHighQualityCandidates()) {
0369 minCompatibleTopSPs++;
0370 }
0371
0372
0373 top_valid.clear();
0374 curvatures.clear();
0375 impactParameters.clear();
0376
0377 float tanLM = std::atan2(rM - bottom[b]->radius(), zM - bottom[b]->z());
0378
0379 for (std::size_t index_t = t0; index_t < numTopSP; index_t++) {
0380 const std::size_t t = sorted_tops[index_t];
0381 auto lt = linCircleTop[t];
0382
0383 if (std::abs(tanLM - tanMT[t]) > 0.005) {
0384 continue;
0385 }
0386
0387
0388
0389 float error2 = lt.Er + lb.Er +
0390 2 * (lb.cotTheta * lt.cotTheta * varianceRM + varianceZM) *
0391 lb.iDeltaR * lt.iDeltaR;
0392
0393 float deltaCotTheta = lb.cotTheta - lt.cotTheta;
0394 float deltaCotTheta2 = deltaCotTheta * deltaCotTheta;
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 if (deltaCotTheta2 > (error2 + scatteringInRegion2)) {
0407
0408
0409
0410 if (deltaCotTheta < 0) {
0411 break;
0412 }
0413 t0 = index_t + 1;
0414 continue;
0415 }
0416
0417 float dU = lt.U - lb.U;
0418
0419
0420
0421 float A = (lt.V - lb.V) / dU;
0422 float S2 = 1. + A * A;
0423 float B = lb.V - A * lb.U;
0424 float B2 = B * B;
0425
0426
0427 if (S2 < B2 * options.minHelixDiameter2) {
0428 continue;
0429 }
0430
0431
0432
0433
0434 float p2scatterSigma = B2 / S2 * sigmaSquaredPtDependent;
0435 if (!std::isinf(m_config.maxPtScattering)) {
0436
0437
0438 if (B2 == 0 || options.pTPerHelixRadius * std::sqrt(S2 / B2) >
0439 2. * m_config.maxPtScattering) {
0440 float pTscatterSigma =
0441 (m_config.highland / m_config.maxPtScattering) *
0442 m_config.sigmaScattering;
0443 p2scatterSigma = pTscatterSigma * pTscatterSigma * iSinTheta2;
0444 }
0445 }
0446
0447 if (deltaCotTheta2 > (error2 + p2scatterSigma)) {
0448 if (deltaCotTheta < 0) {
0449 break;
0450 }
0451 t0 = index_t;
0452 continue;
0453 }
0454
0455
0456
0457
0458 float Im = std::abs((A - B * rM) * rM);
0459
0460 if (Im <= m_config.impactMax) {
0461 top_valid.push_back(top[t]);
0462
0463
0464 curvatures.push_back(B / std::sqrt(S2));
0465 impactParameters.push_back(Im);
0466 }
0467 }
0468
0469
0470 if (top_valid.size() < minCompatibleTopSPs) {
0471 continue;
0472 }
0473
0474 seedFilterState.zOrigin = zM - rM * lb.cotTheta;
0475
0476 m_config.seedFilter->filterSeeds_2SpFixed(
0477 mutableData, *bottom[b], middle, top_valid, curvatures,
0478 impactParameters, seedFilterState, candidates_collector);
0479
0480 }
0481 }
0482
0483 template <typename external_spacepoint_t>
0484 template <typename output_container_t>
0485 void SeedFinderOrthogonal<external_spacepoint_t>::processFromMiddleSP(
0486 const SeedFinderOptions &options, Acts::SpacePointMutableData &mutableData,
0487 const tree_t &tree, output_container_t &out_cont,
0488 const typename tree_t::pair_t &middle_p) const {
0489 using range_t = typename tree_t::range_t;
0490 const external_spacepoint_t &middle = *middle_p.second;
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502 std::vector<const external_spacepoint_t *> bottom_lh_v, bottom_hl_v, top_lh_v,
0503 top_hl_v;
0504
0505
0506
0507
0508 std::size_t max_num_quality_seeds_per_spm =
0509 m_config.seedFilter->getSeedFilterConfig().maxQualitySeedsPerSpMConf;
0510 std::size_t max_num_seeds_per_spm =
0511 m_config.seedFilter->getSeedFilterConfig().maxSeedsPerSpMConf;
0512
0513 CandidatesForMiddleSp<const external_spacepoint_t> candidates_collector;
0514 candidates_collector.setMaxElements(max_num_seeds_per_spm,
0515 max_num_quality_seeds_per_spm);
0516
0517
0518
0519
0520
0521 range_t bottom_r = validTupleOrthoRangeHL(middle);
0522 range_t top_r = validTupleOrthoRangeLH(middle);
0523
0524
0525
0526
0527 float myCotTheta =
0528 std::max(std::abs(middle.z() / middle.radius()), m_config.cotThetaMax);
0529
0530
0531
0532
0533
0534 float deltaRMaxTop = top_r[DimR].max() - middle.radius();
0535 float deltaRMaxBottom = middle.radius() - bottom_r[DimR].min();
0536
0537
0538
0539
0540
0541
0542
0543
0544 range_t bottom_lh_r = bottom_r;
0545 bottom_lh_r[DimZ].shrink(middle.z() - myCotTheta * deltaRMaxBottom,
0546 middle.z());
0547
0548
0549
0550
0551
0552 range_t top_lh_r = top_r;
0553 top_lh_r[DimZ].shrink(middle.z(), middle.z() + myCotTheta * deltaRMaxTop);
0554
0555 range_t bottom_hl_r = bottom_r;
0556 bottom_hl_r[DimZ].shrink(middle.z(),
0557 middle.z() + myCotTheta * deltaRMaxBottom);
0558 range_t top_hl_r = top_r;
0559 top_hl_r[DimZ].shrink(middle.z() - myCotTheta * deltaRMaxTop, middle.z());
0560
0561
0562
0563
0564
0565 bottom_lh_v.clear();
0566 bottom_hl_v.clear();
0567 top_lh_v.clear();
0568 top_hl_v.clear();
0569
0570
0571
0572
0573
0574
0575
0576
0577 if (!bottom_lh_r.degenerate() && !top_lh_r.degenerate()) {
0578
0579
0580
0581 tree.rangeSearchMapDiscard(top_lh_r,
0582 [this, &options, &middle, &top_lh_v](
0583 const typename tree_t::coordinate_t &,
0584 const typename tree_t::value_t &top) {
0585 if (validTuple(options, *top, middle, true)) {
0586 top_lh_v.push_back(top);
0587 }
0588 });
0589 }
0590
0591
0592
0593
0594
0595 if (!bottom_hl_r.degenerate() && !top_hl_r.degenerate()) {
0596 tree.rangeSearchMapDiscard(top_hl_r,
0597 [this, &options, &middle, &top_hl_v](
0598 const typename tree_t::coordinate_t &,
0599 const typename tree_t::value_t &top) {
0600 if (validTuple(options, middle, *top, false)) {
0601 top_hl_v.push_back(top);
0602 }
0603 });
0604 }
0605
0606
0607 SeedFilterState seedFilterState;
0608 bool search_bot_hl = true;
0609 bool search_bot_lh = true;
0610 if (m_config.seedConfirmation) {
0611
0612 SeedConfirmationRangeConfig seedConfRange =
0613 (middle.z() > m_config.centralSeedConfirmationRange.zMaxSeedConf ||
0614 middle.z() < m_config.centralSeedConfirmationRange.zMinSeedConf)
0615 ? m_config.forwardSeedConfirmationRange
0616 : m_config.centralSeedConfirmationRange;
0617
0618
0619 seedFilterState.nTopSeedConf = middle.radius() > seedConfRange.rMaxSeedConf
0620 ? seedConfRange.nTopForLargeR
0621 : seedConfRange.nTopForSmallR;
0622
0623 seedFilterState.rMaxSeedConf = seedConfRange.rMaxSeedConf;
0624
0625 if (top_lh_v.size() < seedFilterState.nTopSeedConf) {
0626 search_bot_lh = false;
0627 }
0628 if (top_hl_v.size() < seedFilterState.nTopSeedConf) {
0629 search_bot_hl = false;
0630 }
0631 }
0632
0633
0634
0635
0636
0637 if (!top_lh_v.empty() && search_bot_lh) {
0638 tree.rangeSearchMapDiscard(
0639 bottom_lh_r, [this, &options, &middle, &bottom_lh_v](
0640 const typename tree_t::coordinate_t &,
0641 const typename tree_t::value_t &bottom) {
0642 if (validTuple(options, *bottom, middle, false)) {
0643 bottom_lh_v.push_back(bottom);
0644 }
0645 });
0646 }
0647
0648
0649
0650
0651 if (!top_hl_v.empty() && search_bot_hl) {
0652 tree.rangeSearchMapDiscard(
0653 bottom_hl_r, [this, &options, &middle, &bottom_hl_v](
0654 const typename tree_t::coordinate_t &,
0655 const typename tree_t::value_t &bottom) {
0656 if (validTuple(options, middle, *bottom, true)) {
0657 bottom_hl_v.push_back(bottom);
0658 }
0659 });
0660 }
0661
0662
0663
0664
0665 if (!bottom_lh_v.empty() && !top_lh_v.empty()) {
0666 filterCandidates(options, mutableData, middle, bottom_lh_v, top_lh_v,
0667 seedFilterState, candidates_collector);
0668 }
0669
0670
0671
0672 if (!bottom_hl_v.empty() && !top_hl_v.empty()) {
0673 filterCandidates(options, mutableData, middle, bottom_hl_v, top_hl_v,
0674 seedFilterState, candidates_collector);
0675 }
0676
0677
0678
0679 if ((!bottom_lh_v.empty() && !top_lh_v.empty()) ||
0680 (!bottom_hl_v.empty() && !top_hl_v.empty())) {
0681 m_config.seedFilter->filterSeeds_1SpFixed(mutableData, candidates_collector,
0682 out_cont);
0683 }
0684 }
0685
0686 template <typename external_spacepoint_t>
0687 auto SeedFinderOrthogonal<external_spacepoint_t>::createTree(
0688 const std::vector<const external_spacepoint_t *> &spacePoints) const
0689 -> tree_t {
0690 std::vector<typename tree_t::pair_t> points;
0691 points.reserve(spacePoints.size());
0692
0693
0694
0695
0696
0697
0698 for (const external_spacepoint_t *sp : spacePoints) {
0699 typename tree_t::coordinate_t point;
0700
0701 point[DimPhi] = sp->phi();
0702 point[DimR] = sp->radius();
0703 point[DimZ] = sp->z();
0704
0705 points.emplace_back(point, sp);
0706 }
0707
0708 ACTS_VERBOSE("Created k-d tree populated with " << points.size()
0709 << " space points");
0710 return tree_t(std::move(points));
0711 }
0712
0713 template <typename external_spacepoint_t>
0714 template <typename input_container_t, typename output_container_t>
0715 void SeedFinderOrthogonal<external_spacepoint_t>::createSeeds(
0716 const Acts::SeedFinderOptions &options,
0717 const input_container_t &spacePoints, output_container_t &out_cont) const {
0718 ACTS_VERBOSE("Creating seeds with Orthogonal strategy");
0719 if (!options.isInInternalUnits) {
0720 throw std::runtime_error(
0721 "SeedFinderOptions not in ACTS internal units in "
0722 "SeedFinderOrthogonal");
0723 }
0724
0725
0726
0727
0728
0729 static_assert(std::is_same_v<typename output_container_t::value_type,
0730 Seed<external_spacepoint_t>>,
0731 "Output iterator container type must accept seeds.");
0732 static_assert(std::is_same_v<typename input_container_t::value_type,
0733 external_spacepoint_t>,
0734 "Input container must contain external spacepoints.");
0735
0736
0737
0738
0739
0740
0741
0742 ACTS_VERBOSE("Running on " << spacePoints.size() << " input space points");
0743 Acts::Extent rRangeSPExtent;
0744 std::vector<const external_spacepoint_t *> internal_sps;
0745 internal_sps.reserve(spacePoints.size());
0746
0747 Acts::SpacePointMutableData mutableData;
0748 mutableData.resize(spacePoints.size());
0749
0750 for (const external_spacepoint_t &p : spacePoints) {
0751
0752 rRangeSPExtent.extend({p.x(), p.y(), p.z()});
0753 internal_sps.push_back(&p);
0754 }
0755 ACTS_VERBOSE(rRangeSPExtent);
0756
0757
0758 const Acts::Range1D<float> rMiddleSPRange(
0759 std::floor(rRangeSPExtent.min(Acts::AxisDirection::AxisR) / 2) * 2 +
0760 m_config.deltaRMiddleMinSPRange,
0761 std::floor(rRangeSPExtent.max(Acts::AxisDirection::AxisR) / 2) * 2 -
0762 m_config.deltaRMiddleMaxSPRange);
0763
0764
0765
0766
0767
0768 tree_t tree = createTree(internal_sps);
0769
0770
0771
0772
0773 for (const typename tree_t::pair_t &middle_p : tree) {
0774 const external_spacepoint_t &middle = *middle_p.second;
0775 auto rM = middle.radius();
0776
0777
0778
0779
0780
0781 if (m_config.useVariableMiddleSPRange) {
0782 if (rM < rMiddleSPRange.min() || rM > rMiddleSPRange.max()) {
0783 continue;
0784 }
0785 } else {
0786 if (rM > m_config.rMaxMiddle || rM < m_config.rMinMiddle) {
0787 continue;
0788 }
0789 }
0790
0791
0792 if (middle.z() < m_config.zOutermostLayers.first ||
0793 middle.z() > m_config.zOutermostLayers.second) {
0794 continue;
0795 }
0796 float spPhi = middle.phi();
0797 if (spPhi > m_config.phiMax || spPhi < m_config.phiMin) {
0798 continue;
0799 }
0800
0801 processFromMiddleSP(options, mutableData, tree, out_cont, middle_p);
0802 }
0803 }
0804
0805 template <typename external_spacepoint_t>
0806 template <typename input_container_t>
0807 std::vector<Seed<external_spacepoint_t>>
0808 SeedFinderOrthogonal<external_spacepoint_t>::createSeeds(
0809 const Acts::SeedFinderOptions &options,
0810 const input_container_t &spacePoints) const {
0811 std::vector<seed_t> r;
0812 createSeeds(options, spacePoints, r);
0813 return r;
0814 }
0815
0816 }