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