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