diff --git a/Core/include/Acts/Seeding/ISourceLinkGrid.hpp b/Core/include/Acts/Seeding/ISourceLinkGrid.hpp deleted file mode 100644 index d1dbdd46bb2..00000000000 --- a/Core/include/Acts/Seeding/ISourceLinkGrid.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. - -#pragma once - -#include "Acts/Definitions/Algebra.hpp" -#include "Acts/EventData/SourceLink.hpp" -#include "Acts/Geometry/GeometryContext.hpp" -#include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/Grid.hpp" - -namespace Acts { - -/// @brief Interface class for binning source links -/// into a lookup table -- a grid of source links -/// -/// @tparam axis_t Type of the axis -/// -template -class ISourceLinkGrid { - using slGrid = Grid, axis_t, axis_t>; - - public: - /// @brief Virtual destructor - virtual ~ISourceLinkGrid() = default; - - /// @brief Interface function to sort - /// the source links into the grid - virtual void initialize(const GeometryContext& gctx, - std::vector sourceLinks) = 0; - - /// @brief Interface function to get the - /// grid of source links for a - /// given geometry identifier - virtual slGrid getSourceLinkTable(const GeometryIdentifier& geoId) const = 0; -}; - -} // namespace Acts diff --git a/Core/include/Acts/Seeding/PathSeeder.hpp b/Core/include/Acts/Seeding/PathSeeder.hpp index 29392862df1..780a00c805a 100644 --- a/Core/include/Acts/Seeding/PathSeeder.hpp +++ b/Core/include/Acts/Seeding/PathSeeder.hpp @@ -8,7 +8,6 @@ #pragma once -#include "Acts/Seeding/ISourceLinkGrid.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Delegate.hpp" @@ -39,9 +38,12 @@ namespace Acts::Experimental { /// /// @note Handling of the rotated surfaces has to happen /// in the user-defined delegate functions. -template + +template class PathSeeder { public: + using GridType = grid_t; + /// @brief The seed struct /// /// The seed struct contains the IP parameters @@ -66,9 +68,32 @@ class PathSeeder { : ipP(ipPmag), ipDir(std::move(ipPdir)), ipVertex(std::move(ipPos)), - sourceLinks(std::move(sls)) {}; + sourceLinks(std::move(sls)){}; }; + /// @brief Delegate to provide the relevant grid + /// filled with source links for the given geometry + /// member + /// + /// @arg The geometry identifier to use + /// + /// @return The grid filled with source links + using SourceLinkGridLookup = + Delegate; + + /// @brief Delegate to estimate the IP parameters + /// and the momentum direction at the first tracking layer + /// + /// @arg The geometry context to use + /// @arg The global position of the pivot source link + /// + /// @return Particle charge, the IP momentum magnitude, the IP vertex position, + /// the IP momentum direction, the momentum direction at the + /// first tracking layer + using TrackEstimator = Delegate< + const std::tuple( + const GeometryContext&, const Vector3&)>; + /// @brief Delegate to transform the source link to the /// appropriate global frame. /// @@ -77,20 +102,7 @@ class PathSeeder { /// /// @return The global position of the source link measurement using SourceLinkCalibrator = - Delegate; - - /// @brief Delegate to provide the path width around - /// the intersection point to pull the source links - /// from the grid - /// - /// @arg The geometry context to use - /// @arg The geometry identifier to use if the - /// path width is varied across different tracking layers - /// - /// @return The path width in the bin0 and bin1 direction - /// defined with respect to the surface normal - using PathWidthLookup = Delegate( - const GeometryContext&, const GeometryIdentifier&)>; + Delegate; /// @brief Delegate to find the intersections for the given pivot /// source link @@ -102,27 +114,27 @@ class PathSeeder { /// @arg The IP momentum magnitude /// @arg The particle charge using IntersectionLookup = - Delegate>( + Delegate>( const GeometryContext&, const Vector3&, const Vector3&, const ActsScalar&, const ActsScalar&)>; - /// @brief Delegate to estimate the IP parameters - /// and the momentum direction at the first tracking layer + /// @brief Delegate to provide the path width around + /// the intersection point to pull the source links + /// from the grid /// /// @arg The geometry context to use - /// @arg The global position of the pivot source link + /// @arg The geometry identifier to use if the + /// path width is varied across different tracking layers /// - /// @return Particle charge, the IP momentum magnitude, the IP vertex position, - /// the IP momentum direction, the momentum direction at the - /// first tracking layer - using TrackEstimator = - Delegate( - const GeometryContext&, const Vector3&)>; + /// @return The path width in the bin0 and bin1 direction + /// defined with respect to the surface normal + using PathWidthLookup = Delegate( + const GeometryContext&, const GeometryIdentifier&)>; /// @brief The nested configuration struct struct Config { /// Binned SourceLink provider - std::shared_ptr> sourceLinkGrid; + SourceLinkGridLookup sourceLinkGridLookup; /// Parameters estimator TrackEstimator trackEstimator; /// SourceLink calibrator @@ -138,7 +150,7 @@ class PathSeeder { }; /// @brief Constructor - PathSeeder(const Config& config) : m_cfg(std::move(config)) {}; + PathSeeder(const Config& config) : m_cfg(std::move(config)){}; /// @brief Destructor ~PathSeeder() = default; @@ -152,9 +164,6 @@ class PathSeeder { /// @return The vector of seeds std::vector getSeeds(const GeometryContext& gctx, const std::vector& sourceLinks) const { - // Sort the source links into the grid - m_cfg.sourceLinkGrid->initialize(gctx, sourceLinks); - // Get plane of the telescope // sensitive surfaces int bin0 = static_cast(BinningValue::binX); @@ -210,7 +219,7 @@ class PathSeeder { ActsScalar bot1 = refPoint[bin1] - pathWidth1; // Get the lookup table for the source links - auto grid = m_cfg.sourceLinkGrid->getSourceLinkTable(geoId); + auto grid = m_cfg.sourceLinkGridLookup(geoId); // Get the range of bins to search for source links auto botLeftBin = grid.localBinsFromPosition(Vector2(bot0, bot1)); diff --git a/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp b/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp index 648b7148602..871d93b802f 100644 --- a/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp +++ b/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp @@ -36,6 +36,7 @@ using namespace Acts; using namespace Acts::UnitLiterals; using Axis = Acts::Axis; +using Grid = Acts::Grid, Axis, Axis>; GeometryContext gctx; @@ -49,14 +50,14 @@ const ActsScalar deltaYZ = 1.; // region of interest for seeding class NoFieldIntersectionFinder { public: - ActsScalar tol = 1e-4; + ActsScalar m_tol = 1e-4; std::vector m_surfaces; // Find the intersections along the path // and return them in the order of the path // length - std::vector> operator()( + const std::vector> operator()( const GeometryContext& geoCtx, const Vector3& position, const Vector3& direction, [[maybe_unused]] const ActsScalar& Pmag = 0, [[maybe_unused]] const ActsScalar& Charge = 0) const { @@ -64,9 +65,9 @@ class NoFieldIntersectionFinder { // Intersect the surfaces for (auto& surface : m_surfaces) { // Get the intersection - auto sMultiIntersection = - surface->intersect(geoCtx, position, direction, - BoundaryTolerance::AbsoluteCartesian(tol, tol)); + auto sMultiIntersection = surface->intersect( + geoCtx, position, direction, + BoundaryTolerance::AbsoluteCartesian(m_tol, m_tol)); // Take the closest auto closestForward = sMultiIntersection.closestForward(); @@ -85,27 +86,27 @@ class NoFieldIntersectionFinder { // Grid to store the source links for // the seeding fast lookup -class SourceLinkGrid : public ISourceLinkGrid { +class SourceLinkGrid { public: - using eGrid = Grid, Axis, Axis>; + using GridType = Grid; /// Lookup table collection - std::unordered_map m_lookupTables; + std::unordered_map m_lookupTables; /// Surface accessor SourceLinkSurfaceAccessor m_surfaceAccessor; void initialize(const GeometryContext& geoCtx, - std::vector sourceLinks) override { + std::vector sourceLinks) { // Lookup table for each layer - std::unordered_map lookupTable; + std::unordered_map lookupTable; // Construct a binned grid for each layer for (int i : {14, 15, 16, 17}) { Axis xAxis(-halfY, halfY, 50); Axis yAxis(-halfZ, halfZ, 50); - eGrid grid(std::make_tuple(xAxis, yAxis)); + GridType grid(std::make_tuple(xAxis, yAxis)); lookupTable.insert({i, grid}); } // Fill the grid with source links @@ -127,7 +128,7 @@ class SourceLinkGrid : public ISourceLinkGrid { }; // Get the source link grid for a given geometry id - eGrid getSourceLinkTable(const GeometryIdentifier& geoId) const override { + const GridType operator()(const GeometryIdentifier& geoId) const { return m_lookupTables.at(geoId.sensitive()); } }; @@ -135,16 +136,10 @@ class SourceLinkGrid : public ISourceLinkGrid { // A simple path width provider to set // the grid lookup boundaries around the // intersection point -class PathWidthProvider { - public: - ActsScalar m_pathWidth = 0.1; - - std::pair operator()( - const GeometryContext& /*geoCtx*/, - const GeometryIdentifier& /*geoId*/) const { - return {m_pathWidth, m_pathWidth}; - } -}; +const std::pair getPathWidth( + const GeometryContext& /*gctx*/, const GeometryIdentifier& /*geoId*/) { + return {0.1, 0.1}; +} // Calibrator to transform the source links // to global coordinates @@ -152,8 +147,8 @@ class SourceLinkCalibrator { public: SourceLinkSurfaceAccessor m_surfaceAccessor; - Vector3 operator()(const GeometryContext& geoCtx, - const SourceLink& sourceLink) const { + const Vector3 operator()(const GeometryContext& geoCtx, + const SourceLink& sourceLink) const { auto ssl = sourceLink.get(); auto res = m_surfaceAccessor(sourceLink) ->localToGlobal(geoCtx, ssl.parameters, Vector3{0, 1, 0}); @@ -168,8 +163,8 @@ class TrackEstimator { public: Vector3 ip; - std::tuple operator()( - const GeometryContext& /*geoCtx*/, const Vector3& pivot) const { + const std::tuple + operator()(const GeometryContext& /*geoCtx*/, const Vector3& pivot) const { Vector3 direction = (pivot - ip).normalized(); return {1_e, 1._GeV, ip, direction, direction}; }; @@ -344,14 +339,15 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) { auto sourceLinks = createSourceLinks(gctx, *detector); // Prepare the PathSeeder - auto pathSeederCfg = Acts::Experimental::PathSeeder::Config(); + auto pathSeederCfg = Acts::Experimental::PathSeeder::Config(); // Grid to bin the source links SurfaceAccessor surfaceAccessor{*detector}; - auto sourceLinkGrid = std::make_shared(); - sourceLinkGrid->m_surfaceAccessor.connect<&SurfaceAccessor::operator()>( + SourceLinkGrid sourceLinkGrid; + sourceLinkGrid.m_surfaceAccessor.connect<&SurfaceAccessor::operator()>( &surfaceAccessor); - pathSeederCfg.sourceLinkGrid = sourceLinkGrid; + pathSeederCfg.sourceLinkGridLookup.connect<&SourceLinkGrid::operator()>( + &sourceLinkGrid); // Estimator of the IP and first hit // parameters of the track @@ -368,7 +364,7 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) { &sourceLinkCalibrator); // Intersection finder - auto intersectionFinder = NoFieldIntersectionFinder(); + NoFieldIntersectionFinder intersectionFinder; for (auto volume : detector->volumes()) { for (auto surface : volume->surfaces()) { intersectionFinder.m_surfaces.push_back(surface); @@ -378,9 +374,7 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) { .connect<&NoFieldIntersectionFinder::operator()>(&intersectionFinder); // Path width provider - auto pathWidthProvider = PathWidthProvider(); - pathSeederCfg.pathWidthProvider.connect<&PathWidthProvider::operator()>( - &pathWidthProvider); + pathSeederCfg.pathWidthProvider.connect<&getPathWidth>(); // First tracking layer Extent firstLayerExtent; @@ -391,9 +385,10 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) { pathSeederCfg.firstLayerExtent = firstLayerExtent; // Create the PathSeeder - Acts::Experimental::PathSeeder pathSeeder(pathSeederCfg); + Acts::Experimental::PathSeeder pathSeeder(pathSeederCfg); // Get the seeds + sourceLinkGrid.initialize(gctx, sourceLinks); auto seeds = pathSeeder.getSeeds(gctx, sourceLinks); // Check the seeds