File indexing completed on 2026-07-26 08:18:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Seeding/TripletSeeder.hpp"
0010
0011 #include "Acts/EventData/SpacePointContainer.hpp"
0012 #include "Acts/Seeding/DoubletSeedFinder.hpp"
0013 #include "Acts/Seeding/TripletSeedFinder.hpp"
0014
0015 #include <Eigen/Dense>
0016
0017 namespace Acts {
0018
0019 namespace {
0020
0021 template <typename DoubletCollections>
0022 void createAndFilterTriplets(TripletSeeder::Cache& cache,
0023 const TripletSeedFinder& tripletFinder,
0024 const ITripletSeedFilter& filter,
0025 const SpacePointContainer& spacePoints,
0026 DoubletCollections bottomDoublets,
0027 const ConstSpacePointProxy& spM,
0028 DoubletCollections topDoublets) {
0029 for (auto bottomDoublet : bottomDoublets) {
0030 if (topDoublets.empty()) {
0031 break;
0032 }
0033
0034 cache.tripletTopCandidates.clear();
0035 tripletFinder.createTripletTopCandidates(spacePoints, spM, bottomDoublet,
0036 topDoublets,
0037 cache.tripletTopCandidates);
0038
0039 filter.filterTripletTopCandidates(spacePoints, spM, bottomDoublet,
0040 cache.tripletTopCandidates);
0041 }
0042 }
0043
0044 template <typename SpacePointCollections>
0045 void createSeedsFromGroupsImpl(
0046 const Logger& logger, TripletSeeder::Cache& cache,
0047 const DoubletSeedFinder& bottomFinder, const DoubletSeedFinder& topFinder,
0048 const TripletSeedFinder& tripletFinder, const ITripletSeedFilter& filter,
0049 const SpacePointContainer& spacePoints,
0050 SpacePointCollections& bottomSpGroups, const ConstSpacePointProxy& middleSp,
0051 SpacePointCollections& topSpGroups, SeedContainer& outputSeeds) {
0052 MiddleSpInfo middleSpInfo = DoubletSeedFinder::computeMiddleSpInfo(middleSp);
0053
0054
0055 cache.topDoublets.clear();
0056 for (auto& topSpGroup : topSpGroups) {
0057 topFinder.createDoublets(middleSp, middleSpInfo, topSpGroup,
0058 cache.topDoublets);
0059 }
0060
0061
0062 if (cache.topDoublets.empty()) {
0063 ACTS_VERBOSE("No compatible Tops, returning");
0064 return;
0065 }
0066
0067 if (!filter.sufficientTopDoublets(spacePoints, middleSp, cache.topDoublets)) {
0068 return;
0069 }
0070
0071
0072 cache.bottomDoublets.clear();
0073 for (auto& bottomSpGroup : bottomSpGroups) {
0074 bottomFinder.createDoublets(middleSp, middleSpInfo, bottomSpGroup,
0075 cache.bottomDoublets);
0076 }
0077
0078
0079 if (cache.bottomDoublets.empty()) {
0080 ACTS_VERBOSE("No compatible Bottoms, returning");
0081 return;
0082 }
0083
0084 ACTS_VERBOSE("Candidates: " << cache.bottomDoublets.size() << " bottoms and "
0085 << cache.topDoublets.size()
0086 << " tops for middle candidate indexed "
0087 << middleSp.index());
0088
0089
0090 if (tripletFinder.config().sortedByCotTheta) {
0091 cache.bottomDoublets.sortByCotTheta({0, cache.bottomDoublets.size()},
0092 cache.sortedBottoms);
0093 cache.topDoublets.sortByCotTheta({0, cache.topDoublets.size()},
0094 cache.sortedTops);
0095
0096 createAndFilterTriplets(cache, tripletFinder, filter, spacePoints,
0097 cache.bottomDoublets.subset(cache.sortedBottoms),
0098 middleSp,
0099 cache.topDoublets.subset(cache.sortedTops));
0100 } else {
0101 createAndFilterTriplets(cache, tripletFinder, filter, spacePoints,
0102 cache.bottomDoublets.range(), middleSp,
0103 cache.topDoublets.range());
0104 }
0105
0106 filter.filterTripletsMiddleFixed(spacePoints, outputSeeds);
0107 }
0108
0109 }
0110
0111 TripletSeeder::TripletSeeder(std::unique_ptr<const Logger> logger_)
0112 : m_logger(std::move(logger_)) {
0113 if (m_logger == nullptr) {
0114 throw std::invalid_argument("TripletSeeder: logger cannot be null");
0115 }
0116 }
0117
0118 void TripletSeeder::createSeedsFromGroup(
0119 Cache& cache, const DoubletSeedFinder& bottomFinder,
0120 const DoubletSeedFinder& topFinder, const TripletSeedFinder& tripletFinder,
0121 const ITripletSeedFilter& filter, const SpacePointContainer& spacePoints,
0122 SpacePointContainer::ConstSubset& bottomSps,
0123 const ConstSpacePointProxy& middleSp,
0124 SpacePointContainer::ConstSubset& topSps,
0125 SeedContainer& outputSeeds) const {
0126 assert((bottomFinder.config().spacePointsSortedByRadius ==
0127 topFinder.config().spacePointsSortedByRadius) &&
0128 "Inconsistent space point sorting");
0129
0130 std::array<SpacePointContainer::ConstSubset, 1> bottomSpGroups{bottomSps};
0131 std::array<SpacePointContainer::ConstSubset, 1> topSpGroups{topSps};
0132
0133 createSeedsFromGroupsImpl(*m_logger, cache, bottomFinder, topFinder,
0134 tripletFinder, filter, spacePoints, bottomSpGroups,
0135 middleSp, topSpGroups, outputSeeds);
0136 }
0137
0138 void TripletSeeder::createSeedsFromGroups(
0139 Cache& cache, const DoubletSeedFinder& bottomFinder,
0140 const DoubletSeedFinder& topFinder, const TripletSeedFinder& tripletFinder,
0141 const ITripletSeedFilter& filter, const SpacePointContainer& spacePoints,
0142 const std::span<SpacePointContainer::ConstRange>& bottomSpGroups,
0143 const SpacePointContainer::ConstRange& middleSpGroup,
0144 const std::span<SpacePointContainer::ConstRange>& topSpGroups,
0145 const std::pair<float, float>& radiusRangeForMiddle,
0146 SeedContainer& outputSeeds) const {
0147 assert((bottomFinder.config().spacePointsSortedByRadius ==
0148 topFinder.config().spacePointsSortedByRadius) &&
0149 "Inconsistent space point sorting");
0150 const bool spacePointsSortedByRadius =
0151 bottomFinder.config().spacePointsSortedByRadius;
0152
0153 if (middleSpGroup.empty()) {
0154 return;
0155 }
0156
0157 if (spacePointsSortedByRadius) {
0158
0159
0160
0161 const ConstSpacePointProxy firstMiddleSp = middleSpGroup.front();
0162 const float firstMiddleSpR = firstMiddleSp.zr()[1];
0163
0164 for (auto& bottomSpGroup : bottomSpGroups) {
0165
0166
0167 const auto low = std::ranges::lower_bound(
0168 bottomSpGroup, firstMiddleSpR - bottomFinder.config().deltaRMax, {},
0169 [&](const ConstSpacePointProxy& sp) { return sp.zr()[1]; });
0170 bottomSpGroup = bottomSpGroup.subrange(low - bottomSpGroup.begin());
0171 }
0172
0173 for (auto& topSpGroup : topSpGroups) {
0174
0175
0176 const auto low = std::ranges::lower_bound(
0177 topSpGroup, firstMiddleSpR + topFinder.config().deltaRMin, {},
0178 [&](const ConstSpacePointProxy& sp) { return sp.zr()[1]; });
0179 topSpGroup = topSpGroup.subrange(low - topSpGroup.begin());
0180 }
0181 }
0182
0183 for (ConstSpacePointProxy spM : middleSpGroup) {
0184 const float rM = spM.zr()[1];
0185
0186 if (spacePointsSortedByRadius) {
0187
0188 if (rM < radiusRangeForMiddle.first) {
0189 continue;
0190 }
0191 if (rM > radiusRangeForMiddle.second) {
0192
0193 break;
0194 }
0195 }
0196
0197 createSeedsFromGroupsImpl(*m_logger, cache, bottomFinder, topFinder,
0198 tripletFinder, filter, spacePoints,
0199 bottomSpGroups, spM, topSpGroups, outputSeeds);
0200 }
0201 }
0202
0203 }