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