Skip to content

refactor!: Clean up triplet seeding config structs and grid API - #6004

Merged
andiwand merged 4 commits into
acts-project:mainfrom
andiwand:refactor-seeding-config-api
Sep 16, 2026
Merged

andiwand merged 4 commits into
acts-project:mainfrom
andiwand:refactor-seeding-config-api

Conversation

@andiwand

@andiwand andiwand commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

A pass over the configuration surface of the triplet seeder and the space
point grids. Seeding output is unchanged.

The three space point grid configs held the bottom and top bin finder in a
std::optional, although neither is optional: every constructor calls
.value() unconditionally, so forgetting one surfaced as an unmessaged
std::bad_optional_access. They are plain members now, with a default member
initializer giving one neighbour on either side per axis, which is what every
call site already set.

The grids are no longer copyable or movable. BinnedGroup keeps pointers to
the bin finders, which live in the grid's own copy of the config, and the base
class keeps a pointer into the binned group, so a move left both referring to
the source object.

spacePointsSortedByRadius, cotThetaDiffMax, absDeltaEtaWeightFactor and
absDeltaEtaMinImpact were missing from the seeding JSON converters and reset
to their defaults on a round trip. The converters themselves moved from
Acts::Experimental to Acts, where the types they convert live, so that ADL
can find them at all.

The rest is consistency. Config validation in the cylindrical and spherical
grids throws std::invalid_argument like the cartesian one and BinnedGroup.
The seeding configs use fixed width integers, and the grid dimension comes from
the grid type instead of a hard coded 3ul. deltaEtaMax is a bin width, so
it is etaBinSize. The doc comments for useStripInfo, cotThetaDiffMax and
computeCoordRange describe what the code does, and two dead members of
GridTripletSeedingAlgorithm are gone.

A pass over the configuration surface of the triplet seeder and the space
point grids. Seeding output is unchanged.

The three space point grid configs held the bottom and top bin finder in a
`std::optional`, although neither is optional: every constructor calls
`.value()` unconditionally, so forgetting one surfaced as an unmessaged
`std::bad_optional_access`. They are plain members now, with a default member
initializer giving one neighbour on either side per axis, which is what every
call site already set.

The grids are no longer copyable or movable. `BinnedGroup` keeps pointers to
the bin finders, which live in the grid's own copy of the config, and the base
class keeps a pointer into the binned group, so a move left both referring to
the source object.

`spacePointsSortedByRadius`, `cotThetaDiffMax`, `absDeltaEtaWeightFactor` and
`absDeltaEtaMinImpact` were missing from the seeding JSON converters and reset
to their defaults on a round trip. The converters themselves moved from
`Acts::Experimental` to `Acts`, where the types they convert live, so that ADL
can find them at all.

The rest is consistency. Config validation in the cylindrical and spherical
grids throws `std::invalid_argument` like the cartesian one and `BinnedGroup`.
The seeding configs use fixed width integers, and the grid dimension comes from
the grid type instead of a hard coded `3ul`. `deltaEtaMax` is a bin width, so
it is `etaBinSize`. The doc comments for `useStripInfo`, `cotThetaDiffMax` and
`computeCoordRange` describe what the code does, and two dead members of
`GridTripletSeedingAlgorithm` are gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017H4TWxPuRU6gxSwMfZPfFp
@andiwand

andiwand commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Review guide

The optional. GridBinFinder has no default constructor, because its two
user-declared constructors (variadic and array) suppress the implicit one. That
is why the config member was a std::optional. It turns out no default
constructor is needed: a default member initializer can call the variadic
constructor directly, and a member with an NSDMI keeps Config
default-constructible even though its type is not.

GridBinFinder<GridType::DIM> bottomBinFinder{1, 1, 0};

The alternative, GridBinFinder() = default;, would have worked too, but its
std::array<std::variant<int, ...>, DIM> value-initializes to int{} == 0,
which getSizePerAxis turns into {-0, 0} — only the bin itself. A forgotten
config would then silently seed on single bins instead of failing. {1, 1, 0}
is what all three call sites set, and matches the convention GridBinFinder
already documents for an empty per-axis vector.

The move. BinnedGroup stores const GridBinFinder<DIM>*, bound to the
reference initializeGrid is handed — which is m_cfg.bottomBinFinder, a
member of the grid itself. SpacePointGridBase::m_grid likewise points into
m_binnedGroup. BinnedGroup deletes copy but defaults move, and the grids
declared nothing, so auto g2 = std::move(g1); compiled and left g2 pointing
at g1. Deleting copy and move on the CRTP base propagates to all three grids;
no call site constructs a grid any way other than in place.

Namespace of the JSON converters. They were declared in
Acts::Experimental, but DoubletSeedFinder, TripletSeedFinder,
BroadTripletSeedFilter and CylindricalSpacePointGrid are all in plain
Acts, so ADL never found them and nlohmann::json j = cfg; did not compile —
only an explicit Acts::Experimental::to_json(j, cfg) worked.
SeedConfirmationRangeConfig, right above them in the same header, was already
in Acts. The file has no callers yet, so nothing outside it changed.

What the type changes do and do not touch. navigation keeps
std::size_t: it holds grid-local bin indices and has to match
BinnedGroup's parameter type, so narrowing it would pull in BinnedGroup,
BinnedGroupIterator and Grid. numPhiNeighbors in
GridTripletSeedingAlgorithm::Config also stays int, because
GridBinFinder's variadic constructor constrains each argument to exactly
int, std::pair<int, int> or std::vector<std::pair<int, int>>.
computeSpacePointGridPhiBins now returns std::uint32_t; deltaPhi > 0 is
already guaranteed by the check above the cast, so the value is identical to
the old int.

Behaviour. The only observable differences are the exception type from
grid config validation, and that a completely unconfigured grid config now
builds a ±1/±1/0 grid instead of throwing bad_optional_access. Every
configured caller is unaffected — the JSON converter, the unit test and
GridTripletSeedingAlgorithm all set the same values as before.

Checked locally. Full build clean apart from a pre-existing local DD4hep
ROOT-dictionary failure, python bindings relinked. ctest -R "Seed|Grid|Json|Triplet|Doublet" passes 38/39; the exception is
StrawLineSeederTest, which fails identically before the change because ROOT
cannot load libRIO/libCling in this environment.

Left for follow-ups. The view parameters of DoubletSeedFinder and
TripletSeedFinder are taken by mutable reference and consumed
(candidateSps = candidateSps.subrange(offset)), which is deliberate but
undocumented, and TripletSeeder::createSeedsFromGroup's bottomSps/topSps
are non-const without being mutated. That is orthogonal to this PR and will get
its own branch. The duplication of minPt, impactMax, helixCutTolerance,
cotThetaMax and deltaRMax across the grid, doublet and triplet configs is
intentional for now and untouched.

@andiwand andiwand changed the title refactor: Clean up triplet seeding config structs and grid API refactor!: Clean up triplet seeding config structs and grid API Sep 2, 2026
@github-actions github-actions Bot added this to the next milestone Sep 2, 2026
@github-actions github-actions Bot added Component - Core Affects the Core module Component - Examples Affects the Examples module Component - Plugins Affects one or more Plugins Seeding Track Finding API breaking labels Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Public API surface diff

+0 added, 13 breaking.

⚠️ Breaking API changes (source-level)

Retyped public data members (13)
  • Acts::BroadTripletSeedFilter::Config::compatSeedLimit: std::size_t -> std::uint32_t
  • Acts::BroadTripletSeedFilter::Config::maxSeedsPerSpM: unsigned int -> std::uint32_t
  • Acts::CartesianSpacePointGrid::Config::bottomBinFinder: std::optional< GridBinFinder< 3ul > > -> GridBinFinder< GridType::DIM >
  • Acts::CartesianSpacePointGrid::Config::nXbins: int -> std::uint32_t
  • Acts::CartesianSpacePointGrid::Config::nYbins: int -> std::uint32_t
  • Acts::CartesianSpacePointGrid::Config::nZbins: int -> std::uint32_t
  • Acts::CartesianSpacePointGrid::Config::navigation: std::array< std::vector< std::size_t >, 3ul > -> std::array< std::vector< std::size_t >, GridType::DIM >
  • Acts::CartesianSpacePointGrid::Config::topBinFinder: std::optional< GridBinFinder< 3ul > > -> GridBinFinder< GridType::DIM >
  • Acts::CylindricalSpacePointGrid::Config::bottomBinFinder: std::optional< GridBinFinder< 3ul > > -> GridBinFinder< GridType::DIM >
  • Acts::CylindricalSpacePointGrid::Config::maxPhiBins: int -> std::uint32_t
  • Acts::CylindricalSpacePointGrid::Config::navigation: std::array< std::vector< std::size_t >, 3ul > -> std::array< std::vector< std::size_t >, GridType::DIM >
  • Acts::CylindricalSpacePointGrid::Config::phiBinDeflectionCoverage: int -> std::uint32_t
  • Acts::CylindricalSpacePointGrid::Config::topBinFinder: std::optional< GridBinFinder< 3ul > > -> GridBinFinder< GridType::DIM >

@andiwand
andiwand marked this pull request as ready for review September 16, 2026 06:20
@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

📊: Physics performance monitoring for e2a3626

Full contents

physmon summary

❗️: Downstream build failure

  • Key4hep (cc @acts-project/key4hep-contacts)

Comment thread Core/include/Acts/Seeding/detail/SpacePointGridBase.hpp Outdated
paulgessinger
paulgessinger previously approved these changes Sep 16, 2026

@paulgessinger paulgessinger left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, one sonar issue

Comment thread Core/include/Acts/Seeding/SphericalSpacePointGrid.hpp Outdated
Co-authored-by: Paul Gessinger <hello@paulgessinger.com>
@sonarqubecloud

Copy link
Copy Markdown

@andiwand
andiwand added this pull request to the merge queue Sep 16, 2026
Merged via the queue into acts-project:main with commit 6274f29 Sep 16, 2026
39 checks passed
@andiwand
andiwand deleted the refactor-seeding-config-api branch September 17, 2026 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API breaking Component - Core Affects the Core module Component - Examples Affects the Examples module Component - Plugins Affects one or more Plugins Seeding Track Finding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants