Skip to content

Fix legacy vertexing: drop ill-conditioned tracks and skip unneeded momenta-at-vertex computation - #525

Open
kjvbrt wants to merge 5 commits into
HEP-FCC:pre-edm4hep1from
kjvbrt:fix-vertex-nonposdef-tracks
Open

Fix legacy vertexing: drop ill-conditioned tracks and skip unneeded momenta-at-vertex computation#525
kjvbrt wants to merge 5 commits into
HEP-FCC:pre-edm4hep1from
kjvbrt:fix-vertex-nonposdef-tracks

Conversation

@kjvbrt

@kjvbrt kjvbrt commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #378. Two issues found while digging into the reported vertexing errors/slowdown:

  • Correctness: VertexFit (Delphes) silently returns a NaN vertex when fed a track with a non-positive-definite covariance matrix, and this broke get_PrimaryTracks()'s chi2-based outlier pruning (NaN comparisons are always false). Now such tracks are dropped before the fit, with the reason logged via stderr. Also extends the stdout suppression from Suppressing printf output from TMatrixBase #379 to get_PrimaryTracks(), which it never covered.
  • Performance: the real bottleneck turned out to be unrelated to the above. VertexFitter_Tk unconditionally builds a Delphes VertexMore to compute per-track momenta at the vertex, which scales ~O(ntracks^3) and dominates runtime for events with many tracks -- even when nothing reads that output. Added a ComputeMomentaAtVertex flag (default true, no behavior change for existing callers) and set it to false in the vertexing tutorial and in myUtils::get_VertexObject()/VertexFitter(), which is what the originally-reported b2snunu slowdown actually goes through.

Verification

On a real winter2023 Bs2Inclusive file, single-threaded: the tutorial's 300 events went from 161s to 58s, and the original issue's minimal repro (get_VertexObject -> hasPV -> Filter) went from 22s to 10s with bit-identical EVT_hasPV output. The NaN-vertex fix was verified with synthetic degenerate-covariance tracks (see commit messages for exact before/after numbers).

kjvbrt added 2 commits July 20, 2026 12:55
Delphes' VertexFit silently returns a NaN vertex (position and chi2)
when fed a track whose covariance matrix is not positive-definite,
instead of failing loudly, while also flooding stdout trying (and
failing) to invert it. In get_PrimaryTracks() this additionally broke
the chi2-based outlier removal loop, since comparisons against a NaN
chi2 are always false, so degenerate tracks were silently never
pruned.

Filter such tracks out before they reach VertexFit, using Delphes'
own TrkUtil::CheckPosDef() guard, and log which track parameters were
dropped and why via stderr (unaffected by the stdout suppression
already wrapping the fit).

Also extends the existing stdout suppression (introduced in HEP-FCC#379) to
get_PrimaryTracks(), which was never covered by it -- this is likely
a contributor to the severe slowdowns reported after that fix landed,
since get_PrimaryTracks() is what the vertexing tutorial and typical
analyses actually call.

Fixes HEP-FCC#378
@kjvbrt kjvbrt changed the title Drop tracks with non positive-definite covariance before vertex fitting [pre-edm4hep1] Drop tracks with non positive-definite covariance before vertex fitting Jul 20, 2026
Profiling on a real winter2023 Zbb_EvtGen_Bs2Inclusive sample showed
that the covariance-matrix fix alone barely moved the needle on the
reported slowdown: constructing Delphes' VertexMore (to fill
updated_track_momentum_at_vertex) dominates VertexFitter_Tk's runtime,
scaling roughly as O(ntracks^3), while the fit itself and the plain
per-track parameter readout are comparatively cheap. Measured on 300
events single-threaded, one call alone cost 429ms-1216ms depending on
track multiplicity, versus a few tens of ms for the fit.

Add a ComputeMomentaAtVertex flag (default true, preserving current
behavior) so callers that only need the vertex position/chi2 -- like
the primary-vertex tutorial, which never reads the per-track momenta
it discards -- can skip that cost. On the same 300-event sample this
takes VertexFitter_Tk's total contribution from ~161s down to ~58s.
@kjvbrt kjvbrt changed the title [pre-edm4hep1] Drop tracks with non positive-definite covariance before vertex fitting Fix legacy vertexing: drop ill-conditioned tracks and skip unneeded momenta-at-vertex computation Jul 21, 2026
kjvbrt added 2 commits July 21, 2026 15:42
…_VertexObject()

The reported b2snunu slowdown goes through myUtils::get_VertexObject()
(called once per MC vertex per event) -> VertexFitterSimple::VertexFitter(),
not VertexFitter_Tk() directly, so the previous commit's flag was
unreachable from that code path. hasPV(), the actual consumer in the
reported reproducer, only ever reads vertex.primary and never the
per-track momenta.

Verified on a real winter2023 Bs2Inclusive file that hasPV() output is
bit-identical with ComputeMomentaAtVertex=false (0 mismatches across
299 surviving events out of 300), while wall time for that reproducer
drops from 22s to 10s single-threaded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant