Skip to content

Kalman per-iteration hit timing cuts, plus SVT truth-relation diagnostics - #1175

Draft
mgignac wants to merge 7 commits into
JeffersonLab:masterfrom
mgignac:mgignac-lowp-tracking
Draft

Kalman per-iteration hit timing cuts, plus SVT truth-relation diagnostics#1175
mgignac wants to merge 7 commits into
JeffersonLab:masterfrom
mgignac:mgignac-lowp-tracking

Conversation

@mgignac

@mgignac mgignac commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Adds per-iteration control over the Kalman hit timing cuts, and the
diagnostics used to work out why tracks lose their truth relations under
pulser overlay.

Kalman pattern recognition

mxTdif becomes a per-iteration array, joined by three new per-iteration
knobs:

  • seedTimeSpread — gate on tmax-tmin across the 5 seed hits
  • hitTimeWindow — pick up hits within a window of the running mean of
    accepted hit times, replacing the tMin/tMax envelope
  • maxTotalSpread — backstop on total tMax-tMin over the track

All three default to 0, selecting existing behaviour, and
setMaxTimeRange() still sets both iterations, so existing steering files
are unaffected. TrackCandidate.reFit() gains a trial argument to
select the window; removeHit()/addHits() use the looser of the two
tiers since they have no iteration context.

Also exposes the iteration-1 seed cuts (maxPtInverseIter1, maxD0Iter1,
maxZ0Iter1, maxTanLambdaIter1) and edgeTolerance — the seed
detector-bounds check, previously hard-coded at 1 mm, which acts as an
acceptance cut rather than a quality cut at low tan(lambda). Seed-by-seed
tracing is armed per event from debugEvent instead of a compile-time
constant.

SVT truth-relation diagnostics

A raw hit can lose its truth relation at either of two gates: G1
(totalContrib > 4*meanNoise) or G2 (readoutCuts, evaluated on the
merged waveform, whose baseline need not match the DB pedestal).
SvtDigitizationWithPulserDataMergingReadoutDriver now counts both,
indexed by whether the channel carried a pulser hit, and reports at
endOfData(). No behaviour change.

Opt-in writeHitOriginCollections (default false) writes
SVTHitOriginPulser and SVTHitOriginMCContrib, which together with
SVTTrueHitRelations resolve "no truth relation" into NOISE / MC_PURE /
MC_PURE_SUBTHRESH / PULSER_PURE / MERGED / MERGED_SUBTHRESH —
distinguishing a lost relation from an absent one. Enabling it widens the
output MCParticle collection, so output is bit-identical only with it off.

Two consumers: SvtHitProvenanceDriver (aggregate — are untruthed track
hits adjacent to MC-charged channels, against the event baseline?) and
SvtEventForensicsDriver (per-event hit dump separating "digitization
dropped the relation" from "patrec used different raw hits").

Also

  • UnbiasedTriggerFilterDriver: accept/reject counters and summary;
    pulser and FaradayCup split into separate branches for counting, same
    outcome.
  • Removed a stray </driver> in the pass5 physics recon steering file.
  • Regenerated detector-model/dependency-reduced-pom.xml.

mgignac added 7 commits August 6, 2026 10:37
Make mxTdif a per-iteration array and add three new per-iteration timing
knobs alongside it:

  seedTimeSpread  gate on tmax-tmin across the 5 seed hits
  hitTimeWindow   pick up hits within a window of the running mean of
                  accepted hit times, replacing the tMin/tMax envelope
  maxTotalSpread  backstop on total tMax-tMin over the track

All three default to 0, which selects the existing behaviour, and
setMaxTimeRange() still sets both iterations, so current steering files
are unaffected. removeHit()/addHits() take max(mxTdif[0], mxTdif[1])
since they have no iteration context.

TrackCandidate.reFit() gains a trial argument to select the time window.

Also expose iteration-1 seed cuts (setMaxKIter1, setMaxdRhoIter1,
setMaxdZIter1, setMaxTanLIter1), which must be applied after the tier-2
setters because those clamp the iteration-1 tier downward; and
edgeTolerance, the seed detector-bounds check that acts as an acceptance
cut at low tan(lambda), previously hard-coded at 1 mm.

KalmanPatRecHPS.debug is now armed per event from KalmanParams.debugEvent
(default -1, off) instead of being a compile-time constant.
Under pulser overlay many raw hits reach readout with no truth relation.
Two independent gates can drop one: G1 (totalContrib > 4*meanNoise),
which attaches simHits to the channel, and G2 (readoutCuts), evaluated
on the combined waveform whose baseline need not match the DB pedestal.

Add counters for both, indexed by whether the channel carried a pulser
hit, plus a pulser-baseline-vs-pedestal measurement, reported at
endOfData(). These are always accumulated and change no behaviour;
setDebug() additionally prints per-hit loss records.

Add opt-in writeHitOriginCollections (default false), writing
SVTHitOriginPulser and SVTHitOriginMCContrib. Combined with
SVTTrueHitRelations these resolve "no truth relation" into NOISE,
MC_PURE, MC_PURE_SUBTHRESH, PULSER_PURE, MERGED or MERGED_SUBTHRESH,
separating a lost relation from an absent one. Enabling it widens the
output MCParticle collection to cover sub-threshold contributors, so
output is only bit-identical with it disabled.
Two analysis drivers consuming the provenance relations written by
SvtDigitizationWithPulserDataMergingReadoutDriver; both require
writeHitOriginCollections=true.

SvtHitProvenanceDriver answers the aggregate question: are the untruthed
hits on a track adjacent to channels that did receive MC charge? Since
high occupancy makes adjacency alone meaningless, it is measured against
the baseline rate for any pulser hit in the event.

SvtEventForensicsDriver dumps named events hit by hit, separating a track
whose particle never produced a truthed raw hit from one where truthed
raw hits existed but pattern recognition used different ones.
Count events by the reason they were kept or dropped (EPICS, scaler,
pulser, FaradayCup, missing TSBank, other) and print a summary at
endOfData(). Optional per-event logging via debug=true in the steering
file.

Pulser and FaradayCup were tested in a single condition and are now
separate branches so they can be counted apart; the accept/reject
outcome is unchanged.
The extra tag followed the v0 skim driver block and did not match any
open element.
…3.2)

Shade plugin output picking up the junit version already declared in the
parent pom; no source change.
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