Skip to content

Commit 923b0fc

Browse files
authored
[PWGLF] Improve ZDC calibration for spectator plane (#18227)
1 parent 8bb3f2f commit 923b0fc

1 file changed

Lines changed: 149 additions & 1 deletion

File tree

‎PWGLF/TableProducer/Common/zdc2stagecalibration.cxx‎

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,18 @@ struct zdc2stagecalibration {
113113
// 4 sums of QxA,QyA,QxC,QyC. Feature 0 is unity, so its sum is N.
114114
static constexpr int kQRecenteringFlatnessNMoments = kQRecenteringMultidimNFeatures + kQRecenteringNComponents;
115115

116+
// Structured regression diagnostic basis. The existing 35 cubic features are
117+
// kept unchanged and augmented with truncated-cubic 1D basis functions for
118+
// time, Vx, Vy and Vz. The additional basis is intentionally overcomplete so
119+
// that the final subset and regularisation can be chosen offline without
120+
// another derivation pass.
121+
static constexpr int kQRecenteringStructuredNKnots = 9;
122+
static constexpr int kQRecenteringStructuredNFeatures = kQRecenteringMultidimNFeatures + 4 * kQRecenteringStructuredNKnots;
123+
static constexpr int kQRecenteringStructuredNMatrixMoments = kQRecenteringStructuredNFeatures * (kQRecenteringStructuredNFeatures + 1) / 2;
124+
static constexpr int kQRecenteringStructuredNMoments = kQRecenteringStructuredNMatrixMoments + kQRecenteringNComponents * kQRecenteringStructuredNFeatures + kQRecenteringNComponents;
125+
// Per conditioning bin store sum(features), sum(Q) and sum(Q^2).
126+
static constexpr int kQRecenteringStructuredFlatnessNMoments = kQRecenteringStructuredNFeatures + 2 * kQRecenteringNComponents;
127+
116128
void init(o2::framework::InitContext&)
117129
{
118130
rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad);
@@ -133,9 +145,11 @@ struct zdc2stagecalibration {
133145
AxisSpec qRecenteringMomentAxis = {kQRecenteringNMoments, 0.0, static_cast<double>(kQRecenteringNMoments), "regression moment"};
134146
AxisSpec qRecenteringMultidimMomentAxis = {kQRecenteringMultidimNMoments, 0.0, static_cast<double>(kQRecenteringMultidimNMoments), "multidimensional regression moment"};
135147
AxisSpec qRecenteringFlatnessMomentAxis = {kQRecenteringFlatnessNMoments, 0.0, static_cast<double>(kQRecenteringFlatnessNMoments), "flatness sufficient-statistic index"};
148+
AxisSpec qRecenteringStructuredMomentAxis = {kQRecenteringStructuredNMoments, 0.0, static_cast<double>(kQRecenteringStructuredNMoments), "structured regression moment"};
149+
AxisSpec qRecenteringStructuredFlatnessMomentAxis = {kQRecenteringStructuredFlatnessNMoments, 0.0, static_cast<double>(kQRecenteringStructuredFlatnessNMoments), "structured flatness sufficient-statistic index"};
136150
AxisSpec centralityAxis = {80, 0.0, 80.0, "centrality (%)"};
137151
AxisSpec resolutionCentralityAxis = {50, 0.0, 50.0, "centrality (%)"};
138-
AxisSpec vertexXYAxis = {100, -0.5, 0.5, "vertex x/y (cm)"};
152+
AxisSpec vertexXYAxis = {100, -0.1, 0.1, "vertex x/y (cm)"};
139153
AxisSpec vertexZAxis = {100, -10.0, 10.0, "vertex z (cm)"};
140154
AxisSpec qComponentAxis = {4, 0.0, 4.0, "Q component"};
141155
AxisSpec qCorrelationComponentAxis = {4, 0.0, 4.0, "A-C correlation component"};
@@ -213,6 +227,19 @@ struct zdc2stagecalibration {
213227
histos.add("QRecenteringCalibration/hFlatnessMomentsVx", "Flatness sufficient statistics vs v_{x};centrality (%);v_{x} (cm);statistic index", kTH3D, {centralityAxis, vertexXYAxis, qRecenteringFlatnessMomentAxis});
214228
histos.add("QRecenteringCalibration/hFlatnessMomentsVy", "Flatness sufficient statistics vs v_{y};centrality (%);v_{y} (cm);statistic index", kTH3D, {centralityAxis, vertexXYAxis, qRecenteringFlatnessMomentAxis});
215229
histos.add("QRecenteringCalibration/hFlatnessMomentsVz", "Flatness sufficient statistics vs v_{z};centrality (%);v_{z} (cm);statistic index", kTH3D, {centralityAxis, vertexZAxis, qRecenteringFlatnessMomentAxis});
230+
231+
// Additional train/validation sufficient statistics for the structured
232+
// regression test. These do not modify the current 35-feature correction.
233+
histos.add("QRecenteringCalibration/hRegressionMomentsStructuredTrain", "Structured Q recentering moments (train);centrality (%);moment index", kTH2D, {centralityAxis, qRecenteringStructuredMomentAxis});
234+
histos.add("QRecenteringCalibration/hRegressionMomentsStructuredValidation", "Structured Q recentering moments (validation);centrality (%);moment index", kTH2D, {centralityAxis, qRecenteringStructuredMomentAxis});
235+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsTimeTrain", "Structured flatness statistics vs time (train);centrality (%);time from SOR (h);statistic index", kTH3D, {centralityAxis, timeAxis, qRecenteringStructuredFlatnessMomentAxis});
236+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsVxTrain", "Structured flatness statistics vs v_{x} (train);centrality (%);v_{x} (cm);statistic index", kTH3D, {centralityAxis, vertexXYAxis, qRecenteringStructuredFlatnessMomentAxis});
237+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsVyTrain", "Structured flatness statistics vs v_{y} (train);centrality (%);v_{y} (cm);statistic index", kTH3D, {centralityAxis, vertexXYAxis, qRecenteringStructuredFlatnessMomentAxis});
238+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsVzTrain", "Structured flatness statistics vs v_{z} (train);centrality (%);v_{z} (cm);statistic index", kTH3D, {centralityAxis, vertexZAxis, qRecenteringStructuredFlatnessMomentAxis});
239+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsTimeValidation", "Structured flatness statistics vs time (validation);centrality (%);time from SOR (h);statistic index", kTH3D, {centralityAxis, timeAxis, qRecenteringStructuredFlatnessMomentAxis});
240+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsVxValidation", "Structured flatness statistics vs v_{x} (validation);centrality (%);v_{x} (cm);statistic index", kTH3D, {centralityAxis, vertexXYAxis, qRecenteringStructuredFlatnessMomentAxis});
241+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsVyValidation", "Structured flatness statistics vs v_{y} (validation);centrality (%);v_{y} (cm);statistic index", kTH3D, {centralityAxis, vertexXYAxis, qRecenteringStructuredFlatnessMomentAxis});
242+
histos.add("QRecenteringCalibration/hStructuredFlatnessMomentsVzValidation", "Structured flatness statistics vs v_{z} (validation);centrality (%);v_{z} (cm);statistic index", kTH3D, {centralityAxis, vertexZAxis, qRecenteringStructuredFlatnessMomentAxis});
216243
}
217244

218245
histos.add("QRecenteringQA/pQBeforeVsCentrality", "Q before recentering vs centrality;centrality (%);Q component;<Q>", kTProfile2D, {centralityAxis, qComponentAxis});
@@ -374,6 +401,42 @@ struct zdc2stagecalibration {
374401
t * x * y, t * x * z, t * y * z, x * y * z};
375402
}
376403

404+
std::array<double, kQRecenteringStructuredNFeatures> makeQRecenteringStructuredFeatures(float timeFromSOR, float vx, float vy, float vz) const
405+
{
406+
const auto baseFeatures = makeQRecenteringMultidimFeatures(timeFromSOR, vx, vy, vz);
407+
std::array<double, kQRecenteringStructuredNFeatures> features{};
408+
409+
for (int i = 0; i < kQRecenteringMultidimNFeatures; ++i) {
410+
features[i] = baseFeatures[i];
411+
}
412+
413+
const double runHours = (eorTimestamp > sorTimestamp) ? static_cast<double>(eorTimestamp - sorTimestamp) * 1.e-3 / 3600.0 : static_cast<double>(cfgMaxRunHours.value);
414+
const double t = (runHours > 0.0) ? (2.0 * static_cast<double>(timeFromSOR) / runHours - 1.0) : 0.0;
415+
const double x = static_cast<double>(vx) / 0.1;
416+
const double y = static_cast<double>(vy) / 0.1;
417+
const double z = static_cast<double>(vz) / 10.0;
418+
419+
// Internal knots in the normalized [-1,1] coordinate. Together with the
420+
// existing 1,u,u^2,u^3 terms this is a cubic regression-spline basis.
421+
constexpr std::array<double, kQRecenteringStructuredNKnots> knots = {
422+
-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8};
423+
424+
int index = kQRecenteringMultidimNFeatures;
425+
auto appendSplineTerms = [&](double value) {
426+
for (int i = 0; i < kQRecenteringStructuredNKnots; ++i) {
427+
const double delta = value - knots[i];
428+
features[index++] = delta > 0.0 ? delta * delta * delta : 0.0;
429+
}
430+
};
431+
432+
appendSplineTerms(t);
433+
appendSplineTerms(x);
434+
appendSplineTerms(y);
435+
appendSplineTerms(z);
436+
437+
return features;
438+
}
439+
377440
using MyCollisions = o2::soa::Join<o2::aod::Collisions, o2::aod::EvSels, o2::aod::Mults, o2::aod::FT0sCorrected, o2::aod::CentFT0Cs>;
378441

379442
void process(MyCollisions::iterator const& collision, o2::aod::FT0s const& /*ft0s*/, o2::aod::FV0As const& /*fv0s*/, BCsRun3 const& /*bcs*/, o2::aod::Zdcs const& /*zdcs*/)
@@ -769,6 +832,91 @@ struct zdc2stagecalibration {
769832
histos.fill(HIST("QRecenteringCalibration/hFlatnessMomentsVy"), centrality, vy, index + 0.5, value);
770833
histos.fill(HIST("QRecenteringCalibration/hFlatnessMomentsVz"), centrality, vz, index + 0.5, value);
771834
}
835+
836+
// Structured regression moments. Events are deterministically split
837+
// 50/50 using a mixed global-BC key, avoiding any dependence on the
838+
// regression variables themselves.
839+
const auto structuredFeatures = makeQRecenteringStructuredFeatures(timeFromSOR, vx, vy, vz);
840+
uint64_t splitKey = globalBC + 0x9e3779b97f4a7c15ULL;
841+
splitKey = (splitKey ^ (splitKey >> 30)) * 0xbf58476d1ce4e5b9ULL;
842+
splitKey = (splitKey ^ (splitKey >> 27)) * 0x94d049bb133111ebULL;
843+
splitKey = splitKey ^ (splitKey >> 31);
844+
const bool isValidation = (splitKey & 1ULL) != 0ULL;
845+
846+
int structuredMoment = 0;
847+
for (int i = 0; i < kQRecenteringStructuredNFeatures; ++i) {
848+
for (int j = i; j < kQRecenteringStructuredNFeatures; ++j) {
849+
const double value = structuredFeatures[i] * structuredFeatures[j];
850+
if (isValidation) {
851+
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsStructuredValidation"), centrality, structuredMoment + 0.5, value);
852+
} else {
853+
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsStructuredTrain"), centrality, structuredMoment + 0.5, value);
854+
}
855+
++structuredMoment;
856+
}
857+
}
858+
859+
for (int component = 0; component < kQRecenteringNComponents; ++component) {
860+
for (int i = 0; i < kQRecenteringStructuredNFeatures; ++i) {
861+
const int index = kQRecenteringStructuredNMatrixMoments + component * kQRecenteringStructuredNFeatures + i;
862+
const double value = structuredFeatures[i] * qValues[component];
863+
if (isValidation) {
864+
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsStructuredValidation"), centrality, index + 0.5, value);
865+
} else {
866+
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsStructuredTrain"), centrality, index + 0.5, value);
867+
}
868+
}
869+
870+
const int q2Index = kQRecenteringStructuredNMatrixMoments + kQRecenteringNComponents * kQRecenteringStructuredNFeatures + component;
871+
const double q2Value = qValues[component] * qValues[component];
872+
if (isValidation) {
873+
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsStructuredValidation"), centrality, q2Index + 0.5, q2Value);
874+
} else {
875+
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsStructuredTrain"), centrality, q2Index + 0.5, q2Value);
876+
}
877+
}
878+
879+
for (int i = 0; i < kQRecenteringStructuredNFeatures; ++i) {
880+
const double value = structuredFeatures[i];
881+
if (isValidation) {
882+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsTimeValidation"), centrality, timeFromSOR, i + 0.5, value);
883+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVxValidation"), centrality, vx, i + 0.5, value);
884+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVyValidation"), centrality, vy, i + 0.5, value);
885+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVzValidation"), centrality, vz, i + 0.5, value);
886+
} else {
887+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsTimeTrain"), centrality, timeFromSOR, i + 0.5, value);
888+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVxTrain"), centrality, vx, i + 0.5, value);
889+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVyTrain"), centrality, vy, i + 0.5, value);
890+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVzTrain"), centrality, vz, i + 0.5, value);
891+
}
892+
}
893+
894+
for (int component = 0; component < kQRecenteringNComponents; ++component) {
895+
const int qIndex = kQRecenteringStructuredNFeatures + component;
896+
const int q2Index = kQRecenteringStructuredNFeatures + kQRecenteringNComponents + component;
897+
const double qValue = qValues[component];
898+
const double q2Value = qValue * qValue;
899+
900+
if (isValidation) {
901+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsTimeValidation"), centrality, timeFromSOR, qIndex + 0.5, qValue);
902+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVxValidation"), centrality, vx, qIndex + 0.5, qValue);
903+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVyValidation"), centrality, vy, qIndex + 0.5, qValue);
904+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVzValidation"), centrality, vz, qIndex + 0.5, qValue);
905+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsTimeValidation"), centrality, timeFromSOR, q2Index + 0.5, q2Value);
906+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVxValidation"), centrality, vx, q2Index + 0.5, q2Value);
907+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVyValidation"), centrality, vy, q2Index + 0.5, q2Value);
908+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVzValidation"), centrality, vz, q2Index + 0.5, q2Value);
909+
} else {
910+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsTimeTrain"), centrality, timeFromSOR, qIndex + 0.5, qValue);
911+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVxTrain"), centrality, vx, qIndex + 0.5, qValue);
912+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVyTrain"), centrality, vy, qIndex + 0.5, qValue);
913+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVzTrain"), centrality, vz, qIndex + 0.5, qValue);
914+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsTimeTrain"), centrality, timeFromSOR, q2Index + 0.5, q2Value);
915+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVxTrain"), centrality, vx, q2Index + 0.5, q2Value);
916+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVyTrain"), centrality, vy, q2Index + 0.5, q2Value);
917+
histos.fill(HIST("QRecenteringCalibration/hStructuredFlatnessMomentsVzTrain"), centrality, vz, q2Index + 0.5, q2Value);
918+
}
919+
}
772920
}
773921
}
774922

0 commit comments

Comments
 (0)