Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Telescope style seeding #3300

Merged
merged 40 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
86713c0
Adding telescope style seeding
ssdetlab Jun 17, 2024
07f8efd
Merge branch 'acts-project:main' into telescope-style-seeding
ssdetlab Jun 17, 2024
7bc1aad
format
ssdetlab Jun 17, 2024
e51586a
minor test fix
ssdetlab Jun 17, 2024
51c71de
pedantic fix
ssdetlab Jun 17, 2024
1bec75f
tidy fixes
ssdetlab Jun 17, 2024
048f6d4
another tidy fix
ssdetlab Jun 17, 2024
46315b1
Merge branch 'main' into telescope-style-seeding
ssdetlab Jul 11, 2024
d5f8637
remove Measurement
ssdetlab Jul 11, 2024
bd30406
fixing includes
ssdetlab Jul 11, 2024
972d0e7
compatibility fixes
ssdetlab Jul 11, 2024
a68e6d7
cleanup
ssdetlab Jul 11, 2024
149c281
test commit
ssdetlab Jul 11, 2024
a995477
bumping the CI test
ssdetlab Jul 11, 2024
5c7a143
Merge branch 'main' into telescope-style-seeding
ssdetlab Jul 11, 2024
77e6c5c
Merge branch 'main' into telescope-style-seeding
ssdetlab Jul 13, 2024
eb93785
Update .gitlab-ci.yml
ssdetlab Jul 13, 2024
b94447a
Merge branch 'main' into telescope-style-seeding
asalzburger Jul 18, 2024
851fe88
Merge branch 'main' into telescope-style-seeding
ssdetlab Jul 25, 2024
acac6e4
Experimental namespace and charge
ssdetlab Jul 25, 2024
42d5e23
format
ssdetlab Jul 25, 2024
4591ce9
Merge branch 'main' into telescope-style-seeding
ssdetlab Aug 4, 2024
54053ba
temporarily fix the tests
ssdetlab Aug 4, 2024
468124f
expanding documentation
ssdetlab Aug 4, 2024
ef37fbd
Merge branch 'main' into telescope-style-seeding
ssdetlab Aug 6, 2024
fa32185
reconcile test source link
ssdetlab Aug 6, 2024
b345633
format
ssdetlab Aug 6, 2024
e39d99b
alignment fix
ssdetlab Aug 6, 2024
439716c
tidy fix
ssdetlab Aug 6, 2024
4d478e1
format
ssdetlab Aug 7, 2024
27c5af6
Merge branch 'main' into telescope-style-seeding
asalzburger Aug 7, 2024
69f8988
Merge branch 'main' into telescope-style-seeding
asalzburger Aug 15, 2024
2f0bc02
Merge branch 'main' into telescope-style-seeding
asalzburger Aug 15, 2024
d1e885d
lint fixes
ssdetlab Aug 15, 2024
0b93c91
nitpicks and the sourcelink grid consistency
ssdetlab Aug 19, 2024
abf2e64
lint fixes
ssdetlab Aug 19, 2024
69cdca0
missing includes
ssdetlab Aug 19, 2024
a98a692
lint
ssdetlab Aug 19, 2024
e258805
cleanup
ssdetlab Aug 21, 2024
133e026
Merge branch 'main' into telescope-style-seeding
paulgessinger Aug 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Core/include/Acts/Seeding/ISourceLinkGrid.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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 <typename axis_t>
class ISourceLinkGrid {
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved
using slGrid = Grid<std::vector<SourceLink>, axis_t, axis_t>;
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved

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<SourceLink> 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
250 changes: 250 additions & 0 deletions Core/include/Acts/Seeding/PathSeeder.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
// 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/Seeding/ISourceLinkGrid.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/Delegate.hpp"

namespace Acts::Experimental {

/// @brief Seeding algorigthm that extracts
/// the IP parameters and sorts the source links
/// into possible track candidates
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved
///
/// The algorithm to convert the given source links
/// into seeds -- pairs of IP parameters and the corresponding
/// source links -- as follows: First the source links
/// are sorted into a user-defined grid. Then, iteration over the source links
/// is performed. If a source link is attached to a surface that is
/// in the first tracking layer, as defined by the user, the IP parameters
/// are estimated and the tracking layers are intersected to construct the
/// core of the "Path". The source links in the subsequent layers are then
/// added to the seed if they lie within the path width of the core.
/// Both the list of source links and the IP parameters are stored in the seed
/// struct.
///
/// @tparam axis_t Type of the axis to bin
/// the source links
///
/// @note The algorithm is designed to be used in the
/// context of a telescope-style geometry. The surfaces
/// are assumed to be planar.
///
/// @note Handling of the rotated surfaces has to happen
/// in the user-defined delegate functions.
template <typename axis_t>
class PathSeeder {
public:
/// @brief The seed struct
///
/// The seed struct contains the IP parameters
/// and the source links that are associated with
/// the seed.
struct Seed {
/// The IP momentum magnitude
ActsScalar ipP;

/// The IP momentum direction
Vector3 ipDir;

/// The IP vertex position
Vector3 ipVertex;

/// The source links associated with the seed
std::vector<SourceLink> sourceLinks;

Seed() = delete;
Seed(ActsScalar ipPmag, Vector3 ipPdir, Vector3 ipPos,
std::vector<SourceLink> sls)
: ipP(ipPmag),
ipDir(std::move(ipPdir)),
ipVertex(std::move(ipPos)),
sourceLinks(std::move(sls)){};
};

/// @brief Delegate to transform the source link to the
/// appropriate global frame.
///
/// @arg The geometry context to use
/// @arg The source link to calibrate
///
/// @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&)>;

/// @brief Delegate to find the intersections for the given pivot
/// source link
///
/// @arg The geometry context to use
/// @arg The global position of the pivot source link
/// @arg The momentum direction of the pivot source link
/// at the first tracking layer
/// @arg The IP momentum magnitude
/// @arg The particle charge
using IntersectionLookup =
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved
Delegate<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
///
/// @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<std::tuple<ActsScalar, ActsScalar, Vector3, Vector3, Vector3>(
const GeometryContext&, const Vector3&)>;

/// @brief The nested configuration struct
struct Config {
/// Binned SourceLink provider
std::shared_ptr<ISourceLinkGrid<axis_t>> sourceLinkGrid;
/// Parameters estimator
TrackEstimator trackEstimator;
/// SourceLink calibrator
SourceLinkCalibrator sourceLinkCalibrator;
/// Intersection finder
IntersectionLookup intersectionFinder;
/// Path width provider
PathWidthLookup pathWidthProvider;
/// First layer extent
Extent firstLayerExtent;
paulgessinger marked this conversation as resolved.
Show resolved Hide resolved
/// Direction of the telescope extent
BinningValue orientation = BinningValue::binX;
};

/// @brief Constructor
PathSeeder(const Config& config) : m_cfg(std::move(config)){};

/// @brief Destructor
~PathSeeder() = default;

/// @brief Extract the IP parameters and
/// sort the source links into the seeds
///
/// @param gctx The geometry context
/// @param sourceLinks The source links to seed
///
/// @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);
int bin1 = static_cast<int>(BinningValue::binY);
if (m_cfg.orientation == BinningValue::binX) {
bin0 = static_cast<int>(BinningValue::binY);
bin1 = static_cast<int>(BinningValue::binZ);
} else if (m_cfg.orientation == BinningValue::binY) {
bin0 = static_cast<int>(BinningValue::binX);
bin1 = static_cast<int>(BinningValue::binZ);
}

// Create the seeds
std::vector<Seed> seeds;
for (const auto& sl : sourceLinks) {
Vector3 globalPos = m_cfg.sourceLinkCalibrator(gctx, sl);

// Check if the hit is in the
// first tracking layer
if (!m_cfg.firstLayerExtent.contains(globalPos)) {
continue;
}

// Get the IP parameters
auto [q, ipP, ipVertex, ipDir, flDir] =
m_cfg.trackEstimator(gctx, globalPos);

// Intersect with the surfaces
std::vector<std::pair<GeometryIdentifier, Vector3>> intersections =
m_cfg.intersectionFinder(gctx, globalPos, flDir, ipP, q);

// Continue if no intersections
if (intersections.empty()) {
continue;
}
// Vector to store the source links
std::vector<SourceLink> seedSourceLinks;

// Store the pivot source link
seedSourceLinks.push_back(sl);

// Iterate over the intersections
// and get the source links
// in the subsequent layers
for (auto& [geoId, refPoint] : intersections) {
// Get the path width
auto [pathWidth0, pathWidth1] = m_cfg.pathWidthProvider(gctx, geoId);

// Get the bounds of the path
ActsScalar top0 = refPoint[bin0] + pathWidth0;
ActsScalar bot0 = refPoint[bin0] - pathWidth0;
ActsScalar top1 = refPoint[bin1] + pathWidth1;
ActsScalar bot1 = refPoint[bin1] - pathWidth1;
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved

// Get the lookup table for the source links
auto grid = m_cfg.sourceLinkGrid->getSourceLinkTable(geoId);

// Get the range of bins to search for source links
auto botLeftBin = grid.localBinsFromPosition(Vector2(bot0, bot1));
auto topRightBin = grid.localBinsFromPosition(Vector2(top0, top1));

// Get the source links from the lookup table
// by iterating over the bin ranges
auto currentBin = botLeftBin;
while (currentBin.at(1) <= topRightBin.at(1)) {
while (currentBin.at(0) <= topRightBin.at(0)) {
auto sourceLinksToAdd = grid.atLocalBins(currentBin);

seedSourceLinks.insert(seedSourceLinks.end(),
sourceLinksToAdd.begin(),
sourceLinksToAdd.end());
currentBin.at(0)++;
}
currentBin.at(1)++;
currentBin.at(0) = botLeftBin.at(0);
}
}
ssdetlab marked this conversation as resolved.
Show resolved Hide resolved

// Store the IP parameters and
// add the source links to the seed
Seed seed{ipP, ipDir, ipVertex, seedSourceLinks};

// Add the seed to the list
seeds.push_back(seed);
}
return seeds;
};

private:
Config m_cfg;
};

} // namespace Acts::Experimental
1 change: 1 addition & 0 deletions Tests/UnitTests/Core/Seeding/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ target_link_libraries(ActsUnitTestSeedFinder PRIVATE ActsCore Boost::boost)

add_unittest(EstimateTrackParamsFromSeed EstimateTrackParamsFromSeedTest.cpp)
add_unittest(BinnedGroupTest BinnedGroupTest.cpp)
add_unittest(PathSeeder PathSeederTest.cpp)
add_unittest(HoughTransformTest HoughTransformTest.cpp)
add_unittest(UtilityFunctions UtilityFunctionsTests.cpp)
add_unittest(CandidatesForMiddleSp CandidatesForMiddleSpTests.cpp)
Loading
Loading