Skip to content

Commit

Permalink
nitpicks and the sourcelink grid consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
ssdetlab committed Aug 19, 2024
1 parent d1e885d commit 0b93c91
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 111 deletions.
43 changes: 0 additions & 43 deletions Core/include/Acts/Seeding/ISourceLinkGrid.hpp

This file was deleted.

75 changes: 42 additions & 33 deletions Core/include/Acts/Seeding/PathSeeder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#pragma once

#include "Acts/Seeding/ISourceLinkGrid.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/Delegate.hpp"

Expand Down Expand Up @@ -39,9 +38,12 @@ namespace Acts::Experimental {
///
/// @note Handling of the rotated surfaces has to happen
/// in the user-defined delegate functions.
template <typename axis_t>

template <typename grid_t>
class PathSeeder {
public:
using GridType = grid_t;

/// @brief The seed struct
///
/// The seed struct contains the IP parameters
Expand All @@ -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<const GridType(const GeometryIdentifier&)>;

/// @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<ActsScalar, ActsScalar, Vector3, Vector3, Vector3>(
const GeometryContext&, const Vector3&)>;

/// @brief Delegate to transform the source link to the
/// appropriate global frame.
///
Expand All @@ -77,20 +102,7 @@ class PathSeeder {
///
/// @return The global position of the source link measurement
using SourceLinkCalibrator =
Delegate<Vector3(const GeometryContext&, const SourceLink&)>;

/// @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<std::pair<ActsScalar, ActsScalar>(
const GeometryContext&, const GeometryIdentifier&)>;
Delegate<const Vector3(const GeometryContext&, const SourceLink&)>;

/// @brief Delegate to find the intersections for the given pivot
/// source link
Expand All @@ -102,27 +114,27 @@ class PathSeeder {
/// @arg The IP momentum magnitude
/// @arg The particle charge
using IntersectionLookup =
Delegate<std::vector<std::pair<GeometryIdentifier, Vector3>>(
Delegate<const std::vector<std::pair<GeometryIdentifier, Vector3>>(
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<std::tuple<ActsScalar, ActsScalar, Vector3, Vector3, Vector3>(
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 std::pair<ActsScalar, ActsScalar>(
const GeometryContext&, const GeometryIdentifier&)>;

/// @brief The nested configuration struct
struct Config {
/// Binned SourceLink provider
std::shared_ptr<ISourceLinkGrid<axis_t>> sourceLinkGrid;
SourceLinkGridLookup sourceLinkGridLookup;
/// Parameters estimator
TrackEstimator trackEstimator;
/// SourceLink calibrator
Expand All @@ -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;
Expand All @@ -152,9 +164,6 @@ class PathSeeder {
/// @return The vector of seeds
std::vector<Seed> getSeeds(const GeometryContext& gctx,
const std::vector<SourceLink>& 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<int>(BinningValue::binX);
Expand Down Expand Up @@ -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));
Expand Down
65 changes: 30 additions & 35 deletions Tests/UnitTests/Core/Seeding/PathSeederTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ using namespace Acts;
using namespace Acts::UnitLiterals;

using Axis = Acts::Axis<AxisType::Equidistant, AxisBoundaryType::Open>;
using Grid = Acts::Grid<std::vector<SourceLink>, Axis, Axis>;

GeometryContext gctx;

Expand All @@ -49,24 +50,24 @@ const ActsScalar deltaYZ = 1.;
// region of interest for seeding
class NoFieldIntersectionFinder {
public:
ActsScalar tol = 1e-4;
ActsScalar m_tol = 1e-4;

std::vector<const Surface*> m_surfaces;

// Find the intersections along the path
// and return them in the order of the path
// length
std::vector<std::pair<GeometryIdentifier, Vector3>> operator()(
const std::vector<std::pair<GeometryIdentifier, Vector3>> operator()(
const GeometryContext& geoCtx, const Vector3& position,
const Vector3& direction, [[maybe_unused]] const ActsScalar& Pmag = 0,
[[maybe_unused]] const ActsScalar& Charge = 0) const {
std::vector<std::pair<GeometryIdentifier, Vector3>> sIntersections;
// 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();
Expand All @@ -85,27 +86,27 @@ class NoFieldIntersectionFinder {

// Grid to store the source links for
// the seeding fast lookup
class SourceLinkGrid : public ISourceLinkGrid<Axis> {
class SourceLinkGrid {
public:
using eGrid = Grid<std::vector<SourceLink>, Axis, Axis>;
using GridType = Grid;

/// Lookup table collection
std::unordered_map<int, eGrid> m_lookupTables;
std::unordered_map<int, GridType> m_lookupTables;

/// Surface accessor
SourceLinkSurfaceAccessor m_surfaceAccessor;

void initialize(const GeometryContext& geoCtx,
std::vector<SourceLink> sourceLinks) override {
std::vector<SourceLink> sourceLinks) {
// Lookup table for each layer
std::unordered_map<int, eGrid> lookupTable;
std::unordered_map<int, GridType> 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
Expand All @@ -127,33 +128,27 @@ class SourceLinkGrid : public ISourceLinkGrid<Axis> {
};

// 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());
}
};

// 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<ActsScalar, ActsScalar> operator()(
const GeometryContext& /*geoCtx*/,
const GeometryIdentifier& /*geoId*/) const {
return {m_pathWidth, m_pathWidth};
}
};
const std::pair<ActsScalar, ActsScalar> getPathWidth(
const GeometryContext& /*gctx*/, const GeometryIdentifier& /*geoId*/) {
return {0.1, 0.1};
}

// Calibrator to transform the source links
// to global coordinates
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<detail::Test::TestSourceLink>();
auto res = m_surfaceAccessor(sourceLink)
->localToGlobal(geoCtx, ssl.parameters, Vector3{0, 1, 0});
Expand All @@ -168,8 +163,8 @@ class TrackEstimator {
public:
Vector3 ip;

std::tuple<ActsScalar, ActsScalar, Vector3, Vector3, Vector3> operator()(
const GeometryContext& /*geoCtx*/, const Vector3& pivot) const {
const std::tuple<ActsScalar, ActsScalar, Vector3, Vector3, Vector3>
operator()(const GeometryContext& /*geoCtx*/, const Vector3& pivot) const {
Vector3 direction = (pivot - ip).normalized();
return {1_e, 1._GeV, ip, direction, direction};
};
Expand Down Expand Up @@ -344,14 +339,15 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) {
auto sourceLinks = createSourceLinks(gctx, *detector);

// Prepare the PathSeeder
auto pathSeederCfg = Acts::Experimental::PathSeeder<Axis>::Config();
auto pathSeederCfg = Acts::Experimental::PathSeeder<Grid>::Config();

// Grid to bin the source links
SurfaceAccessor surfaceAccessor{*detector};
auto sourceLinkGrid = std::make_shared<SourceLinkGrid>();
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
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -391,9 +385,10 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) {
pathSeederCfg.firstLayerExtent = firstLayerExtent;

// Create the PathSeeder
Acts::Experimental::PathSeeder<Axis> pathSeeder(pathSeederCfg);
Acts::Experimental::PathSeeder<Grid> pathSeeder(pathSeederCfg);

// Get the seeds
sourceLinkGrid.initialize(gctx, sourceLinks);
auto seeds = pathSeeder.getSeeds(gctx, sourceLinks);

// Check the seeds
Expand Down

0 comments on commit 0b93c91

Please sign in to comment.