Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 69 additions & 12 deletions PWGLF/TableProducer/Common/zdc2stagecalibration.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ struct zdc2stagecalibration {
uint64_t eorTimestamp = 0;
TH2D* gainprofile = nullptr;
TH3D* spatialprofile = nullptr;
TH2D* qRecenteringProfile = nullptr;
TH3D* qRecenteringProfile = nullptr;

static constexpr int kQRecenteringNFeatures = 21;
static constexpr int kQRecenteringNMatrixMoments = kQRecenteringNFeatures * (kQRecenteringNFeatures + 1) / 2;
Expand All @@ -123,6 +123,8 @@ struct zdc2stagecalibration {
AxisSpec vertexXYAxis = {100, -0.5, 0.5, "vertex x/y (cm)"};
AxisSpec vertexZAxis = {100, -10.0, 10.0, "vertex z (cm)"};
AxisSpec qComponentAxis = {4, 0.0, 4.0, "Q component"};
AxisSpec qCorrelationComponentAxis = {4, 0.0, 4.0, "A-C correlation component"};
AxisSpec qValueAxis = {200, -4.0, 4.0, "Q"};

histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0.0, 10.0}});
auto hEvtSelInfo = histos.get<TH1>(HIST("hEvtSelInfo"));
Expand Down Expand Up @@ -161,6 +163,12 @@ struct zdc2stagecalibration {
histos.add("PhiQA/hPhiAfterGainZNC", "ZNC #phi after gain calibration;#phi;events", kTH1F, {phiAxis});
histos.add("PhiQA/hPhiAfterSpatialZNA", "ZNA #phi after spatial calibration;#phi;events", kTH1F, {phiAxis});
histos.add("PhiQA/hPhiAfterSpatialZNC", "ZNC #phi after spatial calibration;#phi;events", kTH1F, {phiAxis});
histos.add("PhiQA/hPhiRawVsCentralityZNA", "ZNA #phi raw vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});
histos.add("PhiQA/hPhiRawVsCentralityZNC", "ZNC #phi raw vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});
histos.add("PhiQA/hPhiAfterGainVsCentralityZNA", "ZNA #phi after gain vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});
histos.add("PhiQA/hPhiAfterGainVsCentralityZNC", "ZNC #phi after gain vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});
histos.add("PhiQA/hPhiAfterSpatialVsCentralityZNA", "ZNA #phi after spatial calibration vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});
histos.add("PhiQA/hPhiAfterSpatialVsCentralityZNC", "ZNC #phi after spatial calibration vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});

// Stage-1 correction input. For each time bin the first 10 y bins contain sum(T_i*T_j), the next 4 contain sum(C*T_i), and the last contains the event count.
histos.add("GainCalibration/hGainMomentsZNA", "ZNA linear-regression moments;time from SOR (h);moment index", kTH2D, {timeAxis, momentAxis});
Expand All @@ -170,13 +178,15 @@ struct zdc2stagecalibration {
histos.add("SpatialCalibration/hSpatialMomentsZNA", "ZNA normalized pair spatial regression moments;X cross;Y cross;moment index", kTH3D, {spatialCalibAxis, spatialCalibAxis, spatialMomentAxis});
histos.add("SpatialCalibration/hSpatialMomentsZNC", "ZNC normalized pair spatial regression moments;X cross;Y cross;moment index", kTH3D, {spatialCalibAxis, spatialCalibAxis, spatialMomentAxis});

// Q-recentering regression moments. Feature order:
// Q-recentering regression moments derived independently in 1% centrality bins.
// The centrality feature C is local to each 1% bin: C=2*(cent-(floor(cent)+0.5)), so C is in [-1,1).
// Feature order:
// 0:1, 1:C, 2:T, 3:Vx, 4:Vy, 5:Vz, 6:C2, 7:T2, 8:Vx2, 9:Vy2, 10:Vz2,
// 11:C*T, 12:C*Vx, 13:C*Vy, 14:C*Vz, 15:T*Vx, 16:T*Vy, 17:T*Vz,
// 18:Vx*Vy, 19:Vx*Vz, 20:Vy*Vz.
// Moments 0..230 are the upper triangle of sum(X_i X_j).
// Then 4 blocks of 21 sum(X_i Q): QxA, QyA, QxC, QyC.
histos.add("QRecenteringCalibration/hRegressionMoments", "Q recentering regression moments;moment index;sum", kTH1D, {qRecenteringMomentAxis});
// For each 1% centrality bin, moments 0..230 are the upper triangle of sum(X_i X_j),
// followed by 4 blocks of 21 sum(X_i Q): QxA, QyA, QxC, QyC.
histos.add("QRecenteringCalibration/hRegressionMoments", "Q recentering regression moments;centrality (%);moment index", kTH2D, {centralityAxis, qRecenteringMomentAxis});

histos.add("QRecenteringQA/pQBeforeVsCentrality", "Q before recentering vs centrality;centrality (%);Q component;<Q>", kTProfile2D, {centralityAxis, qComponentAxis});
histos.add("QRecenteringQA/pQBeforeVsTime", "Q before recentering vs time;time from SOR (h);Q component;<Q>", kTProfile2D, {timeAxis, qComponentAxis});
Expand All @@ -188,8 +198,26 @@ struct zdc2stagecalibration {
histos.add("QRecenteringQA/pQAfterVsVx", "Q after recentering vs v_{x};v_{x} (cm);Q component;<Q>", kTProfile2D, {vertexXYAxis, qComponentAxis});
histos.add("QRecenteringQA/pQAfterVsVy", "Q after recentering vs v_{y};v_{y} (cm);Q component;<Q>", kTProfile2D, {vertexXYAxis, qComponentAxis});
histos.add("QRecenteringQA/pQAfterVsVz", "Q after recentering vs v_{z};v_{z} (cm);Q component;<Q>", kTProfile2D, {vertexZAxis, qComponentAxis});

// A-C Q-vector correlation QA. These histograms are diagnostic only; no Qx/Qy mixing is applied.
histos.add("QCorrelationQA/hQxAQxCBefore", "QxA vs QxC before recentering;Q_{x}^{A};Q_{x}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("QCorrelationQA/hQyAQyCBefore", "QyA vs QyC before recentering;Q_{y}^{A};Q_{y}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("QCorrelationQA/hQxAQyCBefore", "QxA vs QyC before recentering;Q_{x}^{A};Q_{y}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("QCorrelationQA/hQyAQxCBefore", "QyA vs QxC before recentering;Q_{y}^{A};Q_{x}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("QCorrelationQA/hQxAQxCAfter", "QxA vs QxC after recentering;Q_{x}^{A};Q_{x}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("QCorrelationQA/hQyAQyCAfter", "QyA vs QyC after recentering;Q_{y}^{A};Q_{y}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("QCorrelationQA/hQxAQyCAfter", "QxA vs QyC after recentering;Q_{x}^{A};Q_{y}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("QCorrelationQA/hQyAQxCAfter", "QyA vs QxC after recentering;Q_{y}^{A};Q_{x}^{C}", kTH2F, {qValueAxis, qValueAxis});
histos.add("PhiQA/hPhiAfterRecenteringZNA", "ZNA #phi after Q recentering;#phi;events", kTH1F, {phiAxis});
histos.add("PhiQA/hPhiAfterRecenteringZNC", "ZNC #phi after Q recentering;#phi;events", kTH1F, {phiAxis});
histos.add("PhiQA/hPhiAfterRecenteringVsCentralityZNA", "ZNA #phi after Q recentering vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});
histos.add("PhiQA/hPhiAfterRecenteringVsCentralityZNC", "ZNC #phi after Q recentering vs centrality;centrality (%);#phi", kTH2F, {centralityAxis, phiAxis});

// A-C Q correlations versus centrality. Component convention:
// 0: QxA*QxC, 1: QyA*QyC, 2: QxA*QyC, 3: QyA*QxC.
// These are QA only; they are never used in the recentering correction.
histos.add("QCorrelationQA/pQACorrelationBeforeVsCentrality", "A-C Q correlations before recentering;centrality (%);correlation component;<Q_{A}Q_{C}>", kTProfile2D, {centralityAxis, qCorrelationComponentAxis});
histos.add("QCorrelationQA/pQACorrelationAfterVsCentrality", "A-C Q correlations after recentering;centrality (%);correlation component;<Q_{A}Q_{C}>", kTProfile2D, {centralityAxis, qCorrelationComponentAxis});

ccdb->setURL(cfgCcdbParam.cfgURL);
ccdb->setCaching(true);
Expand Down Expand Up @@ -225,7 +253,7 @@ struct zdc2stagecalibration {
}
}
if (calibrationStage.value == 2 && useQRecentering.value && !confQRecenteringPath.value.empty()) {
qRecenteringProfile = ccdb->getForTimeStamp<TH2D>(confQRecenteringPath.value, timestamp);
qRecenteringProfile = ccdb->getForTimeStamp<TH3D>(confQRecenteringPath.value, timestamp);
if (!qRecenteringProfile) {
LOGF(warn, "No ZDC Q-recentering calibration found for run %d at timestamp %llu", runNumber, static_cast<unsigned long long>(timestamp));
}
Expand Down Expand Up @@ -260,9 +288,12 @@ struct zdc2stagecalibration {

std::array<double, kQRecenteringNFeatures> makeQRecenteringFeatures(float centrality, float timeFromSOR, float vx, float vy, float vz) const
{
// Fixed scaling keeps the polynomial basis numerically well behaved and must be
// used identically when solving/applying the CCDB coefficients.
const double c = (static_cast<double>(centrality) - 40.0) / 40.0;
// Recentering is solved independently in each 1% centrality bin.
// Keep a local centrality coordinate inside the bin so correlations with time/vertex
// are retained without using the global 0-80% centrality scale.
const double cent = static_cast<double>(centrality);
const double centBinLow = std::floor(cent);
const double c = 2.0 * (cent - (centBinLow + 0.5));
const double runHours = (eorTimestamp > sorTimestamp) ? static_cast<double>(eorTimestamp - sorTimestamp) * 1.e-3 / 3600.0 : static_cast<double>(cfgMaxRunHours.value);
const double t = (runHours > 0.0) ? (2.0 * static_cast<double>(timeFromSOR) / runHours - 1.0) : 0.0;
const double x = static_cast<double>(vx) / 0.1;
Expand Down Expand Up @@ -370,6 +401,8 @@ struct zdc2stagecalibration {
const double phiRawC = std::atan2(rawYC, rawXC);
histos.fill(HIST("PhiQA/hPhiRawZNA"), phiRawA);
histos.fill(HIST("PhiQA/hPhiRawZNC"), phiRawC);
histos.fill(HIST("PhiQA/hPhiRawVsCentralityZNA"), centrality, phiRawA);
histos.fill(HIST("PhiQA/hPhiRawVsCentralityZNC"), centrality, phiRawC);

if (calibrationStage.value == 1) {
std::array<double, 15> momentsA{};
Expand Down Expand Up @@ -429,6 +462,8 @@ struct zdc2stagecalibration {
const double phiGainC = std::atan2(gainYC, gainXC);
histos.fill(HIST("PhiQA/hPhiAfterGainZNA"), phiGainA);
histos.fill(HIST("PhiQA/hPhiAfterGainZNC"), phiGainC);
histos.fill(HIST("PhiQA/hPhiAfterGainVsCentralityZNA"), centrality, phiGainA);
histos.fill(HIST("PhiQA/hPhiAfterGainVsCentralityZNC"), centrality, phiGainC);

const double crossLookupXA = (znaCorr[3] - znaCorr[0]) / (znaCorr[3] + znaCorr[0]);
const double crossLookupYA = (znaCorr[2] - znaCorr[1]) / (znaCorr[2] + znaCorr[1]);
Expand Down Expand Up @@ -518,6 +553,8 @@ struct zdc2stagecalibration {
const double phiSpatialC = std::atan2(centroidYC, centroidXC);
histos.fill(HIST("PhiQA/hPhiAfterSpatialZNA"), phiSpatialA);
histos.fill(HIST("PhiQA/hPhiAfterSpatialZNC"), phiSpatialC);
histos.fill(HIST("PhiQA/hPhiAfterSpatialVsCentralityZNA"), centrality, phiSpatialA);
histos.fill(HIST("PhiQA/hPhiAfterSpatialVsCentralityZNC"), centrality, phiSpatialC);

histos.fill(HIST("GainQA/hSumOverCommonVsTimeZNA"), timeFromSOR, ratioA);
histos.fill(HIST("GainQA/hSumOverCommonVsTimeZNC"), timeFromSOR, ratioC);
Expand Down Expand Up @@ -607,18 +644,27 @@ struct zdc2stagecalibration {
histos.fill(HIST("QRecenteringQA/pQBeforeVsVz"), vz, component, qValues[i]);
}

histos.fill(HIST("QCorrelationQA/hQxAQxCBefore"), qValues[0], qValues[2]);
histos.fill(HIST("QCorrelationQA/hQyAQyCBefore"), qValues[1], qValues[3]);
histos.fill(HIST("QCorrelationQA/hQxAQyCBefore"), qValues[0], qValues[3]);
histos.fill(HIST("QCorrelationQA/hQyAQxCBefore"), qValues[1], qValues[2]);
histos.fill(HIST("QCorrelationQA/pQACorrelationBeforeVsCentrality"), centrality, 0.5, qValues[0] * qValues[2]);
histos.fill(HIST("QCorrelationQA/pQACorrelationBeforeVsCentrality"), centrality, 1.5, qValues[1] * qValues[3]);
histos.fill(HIST("QCorrelationQA/pQACorrelationBeforeVsCentrality"), centrality, 2.5, qValues[0] * qValues[3]);
histos.fill(HIST("QCorrelationQA/pQACorrelationBeforeVsCentrality"), centrality, 3.5, qValues[1] * qValues[2]);

if (calibrationStage.value == 2 && useGainCallib.value && useSpatialCalib.value && deriveQRecentering.value && !useQRecentering.value) {
int moment = 0;
for (int i = 0; i < kQRecenteringNFeatures; ++i) {
for (int j = i; j < kQRecenteringNFeatures; ++j) {
histos.fill(HIST("QRecenteringCalibration/hRegressionMoments"), moment + 0.5, qFeatures[i] * qFeatures[j]);
histos.fill(HIST("QRecenteringCalibration/hRegressionMoments"), centrality, moment + 0.5, qFeatures[i] * qFeatures[j]);
++moment;
}
}
for (int component = 0; component < kQRecenteringNComponents; ++component) {
for (int i = 0; i < kQRecenteringNFeatures; ++i) {
const int index = kQRecenteringNMatrixMoments + component * kQRecenteringNFeatures + i;
histos.fill(HIST("QRecenteringCalibration/hRegressionMoments"), index + 0.5, qFeatures[i] * qValues[component]);
histos.fill(HIST("QRecenteringCalibration/hRegressionMoments"), centrality, index + 0.5, qFeatures[i] * qValues[component]);
}
}
}
Expand All @@ -631,7 +677,7 @@ struct zdc2stagecalibration {
for (int component = 0; component < kQRecenteringNComponents; ++component) {
double predictedBias = 0.0;
for (int i = 0; i < kQRecenteringNFeatures; ++i) {
const double coefficient = qRecenteringProfile->GetBinContent(qRecenteringProfile->FindBin(i + 0.5, component + 0.5));
const double coefficient = qRecenteringProfile->GetBinContent(qRecenteringProfile->FindBin(centrality, i + 0.5, component + 0.5));
if (!std::isfinite(coefficient)) {
qRecenteringOK = false;
break;
Expand Down Expand Up @@ -660,10 +706,21 @@ struct zdc2stagecalibration {
histos.fill(HIST("QRecenteringQA/pQAfterVsVz"), vz, component, qValues[i]);
}

histos.fill(HIST("QCorrelationQA/hQxAQxCAfter"), qValues[0], qValues[2]);
histos.fill(HIST("QCorrelationQA/hQyAQyCAfter"), qValues[1], qValues[3]);
histos.fill(HIST("QCorrelationQA/hQxAQyCAfter"), qValues[0], qValues[3]);
histos.fill(HIST("QCorrelationQA/hQyAQxCAfter"), qValues[1], qValues[2]);
histos.fill(HIST("QCorrelationQA/pQACorrelationAfterVsCentrality"), centrality, 0.5, qValues[0] * qValues[2]);
histos.fill(HIST("QCorrelationQA/pQACorrelationAfterVsCentrality"), centrality, 1.5, qValues[1] * qValues[3]);
histos.fill(HIST("QCorrelationQA/pQACorrelationAfterVsCentrality"), centrality, 2.5, qValues[0] * qValues[3]);
histos.fill(HIST("QCorrelationQA/pQACorrelationAfterVsCentrality"), centrality, 3.5, qValues[1] * qValues[2]);

const double phiRecenteringA = std::atan2(qValues[1], qValues[0]);
const double phiRecenteringC = std::atan2(qValues[3], qValues[2]);
histos.fill(HIST("PhiQA/hPhiAfterRecenteringZNA"), phiRecenteringA);
histos.fill(HIST("PhiQA/hPhiAfterRecenteringZNC"), phiRecenteringC);
histos.fill(HIST("PhiQA/hPhiAfterRecenteringVsCentralityZNA"), centrality, phiRecenteringA);
histos.fill(HIST("PhiQA/hPhiAfterRecenteringVsCentralityZNC"), centrality, phiRecenteringC);

histos.fill(HIST("hEvtSelInfo"), 7.5);
fillTable(true, static_cast<float>(qValues[0]), static_cast<float>(qValues[2]), static_cast<float>(qValues[1]), static_cast<float>(qValues[3]));
Expand Down
Loading
Loading