diff --git a/Examples/Algorithms/TrackFinding/CMakeLists.txt b/Examples/Algorithms/TrackFinding/CMakeLists.txt index d10e03884d7..162b990c0dc 100644 --- a/Examples/Algorithms/TrackFinding/CMakeLists.txt +++ b/Examples/Algorithms/TrackFinding/CMakeLists.txt @@ -33,7 +33,7 @@ acts_compile_headers(ExamplesTrackFinding GLOB "include/**/*.hpp") if(ACTS_BUILD_EXAMPLES_HASHING) target_sources( ActsExamplesTrackFinding - PRIVATE src/SeedingAlgorithmHashing.cpp + PRIVATE src/HashingPrototypeSeedingAlgorithm.cpp ) target_link_libraries(ActsExamplesTrackFinding PUBLIC Acts::PluginHashing) diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/HashingPrototypeSeedingAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/HashingPrototypeSeedingAlgorithm.hpp new file mode 100644 index 00000000000..cfef534aea4 --- /dev/null +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/HashingPrototypeSeedingAlgorithm.hpp @@ -0,0 +1,303 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Seeding2/BroadTripletSeedFilter.hpp" +#include "Acts/Seeding2/CylindricalSpacePointGrid2.hpp" +#include "Acts/Seeding2/TripletSeeder.hpp" +#include "Acts/Utilities/GridBinFinder.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/EventData/SimSeed.hpp" +#include "ActsExamples/EventData/SimSpacePoint.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" + +#include +#include +#include +#include + +namespace ActsExamples { + +/// Construct track seeds from space points. +class HashingPrototypeSeedingAlgorithm final : public IAlgorithm { + public: + struct Config { + /// Input space point collections. + std::string inputSpacePoints; + /// Output track seed collection. + std::string outputSeeds; + + // General seeding parameters + + /// Magnetic field in z direction + float bFieldInZ = 2 * Acts::UnitConstants::T; + /// minimum pT + float minPt = 0.4 * Acts::UnitConstants::GeV; + /// maximum forward direction expressed as cot(theta) + float cotThetaMax = 10.01788; // equivalent to eta = 3 (pseudorapidity) + /// maximum impact parameter in mm + float impactMax = 20 * Acts::UnitConstants::mm; + /// Minimum radial distance between two doublet components (prefer + /// deltaRMinTop and deltaRMinBottom to set separate values for top and + /// bottom space points) + float deltaRMin = 5 * Acts::UnitConstants::mm; + /// Maximum radial distance between two doublet components (prefer + /// deltaRMaxTop and deltaRMacBottom to set separate values for top and + /// bottom space points) + float deltaRMax = 270 * Acts::UnitConstants::mm; + /// Minimum radial distance between middle-top doublet components + float deltaRMinTop = std::numeric_limits::quiet_NaN(); + /// Maximum radial distance between middle-outer doublet components + float deltaRMaxTop = std::numeric_limits::quiet_NaN(); + /// Minimum radial distance between bottom-middle doublet components + float deltaRMinBottom = std::numeric_limits::quiet_NaN(); + /// Maximum radial distance between bottom-middle doublet components + float deltaRMaxBottom = std::numeric_limits::quiet_NaN(); + + // Seeding parameters used in the space-point grid creation and bin finding + + /// minimum extension of sensitive detector layer relevant for seeding as + /// distance from x=y=0 (i.e. in r) + /// WARNING: if rMin is smaller than impactMax, the bin size will be 2*pi, + /// which will make seeding very slow! + float rMin = 0 * Acts::UnitConstants::mm; + /// maximum extension of sensitive detector layer relevant for seeding as + /// distance from x=y=0 (i.e. in r) + float rMax = 600 * Acts::UnitConstants::mm; + /// minimum extension of sensitive detector layer relevant for seeding in + /// negative direction in z + float zMin = -2800 * Acts::UnitConstants::mm; + /// maximum extension of sensitive detector layer relevant for seeding in + /// positive direction in z + float zMax = 2800 * Acts::UnitConstants::mm; + /// minimum phi value for phiAxis construction + float phiMin = -std::numbers::pi_v; + /// maximum phi value for phiAxis construction + float phiMax = std::numbers::pi_v; + /// Multiplicator for the number of phi-bins. The minimum number of phi-bins + /// depends on min_pt, magnetic field: 2*pi/(minPT particle phi-deflection). + /// phiBinDeflectionCoverage is a multiplier for this number. If + /// numPhiNeighbors (in the configuration of the BinFinders) is configured + /// to return 1 neighbor on either side of the current phi-bin (and you want + /// to cover the full phi-range of minPT), leave this at 1. + int phiBinDeflectionCoverage = 1; + /// maximum number of phi bins + int maxPhiBins = 10000; + + /// vector containing the map of z bins in the top and bottom layers + std::vector> zBinNeighborsTop; + std::vector> zBinNeighborsBottom; + /// number of phiBin neighbors at each side of the current bin that will be + /// used to search for SPs + int numPhiNeighbors = 1; + + /// Vector containing the z-bin edges for non equidistant binning in z + std::vector zBinEdges; + + /// Order of z bins to loop over when searching for SPs + std::vector zBinsCustomLooping; + + // Seeding parameters used to define the region of interest for middle + // space-point + + /// Radial range for middle space-point + /// The range can be defined manually with (rMinMiddle, rMaxMiddle). If + /// useVariableMiddleSPRange is set to false and the vector rRangeMiddleSP + /// is empty, we use (rMinMiddle, rMaxMiddle) to cut the middle space-points + float rMinMiddle = 60 * Acts::UnitConstants::mm; + float rMaxMiddle = 120 * Acts::UnitConstants::mm; + /// If useVariableMiddleSPRange is set to false, the vector rRangeMiddleSP + /// can be used to define a fixed r range for each z bin: {{rMin, rMax}, + /// ...} + bool useVariableMiddleSPRange = false; + /// Range defined in vector for each z bin + std::vector> rRangeMiddleSP; + + float deltaRMiddleMinSPRange = 10 * Acts::UnitConstants::mm; + float deltaRMiddleMaxSPRange = 10 * Acts::UnitConstants::mm; + + // Seeding parameters used to define the cuts on space-point doublets + + /// Minimal value of z-distance between space-points in doublet + float deltaZMin = -std::numeric_limits::infinity(); + /// Maximum value of z-distance between space-points in doublet + float deltaZMax = std::numeric_limits::infinity(); + + // Seed finder doublet cuts + + /// Enable cut on the compatibility between interaction point and doublet, + /// this is an useful approximation to speed up the seeding + bool interactionPointCut = false; + + /// Limiting location of collision region in z-axis used to check if doublet + /// origin is within reasonable bounds + float collisionRegionMin = -150 * Acts::UnitConstants::mm; + float collisionRegionMax = +150 * Acts::UnitConstants::mm; + + /// Parameter which can loosen the tolerance of the track seed to form a + /// helix. This is useful for e.g. misaligned seeding. + float helixCutTolerance = 1; + + // Seed finder triplet cuts + + /// Number of sigmas of scattering angle to be considered in the minimum pT + /// scattering term + float sigmaScattering = 5; + /// Term that accounts for the thickness of scattering medium in radiation + /// lengths in the Lynch & Dahl correction to the Highland equation default + /// is 5% + /// TODO: necessary to make amount of material dependent on detector region? + float radLengthPerSeed = 0.05; + + /// Tolerance parameter used to check the compatibility of space-point + /// coordinates in xyz. This is only used in a detector specific check for + /// strip modules + float toleranceParam = 1.1 * Acts::UnitConstants::mm; + + // Seed filter parameters + + /// Allowed difference in curvature (inverted seed radii) between two + /// compatible seeds + float deltaInvHelixDiameter = 0.00003 * (1 / Acts::UnitConstants::mm); + /// Seed weight/score is increased by this value if a compatible seed has + /// been found. This is the c1 factor in the seed score calculation (w = c1 + /// * Nt - c2 * d0 - c3 * z0) + float compatSeedWeight = 200; + /// The transverse impact parameters (d0) is multiplied by this factor and + /// subtracted from weight. This is the c2 factor in the seed score + /// calculation (w = c1 * Nt - c2 * d0 - c3 * z0) + float impactWeightFactor = 1; + /// The logitudinal impact parameters (z0) is multiplied by this factor and + /// subtracted from weight. This is the c3 factor in the seed score + /// calculation (w = c1 * Nt - c2 * d0 - c3 * z0) + float zOriginWeightFactor = 1; + /// Maximum number (minus one) of accepted seeds per middle space-point + /// In dense environments many seeds may be found per middle space-point + /// Only seeds with the highest weight will be kept if this limit is reached + unsigned int maxSeedsPerSpM = 5; + /// Maximum limit to number of compatible space-point used in score + /// calculation. We increase by c1 the weight calculation for each + /// compatible space-point until we reach compatSeedLimit + std::size_t compatSeedLimit = 2; + + /// Increment in seed weight if the number of compatible seeds is larger + /// than numSeedIncrement, this is used in case of high occupancy scenarios + /// if we want to increase the weight of the seed by seedWeightIncrement + /// when the number of compatible seeds is higher than a certain value + float seedWeightIncrement = 0; + float numSeedIncrement = std::numeric_limits::infinity(); + + /// Enable quality seed confirmation, this is different than default seeding + /// confirmation because it can also be defined for different (r, z) regions + /// of the detector (e.g. forward or central region) by + /// SeedConfirmationRange. Seeds are classified as "high-quality" seeds and + /// normal quality seeds. Normal quality seeds are only selected if no other + /// "high-quality" seeds has been found for that inner-middle doublet. + bool seedConfirmation = false; + /// Contains parameters for central seed confirmation + Acts::SeedConfirmationRangeConfig centralSeedConfirmationRange; + /// Contains parameters for forward seed confirmation + Acts::SeedConfirmationRangeConfig forwardSeedConfirmationRange; + + /// If seedConfirmation is true we classify seeds as "high-quality" seeds. + /// Seeds that are not confirmed as "high-quality" are only selected if no + /// other "high-quality" seed has been found for that inner-middle doublet + /// Maximum number of normal seeds (not classified as "high-quality" seeds) + /// in seed confirmation + std::uint32_t maxSeedsPerSpMConf = 5; + /// Maximum number of "high-quality" seeds for each inner-middle SP-dublet + /// in seed confirmation. If the limit is reached we check if there is a + /// normal quality seed to be replaced + std::uint32_t maxQualitySeedsPerSpMConf = 5; + + /// Use deltaR between top and middle SP instead of top radius to search for + /// compatible SPs + bool useDeltaRinsteadOfTopRadius = false; + + // other + + /// Connect custom selections on the space points or to the doublet + /// compatibility + bool useExtraCuts = false; + + // hashing training + + /// Random seed for Annoy + std::uint32_t annoySeed = 123456789; + + /// Number of features to use + std::int32_t f = 1; + + // hashing inference + + /// Size of the buckets = number of spacepoints in the bucket + std::uint32_t bucketSize = 10; + /// Number of zBins + std::uint32_t zBins = 0; + /// Number of phiBins + std::uint32_t phiBins = 50; + + /// Layer selection + double layerRMin = 25; + double layerRMax = 40; + double layerZMin = -550; + double layerZMax = 550; + }; + + /// Construct the seeding algorithm. + /// + /// @param cfg is the algorithm configuration + /// @param lvl is the logging level + HashingPrototypeSeedingAlgorithm(Config cfg, Acts::Logging::Level lvl); + + /// Run the seeding algorithm. + /// + /// @param ctx is the algorithm context with event information + /// @return a process code indication success or failure + ProcessCode execute(const AlgorithmContext& ctx) const override; + + /// Const access to the config + const Config& config() const { return m_cfg; } + + private: + Config m_cfg; + Acts::CylindricalSpacePointGrid2::Config m_gridConfig; + + std::unique_ptr> m_bottomBinFinder{nullptr}; + std::unique_ptr> m_topBinFinder{nullptr}; + Acts::BroadTripletSeedFilter::Config m_filterConfig; + std::unique_ptr m_filterLogger; + std::optional m_seedFinder; + + Acts::Delegate m_spacePointSelector{ + Acts::DelegateFuncTag{}}; + + static bool voidSpacePointSelector(const SimSpacePoint& /*sp*/) { + return true; + } + + ReadDataHandle m_inputSpacePoints{this, + "InputSpacePoints"}; + + WriteDataHandle m_outputSeeds{this, "OutputSeeds"}; + + /// Get the proper radius validity range given a middle space point candidate. + /// In case the radius range changes according to the z-bin we need to + /// retrieve the proper range. We can do this computation only once, since all + /// the middle space point candidates belong to the same z-bin + /// @param spM space point candidate to be used as middle SP in a seed + /// @param rMiddleSPRange range object containing the minimum and maximum r for middle SP for a certain z bin + std::pair retrieveRadiusRangeForMiddle( + const Acts::ConstSpacePointProxy2& spM, + const Acts::Range1D& rMiddleSPRange) const; +}; + +} // namespace ActsExamples diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/SeedingAlgorithmHashing.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/SeedingAlgorithmHashing.hpp deleted file mode 100644 index 6fb824a7233..00000000000 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/SeedingAlgorithmHashing.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -#include "Acts/EventData/SpacePointContainer.hpp" -#include "Acts/Seeding/SeedFilter.hpp" -#include "Acts/Seeding/SeedFilterConfig.hpp" -#include "Acts/Seeding/SeedFinder.hpp" -#include "Acts/Seeding/SeedFinderConfig.hpp" -#include "Acts/Seeding/detail/CylindricalSpacePointGrid.hpp" -#include "Acts/Utilities/GridBinFinder.hpp" -#include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/EventData/SimSeed.hpp" -#include "ActsExamples/EventData/SimSpacePoint.hpp" -#include "ActsExamples/EventData/SpacePointContainer.hpp" -#include "ActsExamples/Framework/DataHandle.hpp" -#include "ActsExamples/Framework/IAlgorithm.hpp" -#include "ActsExamples/Framework/ProcessCode.hpp" -#include "ActsPlugins/Hashing/HashingAlgorithm.hpp" -#include "ActsPlugins/Hashing/HashingAlgorithmConfig.hpp" -#include "ActsPlugins/Hashing/HashingTraining.hpp" -#include "ActsPlugins/Hashing/HashingTrainingConfig.hpp" - -#include -#include -#include -#include - -namespace ActsExamples { - -/// Construct track seeds from space points. -class SeedingAlgorithmHashing final : public IAlgorithm { - public: - struct Config { - /// Input space point collections. - /// - /// We allow multiple space point collections to allow different parts of - /// the detector to use different algorithms for space point construction, - /// e.g. single-hit space points for pixel-like detectors or double-hit - /// space points for strip-like detectors. - std::vector inputSpacePoints; - /// Output track seed collection. - std::string outputSeeds; - /// Output space point buckets. - std::string outputBuckets; - - Acts::SeedFilterConfig seedFilterConfig; - Acts::SeedFinderConfig>, - Acts::detail::RefHolder>::SpacePointProxyType> - seedFinderConfig; - - Acts::CylindricalSpacePointGridConfig gridConfig; - Acts::CylindricalSpacePointGridOptions gridOptions; - Acts::SeedFinderOptions seedFinderOptions; - ActsPlugins::HashingAlgorithmConfig hashingConfig; - ActsPlugins::HashingTrainingConfig hashingTrainingConfig; - - // allow for different values of rMax in gridConfig and seedFinderConfig - bool allowSeparateRMax = false; - - // vector containing the map of z bins in the top and bottom layers - std::vector> zBinNeighborsTop; - std::vector> zBinNeighborsBottom; - // number of phiBin neighbors at each side of the current bin that will be - // used to search for SPs - int numPhiNeighbors = 1; - }; - - /// Construct the seeding algorithm. - /// - /// @param cfg is the algorithm configuration - /// @param lvl is the logging level - SeedingAlgorithmHashing(Config cfg, Acts::Logging::Level lvl); - - /// Run the seeding algorithm. - /// - /// @param ctx is the algorithm context with event information - /// @return a process code indication success or failure - ProcessCode execute(const AlgorithmContext& ctx) const override; - - /// Const access to the config - const Config& config() const { return m_cfg; } - - private: - using SpacePointProxy_t = typename Acts::SpacePointContainer< - ActsExamples::SpacePointContainer>, - Acts::detail::RefHolder>::SpacePointProxyType; - - Acts::SeedFinder> - m_seedFinder; - std::unique_ptr> m_bottomBinFinder{nullptr}; - std::unique_ptr> m_topBinFinder{nullptr}; - - Config m_cfg; - - std::vector>> - m_inputSpacePoints{}; - - WriteDataHandle m_outputSeeds{this, "OutputSeeds"}; - WriteDataHandle> m_outputBuckets{ - this, "OutputBuckets"}; - ActsPlugins::HashingAlgorithm> - m_hashing; - ActsPlugins::HashingTrainingAlgorithm> - m_hashingTraining; -}; - -} // namespace ActsExamples diff --git a/Examples/Algorithms/TrackFinding/src/HashingPrototypeSeedingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/HashingPrototypeSeedingAlgorithm.cpp new file mode 100644 index 00000000000..4ec0c4b04a5 --- /dev/null +++ b/Examples/Algorithms/TrackFinding/src/HashingPrototypeSeedingAlgorithm.cpp @@ -0,0 +1,381 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsExamples/TrackFinding/HashingPrototypeSeedingAlgorithm.hpp" + +#include "Acts/Definitions/Direction.hpp" +#include "Acts/EventData/SeedContainer2.hpp" +#include "Acts/EventData/SourceLink.hpp" +#include "Acts/EventData/SpacePointContainer2.hpp" +#include "Acts/EventData/Types.hpp" +#include "Acts/Seeding2/BroadTripletSeedFilter.hpp" +#include "Acts/Seeding2/DoubletSeedFinder.hpp" +#include "Acts/Seeding2/TripletSeedFinder.hpp" +#include "Acts/Utilities/Delegate.hpp" +#include "ActsExamples/EventData/SimSeed.hpp" +#include "ActsExamples/EventData/SimSpacePoint.hpp" + +#include +#include +#include +#include + +namespace ActsExamples { + +namespace { + +static inline bool itkFastTrackingCuts( + const Acts::ConstSpacePointProxy2& /*middle*/, + const Acts::ConstSpacePointProxy2& other, float cotTheta, + bool isBottomCandidate) { + static float rMin = 45; + static float cotThetaMax = 1.5; + + if (isBottomCandidate && other.zr()[1] < rMin && + (cotTheta > cotThetaMax || cotTheta < -cotThetaMax)) { + return false; + } + return true; +} + +static inline bool itkFastTrackingSPselect(const SimSpacePoint& sp) { + // At small r we remove points beyond |z| > 200. + float r = sp.r(); + float zabs = std::abs(sp.z()); + if (zabs > 200. && r < 45.) { + return false; + } + + // Remove space points beyond eta=4 if their z is larger than the max seed + // z0 (150.) + float cotTheta = 27.2899; // corresponds to eta=4 + if ((zabs - 150.) > cotTheta * r) { + return false; + } + return true; +} + +// Custom seed comparison function +template +struct SeedComparison { + bool operator()(const Acts::Seed& seed1, + const Acts::Seed& seed2) const { + const auto& sp1 = seed1.sp(); + const auto& sp2 = seed2.sp(); + + for (std::size_t i = 0; i < sp1.size(); ++i) { + if (sp1[i]->z() != sp2[i]->z()) { + return sp1[i]->z() < sp2[i]->z(); + } + } + + for (std::size_t i = 0; i < sp1.size(); ++i) { + if (sp1[i]->x() != sp2[i]->x()) { + return sp1[i]->x() < sp2[i]->x(); + } + } + + for (std::size_t i = 0; i < sp1.size(); ++i) { + if (sp1[i]->y() != sp2[i]->y()) { + return sp1[i]->y() < sp2[i]->y(); + } + } + + return false; + } +}; + +} // namespace + +HashingPrototypeSeedingAlgorithm::HashingPrototypeSeedingAlgorithm( + Config cfg, Acts::Logging::Level lvl) + : IAlgorithm("HashingPrototypeSeedingAlgorithm", lvl), + m_cfg(std::move(cfg)) { + m_inputSpacePoints.initialize(m_cfg.inputSpacePoints); + m_outputSeeds.initialize(m_cfg.outputSeeds); + + // check that the bins required in the custom bin looping + // are contained in the bins defined by the total number of edges + for (std::size_t i : m_cfg.zBinsCustomLooping) { + if (i >= m_cfg.zBinEdges.size()) { + throw std::invalid_argument( + "Inconsistent config zBinsCustomLooping does not contain a subset " + "of bins defined by zBinEdges"); + } + } + + if (m_cfg.useExtraCuts) { + // This function will be applied to select space points during grid filling + m_spacePointSelector.connect(); + } + + m_gridConfig.minPt = m_cfg.minPt; + // TODO switch to `m_cfg.rMin` + m_gridConfig.rMin = 0; + m_gridConfig.rMax = m_cfg.rMax; + m_gridConfig.zMin = m_cfg.zMin; + m_gridConfig.zMax = m_cfg.zMax; + m_gridConfig.deltaRMax = m_cfg.deltaRMax; + m_gridConfig.cotThetaMax = m_cfg.cotThetaMax; + m_gridConfig.impactMax = m_cfg.impactMax; + m_gridConfig.phiMin = m_cfg.phiMin; + m_gridConfig.phiMax = m_cfg.phiMax; + m_gridConfig.phiBinDeflectionCoverage = m_cfg.phiBinDeflectionCoverage; + m_gridConfig.maxPhiBins = m_cfg.maxPhiBins; + m_gridConfig.rBinEdges = {}; + m_gridConfig.zBinEdges = m_cfg.zBinEdges; + m_gridConfig.bFieldInZ = m_cfg.bFieldInZ; + m_gridConfig.bottomBinFinder.emplace(m_cfg.numPhiNeighbors, + m_cfg.zBinNeighborsBottom, 0); + m_gridConfig.topBinFinder.emplace(m_cfg.numPhiNeighbors, + m_cfg.zBinNeighborsTop, 0); + m_gridConfig.navigation[0ul] = {}; + m_gridConfig.navigation[1ul] = m_cfg.zBinsCustomLooping; + m_gridConfig.navigation[2ul] = {}; + + m_filterConfig.deltaInvHelixDiameter = m_cfg.deltaInvHelixDiameter; + m_filterConfig.deltaRMin = m_cfg.deltaRMin; + m_filterConfig.compatSeedWeight = m_cfg.compatSeedWeight; + m_filterConfig.impactWeightFactor = m_cfg.impactWeightFactor; + m_filterConfig.zOriginWeightFactor = m_cfg.zOriginWeightFactor; + m_filterConfig.maxSeedsPerSpM = m_cfg.maxSeedsPerSpM; + m_filterConfig.compatSeedLimit = m_cfg.compatSeedLimit; + m_filterConfig.seedWeightIncrement = m_cfg.seedWeightIncrement; + m_filterConfig.numSeedIncrement = m_cfg.numSeedIncrement; + m_filterConfig.seedConfirmation = m_cfg.seedConfirmation; + m_filterConfig.centralSeedConfirmationRange = + m_cfg.centralSeedConfirmationRange; + m_filterConfig.forwardSeedConfirmationRange = + m_cfg.forwardSeedConfirmationRange; + m_filterConfig.maxSeedsPerSpMConf = m_cfg.maxSeedsPerSpMConf; + m_filterConfig.maxQualitySeedsPerSpMConf = m_cfg.maxQualitySeedsPerSpMConf; + m_filterConfig.useDeltaRinsteadOfTopRadius = + m_cfg.useDeltaRinsteadOfTopRadius; + + m_filterLogger = logger().cloneWithSuffix("Filter"); + + m_seedFinder = Acts::TripletSeeder(logger().cloneWithSuffix("Finder")); +} + +ProcessCode HashingPrototypeSeedingAlgorithm::execute( + const AlgorithmContext& ctx) const { + const SimSpacePointContainer& spacePoints = m_inputSpacePoints(ctx); + + Acts::CylindricalSpacePointGrid2 grid(m_gridConfig, + logger().cloneWithSuffix("Grid")); + + for (std::size_t i = 0; i < spacePoints.size(); ++i) { + const auto& sp = spacePoints[i]; + + // check if the space point passes the selection + if (!m_spacePointSelector(sp)) { + continue; + } + + float phi = std::atan2(sp.y(), sp.x()); + grid.insert(i, phi, sp.z(), sp.r()); + } + + for (std::size_t i = 0; i < grid.numberOfBins(); ++i) { + std::ranges::sort(grid.at(i), [&](const Acts::SpacePointIndex2& a, + const Acts::SpacePointIndex2& b) { + return spacePoints[a].r() < spacePoints[b].r(); + }); + } + + Acts::SpacePointContainer2 coreSpacePoints( + Acts::SpacePointColumns::SourceLinks | Acts::SpacePointColumns::XY | + Acts::SpacePointColumns::ZR | Acts::SpacePointColumns::VarianceZ | + Acts::SpacePointColumns::VarianceR); + coreSpacePoints.reserve(grid.numberOfSpacePoints()); + std::vector gridSpacePointRanges; + gridSpacePointRanges.reserve(grid.numberOfBins()); + for (std::size_t i = 0; i < grid.numberOfBins(); ++i) { + std::uint32_t begin = coreSpacePoints.size(); + for (Acts::SpacePointIndex2 spIndex : grid.at(i)) { + const SimSpacePoint& sp = spacePoints[spIndex]; + + auto newSp = coreSpacePoints.createSpacePoint(); + newSp.assignSourceLinks( + std::array{Acts::SourceLink(&sp)}); + newSp.xy() = std::array{static_cast(sp.x()), + static_cast(sp.y())}; + newSp.zr() = std::array{static_cast(sp.z()), + static_cast(sp.r())}; + newSp.varianceZ() = static_cast(sp.varianceZ()); + newSp.varianceR() = static_cast(sp.varianceR()); + } + std::uint32_t end = coreSpacePoints.size(); + gridSpacePointRanges.emplace_back(begin, end); + } + + // Compute radius range. We rely on the fact the grid is storing the proxies + // with a sorting in the radius + const Acts::Range1D rRange = [&]() -> Acts::Range1D { + float minRange = std::numeric_limits::max(); + float maxRange = std::numeric_limits::lowest(); + for (const Acts::SpacePointIndexRange2& range : gridSpacePointRanges) { + if (range.first == range.second) { + continue; + } + auto first = coreSpacePoints[range.first]; + auto last = coreSpacePoints[range.second - 1]; + minRange = std::min(first.zr()[1], minRange); + maxRange = std::max(last.zr()[1], maxRange); + } + return {minRange, maxRange}; + }(); + + Acts::DoubletSeedFinder::Config bottomDoubletFinderConfig; + bottomDoubletFinderConfig.spacePointsSortedByRadius = true; + bottomDoubletFinderConfig.candidateDirection = Acts::Direction::Backward(); + bottomDoubletFinderConfig.deltaRMin = std::isnan(m_cfg.deltaRMaxBottom) + ? m_cfg.deltaRMin + : m_cfg.deltaRMinBottom; + bottomDoubletFinderConfig.deltaRMax = std::isnan(m_cfg.deltaRMaxBottom) + ? m_cfg.deltaRMax + : m_cfg.deltaRMaxBottom; + bottomDoubletFinderConfig.deltaZMin = m_cfg.deltaZMin; + bottomDoubletFinderConfig.deltaZMax = m_cfg.deltaZMax; + bottomDoubletFinderConfig.impactMax = m_cfg.impactMax; + bottomDoubletFinderConfig.interactionPointCut = m_cfg.interactionPointCut; + bottomDoubletFinderConfig.collisionRegionMin = m_cfg.collisionRegionMin; + bottomDoubletFinderConfig.collisionRegionMax = m_cfg.collisionRegionMax; + bottomDoubletFinderConfig.cotThetaMax = m_cfg.cotThetaMax; + bottomDoubletFinderConfig.minPt = m_cfg.minPt; + bottomDoubletFinderConfig.helixCutTolerance = m_cfg.helixCutTolerance; + if (m_cfg.useExtraCuts) { + bottomDoubletFinderConfig.experimentCuts.connect(); + } + auto bottomDoubletFinder = + Acts::DoubletSeedFinder::create(Acts::DoubletSeedFinder::DerivedConfig( + bottomDoubletFinderConfig, m_cfg.bFieldInZ)); + + Acts::DoubletSeedFinder::Config topDoubletFinderConfig = + bottomDoubletFinderConfig; + topDoubletFinderConfig.candidateDirection = Acts::Direction::Forward(); + topDoubletFinderConfig.deltaRMin = + std::isnan(m_cfg.deltaRMaxTop) ? m_cfg.deltaRMin : m_cfg.deltaRMinTop; + topDoubletFinderConfig.deltaRMax = + std::isnan(m_cfg.deltaRMaxTop) ? m_cfg.deltaRMax : m_cfg.deltaRMaxTop; + auto topDoubletFinder = + Acts::DoubletSeedFinder::create(Acts::DoubletSeedFinder::DerivedConfig( + topDoubletFinderConfig, m_cfg.bFieldInZ)); + + Acts::TripletSeedFinder::Config tripletFinderConfig; + tripletFinderConfig.useStripInfo = false; + tripletFinderConfig.sortedByCotTheta = true; + tripletFinderConfig.minPt = m_cfg.minPt; + tripletFinderConfig.sigmaScattering = m_cfg.sigmaScattering; + tripletFinderConfig.radLengthPerSeed = m_cfg.radLengthPerSeed; + tripletFinderConfig.impactMax = m_cfg.impactMax; + tripletFinderConfig.helixCutTolerance = m_cfg.helixCutTolerance; + tripletFinderConfig.toleranceParam = m_cfg.toleranceParam; + auto tripletFinder = + Acts::TripletSeedFinder::create(Acts::TripletSeedFinder::DerivedConfig( + tripletFinderConfig, m_cfg.bFieldInZ)); + + // variable middle SP radial region of interest + Acts::Range1D rMiddleSpRange = { + std::floor(rRange.min() / 2) * 2 + m_cfg.deltaRMiddleMinSPRange, + std::floor(rRange.max() / 2) * 2 - m_cfg.deltaRMiddleMaxSPRange}; + + // run the seeding + Acts::SeedContainer2 seeds; + Acts::BroadTripletSeedFilter::State filterState; + Acts::BroadTripletSeedFilter::Cache filterCache; + Acts::BroadTripletSeedFilter seedFilter(m_filterConfig, filterState, + filterCache, *m_filterLogger); + static thread_local Acts::TripletSeeder::Cache cache; + + std::vector bottomSpRanges; + std::optional middleSpRange; + std::vector topSpRanges; + + for (const auto [bottom, middle, top] : grid.binnedGroup()) { + ACTS_VERBOSE("Process middle " << middle); + + bottomSpRanges.clear(); + for (const auto b : bottom) { + bottomSpRanges.push_back( + coreSpacePoints.range(gridSpacePointRanges.at(b)).asConst()); + } + middleSpRange = + coreSpacePoints.range(gridSpacePointRanges.at(middle)).asConst(); + topSpRanges.clear(); + for (const auto t : top) { + topSpRanges.push_back( + coreSpacePoints.range(gridSpacePointRanges.at(t)).asConst()); + } + + if (middleSpRange->empty()) { + ACTS_DEBUG("No middle space points in this group, skipping"); + continue; + } + + // we compute this here since all middle space point candidates belong to + // the same z-bin + Acts::ConstSpacePointProxy2 firstMiddleSp = middleSpRange->front(); + std::pair radiusRangeForMiddle = + retrieveRadiusRangeForMiddle(firstMiddleSp, rMiddleSpRange); + ACTS_VERBOSE("Validity range (radius) for the middle space point is [" + << radiusRangeForMiddle.first << ", " + << radiusRangeForMiddle.second << "]"); + + m_seedFinder->createSeedsFromGroups( + cache, *bottomDoubletFinder, *topDoubletFinder, *tripletFinder, + seedFilter, coreSpacePoints, bottomSpRanges, *middleSpRange, + topSpRanges, radiusRangeForMiddle, seeds); + } + + ACTS_DEBUG("Created " << seeds.size() << " track seeds from " + << spacePoints.size() << " space points"); + + // we have seeds of proxies + // convert them to seed of external space points + SimSeedContainer seedContainerForStorage; + seedContainerForStorage.reserve(seeds.size()); + for (const auto& seed : seeds) { + auto sps = seed.spacePointIndices(); + seedContainerForStorage.emplace_back(*coreSpacePoints.at(sps[0]) + .sourceLinks()[0] + .get(), + *coreSpacePoints.at(sps[1]) + .sourceLinks()[0] + .get(), + *coreSpacePoints.at(sps[2]) + .sourceLinks()[0] + .get()); + seedContainerForStorage.back().setVertexZ(seed.vertexZ()); + seedContainerForStorage.back().setQuality(seed.quality()); + } + + m_outputSeeds(ctx, std::move(seedContainerForStorage)); + return ProcessCode::SUCCESS; +} + +std::pair +HashingPrototypeSeedingAlgorithm::retrieveRadiusRangeForMiddle( + const Acts::ConstSpacePointProxy2& spM, + const Acts::Range1D& rMiddleSpRange) const { + if (m_cfg.useVariableMiddleSPRange) { + return {rMiddleSpRange.min(), rMiddleSpRange.max()}; + } + if (m_cfg.rRangeMiddleSP.empty()) { + return {m_cfg.rMinMiddle, m_cfg.rMaxMiddle}; + } + + // get zBin position of the middle SP + auto pVal = std::ranges::lower_bound(m_cfg.zBinEdges, spM.zr()[0]); + std::size_t zBin = std::distance(m_cfg.zBinEdges.begin(), pVal); + // protects against zM at the limit of zBinEdges + zBin == 0 ? zBin : --zBin; + return {m_cfg.rRangeMiddleSP[zBin][0], m_cfg.rRangeMiddleSP[zBin][1]}; +} + +} // namespace ActsExamples diff --git a/Examples/Algorithms/TrackFinding/src/SeedingAlgorithmHashing.cpp b/Examples/Algorithms/TrackFinding/src/SeedingAlgorithmHashing.cpp deleted file mode 100644 index db4e8c44967..00000000000 --- a/Examples/Algorithms/TrackFinding/src/SeedingAlgorithmHashing.cpp +++ /dev/null @@ -1,356 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#include "ActsExamples/TrackFinding/SeedingAlgorithmHashing.hpp" - -#include "Acts/Definitions/Algebra.hpp" -#include "Acts/EventData/Seed.hpp" -#include "ActsPlugins/Hashing/HashingAlgorithm.hpp" -#include "ActsPlugins/Hashing/HashingTraining.hpp" - -namespace ActsExamples { - -namespace { - -// Custom seed comparison function -template -struct SeedComparison { - bool operator()(const Acts::Seed& seed1, - const Acts::Seed& seed2) const { - const auto& sp1 = seed1.sp(); - const auto& sp2 = seed2.sp(); - - for (std::size_t i = 0; i < sp1.size(); ++i) { - if (sp1[i]->z() != sp2[i]->z()) { - return sp1[i]->z() < sp2[i]->z(); - } - } - - for (std::size_t i = 0; i < sp1.size(); ++i) { - if (sp1[i]->x() != sp2[i]->x()) { - return sp1[i]->x() < sp2[i]->x(); - } - } - - for (std::size_t i = 0; i < sp1.size(); ++i) { - if (sp1[i]->y() != sp2[i]->y()) { - return sp1[i]->y() < sp2[i]->y(); - } - } - - return false; - } -}; - -} // namespace - -SeedingAlgorithmHashing::SeedingAlgorithmHashing( - SeedingAlgorithmHashing::Config cfg, Acts::Logging::Level lvl) - : IAlgorithm("SeedingAlgorithmHashing", lvl), m_cfg(std::move(cfg)) { - using SpacePointProxy_type = typename Acts::SpacePointContainer< - SpacePointContainer>, - Acts::detail::RefHolder>::SpacePointProxyType; - - // Seed Finder config requires Seed Filter object before conversion to - // internal units - m_cfg.seedFinderConfig.seedFilter = - std::make_unique>( - m_cfg.seedFilterConfig); - - m_cfg.seedFinderConfig = m_cfg.seedFinderConfig.calculateDerivedQuantities(); - m_cfg.seedFinderOptions = m_cfg.seedFinderOptions.calculateDerivedQuantities( - m_cfg.seedFinderConfig); - if (m_cfg.inputSpacePoints.empty()) { - throw std::invalid_argument("Missing space point input collections"); - } - - for (const auto& spName : m_cfg.inputSpacePoints) { - if (spName.empty()) { - throw std::invalid_argument("Invalid space point input collection"); - } - - auto& handle = m_inputSpacePoints.emplace_back( - std::make_unique>( - this, - "InputSpacePoints#" + std::to_string(m_inputSpacePoints.size()))); - handle->initialize(spName); - } - if (m_cfg.outputSeeds.empty()) { - throw std::invalid_argument("Missing seeds output collection"); - } - - m_outputSeeds.initialize(m_cfg.outputSeeds); - m_outputBuckets.initialize(m_cfg.outputBuckets); - - if (m_cfg.gridConfig.rMax != m_cfg.seedFinderConfig.rMax && - m_cfg.allowSeparateRMax == false) { - throw std::invalid_argument( - "Inconsistent config rMax: using different values in gridConfig and " - "seedFinderConfig. If values are intentional set allowSeparateRMax to " - "true"); - } - - if (m_cfg.seedFilterConfig.deltaRMin != m_cfg.seedFinderConfig.deltaRMin) { - throw std::invalid_argument("Inconsistent config deltaRMin"); - } - - if (m_cfg.gridConfig.deltaRMax != m_cfg.seedFinderConfig.deltaRMax) { - throw std::invalid_argument("Inconsistent config deltaRMax"); - } - - static_assert( - std::numeric_limits< - decltype(m_cfg.seedFinderConfig.deltaRMaxTopSP)>::has_quiet_NaN, - "Value of deltaRMaxTopSP must support NaN values"); - - static_assert( - std::numeric_limits< - decltype(m_cfg.seedFinderConfig.deltaRMinTopSP)>::has_quiet_NaN, - "Value of deltaRMinTopSP must support NaN values"); - - static_assert( - std::numeric_limits< - decltype(m_cfg.seedFinderConfig.deltaRMaxBottomSP)>::has_quiet_NaN, - "Value of deltaRMaxBottomSP must support NaN values"); - - static_assert( - std::numeric_limits< - decltype(m_cfg.seedFinderConfig.deltaRMinBottomSP)>::has_quiet_NaN, - "Value of deltaRMinBottomSP must support NaN values"); - - if (std::isnan(m_cfg.seedFinderConfig.deltaRMaxTopSP)) { - m_cfg.seedFinderConfig.deltaRMaxTopSP = m_cfg.seedFinderConfig.deltaRMax; - } - - if (std::isnan(m_cfg.seedFinderConfig.deltaRMinTopSP)) { - m_cfg.seedFinderConfig.deltaRMinTopSP = m_cfg.seedFinderConfig.deltaRMin; - } - - if (std::isnan(m_cfg.seedFinderConfig.deltaRMaxBottomSP)) { - m_cfg.seedFinderConfig.deltaRMaxBottomSP = m_cfg.seedFinderConfig.deltaRMax; - } - - if (std::isnan(m_cfg.seedFinderConfig.deltaRMinBottomSP)) { - m_cfg.seedFinderConfig.deltaRMinBottomSP = m_cfg.seedFinderConfig.deltaRMin; - } - - if (m_cfg.gridConfig.zMin != m_cfg.seedFinderConfig.zMin) { - throw std::invalid_argument("Inconsistent config zMin"); - } - - if (m_cfg.gridConfig.zMax != m_cfg.seedFinderConfig.zMax) { - throw std::invalid_argument("Inconsistent config zMax"); - } - - if (m_cfg.seedFilterConfig.maxSeedsPerSpM != - m_cfg.seedFinderConfig.maxSeedsPerSpM) { - throw std::invalid_argument("Inconsistent config maxSeedsPerSpM"); - } - - if (m_cfg.gridConfig.cotThetaMax != m_cfg.seedFinderConfig.cotThetaMax) { - throw std::invalid_argument("Inconsistent config cotThetaMax"); - } - - if (m_cfg.gridConfig.minPt != m_cfg.seedFinderConfig.minPt) { - throw std::invalid_argument("Inconsistent config minPt"); - } - - if (m_cfg.gridOptions.bFieldInZ != m_cfg.seedFinderOptions.bFieldInZ) { - throw std::invalid_argument("Inconsistent config bFieldInZ"); - } - - if (m_cfg.gridConfig.zBinEdges.size() - 1 != m_cfg.zBinNeighborsTop.size() && - m_cfg.zBinNeighborsTop.empty() == false) { - throw std::invalid_argument("Inconsistent config zBinNeighborsTop"); - } - - if (m_cfg.gridConfig.zBinEdges.size() - 1 != - m_cfg.zBinNeighborsBottom.size() && - m_cfg.zBinNeighborsBottom.empty() == false) { - throw std::invalid_argument("Inconsistent config zBinNeighborsBottom"); - } - - m_bottomBinFinder = std::make_unique>( - m_cfg.numPhiNeighbors, m_cfg.zBinNeighborsBottom, 0); - m_topBinFinder = std::make_unique>( - m_cfg.numPhiNeighbors, m_cfg.zBinNeighborsTop, 0); - - m_cfg.seedFinderConfig.seedFilter = - std::make_unique>( - m_cfg.seedFilterConfig); - m_seedFinder = - Acts::SeedFinder>( - m_cfg.seedFinderConfig); - m_hashing = ActsPlugins::HashingAlgorithm>( - m_cfg.hashingConfig); - m_hashingTraining = - ActsPlugins::HashingTrainingAlgorithm>( - m_cfg.hashingTrainingConfig); -} - -ProcessCode SeedingAlgorithmHashing::execute( - const AlgorithmContext& ctx) const { - ACTS_DEBUG("Start of SeedingAlgorithmHashing execute"); - using SpacePointPtrVector = std::vector; - - // construct the combined input container of space point pointers from all - // configured input sources. - // pre-compute the total size required so we only need to allocate once - std::size_t nSpacePoints = 0; - for (const auto& isp : m_inputSpacePoints) { - nSpacePoints += (*isp)(ctx).size(); - } - - SpacePointPtrVector spacePointPtrs; - spacePointPtrs.reserve(nSpacePoints); - for (const auto& isp : m_inputSpacePoints) { - for (const SimSpacePoint& spacePoint : (*isp)(ctx)) { - // since the event store owns the space - // points, their pointers should be stable and - // we do not need to create local copies. - spacePointPtrs.push_back(&spacePoint); - } - } - - // Config - Acts::SpacePointContainerConfig spConfig; - spConfig.useDetailedDoubleMeasurementInfo = - m_cfg.seedFinderConfig.useDetailedDoubleMeasurementInfo; - // Options - Acts::SpacePointContainerOptions spOptions; - spOptions.beamPos = {0., 0.}; - - // Hashing Training - ActsPlugins::AnnoyModel annoyModel = - m_hashingTraining.execute(spacePointPtrs); - // Hashing - static thread_local std::vector bucketsPtrs; - bucketsPtrs.clear(); - m_hashing.execute(spacePointPtrs, &annoyModel, bucketsPtrs); - - // pre-compute the maximum size required so we only need to allocate once - // doesn't combine the input containers of space point pointers - std::size_t maxNSpacePoints = 0; - std::size_t inSpacePoints = 0; - for (const SpacePointPtrVector& bucket : bucketsPtrs) { - inSpacePoints = bucket.size(); - if (inSpacePoints > maxNSpacePoints) { - maxNSpacePoints = inSpacePoints; - } - } - - using value_type = typename Acts::SpacePointContainer< - SpacePointContainer>, - Acts::detail::RefHolder>::SpacePointProxyType; - using seed_type = Acts::Seed; - - // Create the set with custom comparison function - static thread_local std::set> seedsSet; - seedsSet.clear(); - static thread_local decltype(m_seedFinder)::SeedingState state; - state.spacePointMutableData.resize(maxNSpacePoints); - - for (SpacePointPtrVector& bucket : bucketsPtrs) { - std::set> seedsSetForBucket; - state.spacePointMutableData.clear(); - state.spacePointMutableData.resize(maxNSpacePoints); - - // Prepare interface SpacePoint backend-ACTS - SpacePointContainer container(bucket); - // Prepare Acts API - Acts::SpacePointContainer - spContainer(spConfig, spOptions, container); - - // construct the seeding tools - Acts::CylindricalSpacePointGrid grid = - Acts::CylindricalSpacePointGridCreator::createGrid( - m_cfg.gridConfig, m_cfg.gridOptions); - Acts::CylindricalSpacePointGridCreator::fillGrid( - m_cfg.seedFinderConfig, m_cfg.seedFinderOptions, grid, - spContainer.begin(), spContainer.end()); - - // Compute radius Range - // we rely on the fact the grid is storing the proxies - // with a sorting in the radius - float minRange = std::numeric_limits::max(); - float maxRange = std::numeric_limits::lowest(); - for (const auto& coll : grid) { - if (coll.empty()) { - continue; - } - const auto* firstEl = coll.front(); - const auto* lastEl = coll.back(); - minRange = std::min(firstEl->radius(), minRange); - maxRange = std::max(lastEl->radius(), maxRange); - } - - std::array, 3ul> navigation; - navigation[1ul] = m_cfg.seedFinderConfig.zBinsCustomLooping; - - // groups spacepoints - auto spacePointsGrouping = Acts::CylindricalBinnedGroup( - std::move(grid), *m_bottomBinFinder, *m_topBinFinder, - std::move(navigation)); - - /// variable middle SP radial region of interest - const Acts::Range1D rMiddleSPRange( - minRange + m_cfg.seedFinderConfig.deltaRMiddleMinSPRange, - maxRange - m_cfg.seedFinderConfig.deltaRMiddleMaxSPRange); - - // this creates seeds of proxy, we need to convert it to seed of space - // points - for (const auto [bottom, middle, top] : spacePointsGrouping) { - m_seedFinder.createSeedsForGroup( - m_cfg.seedFinderOptions, state, spacePointsGrouping.grid(), - seedsSetForBucket, bottom, middle, top, rMiddleSPRange); - } - - // proxies die when the Acts::SpacePointContainer dies, so we need to - // convert the seeds of space points proxies to seeds of space points - for (const seed_type& seed : seedsSetForBucket) { - const std::array& sps = seed.sp(); - const SimSpacePoint* bottom = sps[0]->externalSpacePoint(); - const SimSpacePoint* middle = sps[1]->externalSpacePoint(); - const SimSpacePoint* top = sps[2]->externalSpacePoint(); - - SimSeed toAdd(*bottom, *middle, *top); - toAdd.setVertexZ(seed.z()); - toAdd.setQuality(seed.seedQuality()); - - seedsSet.insert(toAdd); - } - } - - // convert the set to a simseed collection - SimSeedContainer seeds; - seeds.reserve(seedsSet.size()); - for (const SimSeed& seed : seedsSet) { - seeds.push_back(seed); - } - - ACTS_INFO("Created " << seeds.size() << " track seeds from " - << spacePointPtrs.size() << " space points"); - - m_outputSeeds(ctx, SimSeedContainer{seeds}); - std::vector buckets; - for (const SpacePointPtrVector& bucket : bucketsPtrs) { - SimSpacePointContainer bucketSP; - for (const SimSpacePoint* spacePoint : bucket) { - bucketSP.push_back(*spacePoint); - } - buckets.push_back(bucketSP); - } - m_outputBuckets(ctx, std::vector{buckets}); - - ACTS_DEBUG("End of SeedingAlgorithmHashing execute"); - return ProcessCode::SUCCESS; -} - -} // namespace ActsExamples diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 684cb29a353..f4f379a4d6e 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -10,7 +10,7 @@ SeedingAlgorithm = Enum( "SeedingAlgorithm", - "Default TruthSmeared TruthEstimated Orthogonal HoughTransform AdaptiveHoughTransform Gbts Hashing GridTriplet OrthogonalTriplet", + "Default TruthSmeared TruthEstimated Orthogonal HoughTransform AdaptiveHoughTransform Gbts GridTriplet OrthogonalTriplet HashingPrototype", ) TrackSmearingSigmas = namedtuple( @@ -1175,166 +1175,95 @@ def addHashingSeeding( hashingTrainingConfigArg: HashingTrainingConfigArg, hashingAlgorithmConfigArg: HashingAlgorithmConfigArg, logLevel: acts.logging.Level = None, + outputSeeds: str = "seeds", ): """adds Hashing seeding For parameters description see addSeeding docstring """ logLevel = acts.examples.defaultLogging(sequence, logLevel)() - from acts.examples.hashing import SeedingAlgorithmHashing + from acts.examples.hashing import HashingPrototypeSeedingAlgorithm - # Same configuration than the standard seeding - seedFinderConfig = acts.examples.SeedFinderConfig( + seedingAlg = HashingPrototypeSeedingAlgorithm( + level=logLevel, + inputSpacePoints=spacePoints, + outputSeeds=outputSeeds, **acts.examples.defaultKWArgs( - rMin=seedFinderConfigArg.r[0], - rMax=seedFinderConfigArg.r[1], + bFieldInZ=seedFinderOptionsArg.bFieldInZ, + minPt=seedFinderConfigArg.minPt, + cotThetaMax=seedFinderConfigArg.cotThetaMax, + impactMax=seedFinderConfigArg.impactMax, deltaRMin=seedFinderConfigArg.deltaR[0], deltaRMax=seedFinderConfigArg.deltaR[1], - deltaRMinTopSP=( + deltaRMinTop=( seedFinderConfigArg.deltaR[0] if seedFinderConfigArg.deltaRTopSP[0] is None else seedFinderConfigArg.deltaRTopSP[0] ), - deltaRMaxTopSP=( + deltaRMaxTop=( seedFinderConfigArg.deltaR[1] if seedFinderConfigArg.deltaRTopSP[1] is None else seedFinderConfigArg.deltaRTopSP[1] ), - deltaRMinBottomSP=( + deltaRMinBottom=( seedFinderConfigArg.deltaR[0] if seedFinderConfigArg.deltaRBottomSP[0] is None else seedFinderConfigArg.deltaRBottomSP[0] ), - deltaRMaxBottomSP=( + deltaRMaxBottom=( seedFinderConfigArg.deltaR[1] if seedFinderConfigArg.deltaRBottomSP[1] is None else seedFinderConfigArg.deltaRBottomSP[1] ), + rMin=seedFinderConfigArg.r[0], + rMax=seedFinderConfigArg.r[1], + zMin=seedFinderConfigArg.z[0], + zMax=seedFinderConfigArg.z[1], + phiMin=spacePointGridConfigArg.phi[0], + phiMax=spacePointGridConfigArg.phi[1], + phiBinDeflectionCoverage=spacePointGridConfigArg.phiBinDeflectionCoverage, + maxPhiBins=spacePointGridConfigArg.maxPhiBins, + zBinEdges=spacePointGridConfigArg.zBinEdges, + zBinsCustomLooping=seedFinderConfigArg.zBinsCustomLooping, + rMinMiddle=None, + rMaxMiddle=None, + useVariableMiddleSPRange=seedFinderConfigArg.useVariableMiddleSPRange, + rRangeMiddleSP=seedFinderConfigArg.rRangeMiddleSP, deltaRMiddleMinSPRange=seedFinderConfigArg.deltaRMiddleSPRange[0], deltaRMiddleMaxSPRange=seedFinderConfigArg.deltaRMiddleSPRange[1], + deltaZMin=None, + deltaZMax=None, + interactionPointCut=seedFinderConfigArg.interactionPointCut, collisionRegionMin=seedFinderConfigArg.collisionRegion[0], collisionRegionMax=seedFinderConfigArg.collisionRegion[1], - zMin=seedFinderConfigArg.z[0], - zMax=seedFinderConfigArg.z[1], - maxSeedsPerSpM=seedFinderConfigArg.maxSeedsPerSpM, - cotThetaMax=seedFinderConfigArg.cotThetaMax, + helixCutTolerance=None, sigmaScattering=seedFinderConfigArg.sigmaScattering, radLengthPerSeed=seedFinderConfigArg.radLengthPerSeed, - minPt=seedFinderConfigArg.minPt, - impactMax=seedFinderConfigArg.impactMax, - interactionPointCut=seedFinderConfigArg.interactionPointCut, - deltaZMax=seedFinderConfigArg.deltaZMax, - maxPtScattering=seedFinderConfigArg.maxPtScattering, - zBinEdges=seedFinderConfigArg.zBinEdges, - zBinsCustomLooping=seedFinderConfigArg.zBinsCustomLooping, - rRangeMiddleSP=seedFinderConfigArg.rRangeMiddleSP, - useVariableMiddleSPRange=seedFinderConfigArg.useVariableMiddleSPRange, - binSizeR=seedFinderConfigArg.binSizeR, - seedConfirmation=seedFinderConfigArg.seedConfirmation, - centralSeedConfirmationRange=seedFinderConfigArg.centralSeedConfirmationRange, - forwardSeedConfirmationRange=seedFinderConfigArg.forwardSeedConfirmationRange, - ), - ) - seedFinderOptions = acts.SeedFinderOptions( - **acts.examples.defaultKWArgs( - beamPos=( - acts.Vector2(0.0, 0.0) - if seedFinderOptionsArg.beamPos == (None, None) - else acts.Vector2( - seedFinderOptionsArg.beamPos[0], seedFinderOptionsArg.beamPos[1] - ) - ), - bFieldInZ=seedFinderOptionsArg.bFieldInZ, - ) - ) - seedFilterConfig = acts.SeedFilterConfig( - **acts.examples.defaultKWArgs( - maxSeedsPerSpM=seedFinderConfig.maxSeedsPerSpM, - deltaRMin=( - seedFinderConfig.deltaRMin - if seedFilterConfigArg.deltaRMin is None - else seedFilterConfigArg.deltaRMin - ), + toleranceParam=None, + deltaInvHelixDiameter=None, + compatSeedWeight=seedFilterConfigArg.compatSeedWeight, impactWeightFactor=seedFilterConfigArg.impactWeightFactor, zOriginWeightFactor=seedFilterConfigArg.zOriginWeightFactor, - compatSeedWeight=seedFilterConfigArg.compatSeedWeight, + maxSeedsPerSpM=seedFinderConfigArg.maxSeedsPerSpM, compatSeedLimit=seedFilterConfigArg.compatSeedLimit, - numSeedIncrement=seedFilterConfigArg.numSeedIncrement, seedWeightIncrement=seedFilterConfigArg.seedWeightIncrement, - seedConfirmation=seedFilterConfigArg.seedConfirmation, - centralSeedConfirmationRange=seedFinderConfig.centralSeedConfirmationRange, - forwardSeedConfirmationRange=seedFinderConfig.forwardSeedConfirmationRange, + numSeedIncrement=seedFilterConfigArg.numSeedIncrement, + seedConfirmation=seedFinderConfigArg.seedConfirmation, + centralSeedConfirmationRange=seedFinderConfigArg.centralSeedConfirmationRange, + forwardSeedConfirmationRange=seedFinderConfigArg.forwardSeedConfirmationRange, maxSeedsPerSpMConf=seedFilterConfigArg.maxSeedsPerSpMConf, maxQualitySeedsPerSpMConf=seedFilterConfigArg.maxQualitySeedsPerSpMConf, - useDeltaRorTopRadius=seedFilterConfigArg.useDeltaRorTopRadius, - ) - ) - - gridConfig = acts.SpacePointGridConfig( - **acts.examples.defaultKWArgs( - minPt=seedFinderConfig.minPt, - rMax=( - seedFinderConfig.rMax - if spacePointGridConfigArg.rMax is None - else spacePointGridConfigArg.rMax - ), - zMax=seedFinderConfig.zMax, - zMin=seedFinderConfig.zMin, - deltaRMax=( - seedFinderConfig.deltaRMax - if spacePointGridConfigArg.deltaRMax is None - else spacePointGridConfigArg.deltaRMax - ), - cotThetaMax=seedFinderConfig.cotThetaMax, - phiMin=spacePointGridConfigArg.phi[0], - phiMax=spacePointGridConfigArg.phi[1], - maxPhiBins=spacePointGridConfigArg.maxPhiBins, - impactMax=spacePointGridConfigArg.impactMax, - zBinEdges=spacePointGridConfigArg.zBinEdges, - phiBinDeflectionCoverage=spacePointGridConfigArg.phiBinDeflectionCoverage, - ) - ) - - gridOptions = acts.SpacePointGridOptions( - **acts.examples.defaultKWArgs( - bFieldInZ=seedFinderOptions.bFieldInZ, - ) - ) - - # Hashing configuration - hashingTrainingConfig = acts.hashing.HashingTrainingConfig( - **acts.examples.defaultKWArgs( - annoySeed=hashingTrainingConfigArg.annoySeed, - f=hashingTrainingConfigArg.f, - ), - ) - - hashingConfig = acts.hashing.HashingAlgorithmConfig( - **acts.examples.defaultKWArgs( - bucketSize=hashingAlgorithmConfigArg.bucketSize, - zBins=hashingAlgorithmConfigArg.zBins, - phiBins=hashingAlgorithmConfigArg.phiBins, - ), - ) - - # Seeding algorithm - seedingAlg = SeedingAlgorithmHashing( - level=logLevel, - inputSpacePoints=[spacePoints], - outputSeeds="seeds", - outputBuckets="buckets", - **acts.examples.defaultKWArgs( - allowSeparateRMax=seedingAlgorithmConfigArg.allowSeparateRMax, - zBinNeighborsTop=seedingAlgorithmConfigArg.zBinNeighborsTop, - zBinNeighborsBottom=seedingAlgorithmConfigArg.zBinNeighborsBottom, - numPhiNeighbors=seedingAlgorithmConfigArg.numPhiNeighbors, + useDeltaRinsteadOfTopRadius=seedFilterConfigArg.useDeltaRorTopRadius, + useExtraCuts=seedingAlgorithmConfigArg.useExtraCuts, + annoySeed=seedingAlgorithmConfigArg.annoySeed, + f=seedingAlgorithmConfigArg.f, + bucketSize=seedingAlgorithmConfigArg.bucketSize, + zBins=seedingAlgorithmConfigArg.zBins, + phiBins=seedingAlgorithmConfigArg.phiBins, + layerRMin=seedingAlgorithmConfigArg.layerRMin, + layerRMax=seedingAlgorithmConfigArg.layerRMax, + layerZMin=seedingAlgorithmConfigArg.layerZMin, + layerZMax=seedingAlgorithmConfigArg.layerZMax, ), - gridConfig=gridConfig, - gridOptions=gridOptions, - seedFilterConfig=seedFilterConfig, - seedFinderConfig=seedFinderConfig, - seedFinderOptions=seedFinderOptions, - hashingConfig=hashingConfig, - hashingTrainingConfig=hashingTrainingConfig, ) sequence.addAlgorithm(seedingAlg) diff --git a/Examples/Python/src/Hashing.cpp b/Examples/Python/src/Hashing.cpp index 468fa9ca504..e38672324b9 100644 --- a/Examples/Python/src/Hashing.cpp +++ b/Examples/Python/src/Hashing.cpp @@ -6,14 +6,10 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/TrackFinding/SeedingAlgorithmHashing.hpp" -#include "ActsPlugins/Hashing/HashingAlgorithmConfig.hpp" -#include "ActsPlugins/Hashing/HashingTrainingConfig.hpp" +#include "ActsExamples/TrackFinding/HashingPrototypeSeedingAlgorithm.hpp" #include "ActsPython/Utilities/Helpers.hpp" #include "ActsPython/Utilities/Macros.hpp" -#include - #include #include @@ -28,31 +24,26 @@ namespace ActsPython { void addHashing(Context& ctx) { auto [m, mex] = ctx.get("main", "examples"); - auto hashingModule = m.def_submodule("hashing"); auto hashingExampleModule = mex.def_submodule("_hashing"); - { - using Config = HashingAlgorithmConfig; - auto c = py::class_(hashingModule, "HashingAlgorithmConfig") - .def(py::init<>()); - ACTS_PYTHON_STRUCT(c, bucketSize, zBins, phiBins); - patchKwargsConstructor(c); - } - - { - using Config = HashingTrainingConfig; - auto c = py::class_(hashingModule, "HashingTrainingConfig") - .def(py::init<>()); - ACTS_PYTHON_STRUCT(c, annoySeed, f); - patchKwargsConstructor(c); - } - ACTS_PYTHON_DECLARE_ALGORITHM( - SeedingAlgorithmHashing, hashingExampleModule, "SeedingAlgorithmHashing", - inputSpacePoints, outputSeeds, outputBuckets, seedFilterConfig, - seedFinderConfig, seedFinderOptions, gridConfig, gridOptions, - allowSeparateRMax, zBinNeighborsTop, zBinNeighborsBottom, numPhiNeighbors, - hashingConfig, hashingTrainingConfig); + HashingPrototypeSeedingAlgorithm, hashingExampleModule, + "HashingPrototypeSeedingAlgorithm", inputSpacePoints, outputSeeds, + bFieldInZ, minPt, cotThetaMax, impactMax, deltaRMin, deltaRMax, + deltaRMinTop, deltaRMaxTop, deltaRMinBottom, deltaRMaxBottom, rMin, rMax, + zMin, zMax, phiMin, phiMax, phiBinDeflectionCoverage, maxPhiBins, + zBinNeighborsTop, zBinNeighborsBottom, numPhiNeighbors, zBinEdges, + zBinsCustomLooping, rMinMiddle, rMaxMiddle, useVariableMiddleSPRange, + rRangeMiddleSP, deltaRMiddleMinSPRange, deltaRMiddleMaxSPRange, deltaZMin, + deltaZMax, interactionPointCut, collisionRegionMin, collisionRegionMax, + helixCutTolerance, sigmaScattering, radLengthPerSeed, toleranceParam, + deltaInvHelixDiameter, compatSeedWeight, impactWeightFactor, + zOriginWeightFactor, maxSeedsPerSpM, compatSeedLimit, seedWeightIncrement, + numSeedIncrement, seedConfirmation, centralSeedConfirmationRange, + forwardSeedConfirmationRange, maxSeedsPerSpMConf, + maxQualitySeedsPerSpMConf, useDeltaRinsteadOfTopRadius, useExtraCuts, + annoySeed, f, bucketSize, zBins, phiBins, layerRMin, layerRMax, layerZMin, + layerZMax); } } // namespace ActsPython diff --git a/Examples/Python/src/TrackFinding.cpp b/Examples/Python/src/TrackFinding.cpp index 51d5fef3ce3..e1bacc8824f 100644 --- a/Examples/Python/src/TrackFinding.cpp +++ b/Examples/Python/src/TrackFinding.cpp @@ -7,8 +7,6 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. #include "Acts/EventData/SpacePointContainer.hpp" -#include "Acts/Geometry/GeometryIdentifier.hpp" -#include "Acts/Seeding/SeedConfirmationRangeConfig.hpp" #include "Acts/Seeding/SeedFinderConfig.hpp" #include "Acts/Seeding/SeedFinderGbtsConfig.hpp" #include "Acts/Seeding/SeedFinderOrthogonalConfig.hpp" @@ -31,7 +29,6 @@ #include #include -#include #include #include diff --git a/Examples/Scripts/Python/hashing_seeding.py b/Examples/Scripts/Python/hashing_seeding.py index 2a17dbd49bf..187f20d235b 100755 --- a/Examples/Scripts/Python/hashing_seeding.py +++ b/Examples/Scripts/Python/hashing_seeding.py @@ -38,7 +38,7 @@ def __init__( bucketSize: int = 100, maxSeedsPerSpM: int = 1000, detector: DetectorName = DetectorName.generic, - seedingAlgorithm: SeedingAlgorithm = SeedingAlgorithm.Hashing, + seedingAlgorithm: SeedingAlgorithm = SeedingAlgorithm.HashingPrototype, metric: str = HashingMetric.dphi, annoySeed: int = 123456789, zBins: int = 100_000, diff --git a/Plugins/Hashing/CMakeLists.txt b/Plugins/Hashing/CMakeLists.txt index d1d051a9037..3b4a8b707a6 100644 --- a/Plugins/Hashing/CMakeLists.txt +++ b/Plugins/Hashing/CMakeLists.txt @@ -1,12 +1,16 @@ acts_add_library( PluginHashing - INTERFACE + SHARED + src/HashingAlgorithm.cpp + src/HashingTraining.cpp ACTS_INCLUDE_FOLDER include/ActsPlugins ) + target_include_directories( ActsPluginHashing - INTERFACE + PUBLIC $ $ ) -target_link_libraries(ActsPluginHashing INTERFACE Annoy) + +target_link_libraries(ActsPluginHashing PUBLIC Acts::Core Annoy) diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp b/Plugins/Hashing/include/ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp index 7f5555197ca..cf05f740718 100644 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp +++ b/Plugins/Hashing/include/ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp @@ -18,11 +18,3 @@ class AnnoyIndex; // AnnoyIndex template class class AnnoyIndexSingleThreadedBuildPolicy; // Build policy } // namespace Annoy - -// Define commonly used Annoy types -namespace ActsPlugins { -using AnnoyMetric = Annoy::AngularEuclidean; -using AnnoyModel = - Annoy::AnnoyIndex; -} // namespace ActsPlugins diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithm.hpp b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithm.hpp index 7b1c2ea8ec1..c823975f6ef 100755 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithm.hpp +++ b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithm.hpp @@ -8,23 +8,36 @@ #pragma once -#include "ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp" -#include "ActsPlugins/Hashing/HashingAlgorithmConfig.hpp" +#include "Acts/EventData/SpacePointContainer2.hpp" +#include "Acts/EventData/Types.hpp" +#include "ActsPlugins/Hashing/HashingModel.hpp" + +#include namespace ActsPlugins { -template class HashingAlgorithm { public: - using Config = HashingAlgorithmConfig; + struct Config { + /// Size of the buckets = number of spacepoints in the bucket + std::uint32_t bucketSize = 10; + /// Number of zBins + std::uint32_t zBins = 0; + /// Number of phiBins + std::uint32_t phiBins = 50; + + /// Layer selection + double layerRMin = 25; + double layerRMax = 40; + double layerZMin = -550; + double layerZMax = 550; + }; explicit HashingAlgorithm(const Config& cfg); - HashingAlgorithm() = default; - - template - void execute(SpacePointContainer& spacePoints, AnnoyModel* annoyModel, - collection_t& outputCollection) const; + std::vector> execute( + const AnnoyModel& annoyModel, + const Acts::SpacePointContainer2& spacePoints) const; /// Get readonly access to the config parameters const Config& config() const { return m_cfg; } @@ -34,5 +47,3 @@ class HashingAlgorithm { }; } // namespace ActsPlugins - -#include "ActsPlugins/Hashing/HashingAlgorithm.ipp" diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithm.ipp b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithm.ipp deleted file mode 100644 index 641176ecdde..00000000000 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithm.ipp +++ /dev/null @@ -1,95 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -#include "ActsPlugins/Hashing/HashingAlgorithm.hpp" - -#include "Acts/Seeding/detail/UtilityFunctions.hpp" -#include "ActsPlugins/Hashing/HashingAnnoy.hpp" - -#include - -namespace ActsPlugins { - -// constructor -template -HashingAlgorithm::HashingAlgorithm( - const Config& cfg) - : m_cfg(cfg) { - if (m_cfg.bucketSize <= 0) { - throw std::invalid_argument("Invalid bucket size"); - } -} - -// function to create the buckets of spacepoints. -template -template -void HashingAlgorithm::execute( - SpacePointContainer& spacePoints, AnnoyModel* annoyModel, - collection_t& outputCollection) const { - // Define a map to store the buckets of spacepoints a set is used to exclude - // duplicates - using map_t = std::map>; - - // Get the number of space points - const std::size_t nSpacePoints = spacePoints.size(); - - // Get the bucket size, zBins, and phiBins from the configuration - const unsigned int bucketSize = m_cfg.bucketSize; - const unsigned int zBins = m_cfg.zBins; - const unsigned int phiBins = m_cfg.phiBins; - - // Get the layer selection from the configuration - const double layerRMin = m_cfg.layerRMin; - const double layerRMax = m_cfg.layerRMax; - const double layerZMin = m_cfg.layerZMin; - const double layerZMax = m_cfg.layerZMax; - - // Create an instance of the HashingAnnoy class - auto annoyHashingInstance = std::make_unique< - HashingAnnoy>(); - - // Compute the buckets of spacepoints using the Annoy model - annoyHashingInstance->computeSpacePointsBuckets( - annoyModel, spacePoints, bucketSize, zBins, phiBins, layerRMin, layerRMax, - layerZMin, layerZMax); - - // Get the map of buckets and the number of buckets - map_t bucketsSPMap = annoyHashingInstance->m_bucketsSPMap; - auto nBuckets = static_cast(bucketsSPMap.size()); - - // Check if the number of buckets is greater than the number of space points - if (nBuckets > nSpacePoints) { - throw std::runtime_error("More buckets than the number of Space Points"); - } - - // Convert the map to a SpacePointContainer of SpacePointContainers - for (unsigned int bucketIdx = 0; bucketIdx < nBuckets; bucketIdx++) { - // Find the bucket in the map - typename map_t::iterator iterator = bucketsSPMap.find(bucketIdx); - if (iterator == bucketsSPMap.end()) { - throw std::runtime_error("Not every bucket have been found"); - } - - // Get the set of spacepoints in the bucket - std::set bucketSet = iterator->second; - - // Convert the set to a SpacePointContainer - SpacePointContainer bucket; - for (external_spacepoint_t spacePoint : bucketSet) { - bucket.push_back(spacePoint); - } - - // Add the bucket container to the output collection - Acts::detail::pushBackOrInsertAtEnd(outputCollection, - SpacePointContainer{bucket}); - } -} - -} // namespace ActsPlugins diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithmConfig.hpp b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithmConfig.hpp deleted file mode 100644 index 23092798357..00000000000 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAlgorithmConfig.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -#include - -namespace ActsPlugins { -struct HashingAlgorithmConfig { - /// Size of the buckets = number of spacepoints in the bucket - std::uint32_t bucketSize = 10; - /// Number of zBins - std::uint32_t zBins = 0; - /// Number of phiBins - std::uint32_t phiBins = 50; - - /// Layer selection - double layerRMin = 25; - double layerRMax = 40; - double layerZMin = -550; - double layerZMax = 550; -}; - -} // namespace ActsPlugins diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAnnoy.hpp b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAnnoy.hpp deleted file mode 100644 index 2bbeeee227d..00000000000 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAnnoy.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -#include "ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp" - -#include -#include - -namespace ActsPlugins { - -template -class HashingAnnoy { - public: - void computeSpacePointsBuckets( - const AnnoyModel* annoyModel, const SpacePointContainer& spacePoints, - const unsigned int bucketSize, const unsigned int zBins, - const unsigned int phiBins, const double layerRMin, - const double layerRMax, const double layerZMin, const double layerZMax); - std::map> m_bucketsSPMap; -}; -} // namespace ActsPlugins - -#include "ActsPlugins/Hashing/HashingAnnoy.ipp" diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAnnoy.ipp b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAnnoy.ipp deleted file mode 100644 index 7283743689a..00000000000 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingAnnoy.ipp +++ /dev/null @@ -1,129 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -#include "ActsPlugins/Hashing/HashingAnnoy.hpp" - -#include "Acts/Definitions/Units.hpp" - -#include -#include -#include - -#include -#include - -namespace ActsPlugins { - -template -void HashingAnnoy:: - computeSpacePointsBuckets(const AnnoyModel* annoyModel, - const SpacePointContainer& spacePoints, - const unsigned int bucketSize, - const unsigned int zBins, - const unsigned int phiBins, - const double layerRMin, const double layerRMax, - const double layerZMin, const double layerZMax) { - static thread_local std::vector> - bucketsSetSPMap; - bucketsSetSPMap.clear(); - - unsigned int nBins = 0; - if (zBins > 0) { - nBins = zBins; - } else if (phiBins > 0) { - nBins = phiBins; - } else { - throw std::runtime_error("No bins defined"); - } - bucketsSetSPMap.reserve(nBins); - - // Create the set of spacePoints for each bucket - for (unsigned int binIndex = 0; binIndex < nBins; binIndex++) { - static thread_local std::set bucket; - bucket.clear(); - bucketsSetSPMap.push_back(bucket); - } - - // Function to check if a spacePoint is inside the layer - auto layerSelection = [&layerRMin, &layerRMax, &layerZMin, &layerZMax]( - double r2, double z) { - bool isInside = - (r2 >= layerRMin * layerRMin && r2 <= layerRMax * layerRMax) && - (z >= layerZMin && z <= layerZMax); - return isInside; - }; - - // Functions to get the bin index - auto getBinIndexZ = [&zBins, &layerZMin, &layerZMax](double z) { - double binSize = (layerZMax - layerZMin) / zBins; - auto binIndex = static_cast((z - layerZMin + 0.5 * binSize) / binSize); - return binIndex; - }; - - auto getBinIndexPhi = [&phiBins](double phi) { - double binSize = 2 * std::numbers::pi / phiBins; - auto binIndex = static_cast((phi + std::numbers::pi) / binSize); - return binIndex; - }; - - // Function pointers to a unified bin index function for z and phi - auto getBinIndex = [&zBins, &phiBins, &getBinIndexZ, &getBinIndexPhi]( - double z, double phi) -> int { - if (zBins > 0) { - return getBinIndexZ(z); - } else if (phiBins > 0) { - return getBinIndexPhi(phi); - } else { - throw std::runtime_error("No bins defined"); - } - }; - - // Loop over spacePoints - for (unsigned int spacePointIndex = 0; spacePointIndex < spacePoints.size(); - spacePointIndex++) { - external_spacepoint_t spacePoint = spacePoints[spacePointIndex]; - double x = spacePoint->x() / Acts::UnitConstants::mm; - double y = spacePoint->y() / Acts::UnitConstants::mm; - double z = spacePoint->z() / Acts::UnitConstants::mm; - - // Helix transform - if (double r2 = x * x + y * y; !layerSelection(r2, z)) { - continue; - } - - double phi = atan2(y, x); - - int binIndex = getBinIndex(z, phi); - if (binIndex < 0 || static_cast(binIndex) >= nBins) { - throw std::runtime_error("binIndex outside of bins covering"); - } - - std::vector bucketIds; - - /// Get the bucketSize closest spacePoints - annoyModel->get_nns_by_item(spacePointIndex, bucketSize, -1, &bucketIds, - nullptr); - - for (const unsigned int& bucketSpacePointIndex : bucketIds) { - bucketsSetSPMap[static_cast(binIndex)].insert( - spacePoints.at(bucketSpacePointIndex)); - } - } - - unsigned int n_buckets = 0; - for (unsigned int binIndex = 0; binIndex < nBins; binIndex++) { - if (bucketsSetSPMap[binIndex].size() > 0) { - m_bucketsSPMap[n_buckets] = bucketsSetSPMap[binIndex]; - n_buckets++; - } - } -} - -} // namespace ActsPlugins diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTrainingConfig.hpp b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingModel.hpp similarity index 60% rename from Plugins/Hashing/include/ActsPlugins/Hashing/HashingTrainingConfig.hpp rename to Plugins/Hashing/include/ActsPlugins/Hashing/HashingModel.hpp index 6b7f648815e..a3ca11e4473 100644 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTrainingConfig.hpp +++ b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingModel.hpp @@ -8,16 +8,15 @@ #pragma once +#include "ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp" + #include namespace ActsPlugins { -struct HashingTrainingConfig { - /// Random seed for Annoy - std::uint32_t annoySeed = 123456789; - - /// Number of features to use - std::int32_t f = 1; -}; +using AnnoyMetric = Annoy::AngularEuclidean; +using AnnoyModel = + Annoy::AnnoyIndex; } // namespace ActsPlugins diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTraining.hpp b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTraining.hpp index 218bde3b6cd..62323d5c7d5 100755 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTraining.hpp +++ b/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTraining.hpp @@ -8,25 +8,26 @@ #pragma once -#include "ActsPlugins/Hashing/AnnoyForwardDeclarations.hpp" -#include "ActsPlugins/Hashing/HashingTrainingConfig.hpp" +#include "Acts/EventData/SpacePointContainer2.hpp" +#include "ActsPlugins/Hashing/HashingModel.hpp" + +#include namespace ActsPlugins { -template -class HashingTrainingAlgorithm { +class HashingTraining { public: - using Config = HashingTrainingConfig; + struct Config { + /// Random seed for Annoy + std::uint32_t annoySeed = 123456789; - explicit HashingTrainingAlgorithm(const Config &cfg); + /// Number of features to use + std::int32_t f = 1; + }; - HashingTrainingAlgorithm() = default; - HashingTrainingAlgorithm( - const HashingTrainingAlgorithm &) = delete; - HashingTrainingAlgorithm &operator=( - const HashingTrainingAlgorithm &) = default; + explicit HashingTraining(const Config &cfg); - AnnoyModel execute(SpacePointContainer spacePoints) const; + AnnoyModel execute(const Acts::SpacePointContainer2 &spacePoints) const; // / Get readonly access to the config parameters const Config &config() const { return m_cfg; } @@ -36,5 +37,3 @@ class HashingTrainingAlgorithm { }; } // namespace ActsPlugins - -#include "ActsPlugins/Hashing/HashingTraining.ipp" diff --git a/Plugins/Hashing/src/HashingAlgorithm.cpp b/Plugins/Hashing/src/HashingAlgorithm.cpp new file mode 100644 index 00000000000..e85a09e444e --- /dev/null +++ b/Plugins/Hashing/src/HashingAlgorithm.cpp @@ -0,0 +1,133 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsPlugins/Hashing/HashingAlgorithm.hpp" + +#include "Acts/Definitions/Units.hpp" +#include "Acts/EventData/Types.hpp" +#include "Acts/Utilities/MathHelpers.hpp" +#include "ActsPlugins/Hashing/HashingModel.hpp" + +#include +#include + +#include +#include + +namespace ActsPlugins { + +namespace { + +std::vector> computeSpacePointsBuckets( + const AnnoyModel& annoyModel, const Acts::SpacePointContainer2& spacePoints, + const std::size_t bucketSize, const std::size_t zBins, + const std::size_t phiBins, const double layerRMin, const double layerRMax, + const double layerZMin, const double layerZMax) { + std::vector> resultSets; + + std::size_t nBins = 0; + if (zBins > 0) { + nBins = zBins; + } else if (phiBins > 0) { + nBins = phiBins; + } else { + throw std::runtime_error("No bins defined"); + } + resultSets.resize(nBins); + + auto layerSelection = [&layerRMin, &layerRMax, &layerZMin, &layerZMax]( + double r2, double z) { + bool isInside = + (r2 >= layerRMin * layerRMin && r2 <= layerRMax * layerRMax) && + (z >= layerZMin && z <= layerZMax); + return isInside; + }; + + auto getBinIndexZ = [&zBins, &layerZMin, &layerZMax](const float z) { + const float binSize = (layerZMax - layerZMin) / zBins; + return static_cast((z - layerZMin + 0.5f * binSize) / binSize); + }; + + auto getBinIndexPhi = [&phiBins](const float phi) { + const float binSize = 2 * std::numbers::pi / phiBins; + return static_cast((phi + std::numbers::pi) / binSize); + }; + + auto getBinIndex = [&zBins, &phiBins, &getBinIndexZ, &getBinIndexPhi]( + const float z, const float phi) -> int { + if (zBins > 0) { + return getBinIndexZ(z); + } else if (phiBins > 0) { + return getBinIndexPhi(phi); + } else { + throw std::runtime_error("No bins defined"); + } + }; + + for (const auto spacePoint : spacePoints) { + const float x = spacePoint.x() / Acts::UnitConstants::mm; + const float y = spacePoint.y() / Acts::UnitConstants::mm; + const float z = spacePoint.z() / Acts::UnitConstants::mm; + + if (const float r2 = Acts::hypotSquare(x, y); !layerSelection(r2, z)) { + continue; + } + + const float phi = std::atan2(y, x); + + const int binIndex = getBinIndex(z, phi); + if (binIndex < 0 || static_cast(binIndex) >= nBins) { + throw std::runtime_error("binIndex outside of bins covering"); + } + + std::vector neighborSpacePointIndices; + annoyModel.get_nns_by_item(spacePoint.index(), bucketSize, -1, + &neighborSpacePointIndices, nullptr); + resultSets[binIndex].insert(spacePoint.index()); + for (const auto& neighborSpacePointIndex : neighborSpacePointIndices) { + resultSets[binIndex].insert(neighborSpacePointIndex); + } + } + + std::vector> result; + result.reserve(resultSets.size()); + for (const auto& spSet : resultSets) { + result.emplace_back(spSet.begin(), spSet.end()); + } + return result; +} + +} // namespace + +HashingAlgorithm::HashingAlgorithm(const Config& cfg) : m_cfg(cfg) { + if (m_cfg.bucketSize <= 0) { + throw std::invalid_argument("Invalid bucket size"); + } +} + +std::vector> HashingAlgorithm::execute( + const AnnoyModel& annoyModel, + const Acts::SpacePointContainer2& spacePoints) const { + // Compute the buckets of spacepoints using the Annoy model + std::vector> result = + computeSpacePointsBuckets( + annoyModel, spacePoints, m_cfg.bucketSize, m_cfg.zBins, m_cfg.phiBins, + m_cfg.layerRMin, m_cfg.layerRMax, m_cfg.layerZMin, m_cfg.layerZMax); + + const std::size_t nBuckets = result.size(); + const std::size_t nSpacePoints = spacePoints.size(); + + // Check if the number of buckets is greater than the number of space points + if (nBuckets > nSpacePoints) { + throw std::runtime_error("More buckets than the number of Space Points"); + } + + return result; +} + +} // namespace ActsPlugins diff --git a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTraining.ipp b/Plugins/Hashing/src/HashingTraining.cpp similarity index 54% rename from Plugins/Hashing/include/ActsPlugins/Hashing/HashingTraining.ipp rename to Plugins/Hashing/src/HashingTraining.cpp index 49f19555b5f..ffcf8a3043a 100644 --- a/Plugins/Hashing/include/ActsPlugins/Hashing/HashingTraining.ipp +++ b/Plugins/Hashing/src/HashingTraining.cpp @@ -6,12 +6,11 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#pragma once - #include "ActsPlugins/Hashing/HashingTraining.hpp" #include "Acts/Definitions/Units.hpp" #include "Acts/Utilities/AngleHelpers.hpp" +#include "Acts/Utilities/MathHelpers.hpp" #include #include @@ -21,11 +20,7 @@ namespace ActsPlugins { -// constructor -template -HashingTrainingAlgorithm::HashingTrainingAlgorithm( - const Config& cfg) - : m_cfg(cfg) { +HashingTraining::HashingTraining(const Config& cfg) : m_cfg(cfg) { if (m_cfg.f <= 0) { throw std::invalid_argument("Invalid f, f must be positive"); } @@ -35,9 +30,8 @@ HashingTrainingAlgorithm::HashingTrainingAlgorithm( } } -template -AnnoyModel HashingTrainingAlgorithm::execute( - SpacePointContainer spacePoints) const { +AnnoyModel HashingTraining::execute( + const Acts::SpacePointContainer2& spacePoints) const { const unsigned int annoySeed = m_cfg.annoySeed; const std::int32_t f = m_cfg.f; @@ -45,35 +39,29 @@ AnnoyModel HashingTrainingAlgorithm::execute( annoyModel.set_seed(annoySeed); - unsigned int spacePointIndex = 0; - // Add spacePoints parameters to Annoy for (const auto& spacePoint : spacePoints) { - double x = spacePoint->x() / Acts::UnitConstants::mm; - double y = spacePoint->y() / Acts::UnitConstants::mm; + const float x = spacePoint.x() / Acts::UnitConstants::mm; + const float y = spacePoint.y() / Acts::UnitConstants::mm; - // Helix transform - double phi = std::atan2(y, x); + const float phi = std::atan2(y, x); - std::vector vec(f); - // Avoid potential null pointer dereference + std::array vec{}; if (f >= 1) { vec[0] = phi; } if (f >= 2) { - double z = spacePoint->z() / Acts::UnitConstants::mm; - double r2 = x * x + y * y; - double rho = std::sqrt(r2 + z * z); - double theta = std::acos(z / rho); - double eta = Acts::AngleHelpers::etaFromTheta(theta); + const float z = spacePoint.z() / Acts::UnitConstants::mm; + const float r2 = Acts::hypotSquare(x, y); + const float rho = std::sqrt(r2 + z * z); + const float theta = std::acos(z / rho); + const float eta = Acts::AngleHelpers::etaFromTheta(theta); vec[1] = eta; } - annoyModel.add_item(spacePointIndex, vec.data()); - spacePointIndex++; + annoyModel.add_item(spacePoint.index(), vec.data()); } - unsigned int nTrees = 2 * f; - + const int nTrees = 2 * f; annoyModel.build(nTrees); return annoyModel; diff --git a/Tests/UnitTests/Plugins/Hashing/HashingSeedingTest.cpp b/Tests/UnitTests/Plugins/Hashing/HashingSeedingTest.cpp index f6a809f3c9e..86ac866136c 100644 --- a/Tests/UnitTests/Plugins/Hashing/HashingSeedingTest.cpp +++ b/Tests/UnitTests/Plugins/Hashing/HashingSeedingTest.cpp @@ -8,58 +8,51 @@ #include +#include "Acts/Definitions/Units.hpp" +#include "Acts/EventData/SpacePointContainer2.hpp" #include "ActsPlugins/Hashing/HashingAlgorithm.hpp" -#include "ActsPlugins/Hashing/HashingAlgorithmConfig.hpp" #include "ActsPlugins/Hashing/HashingTraining.hpp" -#include "ActsPlugins/Hashing/HashingTrainingConfig.hpp" #include -#include #include #include #include -#include "SpacePoint.hpp" - using namespace Acts::UnitLiterals; // Function to create and initialize the test vector -std::vector> createTestVector() { - std::optional t, varianceT; - std::vector> testVector; - testVector.reserve(6); // Reserve space for efficiency - - testVector.push_back(std::make_unique( - 27.2535, -18.0088, -146.526, 29.0, 1, 0.00520833, 0.5, t, varianceT)); - testVector.push_back(std::make_unique( - 42.9126, -27.3057, -171.477, 50.0, 1, 0.0133333, 0.8, t, varianceT)); - testVector.push_back(std::make_unique( - 42.7087, -27.4589, -171.557, 50.0, 1, 0.0133333, 0.4, t, varianceT)); - testVector.push_back(std::make_unique( - 74.3652, -45.8552, -221.277, 80.0, 1, 0.0133333, 0.4, t, varianceT)); - testVector.push_back(std::make_unique( - 104.12, -63.4203, -268.468, 110.0, 1, 0.0133333, 0.4, t, varianceT)); - testVector.push_back(std::make_unique( - 104.412, -63.1851, -268.468, 110.0, 1, 0.0133333, 0.4, t, varianceT)); +Acts::SpacePointContainer2 createTestVector() { + Acts::SpacePointContainer2 testVector(Acts::SpacePointColumns::X | + Acts::SpacePointColumns::Y | + Acts::SpacePointColumns::Z); + testVector.reserve(6); + + const auto createSpacePoint = [&testVector](const float x, const float y, + const float z) { + auto sp = testVector.createSpacePoint(); + sp.x() = x; + sp.y() = y; + sp.z() = z; + return sp; + }; + + createSpacePoint(27.2535, -18.0088, -146.526); + createSpacePoint(42.9126, -27.3057, -171.477); + createSpacePoint(42.7087, -27.4589, -171.557); + createSpacePoint(74.3652, -45.8552, -221.277); + createSpacePoint(104.12, -63.4203, -268.468); + createSpacePoint(104.412, -63.1851, -268.468); + return testVector; } namespace Acts::Test { BOOST_AUTO_TEST_CASE(HashingBucketCreationTest) { - using SpacePointPtrVector = std::vector; - // Initialize testVector using the createTestVector function auto testVector = createTestVector(); - // Extract raw pointers from unique_ptrs for the test - SpacePointPtrVector spVec; - spVec.reserve(testVector.size()); - for (const auto& sp : testVector) { - spVec.push_back(sp.get()); - } - /// Random seed for Annoy unsigned int annoySeed = 123456789; @@ -79,7 +72,7 @@ BOOST_AUTO_TEST_CASE(HashingBucketCreationTest) { double layerZMin = -550; double layerZMax = 550; - ActsPlugins::HashingAlgorithmConfig hashingConfig; + ActsPlugins::HashingAlgorithm::Config hashingConfig; hashingConfig.bucketSize = bucketSize; hashingConfig.zBins = zBins; hashingConfig.phiBins = phiBins; @@ -88,43 +81,27 @@ BOOST_AUTO_TEST_CASE(HashingBucketCreationTest) { hashingConfig.layerZMin = layerZMin; hashingConfig.layerZMax = layerZMax; - ActsPlugins::HashingTrainingConfig hashingTrainingConfig; + ActsPlugins::HashingTraining::Config hashingTrainingConfig; hashingTrainingConfig.annoySeed = annoySeed; hashingTrainingConfig.f = nf; - ActsPlugins::HashingAlgorithm - hashing = - ActsPlugins::HashingAlgorithm( - hashingConfig); - ActsPlugins::HashingTrainingAlgorithm hashingTraining = - ActsPlugins::HashingTrainingAlgorithm( - hashingTrainingConfig); + ActsPlugins::HashingTraining hashingTraining(hashingTrainingConfig); + ActsPlugins::HashingAlgorithm hashing(hashingConfig); // Hashing Training - ActsPlugins::AnnoyModel annoyModel = hashingTraining.execute(spVec); + ActsPlugins::AnnoyModel annoyModel = hashingTraining.execute(testVector); // Hashing - std::vector bucketsPtrs; - bucketsPtrs.clear(); - hashing.execute(spVec, &annoyModel, bucketsPtrs); + auto result = hashing.execute(annoyModel, testVector); // Check the number of buckets created - BOOST_CHECK_GT(bucketsPtrs.size(), 0); + BOOST_CHECK_GT(result.size(), 0); } BOOST_AUTO_TEST_CASE(HashingBucketContentTest) { - using SpacePointPtrVector = std::vector; - // Initialize testVector using the createTestVector function auto testVector = createTestVector(); - // Extract raw pointers from unique_ptrs for the test - SpacePointPtrVector spVec; - spVec.reserve(testVector.size()); - for (const auto& sp : testVector) { - spVec.push_back(sp.get()); - } - /// Random seed for Annoy unsigned int annoySeed = 123456789; @@ -144,7 +121,7 @@ BOOST_AUTO_TEST_CASE(HashingBucketContentTest) { double layerZMin = -550; double layerZMax = 550; - ActsPlugins::HashingAlgorithmConfig hashingConfig; + ActsPlugins::HashingAlgorithm::Config hashingConfig; hashingConfig.bucketSize = bucketSize; hashingConfig.zBins = zBins; hashingConfig.phiBins = phiBins; @@ -153,31 +130,24 @@ BOOST_AUTO_TEST_CASE(HashingBucketContentTest) { hashingConfig.layerZMin = layerZMin; hashingConfig.layerZMax = layerZMax; - ActsPlugins::HashingTrainingConfig hashingTrainingConfig; + ActsPlugins::HashingTraining::Config hashingTrainingConfig; hashingTrainingConfig.annoySeed = annoySeed; hashingTrainingConfig.f = nf; - ActsPlugins::HashingAlgorithm - hashing = - ActsPlugins::HashingAlgorithm( - hashingConfig); - ActsPlugins::HashingTrainingAlgorithm hashingTraining = - ActsPlugins::HashingTrainingAlgorithm( - hashingTrainingConfig); + ActsPlugins::HashingTraining hashingTraining(hashingTrainingConfig); + ActsPlugins::HashingAlgorithm hashing(hashingConfig); // Hashing Training - ActsPlugins::AnnoyModel annoyModel = hashingTraining.execute(spVec); + ActsPlugins::AnnoyModel annoyModel = hashingTraining.execute(testVector); // Hashing - std::vector bucketsPtrs; - bucketsPtrs.clear(); - hashing.execute(spVec, &annoyModel, bucketsPtrs); + auto result = hashing.execute(annoyModel, testVector); // Validate bucket content - for (const auto& bucket : bucketsPtrs) { + for (const auto& bucket : result) { BOOST_CHECK_LE(bucket.size(), bucketSize); - for (const auto* sp : bucket) { - BOOST_CHECK(sp != nullptr); + for (const auto& sp : bucket) { + BOOST_CHECK_NE(sp, 0); } } } diff --git a/Tests/UnitTests/Plugins/Hashing/SpacePoint.hpp b/Tests/UnitTests/Plugins/Hashing/SpacePoint.hpp deleted file mode 100644 index 4b6b6ddd31f..00000000000 --- a/Tests/UnitTests/Plugins/Hashing/SpacePoint.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -#include -#include - -struct SpacePoint { - // Member variables - float m_x{}; - float m_y{}; - float m_z{}; - float m_r{}; - int layer{}; - float varianceR{}; - float varianceZ{}; - std::optional m_t; - std::optional varianceT; - - // Default constructor - SpacePoint() = default; - - // Constructor with parameters - SpacePoint(float x, float y, float z, float r, int l, float varR, float varZ, - std::optional t, std::optional varT) - : m_x(x), - m_y(y), - m_z(z), - m_r(r), - layer(l), - varianceR(varR), - varianceZ(varZ), - m_t(t), - varianceT(varT) {} - - // Member functions - float x() const { return m_x; } - float y() const { return m_y; } - float z() const { return m_z; } - float r() const { return m_r; } - std::optional t() const { return m_t; } - - // Equality operator - friend bool operator==(const SpacePoint &a, const SpacePoint &b) { - return std::abs(a.m_x - b.m_x) < 1e-6 && std::abs(a.m_y - b.m_y) < 1e-6 && - std::abs(a.m_z - b.m_z) < 1e-6; - } -};