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