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
131 changes: 116 additions & 15 deletions PWGLF/TableProducer/Common/zdc2stagecalibration.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ struct zdc2stagecalibration {
Configurable<bool> deriveSpatialCalib{"deriveSpatialCalib", false, "store spatial regression moments after gain correction"};
Configurable<bool> deriveQRecentering{"deriveQRecentering", false, "store Q-vector recentering regression moments after gain and spatial correction"};
Configurable<bool> useQRecentering{"useQRecentering", false, "apply Q-vector recentering calibration"};
Configurable<std::string> confQRecenteringPath{"confQRecenteringPath", "", "CCDB path to the run-wise Q-vector recentering coefficients"};
Configurable<int> qRecenteringMethod{"qRecenteringMethod", 0, "Q recentering method: 0=current regression, 1=multidimensional cubic regression"};
Configurable<std::string> confQRecenteringPath{"confQRecenteringPath", "", "CCDB path to the current run-wise Q-vector recentering coefficients"};
Configurable<std::string> confQRecenteringMultidimPath{"confQRecenteringMultidimPath", "", "CCDB path to the multidimensional cubic Q-vector recentering coefficients"};

Configurable<int> cfgSpatialCalibBins{
"cfgSpatialCalibBins", 30,
Expand All @@ -103,10 +105,16 @@ struct zdc2stagecalibration {
static constexpr int kQRecenteringNMatrixMoments = kQRecenteringNFeatures * (kQRecenteringNFeatures + 1) / 2;
static constexpr int kQRecenteringNComponents = 4;
static constexpr int kQRecenteringNMoments = kQRecenteringNMatrixMoments + kQRecenteringNComponents * kQRecenteringNFeatures;
static constexpr int kQRecenteringMultidimNFeatures = 35;
static constexpr int kQRecenteringMultidimNMatrixMoments = kQRecenteringMultidimNFeatures * (kQRecenteringMultidimNFeatures + 1) / 2;
static constexpr int kQRecenteringMultidimNMoments = kQRecenteringMultidimNMatrixMoments + kQRecenteringNComponents * kQRecenteringMultidimNFeatures;

void init(o2::framework::InitContext&)
{
rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad);
if (qRecenteringMethod.value < 0 || qRecenteringMethod.value > 1) {
LOGF(fatal, "Unsupported qRecenteringMethod=%d. Use 0 for the current regression or 1 for the multidimensional cubic regression.", qRecenteringMethod.value);
}

const int nTimeBins = static_cast<int>(std::ceil(cfgMaxRunHours.value * 60.f / cfgTimeSliceMinutes.value));
AxisSpec timeAxis = {nTimeBins, 0.0, cfgMaxRunHours.value, "time from SOR (h)"};
Expand All @@ -119,6 +127,7 @@ struct zdc2stagecalibration {
AxisSpec crossCoordAxis = {2, 0.0, 2.0, "coordinate"};
AxisSpec ratioAxis = {240, 0.0, 2.4, "#Sigma tower/common"};
AxisSpec qRecenteringMomentAxis = {kQRecenteringNMoments, 0.0, static_cast<double>(kQRecenteringNMoments), "regression moment"};
AxisSpec qRecenteringMultidimMomentAxis = {kQRecenteringMultidimNMoments, 0.0, static_cast<double>(kQRecenteringMultidimNMoments), "multidimensional regression moment"};
AxisSpec centralityAxis = {80, 0.0, 80.0, "centrality (%)"};
AxisSpec vertexXYAxis = {100, -0.5, 0.5, "vertex x/y (cm)"};
AxisSpec vertexZAxis = {100, -10.0, 10.0, "vertex z (cm)"};
Expand Down Expand Up @@ -187,6 +196,7 @@ struct zdc2stagecalibration {
// 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("QRecenteringCalibration/hRegressionMomentsMultidim", "Multidimensional cubic Q recentering regression moments;centrality (%);moment index", kTH2D, {centralityAxis, qRecenteringMultidimMomentAxis});

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 @@ -198,6 +208,22 @@ 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});
histos.add("QRecentering2DQA/pQxAAfterVsCentralityTime", "QxA after recentering;centrality (%);time from SOR (h);<Q_{x}^{A}>", kTProfile2D, {centralityAxis, timeAxis});
histos.add("QRecentering2DQA/pQyAAfterVsCentralityTime", "QyA after recentering;centrality (%);time from SOR (h);<Q_{y}^{A}>", kTProfile2D, {centralityAxis, timeAxis});
histos.add("QRecentering2DQA/pQxCAfterVsCentralityTime", "QxC after recentering;centrality (%);time from SOR (h);<Q_{x}^{C}>", kTProfile2D, {centralityAxis, timeAxis});
histos.add("QRecentering2DQA/pQyCAfterVsCentralityTime", "QyC after recentering;centrality (%);time from SOR (h);<Q_{y}^{C}>", kTProfile2D, {centralityAxis, timeAxis});
histos.add("QRecentering2DQA/pQxAAfterVsCentralityVx", "QxA after recentering;centrality (%);v_{x} (cm);<Q_{x}^{A}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQyAAfterVsCentralityVx", "QyA after recentering;centrality (%);v_{x} (cm);<Q_{y}^{A}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQxCAfterVsCentralityVx", "QxC after recentering;centrality (%);v_{x} (cm);<Q_{x}^{C}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQyCAfterVsCentralityVx", "QyC after recentering;centrality (%);v_{x} (cm);<Q_{y}^{C}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQxAAfterVsCentralityVy", "QxA after recentering;centrality (%);v_{y} (cm);<Q_{x}^{A}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQyAAfterVsCentralityVy", "QyA after recentering;centrality (%);v_{y} (cm);<Q_{y}^{A}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQxCAfterVsCentralityVy", "QxC after recentering;centrality (%);v_{y} (cm);<Q_{x}^{C}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQyCAfterVsCentralityVy", "QyC after recentering;centrality (%);v_{y} (cm);<Q_{y}^{C}>", kTProfile2D, {centralityAxis, vertexXYAxis});
histos.add("QRecentering2DQA/pQxAAfterVsCentralityVz", "QxA after recentering;centrality (%);v_{z} (cm);<Q_{x}^{A}>", kTProfile2D, {centralityAxis, vertexZAxis});
histos.add("QRecentering2DQA/pQyAAfterVsCentralityVz", "QyA after recentering;centrality (%);v_{z} (cm);<Q_{y}^{A}>", kTProfile2D, {centralityAxis, vertexZAxis});
histos.add("QRecentering2DQA/pQxCAfterVsCentralityVz", "QxC after recentering;centrality (%);v_{z} (cm);<Q_{x}^{C}>", kTProfile2D, {centralityAxis, vertexZAxis});
histos.add("QRecentering2DQA/pQyCAfterVsCentralityVz", "QyC after recentering;centrality (%);v_{z} (cm);<Q_{y}^{C}>", kTProfile2D, {centralityAxis, vertexZAxis});

// 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});
Expand Down Expand Up @@ -252,8 +278,11 @@ struct zdc2stagecalibration {
LOGF(warn, "No ZDC spatial calibration found for run %d at timestamp %llu", runNumber, static_cast<unsigned long long>(timestamp));
}
}
if (calibrationStage.value == 2 && useQRecentering.value && !confQRecenteringPath.value.empty()) {
qRecenteringProfile = ccdb->getForTimeStamp<TH3D>(confQRecenteringPath.value, timestamp);
if (calibrationStage.value == 2 && useQRecentering.value) {
const std::string qRecenteringPath = qRecenteringMethod.value == 1 ? confQRecenteringMultidimPath.value : confQRecenteringPath.value;
if (!qRecenteringPath.empty()) {
qRecenteringProfile = ccdb->getForTimeStamp<TH3D>(qRecenteringPath, 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 @@ -307,6 +336,26 @@ struct zdc2stagecalibration {
x * y, x * z, y * z};
}

std::array<double, kQRecenteringMultidimNFeatures> makeQRecenteringMultidimFeatures(float timeFromSOR, float vx, float vy, float vz) const
{
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;
const double y = static_cast<double>(vy) / 0.1;
const double z = static_cast<double>(vz) / 10.0;
const double t2 = t * t;
const double x2 = x * x;
const double y2 = y * y;
const double z2 = z * z;

return {1.0, t, x, y, z,
t2, x2, y2, z2, t * x, t * y, t * z, x * y, x * z, y * z,
t2 * t, x2 * x, y2 * y, z2 * z,
t2 * x, t2 * y, t2 * z, x2 * t, x2 * y, x2 * z,
y2 * t, y2 * x, y2 * z, z2 * t, z2 * x, z2 * y,
t * x * y, t * x * z, t * y * z, x * y * z};
}

using MyCollisions = o2::soa::Join<o2::aod::Collisions, o2::aod::EvSels, o2::aod::Mults, o2::aod::FT0sCorrected, o2::aod::CentFT0Cs>;

void process(MyCollisions::iterator const& collision, o2::aod::FT0s const& /*ft0s*/, o2::aod::FV0As const& /*fv0s*/, BCsRun3 const& /*bcs*/, o2::aod::Zdcs const& /*zdcs*/)
Expand Down Expand Up @@ -632,7 +681,6 @@ struct zdc2stagecalibration {
return;
}

const auto qFeatures = makeQRecenteringFeatures(centrality, timeFromSOR, vx, vy, vz);
std::array<double, 4> qValues = {qxZDCA, qyZDCA, qxZDCC, qyZDCC};

for (int i = 0; i < 4; ++i) {
Expand All @@ -654,17 +702,35 @@ struct zdc2stagecalibration {
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"), centrality, moment + 0.5, qFeatures[i] * qFeatures[j]);
++moment;
}
}
for (int component = 0; component < kQRecenteringNComponents; ++component) {
if (qRecenteringMethod.value == 0) {
const auto qFeatures = makeQRecenteringFeatures(centrality, timeFromSOR, vx, vy, vz);
int moment = 0;
for (int i = 0; i < kQRecenteringNFeatures; ++i) {
const int index = kQRecenteringNMatrixMoments + component * kQRecenteringNFeatures + i;
histos.fill(HIST("QRecenteringCalibration/hRegressionMoments"), centrality, index + 0.5, qFeatures[i] * qValues[component]);
for (int j = i; j < kQRecenteringNFeatures; ++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"), centrality, index + 0.5, qFeatures[i] * qValues[component]);
}
}
} else {
const auto qFeatures = makeQRecenteringMultidimFeatures(timeFromSOR, vx, vy, vz);
int moment = 0;
for (int i = 0; i < kQRecenteringMultidimNFeatures; ++i) {
for (int j = i; j < kQRecenteringMultidimNFeatures; ++j) {
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsMultidim"), centrality, moment + 0.5, qFeatures[i] * qFeatures[j]);
++moment;
}
}
for (int component = 0; component < kQRecenteringNComponents; ++component) {
for (int i = 0; i < kQRecenteringMultidimNFeatures; ++i) {
const int index = kQRecenteringMultidimNMatrixMoments + component * kQRecenteringMultidimNFeatures + i;
histos.fill(HIST("QRecenteringCalibration/hRegressionMomentsMultidim"), centrality, index + 0.5, qFeatures[i] * qValues[component]);
}
}
}
}
Expand All @@ -673,7 +739,8 @@ struct zdc2stagecalibration {
if (calibrationStage.value == 2 && useQRecentering.value) {
if (!qRecenteringProfile) {
qRecenteringOK = false;
} else {
} else if (qRecenteringMethod.value == 0) {
const auto qFeatures = makeQRecenteringFeatures(centrality, timeFromSOR, vx, vy, vz);
for (int component = 0; component < kQRecenteringNComponents; ++component) {
double predictedBias = 0.0;
for (int i = 0; i < kQRecenteringNFeatures; ++i) {
Expand All @@ -690,6 +757,24 @@ struct zdc2stagecalibration {
}
qValues[component] -= predictedBias;
}
} else {
const auto qFeatures = makeQRecenteringMultidimFeatures(timeFromSOR, vx, vy, vz);
for (int component = 0; component < kQRecenteringNComponents; ++component) {
double predictedBias = 0.0;
for (int i = 0; i < kQRecenteringMultidimNFeatures; ++i) {
const double coefficient = qRecenteringProfile->GetBinContent(qRecenteringProfile->FindBin(centrality, i + 0.5, component + 0.5));
if (!std::isfinite(coefficient)) {
qRecenteringOK = false;
break;
}
predictedBias += coefficient * qFeatures[i];
}
if (!qRecenteringOK || !std::isfinite(predictedBias)) {
qRecenteringOK = false;
break;
}
qValues[component] -= predictedBias;
}
}
}
if (!qRecenteringOK) {
Expand All @@ -705,6 +790,22 @@ struct zdc2stagecalibration {
histos.fill(HIST("QRecenteringQA/pQAfterVsVy"), vy, component, qValues[i]);
histos.fill(HIST("QRecenteringQA/pQAfterVsVz"), vz, component, qValues[i]);
}
histos.fill(HIST("QRecentering2DQA/pQxAAfterVsCentralityTime"), centrality, timeFromSOR, qValues[0]);
histos.fill(HIST("QRecentering2DQA/pQyAAfterVsCentralityTime"), centrality, timeFromSOR, qValues[1]);
histos.fill(HIST("QRecentering2DQA/pQxCAfterVsCentralityTime"), centrality, timeFromSOR, qValues[2]);
histos.fill(HIST("QRecentering2DQA/pQyCAfterVsCentralityTime"), centrality, timeFromSOR, qValues[3]);
histos.fill(HIST("QRecentering2DQA/pQxAAfterVsCentralityVx"), centrality, vx, qValues[0]);
histos.fill(HIST("QRecentering2DQA/pQyAAfterVsCentralityVx"), centrality, vx, qValues[1]);
histos.fill(HIST("QRecentering2DQA/pQxCAfterVsCentralityVx"), centrality, vx, qValues[2]);
histos.fill(HIST("QRecentering2DQA/pQyCAfterVsCentralityVx"), centrality, vx, qValues[3]);
histos.fill(HIST("QRecentering2DQA/pQxAAfterVsCentralityVy"), centrality, vy, qValues[0]);
histos.fill(HIST("QRecentering2DQA/pQyAAfterVsCentralityVy"), centrality, vy, qValues[1]);
histos.fill(HIST("QRecentering2DQA/pQxCAfterVsCentralityVy"), centrality, vy, qValues[2]);
histos.fill(HIST("QRecentering2DQA/pQyCAfterVsCentralityVy"), centrality, vy, qValues[3]);
histos.fill(HIST("QRecentering2DQA/pQxAAfterVsCentralityVz"), centrality, vz, qValues[0]);
histos.fill(HIST("QRecentering2DQA/pQyAAfterVsCentralityVz"), centrality, vz, qValues[1]);
histos.fill(HIST("QRecentering2DQA/pQxCAfterVsCentralityVz"), centrality, vz, qValues[2]);
histos.fill(HIST("QRecentering2DQA/pQyCAfterVsCentralityVz"), centrality, vz, qValues[3]);

histos.fill(HIST("QCorrelationQA/hQxAQxCAfter"), qValues[0], qValues[2]);
histos.fill(HIST("QCorrelationQA/hQyAQyCAfter"), qValues[1], qValues[3]);
Expand Down
Loading
Loading