Repository navigation
TPC TimeSeries: TRD − TPC residuals at a common plane, optional track parameters, TRD readout flag - #16018
Conversation
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
GSI Test of the default mode (option
|
| 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); |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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")
- 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
…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
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) iftrdInOK≠ 0, so select withtrdInOK == 0.With the new option
--store-full-trackpar(default off):tpcOut,trdInandtpcAtVtxasTrackPar(without covariance).tpcAtVtxis 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)
--disable-min-bias-triggerand without Tsallis samplingtrdInReadout= 1deltaTRDTPCvstrdIn − tpcOutdev🤖 Generated with Claude Code
https://claude.ai/code/session_01YYeB7SW1TM7vU8qhVHiG61