Skip to content

TPC SCD: add option to keep all cluster and add MC to unbinned residuals - #15893

Open
matthias-kleiner wants to merge 6 commits into
AliceO2Group:devfrom
matthias-kleiner:tpc-scd-keepClOnPropFail
Open

matthias-kleiner wants to merge 6 commits into
AliceO2Group:devfrom
matthias-kleiner:tpc-scd-keepClOnPropFail

Conversation

@matthias-kleiner

Copy link
Copy Markdown
Contributor

No description provided.

matthias-kleiner and others added 5 commits October 3, 2026 09:12
…opagation fails

TrackInterpolation drops the whole track when the propagation of the reference track to a TPC pad row (or to the
TRD/TOF anchor) fails, e.g. at scdcalib.maxSnp. That propagation follows the ITS-predicted direction, so the drop
selects tracks by the reference's own curvature error and biases the residuals of the surviving sample at low pt.

With scdcalib.keepClustersOnPropFail=true the track is kept. TPC clusters without a reference are stored
position-only: y, z = cluster position, dy = dz = 0, tgSlp = UnbinnedResid::TgSlpPositionOnly (-0x8000, which the
tgSlp packing never produces; UnbinnedResid::isPositionOnly()). extrapolateTrack: all clusters after the failure.
interpolateTrack: a row keeps its residual only if both the outward and the inward propagation reached it; a failure
of the outer TRD/TOF anchor makes all TPC clusters position-only and suppresses the TRD/TOF residuals. Position-only
clusters are excluded from validateTrack and stored in row order. The ITS and PV residuals are unaffected.
ResidualsContainer::fill, staticMapCreator.C and TPCResidualReaderSpec skip position-only (and tgSlp-clamped)
residuals for the binned voxel fit. Default false: output unchanged (verified on one MC TF, all fields identical).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The interpolation workflow had MC switched off ("not yet implemented"). With --enable-mc (opt-in, since the
workflow also runs on data without --disable-mc) and --send-track-data, a TrackDataMC vector aligned 1:1 with
the TrackData output is sent as GLO/TRKDATAMC: MC labels of the ITS-TPC part of the seeding track and of its
ITS and TPC parts (flag for a fake ITS-TPC match), the truth at the ITS outer parameters (nearest ITS track
reference, propagated with the workflow's material correction and the true mass to the x and alpha of
TrackData::par, with the distance to that reference), the truth at the TPC entrance (first TPC track reference
in time, sector frame) with the distance between it, propagated to the innermost TPC cluster of the track, and
that cluster (flags loopers, wrong legs and fakes), and the PDG code. Only the ITS, TPC and ITS-TPC track
labels are read; the kinematics are looked up event by event and released after each event. The residual
aggregator writes the truth as branch trkMC of the trackData tree with --enable-mc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For tracks with TRD residuals (TRD seeds and ITS-TPC map seeds whose most complete track has TRD), TrackDataMC
now also holds the truth at the TRD entrance (first TRD track reference in time, sector frame) and, per layer, the
true y and z at the x of the tracklet in the tracklet's sector frame, i.e. the frame of the stored TRD residual
(nearest TRD track reference propagated with the workflow's material correction), for the true particle of the
ITS-TPC part (ideal tracklets). TrackInterpolation records which ITS-TPC-TRD track gave the TRD residuals of each
stored track (getTRDGIDsSuccess, aligned with the track data).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… sister tracks)

For the particle of the ITS-TPC part TrackDataMC now holds the mother label and PDG code (for primaries the
generator-level parent), the production vertex, momentum and process, a primary flag, and sisterIdx: the index
of another stored track with the same mother (cycling through all of them if more than two), e.g. to select both
daughters of a K0s. pdg is now the PDG code of the particle of the ITS-TPC part, consistent with the origin and TRD
fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ree the baskets

loadTracksForSourceAndEvent deep-copied the vector which ROOT allocated for us (a pointer to nullptr was
passed, so it is ours) and deleted the original: +1x the event at peak (373 MB for a PbPb event with 6.5M
MCTracks). The vector is now stored directly and the branch address reset. In addition, the decompressed
baskets (~1x the event for the split MCTrack branch) are dropped once the event is the last entry of its
TTree cluster, i.e. when no later entry can reuse them, which keeps small events sharing baskets as fast
as before (QED, 10k events: 0.17 s either way, 0.70 s when dropping after every event). For the PbPb
event: peak memory in use 1628 -> 1232 MB, held after releaseTracksForSourceAndEvent 882 -> 443 MB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@matthias-kleiner

Copy link
Copy Markdown
Contributor Author

Hi @sawenzel ,
can you please check the changes for the MCKinematicsReader?
Many thanks,
Matthias

@sawenzel

sawenzel commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator

@matthias-kleiner : Ok for the MCKinematicsReader. But it appears that loadTrackRefsForSource() still loads the references of all events and never releases them. The new TPC code in this PR calls it, so the per-event saving is partly undone there. A per-event load and release for track references would a the natural follow-up.

The track references of a source were loaded for all events at the first access and never released. They are
now loaded per event on demand (with the baskets dropped at the end of a TTree cluster, as for the tracks) and
releaseTracksForSourceAndEvent frees them together with the tracks. For a PbPb TF (10 signal events, 1.75M
references): +304 MB held from the first access until the end before, now +135 MB at peak and +55 MB after
releasing all events.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@matthias-kleiner

Copy link
Copy Markdown
Contributor Author

@matthias-kleiner : Ok for the MCKinematicsReader. But it appears that loadTrackRefsForSource() still loads the references of all events and never releases them. The new TPC code in this PR calls it, so the per-event saving is partly undone there. A per-event load and release for track references would a the natural follow-up.

Thanks for spotting this. The track references are now also read per event on demand and released together with the tracks in releaseTracksForSourceAndEvent. For a PbPb TF this lowers the peak memory by about 170 MB (+304 MB before vs +135 MB) with no change in speed.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants