feat: Write track parameter performance from track states in a geometry region - #5882
feat: Write track parameter performance from track states in a geometry region#5882andiwand wants to merge 8 commits into
Conversation
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
8a96ac2 to
af65c24
Compare
Public API surface diffNo change to the public API surface. ✅ |
…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>
…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
|
Notes for review, moved out of the description now that it is the commit The per-state half of the original #5721, which was rewritten down to the Notes
ValidationMeasured before the merge of Generic detector, 20 events, truth-smeared seeding into the KF.
|
|
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



RootTrackParameterPerformanceWritergainsparameterSource = TrackState: itcompares 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.
geometrySelectionnarrows that to a geometry region, so a single volume orlayer can be looked at on its own, and
parameterTypepicks 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
TrackExtrapolationAlgorithmdoes, answers a different question; this is thelocal half.
Supporting it:
truthParametersOnSurfaceandrecoParametersOnSurfacein thenew
ParametersOnSurface.hpp, aResPlotTool::filloverload taking the truthas bound parameters on the fitted surface, and
addTrackStateParameterPerformanceWriterin python, whosedefaultOnSurfaceResPlotToolConfignames the local parametersloc0/loc1rather than
d0/z0, which only mean something on a line surface.ResPlotToolnow names the offending key whenvarBinningorparamNamesdoes not cover the bound parameters.
Nothing is enabled by default.