Skip to content

Commit 22f943e

Browse files
miranov25claude
andcommitted
TPC TimeSeries: store TRD-TPC residuals at the 275 cm plane by default
- 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
1 parent cc29423 commit 22f943e

1 file changed

Lines changed: 56 additions & 43 deletions

File tree

‎Detectors/TPC/workflow/src/TPCTimeSeriesSpec.cxx‎

Lines changed: 56 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "DetectorsCalibration/IntegratedClusterCalibrator.h"
3131
#include "CommonUtils/TreeStreamRedirector.h"
3232
#include "MathUtils/Tsallis.h"
33+
#include "MathUtils/Utils.h"
3334
#include "ReconstructionDataFormats/TrackTPCITS.h"
3435
#include "ReconstructionDataFormats/PrimaryVertex.h"
3536
#include "ReconstructionDataFormats/VtxTrackIndex.h"
@@ -71,7 +72,7 @@ class TPCTimeSeries : public Task
7172
uint8_t trdPattern = 0;
7273
uint8_t nTRDTracklets = 0;
7374
int trackletIndices[6] = {-1, -1, -1, -1, -1, -1};
74-
o2::track::TrackParCov trdTrackParCov; // TRD track state for propagation to the common local X = 275 cm plane; filled only with --store-full-trackpar
75+
o2::track::TrackParCov trdTrackParCov; // TRD track state for propagation to the common local X = 275 cm plane
7576
bool hasTRDTrackPar = false;
7677
};
7778

@@ -398,10 +399,8 @@ class TPCTimeSeries : public Task
398399
trdData.trackletIndices[iLay] = trkltId;
399400
}
400401
}
401-
if (mStoreFullTrackPar) {
402-
trdData.trdTrackParCov = o2::track::TrackParCov(trdTrack); // TrackTRD base state, not validated as the outer/entrance state (open Phase 0.4 finding)
403-
trdData.hasTRDTrackPar = true;
404-
}
402+
trdData.trdTrackParCov = o2::track::TrackParCov(trdTrack); // TrackTRD base state, not validated as the outer/entrance state (open Phase 0.4 finding)
403+
trdData.hasTRDTrackPar = true;
405404
tpcToTRDMap[refTPC] = trdData;
406405
}
407406
}
@@ -1217,7 +1216,7 @@ class TPCTimeSeries : public Task
12171216
float mMaxdEdxRegionRatio{0.5}; ///< maximum abs dedx region ratio: log(dedx_region/dedx)
12181217
float mSamplingFactor{0.1}; ///< sampling factor in case sampling is used for unbinned data
12191218
bool mSampleTsallis{false}; ///< perform sampling of unbinned data
1220-
bool mStoreFullTrackPar{false}; ///< experimental: compute and store tpcOut/trdIn/tpcAtVtx TrackPar and TPC-TRD chi2 (constant per job)
1219+
bool mStoreFullTrackPar{false}; ///< experimental: store tpcOut/trdIn/tpcAtVtx as TrackPar (constant per job)
12211220
uint8_t mTRDInReadout{255}; ///< TRD in detector readout (GRPECS): 1 yes, 0 no, 255 unknown
12221221
std::vector<std::mt19937> mGenerator; ///< random generator for debug tree sampling
12231222
std::vector<std::unique_ptr<o2::utils::TreeStreamRedirector>> mStreamer; ///< streamer for unbinned data
@@ -1485,46 +1484,55 @@ class TPCTimeSeries : public Task
14851484
}
14861485
}
14871486

1488-
// Optional TPC-out / TRD-in states on a common local X plane (experimental, --store-full-trackpar, default off).
1487+
// TPC-out / TRD-in states on a common local X plane, computed for every written entry (Architect decision 2026-10-28:
1488+
// residuals always stored; only the full TrackPar objects depend on --store-full-trackpar).
14891489
// Open Phase 0.4 findings, deferred: the target is local X = kTPCTRDMiddle in the frame rotated to the track
14901490
// position angle (lab radius = sqrt(X^2 + Y^2), not exactly 275 cm), and the TRD starting state is the TrackTRD
1491-
// base state, not validated as the outer/entrance state. With the switch off nothing below is computed.
1492-
static constexpr float kTPCTRDMiddle = 275.f; // cm, common local X plane between TPC outer wall and TRD layer 0
1493-
o2::track::TrackParCov tpcOutCov; // local temporary with covariance (needed for chi2); persisted as TrackPar
1491+
// base state (TrackTRD carries a single parameter set), not validated as the outer/entrance state.
1492+
static constexpr float kTPCTRDMiddle = 275.f; // cm, common local X plane between TPC outer wall and TRD layer 0
1493+
static constexpr uint32_t kDeltaTRDTPCMask = 0xFFFFE000; // keep 10 mantissa bits: float16-like relative precision ~1e-3
1494+
o2::track::TrackParCov tpcOutCov; // local temporary with covariance (needed for chi2); persisted as TrackPar
14941495
o2::track::TrackParCov trdInCov;
1495-
uint8_t tpcOutOK = 255; // 0 propagated, 2 propagation failed, 255 switch off (not computed)
1496-
uint8_t trdInOK = 255; // 0 propagated, 1 not attempted (no TRD match or tpcOutOK != 0), 2 propagation failed, 255 switch off; count TRD matches with trdPattern > 0
1497-
float chi2PhiTPCTRD = -1.f; // -1: not computed (switch off, trdInOK != 0) or singular covariance
1496+
uint8_t tpcOutOK = 2; // 0 propagated, 2 propagation failed
1497+
uint8_t trdInOK = 1; // 0 propagated, 1 not attempted (no TRD match or tpcOutOK != 0), 2 propagation failed; count TRD matches with trdPattern > 0
1498+
float chi2PhiTPCTRD = -1.f; // -1: not computed (trdInOK != 0) or singular covariance
14981499
float chi2ZTPCTRD = -1.f;
1499-
if (mStoreFullTrackPar) {
1500-
// D1: TPC outer → kTPCTRDMiddle
1501-
tpcOutCov = o2::track::TrackParCov(tracksTPC[iTrk].getParamOut());
1502-
tpcOutOK = 2; // default: propagation failed
1503-
{
1504-
// rotate to sector angle at current position
1505-
float sn = std::sin(tpcOutCov.getAlpha());
1506-
float cs = std::cos(tpcOutCov.getAlpha());
1507-
float gy = tpcOutCov.getX() * sn + tpcOutCov.getY() * cs;
1508-
float gx = tpcOutCov.getX() * cs - tpcOutCov.getY() * sn;
1509-
if (tpcOutCov.rotate(std::atan2(gy, gx)) &&
1510-
propagator->propagateTo(tpcOutCov, kTPCTRDMiddle, false, mMaxSnp, mCoarseStep, mMatType)) {
1511-
tpcOutOK = 0;
1512-
}
1500+
// TRD - TPC residuals at the common plane (same alpha, same X), parameters 0..4 = Y, Z, Snp, Tgl, Q2Pt; -999 if trdInOK != 0
1501+
float deltaP0TRDTPC = -999.f;
1502+
float deltaP1TRDTPC = -999.f;
1503+
float deltaP2TRDTPC = -999.f;
1504+
float deltaP3TRDTPC = -999.f;
1505+
float deltaP4TRDTPC = -999.f;
1506+
// D1: TPC outer → kTPCTRDMiddle
1507+
tpcOutCov = o2::track::TrackParCov(tracksTPC[iTrk].getParamOut());
1508+
{
1509+
// rotate to sector angle at current position
1510+
float sn = std::sin(tpcOutCov.getAlpha());
1511+
float cs = std::cos(tpcOutCov.getAlpha());
1512+
float gy = tpcOutCov.getX() * sn + tpcOutCov.getY() * cs;
1513+
float gx = tpcOutCov.getX() * cs - tpcOutCov.getY() * sn;
1514+
if (tpcOutCov.rotate(std::atan2(gy, gx)) &&
1515+
propagator->propagateTo(tpcOutCov, kTPCTRDMiddle, false, mMaxSnp, mCoarseStep, mMatType)) {
1516+
tpcOutOK = 0;
15131517
}
1518+
}
15141519

1515-
// D2: TRD matched → kTPCTRDMiddle, rotated to SAME alpha as TPC out
1516-
trdInOK = 1; // default: not attempted
1517-
if (itTRD != tpcToTRDMap.end() && itTRD->second.hasTRDTrackPar && tpcOutOK == 0) {
1518-
trdInCov = o2::track::TrackParCov(itTRD->second.trdTrackParCov);
1519-
// rotate to TPC alpha FIRST, then propagate — guarantees same frame + same X
1520-
if (trdInCov.rotate(tpcOutCov.getAlpha()) &&
1521-
propagator->propagateTo(trdInCov, kTPCTRDMiddle, false, mMaxSnp, mCoarseStep, mMatType)) {
1522-
trdInOK = 0;
1523-
chi2PhiTPCTRD = chi2Match_Phi(tpcOutCov, trdInCov);
1524-
chi2ZTPCTRD = chi2Match_Z(tpcOutCov, trdInCov);
1525-
} else {
1526-
trdInOK = 2; // propagation failed
1527-
}
1520+
// D2: TRD matched → kTPCTRDMiddle, rotated to SAME alpha as TPC out
1521+
if (itTRD != tpcToTRDMap.end() && itTRD->second.hasTRDTrackPar && tpcOutOK == 0) {
1522+
trdInCov = o2::track::TrackParCov(itTRD->second.trdTrackParCov);
1523+
// rotate to TPC alpha FIRST, then propagate — guarantees same frame + same X
1524+
if (trdInCov.rotate(tpcOutCov.getAlpha()) &&
1525+
propagator->propagateTo(trdInCov, kTPCTRDMiddle, false, mMaxSnp, mCoarseStep, mMatType)) {
1526+
trdInOK = 0;
1527+
chi2PhiTPCTRD = chi2Match_Phi(tpcOutCov, trdInCov);
1528+
chi2ZTPCTRD = chi2Match_Z(tpcOutCov, trdInCov);
1529+
deltaP0TRDTPC = o2::math_utils::truncateFloatFraction(trdInCov.getParam(0) - tpcOutCov.getParam(0), kDeltaTRDTPCMask);
1530+
deltaP1TRDTPC = o2::math_utils::truncateFloatFraction(trdInCov.getParam(1) - tpcOutCov.getParam(1), kDeltaTRDTPCMask);
1531+
deltaP2TRDTPC = o2::math_utils::truncateFloatFraction(trdInCov.getParam(2) - tpcOutCov.getParam(2), kDeltaTRDTPCMask);
1532+
deltaP3TRDTPC = o2::math_utils::truncateFloatFraction(trdInCov.getParam(3) - tpcOutCov.getParam(3), kDeltaTRDTPCMask);
1533+
deltaP4TRDTPC = o2::math_utils::truncateFloatFraction(trdInCov.getParam(4) - tpcOutCov.getParam(4), kDeltaTRDTPCMask);
1534+
} else {
1535+
trdInOK = 2; // propagation failed
15281536
}
15291537
}
15301538

@@ -1693,12 +1701,17 @@ class TPCTimeSeries : public Task
16931701
<< "nTRDTracklets=" << nTRDTracklets
16941702
<< "trdTracklets=" << trdTrackletVec
16951703
<< "trdCalibTracklets=" << trdCalibVec
1696-
// TPC out / TRD in on the common local X = 275 cm plane: status and matching chi2
1697-
// (255 / -1 when --store-full-trackpar is off; the TrackPar objects are written above)
1704+
// TPC out / TRD in on the common local X = 275 cm plane: status, matching chi2 and TRD - TPC residuals
1705+
// (the full TrackPar objects are written above, only with --store-full-trackpar)
16981706
<< "tpcOutOK=" << tpcOutOK
16991707
<< "trdInOK=" << trdInOK
17001708
<< "chi2PhiTPCTRD=" << chi2PhiTPCTRD
17011709
<< "chi2ZTPCTRD=" << chi2ZTPCTRD
1710+
<< "deltaP0TRDTPC=" << deltaP0TRDTPC
1711+
<< "deltaP1TRDTPC=" << deltaP1TRDTPC
1712+
<< "deltaP2TRDTPC=" << deltaP2TRDTPC
1713+
<< "deltaP3TRDTPC=" << deltaP3TRDTPC
1714+
<< "deltaP4TRDTPC=" << deltaP4TRDTPC
17021715
// TRD in detector readout for this run (GRPECS): 1 yes, 0 no, 255 unknown
17031716
<< "trdInReadout=" << mTRDInReadout
17041717
<< "chi2match_ITSTPC=" << chi2match_ITSTPC
@@ -2149,7 +2162,7 @@ o2::framework::DataProcessorSpec getTPCTimeSeriesSpec(const bool disableWriter,
21492162
{"sample-unbinned-tsallis", VariantType::Bool, false, {"Perform sampling of unbinned data based on Tsallis function"}},
21502163
{"sampling-factor", VariantType::Float, 0.001f, {"Sampling factor in case sample-unbinned-tsallis is used"}},
21512164
{"disable-min-bias-trigger", VariantType::Bool, false, {"Disable the minimum bias trigger for skimmed data"}},
2152-
{"store-full-trackpar", VariantType::Bool, false, {"Experimental: compute TPC-out/TRD-in states on the common local X = 275 cm plane and the TPC-TRD matching chi2, and store tpcOut, trdIn, tpcAtVtx as TrackPar in the unbinned tree"}},
2165+
{"store-full-trackpar", VariantType::Bool, false, {"Experimental: store tpcOut, trdIn (common local X = 275 cm plane) and tpcAtVtx as TrackPar in the unbinned tree"}},
21532166
{"out-file-unbinned", VariantType::String, "time_series_tracks.root", {"name of the output file for the unbinned data"}},
21542167
{"max-occupancy-bins", VariantType::Int, 912, {"Maximum number of occupancy bins"}}}};
21552168
}

0 commit comments

Comments
 (0)