Skip to content

feat: Write track parameter performance from track states in a geometry region - #5882

Open
andiwand wants to merge 8 commits into
acts-project:mainfrom
andiwand:track-state-parameter-performance
Open

feat: Write track parameter performance from track states in a geometry region#5882
andiwand wants to merge 8 commits into
acts-project:mainfrom
andiwand:track-state-parameter-performance

Conversation

@andiwand

@andiwand andiwand commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

RootTrackParameterPerformanceWriter gains parameterSource = TrackState: it
compares every measurement state of a track to the truth on the surface that
state sits on, instead of the track reference parameters to the truth particle.
geometrySelection narrows that to a geometry region, so a single volume or
layer can be looked at on its own, and parameterType picks predicted,
filtered, smoothed or unbiased parameters.

Comparing on the state's own surface is what makes a per-sensor estimate
measurable at all. Extrapolating to a common reference first, as
TrackExtrapolationAlgorithm does, answers a different question; this is the
local half.

Supporting it: truthParametersOnSurface and recoParametersOnSurface in the
new ParametersOnSurface.hpp, a ResPlotTool::fill overload taking the truth
as bound parameters on the fitted surface, and
addTrackStateParameterPerformanceWriter in python, whose
defaultOnSurfaceResPlotToolConfig names the local parameters loc0/loc1
rather than d0/z0, which only mean something on a line surface.
ResPlotTool now names the offending key when varBinning or paramNames
does not cover the bound parameters.

Nothing is enabled by default.

@andiwand
andiwand requested a review from AJPfleger as a code owner August 14, 2026 09:58
@github-actions github-actions Bot added Infrastructure Changes to build tools, continous integration, ... Component - Examples Affects the Examples module labels Aug 14, 2026
@github-actions github-actions Bot added this to the next milestone Aug 14, 2026
@andiwand
andiwand marked this pull request as draft August 14, 2026 11:12
andiwand and others added 6 commits August 14, 2026 13:13
Moves the track parameters of a track container onto a common surface,
typically a perigee, on `Acts::extrapolateTrackToReferenceSurface`. That is
where a seed estimate has to be compared to truth: the estimate sits on the
bottom space point's sensor, and expressing the truth particle there means
intersecting it on a straight line, which ignores the bending in between.

The track states are carried over, so they keep the parameters on their own
surfaces and the output has the same layering a fitter produces.

Tracks whose extrapolation fails are dropped, hence the truth matching has to
run downstream of this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxPc2jP43AQuQKz8c4qsaC
`addSeeding(trackParameterPerformance=True)` extrapolates the seed tracks to
the perigee and writes residuals and pulls of the seed estimate against truth,
through `RootTrackParameterPerformanceWriter`.

Seed tracks only carry parameters on their innermost state, so the
extrapolation uses `TrackExtrapolationStrategy::first`; `firstOrLast` would
touch the outermost state, which has none.

Nothing is enabled by default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxPc2jP43AQuQKz8c4qsaC
`addTrackParameterPerformanceWriter` takes a `resPlotToolConfig`. The default
residual axes are cut for fitted tracks, and a seed estimate needs wider ones.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdoihK1K7tHeLCstKM5ZaB
The `fill` overload taking a truth particle intersects it onto the fitted
reference surface, which only makes sense when that surface is a perigee. A
second overload takes the truth as `Acts::BoundTrackParameters` already
expressed on the same surface, so a per-sensor comparison can use the same
histograms. Both funnel into a common private `fill`, and the binning
quantities stay derived from each overload's own truth source rather than
round-tripping the direction through phi/theta.

Missing binning keys and a `paramNames` of the wrong length now throw with a
message naming the key, since renaming the local parameters means renaming
their residual axes too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qsBZHi1zxiUBY5txvM9fg
`truthParametersOnSurface` builds the truth bound parameters on a surface from
the simulated hits of a measurement, the same averaging
`RootTrackParameterWriter` does inline. `recoParametersOnSurface` picks the
parameters of a track state, either a requested `TrackParameterType` or the
best available ones.

Both are needed to compare a track state to truth on its own surface. Nothing
calls them yet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qsBZHi1zxiUBY5txvM9fg
`RootTrackParameterPerformanceWriter` gains `parameterSource = TrackState`,
which compares every measurement state to the truth on its own surface instead
of comparing the track reference parameters to the truth particle.
`geometrySelection` restricts that to a geometry region, and `parameterType`
picks predicted, filtered, smoothed, or unbiased parameters.

`addTrackStateParameterPerformanceWriter` wires it up from python. Nothing is
enabled by default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qsBZHi1zxiUBY5txvM9fg
@andiwand
andiwand force-pushed the track-state-parameter-performance branch from 8a96ac2 to af65c24 Compare August 14, 2026 11:23
@github-actions github-actions Bot removed the Infrastructure Changes to build tools, continous integration, ... label Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Public API surface diff

No change to the public API surface. ✅

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

📊: Physics performance monitoring for 078224a

Full contents

physmon summary

❗️: Downstream build failure

  • eic-shell EICrecon (cc @acts-project/epic-contacts)

yannikaMatt pushed a commit to yannikaMatt/acts that referenced this pull request Aug 21, 2026
…5721)

`addSeeding(trackParameterPerformance=True)` extrapolates the seed
tracks to a
perigee and writes residuals and pulls of the seed estimate against
truth,
through `RootTrackParameterPerformanceWriter`. Seed parameters steer the
CKF,
and nothing so far plots them next to the fitter performance output.

The perigee is what makes the comparison meaningful, since `ResPlotTool`
intersects the truth particle onto the reference surface along a
straight line
and a 1 GeV track in 2 T has already bent by ~18 mrad at the bottom
space
point. Seed tracks carry parameters only on their innermost state, so
the
extrapolation uses `TrackExtrapolationStrategy::first`.

Nothing is enabled by default. The per-state half follows in acts-project#5882.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
yannikaMatt pushed a commit to yannikaMatt/acts that referenced this pull request Aug 21, 2026
…5721)

`addSeeding(trackParameterPerformance=True)` extrapolates the seed
tracks to a
perigee and writes residuals and pulls of the seed estimate against
truth,
through `RootTrackParameterPerformanceWriter`. Seed parameters steer the
CKF,
and nothing so far plots them next to the fitter performance output.

The perigee is what makes the comparison meaningful, since `ResPlotTool`
intersects the truth particle onto the reference surface along a
straight line
and a 1 GeV track in 2 T has already bent by ~18 mrad at the bottom
space
point. Seed tracks carry parameters only on their innermost state, so
the
extrapolation uses `TrackExtrapolationStrategy::first`.

Nothing is enabled by default. The per-state half follows in acts-project#5882.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…er-performance

# Conflicts:
#	Examples/Algorithms/Utilities/include/ActsExamples/Utilities/TrackExtrapolationAlgorithm.hpp
#	Examples/Algorithms/Utilities/src/TrackExtrapolationAlgorithm.cpp
#	Python/Examples/python/reconstruction.py
#	Python/Examples/src/Utilities.cpp
@andiwand

Copy link
Copy Markdown
Contributor Author

Notes for review, moved out of the description now that it is the commit
message verbatim.

The per-state half of the original #5721, which was rewritten down to the
perigee comparison. main is merged in, and with #5842 and #5721 merged this
no longer depends on anything: the diff is this PR alone.

Notes

  • res_loc0/res_loc1 then measure the measurement resolution and res_t the
    time convention of the input. Only direction and momentum say something about
    the parameter estimate itself.
  • parameterType and geometrySelection throw when combined with
    parameterSource = Track, where they have no meaning.
  • ResPlotTool now throws with the missing key named when varBinning lacks
    one, and when paramNames is not one name per bound parameter. Renaming the
    local parameters means renaming their residual axes too, and varBinning.at
    only reported the key type.

Validation

Measured before the merge of main; the merge only dropped the in-branch
copies of #5842 and #5721 in favour of their merged form.

Generic detector, 20 events, truth-smeared seeding into the KF.

parameterSource = Track is untouched: the 208 objects of performance_kf.root
are bit-identical to the same run on the parent branch, so the physmon
references stay valid.

parameterSource = TrackState over the same tracks gives 257 filled states
across the detector and 80 with geometrySelection set to volume 8, with the
residual means centered at zero:

param all states volume 8
loc0 257 80
loc1 257 80
phi 257 80
theta 257 80
qop 257 80
t 257 80

Python/Examples/tests/test_writer.py gives the same two failures
(test_json_material_writer) as the parent branch on the same machine.

@sonarqubecloud

Copy link
Copy Markdown

Define `truthParametersOnSurface` and `recoParametersOnSurface` with their
`ActsExamples::` qualification instead of re-opening the namespace, so a
signature that drifts from the header fails to compile rather than silently
becoming a new overload.

Also drop the unused `addTrackStateParameterPerformanceWriter` and
`defaultOnSurfaceResPlotToolConfig` helpers. The writer stays reachable from
Python through its bindings.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013asNjmmrVRex58ppaX1WJ4
@andiwand
andiwand marked this pull request as ready for review August 24, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component - Examples Affects the Examples module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant