Skip to content

TPC TimeSeries: TRD − TPC residuals at a common plane, optional track parameters, TRD readout flag - #16018

Merged
shahor02 merged 9 commits into
AliceO2Group:devfrom
miranov25:timeseries-phase04
Oct 28, 2026
Merged

shahor02 merged 9 commits into
AliceO2Group:devfrom
miranov25:timeseries-phase04

Conversation

@miranov25

@miranov25 miranov25 commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

What this adds

Changes only the unbinned TimeSeries tree (treeTimeSeries, written with --enable-unbinned-root-output). The binned output, all other files and all class versions are unchanged.

Always written (about 43 bytes of uncompressed payload per entry):

  • trdInReadout (uint8_t): TRD in the readout of the run, from GRPECS: 1 yes, 0 no, 255 unknown.
  • tpcOutOK, trdInOK (uint8_t): TPC / TRD state brought to the common plane: 0 yes, 1 not attempted (TRD only: no match or TPC failed), 2 rotation or propagation failed.
  • chi2PhiTPCTRD, chi2ZTPCTRD (float): TPC–TRD matching χ² in the bending plane (y, sin φ, q/pT) and in z (z, tan λ); −1 if not computed.
  • deltaTRDTPC (o2::track::TrackPar): mX, mAlpha = common plane and frame (full precision); mP[0..4] = TRD − TPC residuals of y, z, sin φ, tan λ, q/pT, kept to 10 mantissa bits (truncateFloatFraction). Direct parameter getters are meaningful; derived ones (getPt(), getPhi(), …) are not. Default object (X = 0) if trdInOK ≠ 0, so select with trdInOK == 0.

With the new option --store-full-trackpar (default off): tpcOut, trdIn and tpcAtVtx as TrackPar (without covariance). tpcAtVtx is the TPC track at its DCA (to the primary vertex for ITS-TPC contributors passing the DCA cuts).

Method

The TPC outer parameters are rotated to the track position angle and propagated to local X = 275 cm, between the TPC outer wall and TRD layer 0. The TRD-side state is rotated to the same angle and propagated to the same X, with the configured material correction and the full field map.

The TRD side is deliberately the inner state of the ITS-TPC-TRD track (the stored base state after the inward refit), not getOuterParam(). That refit includes the TPC clusters, so TRD − TPC is not a comparison of independent measurements.

The TPC propagation runs for every written entry; the TRD propagation and the χ² only for TRD-matched tracks. GRPECS is requested only when the unbinned output is enabled.

Testing (PbPb 2025, LHC25an.b5p, run 567939)

  • Build: alma2, GSI
  • Option off and on: expected branches present and readable
  • Same entry count off vs on, with --disable-min-bias-trigger and without Tsallis sampling
  • trdInReadout = 1
  • Truncation closure: deltaTRDTPC vs trdIn − tpcOut
  • Wall time and compressed bytes per entry vs dev
  • Residual and χ² distributions

🤖 Generated with Claude Code

https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61

miranov25 and others added 5 commits October 27, 2026 20:46
Store full TrackParCov (params + covariance) at three reference surfaces:
  tpcOut:      TPC outer at kTPCTRDMiddle (275 cm), from getParamOut()
  trdIn:       TRD matched at 275 cm, same alpha as TPC out
  tpcAtVtx:    TPC track at vertex (propagated to DCA)
  itstpcAtVtx: ITS-TPC track at vertex (propagated to DCA)

chi2Match_Phi: reusable 3x3 chi2 (Y, Snp, Q2Pt) — 3 DOF
chi2Match_Z:   reusable 2x2 chi2 (Z, Tgl) — 2 DOF
Both stored per track: chi2PhiTPCTRD, chi2ZTPCTRD.
…t flag

- tpcOut, trdIn and tpcAtVtx are written only with --store-full-trackpar
  (default off), as o2::track::TrackPar without covariance. The TPC/TRD
  propagation to the common local X = 275 cm plane, the TPC-TRD matching
  chi2 and the per-track TrackParCov copy in the TRD map run only with this
  option; otherwise tpcOutOK/trdInOK = 255 and the chi2 values are -1.
  With the option on, the three objects are the first branches of the tree.
- New per-entry flag trdInReadout (TRD in detector readout from GRPECS:
  1 yes, 0 no, 255 unknown). GRPECS is requested only when the unbinned
  output is enabled.
- Deferred, not fixed: propagation targets local X (not lab radius), and the
  TRD starting state is the TrackTRD base state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
- The TPC-out and TRD-in propagation to the common local X = 275 cm plane
  and the TPC-TRD matching chi2 now run for every written entry.
- New branches deltaP0TRDTPC..deltaP4TRDTPC: TRD - TPC residuals of
  Y, Z, sin(phi), tan(lambda) and q/pT at that plane (same frame, same X),
  stored with float16-like precision (truncateFloatFraction, 10 mantissa
  bits); -999 if the TRD propagation was not done (trdInOK != 0).
- --store-full-trackpar now controls only the tpcOut, trdIn and tpcAtVtx
  TrackPar objects; tpcOutOK/trdInOK no longer use the value 255.
- Still open: the plane is local X, not the lab radius, and the TRD
  starting state is the TrackTRD base state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
- deltaTRDTPC (o2::track::TrackPar) replaces deltaP0TRDTPC..deltaP4TRDTPC.
  mX and mAlpha are the common plane and frame in full precision (copied
  from the propagated TPC state); mP[0..4] are the TRD - TPC residuals of
  Y, Z, sin(phi), tan(lambda) and q/pT with 10 mantissa bits. Only getX(),
  getAlpha() and getParam(i) are meaningful on this object.
- Default object (X = 0) if the TRD propagation was not done (trdInOK != 0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
@miranov25

miranov25 commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor Author

GSI Test of the default mode (option --store-full-trackpar off

PbPb 2025, LHC25an.b5p, run 567939, one of four output files (797,800 entries). The run stopped early when the shared-memory segment was full, so the sample is partial; per-entry sizes are still representative.

New, always-written branches: trdInReadout, tpcOutOK, trdInOK, chi2PhiTPCTRD, chi2ZTPCTRD, deltaTRDTPC. The TRD tracklet branches (trdPattern, nTRDTracklets, trdTracklets, trdCalibTracklets) were already in dev. tpcOut, trdIn and tpcAtVtx are absent, as expected with the option off.

Branch Compressed size Bytes per entry
deltaTRDTPC (all members) 3.74 MB 4.7
of which mP[5] (the residuals) 2.03 MB 2.5
chi2PhiTPCTRD + chi2ZTPCTRD 0.58 MB 0.7
trdInOK + trdInReadout 0.07 MB 0.08
whole file 159 MB 199

The new branches add about 5.5 bytes per entry (without tpcOutOK), under 3 % of the file. trdInReadout = 1 in all entries; 5.8 % of the entries carry a TRD residual (trdInOK == 0).

root [6] treeTimeSeries->GetListOfBranches()->Print("","*trd*")
Collection name='TObjArray', class='TObjArray', size=96
 *Br    9 :trdPattern : trdPattern/b                                          *
*Entries :   797800 : Total  Size=     799086 bytes  File Size  =      98657 *
*Baskets :        9 : Basket Size=     189952 bytes  Compression=   8.09     *
*............................................................................*
 *Br   10 :trdTracklets : Int_t trdTracklets_                                 *
*Entries :   797800 : Total  Size=    6431055 bytes  File Size  =    1028915 *
*Baskets :      305 : Basket Size=      32000 bytes  Compression=   6.23     *
*............................................................................*
*Br   11 :trdTracklets.mtrackletWord : ULong_t mtrackletWord[trdTracklets_]  *
*Entries :   797800 : Total  Size=   41523422 bytes  File Size  =    2968520 *
*Baskets :      285 : Basket Size=    9839463 bytes  Compression=  13.99     *
*............................................................................*
 *Br   12 :trdCalibTracklets : Int_t trdCalibTracklets_                       *
*Entries :   797800 : Total  Size=    6441529 bytes  File Size  =    1029540 *
*Baskets :      305 : Basket Size=      32000 bytes  Compression=   6.23     *
*............................................................................*
*Br   13 :trdCalibTracklets.mX : Float_t mX[trdCalibTracklets_]              *
*Entries :   797800 : Total  Size=   22359498 bytes  File Size  =    2005339 *
*Baskets :      165 : Basket Size=    6587904 bytes  Compression=  11.15     *
*............................................................................*
*Br   14 :trdCalibTracklets.mY : Float_t mY[trdCalibTracklets_]              *
*Entries :   797800 : Total  Size=   22359498 bytes  File Size  =    2082673 *
*Baskets :      165 : Basket Size=    6587904 bytes  Compression=  10.73     *
*............................................................................*
*Br   15 :trdCalibTracklets.mZ : Float_t mZ[trdCalibTracklets_]              *
*Entries :   797800 : Total  Size=   22359498 bytes  File Size  =    2068494 *
*Baskets :      165 : Basket Size=    6587904 bytes  Compression=  10.81     *
*............................................................................*
*Br   16 :trdCalibTracklets.mDy : Float_t mDy[trdCalibTracklets_]            *
*Entries :   797800 : Total  Size=   22359667 bytes  File Size  =    2028928 *
*Baskets :      165 : Basket Size=    6587904 bytes  Compression=  11.02     *
*............................................................................*
 *Br   17 :trdInOK   : trdInOK/b                                              *
*Entries :   797800 : Total  Size=     799047 bytes  File Size  =      62282 *
*Baskets :        9 : Basket Size=     189952 bytes  Compression=  12.82     *
*............................................................................*
 *Br   18 :trdInReadout : trdInReadout/b                                      *
*Entries :   797800 : Total  Size=     799221 bytes  File Size  =       4676 *
*Baskets :       10 : Basket Size=     189952 bytes  Compression= 170.81     *
*............................................................................*
root [5] treeTimeSeries->GetListOfBranches()->Print("","*TRD*")
Collection name='TObjArray', class='TObjArray', size=96
 *Br    0 :nTRDTracklets : nTRDTracklets/b                                    *
*Entries :   797800 : Total  Size=     799235 bytes  File Size  =      76617 *
*Baskets :       10 : Basket Size=     189952 bytes  Compression=  10.42     *
*............................................................................*
 *Br    1 :chi2PhiTPCTRD : chi2PhiTPCTRD/F                                    *
*Entries :   797800 : Total  Size=    3194291 bytes  File Size  =     291412 *
*Baskets :       25 : Basket Size=     758272 bytes  Compression=  10.96     *
*............................................................................*
 *Br    2 :chi2ZTPCTRD : chi2ZTPCTRD/F                                        *
*Entries :   797800 : Total  Size=    3194233 bytes  File Size  =     293246 *
*Baskets :       25 : Basket Size=     758272 bytes  Compression=  10.89     *
*............................................................................*
 *Branch  :deltaTRDTPC                                                        *
*Entries :   797800 : BranchElement (see below)                              *
*............................................................................*
*Br    3 :mX        : Float_t                                                *
*Entries :   797800 : Total  Size=    3193877 bytes  File Size  =     103788 *
*Baskets :       24 : Basket Size=     757760 bytes  Compression=  30.77     *
*............................................................................*
*Br    4 :mAlpha    : Float_t                                                *
*Entries :   797800 : Total  Size=    3193989 bytes  File Size  =     289721 *
*Baskets :       24 : Basket Size=     758272 bytes  Compression=  11.02     *
*............................................................................*
*Br    5 :mP[5]     : Float_t                                                *
*Entries :   797800 : Total  Size=   19163350 bytes  File Size  =    2026736 *
*Baskets :      144 : Basket Size=    5827072 bytes  Compression=   9.45     *
*............................................................................*
*Br    6 :mAbsCharge : Char_t                                                *
*Entries :   797800 : Total  Size=     799096 bytes  File Size  =       4653 *
*Baskets :        9 : Basket Size=     189952 bytes  Compression= 171.63     *
*............................................................................*
*Br    7 :mPID      : o2::track::PID                                         *
*Entries :   797800 : Total  Size=    8784720 bytes  File Size  =    1301977 *
*Baskets :       79 : Basket Size=    3363328 bytes  Compression=   6.75     *
*............................................................................*
*Br    8 :mUserField : UShort_t                                              *
*Entries :   797800 : Total  Size=    1597431 bytes  File Size  =       8630 *
*Baskets :       14 : Basket Size=     379392 bytes  Compression= 185.03     *
*............................................................................*

- The TRD side of deltaTRDTPC, of the matching chi2 and of trdIn is now
  the outer state of the ITS-TPC-TRD track (TrackTRD::getOuterParam():
  outward refit through ITS, TPC and TRD, at the outermost TRD layer),
  propagated inward to the 275 cm plane, as RecoContainer does. The base
  state used before is the inward refit, which ends at the innermost ITS
  cluster, i.e. the combined track at the vertex.
- Comments corrected: TrackTRD has two parameter sets; the outward refit
  includes the TPC clusters, so TRD - TPC is not independent; full list of
  meaningful getters of deltaTRDTPC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
if (!refTRD.isIndexSet()) {
continue;
}
const auto& trdTrack = recoData.getTrack<o2::trd::TrackTRD>(refTRD);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you pick the track param at innermost point, i.e. ITS.

trdData.trackletIndices[iLay] = trkltId;
}
}
trdData.trdTrackParCov = o2::track::TrackParCov(trdTrack); // TrackTRD base state, not validated as the outer/entrance state (open Phase 0.4 finding)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get the TRDout (full track refitted from ITS to TRD till the outermost TRD layer), use

trdData.trdTrackParCov = recoData.getTrackParamOut(gid);

// scan ITS-TPC-TRD tracks
auto itstpctrdTracks = recoData.getITSTPCTRDTracks<o2::trd::TrackTRD>();
for (unsigned int ig = 0; ig < itstpctrdTracks.size(); ++ig) {
auto gid = GTrackID(ig, GTrackID::ITSTPCTRD);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the line 378 build vector of TRD triggers:
auto trdTrig = recoData.getTRDTriggerRecords();
std::vectoro2::InteractionRecord trdBCs;
trdBCs.reserve(trdTrig.size());
for (const auto& trg : trdTrig) {
trdBCs.push_back(trg.getBCData());
}
// Save it once per TF, not in the loop over tracks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Ruben, it is working well.

Can you approve pull request?

Example: number of TRD contributors to the vertex with different deltaBC criteria
For the nearest bunch crossing with TRD

treeTimeSeries->Draw("vertex_nContributorsTRD:vertex_nContributorsITSTPC","trdTrigDBCVtxBefore==0","colz")
treeTimeSeries->Draw("vertex_nContributorsTRD:vertex_nContributorsITSTPC","trdTrigDBCVtxBefore<0","colz")

image image

miranov25 and others added 3 commits October 28, 2026 15:55
- TRD-triggered BCs are collected once per TF from the TRD trigger
  records (bogus bc >= 3564 dropped). Per entry, trdTrigDBCBefore/After
  give the closest TRD trigger to the BC range [IRMin, IRMax] of the
  entry's vertex: both 0 if a trigger lies inside the range, else the
  distance in BC before the range start (< 0) and after its end (> 0);
  -999999/999999 if none or no vertex BC range.
- vertex_nContributorsITS/ITSTPC/TRD: contributor counts of the same
  vertex, so the TRD-matched fraction of high-multiplicity collisions
  gives a second, independent TRD-readout estimator.
- The TRD-out state is taken with recoData.getTrackParamOut(gid).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
- vertex_bc: BC number (from the TF start, orbit firstTFOrbit) of the
  vertex time, for the same vertex as vertex_time.
- trdTrigBCBefore/After: BC numbers of the closest TRD-triggered BCs at
  or before / at or after vertex_bc (-999999 if none or no vertex), so
  the TRD-in-collision estimators can be calibrated from raw BC numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
- vertex_bc: BC number (from the TF start, orbit firstTFOrbit) of the
  vertex time, for the same vertex as vertex_time.
- trdTrigDBCVtxBefore/After: closest TRD-triggered BC at or before / at
  or after vertex_bc, minus vertex_bc (<= 0 / >= 0; -999999/999999 if
  none or no vertex), to calibrate the TRD-in-collision estimators.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
@shahor02
shahor02 merged commit 946c509 into AliceO2Group:dev Oct 28, 2026
12 of 13 checks passed
github-actions Bot pushed a commit that referenced this pull request Oct 30, 2026
…in-apass1-v3

Brings TPCTimeSeriesSpec.cxx and IntegratedClusterCalibrator.h to the state
already used in production in async-2026-ppLowTPCgain-apass1-v3/v4, instead
of resolving the same conflict again. Needed by #15670 and #16018.

- upstream source: #15658, commit 907c011
- production resolution reused (Alberto Caliva, ppLowTPCgain-apass1):
  7844bac (cherry-picking Marian's PRs) and
  90bda7e (update TPC time-series: sector-edge
  code of #15532 removed, TimeSeriesITSTPC class version 7)
- files copied from 90bda7e:
  TPCTimeSeriesSpec.cxx        blob 12f2396
  IntegratedClusterCalibrator.h blob 87fcdf9
- not included: #15532 (sector-edge correction), #15659 (internal readers)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61
github-actions Bot pushed a commit that referenced this pull request Oct 30, 2026
… parameters, TRD readout flag (#16018)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: miranov25 <marian.ivanov@cern.cg>
(cherry picked from commit 946c509)
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.

2 participants