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

refactor!: Middle range strategy #3719

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
53 changes: 33 additions & 20 deletions Core/include/Acts/Seeding/SeedFinder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,21 @@
#include <string>
#include <utility>
#include <vector>
#include <ranges>

namespace Acts {

template <typename Coll>
concept GridBinCollection =
std::ranges::random_access_range<Coll> &&
std::same_as<typename Coll::value_type, std::size_t>;

template <typename Coll, typename external_t, std::size_t N = 3ul>
concept CollectionStoresSeedsTo = requires(Coll coll, external_t sp) {
Acts::detail::pushBackOrInsertAtEnd(coll,
Acts::Seed<external_t, N>(sp, sp, sp));
};

enum class SpacePointCandidateType : short { eBottom, eTop };

enum class DetectorMeasurementInfo : short { eDefault, eDetailed };
Expand All @@ -44,33 +56,34 @@ class SeedFinder {
public:
struct SeedingState {
// bottom space point
std::vector<const external_spacepoint_t*> compatBottomSP;
std::vector<const external_spacepoint_t*> compatTopSP;
std::vector<const external_spacepoint_t*> compatBottomSP{};
std::vector<const external_spacepoint_t*> compatTopSP{};
// contains parameters required to calculate circle with linear equation
// ...for bottom-middle
std::vector<LinCircle> linCircleBottom;
std::vector<LinCircle> linCircleBottom{};
// ...for middle-top
std::vector<LinCircle> linCircleTop;
std::vector<LinCircle> linCircleTop{};

// create vectors here to avoid reallocation in each loop
std::vector<const external_spacepoint_t*> topSpVec;
std::vector<float> curvatures;
std::vector<float> impactParameters;
std::vector<const external_spacepoint_t*> topSpVec{};
std::vector<float> curvatures{};
std::vector<float> impactParameters{};

// managing seed candidates for SpM
CandidatesForMiddleSp<const external_spacepoint_t> candidates_collector;
CandidatesForMiddleSp<const external_spacepoint_t> candidates_collector{};

// managing doublet candidates
boost::container::small_vector<Acts::Neighbour<grid_t>,
Acts::detail::ipow(3, grid_t::DIM)>
bottomNeighbours;
bottomNeighbours{};
boost::container::small_vector<Acts::Neighbour<grid_t>,
Acts::detail::ipow(3, grid_t::DIM)>
topNeighbours;
topNeighbours{};

// Mutable variables for Space points used in the seeding
Acts::SpacePointMutableData spacePointMutableData;
Acts::SpacePointMutableData spacePointMutableData{};
};


/// The only constructor. Requires a config object.
/// @param config the configuration for the SeedFinder
Expand All @@ -94,28 +107,28 @@ class SeedFinder {
/// @param bottomSPs group of space points to be used as innermost SP in a seed.
/// @param middleSPs group of space points to be used as middle SP in a seed.
/// @param topSPs group of space points to be used as outermost SP in a seed.
/// @param rMiddleSPRange range object containing the minimum and maximum r for middle SP for a certain z bin.
/// @note Ranges must return pointers.
/// @note Ranges must be separate objects for each parallel call.
template <typename container_t, typename sp_range_t>
template <typename container_t,
Acts::GridBinCollection sp_range_t>
requires Acts::CollectionStoresSeedsTo<container_t, external_spacepoint_t, 3ul>
void createSeedsForGroup(const Acts::SeedFinderOptions& options,
SeedingState& state, const grid_t& grid,
container_t& outputCollection,
const sp_range_t& bottomSPs,
const std::size_t middleSPs,
const sp_range_t& topSPs,
const Acts::Range1D<float>& rMiddleSPRange) const;
const sp_range_t& topSPs) const;

private:
/// Given a middle space point candidate, get the proper radius validity range
/// Given a middle space point candidate get the proper radius validity range
/// 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
/// retrieve the proper range We can do it this computation only once, since
/// all the middle space point candidates belong to the same z-bin
/// @param options frequently changing configuration (like beam position)
/// @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<float, float> retrieveRadiusRangeForMiddle(
const external_spacepoint_t& spM,
const Acts::Range1D<float>& rMiddleSPRange) const;
const Acts::SeedFinderOptions& options,
const external_spacepoint_t& spM) const;

/// Iterates over dublets and tests the compatibility between them by applying
/// a series of cuts that can be tested with only two SPs
Expand Down
75 changes: 45 additions & 30 deletions Core/include/Acts/Seeding/SeedFinder.ipp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// -*- C++ -*-
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️

// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
Expand Down Expand Up @@ -36,13 +37,13 @@ SeedFinder<external_spacepoint_t, grid_t, platform_t>::SeedFinder(
}

template <typename external_spacepoint_t, typename grid_t, typename platform_t>
template <typename container_t, typename sp_range_t>
template <typename container_t, Acts::GridBinCollection sp_range_t>
requires Acts::CollectionStoresSeedsTo<container_t, external_spacepoint_t, 3ul>
void SeedFinder<external_spacepoint_t, grid_t, platform_t>::createSeedsForGroup(
const Acts::SeedFinderOptions& options, SeedingState& state,
const grid_t& grid, container_t& outputCollection,
const sp_range_t& bottomSPsIdx, const std::size_t middleSPsIdx,
const sp_range_t& topSPsIdx,
const Acts::Range1D<float>& rMiddleSPRange) const {
const sp_range_t& topSPsIdx) const {
if (!options.isInInternalUnits) {
throw std::runtime_error(
"SeedFinderOptions not in ACTS internal units in SeedFinder");
Expand Down Expand Up @@ -104,20 +105,23 @@ void SeedFinder<external_spacepoint_t, grid_t, platform_t>::createSeedsForGroup(
return;
}

// we compute this here since all middle space point candidates belong to the
// same z-bin
// we compute this since all middle space point candidates belong to the same
// z-bin
auto [minRadiusRangeForMiddle, maxRadiusRangeForMiddle] =
retrieveRadiusRangeForMiddle(*middleSPs.front(), rMiddleSPRange);
retrieveRadiusRangeForMiddle(options, *middleSPs.front());
for (const external_spacepoint_t* spM : middleSPs) {
const float rM = spM->radius();

// check if spM is outside our radial region of interest
if (rM < minRadiusRangeForMiddle) {
continue;
}
if (rM > maxRadiusRangeForMiddle) {
// break because SPs are sorted in r
break;
// Unless we rely on the grid, we need to check if the middle space point
// is in a valid radius range
if(m_config.middleRangeStrategy != Acts::SeedFinding::MiddleRadialStrategy::RelyOnGrid) {
if (rM < minRadiusRangeForMiddle) {
continue;
}
if (rM > maxRadiusRangeForMiddle) {
// break because SPs are sorted in r
break;
}
}

const float zM = spM->z();
Expand Down Expand Up @@ -187,6 +191,7 @@ void SeedFinder<external_spacepoint_t, grid_t, platform_t>::createSeedsForGroup(
} // loop on mediums
}


template <typename external_spacepoint_t, typename grid_t, typename platform_t>
template <Acts::SpacePointCandidateType candidateType, typename out_range_t>
inline void
Expand Down Expand Up @@ -809,23 +814,33 @@ SeedFinder<external_spacepoint_t, grid_t, platform_t>::filterCandidates(

template <typename external_spacepoint_t, typename grid_t, typename platform_t>
std::pair<float, float> SeedFinder<external_spacepoint_t, grid_t, platform_t>::
retrieveRadiusRangeForMiddle(
const external_spacepoint_t& spM,
const Acts::Range1D<float>& rMiddleSPRange) const {
if (m_config.useVariableMiddleSPRange) {
return std::make_pair(rMiddleSPRange.min(), rMiddleSPRange.max());
}
if (!m_config.rRangeMiddleSP.empty()) {
/// get zBin position of the middle SP
auto pVal = std::lower_bound(m_config.zBinEdges.begin(),
m_config.zBinEdges.end(), spM.z());
int zBin = std::distance(m_config.zBinEdges.begin(), pVal);
/// protects against zM at the limit of zBinEdges
zBin == 0 ? zBin : --zBin;
return std::make_pair(m_config.rRangeMiddleSP[zBin][0],
m_config.rRangeMiddleSP[zBin][1]);
}
return std::make_pair(m_config.rMinMiddle, m_config.rMaxMiddle);
retrieveRadiusRangeForMiddle(const Acts::SeedFinderOptions& options,
const external_spacepoint_t& spM) const {

switch(m_config.middleRangeStrategy) {
using enum Acts::SeedFinding::MiddleRadialStrategy;
case RelyOnGrid:
// The grid makes sure the middle space point is in the proper range
// no need to check
return {};
case UserRange:
// Range provided by the user in the options
return std::make_pair(options.rMinMiddle, options.rMaxMiddle);
case VariableRange:
{
// The range depends on the z-bin. Needs some computation
/// get zBin position of the middle SP
auto pVal = std::lower_bound(m_config.zBinEdges.begin(),
m_config.zBinEdges.end(), spM.z());
int zBin = std::distance(m_config.zBinEdges.begin(), pVal);
/// protects against zM at the limit of zBinEdges
zBin == 0 ? zBin : --zBin;
return std::make_pair(m_config.rRangeMiddleSP[zBin][0],
m_config.rRangeMiddleSP[zBin][1]);
}
default:
throw std::runtime_error("MiddleRadialStrategy is not recognized");
};
}

} // namespace Acts
Loading
Loading