File indexing completed on 2025-06-30 07:52:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/TrackFinding/SeedingAlgorithm.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/EventData/Seed.hpp"
0013 #include "Acts/Seeding/SeedFilter.hpp"
0014 #include "Acts/Utilities/Delegate.hpp"
0015 #include "Acts/Utilities/GridBinFinder.hpp"
0016 #include "ActsExamples/EventData/SimSeed.hpp"
0017
0018 #include <cmath>
0019 #include <csignal>
0020 #include <cstddef>
0021 #include <limits>
0022 #include <ostream>
0023 #include <stdexcept>
0024
0025 using namespace Acts::HashedStringLiteral;
0026
0027 namespace ActsExamples {
0028
0029 SeedingAlgorithm::SeedingAlgorithm(SeedingAlgorithm::Config cfg,
0030 Acts::Logging::Level lvl)
0031 : IAlgorithm("SeedingAlgorithm", lvl), m_cfg(std::move(cfg)) {
0032 using SpacePointProxy_type = typename Acts::SpacePointContainer<
0033 SpacePointContainer<std::vector<const SimSpacePoint*>>,
0034 Acts::detail::RefHolder>::SpacePointProxyType;
0035
0036
0037
0038 m_cfg.seedFinderConfig.seedFilter =
0039 std::make_unique<Acts::SeedFilter<SpacePointProxy_type>>(
0040 m_cfg.seedFilterConfig, logger().cloneWithSuffix("SeedFilter"));
0041 m_cfg.seedFinderConfig = m_cfg.seedFinderConfig.calculateDerivedQuantities();
0042 m_cfg.seedFinderOptions = m_cfg.seedFinderOptions.calculateDerivedQuantities(
0043 m_cfg.seedFinderConfig);
0044 if (m_cfg.inputSpacePoints.empty()) {
0045 throw std::invalid_argument("Missing space point input collections");
0046 }
0047
0048 for (const auto& spName : m_cfg.inputSpacePoints) {
0049 if (spName.empty()) {
0050 throw std::invalid_argument("Invalid space point input collection");
0051 }
0052
0053 auto& handle = m_inputSpacePoints.emplace_back(
0054 std::make_unique<ReadDataHandle<SimSpacePointContainer>>(
0055 this,
0056 "InputSpacePoints#" + std::to_string(m_inputSpacePoints.size())));
0057 handle->initialize(spName);
0058 }
0059 if (m_cfg.outputSeeds.empty()) {
0060 throw std::invalid_argument("Missing seeds output collection");
0061 }
0062
0063 m_outputSeeds.initialize(m_cfg.outputSeeds);
0064
0065 if (m_cfg.gridConfig.rMax != m_cfg.seedFinderConfig.rMax &&
0066 m_cfg.allowSeparateRMax == false) {
0067 throw std::invalid_argument(
0068 "Inconsistent config rMax: using different values in gridConfig and "
0069 "seedFinderConfig. If values are intentional set allowSeparateRMax to "
0070 "true");
0071 }
0072
0073 if (m_cfg.seedFilterConfig.deltaRMin != m_cfg.seedFinderConfig.deltaRMin) {
0074 throw std::invalid_argument("Inconsistent config deltaRMin");
0075 }
0076
0077 if (m_cfg.gridConfig.deltaRMax != m_cfg.seedFinderConfig.deltaRMax) {
0078 throw std::invalid_argument("Inconsistent config deltaRMax");
0079 }
0080
0081 static_assert(
0082 std::numeric_limits<
0083 decltype(m_cfg.seedFinderConfig.deltaRMaxTopSP)>::has_quiet_NaN,
0084 "Value of deltaRMaxTopSP must support NaN values");
0085
0086 static_assert(
0087 std::numeric_limits<
0088 decltype(m_cfg.seedFinderConfig.deltaRMinTopSP)>::has_quiet_NaN,
0089 "Value of deltaRMinTopSP must support NaN values");
0090
0091 static_assert(
0092 std::numeric_limits<
0093 decltype(m_cfg.seedFinderConfig.deltaRMaxBottomSP)>::has_quiet_NaN,
0094 "Value of deltaRMaxBottomSP must support NaN values");
0095
0096 static_assert(
0097 std::numeric_limits<
0098 decltype(m_cfg.seedFinderConfig.deltaRMinBottomSP)>::has_quiet_NaN,
0099 "Value of deltaRMinBottomSP must support NaN values");
0100
0101 if (std::isnan(m_cfg.seedFinderConfig.deltaRMaxTopSP)) {
0102 m_cfg.seedFinderConfig.deltaRMaxTopSP = m_cfg.seedFinderConfig.deltaRMax;
0103 }
0104
0105 if (std::isnan(m_cfg.seedFinderConfig.deltaRMinTopSP)) {
0106 m_cfg.seedFinderConfig.deltaRMinTopSP = m_cfg.seedFinderConfig.deltaRMin;
0107 }
0108
0109 if (std::isnan(m_cfg.seedFinderConfig.deltaRMaxBottomSP)) {
0110 m_cfg.seedFinderConfig.deltaRMaxBottomSP = m_cfg.seedFinderConfig.deltaRMax;
0111 }
0112
0113 if (std::isnan(m_cfg.seedFinderConfig.deltaRMinBottomSP)) {
0114 m_cfg.seedFinderConfig.deltaRMinBottomSP = m_cfg.seedFinderConfig.deltaRMin;
0115 }
0116
0117 if (m_cfg.gridConfig.zMin != m_cfg.seedFinderConfig.zMin) {
0118 throw std::invalid_argument("Inconsistent config zMin");
0119 }
0120
0121 if (m_cfg.gridConfig.zMax != m_cfg.seedFinderConfig.zMax) {
0122 throw std::invalid_argument("Inconsistent config zMax");
0123 }
0124
0125 if (m_cfg.seedFilterConfig.maxSeedsPerSpM !=
0126 m_cfg.seedFinderConfig.maxSeedsPerSpM) {
0127 throw std::invalid_argument("Inconsistent config maxSeedsPerSpM");
0128 }
0129
0130 if (m_cfg.gridConfig.cotThetaMax != m_cfg.seedFinderConfig.cotThetaMax) {
0131 throw std::invalid_argument("Inconsistent config cotThetaMax");
0132 }
0133
0134 if (m_cfg.gridConfig.minPt != m_cfg.seedFinderConfig.minPt) {
0135 throw std::invalid_argument("Inconsistent config minPt");
0136 }
0137
0138 if (m_cfg.gridOptions.bFieldInZ != m_cfg.seedFinderOptions.bFieldInZ) {
0139 throw std::invalid_argument("Inconsistent config bFieldInZ");
0140 }
0141
0142 if (m_cfg.gridConfig.zBinEdges.size() - 1 != m_cfg.zBinNeighborsTop.size() &&
0143 m_cfg.zBinNeighborsTop.empty() == false) {
0144 throw std::invalid_argument("Inconsistent config zBinNeighborsTop");
0145 }
0146
0147 if (m_cfg.gridConfig.zBinEdges.size() - 1 !=
0148 m_cfg.zBinNeighborsBottom.size() &&
0149 m_cfg.zBinNeighborsBottom.empty() == false) {
0150 throw std::invalid_argument("Inconsistent config zBinNeighborsBottom");
0151 }
0152
0153 if (!m_cfg.seedFinderConfig.zBinsCustomLooping.empty()) {
0154
0155
0156
0157 for (std::size_t i : m_cfg.seedFinderConfig.zBinsCustomLooping) {
0158 if (i >= m_cfg.gridConfig.zBinEdges.size()) {
0159 throw std::invalid_argument(
0160 "Inconsistent config zBinsCustomLooping does not contain a subset "
0161 "of bins defined by zBinEdges");
0162 }
0163 }
0164 }
0165
0166 if (m_cfg.useExtraCuts) {
0167
0168 m_cfg.seedFinderConfig.spacePointSelector
0169 .connect<itkFastTrackingSPselect>();
0170
0171
0172 m_cfg.seedFinderConfig.experimentCuts.connect<itkFastTrackingCuts>();
0173 }
0174
0175 using SpacePointProxy_type = typename Acts::SpacePointContainer<
0176 SpacePointContainer<std::vector<const SimSpacePoint*>>,
0177 Acts::detail::RefHolder>::SpacePointProxyType;
0178
0179 m_bottomBinFinder = std::make_unique<const Acts::GridBinFinder<3ul>>(
0180 m_cfg.numPhiNeighbors, cfg.zBinNeighborsBottom, 0);
0181 m_topBinFinder = std::make_unique<const Acts::GridBinFinder<3ul>>(
0182 m_cfg.numPhiNeighbors, m_cfg.zBinNeighborsTop, 0);
0183
0184 m_seedFinder =
0185 Acts::SeedFinder<SpacePointProxy_type,
0186 Acts::CylindricalSpacePointGrid<SpacePointProxy_type>>(
0187 m_cfg.seedFinderConfig, logger().cloneWithSuffix("SeedFinder"));
0188 }
0189
0190 ProcessCode SeedingAlgorithm::execute(const AlgorithmContext& ctx) const {
0191
0192
0193
0194 std::size_t nSpacePoints = 0;
0195 for (const auto& isp : m_inputSpacePoints) {
0196 nSpacePoints += (*isp)(ctx).size();
0197 }
0198
0199 std::vector<const SimSpacePoint*> spacePointPtrs;
0200 spacePointPtrs.reserve(nSpacePoints);
0201 for (const auto& isp : m_inputSpacePoints) {
0202 for (const auto& spacePoint : (*isp)(ctx)) {
0203
0204
0205
0206 spacePointPtrs.push_back(&spacePoint);
0207 }
0208 }
0209
0210
0211 Acts::SpacePointContainerConfig spConfig;
0212 spConfig.useDetailedDoubleMeasurementInfo =
0213 m_cfg.seedFinderConfig.useDetailedDoubleMeasurementInfo;
0214
0215 Acts::SpacePointContainerOptions spOptions;
0216 spOptions.beamPos = {0., 0.};
0217
0218
0219 SpacePointContainer container(spacePointPtrs);
0220
0221 Acts::SpacePointContainer<decltype(container), Acts::detail::RefHolder>
0222 spContainer(spConfig, spOptions, container);
0223
0224 using value_type = typename decltype(spContainer)::SpacePointProxyType;
0225 using seed_type = Acts::Seed<value_type>;
0226
0227 Acts::CylindricalSpacePointGrid<value_type> grid =
0228 Acts::CylindricalSpacePointGridCreator::createGrid<value_type>(
0229 m_cfg.gridConfig, m_cfg.gridOptions, logger());
0230
0231 Acts::CylindricalSpacePointGridCreator::fillGrid<value_type>(
0232 m_cfg.seedFinderConfig, m_cfg.seedFinderOptions, grid, spContainer,
0233 logger());
0234
0235
0236
0237
0238 float minRange = std::numeric_limits<float>::max();
0239 float maxRange = std::numeric_limits<float>::lowest();
0240 for (const auto& coll : grid) {
0241 if (coll.empty()) {
0242 continue;
0243 }
0244 const auto* firstEl = coll.front();
0245 const auto* lastEl = coll.back();
0246 minRange = std::min(firstEl->radius(), minRange);
0247 maxRange = std::max(lastEl->radius(), maxRange);
0248 }
0249
0250 std::array<std::vector<std::size_t>, 3ul> navigation;
0251 navigation[1ul] = m_cfg.seedFinderConfig.zBinsCustomLooping;
0252
0253 auto spacePointsGrouping = Acts::CylindricalBinnedGroup<value_type>(
0254 std::move(grid), *m_bottomBinFinder, *m_topBinFinder,
0255 std::move(navigation));
0256
0257
0258 const Acts::Range1D<float> rMiddleSPRange(
0259 std::floor(minRange / 2) * 2 +
0260 m_cfg.seedFinderConfig.deltaRMiddleMinSPRange,
0261 std::floor(maxRange / 2) * 2 -
0262 m_cfg.seedFinderConfig.deltaRMiddleMaxSPRange);
0263
0264
0265 static thread_local std::vector<seed_type> seeds;
0266 seeds.clear();
0267 static thread_local decltype(m_seedFinder)::SeedingState state;
0268 state.spacePointMutableData.resize(spContainer.size());
0269
0270 for (const auto [bottom, middle, top] : spacePointsGrouping) {
0271 m_seedFinder.createSeedsForGroup(m_cfg.seedFinderOptions, state,
0272 spacePointsGrouping.grid(), seeds, bottom,
0273 middle, top, rMiddleSPRange);
0274 }
0275
0276 ACTS_DEBUG("Created " << seeds.size() << " track seeds from "
0277 << spacePointPtrs.size() << " space points");
0278
0279
0280
0281 SimSeedContainer SeedContainerForStorage;
0282 SeedContainerForStorage.reserve(seeds.size());
0283 for (const auto& seed : seeds) {
0284 const auto& sps = seed.sp();
0285 SeedContainerForStorage.emplace_back(*sps[0]->externalSpacePoint(),
0286 *sps[1]->externalSpacePoint(),
0287 *sps[2]->externalSpacePoint());
0288 SeedContainerForStorage.back().setVertexZ(seed.z());
0289 SeedContainerForStorage.back().setQuality(seed.seedQuality());
0290 }
0291
0292 m_outputSeeds(ctx, std::move(SeedContainerForStorage));
0293 return ProcessCode::SUCCESS;
0294 }
0295
0296 }