From c04c625033ca3e2cc342ee63ab063ea68ab5c017 Mon Sep 17 00:00:00 2001 From: Somadutta Bhatta Date: Tue, 24 Feb 2026 22:12:40 +0100 Subject: [PATCH] Feature: 2D Matrix for Decorrelation measurement --- .../Tasks/radialFlowDecorr.cxx | 3572 ++++++++++------- 1 file changed, 2225 insertions(+), 1347 deletions(-) diff --git a/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx b/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx index a3e9bd56fcd..c0d1439192b 100644 --- a/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx @@ -43,6 +43,7 @@ #include "TH1F.h" #include "TH2F.h" #include "TH3F.h" +#include "THnSparse.h" #include "TMath.h" #include "TProfile.h" #include "TProfile2D.h" @@ -77,12 +78,14 @@ struct RadialFlowDecorr { static constexpr int KPiPlus = 211; static constexpr int KKPlus = 321; static constexpr int KProton = 2212; + static constexpr int KNsp = 4; static constexpr float KCentTestMin = 10.f; static constexpr float KCentTestMaxLo = 60.f; static constexpr float KCentTestMaxHi = 70.f; static constexpr float KCentCovCut = 1.0f; static constexpr float KBinOffset = 0.5f; + static constexpr float KHalf = 0.5f; static constexpr float KPhiMin = 0.f; @@ -101,7 +104,8 @@ struct RadialFlowDecorr { static constexpr int KNbinsPhi = 64; static constexpr float KEtaAxisMin = -0.8f; static constexpr float KEtaAxisMax = 0.8f; - static constexpr int KNbinsPhiFine = 30; + static constexpr int KNbinsPhiFine = 16; + static constexpr int KNbinsPtRes = 50; static constexpr float KPtResMax = 1.f; static constexpr int KNbinsEtaRes = 100; @@ -120,18 +124,29 @@ struct RadialFlowDecorr { static constexpr float KPtHighMax = 5.0f; static constexpr float KPtFullMax = 10.0f; static constexpr float KCentMax = 90; - enum PID { kInclusive = 0, - kCombinedPID, - kNumPID }; + enum PID { + numKInclusive = 0, // Suffix "" + numKPion, // Suffix "_Pi" + numKKaon, // Suffix "_Ka" + numKProton, // Suffix "_Pr" + numKNumPID // Total: 4 + }; + + const std::vector pidSuffix = {"", "_Pi", "_Ka", "_Pr"}; + enum ECentralityEstimator { kCentFT0C = 1, kCentFT0A = 2, kCentFT0M = 3, kCentFV0A = 4 }; + enum SystemType { + kPbPb = 1, + kOO = 2, + kpPb = 3, + kpp = 4 + }; static constexpr float KinvalidCentrality = -1.0f; - const std::vector pidSuffix = {"", "_PID"}; - const std::vector etaLw = { -0.8, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7}; @@ -167,7 +182,6 @@ struct RadialFlowDecorr { Configurable cfgnSigmaCutTOF{"cfgnSigmaCutTOF", 2.0f, "PID nSigma cut for TOF"}; Configurable cfgnSigmaCutCombTPCTOF{"cfgnSigmaCutCombTPCTOF", 2.0f, "PID nSigma combined cut for TPC and TOF"}; Configurable cfgCutPtLower{"cfgCutPtLower", 0.2f, "Lower pT cut"}; - Configurable cfgCutPtLowerProt{"cfgCutPtLowerProt", 0.2f, "Lower pT cut"}; Configurable cfgCutPtUpper{"cfgCutPtUpper", 10.0f, "Higher pT cut for inclusive hadron analysis"}; Configurable cfgCutPtUpperPID{"cfgCutPtUpperPID", 6.0f, "Higher pT cut for identified particle analysis"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "absolute Eta cut"}; @@ -179,29 +193,71 @@ struct RadialFlowDecorr { Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time interval with dead ITS zone"}; Configurable cfgEvSelkNoITSROFrameBorder{"cfgEvSelkNoITSROFrameBorder", true, "ITSROFrame border event selection cut"}; Configurable cfgEvSelkNoTimeFrameBorder{"cfgEvSelkNoTimeFrameBorder", true, "TimeFrame border event selection cut"}; + Configurable cfgIsGoodZvtxFT0VsPV{"cfgIsGoodZvtxFT0VsPV", true, "Good Vertexing cut"}; + + Configurable cfgNchPbMax{"cfgNchPbMax", 4000, "Max Nch range for PbPb collisions"}; + Configurable cfgNchOMax{"cfgNchOMax", 600, "Max Nch range for OO collisions"}; + + Configurable cfgSys{"cfgSys", 1, "Efficiency to be used for which system? 1-->PbPb, 2-->OO, 3-->pPb, 4-->pp"}; + Configurable cfgFlat{"cfgFlat", false, "Whether to use flattening weights"}; + Configurable cfgEff{"cfgEff", false, "Whether to use Efficiency weights"}; + Configurable cfgZDC{"cfgZDC", false, "Whether to use ZDC for pileup histograms"}; + + Configurable cfgCCDBurl{"cfgCCDBurl", "https://alice-ccdb.cern.ch", "ccdb url"}; + Configurable cfgCCDBUserPath{"cfgCCDBUserPath", "/Users/s/somadutt", "Base CCDB path"}; + + ConfigurableAxis cfgAxisCent{"cfgAxisCent", {0.0, 1.0, 3.0, 5.0, 10, 20, 30, 40, 50, 60, 70, 80, 100}, "centrality axis (percentile)"}; + + const AxisSpec centAxis{cfgAxisCent, "Centrality (%)"}; + const AxisSpec centAxis1Per{101, -0.5, 100.5, + "Centrality (%)" + "Centrality (%)"}; + AxisSpec nChAxis{1, 0., 1., "Nch", "Nch"}; + AxisSpec nChAxis2{1, 0., 1., "Nch", "Nch"}; + + const AxisSpec vzAxis{5, -12.5, 12.5, "Vz"}; + const AxisSpec chgAxis{3, -1.5, 1.5}; + const AxisSpec pTAxis{{0.0, 0.2, 0.5, 1, 3, 5, 7.5, 10}, "pT Axis"}; + const AxisSpec etaAxis{{-0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}, "Eta"}; + const AxisSpec gapAxis{{-1.55, -1.45, -1.35, -1.25, -1.15, -1.05, -0.95, -0.85, -0.75, -0.65, -0.55, -0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95, 1.05, 1.15, 1.25, 1.35, 1.45, 1.55}, "Gaps"}; + const AxisSpec sumAxis{{-0.775, -0.725, -0.675, -0.625, -0.575, -0.525, -0.475, -0.425, -0.375, -0.325, -0.275, -0.225, -0.175, -0.125, -0.075, -0.025, 0.025, 0.075, 0.125, 0.175, 0.225, 0.275, 0.325, 0.375, 0.425, 0.475, 0.525, 0.575, 0.625, 0.675, 0.725, 0.775}, "Sums"}; + + Configurable cfgRunGetEff{"cfgRunGetEff", false, "Run MC pass to build efficiency/fake maps"}; + Configurable cfgRunGetMCFlat{"cfgRunGetMCFlat", false, "Run MC to Get Flattening Weights"}; + Configurable cfgRunMCMean{"cfgRunMCMean", false, "Run MC mean(pT) & mean(Et)"}; + Configurable cfgRunMCFluc{"cfgRunMCFluc", false, "Run MC fluctuations (C2, subevent)"}; + Configurable cfgRunGetDataFlat{"cfgRunGetDataFlat", false, "Run Data Get Flattening Weights"}; + Configurable cfgRunDataMean{"cfgRunDataMean", false, "Run DATA mean(pT) & mean(Et)"}; + Configurable cfgRunDataFluc{"cfgRunDataFluc", false, "Run DATA fluctuations (C2, subevent)"}; Service ccdb; Service pdg; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - std::array hEff{}; - std::array hFake{}; - std::array hWeightMap3D{}; + std::array hEff{}; + std::array hFake{}; + std::array hFlatWeight{}; + + std::array pmeanTruNchEtabinPtbinStep2{}; + std::array pmeanRecoNchEtabinPtbinStep2{}; + std::array pmeanRecoEffcorrNchEtabinPtbinStep2{}; - TProfile3D* pmeanTruNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanRecoNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanRecoMatchedNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanRecoEffcorrNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanRecoMatchedEffcorrNchEtabinPtbinStep2 = nullptr; + std::array pmeanMultTruNchEtabinPtbinStep2{}; + std::array pmeanMultRecoNchEtabinPtbinStep2{}; + std::array pmeanMultRecoEffcorrNchEtabinPtbinStep2{}; - TProfile3D* pmeanEtTruNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanEtRecoNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanEtRecoMatchedNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanEtRecoEffcorrNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanEtRecoMatchedEffcorrNchEtabinPtbinStep2 = nullptr; + std::array pmeanNchEtabinPtbinStep2{}; + std::array pmeanMultNchEtabinPtbinStep2{}; - TProfile3D* pmeanNchEtabinPtbinStep2 = nullptr; - TProfile3D* pmeanEtNchEtabinPtbinStep2 = nullptr; + template + static std::tuple getAllCombinedNSigmas(const T& candidate) + { + return { + std::hypot(candidate.tpcNSigmaPr(), candidate.tofNSigmaPr()), // Proton + std::hypot(candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()), // Pion + std::hypot(candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()) // Kaon + }; + } template bool isEventSelected(const T& col) @@ -212,10 +268,9 @@ struct RadialFlowDecorr { return false; if (cfgEvSelkNoSameBunchPileup && !col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) return false; - if (cfgEvSelkNoITSROFrameBorder && !col.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) - return false; - if (cfgEvSelkNoTimeFrameBorder && !col.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) - return false; + // if (cfgIsGoodZvtxFT0VsPV && !col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + // return false; + return true; } @@ -248,7 +303,6 @@ struct RadialFlowDecorr { auto* pd = pdg->GetParticle(particle.pdgCode()); if (!pd) return false; - // if (dpt::isStrangeBaryonPDG(particle.pdgCode())) return false; if (std::abs(pd->Charge()) == 0) return false; if (particle.pt() < cfgCutPtLower || particle.pt() > cfgCutPtUpper || std::abs(particle.eta()) > cfgCutEta) @@ -274,10 +328,7 @@ struct RadialFlowDecorr { } } if (candidate.hasTOF() && candidate.pt() > cfgCutPtUpperTPC && candidate.pt() < cfgCutPtUpperPID) { - float combNSigmaPr = std::sqrt(std::pow(candidate.tpcNSigmaPr(), 2.0) + std::pow(candidate.tofNSigmaPr(), 2.0)); - float combNSigmaPi = std::sqrt(std::pow(candidate.tpcNSigmaPi(), 2.0) + std::pow(candidate.tofNSigmaPi(), 2.0)); - float combNSigmaKa = std::sqrt(std::pow(candidate.tpcNSigmaKa(), 2.0) + std::pow(candidate.tofNSigmaKa(), 2.0)); - + auto [combNSigmaPr, combNSigmaPi, combNSigmaKa] = getAllCombinedNSigmas(candidate); int flag2 = 0; if (combNSigmaPr < cfgnSigmaOtherParticles) flag2 += 1; @@ -313,10 +364,7 @@ struct RadialFlowDecorr { } } if (candidate.hasTOF() && candidate.pt() > cfgCutPtUpperTPC && candidate.pt() < cfgCutPtUpperPID) { - float combNSigmaPr = std::sqrt(std::pow(candidate.tpcNSigmaPr(), 2.0) + std::pow(candidate.tofNSigmaPr(), 2.0)); - float combNSigmaPi = std::sqrt(std::pow(candidate.tpcNSigmaPi(), 2.0) + std::pow(candidate.tofNSigmaPi(), 2.0)); - float combNSigmaKa = std::sqrt(std::pow(candidate.tpcNSigmaKa(), 2.0) + std::pow(candidate.tofNSigmaKa(), 2.0)); - + auto [combNSigmaPr, combNSigmaPi, combNSigmaKa] = getAllCombinedNSigmas(candidate); int flag2 = 0; if (combNSigmaPr < cfgnSigmaOtherParticles) flag2 += 1; @@ -352,10 +400,7 @@ struct RadialFlowDecorr { } } if (candidate.hasTOF() && candidate.pt() > cfgCutPtUpperTPC && candidate.pt() < cfgCutPtUpperPID) { - float combNSigmaPr = std::sqrt(std::pow(candidate.tpcNSigmaPr(), 2.0) + std::pow(candidate.tofNSigmaPr(), 2.0)); - float combNSigmaPi = std::sqrt(std::pow(candidate.tpcNSigmaPi(), 2.0) + std::pow(candidate.tofNSigmaPi(), 2.0)); - float combNSigmaKa = std::sqrt(std::pow(candidate.tpcNSigmaKa(), 2.0) + std::pow(candidate.tofNSigmaKa(), 2.0)); - + auto [combNSigmaPr, combNSigmaPi, combNSigmaKa] = getAllCombinedNSigmas(candidate); int flag2 = 0; if (combNSigmaPr < cfgnSigmaOtherParticles) flag2 += 1; @@ -388,8 +433,14 @@ struct RadialFlowDecorr { return KinvalidCentrality; } - float getEfficiency(float mult, float pt, float eta, PID pidType, int effidx) const + float getEfficiency(float mult, float pt, float eta, PID pidType, int effidx, bool cfgEff) const { + if (!cfgEff) { + if (effidx == 0) + return 1.0; + if (effidx == 1) + return 0.0; + } TH3F* h = nullptr; if (effidx == 0) h = hEff[pidType]; @@ -405,15 +456,22 @@ struct RadialFlowDecorr { return val; } - float getFlatteningWeight(float cent, float eta, float phi, PID pidType) const + float getFlatteningWeight(float vz, float chg, float pt, float eta, float phi, PID pidType, bool cfgflat) const { - TH3F* h = hWeightMap3D[pidType]; + if (!cfgflat) + return 1.0; + THnSparseF* h = hFlatWeight[pidType]; + if (!h) - return -1; - const int ibx = h->GetXaxis()->FindBin(cent); - const int iby = h->GetYaxis()->FindBin(eta); - const int ibz = h->GetZaxis()->FindBin(phi); - float val = h->GetBinContent(ibx, iby, ibz); + return 0.0; + int bins[5]; + bins[0] = h->GetAxis(0)->FindBin(vz); + bins[1] = h->GetAxis(1)->FindBin(chg); + bins[2] = h->GetAxis(2)->FindBin(pt); + bins[3] = h->GetAxis(3)->FindBin(eta); + bins[4] = h->GetAxis(4)->FindBin(phi); + float val = h->GetBinContent(bins); + return val; } @@ -456,21 +514,6 @@ struct RadialFlowDecorr { return {calculatedMeanPt, twopcorr}; } - ConfigurableAxis cfgAxisCent{"cfgAxisCent", {0.0, 1.0, 3.0, 5.0, 10, 20, 30, 40, 50, 60, 70, 80, 100}, "centrality axis (percentile)"}; // FT0*/FV0A style - const AxisSpec centAxis{cfgAxisCent, "Centrality (%)"}; - static constexpr int KNbinsNch = 5000; - static constexpr float KNchMax = 5000.5f; - static constexpr int KNbinsNchCoarse = 500; - ConfigurableAxis nChAxis{"nChAxis", {KNbinsNch, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - ConfigurableAxis nChAxis2{"nChAxis2", {KNbinsNchCoarse, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - - Configurable cfgRunGetEff{"cfgRunGetEff", false, "Run MC pass to build efficiency/fake maps"}; - Configurable cfgRunMCMean{"cfgRunMCMean", false, "Run MC mean(pT) & mean(Et)"}; - Configurable cfgRunMCFluc{"cfgRunMCFluc", false, "Run MC fluctuations (C2, subevent)"}; - Configurable cfgRunGetFlat{"cfgRunGetFlat", false, "Run Data Get Flattening Weights"}; - Configurable cfgRunDataMean{"cfgRunDataMean", false, "Run DATA mean(pT) & mean(Et)"}; - Configurable cfgRunDataFluc{"cfgRunDataFluc", false, "Run DATA fluctuations (C2, subevent)"}; - using GeneralCollisions = soa::Join< aod::Collisions, aod::EvSels, @@ -494,6 +537,7 @@ struct RadialFlowDecorr { using AodTracksSel = soa::Filtered; using TCs = soa::Join; using FilteredTCs = soa::Filtered; + using BCsRun3 = soa::Join; using MyRun3MCCollisions = soa::Join< aod::Collisions, aod::EvSels, aod::Mults, aod::MultsExtra, @@ -516,75 +560,66 @@ struct RadialFlowDecorr { { histos.add("hZvtx_after_sel", ";z_{vtx} (cm)", kTH1F, {{KNbinsZvtx, KZvtxMin, KZvtxMax}}); histos.add("hVtxZ", ";z_{vtx} (cm)", kTH1F, {{KNbinsZvtx, KZvtxMin, KZvtxMax}}); - histos.add("hCentrality", ";centrality (%)", kTH1F, {{centAxis}}); + histos.add("hCentrality", ";centrality (%)", kTH1F, {{centAxis1Per}}); histos.add("Hist2D_globalTracks_PVTracks", ";N_{global};N_{PV}", kTH2F, {{nChAxis2}, {nChAxis2}}); - histos.add("Hist2D_cent_nch", ";N_{PV};cent (%)", kTH2F, {{nChAxis2}, {centAxis}}); + histos.add("Hist2D_cent_nch", ";N_{PV};cent (%)", kTH2F, {{nChAxis2}, {centAxis1Per}}); histos.add("hP", ";p (GeV/c)", kTH1F, {{KNbinsP, KPMin, KPMax}}); histos.add("hPt", ";p_{T} (GeV/c)", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); histos.add("hEta", ";#eta", kTH1F, {{KNbinsEta, KEtaMin, KEtaMax}}); histos.add("hPhi", ";#phi", kTH1F, {{KNbinsPhi, KPhiMin, TwoPI}}); - - histos.add("hCentEtaPhi", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent1EtaPhi", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent7EtaPhi", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiWtd", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent1EtaPhiWtd", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent7EtaPhiWtd", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - - histos.add("hCentEtaPhiWtd_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent1EtaPhiWtd_PID", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCent7EtaPhiWtd_PID", ";#eta;#phi", kTH2F, {{(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - - histos.add("hCentEtaPhiTrue", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiReco", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiRecoMatched", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - - histos.add("hCentEtaPhiTrue_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiReco_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); - histos.add("hCentEtaPhiRecoMatched_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); } void declareMCCommonHists() { + for (const auto& suf : pidSuffix) { + histos.add("h3_AllPrimary" + suf, ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); + histos.add("h3_RecoMatchedToPrimary" + suf, ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); + histos.add("h3_AllReco" + suf, ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); + histos.add("h3_RecoUnMatchedToPrimary_Secondary" + suf, ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); + histos.add("h3_RecoUnMatchedToPrimary_Fake" + suf, ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); + histos.add("hTruth_ParticleWeight" + suf, ";cent;p_{T};#eta", kTH3F, {{centAxis1Per}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); + } histos.add("ptResolution", ";p_{T}^{MC};p_{T}^{MC}-p_{T}^{reco}", kTH2F, {{KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsPtRes, -KPtResMax, KPtResMax}}); histos.add("ptTruthReco", ";p_{T}^{MC};p_{T}^{reco}", kTH2F, {{KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsPtRes, cfgPtMin, cfgPtMax}}); histos.add("etaResolution", ";#eta^{MC};#eta^{MC}-#eta^{reco}", kTH2F, {{KNbinsEtaRes, -KEtaFineMax, KEtaFineMax}, {KNbinsPtRes, -KEtaResMax, KEtaResMax}}); histos.add("etaTruthReco", ";#eta^{MC};#eta^{reco}", kTH2F, {{KNbinsPtRes, -KEtaFineMax, KEtaFineMax}, {KNbinsPtRes, -KEtaFineMax, KEtaFineMax}}); - histos.add("TruthTracKVz", ";Vz^{MC};Vz^{Reco}", kTH2F, {{KNbinsVz, KVzMin, KVzMax}, {KNbinsVz, KVzMin, KVzMax}}); histos.add("vzResolution", ";Vz^{MC};Vz^{MC}-Vz^{Reco}", kTH2F, {{KNbinsVz, KVzMin, KVzMax}, {KNbinsVz, -KVzResMax, KVzResMax}}); - histos.add("h3_AllPrimary", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_RecoMatchedToPrimary", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_RecoUnMatchedToPrimary_Secondary", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_RecoUnMatchedToPrimary_Fake", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_AllReco", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - - histos.add("h3_AllPrimary_PID", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_RecoMatchedToPrimary_PID", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_RecoUnMatchedToPrimary_Secondary_PID", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_RecoUnMatchedToPrimary_Fake_PID", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - histos.add("h3_AllReco_PID", ";N_{PV};p_{T};#eta", kTH3F, {{nChAxis2}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - - histos.add("h_AllPrimary", ";p_{T}", kTH1F, {{KNbinsP, cfgPtMin, cfgPtMax}}); - histos.add("h_RecoMatchedToPrimary", ";p_{T}", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); - histos.add("h_RecoUnMatchedToPrimary", ";p_{T}", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); - histos.add("h_AllReco", ";p_{T}", kTH1F, {{KNbinsPt, KPtMin, KPtMax}}); - - histos.add("hReco_ParticleWeight", ";cent;p_{T};#eta", kTH3F, {{centAxis}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsPtRes, -KEtaFineMax, KEtaFineMax}}); - histos.add("hTruth_ParticleWeight", ";cent;p_{T};#eta", kTH3F, {{centAxis}, {KNbinsPtRes, cfgPtMin, cfgPtMax}, {KNbinsPtRes, -KEtaFineMax, KEtaFineMax}}); + histos.add("h_AllPrimary", ";p_{T}", kTH1F, {{KNbinsPtRes, cfgPtMin, cfgPtMax}}); + histos.add("h_RecoMatchedToPrimary", ";p_{T}", kTH1F, {{KNbinsPtRes, cfgPtMin, cfgPtMax}}); + histos.add("h_RecoUnMatchedToPrimary", ";p_{T}", kTH1F, {{KNbinsPtRes, cfgPtMin, cfgPtMax}}); + histos.add("h_AllReco", ";p_{T}", kTH1F, {{KNbinsPtRes, cfgPtMin, cfgPtMax}}); + histos.add("h_AllRecoEffCorr", ";p_{T}", kTH1F, {{KNbinsPtRes, cfgPtMin, cfgPtMax}}); histos.add("hDCAxy_Unmatched", ";DCA_{xy} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); histos.add("hDCAz_Unmatched", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); histos.add("hDCAxy_NotPrimary", ";DCA_{xy} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); histos.add("hDCAz_NotPrimary", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAxy_RecoMatched", ";DCA_{xy} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAz_RecoMatched", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAxy_Reco", ";DCA_{xy} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + histos.add("hDCAz_Reco", ";DCA_{z} (cm)", kTH1F, {{KNbinsDca, -KDcaMax, KDcaMax}}); + } + + void declareMCGetFlatHists() + { + for (const auto& suf : pidSuffix) { + std::string nameEff = "hEtaPhiReco" + suf; + std::string nameWtd = "hEtaPhiRecoWtd" + suf; + std::string nameEffWtd = "hEtaPhiRecoEffWtd" + suf; + + histos.add(nameEffWtd, nameEffWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameEff, nameEff.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameWtd, nameWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + } } void declareMCMeanHists() { - histos.add("Eff_cent", ";cent;#epsilon", kTProfile, {centAxis}); - histos.add("Fake_cent", ";cent;f_{fake}", kTProfile, {centAxis}); - histos.add("wgt_cent", ";cent;w", kTProfile, {centAxis}); + histos.add("Eff_cent", ";cent;#epsilon", kTProfile, {centAxis1Per}); + histos.add("Fake_cent", ";cent;f_{fake}", kTProfile, {centAxis1Per}); + histos.add("wgt_cent", ";cent;w", kTProfile, {centAxis1Per}); histos.add("Eff_Ntrk", ";N_{PV};#epsilon", kTProfile, {nChAxis2}); histos.add("Fake_Ntrk", ";N_{PV};f_{fake}", kTProfile, {nChAxis2}); histos.add("wgt_Ntrk", ";N_{PV};w", kTProfile, {nChAxis2}); @@ -594,162 +629,210 @@ struct RadialFlowDecorr { histos.add("Eff_eta", ";#eta;#epsilon", kTProfile, {{KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); histos.add("Fake_eta", ";#eta;f_{fake}", kTProfile, {{KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); histos.add("wgt_eta", ";#eta;w", kTProfile, {{KNbinsEtaFine, -KEtaFineMax, KEtaFineMax}}); - // MC mean profiles (pT & Et) for various selections - histos.add("MCGen/Prof_cent_Nchrec", ";cent;#LT N_{PV}#GT", kTProfile, {centAxis}); - histos.add("MCGen/Prof_MeanpT_Cent", ";cent;#LT p_{T}#GT", kTProfile, {centAxis}); - histos.add("MCGen/Prof_MeanpT_Mult", ";N_{PV};#LT p_{T}#GT", kTProfile, {nChAxis}); - histos.add("pmeanTruNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoMatchedNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoMatchedEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - - histos.add("MCGen/Prof_MeanEt_Cent", ";cent;#LT E_{T}#GT", kTProfile, {centAxis}); - histos.add("MCGen/Prof_MeanEt_Mult", ";N_{PV};#LT E_{T}#GT", kTProfile, {nChAxis}); - histos.add("pmeanEtTruNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoMatchedNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoMatchedEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - - histos.addClone("MCGen/", "MCReco/"); - histos.addClone("MCGen/", "MCRecoMatched/"); - histos.addClone("MCGen/", "MCRecoEffCorr/"); - histos.addClone("MCGen/", "MCRecoMatchedEffCorr/"); + + for (const auto& suf : pidSuffix) { + // Basic Profiles + histos.add("MCGen/Prof_Cent_Nchrec" + suf, ";cent;#LT N_{PV}#GT", kTProfile, {centAxis1Per}); + histos.add("MCGen/Prof_Mult_Nchrec" + suf, ";N_{PV};#LT N_{PV}#GT", kTProfile, {nChAxis}); + + histos.add("MCGen/Prof_Cent_MeanpT" + suf, ";cent;#LT p_{T}#GT", kTProfile, {centAxis1Per}); + histos.add("MCGen/Prof_Mult_MeanpT" + suf, ";N_{PV};#LT p_{T}#GT", kTProfile, {nChAxis}); + + histos.add("pmeanTruNchEtabinPtbin" + suf, ";N_{PV};#eta bin;p_{T} bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("pmeanRecoNchEtabinPtbin" + suf, ";N_{PV};#eta bin;p_{T} bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("pmeanRecoEffcorrNchEtabinPtbin" + suf, ";N_{PV};#eta bin;p_{T} bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + histos.add("pmeanMultTruNchEtabinPtbin" + suf, ";N_{PV};#eta bin;p_{T} bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("pmeanMultRecoNchEtabinPtbin" + suf, ";N_{PV};#eta bin;p_{T} bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("pmeanMultRecoEffcorrNchEtabinPtbin" + suf, ";N_{PV};#eta bin;p_{T} bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + for (const int& i : {0, 1, 2}) { + std::string ptTag = "_ipt" + std::to_string(i); + histos.add("Prof2D_MeanpT_Sub" + ptTag + "_Tru" + suf, ";cent;etaA;etaB", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}}); + histos.add("Prof2D_MeanpT_Sub" + ptTag + "_Reco" + suf, ";cent;etaA;etaB", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}}); + histos.add("Prof2D_MeanpT_Sub" + ptTag + "_RecoEffCorr" + suf, ";cent;etaA;etaB", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}}); + } + } + + for (const auto& suf : pidSuffix) { + std::string nameEff = "hEtaPhiReco" + suf; + std::string nameWtd = "hEtaPhiRecoWtd" + suf; + std::string nameEffWtd = "hEtaPhiRecoEffWtd" + suf; + + histos.add(nameEffWtd, nameEffWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameEff, nameEff.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameWtd, nameWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + } } + void declareMCFlucHists() { - static constexpr int KNbinsNchFluc = 1000; - - ConfigurableAxis nChAxis{"nChAxis", {KNbinsNch, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - ConfigurableAxis nChAxis2{"nChAxis2", {KNbinsNchCoarse, KBinOffset, KNchMax}, "PV-contributor track multiplicity axis"}; - - // pT cumulants - histos.add("MCGen/Prof_C2_Cent", ";cent;C_{2}", kTProfile, {centAxis}); - histos.add("MCGen/Prof_C2_Mult", ";N_{PV};C_{2}", kTProfile, {nChAxis}); - histos.add("MCGen/Prof_C2Sub_Mult_etabin_ptbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{KNbinsNchFluc, KBinOffset, KNchMax}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("MCGen/Prof_ipt0_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt1_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt2_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt0_Cov_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt0_Cov_Eta", ";#eta;cov", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt1_Cov_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt1_Cov_Eta", ";#eta;cov", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt2_Cov_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt2_Cov_Eta", ";#eta;cov", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("MCGen/Prof_C2Et_Cent", ";cent;C_{2}^{E_{T}}", kTProfile, {centAxis}); - histos.add("MCGen/Prof_C2Et_Mult", ";N_{PV};C_{2}^{E_{T}}", kTProfile, {nChAxis}); - histos.add("MCGen/Prof_C2EtSub_Mult_etabin_ptbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{KNbinsNchFluc, KBinOffset, KNchMax}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("MCGen/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt0_CovEt_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt0_CovEt_Eta", ";#eta;cov^{E_{T}}", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt1_CovEt_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt1_CovEt_Eta", ";#eta;cov^{E_{T}}", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt2_CovEt_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("MCGen/Prof_ipt2_CovEt_Eta", ";#eta;cov^{E_{T}}", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - - histos.add("MCGen/Prof_cent_Nchrec", ";cent;#LT N_{PV}#GT", kTProfile, {centAxis}); - histos.add("MCGen/Prof_MeanpT_Cent", ";cent;#LT p_{T}#GT", kTProfile, {centAxis}); - histos.add("MCGen/Prof_MeanpT_Mult", ";N_{PV};#LT p_{T}#GT", kTProfile, {nChAxis}); - - histos.add("pmeanTruNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoMatchedNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanRecoMatchedEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - - histos.add("MCGen/Prof_MeanEt_Cent", ";cent;#LT E_{T}#GT", kTProfile, {centAxis}); - histos.add("MCGen/Prof_MeanEt_Mult", ";N_{PV};#LT E_{T}#GT", kTProfile, {nChAxis}); - histos.add("pmeanEtTruNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoMatchedNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("pmeanEtRecoMatchedEffcorrNchEtabinPtbin", ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + for (const auto& suf : pidSuffix) { + // --- 1D Full Event Calc Profiles --- + histos.add("MCGen/Prof_MeanpT_Cent_etabin_ptbin" + suf, ";cent;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("MCGen/Prof_MeanpT_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + histos.add("MCGen/Prof_C2_Cent_etabin_ptbin" + suf, ";cent;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("MCGen/Prof_C2_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + // --- 1D Sub-Event Covariances --- + histos.add("MCGen/Prof_C2Sub_Cent_etabin_ptbin" + suf, ";Centrality;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("MCGen/Prof_C2Sub_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + histos.add("MCGen/Prof_Cov_Cent_etabin_ptbin" + suf, ";Centrality;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("MCGen/Prof_Cov_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + for (const int& i : {0, 1, 2}) { + std::string ptTag = "_ipt" + std::to_string(i); + histos.add("MCGen/Prof" + ptTag + "_C2Sub2D_Cent_etaA_etaC" + suf, ";cent;#eta_{A};#eta_{B}", kTProfile3D, {{centAxis1Per}, {etaAxis}, {etaAxis}}); + histos.add("MCGen/Prof" + ptTag + "_Cov2D_Cent_etaA_etaC" + suf, ";cent;#eta_{A};#eta_{B}", kTProfile3D, {{centAxis1Per}, {etaAxis}, {etaAxis}}); + histos.add("MCGen/Prof" + ptTag + "_GapSum2D" + suf, ";cent;#Delta#eta (Gap);#Sigma#eta/2 (Sum)", kTProfile3D, {{centAxis1Per}, {gapAxis}, {sumAxis}}); + } + + std::string nameEff = "hEtaPhiReco" + suf; + std::string nameWtd = "hEtaPhiRecoWtd" + suf; + std::string nameEffWtd = "hEtaPhiRecoEffWtd" + suf; + histos.add(nameEffWtd, nameEffWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameEff, nameEff.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameWtd, nameWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + + histos.add("MCGen/Prof_Cent_Nchrec" + suf, ";cent;#LT N_{PV}#GT", kTProfile, {centAxis1Per}); + histos.add("MCGen/Prof_Mult_Nchrec" + suf, ";N_{PV};#LT N_{PV}#GT", kTProfile, {nChAxis}); + histos.add("MCGen/Prof_Cent_MeanpT" + suf, ";cent;#LT p_{T}#GT", kTProfile, {centAxis1Per}); + histos.add("MCGen/Prof_Mult_MeanpT" + suf, ";N_{PV};#LT p_{T}#GT", kTProfile, {nChAxis}); + } } - void declareDataMeanHists() + + void declareDataGetFlatHists() { - histos.add("Prof_cent_Nchrec", ";cent;#LT N_{PV}#GT", kTProfile, {centAxis}); - histos.add("Prof_MeanpT_Cent", ";cent;#LT p_{T}#GT", kTProfile, {centAxis}); - histos.add("pmean_nch_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - // Et - histos.add("Prof_MeanEt_Cent", ";cent;#LT E_{T}#GT", kTProfile, {centAxis}); - histos.add("pmeanEt_nch_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + // 1. Species-dependent Sparse Histograms + for (const auto& suf : pidSuffix) { + std::string nameEff = "hEtaPhiReco" + suf; + std::string nameWtd = "hEtaPhiRecoWtd" + suf; + std::string nameEffWtd = "hEtaPhiRecoEffWtd" + suf; + + histos.add(nameEffWtd, nameEffWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameEff, nameEff.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameWtd, nameWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + } + + histos.add("hnTrkPVZDC", ";N_{PV};ZDC_{A+C}", kTH2F, {{nChAxis2}, {200, 0, 3000}}); + histos.add("hNchZDC", ";N_{trk};ZDC_{A+C}", kTH2F, {{nChAxis2}, {200, 0, 30000}}); + + histos.add("hCentnTrk", ";Centrality (%);N_{trk}", kTH2F, {{centAxis1Per}, {nChAxis2}}); + histos.add("hCentnTrkPV", ";Centrality (%);N_{trk, PV}", kTH2F, {{centAxis1Per}, {nChAxis2}}); } - void declareDataGetFlatHists() + void declareDataMeanHists() { - histos.add("hCentEtaPhi_PID", ";cent;#eta;#phi", kTH3F, {{centAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, 0, TwoPI}}); + for (const auto& suf : pidSuffix) { + std::string nameReco = "hEtaPhiReco" + suf; + std::string nameWtd = "hEtaPhiRecoWtd" + suf; + std::string nameEffWtd = "hEtaPhiRecoEffWtd" + suf; + + histos.add(nameReco, nameReco.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameWtd, nameWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameEffWtd, nameEffWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + + histos.add("Prof_Cent_Nchrec" + suf, ";cent;#LT N_{PV}#GT", kTProfile, {centAxis1Per}); + histos.add("Prof_Mult_Nchrec" + suf, ";N_{PV};#LT N_{PV}#GT", kTProfile, {nChAxis}); + histos.add("Prof_Cent_MeanpT" + suf, ";cent;#LT p_{T}#GT", kTProfile, {centAxis1Per}); + + histos.add("pmean_nch_etabin_ptbin" + suf, ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("pmeanMult_nch_etabin_ptbin" + suf, ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + histos.add("pmean_cent_etabin_ptbin" + suf, ";Centrality (%) ;#eta-bin;p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("pmeanMult_cent_etabin_ptbin" + suf, ";Centrality (%) ;#eta-bin;p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + for (const int& i : {0, 1, 2}) { + std::string ptTag = "_ipt" + std::to_string(i); + std::string histName = "Prof2D_MeanpT_Sub" + ptTag + suf; + histos.add(histName, ";cent;#eta_{A} bin;#eta_{B} bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}}); + } + } } void declareDataFlucHists() { - histos.add("pmean_nch_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - histos.add("Prof_MeanEt_Cent", ";cent;#LT E_{T}#GT", kTProfile, {centAxis}); - histos.add("pmeanEt_nch_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - - histos.add("Prof_C2_Cent", ";cent;C_{2}", kTProfile, {centAxis}); - histos.add("Prof_MeanpT_Cent", ";cent;#LT p_{T}#GT", kTProfile, {centAxis}); - histos.add("Prof_MeanpT_Mult", ";N_{PV};#LT p_{T}#GT", kTProfile, {nChAxis}); - histos.add("Prof_C2_Mult_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - - histos.add("Prof_ipt0_Cov_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("Prof_ipt0_Cov_Eta", ";#eta;cov", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("Prof_ipt1_Cov_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("Prof_ipt1_Cov_Eta", ";#eta;cov", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("Prof_ipt2_Cov_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("Prof_ipt2_Cov_Eta", ";#eta;cov", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - - histos.add("Prof_C2Et_Cent", ";cent;C_{2}^{E_{T}}", kTProfile, {centAxis}); - histos.add("Prof_MeanEt_Mult", ";N_{PV};#LT E_{T}#GT", kTProfile, {nChAxis}); - histos.add("Prof_C2Et_Mult_etabin_ptbin", ";N_{PV};#eta-bin;p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); - - histos.add("Prof_ipt0_CovEt_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("Prof_ipt0_CovEt_Eta", ";#eta;cov^{E_{T}}", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("Prof_ipt1_CovEt_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("Prof_ipt1_CovEt_Eta", ";#eta;cov^{E_{T}}", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - histos.add("Prof_ipt2_CovEt_Cent_eta", ";cent;#eta", kTProfile2D, {{centAxis}, {(KNEta - 1) / 2, 0, KEtaAxisMax}}); - histos.add("Prof_ipt2_CovEt_Eta", ";#eta;cov^{E_{T}}", kTProfile, {{(KNEta - 1) / 2, 0., KEtaAxisMax}}); - - histos.add("Prof_ipt0_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("Prof_ipt1_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("Prof_ipt2_C2Sub2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("Prof_ipt0_C2SubEt2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("Prof_ipt1_C2SubEt2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); - histos.add("Prof_ipt2_C2SubEt2D_Mult_etaA_etaC", ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}, {KNEta - 1, KEtaAxisMin, KEtaAxisMax}}); + for (const auto& suf : pidSuffix) { + + // --- THnSparse QA Histograms --- + std::string nameReco = "hEtaPhiReco" + suf; + std::string nameEff = "hEtaPhiRecoEffWtd" + suf; + std::string nameWtd = "hEtaPhiRecoWtd" + suf; + + histos.add(nameReco, nameReco.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameEff, nameEff.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + histos.add(nameWtd, nameWtd.c_str(), kTHnSparseF, {{vzAxis}, {chgAxis}, {pTAxis}, {(KNEta - 1), KEtaAxisMin, KEtaAxisMax}, {KNbinsPhiFine, KPhiMin, TwoPI}}); + + // --- 1D Full Event Calc Profiles --- + histos.add("Prof_MeanpT_Cent_etabin_ptbin" + suf, ";cent;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("Prof_MeanpT_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + histos.add("Prof_C2_Cent_etabin_ptbin" + suf, ";cent;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("Prof_C2_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + // --- 1D Sub-Event Covariances --- + histos.add("Prof_C2Sub_Cent_etabin_ptbin" + suf, ";Centrality;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("Prof_C2Sub_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + histos.add("Prof_Cov_Cent_etabin_ptbin" + suf, ";Centrality;#eta-bin; p_{T}-bin", kTProfile3D, {{centAxis1Per}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + histos.add("Prof_Cov_Mult_etabin_ptbin" + suf, ";N_{PV};#eta-bin; p_{T}-bin", kTProfile3D, {{nChAxis}, {KNEta + 1, -KBinOffset, KNEta + KBinOffset}, {KNpT + 1, -KBinOffset, KNpT + KBinOffset}}); + + for (const int& i : {0, 1, 2}) { + std::string ptTag = "_ipt" + std::to_string(i); + histos.add("Prof" + ptTag + "_C2Sub2D_Cent_etaA_etaC" + suf, ";cent;#eta_{A};#eta_{C}", kTProfile3D, {{centAxis1Per}, {etaAxis}, {etaAxis}}); + histos.add("Prof" + ptTag + "_GapSum2D" + suf, ";cent;#Delta#eta (Gap);#Sigma#eta/2 (Sum)", kTProfile3D, {{centAxis1Per}, {gapAxis}, {sumAxis}}); + histos.add("Prof" + ptTag + "_Cov2D_Cent_etaA_etaC" + suf, ";cent;#eta_{A} bin;#eta_{C} bin", kTProfile3D, {{centAxis1Per}, {etaAxis}, {etaAxis}}); + } + } } - TH3F* buildWeightMapFromRaw(TH3F* hRaw, const char* mapName) + THnSparseF* buildWeightMapFromRaw(THnSparseF* hRaw, const char* mapName) { if (!hRaw) { LOGF(error, "Raw eta-phi map for '%s' is null; no flattening will be applied.", mapName); return nullptr; } - auto hWeightMap = reinterpret_cast(hRaw->Clone(mapName)); - hWeightMap->SetTitle(Form("Flattening Weight Map %s (w_{#phi} = / N_{#phi})", mapName)); - hWeightMap->SetDirectory(nullptr); - hWeightMap->Reset(); - auto axC = hRaw->GetXaxis(); - auto axE = hRaw->GetYaxis(); - auto axP = hRaw->GetZaxis(); - for (int ic = 1; ic <= axC->GetNbins(); ++ic) { - for (int ie = 1; ie <= axE->GetNbins(); ++ie) { - // average over phi at fixed (cent,eta) - double sum = 0.0; - int nphi = axP->GetNbins(); - for (int ip = 1; ip <= nphi; ++ip) - sum += hRaw->GetBinContent(ic, ie, ip); - const double avg = (nphi > 0 ? sum / nphi : 0.0); - for (int ip = 1; ip <= nphi; ++ip) { - const double raw = hRaw->GetBinContent(ic, ie, ip); - const double w = (avg > 0.0 && raw > 0.0) ? (avg / raw) : 1.0; - hWeightMap->SetBinContent(ic, ie, ip, w); + auto hWMap = reinterpret_cast(hRaw->Clone(mapName)); + hWMap->SetTitle(Form("Flattening Weight Map %s (w_{#phi} = / N_{#phi})", mapName)); + hWMap->Reset(); + auto axV = hRaw->GetAxis(0); // Vz + auto axChg = hRaw->GetAxis(1); // Charge + auto axPt = hRaw->GetAxis(2); // Charge + auto axE = hRaw->GetAxis(3); // Eta + auto axP = hRaw->GetAxis(4); // Phi + + int bins[5]; + for (int iv = 1; iv <= axV->GetNbins(); ++iv) { + bins[0] = iv; + for (int ichg = 1; ichg <= axChg->GetNbins(); ++ichg) { + bins[1] = ichg; + for (int ipt = 1; ipt <= axPt->GetNbins(); ++ipt) { + bins[2] = ipt; + for (int ie = 1; ie <= axE->GetNbins(); ++ie) { + bins[3] = ie; + double sum = 0.0; + int nphi = axP->GetNbins(); + for (int ip = 1; ip <= nphi; ++ip) { + bins[4] = ip; + sum += hRaw->GetBinContent(bins); + } + const double avg = (nphi > 0 ? sum / nphi : 0.0); + for (int ip = 1; ip <= nphi; ++ip) { + bins[4] = ip; + const double raw = hRaw->GetBinContent(bins); + const double w = (avg > 0.0 && raw > 0.0) ? (avg / raw) : 1.0; + hWMap->SetBinContent(bins, w); + } + } } } } + LOGF(info, "Flattening weight map '%s' built.", mapName); - return hWeightMap; + return hWMap; } inline void loadTProfile3D(TDirectory* dir, const char* name, TProfile3D*& target) @@ -758,19 +841,16 @@ struct RadialFlowDecorr { LOGF(error, "loadTProfile3D: directory is null for object %s", name); return; } - auto* obj = dir->Get(name); if (!obj) { LOGF(error, "loadTProfile3D: object '%s' not found in directory %s", name, dir->GetName()); return; } - auto* prof = dynamic_cast(obj); if (!prof) { LOGF(error, "loadTProfile3D: object '%s' is not a TProfile3D (it is %s)", name, obj->ClassName()); return; } - target = reinterpret_cast(prof->Clone(Form("%s_clone", name))); target->SetDirectory(nullptr); LOGF(info, "Loaded TProfile3D '%s' with entries = %.0f", name, target->GetEntries()); @@ -778,35 +858,81 @@ struct RadialFlowDecorr { void init(InitContext&) { - ccdb->setURL("https://alice-ccdb.cern.ch"); + if (cfgSys == kPbPb) { + nChAxis = {cfgNchPbMax / 4, KBinOffset, cfgNchPbMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + nChAxis2 = {cfgNchPbMax / 20, KBinOffset, cfgNchPbMax + KBinOffset, , "Nch", "PV-contributor track multiplicity"}; + } else if (cfgSys == kOO || cfgSys == kpPb) { + nChAxis = {cfgNchOMax / 2, KBinOffset, cfgNchOMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + nChAxis2 = {cfgNchOMax / 5, KBinOffset, cfgNchOMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + } else { + nChAxis = {cfgNchOMax / 2, KBinOffset, cfgNchOMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + nChAxis2 = {cfgNchOMax / 5, KBinOffset, cfgNchOMax + KBinOffset, "Nch", "PV-contributor track multiplicity"}; + } + + ccdb->setURL(cfgCCDBurl.value); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - int64_t now = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); + int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); - declareCommonQA(); + std::string sysDir = ""; + switch (cfgSys) { + case kPbPb: + sysDir = "PbPbTest"; + break; + case kOO: + sysDir = "OOTest"; + break; + case kpPb: + sysDir = "pPbTest"; + break; + case kpp: + sysDir = "ppTest"; + break; + default: + LOGF(fatal, "Invalid cfgSys value: %d", cfgSys.value); + } - const std::string userCcdbPath = "/Users/s/somadutt/PbPbTest/"; + std::string pathEff = cfgCCDBUserPath.value + "/" + sysDir + "/Job1_EffMaps"; + std::string pathMCFlat = cfgCCDBUserPath.value + "/" + sysDir + "/Job1_MCFlatMaps"; + std::string pathMCMean = cfgCCDBUserPath.value + "/" + sysDir + "/Job2_MCMean"; + std::string pathDataFlat = cfgCCDBUserPath.value + "/" + sysDir + "/Job1_DataFlatMaps"; + std::string pathDataMean = cfgCCDBUserPath.value + "/" + sysDir + "/Job2_DataMean"; + + declareCommonQA(); + std::string userCcdbPath; + if (cfgSys == kPbPb) { + userCcdbPath = "/Users/s/somadutt/PbPbTest/"; + } + if (cfgSys == kOO) { + userCcdbPath = "/Users/s/somadutt/OOTest/"; + } + if (cfgSys == kpPb) { + userCcdbPath = "/Users/s/somadutt/pPbTest/"; + } + if (cfgSys == kpp) { + userCcdbPath = "/Users/s/somadutt/ppTest/"; + } if (cfgRunMCMean || cfgRunMCFluc || cfgRunGetEff) { declareMCCommonHists(); } if (cfgRunMCMean) { declareMCMeanHists(); + histos.addClone("MCGen/", "MCReco/"); + histos.addClone("MCGen/", "MCRecoEffCorr/"); } if (cfgRunMCFluc) { declareMCFlucHists(); - histos.addClone("MCGen/", "MCReco/"); - histos.addClone("MCGen/", "MCRecoMatched/"); histos.addClone("MCGen/", "MCRecoEffCorr/"); - histos.addClone("MCGen/", "MCRecoMatchedEffCorr/"); } - if (cfgRunGetFlat) { + if (cfgRunGetDataFlat) { declareDataGetFlatHists(); } + if (cfgRunGetMCFlat) { + declareMCGetFlatHists(); + } if (cfgRunDataMean) { declareDataMeanHists(); } @@ -814,10 +940,14 @@ struct RadialFlowDecorr { declareDataFlucHists(); } - const bool needEffMaps = cfgRunMCMean || cfgRunMCFluc || cfgRunDataMean || cfgRunDataFluc; - if (needEffMaps && !cfgRunGetEff) { + if (!cfgRunGetEff && (cfgEff)) { + TList* lst = ccdb->getForTimeStamp(pathEff, now); - LOGF(info, "Loading Eff/Fake maps from CCDB path: %s", userCcdbPath.c_str()); + if (!lst) { + LOGF(fatal, "Efficiency maps required but CCDB list is null at %s!", pathEff.c_str()); + } + + LOGF(info, "Loading Eff/Fake maps from TList for all species..."); auto loadEffFakeForPID = [&](PID pidType) { std::string suffix = pidSuffix[pidType]; @@ -827,112 +957,156 @@ struct RadialFlowDecorr { std::string hFakeNumFakName = "h3_RecoUnMatchedToPrimary_Fake" + suffix; std::string hFakeDenName = "h3_AllReco" + suffix; - // --- Efficiency --- - auto* hNum = ccdb->get(userCcdbPath + hEffNumName); - auto* hDen = ccdb->get(userCcdbPath + hEffDenName); + auto* hNum = reinterpret_cast(lst->FindObject(hEffNumName.c_str())); + auto* hDen = reinterpret_cast(lst->FindObject(hEffDenName.c_str())); + if (hNum && hDen) { hEff[pidType] = reinterpret_cast(hNum->Clone(Form("hEff%s", suffix.c_str()))); hEff[pidType]->SetDirectory(nullptr); hEff[pidType]->Divide(hDen); } else { - LOGF(error, "Missing CCDB objects for efficiency. Checked:\n%s\n%s", - (userCcdbPath + hEffNumName).c_str(), - (userCcdbPath + hEffDenName).c_str()); + LOGF(error, "Missing CCDB objects for efficiency. Checked: %s, %s", hEffNumName.c_str(), hEffDenName.c_str()); } - // --- Fakes --- - auto* hNumS = ccdb->get(userCcdbPath + hFakeNumSecName); - auto* hNumF = ccdb->get(userCcdbPath + hFakeNumFakName); - auto* hDenF = ccdb->get(userCcdbPath + hFakeDenName); + auto* hNumS = reinterpret_cast(lst->FindObject(hFakeNumSecName.c_str())); + auto* hNumF = reinterpret_cast(lst->FindObject(hFakeNumFakName.c_str())); + auto* hDenF = reinterpret_cast(lst->FindObject(hFakeDenName.c_str())); + if (hNumS && hNumF && hDenF) { hFake[pidType] = reinterpret_cast(hNumS->Clone(Form("hFake%s", suffix.c_str()))); hFake[pidType]->Add(hNumF); hFake[pidType]->SetDirectory(nullptr); hFake[pidType]->Divide(hDenF); } else { - LOGF(error, "Missing CCDB object(s) for fakes for %s. Checked path prefix: %s", - suffix.c_str(), userCcdbPath.c_str()); + LOGF(error, "Missing CCDB object(s) for fakes for %s in list.", suffix.c_str()); } }; - loadEffFakeForPID(kInclusive); - loadEffFakeForPID(kCombinedPID); + // Loop through all PID types: kInclusive, kPion, kKaon, KProton + for (int i = 0; i < PID::numKNumPID; ++i) { + loadEffFakeForPID(static_cast(i)); + } + } - const bool isDataRun = cfgRunDataMean || cfgRunDataFluc; - if (isDataRun) { - LOGF(info, "Data Run: Loading flattening maps from CCDB path: %s", userCcdbPath.c_str()); + if (!cfgRunGetEff && (cfgFlat)) { + // --- 1. Load Data Flattening Maps --- + if (cfgRunDataMean || cfgRunDataFluc) { + LOGF(info, "Data Run: Loading flattening maps from %s", pathDataFlat.c_str()); + TList* lstDataFlat = ccdb->getForTimeStamp(pathDataFlat, now); + + if (lstDataFlat) { + // Use a loop to load species-specific flattening weights if they exist in data + for (int i = 0; i < PID::numKNumPID; ++i) { + std::string suffix = pidSuffix[i]; + std::string hName; + + if (cfgEff && cfgFlat) { + hName = "hEtaPhiRecoWtd" + suffix; + } else if (cfgEff) { + hName = "hEtaPhiRecoEffWtd" + suffix; + } else { + hName = "hEtaPhiReco" + suffix; + } + auto* hRaw = reinterpret_cast(lstDataFlat->FindObject(hName.c_str())); - auto* hRawIncl = ccdb->get(userCcdbPath + "hCentEtaPhi"); - if (hRawIncl) { - hWeightMap3D[kInclusive] = buildWeightMapFromRaw(hRawIncl, "hWeightMap3D"); + if (hRaw) { + hFlatWeight[i] = buildWeightMapFromRaw(hRaw, Form("hFlatWeight%s", suffix.c_str())); + } else { + LOGF(error, "Data flattening map '%s' not found.", hName.c_str()); + } + } } else { - LOGF(error, "Data flattening 'hCentEtaPhi' not found at path %s", - (userCcdbPath + "hCentEtaPhi").c_str()); + LOGF(error, "Could not retrieve Data Flattening TList from: %s", pathDataFlat.c_str()); } + } + + // --- 2. Load MC Flattening Maps --- + if (cfgRunMCMean || cfgRunMCFluc) { + LOGF(info, "MC Run: Loading flattening maps from %s", pathMCFlat.c_str()); + TList* lstMCFlat = ccdb->getForTimeStamp(pathMCFlat, now); + + if (lstMCFlat) { + auto loadFlatForPID = [&](PID pidType) { + std::string suffix = pidSuffix[pidType]; + std::string hFlatSrcName; + if (cfgEff && cfgFlat) { + hFlatSrcName = "hEtaPhiRecoWtd" + suffix; + } else if (cfgEff) { + hFlatSrcName = "hEtaPhiRecoEffWtd" + suffix; + } else { + hFlatSrcName = "hEtaPhiReco" + suffix; + } + + auto* hRaw = reinterpret_cast(lstMCFlat->FindObject(hFlatSrcName.c_str())); - auto* hRawPID = ccdb->get(userCcdbPath + "hCentEtaPhi_PID"); - if (hRawPID) { - hWeightMap3D[kCombinedPID] = buildWeightMapFromRaw(hRawPID, "hWeightMap3D_PID"); + if (hRaw) { + hFlatWeight[pidType] = buildWeightMapFromRaw(hRaw, Form("hFlatWeight%s", suffix.c_str())); + } else { + LOGF(warning, "MC flattening source '%s' not found in list.", hFlatSrcName.c_str()); + } + }; + + for (int i = 0; i < PID::numKNumPID; ++i) { + loadFlatForPID(static_cast(i)); + } } else { - LOGF(error, "Data flattening 'hCentEtaPhi_PID' not found at path %s", - (userCcdbPath + "hCentEtaPhi_PID").c_str()); + LOGF(error, "Could not retrieve MC Flattening TList from: %s", pathMCFlat.c_str()); } - } else { - LOGF(info, "MC Run: Loading flattening maps from CCDB path: %s", userCcdbPath.c_str()); - - auto loadFlatForPID = [&](PID pidType) { - std::string suffix = pidSuffix[pidType]; - std::string hFlatSrcName = "hCentEtaPhiReco" + suffix; - auto* hRaw = ccdb->get(userCcdbPath + hFlatSrcName); - if (hRaw) { - hWeightMap3D[pidType] = buildWeightMapFromRaw(hRaw, Form("hWeightMap3D%s", suffix.c_str())); - } else { - LOGF(warning, "MC flattening source '%s' not found at %s; skipping this PID.", - hFlatSrcName.c_str(), (userCcdbPath + hFlatSrcName).c_str()); - } - }; - loadFlatForPID(kInclusive); - loadFlatForPID(kCombinedPID); } } - auto loadTProfile3DFromCCDB = [&](const std::string& ccdbPath, const char* objName, TProfile3D*& target) { - std::string fullPath = ccdbPath + objName; - LOGF(info, "Loading TProfile3D from CCDB: %s", fullPath.c_str()); - if (auto* tp = ccdb->get(fullPath)) { + auto loadTProfile3DFromList = [&](TList* sourceList, const char* objName, TProfile3D*& target) { + if (!sourceList) + return; + + auto* tp = reinterpret_cast(sourceList->FindObject(objName)); + if (tp) { target = reinterpret_cast(tp->Clone()); target->SetDirectory(nullptr); + LOGF(info, "Loaded %s from list", objName); } else { - LOGF(error, "Histogram %s missing in CCDB at path: %s", objName, fullPath.c_str()); + LOGF(error, "Histogram %s missing in CCDB TList", objName); } }; if (cfgRunMCFluc) { - LOGF(info, "Loading MC Mean profiles from CCDB path: %s", userCcdbPath.c_str()); - - loadTProfile3DFromCCDB(userCcdbPath, "pmeanTruNchEtabinPtbin", pmeanTruNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoNchEtabinPtbin", pmeanRecoNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoMatchedNchEtabinPtbin", pmeanRecoMatchedNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoEffcorrNchEtabinPtbin", pmeanRecoEffcorrNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanRecoMatchedEffcorrNchEtabinPtbin", pmeanRecoMatchedEffcorrNchEtabinPtbinStep2); - - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtTruNchEtabinPtbin", pmeanEtTruNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoNchEtabinPtbin", pmeanEtRecoNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoMatchedNchEtabinPtbin", pmeanEtRecoMatchedNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoEffcorrNchEtabinPtbin", pmeanEtRecoEffcorrNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEtRecoMatchedEffcorrNchEtabinPtbin", pmeanEtRecoMatchedEffcorrNchEtabinPtbinStep2); + LOGF(info, "Loading MC Mean profiles from CCDB path: %s", pathMCMean.c_str()); + TList* lstMCMean = ccdb->getForTimeStamp(pathMCMean, now); + + if (lstMCMean) { + for (int isp = 0; isp < KNsp; ++isp) { + std::string suf = pidSuffix[isp]; + loadTProfile3DFromList(lstMCMean, ("pmeanTruNchEtabinPtbin" + suf).c_str(), pmeanTruNchEtabinPtbinStep2[isp]); + loadTProfile3DFromList(lstMCMean, ("pmeanRecoNchEtabinPtbin" + suf).c_str(), pmeanRecoNchEtabinPtbinStep2[isp]); + loadTProfile3DFromList(lstMCMean, ("pmeanRecoEffcorrNchEtabinPtbin" + suf).c_str(), pmeanRecoEffcorrNchEtabinPtbinStep2[isp]); + + loadTProfile3DFromList(lstMCMean, ("pmeanMultTruNchEtabinPtbin" + suf).c_str(), pmeanMultTruNchEtabinPtbinStep2[isp]); + loadTProfile3DFromList(lstMCMean, ("pmeanMultRecoNchEtabinPtbin" + suf).c_str(), pmeanMultRecoNchEtabinPtbinStep2[isp]); + loadTProfile3DFromList(lstMCMean, ("pmeanMultRecoEffcorrNchEtabinPtbin" + suf).c_str(), pmeanMultRecoEffcorrNchEtabinPtbinStep2[isp]); + } + } else { + LOGF(error, "Could not retrieve TList for MC Mean from: %s", pathMCMean.c_str()); + } } if (cfgRunDataFluc) { - LOGF(info, "Loading Data Mean profiles from CCDB path: %s", userCcdbPath.c_str()); - loadTProfile3DFromCCDB(userCcdbPath, "pmean_nch_etabin_ptbin", pmeanNchEtabinPtbinStep2); - loadTProfile3DFromCCDB(userCcdbPath, "pmeanEt_nch_etabin_ptbin", pmeanEtNchEtabinPtbinStep2); + LOGF(info, "Loading Data Mean profiles from CCDB path: %s", pathDataMean.c_str()); + TList* lstDataMean = ccdb->getForTimeStamp(pathDataMean, now); + + if (lstDataMean) { + for (int isp = 0; isp < KNsp; ++isp) { + std::string suf = pidSuffix[isp]; + loadTProfile3DFromList(lstDataMean, ("pmean_nch_etabin_ptbin" + suf).c_str(), pmeanNchEtabinPtbinStep2[isp]); + loadTProfile3DFromList(lstDataMean, ("pmeanMult_nch_etabin_ptbin" + suf).c_str(), pmeanMultNchEtabinPtbinStep2[isp]); + } + } else { + LOGF(error, "Could not retrieve TList for Data Mean from: %s", pathDataMean.c_str()); + } } - LOGF(info, "CCDB initialization complete for RadialFlowDecorr."); } - void processGetEffHists(aod::McCollisions const& mcColl, soa::SmallGroups const& collisions, TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) + void processGetEffHists(aod::McCollisions const& mcColl, MyRun3MCCollisions const& collisions, /*soa::SmallGroups const& collisions,*/ TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) { for (const auto& mcCollision : mcColl) { auto colSlice = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); @@ -942,455 +1116,691 @@ struct RadialFlowDecorr { for (const auto& col : colSlice) { if (!col.has_mcCollision()) continue; + histos.fill(HIST("hVtxZ"), col.posZ()); if (!isEventSelected(col)) continue; auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); - if (trackSlice.size() < 1) - continue; - auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); - if (partSlice.size() < 1) + if (trackSlice.size() < 1 || partSlice.size() < 1) continue; - if (col.globalIndex() >= trackSlice.size()) { - LOGF(warning, "Skipping invalid globalIndex=%d for tracks (tracks.size=%d)", col.globalIndex(), tracks.size()); - continue; - } float cent = getCentrality(col); if (cent > KCentMax) continue; + float multPV = col.multNTracksPV(); + histos.fill(HIST("hZvtx_after_sel"), col.posZ()); + histos.fill(HIST("hCentrality"), cent); + histos.fill(HIST("Hist2D_globalTracks_PVTracks"), multPV, tracks.size()); + histos.fill(HIST("Hist2D_cent_nch"), multPV, cent); + + // --- Denominator: Truth Particles --- for (const auto& particle : partSlice) { - if (!isParticleSelected(particle)) - continue; - if (!particle.isPhysicalPrimary()) + if (!isParticleSelected(particle) || !particle.isPhysicalPrimary()) continue; const int absPdgId = std::abs(particle.pdgCode()); - const bool isPion = (absPdgId == KPiPlus); - const bool isKaon = (absPdgId == KKPlus); - const bool isProton = (absPdgId == KProton); - const bool isPid = (isPion || isKaon || isProton); - - histos.fill(HIST("hTruth_ParticleWeight"), cent, particle.pt(), particle.eta(), particle.weight()); - histos.fill(HIST("hCentEtaPhiTrue"), cent, particle.eta(), particle.phi()); - histos.fill(HIST("h3_AllPrimary"), col.multNTracksPV(), particle.pt(), particle.eta()); - - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhi"), particle.eta(), particle.phi()); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhi"), particle.eta(), particle.phi()); - - if (isPid) { - histos.fill(HIST("hCentEtaPhiTrue_PID"), cent, particle.eta(), particle.phi()); - histos.fill(HIST("h3_AllPrimary_PID"), col.multNTracksPV(), particle.pt(), particle.eta()); + float pt = particle.pt(); + float eta = particle.eta(); + float w = particle.weight(); + + // Inclusive (Denominator) + histos.fill(HIST("hTruth_ParticleWeight"), cent, pt, eta, w); + histos.fill(HIST("h3_AllPrimary"), multPV, pt, eta); + histos.fill(HIST("h_AllPrimary"), pt); + + // Species Specific Denominators + if (absPdgId == KPiPlus) { + histos.fill(HIST("hTruth_ParticleWeight_Pi"), cent, pt, eta, w); + histos.fill(HIST("h3_AllPrimary_Pi"), multPV, pt, eta); + } else if (absPdgId == KKPlus) { + histos.fill(HIST("hTruth_ParticleWeight_Ka"), cent, pt, eta, w); + histos.fill(HIST("h3_AllPrimary_Ka"), multPV, pt, eta); + } else if (absPdgId == KProton) { + histos.fill(HIST("hTruth_ParticleWeight_Pr"), cent, pt, eta, w); + histos.fill(HIST("h3_AllPrimary_Pr"), multPV, pt, eta); } } - histos.fill(HIST("TruthTracKVz"), mcCollision.posZ(), col.posZ()); - histos.fill(HIST("vzResolution"), mcCollision.posZ(), mcCollision.posZ() - col.posZ()); - // Reconstructed + // --- Numerator and Fakes: Reconstructed Tracks --- for (const auto& track : trackSlice) { if (!isTrackSelected(track)) continue; - const bool isPion = selectionPion(track); - const bool isKaon = selectionKaon(track); - const bool isProton = selectionProton(track); - const bool isPid = (isPion || isKaon || isProton); + float pt = track.pt(); + float eta = track.eta(); + float phi = track.phi(); + + bool isPi = selectionPion(track); + bool isKa = selectionKaon(track); + bool isPr = selectionProton(track); - histos.fill(HIST("h3_AllReco"), col.multNTracksPV(), track.pt(), track.eta()); - histos.fill(HIST("hCentEtaPhiReco"), cent, track.eta(), track.phi()); + // Inclusive QA + histos.fill(HIST("h_AllReco"), pt); + histos.fill(HIST("h3_AllReco"), multPV, pt, eta); + histos.fill(HIST("hEtaPhiReco"), col.posZ(), track.sign(), pt, eta, phi); - if (isPid) { - histos.fill(HIST("h3_AllReco_PID"), col.multNTracksPV(), track.pt(), track.eta()); - histos.fill(HIST("hCentEtaPhiReco_PID"), cent, track.eta(), track.phi()); + // Species QA (Fills based on your PID selection) + if (isPi) { + histos.fill(HIST("h3_AllReco_Pi"), multPV, pt, eta); + } + if (isKa) { + histos.fill(HIST("h3_AllReco_Ka"), multPV, pt, eta); + } + if (isPr) { + histos.fill(HIST("h3_AllReco_Pr"), multPV, pt, eta); } if (track.has_mcParticle()) { auto mcPart2 = track.mcParticle(); + const int absPdgId = std::abs(mcPart2.pdgCode()); + if (mcPart2.isPhysicalPrimary()) { - const int absPdgId = std::abs(mcPart2.pdgCode()); - const bool isPionTrue = (absPdgId == kPiPlus); - const bool isKaonTrue = (absPdgId == kKPlus); - const bool isProtonTrue = (absPdgId == kProton); - const bool isPidTrue = (isPionTrue || isKaonTrue || isProtonTrue); - - histos.fill(HIST("hReco_ParticleWeight"), cent, mcPart2.pt(), mcPart2.eta(), mcPart2.weight()); - histos.fill(HIST("ptResolution"), mcPart2.pt(), mcPart2.pt() - track.pt()); - histos.fill(HIST("ptTruthReco"), mcPart2.pt(), track.pt()); - histos.fill(HIST("etaResolution"), mcPart2.eta(), mcPart2.eta() - track.eta()); - histos.fill(HIST("etaTruthReco"), mcPart2.eta(), track.eta()); - histos.fill(HIST("h3_RecoMatchedToPrimary"), col.multNTracksPV(), mcPart2.pt(), mcPart2.eta()); - histos.fill(HIST("hCentEtaPhiRecoMatched"), cent, mcPart2.eta(), mcPart2.phi()); - - if (isPid && isPidTrue) { - histos.fill(HIST("h3_RecoMatchedToPrimary_PID"), col.multNTracksPV(), mcPart2.pt(), mcPart2.eta()); - histos.fill(HIST("hCentEtaPhiRecoMatched_PID"), cent, mcPart2.eta(), mcPart2.phi()); - } + + histos.fill(HIST("ptResolution"), mcPart2.pt(), (pt - mcPart2.pt()) / mcPart2.pt()); + histos.fill(HIST("etaResolution"), mcPart2.eta(), eta - mcPart2.eta()); + histos.fill(HIST("etaTruthReco"), mcPart2.eta(), eta); + histos.fill(HIST("vzResolution"), mcPart2.vz(), (col.posZ() - mcPart2.vz()) / mcPart2.vz()); + histos.fill(HIST("TruthTracKVz"), mcPart2.vz(), col.posZ()); + + // Reconstructed Numerator (Inclusive) + histos.fill(HIST("h3_RecoMatchedToPrimary"), multPV, mcPart2.pt(), mcPart2.eta()); + histos.fill(HIST("h_RecoMatchedToPrimary"), pt); + + // Species Matching (Efficiency Numerator) + // We fill ONLY if the reconstructed PID matches the Truth PDG + if (isPi && absPdgId == KPiPlus) + histos.fill(HIST("h3_RecoMatchedToPrimary_Pi"), multPV, mcPart2.pt(), mcPart2.eta()); + if (isKa && absPdgId == KKPlus) + histos.fill(HIST("h3_RecoMatchedToPrimary_Ka"), multPV, mcPart2.pt(), mcPart2.eta()); + if (isPr && absPdgId == KProton) + histos.fill(HIST("h3_RecoMatchedToPrimary_Pr"), multPV, mcPart2.pt(), mcPart2.eta()); } else { - // Matched to secondary - histos.fill(HIST("h3_RecoUnMatchedToPrimary_Secondary"), col.multNTracksPV(), track.pt(), track.eta()); - histos.fill(HIST("hDCAxy_Unmatched"), track.dcaXY()); - histos.fill(HIST("hDCAz_Unmatched"), track.dcaZ()); - if (isPid) { - histos.fill(HIST("h3_RecoUnMatchedToPrimary_Secondary_PID"), col.multNTracksPV(), track.pt(), track.eta()); - } + // Secondary (Contamination) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Secondary"), multPV, pt, eta); + histos.fill(HIST("h_RecoUnMatchedToPrimary"), pt); + if (isPi) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Secondary_Pi"), multPV, pt, eta); + if (isKa) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Secondary_Ka"), multPV, pt, eta); + if (isPr) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Secondary_Pr"), multPV, pt, eta); } } else { - // Fake track - histos.fill(HIST("h3_RecoUnMatchedToPrimary_Fake"), col.multNTracksPV(), track.pt(), track.eta()); - histos.fill(HIST("hDCAxy_NotPrimary"), track.dcaXY()); - histos.fill(HIST("hDCAz_NotPrimary"), track.dcaZ()); - if (isPid) { - histos.fill(HIST("h3_RecoUnMatchedToPrimary_Fake_PID"), col.multNTracksPV(), track.pt(), track.eta()); - } + // Fake Tracks (No MC matching) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Fake"), multPV, pt, eta); + if (isPi) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Fake_Pi"), multPV, pt, eta); + if (isKa) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Fake_Ka"), multPV, pt, eta); + if (isPr) + histos.fill(HIST("h3_RecoUnMatchedToPrimary_Fake_Pr"), multPV, pt, eta); } - } // tracks - } // cols - } // mcColl + } + } + } LOGF(info, "FINISHED RUNNING processGetEffHists"); } PROCESS_SWITCH(RadialFlowDecorr, processGetEffHists, "process MC to calculate Eff and Fakes", cfgRunGetEff); - void processMCMean(aod::McCollisions const& mcColl, MyRun3MCCollisions const& collisions, TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) + void processMCFlat(aod::McCollisions const& mcColl, MyRun3MCCollisions const& collisions, /*soa::SmallGroups const& collisions,*/ TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) { - float sumWiTruth[KNEta][KNpT], sumWiptiTruth[KNEta][KNpT]; - float sumWiReco[KNEta][KNpT], sumWiptiReco[KNEta][KNpT]; - float sumWiRecoMatched[KNEta][KNpT], sumWiptiRecoMatched[KNEta][KNpT]; - float sumWiRecoEffCorr[KNEta][KNpT], sumWiptiRecoEffCorr[KNEta][KNpT]; - float sumWiRecoMatchedEffCorr[KNEta][KNpT], sumWiptiRecoMatchedEffCorr[KNEta][KNpT]; - float sumWiTruthEt[KNEta][KNpT], sumWiptiTruthEt[KNEta][KNpT]; - float sumWiRecoEt[KNEta][KNpT], sumWiptiRecoEt[KNEta][KNpT]; - float sumWiRecoMatchedEt[KNEta][KNpT], sumWiptiRecoMatchedEt[KNEta][KNpT]; - float sumWiRecoEffCorrEt[KNEta][KNpT], sumWiptiRecoEffCorrEt[KNEta][KNpT]; - float sumWiRecoMatchedEffCorrEt[KNEta][KNpT], sumWiptiRecoMatchedEffCorrEt[KNEta][KNpT]; - for (const auto& mcCollision : mcColl) { auto colSlice = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); - if (colSlice.size() != 1) continue; + for (const auto& col : colSlice) { - if (!col.has_mcCollision()) - continue; - if (!isEventSelected(col)) + if (!col.has_mcCollision() || !isEventSelected(col)) continue; + // + // auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); + // if (trackSlice.size() < 1) continue; auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); - if (trackSlice.size() < 1) + auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); + if (trackSlice.size() < 1 || partSlice.size() < 1) continue; - auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); - if (partSlice.size() < 1) + float multPV = col.multNTracksPV(); + float vz = col.posZ(); + + for (const auto& track : trackSlice) { + if (!isTrackSelected(track)) + continue; + + float pt = track.pt(); + float eta = track.eta(); + float phi = track.phi(); + auto sign = track.sign(); + + // 1. Inclusive Weighting (Always filled for selected tracks) + float effIncl = getEfficiency(multPV, pt, eta, numKInclusive, 0, cfgEff); + float fakeIncl = getEfficiency(multPV, pt, eta, numKInclusive, 1, cfgEff); + float wIncl = (1.0 - fakeIncl) / effIncl; + + if (std::isfinite(wIncl) && wIncl > 0.f && effIncl > KFloatEpsilon) { + histos.fill(HIST("hEtaPhiRecoEffWtd"), vz, sign, pt, eta, phi, wIncl); + histos.fill(HIST("hEtaPhiReco"), vz, sign, pt, eta, phi, 1.0); + } + + // 2. Pion Weighting + if (selectionPion(track)) { + float effPi = getEfficiency(multPV, pt, eta, numKPion, 0, cfgEff); + float fakePi = getEfficiency(multPV, pt, eta, numKPion, 1, cfgEff); + float wPi = (1.0 - fakePi) / effPi; + if (std::isfinite(wPi) && wPi > 0.f && effPi > KFloatEpsilon) { + histos.fill(HIST("hEtaPhiRecoEffWtd_Pi"), vz, sign, pt, eta, phi, wPi); + histos.fill(HIST("hEtaPhiReco_Pi"), vz, sign, pt, eta, phi, 1.0); + } + } + + // 3. Kaon Weighting + if (selectionKaon(track)) { + float effKa = getEfficiency(multPV, pt, eta, numKKaon, 0, cfgEff); + float fakeKa = getEfficiency(multPV, pt, eta, numKKaon, 1, cfgEff); + float wKa = (1.0 - fakeKa) / effKa; + if (std::isfinite(wKa) && wKa > 0.f && effKa > KFloatEpsilon) { + histos.fill(HIST("hEtaPhiRecoEffWtd_Ka"), vz, sign, pt, eta, phi, wKa); + histos.fill(HIST("hEtaPhiReco_Ka"), vz, sign, pt, eta, phi, 1.0); + } + } + + // 4. Proton Weighting + if (selectionProton(track)) { + float effPr = getEfficiency(multPV, pt, eta, numKProton, 0, cfgEff); + float fakePr = getEfficiency(multPV, pt, eta, numKProton, 1, cfgEff); + float wPr = (1.0 - fakePr) / effPr; + if (std::isfinite(wPr) && wPr > 0.f && effPr > KFloatEpsilon) { + histos.fill(HIST("hEtaPhiRecoEffWtd_Pr"), vz, sign, pt, eta, phi, wPr); + histos.fill(HIST("hEtaPhiReco_Pr"), vz, sign, pt, eta, phi, 1.0); + } + } + } // end track loop + } // end col loop + } // end mcColl loop + LOGF(info, "FINISHED RUNNING processMCFlat"); + } + PROCESS_SWITCH(RadialFlowDecorr, processMCFlat, "process MC to calculate FlatWeights", cfgRunGetMCFlat); + + void processMCMean(aod::McCollisions const& mcColl, MyRun3MCCollisions const& collisions, TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) + { + // Track-sum arrays using KNsp index (isp=0: Incl, 1: Pi, 2: Ka, 3: Pr) + double sumWiTruth[KNsp][KNEta][KNpT]{}, sumWiptiTruth[KNsp][KNEta][KNpT]{}; + double sumWiReco[KNsp][KNEta][KNpT]{}, sumWiptiReco[KNsp][KNEta][KNpT]{}; + double sumWiRecoEffCorr[KNsp][KNEta][KNpT]{}, sumWiptiRecoEffCorr[KNsp][KNEta][KNpT]{}; + + for (const auto& mcCollision : mcColl) { + auto colSlice = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + if (colSlice.size() != 1) + continue; + + for (const auto& col : colSlice) { + if (!col.has_mcCollision() || !isEventSelected(col)) continue; - if (col.globalIndex() >= trackSlice.size()) { - LOGF(warning, "Skipping invalid globalIndex=%d for tracks (tracks.size=%d)", col.globalIndex(), tracks.size()); + + auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); + auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); + if (trackSlice.size() < 1 || partSlice.size() < 1) continue; - } float cent = getCentrality(col); if (cent > KCentMax) continue; + float multPV = col.multNTracksPV(); + float vz = col.posZ(); - if (col.globalIndex() >= trackSlice.size()) { - LOGF(warning, "Skipping invalid globalIndex=%d for tracks (tracks.size=%d)", col.globalIndex(), tracks.size()); - continue; - } - - LOGF(info, "Event Check: cent = %.1f, nTracks = %d", cent, (int)trackSlice.size()); + // Reset local event sum memset(sumWiTruth, 0, sizeof(sumWiTruth)); memset(sumWiptiTruth, 0, sizeof(sumWiptiTruth)); memset(sumWiReco, 0, sizeof(sumWiReco)); memset(sumWiptiReco, 0, sizeof(sumWiptiReco)); - memset(sumWiRecoMatched, 0, sizeof(sumWiRecoMatched)); - memset(sumWiptiRecoMatched, 0, sizeof(sumWiptiRecoMatched)); memset(sumWiRecoEffCorr, 0, sizeof(sumWiRecoEffCorr)); memset(sumWiptiRecoEffCorr, 0, sizeof(sumWiptiRecoEffCorr)); - memset(sumWiRecoMatchedEffCorr, 0, sizeof(sumWiRecoMatchedEffCorr)); - memset(sumWiptiRecoMatchedEffCorr, 0, sizeof(sumWiptiRecoMatchedEffCorr)); - memset(sumWiTruthEt, 0, sizeof(sumWiTruthEt)); - memset(sumWiptiTruthEt, 0, sizeof(sumWiptiTruthEt)); - memset(sumWiRecoEt, 0, sizeof(sumWiRecoEt)); - memset(sumWiptiRecoEt, 0, sizeof(sumWiptiRecoEt)); - memset(sumWiRecoMatchedEt, 0, sizeof(sumWiRecoMatchedEt)); - memset(sumWiptiRecoMatchedEt, 0, sizeof(sumWiptiRecoMatchedEt)); - memset(sumWiRecoEffCorrEt, 0, sizeof(sumWiRecoEffCorrEt)); - memset(sumWiptiRecoEffCorrEt, 0, sizeof(sumWiptiRecoEffCorrEt)); - memset(sumWiRecoMatchedEffCorrEt, 0, sizeof(sumWiRecoMatchedEffCorrEt)); - memset(sumWiptiRecoMatchedEffCorrEt, 0, sizeof(sumWiptiRecoMatchedEffCorrEt)); - - // Truth + + // --- 1. Truth Loop --- for (const auto& particle : partSlice) { - if (!isParticleSelected(particle)) + if (!isParticleSelected(particle) || !particle.isPhysicalPrimary()) continue; - if (!particle.isPhysicalPrimary()) - continue; - + float pt = particle.pt(), eta = particle.eta(); const int absPdgId = std::abs(particle.pdgCode()); - const bool isPion = (absPdgId == kPiPlus); - const bool isKaon = (absPdgId == kKPlus); - const bool isProton = (absPdgId == kProton); - - float pt = particle.pt(); - float eta = particle.eta(); - float p = particle.p(); - + bool isSpecies[KNsp] = {true, (absPdgId == KPiPlus), (absPdgId == KKPlus), (absPdgId == KProton)}; for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) continue; for (int ipt = 0; ipt < KNpT; ++ipt) { if (pt <= pTLw[ipt] || pt > pTUp[ipt]) continue; - sumWiTruth[ieta][ipt]++; - sumWiptiTruth[ieta][ipt] += pt; - if (isPion || isKaon || isProton) { - float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus - : o2::constants::physics::MassProton; - float energy = std::sqrt(p * p + m * m); - float et = energy * (pt / p); // E_T = E * sin(theta) = E * (pT / p) - sumWiTruthEt[ieta][ipt]++; - sumWiptiTruthEt[ieta][ipt] += et; + for (int isp = 0; isp < KNsp; ++isp) { + if (isSpecies[isp]) { + sumWiTruth[isp][ieta][ipt]++; + sumWiptiTruth[isp][ieta][ipt] += pt; + } } } } } - for (const auto& track : trackSlice) { - if (!isTrackSelected(track)) - continue; + for (int isp = 0; isp < KNsp; ++isp) { + if (isp == numKInclusive) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec"), cent, sumWiTruth[0][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec"), multPV, sumWiTruth[0][0][0]); + if (sumWiTruth[0][0][0] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT"), cent, sumWiptiTruth[0][0][0] / sumWiTruth[0][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT"), multPV, sumWiptiTruth[0][0][0] / sumWiTruth[0][0][0]); + } - float pt = track.pt(); - float eta = track.eta(); - float p = track.p(); - float phi = track.phi(); + } else if (isp == numKPion) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec_Pi"), cent, sumWiTruth[1][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec_Pi"), multPV, sumWiTruth[1][0][0]); - histos.fill(HIST("hCentEtaPhi"), cent, eta, phi); - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhi"), eta, phi); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhi"), eta, phi); + if (sumWiTruth[1][0][0] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT_Pi"), cent, sumWiptiTruth[1][0][0] / sumWiTruth[1][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT_Pi"), multPV, sumWiptiTruth[1][0][0] / sumWiTruth[1][0][0]); + } - float effIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 0); - float fakeIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; + } else if (isp == numKKaon) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec_Ka"), cent, sumWiTruth[2][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec_Ka"), multPV, sumWiTruth[2][0][0]); - histos.fill(HIST("hCentEtaPhiWtd"), cent, eta, track.phi(), flatWeightIncl); - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhiWtd"), track.eta(), track.phi(), flatWeightIncl); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhiWtd"), track.eta(), track.phi(), flatWeightIncl); + if (sumWiTruth[2][0][0] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT_Ka"), cent, sumWiptiTruth[2][0][0] / sumWiTruth[2][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT_Ka"), multPV, sumWiptiTruth[2][0][0] / sumWiTruth[2][0][0]); + } + } else if (isp == numKProton) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec_Pr"), cent, sumWiTruth[3][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec_Pr"), multPV, sumWiTruth[3][0][0]); - for (int ieta = 0; ieta < KNEta; ++ieta) { - if (eta <= etaLw[ieta] || eta > etaUp[ieta]) - continue; - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (pt <= pTLw[ipt] || pt > pTUp[ipt]) - continue; - sumWiReco[ieta][ipt] += 1.0; - sumWiptiReco[ieta][ipt] += pt; + if (sumWiTruth[3][0][0] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT_Pr"), cent, sumWiptiTruth[3][0][0] / sumWiTruth[3][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT_Pr"), multPV, sumWiptiTruth[3][0][0] / sumWiTruth[3][0][0]); } } + } - if (effIncl <= 0 || !std::isfinite(wIncl) || !std::isfinite(fakeIncl) || !std::isfinite(flatWeightIncl)) + // --- 2. Reco Loop --- + for (const auto& track : trackSlice) { + if (!isTrackSelected(track)) continue; - - for (int ieta = 0; ieta < KNEta; ++ieta) { - if (eta <= etaLw[ieta] || eta > etaUp[ieta]) + float pt = track.pt(), eta = track.eta(), phi = track.phi(); + auto sign = track.sign(); + bool isSpecies[KNsp] = {true, selectionPion(track), selectionKaon(track), selectionProton(track)}; + for (int isp = 0; isp < KNsp; ++isp) { + if (!isSpecies[isp]) + continue; + float eff = getEfficiency(multPV, pt, eta, static_cast(isp), 0, cfgEff); + float fake = getEfficiency(multPV, pt, eta, static_cast(isp), 1, cfgEff); + float flatW = getFlatteningWeight(vz, sign, pt, eta, phi, static_cast(isp), cfgFlat); + float w = flatW * (1.0 - fake) / eff; + if (!std::isfinite(w) || w <= 0.f || eff <= KFloatEpsilon) continue; - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (pt <= pTLw[ipt] || pt > pTUp[ipt]) - continue; - sumWiRecoEffCorr[ieta][ipt] += wIncl; - sumWiptiRecoEffCorr[ieta][ipt] += wIncl * pt; - } - } - const bool isPion = selectionPion(track); - const bool isKaon = selectionKaon(track); - const bool isProton = selectionProton(track); - if (isPion || isKaon || isProton) { - float effPid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 0); - float fakePid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); - float wPid = flatWeightPid * (1.0 - fakePid) / effPid; - - histos.fill(HIST("hCentEtaPhiWtd_PID"), cent, eta, track.phi(), flatWeightPid); - if (cent < KCentTestMin) - histos.fill(HIST("hCent1EtaPhiWtd_PID"), track.eta(), track.phi(), flatWeightPid); - if (cent > KCentTestMaxLo && cent < KCentTestMaxHi) - histos.fill(HIST("hCent7EtaPhiWtd_PID"), track.eta(), track.phi(), flatWeightPid); - - float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus - : o2::constants::physics::MassProton; - float energy = std::sqrt(p * p + m * m); - float et = energy * (pt / p); // E_T = E * sin(theta) for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) continue; for (int ipt = 0; ipt < KNpT; ++ipt) { if (pt <= pTLw[ipt] || pt > pTUp[ipt]) continue; - sumWiRecoEt[ieta][ipt] += 1.0; - sumWiptiRecoEt[ieta][ipt] += et; + sumWiReco[isp][ieta][ipt]++; + sumWiptiReco[isp][ieta][ipt] += pt; + sumWiRecoEffCorr[isp][ieta][ipt] += w; + sumWiptiRecoEffCorr[isp][ieta][ipt] += w * pt; + + if (ipt == 0) { + // Fill profiles vs. Centrality + histos.fill(HIST("Eff_cent"), cent, eff); + histos.fill(HIST("Fake_cent"), cent, fake); + histos.fill(HIST("wgt_cent"), cent, w); + + // Fill profiles vs. Multiplicity (Ntrk) + histos.fill(HIST("Eff_Ntrk"), multPV, eff); + histos.fill(HIST("Fake_Ntrk"), multPV, fake); + histos.fill(HIST("wgt_Ntrk"), multPV, w); + + // Fill profiles vs. pT + histos.fill(HIST("Eff_pT"), pt, eff); + histos.fill(HIST("Fake_pT"), pt, fake); + histos.fill(HIST("wgt_pT"), pt, w); + + // Fill profiles vs. Eta + histos.fill(HIST("Eff_eta"), eta, eff); + histos.fill(HIST("Fake_eta"), eta, fake); + histos.fill(HIST("wgt_eta"), eta, w); + } } } - if (effPid <= KFloatEpsilon || !std::isfinite(wPid) || !std::isfinite(fakePid) || !std::isfinite(flatWeightPid)) - continue; + if (isp == numKInclusive) { - for (int ieta = 0; ieta < KNEta; ++ieta) { - if (eta <= etaLw[ieta] || eta > etaUp[ieta]) - continue; - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (pt <= pTLw[ipt] || pt > pTUp[ipt]) - continue; - sumWiRecoEffCorrEt[ieta][ipt] += wPid; - sumWiptiRecoEffCorrEt[ieta][ipt] += wPid * et; - } + histos.fill(HIST("hEtaPhiReco"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + + } else if (isp == numKPion) { // Pion + histos.fill(HIST("hEtaPhiReco_Pi"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd_Pi"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pi"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + + } else if (isp == numKKaon) { // Kaon + histos.fill(HIST("hEtaPhiReco_Ka"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd_Ka"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd_Ka"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + + } else if (isp == numKProton) { // Proton + histos.fill(HIST("hEtaPhiReco_Pr"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd_Pr"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pr"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); } } + } - if (std::isfinite(wIncl)) { - if (cent < KCentTestMin) { - histos.fill(HIST("wgt_pT"), pt, wIncl); - histos.fill(HIST("Eff_pT"), pt, effIncl); - histos.fill(HIST("Fake_pT"), pt, fakeIncl); - histos.fill(HIST("Eff_eta"), eta, effIncl); - histos.fill(HIST("Fake_eta"), eta, fakeIncl); - histos.fill(HIST("wgt_eta"), eta, wIncl); - } - histos.fill(HIST("Eff_cent"), cent, effIncl); - histos.fill(HIST("Eff_Ntrk"), col.multNTracksPV(), effIncl); - histos.fill(HIST("Fake_cent"), cent, fakeIncl); - histos.fill(HIST("Fake_Ntrk"), col.multNTracksPV(), fakeIncl); - histos.fill(HIST("wgt_cent"), cent, wIncl); - histos.fill(HIST("wgt_Ntrk"), col.multNTracksPV(), wIncl); - } + for (int isp = 0; isp < KNsp; ++isp) { + if (isp == numKInclusive) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec"), cent, sumWiReco[0][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec"), multPV, sumWiReco[0][0][0]); + if (sumWiReco[0][0][0] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT"), cent, sumWiptiReco[0][0][0] / sumWiReco[0][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT"), multPV, sumWiptiReco[0][0][0] / sumWiReco[0][0][0]); + } - } // end track loop + } else if (isp == numKPion) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec_Pi"), cent, sumWiReco[1][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec_Pi"), multPV, sumWiReco[1][0][0]); - if (std::isfinite(sumWiTruth[0][0])) { - float meanPtTruth = sumWiptiTruth[0][0] / sumWiTruth[0][0]; - if (!std::isfinite(meanPtTruth)) - LOGF(info, "meanPtTruth = %.3f, num = %.3f, den =%.3f", meanPtTruth, sumWiptiTruth[0][0], sumWiTruth[0][0]); - if (!std::isfinite(meanPtTruth)) - continue; - histos.fill(HIST("MCGen/Prof_cent_Nchrec"), cent, sumWiTruth[0][0]); - histos.fill(HIST("MCGen/Prof_MeanpT_Cent"), cent, meanPtTruth); - histos.fill(HIST("MCGen/Prof_MeanpT_Mult"), col.multNTracksPV(), meanPtTruth); - } - if (std::isfinite(sumWiReco[0][0])) { - float meanPtReco = sumWiptiReco[0][0] / sumWiReco[0][0]; - if (!std::isfinite(meanPtReco)) - LOGF(info, "meanPtReco = %.3f, num = %.3f, den =%.3f", meanPtReco, sumWiptiReco[0][0], sumWiReco[0][0]); - if (!std::isfinite(meanPtReco)) - continue; - histos.fill(HIST("MCReco/Prof_cent_Nchrec"), cent, sumWiReco[0][0]); - histos.fill(HIST("MCReco/Prof_MeanpT_Cent"), cent, meanPtReco); - histos.fill(HIST("MCReco/Prof_MeanpT_Mult"), col.multNTracksPV(), meanPtReco); - } - if (std::isfinite(sumWiRecoEffCorr[0][0])) { - float meanpTeffcorr = sumWiptiRecoEffCorr[0][0] / sumWiRecoEffCorr[0][0]; - if (!std::isfinite(meanpTeffcorr)) - LOGF(info, "meanPtRecoEffcorr = %.3f, num = %.3f, den =%.3f", meanpTeffcorr, sumWiptiRecoEffCorr[0][0], sumWiRecoEffCorr[0][0]); - if (!std::isfinite(meanpTeffcorr)) - continue; - histos.fill(HIST("MCRecoEffCorr/Prof_cent_Nchrec"), cent, sumWiRecoEffCorr[0][0]); - histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Cent"), cent, meanpTeffcorr); - histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Mult"), col.multNTracksPV(), meanpTeffcorr); - } + if (sumWiReco[1][0][0] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT_Pi"), cent, sumWiptiReco[1][0][0] / sumWiReco[1][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT_Pi"), multPV, sumWiptiReco[1][0][0] / sumWiReco[1][0][0]); + } - if (std::isfinite(sumWiTruthEt[0][0])) { - float meanEt = sumWiptiTruthEt[0][0] / sumWiTruthEt[0][0]; - if (!std::isfinite(meanEt)) - LOGF(info, "meanEtTruthEt = %.3f, num = %.3f, den =%.3f", meanEt, sumWiptiTruthEt[0][0], sumWiTruthEt[0][0]); - if (!std::isfinite(meanEt)) - continue; - histos.fill(HIST("MCGen/Prof_MeanEt_Cent"), cent, meanEt); - histos.fill(HIST("MCGen/Prof_MeanEt_Mult"), col.multNTracksPV(), meanEt); - } - // "MCReco" - if (std::isfinite(sumWiRecoEt[0][0])) { - float meanEt = sumWiptiRecoEt[0][0] / sumWiRecoEt[0][0]; - if (!std::isfinite(meanEt)) - LOGF(info, "meanEtRecoEt = %.3f, num = %.3f, den =%.3f", meanEt, sumWiptiRecoEt[0][0], sumWiRecoEt[0][0]); - if (!std::isfinite(meanEt)) - continue; - histos.fill(HIST("MCReco/Prof_MeanEt_Cent"), cent, meanEt); - histos.fill(HIST("MCReco/Prof_MeanEt_Mult"), col.multNTracksPV(), meanEt); - } - // "MCRecoEffCorr" - if (std::isfinite(sumWiRecoEffCorrEt[0][0])) { - float meanEt = sumWiptiRecoEffCorrEt[0][0] / sumWiRecoEffCorrEt[0][0]; - if (!std::isfinite(meanEt)) - LOGF(info, "meanEtRecoEffcorrEt = %.3f, num = %.3f, den =%.3f", meanEt, sumWiptiRecoEffCorrEt[0][0], sumWiRecoEffCorrEt[0][0]); - if (!std::isfinite(meanEt)) - continue; - histos.fill(HIST("MCRecoEffCorr/Prof_MeanEt_Cent"), cent, meanEt); - histos.fill(HIST("MCRecoEffCorr/Prof_MeanEt_Mult"), col.multNTracksPV(), meanEt); - } + } else if (isp == numKKaon) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec_Ka"), cent, sumWiReco[2][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec_Ka"), multPV, sumWiReco[2][0][0]); - for (int ieta = 0; ieta < KNEta; ++ieta) { - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (std::isfinite(sumWiTruth[ieta][ipt])) - histos.fill(HIST("pmeanTruNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, sumWiptiTruth[ieta][ipt] / sumWiTruth[ieta][ipt]); - if (std::isfinite(sumWiReco[ieta][ipt])) - histos.fill(HIST("pmeanRecoNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, sumWiptiReco[ieta][ipt] / sumWiReco[ieta][ipt]); - if (std::isfinite(sumWiRecoEffCorr[ieta][ipt])) - histos.fill(HIST("pmeanRecoEffcorrNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, sumWiptiRecoEffCorr[ieta][ipt] / sumWiRecoEffCorr[ieta][ipt]); - - if (std::isfinite(sumWiTruthEt[ieta][ipt])) - histos.fill(HIST("pmeanEtTruNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, sumWiptiTruthEt[ieta][ipt] / sumWiTruthEt[ieta][ipt]); - if (std::isfinite(sumWiRecoEt[ieta][ipt])) - histos.fill(HIST("pmeanEtRecoNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, sumWiptiRecoEt[ieta][ipt] / sumWiRecoEt[ieta][ipt]); - if (std::isfinite(sumWiRecoEffCorrEt[ieta][ipt])) - histos.fill(HIST("pmeanEtRecoEffcorrNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, sumWiptiRecoEffCorrEt[ieta][ipt] / sumWiRecoEffCorrEt[ieta][ipt]); + if (sumWiReco[2][0][0] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT_Ka"), cent, sumWiptiReco[2][0][0] / sumWiReco[2][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT_Ka"), multPV, sumWiptiReco[2][0][0] / sumWiReco[2][0][0]); + } + } else if (isp == numKProton) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec_Pr"), cent, sumWiReco[3][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec_Pr"), multPV, sumWiReco[3][0][0]); + if (sumWiReco[3][0][0] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT_Pr"), cent, sumWiptiReco[3][0][0] / sumWiReco[3][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT_Pr"), multPV, sumWiptiReco[3][0][0] / sumWiReco[3][0][0]); + } + } + + if (isp == numKInclusive) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec"), cent, sumWiRecoEffCorr[0][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec"), multPV, sumWiRecoEffCorr[0][0][0]); + if (sumWiRecoEffCorr[0][0][0] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT"), cent, sumWiptiRecoEffCorr[0][0][0] / sumWiRecoEffCorr[0][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT"), multPV, sumWiptiRecoEffCorr[0][0][0] / sumWiRecoEffCorr[0][0][0]); + } + + } else if (isp == numKPion) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec_Pi"), cent, sumWiRecoEffCorr[1][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec_Pi"), multPV, sumWiRecoEffCorr[1][0][0]); + if (sumWiRecoEffCorr[1][0][0] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT_Pi"), cent, sumWiptiRecoEffCorr[1][0][0] / sumWiRecoEffCorr[1][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT_Pi"), multPV, sumWiptiRecoEffCorr[1][0][0] / sumWiRecoEffCorr[1][0][0]); + } + + } else if (isp == numKKaon) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec_Ka"), cent, sumWiRecoEffCorr[2][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec_Ka"), multPV, sumWiRecoEffCorr[2][0][0]); + if (sumWiRecoEffCorr[2][0][0] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT_Ka"), cent, sumWiptiRecoEffCorr[2][0][0] / sumWiRecoEffCorr[2][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT_Ka"), multPV, sumWiptiRecoEffCorr[2][0][0] / sumWiRecoEffCorr[2][0][0]); + } + } else if (isp == numKProton) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec_Pr"), cent, sumWiRecoEffCorr[3][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec_Pr"), multPV, sumWiRecoEffCorr[3][0][0]); + if (sumWiRecoEffCorr[3][0][0] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT_Pr"), cent, sumWiptiRecoEffCorr[3][0][0] / sumWiRecoEffCorr[3][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT_Pr"), multPV, sumWiptiRecoEffCorr[3][0][0] / sumWiRecoEffCorr[3][0][0]); + } } } - } // end col loop - } - LOGF(info, "FINISHED RUNNING processMCMean (pT + Et)"); + for (int ietaA = 0; ietaA < KNEta; ++ietaA) { + for (int ietaB = 0; ietaB < KNEta; ++ietaB) { + for (int ipt = 0; ipt < KNpT; ++ipt) { + for (int isp = 0; isp < KNsp; ++isp) { + + // 1. Truth Sub-event Mean + double nTruAB = sumWiTruth[isp][ietaA][ipt] + sumWiTruth[isp][ietaB][ipt]; + if (nTruAB > 0) { + float mptsubTru = (sumWiptiTruth[isp][ietaA][ipt] + sumWiptiTruth[isp][ietaB][ipt]) / nTruAB; + if (isp == numKInclusive) { // Inclusive + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Tru"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Tru"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Tru"), cent, ietaA, ietaB, mptsubTru); + } else if (isp == numKPion) { // Pion + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Tru_Pi"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Tru_Pi"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Tru_Pi"), cent, ietaA, ietaB, mptsubTru); + } else if (isp == numKKaon) { // Kaon + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Tru_Ka"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Tru_Ka"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Tru_Ka"), cent, ietaA, ietaB, mptsubTru); + } else if (isp == numKProton) { // Proton + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Tru_Pr"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Tru_Pr"), cent, ietaA, ietaB, mptsubTru); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Tru_Pr"), cent, ietaA, ietaB, mptsubTru); + } + } + + // 2. Reco Raw Sub-event Mean + double nRecAB = sumWiReco[isp][ietaA][ipt] + sumWiReco[isp][ietaB][ipt]; + if (nRecAB > 0) { + float mptsubReco = (sumWiptiReco[isp][ietaA][ipt] + sumWiptiReco[isp][ietaB][ipt]) / nRecAB; + if (isp == numKInclusive) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Reco"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Reco"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Reco"), cent, ietaA, ietaB, mptsubReco); + } else if (isp == numKPion) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Reco_Pi"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Reco_Pi"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Reco_Pi"), cent, ietaA, ietaB, mptsubReco); + } else if (isp == numKKaon) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Reco_Ka"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Reco_Ka"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Reco_Ka"), cent, ietaA, ietaB, mptsubReco); + } else if (isp == numKProton) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Reco_Pr"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Reco_Pr"), cent, ietaA, ietaB, mptsubReco); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Reco_Pr"), cent, ietaA, ietaB, mptsubReco); + } + } + + // 3. Reco Efficiency Corrected Sub-event Mean + double wCorrAB = sumWiRecoEffCorr[isp][ietaA][ipt] + sumWiRecoEffCorr[isp][ietaB][ipt]; + if (wCorrAB > 0) { + float mptsubRecoEffCorr = (sumWiptiRecoEffCorr[isp][ietaA][ipt] + sumWiptiRecoEffCorr[isp][ietaB][ipt]) / wCorrAB; + if (isp == numKInclusive) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_RecoEffCorr"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_RecoEffCorr"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_RecoEffCorr"), cent, ietaA, ietaB, mptsubRecoEffCorr); + } else if (isp == numKPion) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_RecoEffCorr_Pi"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_RecoEffCorr_Pi"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_RecoEffCorr_Pi"), cent, ietaA, ietaB, mptsubRecoEffCorr); + } else if (isp == numKKaon) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_RecoEffCorr_Ka"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_RecoEffCorr_Ka"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_RecoEffCorr_Ka"), cent, ietaA, ietaB, mptsubRecoEffCorr); + } else if (isp == numKProton) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_RecoEffCorr_Pr"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_RecoEffCorr_Pr"), cent, ietaA, ietaB, mptsubRecoEffCorr); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_RecoEffCorr_Pr"), cent, ietaA, ietaB, mptsubRecoEffCorr); + } + } + + // 4. pmean Profiles (Individual Bins) + if (ietaA == ietaB) { // only fill once per eta bin + if (sumWiTruth[isp][ietaA][ipt] > 0) { + float val = sumWiptiTruth[isp][ietaA][ipt] / sumWiTruth[isp][ietaA][ipt]; + if (isp == numKInclusive) + histos.fill(HIST("pmeanTruNchEtabinPtbin"), multPV, ietaA, ipt, val); + else if (isp == numKPion) + histos.fill(HIST("pmeanTruNchEtabinPtbin_Pi"), multPV, ietaA, ipt, val); + else if (isp == numKKaon) + histos.fill(HIST("pmeanTruNchEtabinPtbin_Ka"), multPV, ietaA, ipt, val); + else if (isp == numKProton) + histos.fill(HIST("pmeanTruNchEtabinPtbin_Pr"), multPV, ietaA, ipt, val); + } + + if (sumWiReco[isp][ietaA][ipt] > 0) { + float val = sumWiptiReco[isp][ietaA][ipt] / sumWiReco[isp][ietaA][ipt]; + if (isp == numKInclusive) + histos.fill(HIST("pmeanRecoNchEtabinPtbin"), multPV, ietaA, ipt, val); + else if (isp == numKPion) + histos.fill(HIST("pmeanRecoNchEtabinPtbin_Pi"), multPV, ietaA, ipt, val); + else if (isp == numKKaon) + histos.fill(HIST("pmeanRecoNchEtabinPtbin_Ka"), multPV, ietaA, ipt, val); + else if (isp == numKProton) + histos.fill(HIST("pmeanRecoNchEtabinPtbin_Pr"), multPV, ietaA, ipt, val); + } + if (sumWiRecoEffCorr[isp][ietaA][ipt] > 0) { + float val = sumWiptiRecoEffCorr[isp][ietaA][ipt] / sumWiRecoEffCorr[isp][ietaA][ipt]; + if (isp == numKInclusive) + histos.fill(HIST("pmeanRecoEffcorrNchEtabinPtbin"), multPV, ietaA, ipt, val); + else if (isp == numKPion) + histos.fill(HIST("pmeanRecoEffcorrNchEtabinPtbin_Pi"), multPV, ietaA, ipt, val); + else if (isp == numKKaon) + histos.fill(HIST("pmeanRecoEffcorrNchEtabinPtbin_Ka"), multPV, ietaA, ipt, val); + else if (isp == numKProton) + histos.fill(HIST("pmeanRecoEffcorrNchEtabinPtbin_Pr"), multPV, ietaA, ipt, val); + } + + if (sumWiTruth[isp][ietaA][ipt] > 0) { + if (isp == numKInclusive) + histos.fill(HIST("pmeanMultTruNchEtabinPtbin"), multPV, ietaA, ipt, sumWiTruth[isp][ietaA][ipt]); + else if (isp == numKPion) + histos.fill(HIST("pmeanMultTruNchEtabinPtbin_Pi"), multPV, ietaA, ipt, sumWiTruth[isp][ietaA][ipt]); + else if (isp == numKKaon) + histos.fill(HIST("pmeanMultTruNchEtabinPtbin_Ka"), multPV, ietaA, ipt, sumWiTruth[isp][ietaA][ipt]); + else if (isp == numKProton) + histos.fill(HIST("pmeanMultTruNchEtabinPtbin_Pr"), multPV, ietaA, ipt, sumWiTruth[isp][ietaA][ipt]); + } + + if (sumWiReco[isp][ietaA][ipt] > 0) { + if (isp == numKInclusive) + histos.fill(HIST("pmeanMultRecoNchEtabinPtbin"), multPV, ietaA, ipt, sumWiReco[isp][ietaA][ipt]); + else if (isp == numKPion) + histos.fill(HIST("pmeanMultRecoNchEtabinPtbin_Pi"), multPV, ietaA, ipt, sumWiReco[isp][ietaA][ipt]); + else if (isp == numKKaon) + histos.fill(HIST("pmeanMultRecoNchEtabinPtbin_Ka"), multPV, ietaA, ipt, sumWiReco[isp][ietaA][ipt]); + else if (isp == numKProton) + histos.fill(HIST("pmeanMultRecoNchEtabinPtbin_Pr"), multPV, ietaA, ipt, sumWiReco[isp][ietaA][ipt]); + } + if (sumWiRecoEffCorr[isp][ietaA][ipt] > 0) { + if (isp == numKInclusive) + histos.fill(HIST("pmeanMultRecoEffcorrNchEtabinPtbin"), multPV, ietaA, ipt, sumWiRecoEffCorr[isp][ietaA][ipt]); + else if (isp == numKPion) + histos.fill(HIST("pmeanMultRecoEffcorrNchEtabinPtbin_Pi"), multPV, ietaA, ipt, sumWiRecoEffCorr[isp][ietaA][ipt]); + else if (isp == numKKaon) + histos.fill(HIST("pmeanMultRecoEffcorrNchEtabinPtbin_Ka"), multPV, ietaA, ipt, sumWiRecoEffCorr[isp][ietaA][ipt]); + else if (isp == numKProton) + histos.fill(HIST("pmeanMultRecoEffcorrNchEtabinPtbin_Pr"), multPV, ietaA, ipt, sumWiRecoEffCorr[isp][ietaA][ipt]); + } + } + } // end isp + } // end ipt + } // end ietaB + } // end ietaA + } + } } PROCESS_SWITCH(RadialFlowDecorr, processMCMean, "process MC to calculate mean pt/Et and Eff Hists", cfgRunMCMean); void processMCFluc(aod::McCollisions const& mcColl, MyRun3MCCollisions const& collisions, TCs const& tracks, FilteredTCs const& /*filteredTracks*/, aod::McParticles const& mcParticles) { - double sumPmwkTru[KNEta][KNpT][KIntM][KIntK]{}; - double sumWkTru[KNEta][KNpT][KIntK]{}; - double sumPmwkReco[KNEta][KNpT][KIntM][KIntK]{}; - double sumWkReco[KNEta][KNpT][KIntK]{}; - double sumPmwkRecoEffCor[KNEta][KNpT][KIntM][KIntK]{}; - double sumWkRecoEffCor[KNEta][KNpT][KIntK]{}; - double sumPmwkTruEt[KNEta][KNpT][KIntM][KIntK]{}; - double sumWkTruEt[KNEta][KNpT][KIntK]{}; - double sumPmwkRecoEt[KNEta][KNpT][KIntM][KIntK]{}; - double sumWkRecoEt[KNEta][KNpT][KIntK]{}; - double sumPmwkRecoEffCorEt[KNEta][KNpT][KIntM][KIntK]{}; - double sumWkRecoEffCorEt[KNEta][KNpT][KIntK]{}; - double meanTru[KNEta][KNpT]{}, c2Tru[KNEta][KNpT]{}; - double meanReco[KNEta][KNpT]{}, c2Reco[KNEta][KNpT]{}; - double meanRecoEffCor[KNEta][KNpT]{}, c2RecoEffCor[KNEta][KNpT]{}; - double meanTruEt[KNEta][KNpT]{}, c2TruEt[KNEta][KNpT]{}; - double meanRecoEt[KNEta][KNpT]{}, c2RecoEt[KNEta][KNpT]{}; - double meanRecoEffCorEt[KNEta][KNpT]{}, c2RecoEffCorEt[KNEta][KNpT]{}; + // 1. Safety Check: Step 2 Mean Maps + for (int isp = 0; isp < KNsp; ++isp) { + if (!pmeanTruNchEtabinPtbinStep2[isp] || !pmeanRecoNchEtabinPtbinStep2[isp] || !pmeanRecoEffcorrNchEtabinPtbinStep2[isp] || + !pmeanMultTruNchEtabinPtbinStep2[isp] || !pmeanMultRecoNchEtabinPtbinStep2[isp] || !pmeanMultRecoEffcorrNchEtabinPtbinStep2[isp]) { + LOGF(warning, "MC fluc: Mean pT or Mult map missing for species index %d", isp); + return; + } + } + + // Expanded with KNsp index (isp=0: Incl, 1: Pi, 2: Ka, 3: Pr) + double sumPmwkTru[KNsp][KNEta][KNpT][KIntM][KIntK]{}; + double sumWkTru[KNsp][KNEta][KNpT][KIntK]{}; + double sumPmwkReco[KNsp][KNEta][KNpT][KIntM][KIntK]{}; + double sumWkReco[KNsp][KNEta][KNpT][KIntK]{}; + double sumPmwkRecoEffCor[KNsp][KNEta][KNpT][KIntM][KIntK]{}; + double sumWkRecoEffCor[KNsp][KNEta][KNpT][KIntK]{}; + + double meanTru[KNsp][KNEta][KNpT]{}, c2Tru[KNsp][KNEta][KNpT]{}; + double meanReco[KNsp][KNEta][KNpT]{}, c2Reco[KNsp][KNEta][KNpT]{}; + double meanRecoEffCor[KNsp][KNEta][KNpT]{}, c2RecoEffCor[KNsp][KNEta][KNpT]{}; + + double meanTruMult[KNsp][KNEta][KNpT]{}; + double meanRecoMult[KNsp][KNEta][KNpT]{}; + double meanRecoEffCorMult[KNsp][KNEta][KNpT]{}; + + double p1kBarTru[KNsp][KNEta][KNpT]{}, p1kBarReco[KNsp][KNEta][KNpT]{}, p1kBarRecoEffCor[KNsp][KNEta][KNpT]{}; + double p1kBarTruMult[KNsp][KNEta][KNpT]{}, p1kBarRecoMult[KNsp][KNEta][KNpT]{}, p1kBarRecoEffCorMult[KNsp][KNEta][KNpT]{}; for (const auto& mcCollision : mcColl) { auto partSlice = mcParticles.sliceBy(partPerMcCollision, mcCollision.globalIndex()); auto colSlice = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); if (colSlice.size() != 1) continue; - // histos.fill(HIST("MCGen/hVtxZ"), mcCollision.posZ()); + for (const auto& col : colSlice) { + if (!col.has_mcCollision() || !isEventSelected(col)) + continue; auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); if (trackSlice.size() < 1) continue; + float cent = getCentrality(col); + if (cent > KCentMax) + continue; + float multPV = col.multNTracksPV(); + // Reset local arrays memset(sumPmwkTru, 0, sizeof(sumPmwkTru)); memset(sumWkTru, 0, sizeof(sumWkTru)); memset(sumPmwkReco, 0, sizeof(sumPmwkReco)); @@ -1398,13 +1808,6 @@ struct RadialFlowDecorr { memset(sumPmwkRecoEffCor, 0, sizeof(sumPmwkRecoEffCor)); memset(sumWkRecoEffCor, 0, sizeof(sumWkRecoEffCor)); - memset(sumPmwkTruEt, 0, sizeof(sumPmwkTruEt)); - memset(sumWkTruEt, 0, sizeof(sumWkTruEt)); - memset(sumPmwkRecoEt, 0, sizeof(sumPmwkRecoEt)); - memset(sumWkRecoEt, 0, sizeof(sumWkRecoEt)); - memset(sumPmwkRecoEffCorEt, 0, sizeof(sumPmwkRecoEffCorEt)); - memset(sumWkRecoEffCorEt, 0, sizeof(sumWkRecoEffCorEt)); - memset(meanTru, 0, sizeof(meanTru)); memset(c2Tru, 0, sizeof(c2Tru)); memset(meanReco, 0, sizeof(meanReco)); @@ -1412,28 +1815,27 @@ struct RadialFlowDecorr { memset(meanRecoEffCor, 0, sizeof(meanRecoEffCor)); memset(c2RecoEffCor, 0, sizeof(c2RecoEffCor)); - memset(meanTruEt, 0, sizeof(meanTruEt)); - memset(c2TruEt, 0, sizeof(c2TruEt)); - memset(meanRecoEt, 0, sizeof(meanRecoEt)); - memset(c2RecoEt, 0, sizeof(c2RecoEt)); - memset(meanRecoEffCorEt, 0, sizeof(meanRecoEffCorEt)); - memset(c2RecoEffCorEt, 0, sizeof(c2RecoEffCorEt)); + memset(meanTruMult, 0, sizeof(meanTruMult)); + memset(meanRecoMult, 0, sizeof(meanRecoMult)); + memset(meanRecoEffCorMult, 0, sizeof(meanRecoEffCorMult)); - if (!col.has_mcCollision() || !isEventSelected(col)) - continue; - float cent = getCentrality(col); - if (cent > KCentMax) - continue; + memset(p1kBarTru, 0, sizeof(p1kBarTru)); + memset(p1kBarReco, 0, sizeof(p1kBarReco)); + memset(p1kBarRecoEffCor, 0, sizeof(p1kBarRecoEffCor)); + + memset(p1kBarTruMult, 0, sizeof(p1kBarTruMult)); + memset(p1kBarRecoMult, 0, sizeof(p1kBarRecoMult)); + memset(p1kBarRecoEffCorMult, 0, sizeof(p1kBarRecoEffCorMult)); - // truth + // --- 1. Truth Loop --- for (const auto& particle : partSlice) { - if (!isParticleSelected(particle)) - continue; - if (!particle.isPhysicalPrimary()) + if (!isParticleSelected(particle) || !particle.isPhysicalPrimary()) continue; + float pt = particle.pt(); float eta = particle.eta(); - float p = particle.p(); + const int absPdgId = std::abs(particle.pdgCode()); + bool isSpecies[KNsp] = {true, (absPdgId == KPiPlus), (absPdgId == KKPlus), (absPdgId == KProton)}; for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) @@ -1441,90 +1843,43 @@ struct RadialFlowDecorr { for (int ipt = 0; ipt < KNpT; ++ipt) { if (pt <= pTLw[ipt] || pt > pTUp[ipt]) continue; - for (int k = 0; k < KIntK; ++k) { - for (int m = 0; m < KIntM; ++m) { - sumPmwkTru[ieta][ipt][m][k] += std::pow(pt, m); - } - sumWkTru[ieta][ipt][k]++; - } - } - } - const int absPdgId = std::abs(particle.pdgCode()); - const bool isPion = (absPdgId == kPiPlus); - const bool isKaon = (absPdgId == kKPlus); - const bool isProton = (absPdgId == kProton); - if (isPion || isKaon || isProton) { - - float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus - : o2::constants::physics::MassProton; - float energy = std::sqrt(p * p + m * m); - float et = energy * (pt / p); - for (int ieta = 0; ieta < KNEta; ++ieta) { - if (eta <= etaLw[ieta] || eta > etaUp[ieta]) - continue; - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (pt <= pTLw[ipt] || pt > pTUp[ipt]) - continue; - for (int k = 0; k < KIntK; ++k) { - for (int m = 0; m < KIntM; ++m) { - sumPmwkTruEt[ieta][ipt][m][k] += std::pow(et, m); + + for (int isp = 0; isp < KNsp; ++isp) { + if (isSpecies[isp]) { + for (int k = 0; k < KIntK; ++k) { + for (int m = 0; m < KIntM; ++m) { + sumPmwkTru[isp][ieta][ipt][m][k] += std::pow(pt, m); + } + sumWkTru[isp][ieta][ipt][k]++; } - sumWkTruEt[ieta][ipt][k]++; } } } } - } // end truth loop + // --- 2. Reco Loop --- + float vz = col.posZ(); for (const auto& track : trackSlice) { if (!isTrackSelected(track)) continue; + float pt = track.pt(); float eta = track.eta(); - float p = track.p(); float phi = track.phi(); + float sign = track.sign(); + bool isSpecies[KNsp] = {true, selectionPion(track), selectionKaon(track), selectionProton(track)}; - float effIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 0); - float fakeIncl = getEfficiency(col.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; - if (!std::isfinite(wIncl) || wIncl <= 0.f) - continue; - if (effIncl <= 0 || !std::isfinite(effIncl) || !std::isfinite(fakeIncl) || !std::isfinite(flatWeightIncl)) - continue; - - for (int ieta = 0; ieta < KNEta; ++ieta) { - if (eta <= etaLw[ieta] || eta > etaUp[ieta]) + for (int isp = 0; isp < KNsp; ++isp) { + if (!isSpecies[isp]) continue; - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (pt <= pTLw[ipt] || pt > pTUp[ipt]) - continue; - for (int k = 0; k < KIntK; ++k) { - for (int m = 0; m < KIntM; ++m) { - sumPmwkReco[ieta][ipt][m][k] += std::pow(1.0f, k) * std::pow(pt, m); - sumPmwkRecoEffCor[ieta][ipt][m][k] += std::pow(wIncl, k) * std::pow(pt, m); - } - sumWkReco[ieta][ipt][k] += std::pow(1.0f, k); - sumWkRecoEffCor[ieta][ipt][k] += std::pow(wIncl, k); - } - } - } - const bool isPion = selectionPion(track); - const bool isKaon = selectionKaon(track); - const bool isProton = selectionProton(track); - - if (isPion || isKaon || isProton) { - float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus - : o2::constants::physics::MassProton; - float energy = std::sqrt(p * p + m * m); - float et = energy * (pt / p); // E_T = E * sin(theta) - float effPid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 0); - float fakePid = getEfficiency(col.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); - float wPid = flatWeightPid * (1.0 - fakePid) / effPid; - if (effPid >= 1.f || fakePid >= 1.f || !std::isfinite(effPid) || effPid <= KFloatEpsilon || !std::isfinite(fakePid) || !std::isfinite(flatWeightPid)) + float eff = getEfficiency(col.multNTracksPV(), pt, eta, static_cast(isp), 0, cfgEff); + float fake = getEfficiency(col.multNTracksPV(), pt, eta, static_cast(isp), 1, cfgEff); + float flatW = getFlatteningWeight(vz, sign, pt, eta, phi, static_cast(isp), cfgFlat); + float w = flatW * (1.0 - fake) / eff; + + if (!std::isfinite(w) || w <= 0.f || eff <= KFloatEpsilon) continue; for (int ieta = 0; ieta < KNEta; ++ieta) { @@ -1535,484 +1890,796 @@ struct RadialFlowDecorr { continue; for (int k = 0; k < KIntK; ++k) { for (int m = 0; m < KIntM; ++m) { - sumPmwkRecoEt[ieta][ipt][m][k] += std::pow(1.0f, k) * std::pow(et, m); - sumPmwkRecoEffCorEt[ieta][ipt][m][k] += std::pow(wPid, k) * std::pow(et, m); + sumPmwkReco[isp][ieta][ipt][m][k] += std::pow(1.0, k) * std::pow(pt, m); + sumPmwkRecoEffCor[isp][ieta][ipt][m][k] += std::pow(w, k) * std::pow(pt, m); } - sumWkRecoEt[ieta][ipt][k] += std::pow(1.0f, k); - sumWkRecoEffCorEt[ieta][ipt][k] += std::pow(wPid, k); + sumWkReco[isp][ieta][ipt][k] += std::pow(1.0, k); + sumWkRecoEffCor[isp][ieta][ipt][k] += std::pow(w, k); } } } + + if (isp == numKInclusive) { + histos.fill(HIST("hEtaPhiReco"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + + } else if (isp == numKPion) { // Pion + histos.fill(HIST("hEtaPhiReco_Pi"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd_Pi"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pi"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + + } else if (isp == numKKaon) { // Kaon + histos.fill(HIST("hEtaPhiReco_Ka"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd_Ka"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd_Ka"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + + } else if (isp == numKProton) { // Proton + histos.fill(HIST("hEtaPhiReco_Pr"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoWtd_Pr"), vz, sign, pt, eta, phi, w); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pr"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + } } + } // trkslice - for (int ieta = 0; ieta < KNEta; ++ieta) { - for (int ipt = 0; ipt < KNpT; ++ipt) { - const int ibx = pmeanTruNchEtabinPtbinStep2->GetXaxis()->FindBin(col.multNTracksPV()); - const int iby = ieta + 1; - const int ibz = ipt + 1; + // --- 3. FullEvent calculation & Covariances --- + for (int ieta = 0; ieta < KNEta; ++ieta) { + for (int ipt = 0; ipt < KNpT; ++ipt) { + + // Safely get the X-axis bin using the Inclusive map [0] + const int ibx = pmeanTruNchEtabinPtbinStep2[0]->GetXaxis()->FindBin(col.multNTracksPV()); + const int iby = ieta + 1; + const int ibz = ipt + 1; - float mmptTru = pmeanTruNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmptReco = pmeanRecoNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmptRecoEffCor = pmeanRecoEffcorrNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmetTru = pmeanEtTruNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmetReco = pmeanEtRecoNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmetRecoEffCor = pmeanEtRecoEffcorrNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); + for (int isp = 0; isp < KNsp; ++isp) { + meanTruMult[isp][ieta][ipt] = sumWkTru[isp][ieta][ipt][1]; + meanRecoMult[isp][ieta][ipt] = sumWkReco[isp][ieta][ipt][1]; + meanRecoEffCorMult[isp][ieta][ipt] = sumWkRecoEffCor[isp][ieta][ipt][1]; + + // Dynamically fetch from the arrays using the 'isp' index! + float mmptTru = pmeanTruNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); + float mmptReco = pmeanRecoNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); + float mmptRecoEffCor = pmeanRecoEffcorrNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); + + float mmMultTru = pmeanMultTruNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); + float mmMultReco = pmeanMultRecoNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); + float mmMultRecoEffCor = pmeanMultRecoEffcorrNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); if (std::isfinite(mmptTru)) - std::tie(meanTru[ieta][ipt], c2Tru[ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkTru[ieta][ipt], sumWkTru[ieta][ipt], mmptTru); + std::tie(meanTru[isp][ieta][ipt], c2Tru[isp][ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkTru[isp][ieta][ipt], sumWkTru[isp][ieta][ipt], mmptTru); if (std::isfinite(mmptReco)) - std::tie(meanReco[ieta][ipt], c2Reco[ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkReco[ieta][ipt], sumWkReco[ieta][ipt], mmptReco); + std::tie(meanReco[isp][ieta][ipt], c2Reco[isp][ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkReco[isp][ieta][ipt], sumWkReco[isp][ieta][ipt], mmptReco); if (std::isfinite(mmptRecoEffCor)) - std::tie(meanRecoEffCor[ieta][ipt], c2RecoEffCor[ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkRecoEffCor[ieta][ipt], sumWkRecoEffCor[ieta][ipt], mmptRecoEffCor); - - if (std::isfinite(mmetTru)) - std::tie(meanTruEt[ieta][ipt], c2TruEt[ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkTruEt[ieta][ipt], sumWkTruEt[ieta][ipt], mmetTru); - if (std::isfinite(mmetReco)) - std::tie(meanRecoEt[ieta][ipt], c2RecoEt[ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkRecoEt[ieta][ipt], sumWkRecoEt[ieta][ipt], mmetReco); - if (std::isfinite(mmetRecoEffCor)) - std::tie(meanRecoEffCorEt[ieta][ipt], c2RecoEffCorEt[ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkRecoEffCorEt[ieta][ipt], sumWkRecoEffCorEt[ieta][ipt], mmetRecoEffCor); + std::tie(meanRecoEffCor[isp][ieta][ipt], c2RecoEffCor[isp][ieta][ipt]) = calculateMeanAndC2FromSums(sumPmwkRecoEffCor[isp][ieta][ipt], sumWkRecoEffCor[isp][ieta][ipt], mmptRecoEffCor); + + if (mmptTru != 0.0f) + p1kBarTru[isp][ieta][ipt] = meanTru[isp][ieta][ipt] - mmptTru; + if (mmptReco != 0.0f) + p1kBarReco[isp][ieta][ipt] = meanReco[isp][ieta][ipt] - mmptReco; + if (mmptRecoEffCor != 0.0f) + p1kBarRecoEffCor[isp][ieta][ipt] = meanRecoEffCor[isp][ieta][ipt] - mmptRecoEffCor; + + if (mmMultTru != 0.0f) + p1kBarTruMult[isp][ieta][ipt] = meanTruMult[isp][ieta][ipt] - mmMultTru; + if (mmMultReco != 0.0f) + p1kBarRecoMult[isp][ieta][ipt] = meanRecoMult[isp][ieta][ipt] - mmMultReco; + if (mmMultRecoEffCor != 0.0f) + p1kBarRecoEffCorMult[isp][ieta][ipt] = meanRecoEffCorMult[isp][ieta][ipt] - mmMultRecoEffCor; } } } - if (std::isfinite(c2Tru[0][0])) { - histos.fill(HIST("MCGen/Prof_C2_Cent"), cent, c2Tru[0][0]); - histos.fill(HIST("MCGen/Prof_C2_Mult"), col.multNTracksPV(), c2Tru[0][0]); - } - if (std::isfinite(c2TruEt[0][0])) { - histos.fill(HIST("MCGen/Prof_C2Et_Cent"), cent, c2TruEt[0][0]); - histos.fill(HIST("MCGen/Prof_C2Et_Mult"), col.multNTracksPV(), c2TruEt[0][0]); - } - // "MCReco" - if (std::isfinite(c2Reco[0][0])) { - histos.fill(HIST("MCReco/Prof_C2_Cent"), cent, c2Reco[0][0]); - histos.fill(HIST("MCReco/Prof_C2_Mult"), col.multNTracksPV(), c2Reco[0][0]); - } - if (std::isfinite(c2RecoEt[0][0])) { - histos.fill(HIST("MCReco/Prof_C2Et_Cent"), cent, c2RecoEt[0][0]); - histos.fill(HIST("MCReco/Prof_C2Et_Mult"), col.multNTracksPV(), c2RecoEt[0][0]); - } - if (std::isfinite(c2RecoEffCor[0][0])) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2_Cent"), cent, c2RecoEffCor[0][0]); - histos.fill(HIST("MCRecoEffCorr/Prof_C2_Mult"), col.multNTracksPV(), c2RecoEffCor[0][0]); - } - if (std::isfinite(c2RecoEffCorEt[0][0])) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2Et_Cent"), cent, c2RecoEffCorEt[0][0]); - histos.fill(HIST("MCRecoEffCorr/Prof_C2Et_Mult"), col.multNTracksPV(), c2RecoEffCorEt[0][0]); - } + for (int isp = 0; isp < KNsp; ++isp) { + if (isp == numKInclusive) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec"), cent, sumWkTru[isp][0][0][1]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec"), multPV, sumWkTru[isp][0][0][1]); + if (sumWkTru[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT"), cent, meanTru[isp][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT"), multPV, meanTru[isp][0][0]); + } - if (std::isfinite(sumWkTru[0][0][1])) { - histos.fill(HIST("MCGen/Prof_cent_Nchrec"), cent, sumWkTru[0][0][1]); - histos.fill(HIST("MCGen/Prof_MeanpT_Cent"), cent, meanTru[0][0]); - histos.fill(HIST("MCGen/Prof_MeanpT_Mult"), col.multNTracksPV(), meanTru[0][0]); - } - if (std::isfinite(sumWkTruEt[0][0][1])) { - histos.fill(HIST("MCGen/Prof_MeanEt_Cent"), cent, meanTruEt[0][0]); - histos.fill(HIST("MCGen/Prof_MeanEt_Mult"), col.multNTracksPV(), meanTruEt[0][0]); - } - // "MCReco" - if (std::isfinite(sumWkReco[0][0][1])) { - histos.fill(HIST("MCReco/Prof_cent_Nchrec"), cent, sumWkReco[0][0][1]); - histos.fill(HIST("MCReco/Prof_MeanpT_Cent"), cent, meanReco[0][0]); - histos.fill(HIST("MCReco/Prof_MeanpT_Mult"), col.multNTracksPV(), meanReco[0][0]); - } - if (std::isfinite(sumWkRecoEt[0][0][1])) { - histos.fill(HIST("MCReco/Prof_MeanEt_Cent"), cent, meanRecoEt[0][0]); - histos.fill(HIST("MCReco/Prof_MeanEt_Mult"), col.multNTracksPV(), meanRecoEt[0][0]); - } - // "MCRecoEffCorr" - if (std::isfinite(sumWkRecoEffCor[0][0][1])) { - histos.fill(HIST("MCRecoEffCorr/Prof_cent_Nchrec"), cent, sumWkRecoEffCor[0][0][1]); - histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Cent"), cent, meanRecoEffCor[0][0]); - histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Mult"), col.multNTracksPV(), meanRecoEffCor[0][0]); - } - if (std::isfinite(sumWkRecoEffCorEt[0][0][1])) { - histos.fill(HIST("MCRecoEffCorr/Prof_MeanEt_Cent"), cent, meanRecoEffCorEt[0][0]); - histos.fill(HIST("MCRecoEffCorr/Prof_MeanEt_Mult"), col.multNTracksPV(), meanRecoEffCorEt[0][0]); - } + } else if (isp == numKPion) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec_Pi"), cent, sumWkTru[isp][0][0][1]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec_Pi"), multPV, sumWkTru[isp][0][0][1]); - for (int ieta = 0; ieta < KNEta; ++ieta) { - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (std::isfinite(sumWkTru[ieta][ipt][1])) - histos.fill(HIST("pmeanTruNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, meanTru[ieta][ipt]); - if (std::isfinite(sumWkReco[ieta][ipt][1])) - histos.fill(HIST("pmeanRecoNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, meanReco[ieta][ipt]); - if (std::isfinite(sumWkRecoEffCor[ieta][ipt][1])) - histos.fill(HIST("pmeanRecoEffcorrNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, meanRecoEffCor[ieta][ipt]); - if (std::isfinite(sumWkTruEt[ieta][ipt][1])) - histos.fill(HIST("pmeanEtTruNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, meanTruEt[ieta][ipt]); - if (std::isfinite(sumWkRecoEt[ieta][ipt][1])) - histos.fill(HIST("pmeanEtRecoNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, meanRecoEt[ieta][ipt]); - if (std::isfinite(sumWkRecoEffCorEt[ieta][ipt][1])) - histos.fill(HIST("pmeanEtRecoEffcorrNchEtabinPtbin"), col.multNTracksPV(), ieta, ipt, meanRecoEffCorEt[ieta][ipt]); - } - } + if (sumWkTru[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT_Pi"), cent, meanTru[isp][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT_Pi"), multPV, meanTru[isp][0][0]); + } - float p1kBarTru[KNEta][KNpT]{}, p1kBarReco[KNEta][KNpT]{}, p1kBarRecoEffCor[KNEta][KNpT]{}; - float p1kBarTruEt[KNEta][KNpT]{}, p1kBarRecoEt[KNEta][KNpT]{}, p1kBarRecoEffCorEt[KNEta][KNpT]{}; - for (int ieta = 0; ieta < KNEta; ++ieta) { - for (int ipt = 0; ipt < KNpT; ++ipt) { - const int ibx = pmeanTruNchEtabinPtbinStep2->GetXaxis()->FindBin(col.multNTracksPV()); - const int iby = ieta + 1; - const int ibz = ipt + 1; + } else if (isp == numKKaon) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec_Ka"), cent, sumWkTru[isp][0][0][1]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec_Ka"), multPV, sumWkTru[isp][0][0][1]); - float mmptTru = pmeanTruNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmptReco = pmeanRecoNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmptRecoEffCor = pmeanRecoEffcorrNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmetTru = pmeanEtTruNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmetReco = pmeanEtRecoNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmetRecoEffCor = pmeanEtRecoEffcorrNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - - if (mmptTru != 0.0f) - p1kBarTru[ieta][ipt] = meanTru[ieta][ipt] - mmptTru; - if (mmptReco != 0.0f) - p1kBarReco[ieta][ipt] = meanReco[ieta][ipt] - mmptReco; - if (mmptRecoEffCor != 0.0f) - p1kBarRecoEffCor[ieta][ipt] = meanRecoEffCor[ieta][ipt] - mmptRecoEffCor; - - if (mmetTru != 0.0f) - p1kBarTruEt[ieta][ipt] = meanTruEt[ieta][ipt] - mmetTru; - if (mmetReco != 0.0f) - p1kBarRecoEt[ieta][ipt] = meanRecoEt[ieta][ipt] - mmetReco; - if (mmetRecoEffCor != 0.0f) - p1kBarRecoEffCorEt[ieta][ipt] = meanRecoEffCorEt[ieta][ipt] - mmetRecoEffCor; - } - } + if (sumWkTru[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT_Ka"), cent, meanTru[isp][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT_Ka"), multPV, meanTru[isp][0][0]); + } + } else if (isp == numKProton) { + histos.fill(HIST("MCGen/Prof_Cent_Nchrec_Pr"), cent, sumWkTru[isp][0][0][1]); + histos.fill(HIST("MCGen/Prof_Mult_Nchrec_Pr"), multPV, sumWkTru[isp][0][0][1]); - // 1D Covariance (vs eta) - for (int ietaA = 1; ietaA <= (KNEta - 1) / 2; ++ietaA) { - int ietaC = KNEta - ietaA; - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - { - const int ipt = 0; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCGen/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCGen/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCGen/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); + if (sumWkTru[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCGen/Prof_Cent_MeanpT_Pr"), cent, meanTru[isp][0][0]); + histos.fill(HIST("MCGen/Prof_Mult_MeanpT_Pr"), multPV, meanTru[isp][0][0]); } } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCGen/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCGen/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCGen/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + } + + for (int isp = 0; isp < KNsp; ++isp) { + if (isp == numKInclusive) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec"), cent, sumWkReco[isp][0][0][1]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec"), multPV, sumWkReco[isp][0][0][1]); + if (sumWkReco[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT"), cent, meanReco[isp][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT"), multPV, meanReco[isp][0][0]); } - } - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCGen/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt2_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCGen/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCGen/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCGen/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + + } else if (isp == numKPion) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec_Pi"), cent, sumWkReco[isp][0][0][1]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec_Pi"), multPV, sumWkReco[isp][0][0][1]); + + if (sumWkReco[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT_Pi"), cent, meanReco[isp][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT_Pi"), multPV, meanReco[isp][0][0]); } - } - } - for (int ietaA = 1; ietaA < KNEta; ++ietaA) { - for (int ietaC = 1; ietaC < KNEta; ++ietaC) { - float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCGen/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCGen/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCGen/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCGen/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarTru[ietaA][ipt] * p1kBarTru[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCGen/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarTruEt[ietaA][ipt] * p1kBarTruEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCGen/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + } else if (isp == numKKaon) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec_Ka"), cent, sumWkReco[isp][0][0][1]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec_Ka"), multPV, sumWkReco[isp][0][0][1]); + + if (sumWkReco[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT_Ka"), cent, meanReco[isp][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT_Ka"), multPV, meanReco[isp][0][0]); + } + } else if (isp == numKProton) { + histos.fill(HIST("MCReco/Prof_Cent_Nchrec_Pr"), cent, sumWkReco[isp][0][0][1]); + histos.fill(HIST("MCReco/Prof_Mult_Nchrec_Pr"), multPV, sumWkReco[isp][0][0][1]); + if (sumWkReco[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCReco/Prof_Cent_MeanpT_Pr"), cent, meanReco[isp][0][0]); + histos.fill(HIST("MCReco/Prof_Mult_MeanpT_Pr"), multPV, meanReco[isp][0][0]); } } - } - for (int ietaA = 1; ietaA <= (KNEta - 1) / 2; ++ietaA) { - int ietaC = KNEta - ietaA; - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCReco/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCReco/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCReco/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); + if (isp == numKInclusive) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec"), cent, sumWkRecoEffCor[isp][0][0][1]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec"), multPV, sumWkRecoEffCor[isp][0][0][1]); + if (sumWkRecoEffCor[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT"), cent, meanRecoEffCor[isp][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT"), multPV, meanRecoEffCor[isp][0][0]); } - } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCReco/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt1_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCReco/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCReco/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); + } else if (isp == numKPion) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec_Pi"), cent, sumWkRecoEffCor[isp][0][0][1]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec_Pi"), multPV, sumWkRecoEffCor[isp][0][0][1]); + if (sumWkRecoEffCor[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT_Pi"), cent, meanRecoEffCor[isp][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT_Pi"), multPV, meanRecoEffCor[isp][0][0]); } - } - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCReco/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt2_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCReco/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCReco/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCReco/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + } else if (isp == numKKaon) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec_Ka"), cent, sumWkRecoEffCor[isp][0][0][1]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec_Ka"), multPV, sumWkRecoEffCor[isp][0][0][1]); + if (sumWkRecoEffCor[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT_Ka"), cent, meanRecoEffCor[isp][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT_Ka"), multPV, meanRecoEffCor[isp][0][0]); + } + } else if (isp == numKProton) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_Nchrec_Pr"), cent, sumWkRecoEffCor[isp][0][0][1]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_Nchrec_Pr"), multPV, sumWkRecoEffCor[isp][0][0][1]); + if (sumWkRecoEffCor[isp][0][0][1] > 1.0f) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cent_MeanpT_Pr"), cent, meanRecoEffCor[isp][0][0]); + histos.fill(HIST("MCRecoEffCorr/Prof_Mult_MeanpT_Pr"), multPV, meanRecoEffCor[isp][0][0]); } } } - for (int ietaA = 1; ietaA < KNEta; ++ietaA) { - for (int ietaC = 1; ietaC < KNEta; ++ietaC) { - float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCReco/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCReco/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCReco/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCReco/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarReco[ietaA][ipt] * p1kBarReco[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCReco/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEt[ietaA][ipt] * p1kBarRecoEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCReco/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + // --- 3. Fill 1D Profiles: Gen, Reco, and EffCorr Levels --- + for (int ieta = 0; ieta < KNEta; ++ieta) { + for (int ipt = 0; ipt < KNpT; ++ipt) { + for (int isp = 0; isp < KNsp; ++isp) { + + if (isp == numKInclusive) { // Inclusive (No suffix) + // --- MCGen (Truth) --- + if (std::isfinite(meanTru[0][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_MeanpT_Cent_etabin_ptbin"), cent, ieta, ipt, meanTru[0][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_MeanpT_Mult_etabin_ptbin"), col.multNTracksPV(), ieta, ipt, meanTru[0][ieta][ipt]); + } + if (std::isfinite(c2Tru[0][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_C2_Cent_etabin_ptbin"), cent, ieta, ipt, c2Tru[0][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_C2_Mult_etabin_ptbin"), col.multNTracksPV(), ieta, ipt, c2Tru[0][ieta][ipt]); + } + // --- MCReco --- + if (std::isfinite(meanReco[0][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_MeanpT_Cent_etabin_ptbin"), cent, ieta, ipt, meanReco[0][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_MeanpT_Mult_etabin_ptbin"), col.multNTracksPV(), ieta, ipt, meanReco[0][ieta][ipt]); + } + if (std::isfinite(c2Reco[0][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_C2_Cent_etabin_ptbin"), cent, ieta, ipt, c2Reco[0][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_C2_Mult_etabin_ptbin"), col.multNTracksPV(), ieta, ipt, c2Reco[0][ieta][ipt]); + } + // --- MCRecoEffCorr --- + if (std::isfinite(meanRecoEffCor[0][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Cent_etabin_ptbin"), cent, ieta, ipt, meanRecoEffCor[0][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Mult_etabin_ptbin"), col.multNTracksPV(), ieta, ipt, meanRecoEffCor[0][ieta][ipt]); + } + if (std::isfinite(c2RecoEffCor[0][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Cent_etabin_ptbin"), cent, ieta, ipt, c2RecoEffCor[0][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Mult_etabin_ptbin"), col.multNTracksPV(), ieta, ipt, c2RecoEffCor[0][ieta][ipt]); + } + + } else if (isp == numKPion) { // Pions (_Pi) + // --- MCGen (Truth) --- + if (std::isfinite(meanTru[1][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_MeanpT_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, meanTru[1][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_MeanpT_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ieta, ipt, meanTru[1][ieta][ipt]); + } + if (std::isfinite(c2Tru[1][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_C2_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, c2Tru[1][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_C2_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ieta, ipt, c2Tru[1][ieta][ipt]); + } + // --- MCReco --- + if (std::isfinite(meanReco[1][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_MeanpT_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, meanReco[1][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_MeanpT_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ieta, ipt, meanReco[1][ieta][ipt]); + } + if (std::isfinite(c2Reco[1][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_C2_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, c2Reco[1][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_C2_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ieta, ipt, c2Reco[1][ieta][ipt]); + } + // --- MCRecoEffCorr --- + if (std::isfinite(meanRecoEffCor[1][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, meanRecoEffCor[1][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ieta, ipt, meanRecoEffCor[1][ieta][ipt]); + } + if (std::isfinite(c2RecoEffCor[1][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, c2RecoEffCor[1][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ieta, ipt, c2RecoEffCor[1][ieta][ipt]); + } + + } else if (isp == numKKaon) { // Kaons (_Ka) + // --- MCGen (Truth) --- + if (std::isfinite(meanTru[2][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_MeanpT_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, meanTru[2][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_MeanpT_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ieta, ipt, meanTru[2][ieta][ipt]); + } + if (std::isfinite(c2Tru[2][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_C2_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, c2Tru[2][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_C2_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ieta, ipt, c2Tru[2][ieta][ipt]); + } + // --- MCReco --- + if (std::isfinite(meanReco[2][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_MeanpT_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, meanReco[2][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_MeanpT_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ieta, ipt, meanReco[2][ieta][ipt]); + } + if (std::isfinite(c2Reco[2][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_C2_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, c2Reco[2][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_C2_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ieta, ipt, c2Reco[2][ieta][ipt]); + } + // --- MCRecoEffCorr --- + if (std::isfinite(meanRecoEffCor[2][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, meanRecoEffCor[2][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ieta, ipt, meanRecoEffCor[2][ieta][ipt]); + } + if (std::isfinite(c2RecoEffCor[2][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, c2RecoEffCor[2][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ieta, ipt, c2RecoEffCor[2][ieta][ipt]); + } + + } else if (isp == numKProton) { // Protons (_Pr) + // --- MCGen (Truth) --- + if (std::isfinite(meanTru[3][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_MeanpT_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, meanTru[3][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_MeanpT_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ieta, ipt, meanTru[3][ieta][ipt]); + } + if (std::isfinite(c2Tru[3][ieta][ipt])) { + histos.fill(HIST("MCGen/Prof_C2_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, c2Tru[3][ieta][ipt]); + histos.fill(HIST("MCGen/Prof_C2_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ieta, ipt, c2Tru[3][ieta][ipt]); + } + // --- MCReco --- + if (std::isfinite(meanReco[3][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_MeanpT_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, meanReco[3][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_MeanpT_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ieta, ipt, meanReco[3][ieta][ipt]); + } + if (std::isfinite(c2Reco[3][ieta][ipt])) { + histos.fill(HIST("MCReco/Prof_C2_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, c2Reco[3][ieta][ipt]); + histos.fill(HIST("MCReco/Prof_C2_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ieta, ipt, c2Reco[3][ieta][ipt]); + } + // --- MCRecoEffCorr --- + if (std::isfinite(meanRecoEffCor[3][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, meanRecoEffCor[3][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_MeanpT_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ieta, ipt, meanRecoEffCor[3][ieta][ipt]); + } + if (std::isfinite(c2RecoEffCor[3][ieta][ipt])) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, c2RecoEffCor[3][ieta][ipt]); + histos.fill(HIST("MCRecoEffCorr/Prof_C2_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ieta, ipt, c2RecoEffCor[3][ieta][ipt]); + } + } } } } + // --- 4. Symmetric Sub-Event (1D) Covariances --- for (int ietaA = 1; ietaA <= (KNEta - 1) / 2; ++ietaA) { int ietaC = KNEta - ietaA; - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_CovEt_Eta"), valy, c2SubEt); - } - } + for (int ipt = 0; ipt < KNpT; ++ipt) { + for (int isp = 0; isp < KNsp; ++isp) { + float c2SubTru = p1kBarTru[isp][ietaA][ipt] * p1kBarTru[isp][ietaC][ipt]; + float c2SubReco = p1kBarReco[isp][ietaA][ipt] * p1kBarReco[isp][ietaC][ipt]; + float c2SubRecoEffCor = p1kBarRecoEffCor[isp][ietaA][ipt] * p1kBarRecoEffCor[isp][ietaC][ipt]; + + float covTru = p1kBarTruMult[isp][ietaA][ipt] * p1kBarTru[isp][ietaC][ipt]; + float covReco = p1kBarRecoMult[isp][ietaA][ipt] * p1kBarReco[isp][ietaC][ipt]; + float covRecoEffCor = p1kBarRecoEffCorMult[isp][ietaA][ipt] * p1kBarRecoEffCor[isp][ietaC][ipt]; + + if (isp == numKInclusive) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_C2Sub_Cent_etabin_ptbin"), cent, ietaA, ipt, c2SubTru); + histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_C2Sub_Cent_etabin_ptbin"), cent, ietaA, ipt, c2SubReco); + histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Cent_etabin_ptbin"), cent, ietaA, ipt, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) { + histos.fill(HIST("MCGen/Prof_Cov_Cent_etabin_ptbin"), cent, ietaA, ipt, covTru); + histos.fill(HIST("MCGen/Prof_Cov_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, covTru); + } + if (std::isfinite(covReco)) { + histos.fill(HIST("MCReco/Prof_Cov_Cent_etabin_ptbin"), cent, ietaA, ipt, covReco); + histos.fill(HIST("MCReco/Prof_Cov_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, covReco); + } + if (std::isfinite(covRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Cent_etabin_ptbin"), cent, ietaA, ipt, covRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, covRecoEffCor); + } - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_CovEt_Eta"), valy, c2SubEt); - } - } + } else if (isp == numKPion) { // Pion + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_C2Sub_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, c2SubTru); + histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ietaA, ipt, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_C2Sub_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, c2SubReco); + histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ietaA, ipt, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ietaA, ipt, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) { + histos.fill(HIST("MCGen/Prof_Cov_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, covTru); + histos.fill(HIST("MCGen/Prof_Cov_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ietaA, ipt, covTru); + } + if (std::isfinite(covReco)) { + histos.fill(HIST("MCReco/Prof_Cov_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, covReco); + histos.fill(HIST("MCReco/Prof_Cov_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ietaA, ipt, covReco); + } + if (std::isfinite(covRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, covRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Mult_etabin_ptbin_Pi"), col.multNTracksPV(), ietaA, ipt, covRecoEffCor); + } - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2Sub); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("MCRecoEffCorr/Prof_C2EtSub_Mult_etabin_ptbin"), col.multNTracksPV(), ietaA, ipt, c2SubEt); - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + } else if (isp == numKKaon) { // Kaon + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_C2Sub_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, c2SubTru); + histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ietaA, ipt, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_C2Sub_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, c2SubReco); + histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ietaA, ipt, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ietaA, ipt, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) { + histos.fill(HIST("MCGen/Prof_Cov_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, covTru); + histos.fill(HIST("MCGen/Prof_Cov_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ietaA, ipt, covTru); + } + if (std::isfinite(covReco)) { + histos.fill(HIST("MCReco/Prof_Cov_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, covReco); + histos.fill(HIST("MCReco/Prof_Cov_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ietaA, ipt, covReco); + } + if (std::isfinite(covRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, covRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Mult_etabin_ptbin_Ka"), col.multNTracksPV(), ietaA, ipt, covRecoEffCor); + } + } else if (isp == numKProton) { // Proton + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_C2Sub_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, c2SubTru); + histos.fill(HIST("MCGen/Prof_C2Sub_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ietaA, ipt, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_C2Sub_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, c2SubReco); + histos.fill(HIST("MCReco/Prof_C2Sub_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ietaA, ipt, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_C2Sub_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ietaA, ipt, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) { + histos.fill(HIST("MCGen/Prof_Cov_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, covTru); + histos.fill(HIST("MCGen/Prof_Cov_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ietaA, ipt, covTru); + } + if (std::isfinite(covReco)) { + histos.fill(HIST("MCReco/Prof_Cov_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, covReco); + histos.fill(HIST("MCReco/Prof_Cov_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ietaA, ipt, covReco); + } + if (std::isfinite(covRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, covRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_Cov_Mult_etabin_ptbin_Pr"), col.multNTracksPV(), ietaA, ipt, covRecoEffCor); + } + } } } } + // --- 5. Full 2D Covariances & GapSum2D Profiles --- for (int ietaA = 1; ietaA < KNEta; ++ietaA) { - for (int ietaC = 1; ietaC < KNEta; ++ietaC) { - float valx = 0.5f * (etaLw[ietaA] + etaUp[ietaA]); - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - - // ipt = 0 - { - const int ipt = 0; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - - // ipt = 1 - { - const int ipt = 1; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); - } - - // ipt = 2 - { - const int ipt = 2; - float c2Sub = p1kBarRecoEffCor[ietaA][ipt] * p1kBarRecoEffCor[ietaC][ipt]; - if (std::isfinite(c2Sub)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, c2Sub); - float c2SubEt = p1kBarRecoEffCorEt[ietaA][ipt] * p1kBarRecoEffCorEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) - histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2EtSub2D_Mult_etaA_etaC"), cent, valx, valy, c2SubEt); + for (int ietaB = 1; ietaB < KNEta; ++ietaB) { + + // Gap and Sum calculations + float etaValA = (etaLw[ietaA] + etaUp[ietaA]) / 2.0f; + float etaValB = (etaLw[ietaB] + etaUp[ietaB]) / 2.0f; + float gap = etaValA - etaValB; + float sum = (etaValA + etaValB) / 2.0f; + + for (int ipt = 0; ipt < KNpT; ++ipt) { + for (int isp = 0; isp < KNsp; ++isp) { + + float c2SubTru = p1kBarTru[isp][ietaA][ipt] * p1kBarTru[isp][ietaB][ipt]; + float c2SubReco = p1kBarReco[isp][ietaA][ipt] * p1kBarReco[isp][ietaB][ipt]; + float c2SubRecoEffCor = p1kBarRecoEffCor[isp][ietaA][ipt] * p1kBarRecoEffCor[isp][ietaB][ipt]; + + float covTru = p1kBarTruMult[isp][ietaA][ipt] * p1kBarTru[isp][ietaB][ipt]; + float covReco = p1kBarRecoMult[isp][ietaA][ipt] * p1kBarReco[isp][ietaB][ipt]; + float covRecoEffCor = p1kBarRecoEffCorMult[isp][ietaA][ipt] * p1kBarRecoEffCor[isp][ietaB][ipt]; + + if (isp == numKInclusive) { // Inclusive + if (ipt == 0) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt0_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt0_GapSum2D"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt0_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt0_GapSum2D"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_GapSum2D"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt0_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt0_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt1_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt1_GapSum2D"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt1_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt1_GapSum2D"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_GapSum2D"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt1_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt1_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt2_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt2_GapSum2D"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt2_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt2_GapSum2D"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_GapSum2D"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt2_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt2_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, covRecoEffCor); + } + + } else if (isp == numKPion) { // Pion + if (ipt == 0) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt0_GapSum2D_Pi"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt0_GapSum2D_Pi"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_GapSum2D_Pi"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt0_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt0_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt1_GapSum2D_Pi"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt1_GapSum2D_Pi"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_GapSum2D_Pi"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt1_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt1_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt2_GapSum2D_Pi"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt2_GapSum2D_Pi"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_GapSum2D_Pi"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt2_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt2_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, covRecoEffCor); + } + } else if (isp == numKKaon) { // Kaon + if (ipt == 0) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt0_GapSum2D_Ka"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt0_GapSum2D_Ka"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_GapSum2D_Ka"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt0_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt0_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt1_GapSum2D_Ka"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt1_GapSum2D_Ka"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_GapSum2D_Ka"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt1_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt1_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt2_GapSum2D_Ka"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt2_GapSum2D_Ka"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_GapSum2D_Ka"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt2_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt2_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, covRecoEffCor); + } + } else if (isp == numKProton) { // Proton + if (ipt == 0) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt0_GapSum2D_Pr"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt0_GapSum2D_Pr"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_GapSum2D_Pr"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt0_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt0_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt0_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt1_GapSum2D_Pr"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt1_GapSum2D_Pr"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_GapSum2D_Pr"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt1_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt1_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt1_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covRecoEffCor); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2SubTru)) { + histos.fill(HIST("MCGen/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubTru); + histos.fill(HIST("MCGen/Prof_ipt2_GapSum2D_Pr"), cent, gap, sum, c2SubTru); + } + if (std::isfinite(c2SubReco)) { + histos.fill(HIST("MCReco/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubReco); + histos.fill(HIST("MCReco/Prof_ipt2_GapSum2D_Pr"), cent, gap, sum, c2SubReco); + } + if (std::isfinite(c2SubRecoEffCor)) { + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2SubRecoEffCor); + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_GapSum2D_Pr"), cent, gap, sum, c2SubRecoEffCor); + } + if (std::isfinite(covTru)) + histos.fill(HIST("MCGen/Prof_ipt2_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covTru); + if (std::isfinite(covReco)) + histos.fill(HIST("MCReco/Prof_ipt2_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covReco); + if (std::isfinite(covRecoEffCor)) + histos.fill(HIST("MCRecoEffCorr/Prof_ipt2_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, covRecoEffCor); + } + } + } } } } - } - } - LOGF(info, "FINISHED RUNNING processMCFluc (pT + Et)"); + } // colSlice + } // mcColl + LOGF(info, "FINISHED RUNNING processMCFluc"); } - PROCESS_SWITCH(RadialFlowDecorr, processMCFluc, "process MC to calculate pt/Et fluc", cfgRunMCFluc); + PROCESS_SWITCH(RadialFlowDecorr, processMCFluc, "process MC to calculate pt fluc", cfgRunMCFluc); - void processGetFlat(AodCollisionsSel::iterator const& coll, aod::BCsWithTimestamps const&, AodTracksSel const& tracks) + void processGetDataFlat(AodCollisionsSel::iterator const& coll, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcsData*/, AodTracksSel const& tracks) { + histos.fill(HIST("hVtxZ"), coll.posZ()); if (!isEventSelected(coll)) return; float cent = getCentrality(coll); if (cent > KCentMax) return; + + histos.fill(HIST("hZvtx_after_sel"), coll.posZ()); + histos.fill(HIST("hCentrality"), cent); + + histos.fill(HIST("Hist2D_globalTracks_PVTracks"), coll.multNTracksPV(), tracks.size()); + histos.fill(HIST("Hist2D_cent_nch"), tracks.size(), cent); + + int ntrk = 0; + float vz = coll.posZ(); + for (const auto& track : tracks) { if (!isTrackSelected(track)) continue; + float p = track.p(); + float pt = track.pt(); float eta = track.eta(); float phi = track.phi(); + auto sign = track.sign(); + if (p < KFloatEpsilon) continue; - histos.fill(HIST("hCentEtaPhi"), cent, eta, phi); - const bool isPion = selectionPion(track); - const bool isKaon = selectionKaon(track); - const bool isProton = selectionProton(track); - if (isPion || isKaon || isProton) { - histos.fill(HIST("hCentEtaPhi_PID"), cent, eta, phi); + + // Count tracks in the primary eta acceptance + if (eta > etaLw[0] && eta < etaUp[0]) + ntrk++; + + // Define species array (0: Inclusive, 1: Pion, 2: Kaon, 3: Proton) + bool isSpecies[KNsp] = {true, selectionPion(track), selectionKaon(track), selectionProton(track)}; + + for (int isp = 0; isp < KNsp; ++isp) { + if (!isSpecies[isp]) + continue; + + // Fetch efficiency specifically for this particle species + float eff = getEfficiency(coll.multNTracksPV(), pt, eta, static_cast(isp), 0, cfgEff); + float fake = getEfficiency(coll.multNTracksPV(), pt, eta, static_cast(isp), 1, cfgEff); + float w = (1.0 - fake) / eff; + + if (!std::isfinite(w) || w <= KFloatEpsilon || eff <= KFloatEpsilon) + continue; + + // Unrolled THnSparse / QA Fills + if (isp == numKInclusive) { + histos.fill(HIST("hEtaPhiReco"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd"), vz, sign, pt, eta, phi, w); + } else if (isp == numKPion) { // Pion + histos.fill(HIST("hEtaPhiReco_Pi"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pi"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Pi"), vz, sign, pt, eta, phi, w); + } else if (isp == numKKaon) { // Kaon + histos.fill(HIST("hEtaPhiReco_Ka"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Ka"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Ka"), vz, sign, pt, eta, phi, w); + } else if (isp == numKProton) { // Proton + histos.fill(HIST("hEtaPhiReco_Pr"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pr"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Pr"), vz, sign, pt, eta, phi, w); + } + } + } + + histos.fill(HIST("hCentnTrk"), cent, ntrk); + histos.fill(HIST("hCentnTrkPV"), cent, coll.multNTracksPV()); + + if (cfgZDC) { + const auto& foundBC = coll.foundBC_as(); + if (!foundBC.has_zdc()) { + return; } + auto zdc = foundBC.zdc(); + auto zdcAmp = zdc.energyCommonZNA() + zdc.energyCommonZNC(); + histos.fill(HIST("hnTrkPVZDC"), coll.multNTracksPV(), zdcAmp); + histos.fill(HIST("hNchZDC"), ntrk, zdcAmp); } } - PROCESS_SWITCH(RadialFlowDecorr, processGetFlat, "process real data to calculate mean pT and Et", cfgRunGetFlat); + PROCESS_SWITCH(RadialFlowDecorr, processGetDataFlat, "process data to calculate Flattening maps", cfgRunGetDataFlat); - void processDataMean(AodCollisionsSel::iterator const& coll, aod::BCsWithTimestamps const&, AodTracksSel const& tracks) + void processDataMean(AodCollisionsSel::iterator const& coll, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcsData*/, AodTracksSel const& tracks) { - float sumWi[KNEta][KNpT]{}, sumWipti[KNEta][KNpT]{}; - float sumWiEt[KNEta][KNpT]{}, sumWiEtVal[KNEta][KNpT]{}; + // Expanded to 4 species (isp = 0: Incl, 1: Pi, 2: Ka, 3: Pr) + double sumWi[KNsp][KNEta][KNpT]{}, sumWipti[KNsp][KNEta][KNpT]{}; + if (!isEventSelected(coll)) return; @@ -2026,161 +2693,260 @@ struct RadialFlowDecorr { histos.fill(HIST("Hist2D_globalTracks_PVTracks"), coll.multNTracksPV(), tracks.size()); histos.fill(HIST("Hist2D_cent_nch"), tracks.size(), cent); + float vz = coll.posZ(); + for (const auto& track : tracks) { if (!isTrackSelected(track)) continue; + float pt = track.pt(); float eta = track.eta(); float p = track.p(); float phi = track.phi(); + auto sign = track.sign(); + if (p < KFloatEpsilon) continue; + histos.fill(HIST("hP"), p); histos.fill(HIST("hPt"), pt); histos.fill(HIST("hEta"), eta); - histos.fill(HIST("hPhi"), track.phi()); + histos.fill(HIST("hPhi"), phi); - float effIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 0); - float fakeIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; - if (!std::isfinite(wIncl) || wIncl <= KFloatEpsilon || effIncl <= KFloatEpsilon) - continue; - - histos.fill(HIST("hCentEtaPhi"), cent, eta, track.phi()); - histos.fill(HIST("hCentEtaPhiWtd"), cent, eta, track.phi(), flatWeightIncl); + // Define species array + bool isSpecies[KNsp] = {true, selectionPion(track), selectionKaon(track), selectionProton(track)}; - for (int ieta = 0; ieta < KNEta; ++ieta) { - if (eta <= etaLw[ieta] || eta > etaUp[ieta]) + for (int isp = 0; isp < KNsp; ++isp) { + if (!isSpecies[isp]) continue; - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (pt <= pTLw[ipt] || pt > pTUp[ipt]) - continue; - sumWi[ieta][ipt] += wIncl; - sumWipti[ieta][ipt] += wIncl * pt; - } - } - const bool isPion = selectionPion(track); - const bool isKaon = selectionKaon(track); - const bool isProton = selectionProton(track); - if (isPion || isKaon || isProton) { + float eff = getEfficiency(coll.multNTracksPV(), pt, eta, static_cast(isp), 0, cfgEff); + float fake = getEfficiency(coll.multNTracksPV(), pt, eta, static_cast(isp), 1, cfgEff); + float flatWeight = getFlatteningWeight(vz, sign, pt, eta, phi, static_cast(isp), cfgFlat); + float w = flatWeight * (1.0 - fake) / eff; - float effPid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 0); - float fakePid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); - float wPid = flatWeightPid * (1.0 - fakePid) / effPid; - if (!std::isfinite(wPid) || wPid <= KFloatEpsilon || effPid <= KFloatEpsilon) + if (!std::isfinite(w) || w <= KFloatEpsilon || eff <= KFloatEpsilon) continue; - histos.fill(HIST("hCentEtaPhiWtd_PID"), cent, eta, track.phi(), flatWeightPid); - float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus - : o2::constants::physics::MassProton; - float energy = std::sqrt(p * p + m * m); - float et = energy * (pt / p); // E_T = E * sin(theta) + // Unrolled THnSparse / QA Fills + if (isp == numKInclusive) { + histos.fill(HIST("hEtaPhiReco"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd"), vz, sign, pt, eta, phi, w); + } else if (isp == numKPion) { // Pion + histos.fill(HIST("hEtaPhiReco_Pi"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pi"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Pi"), vz, sign, pt, eta, phi, w); + } else if (isp == numKKaon) { // Kaon + histos.fill(HIST("hEtaPhiReco_Ka"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Ka"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Ka"), vz, sign, pt, eta, phi, w); + } else if (isp == numKProton) { // Proton + histos.fill(HIST("hEtaPhiReco_Pr"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pr"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Pr"), vz, sign, pt, eta, phi, w); + } + + // Accumulate sum for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) continue; for (int ipt = 0; ipt < KNpT; ++ipt) { if (pt <= pTLw[ipt] || pt > pTUp[ipt]) continue; - sumWiEt[ieta][ipt] += wPid; - sumWiEtVal[ieta][ipt] += wPid * et; + sumWi[isp][ieta][ipt] += w; + sumWipti[isp][ieta][ipt] += w * pt; } } } } - histos.fill(HIST("Prof_cent_Nchrec"), cent, sumWi[0][0]); - if (std::isfinite(sumWi[0][0])) - histos.fill(HIST("Prof_MeanpT_Cent"), cent, sumWipti[0][0] / sumWi[0][0]); - if (std::isfinite(sumWiEt[0][0])) - histos.fill(HIST("Prof_MeanEt_Cent"), cent, sumWiEtVal[0][0] / sumWiEt[0][0]); - for (int ieta = 0; ieta < KNEta; ++ieta) { - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (std::isfinite(sumWi[ieta][ipt])) - histos.fill(HIST("pmean_nch_etabin_ptbin"), coll.multNTracksPV(), ieta, ipt, sumWipti[ieta][ipt] / sumWi[ieta][ipt]); - if (std::isfinite(sumWiEt[ieta][ipt])) - histos.fill(HIST("pmeanEt_nch_etabin_ptbin"), coll.multNTracksPV(), ieta, ipt, sumWiEtVal[ieta][ipt] / sumWiEt[ieta][ipt]); + // Full Event Means + for (int isp = 0; isp < KNsp; ++isp) { + if (isp == numKInclusive) { + histos.fill(HIST("Prof_Cent_Nchrec"), cent, sumWi[0][0][0]); + histos.fill(HIST("Prof_Mult_Nchrec"), coll.multNTracksPV(), sumWi[0][0][0]); + if (sumWi[0][0][0] > 1.0f) + histos.fill(HIST("Prof_Cent_MeanpT"), cent, sumWipti[0][0][0] / sumWi[0][0][0]); + } else if (isp == numKPion) { + histos.fill(HIST("Prof_Cent_Nchrec_Pi"), cent, sumWi[1][0][0]); + histos.fill(HIST("Prof_Mult_Nchrec_Pi"), coll.multNTracksPV(), sumWi[1][0][0]); + + if (sumWi[1][0][0] > 1.0f) + histos.fill(HIST("Prof_Cent_MeanpT_Pi"), cent, sumWipti[1][0][0] / sumWi[1][0][0]); + } else if (isp == numKKaon) { + histos.fill(HIST("Prof_Cent_Nchrec_Ka"), cent, sumWi[2][0][0]); + histos.fill(HIST("Prof_Mult_Nchrec_Ka"), coll.multNTracksPV(), sumWi[2][0][0]); + + if (sumWi[2][0][0] > 1.0f) + histos.fill(HIST("Prof_Cent_MeanpT_Ka"), cent, sumWipti[2][0][0] / sumWi[2][0][0]); + } else if (isp == numKProton) { + histos.fill(HIST("Prof_Cent_Nchrec_Pr"), cent, sumWi[3][0][0]); + histos.fill(HIST("Prof_Mult_Nchrec_Pr"), coll.multNTracksPV(), sumWi[3][0][0]); + + if (sumWi[3][0][0] > 1.0f) + histos.fill(HIST("Prof_Cent_MeanpT_Pr"), cent, sumWipti[3][0][0] / sumWi[3][0][0]); + } + } + + // Kinematic Bin Means (1D and 2D Sub-event) + for (int ietaA = 0; ietaA < KNEta; ++ietaA) { + for (int ietaB = 0; ietaB < KNEta; ++ietaB) { + for (int ipt = 0; ipt < KNpT; ++ipt) { + for (int isp = 0; isp < KNsp; ++isp) { + + // --- 2D Sub-Event Calculations --- + double wCorrAB = sumWi[isp][ietaA][ipt] + sumWi[isp][ietaB][ipt]; + if (wCorrAB > 0) { + float mptsub = (sumWipti[isp][ietaA][ipt] + sumWipti[isp][ietaB][ipt]) / wCorrAB; + if (isp == numKInclusive) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2"), cent, ietaA, ietaB, mptsub); + } else if (isp == numKPion) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Pi"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Pi"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Pi"), cent, ietaA, ietaB, mptsub); + } else if (isp == numKKaon) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Ka"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Ka"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Ka"), cent, ietaA, ietaB, mptsub); + } else if (isp == numKProton) { + if (ipt == 0) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt0_Pr"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 2) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt1_Pr"), cent, ietaA, ietaB, mptsub); + if (ipt == KNpT - 1) + histos.fill(HIST("Prof2D_MeanpT_Sub_ipt2_Pr"), cent, ietaA, ietaB, mptsub); + } + } + + // --- 1D Individual Bin Calculations (Only do when A == B to avoid overfilling) --- + if (ietaA == ietaB) { + double mpt = sumWipti[isp][ietaA][ipt] / sumWi[isp][ietaA][ipt]; + if (sumWi[isp][ietaA][ipt] >= 1.0f && std::isfinite(mpt)) { + if (isp == numKInclusive) { + histos.fill(HIST("pmean_nch_etabin_ptbin"), coll.multNTracksPV(), ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_nch_etabin_ptbin"), coll.multNTracksPV(), ietaA, ipt, sumWi[0][ietaA][ipt]); + histos.fill(HIST("pmean_cent_etabin_ptbin"), cent, ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_cent_etabin_ptbin"), cent, ietaA, ipt, sumWi[0][ietaA][ipt]); + } else if (isp == numKPion) { + histos.fill(HIST("pmean_nch_etabin_ptbin_Pi"), coll.multNTracksPV(), ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_nch_etabin_ptbin_Pi"), coll.multNTracksPV(), ietaA, ipt, sumWi[1][ietaA][ipt]); + histos.fill(HIST("pmean_cent_etabin_ptbin_Pi"), cent, ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_cent_etabin_ptbin_Pi"), cent, ietaA, ipt, sumWi[1][ietaA][ipt]); + } else if (isp == numKKaon) { + histos.fill(HIST("pmean_nch_etabin_ptbin_Ka"), coll.multNTracksPV(), ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_nch_etabin_ptbin_Ka"), coll.multNTracksPV(), ietaA, ipt, sumWi[2][ietaA][ipt]); + histos.fill(HIST("pmean_cent_etabin_ptbin_Ka"), cent, ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_cent_etabin_ptbin_Ka"), cent, ietaA, ipt, sumWi[2][ietaA][ipt]); + } else if (isp == numKProton) { + histos.fill(HIST("pmean_nch_etabin_ptbin_Pr"), coll.multNTracksPV(), ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_nch_etabin_ptbin_Pr"), coll.multNTracksPV(), ietaA, ipt, sumWi[3][ietaA][ipt]); + histos.fill(HIST("pmean_cent_etabin_ptbin_Pr"), cent, ietaA, ipt, mpt); + histos.fill(HIST("pmeanMult_cent_etabin_ptbin_Pr"), cent, ietaA, ipt, sumWi[3][ietaA][ipt]); + } + } + } + } + } } } } - PROCESS_SWITCH(RadialFlowDecorr, processDataMean, "process real data to calculate mean pT and Et", cfgRunDataMean); + PROCESS_SWITCH(RadialFlowDecorr, processDataMean, "process data to calculate mean pT", cfgRunDataMean); - void processDataFluc(AodCollisionsSel::iterator const& coll, aod::BCsWithTimestamps const&, AodTracksSel const& tracks) + void processDataFluc(AodCollisionsSel::iterator const& coll, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcsData*/, AodTracksSel const& tracks) { if (!isEventSelected(coll)) return; float cent = getCentrality(coll); if (cent > KCentMax) return; - if (!pmeanNchEtabinPtbinStep2 || !pmeanEtNchEtabinPtbinStep2) { - LOGF(warning, "Data fluc: Mean pT or Et map missing"); - return; + + // 1. Safety Check: Step 2 Mean Maps + for (int isp = 0; isp < KNsp; ++isp) { + if (!pmeanNchEtabinPtbinStep2[isp] || !pmeanMultNchEtabinPtbinStep2[isp]) { + LOGF(warning, "Data fluc: Mean pT or Mult map missing for species index %d", isp); + return; + } } - if (!hEff[kInclusive] || !hFake[kInclusive] || !hWeightMap3D[kInclusive] || !hEff[kCombinedPID] || !hFake[kCombinedPID] || !hWeightMap3D[kCombinedPID]) { - LOGF(warning, "Data fluc: Inclusive or PID correction maps are null"); - return; + // 2. Safety Check: Correction Maps (Looping over Inclusive, Pi, Ka, Pr) + for (int isp = 0; isp < KNsp; ++isp) { + auto pid = static_cast(isp); + if (!hEff[pid] || !hFake[pid] || !hFlatWeight[pid]) { + LOGF(warning, "Data fluc: Correction maps (Eff, Fake, or Flat) are null for species index %d", isp); + return; + } } - double sumpmwk[KNEta][KNpT][KIntM][KIntK]{}; - double sumwk[KNEta][KNpT][KIntK]{}; - double sumpmwkEt[KNEta][KNpT][KIntM][KIntK]{}; - double sumwkEt[KNEta][KNpT][KIntK]{}; - double mean[KNEta][KNpT]{}, c2[KNEta][KNpT]{}; - double p1kBar[KNEta][KNpT]{}; - double meanEt[KNEta][KNpT]{}, c2Et[KNEta][KNpT]{}; - double p1kBarEt[KNEta][KNpT]{}; + // Expanded arrays to handle KNsp species (0: Incl, 1: Pi, 2: Ka, 3: Pr) + double sumpmwk[KNsp][KNEta][KNpT][KIntM][KIntK]{}; + double sumwk[KNsp][KNEta][KNpT][KIntK]{}; + + double mean[KNsp][KNEta][KNpT]{}, c2[KNsp][KNEta][KNpT]{}; + double p1kBar[KNsp][KNEta][KNpT]{}; + double meanMult[KNsp][KNEta][KNpT]{}, p1kBarMult[KNsp][KNEta][KNpT]{}; + + float vz = coll.posZ(); + + // --- 1. Track Loop: Accumulate sum --- for (const auto& track : tracks) { if (!isTrackSelected(track)) continue; + float pt = track.pt(); float eta = track.eta(); float p = track.p(); float phi = track.phi(); + auto sign = track.sign(); + if (p < KFloatEpsilon) continue; - float effIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 0); - float fakeIncl = getEfficiency(coll.multNTracksPV(), pt, eta, kInclusive, 1); - float flatWeightIncl = getFlatteningWeight(cent, eta, phi, kInclusive); - - float wIncl = flatWeightIncl * (1.0 - fakeIncl) / effIncl; - if (!std::isfinite(wIncl) || wIncl <= KFloatEpsilon || effIncl <= KFloatEpsilon) - continue; + bool isSpecies[KNsp] = {true, selectionPion(track), selectionKaon(track), selectionProton(track)}; - for (int ieta = 0; ieta < KNEta; ++ieta) { - if (eta <= etaLw[ieta] || eta > etaUp[ieta]) + for (int isp = 0; isp < KNsp; ++isp) { + if (!isSpecies[isp]) continue; - for (int ipt = 0; ipt < KNpT; ++ipt) { - if (pt <= pTLw[ipt] || pt > pTUp[ipt]) - continue; - for (int k = 0; k < KIntK; ++k) { - for (int m = 0; m < KIntM; ++m) - sumpmwk[ieta][ipt][m][k] += std::pow(wIncl, k) * std::pow(pt, m); - sumwk[ieta][ipt][k] += std::pow(wIncl, k); - } - } - } - const bool isPion = selectionPion(track); - const bool isKaon = selectionKaon(track); - const bool isProton = selectionProton(track); - if (isPion || isKaon || isProton) { - float effPid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 0); - float fakePid = getEfficiency(coll.multNTracksPV(), pt, eta, kCombinedPID, 1); - float flatWeightPid = getFlatteningWeight(cent, eta, phi, kCombinedPID); + float eff = getEfficiency(coll.multNTracksPV(), pt, eta, static_cast(isp), 0, cfgEff); + float fake = getEfficiency(coll.multNTracksPV(), pt, eta, static_cast(isp), 1, cfgEff); + float flatWeight = getFlatteningWeight(vz, sign, pt, eta, phi, static_cast(isp), cfgFlat); + float w = flatWeight * (1.0 - fake) / eff; - float wPid = flatWeightPid * (1.0 - fakePid) / effPid; - if (!std::isfinite(wPid) || wPid <= KFloatEpsilon || effPid <= KFloatEpsilon) + if (!std::isfinite(w) || w <= KFloatEpsilon || eff <= KFloatEpsilon) continue; - float m = isPion ? o2::constants::physics::MassPiPlus : isKaon ? o2::constants::physics::MassKPlus - : o2::constants::physics::MassProton; + // QA Fills + if (isp == numKInclusive) { + histos.fill(HIST("hEtaPhiReco"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd"), vz, sign, pt, eta, phi, w); + } else if (isp == numKPion) { // Pion + histos.fill(HIST("hEtaPhiReco_Pi"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pi"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Pi"), vz, sign, pt, eta, phi, w); + } else if (isp == numKKaon) { // Kaon + histos.fill(HIST("hEtaPhiReco_Ka"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Ka"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Ka"), vz, sign, pt, eta, phi, w); + } else if (isp == numKProton) { // Proton + histos.fill(HIST("hEtaPhiReco_Pr"), vz, sign, pt, eta, phi); + histos.fill(HIST("hEtaPhiRecoEffWtd_Pr"), vz, sign, pt, eta, phi, (1.0 - fake) / eff); + histos.fill(HIST("hEtaPhiRecoWtd_Pr"), vz, sign, pt, eta, phi, w); + } - float energy = std::sqrt(p * p + m * m); - float et = energy * (pt / p); // E_T = E * sin(theta) + // Kinematic Bin sum for (int ieta = 0; ieta < KNEta; ++ieta) { if (eta <= etaLw[ieta] || eta > etaUp[ieta]) continue; @@ -2188,154 +2954,266 @@ struct RadialFlowDecorr { if (pt <= pTLw[ipt] || pt > pTUp[ipt]) continue; for (int k = 0; k < KIntK; ++k) { - for (int m = 0; m < KIntM; ++m) - sumpmwkEt[ieta][ipt][m][k] += std::pow(wPid, k) * std::pow(et, m); - sumwkEt[ieta][ipt][k] += std::pow(wPid, k); + for (int m = 0; m < KIntM; ++m) { + sumpmwk[isp][ieta][ipt][m][k] += std::pow(w, k) * std::pow(pt, m); + } + sumwk[isp][ieta][ipt][k] += std::pow(w, k); } } } } } + // --- 2. Step 2 Means and 1D Fluc Variables --- for (int ieta = 0; ieta < KNEta; ++ieta) { for (int ipt = 0; ipt < KNpT; ++ipt) { - const int ibx = pmeanNchEtabinPtbinStep2->GetXaxis()->FindBin(coll.multNTracksPV()); + + // Use [0] to safely grab the X-axis from the array! + const int ibx = pmeanNchEtabinPtbinStep2[0]->GetXaxis()->FindBin(coll.multNTracksPV()); const int iby = ieta + 1; const int ibz = ipt + 1; - float mmpt = pmeanNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - float mmet = pmeanEtNchEtabinPtbinStep2->GetBinContent(ibx, iby, ibz); - mean[ieta][ipt] = sumpmwk[ieta][ipt][1][1] / sumwk[ieta][ipt][1]; - meanEt[ieta][ipt] = sumpmwkEt[ieta][ipt][1][1] / sumwkEt[ieta][ipt][1]; + for (int isp = 0; isp < KNsp; ++isp) { + // Dynamically fetch from the array + float mmpt = pmeanNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); + float mmMult = pmeanMultNchEtabinPtbinStep2[isp]->GetBinContent(ibx, iby, ibz); - if (std::isfinite(mmpt)) { - std::tie(mean[ieta][ipt], c2[ieta][ipt]) = - calculateMeanAndC2FromSums(sumpmwk[ieta][ipt], sumwk[ieta][ipt], mmpt); - p1kBar[ieta][ipt] = mean[ieta][ipt] - mmpt; - } - if (std::isfinite(mmet)) { - std::tie(meanEt[ieta][ipt], c2Et[ieta][ipt]) = - calculateMeanAndC2FromSums(sumpmwkEt[ieta][ipt], sumwkEt[ieta][ipt], mmet); - p1kBarEt[ieta][ipt] = meanEt[ieta][ipt] - mmet; + mean[isp][ieta][ipt] = sumpmwk[isp][ieta][ipt][1][1] / sumwk[isp][ieta][ipt][1]; + meanMult[isp][ieta][ipt] = sumwk[isp][ieta][ipt][1]; + + if (std::isfinite(mmpt)) { + std::tie(mean[isp][ieta][ipt], c2[isp][ieta][ipt]) = calculateMeanAndC2FromSums(sumpmwk[isp][ieta][ipt], sumwk[isp][ieta][ipt], mmpt); + p1kBar[isp][ieta][ipt] = mean[isp][ieta][ipt] - mmpt; + } + p1kBarMult[isp][ieta][ipt] = meanMult[isp][ieta][ipt] - mmMult; } } } - if (std::isfinite(c2[0][0])) - histos.fill(HIST("Prof_C2_Cent"), cent, c2[0][0]); - if (std::isfinite(c2Et[0][0])) - histos.fill(HIST("Prof_C2Et_Cent"), cent, c2Et[0][0]); - if (std::isfinite(sumwk[0][0][1])) { - histos.fill(HIST("Prof_MeanpT_Cent"), cent, mean[0][0]); - histos.fill(HIST("Prof_MeanpT_Mult"), coll.multNTracksPV(), mean[0][0]); - } - if (std::isfinite(sumwkEt[0][0][1])) { - histos.fill(HIST("Prof_MeanEt_Cent"), cent, meanEt[0][0]); - histos.fill(HIST("Prof_MeanEt_Mult"), coll.multNTracksPV(), meanEt[0][0]); - } - + // --- 3. Fill 1D Profiles --- for (int ieta = 0; ieta < KNEta; ++ieta) { for (int ipt = 0; ipt < KNpT; ++ipt) { - if (std::isfinite(c2[ieta][ipt])) - histos.fill(HIST("Prof_C2_Mult_etabin_ptbin"), coll.multNTracksPV(), ieta, ipt, c2[ieta][ipt]); - if (std::isfinite(c2Et[ieta][ipt])) - histos.fill(HIST("Prof_C2Et_Mult_etabin_ptbin"), coll.multNTracksPV(), ieta, ipt, c2Et[ieta][ipt]); + for (int isp = 0; isp < KNsp; ++isp) { + if (isp == numKInclusive) { + if (std::isfinite(mean[0][ieta][ipt])) { + histos.fill(HIST("Prof_MeanpT_Cent_etabin_ptbin"), cent, ieta, ipt, mean[0][ieta][ipt]); + histos.fill(HIST("Prof_MeanpT_Mult_etabin_ptbin"), coll.multNTracksPV(), ieta, ipt, mean[0][ieta][ipt]); + } + if (std::isfinite(c2[0][ieta][ipt])) { + histos.fill(HIST("Prof_C2_Cent_etabin_ptbin"), cent, ieta, ipt, c2[0][ieta][ipt]); + histos.fill(HIST("Prof_C2_Mult_etabin_ptbin"), coll.multNTracksPV(), ieta, ipt, c2[0][ieta][ipt]); + } + } else if (isp == numKPion) { // Pi + if (std::isfinite(mean[1][ieta][ipt])) { + histos.fill(HIST("Prof_MeanpT_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, mean[1][ieta][ipt]); + histos.fill(HIST("Prof_MeanpT_Mult_etabin_ptbin_Pi"), coll.multNTracksPV(), ieta, ipt, mean[1][ieta][ipt]); + } + if (std::isfinite(c2[1][ieta][ipt])) { + histos.fill(HIST("Prof_C2_Cent_etabin_ptbin_Pi"), cent, ieta, ipt, c2[1][ieta][ipt]); + histos.fill(HIST("Prof_C2_Mult_etabin_ptbin_Pi"), coll.multNTracksPV(), ieta, ipt, c2[1][ieta][ipt]); + } + } else if (isp == numKKaon) { // Ka + if (std::isfinite(mean[2][ieta][ipt])) { + histos.fill(HIST("Prof_MeanpT_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, mean[2][ieta][ipt]); + histos.fill(HIST("Prof_MeanpT_Mult_etabin_ptbin_Ka"), coll.multNTracksPV(), ieta, ipt, mean[2][ieta][ipt]); + } + if (std::isfinite(c2[2][ieta][ipt])) { + histos.fill(HIST("Prof_C2_Cent_etabin_ptbin_Ka"), cent, ieta, ipt, c2[2][ieta][ipt]); + histos.fill(HIST("Prof_C2_Mult_etabin_ptbin_Ka"), coll.multNTracksPV(), ieta, ipt, c2[2][ieta][ipt]); + } + } else if (isp == numKProton) { // Pr + if (std::isfinite(mean[3][ieta][ipt])) { + histos.fill(HIST("Prof_MeanpT_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, mean[3][ieta][ipt]); + histos.fill(HIST("Prof_MeanpT_Mult_etabin_ptbin_Pr"), coll.multNTracksPV(), ieta, ipt, mean[3][ieta][ipt]); + } + if (std::isfinite(c2[3][ieta][ipt])) { + histos.fill(HIST("Prof_C2_Cent_etabin_ptbin_Pr"), cent, ieta, ipt, c2[3][ieta][ipt]); + histos.fill(HIST("Prof_C2_Mult_etabin_ptbin_Pr"), coll.multNTracksPV(), ieta, ipt, c2[3][ieta][ipt]); + } + } + } } } for (int ietaA = 1; ietaA <= (KNEta - 1) / 2; ++ietaA) { int ietaC = KNEta - ietaA; - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - - { - const int ipt = 0; - float c2Sub = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("Prof_ipt0_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt0_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("Prof_ipt0_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt0_CovEt_Eta"), valy, c2SubEt); - } - } - - { - const int ipt = 1; - float c2Sub = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("Prof_ipt1_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt1_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("Prof_ipt1_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt1_CovEt_Eta"), valy, c2SubEt); - } - } + for (int ipt = 0; ipt < KNpT; ++ipt) { + for (int isp = 0; isp < KNsp; ++isp) { + float c2Sub = p1kBar[isp][ietaA][ipt] * p1kBar[isp][ietaC][ipt]; + float covAC = p1kBarMult[isp][ietaA][ipt] * p1kBar[isp][ietaC][ipt]; + float covCA = p1kBar[isp][ietaA][ipt] * p1kBarMult[isp][ietaC][ipt]; - { - const int ipt = 2; - float c2Sub = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(c2Sub)) { - histos.fill(HIST("Prof_ipt2_Cov_Cent_eta"), cent, valy, c2Sub); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt2_Cov_Eta"), valy, c2Sub); - } - float c2SubEt = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(c2SubEt)) { - histos.fill(HIST("Prof_ipt2_CovEt_Cent_eta"), cent, valy, c2SubEt); - if (cent < KCentCovCut) - histos.fill(HIST("Prof_ipt2_CovEt_Eta"), valy, c2SubEt); + if (isp == numKInclusive) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_C2Sub_Cent_etabin_ptbin"), cent, ietaA, ipt, c2Sub); + histos.fill(HIST("Prof_C2Sub_Mult_etabin_ptbin"), coll.multNTracksPV(), ietaA, ipt, c2Sub); + } + if (std::isfinite(covAC)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin"), cent, ietaA, ipt, covAC); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin"), coll.multNTracksPV(), ietaA, ipt, covAC); + } + if (std::isfinite(covCA)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin"), cent, ietaA, ipt, covCA); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin"), coll.multNTracksPV(), ietaA, ipt, covCA); + } + } else if (isp == numKPion) { // Pi + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_C2Sub_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, c2Sub); + histos.fill(HIST("Prof_C2Sub_Mult_etabin_ptbin_Pi"), coll.multNTracksPV(), ietaA, ipt, c2Sub); + } + if (std::isfinite(covAC)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, covAC); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin_Pi"), coll.multNTracksPV(), ietaA, ipt, covAC); + } + if (std::isfinite(covCA)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin_Pi"), cent, ietaA, ipt, covCA); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin_Pi"), coll.multNTracksPV(), ietaA, ipt, covCA); + } + } else if (isp == numKKaon) { // Ka + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_C2Sub_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, c2Sub); + histos.fill(HIST("Prof_C2Sub_Mult_etabin_ptbin_Ka"), coll.multNTracksPV(), ietaA, ipt, c2Sub); + } + if (std::isfinite(covAC)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, covAC); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin_Ka"), coll.multNTracksPV(), ietaA, ipt, covAC); + } + if (std::isfinite(covCA)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin_Ka"), cent, ietaA, ipt, covCA); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin_Ka"), coll.multNTracksPV(), ietaA, ipt, covCA); + } + } else if (isp == numKProton) { // Pr + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_C2Sub_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, c2Sub); + histos.fill(HIST("Prof_C2Sub_Mult_etabin_ptbin_Pr"), coll.multNTracksPV(), ietaA, ipt, c2Sub); + } + if (std::isfinite(covAC)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, covAC); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin_Pr"), coll.multNTracksPV(), ietaA, ipt, covAC); + } + if (std::isfinite(covCA)) { + histos.fill(HIST("Prof_Cov_Cent_etabin_ptbin_Pr"), cent, ietaA, ipt, covCA); + histos.fill(HIST("Prof_Cov_Mult_etabin_ptbin_Pr"), coll.multNTracksPV(), ietaA, ipt, covCA); + } + } } } } + // --- 5. Full 2D Covariances & GapSum Profiles --- for (int ietaA = 1; ietaA < KNEta; ++ietaA) { - for (int ietaC = 1; ietaC < KNEta; ++ietaC) { - float valx = KHalf * (etaLw[ietaA] + etaUp[ietaA]); - float valy = KHalf * (etaLw[ietaC] + etaUp[ietaC]); - { - const int ipt = 0; - float covpt = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(covpt)) - histos.fill(HIST("Prof_ipt0_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); - - float covet = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(covet)) - histos.fill(HIST("Prof_ipt0_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); - } + for (int ietaB = 1; ietaB < KNEta; ++ietaB) { - { - const int ipt = 1; - float covpt = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(covpt)) - histos.fill(HIST("Prof_ipt1_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); + float etaValA = (etaLw[ietaA] + etaUp[ietaA]) / 2.0f; + float etaValB = (etaLw[ietaB] + etaUp[ietaB]) / 2.0f; + float gap = etaValA - etaValB; + float sum = (etaValA + etaValB) / 2.0f; - float covet = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(covet)) - histos.fill(HIST("Prof_ipt1_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); - } - { - const int ipt = 2; + for (int ipt = 0; ipt < KNpT; ++ipt) { + for (int isp = 0; isp < KNsp; ++isp) { - float covpt = p1kBar[ietaA][ipt] * p1kBar[ietaC][ipt]; - if (std::isfinite(covpt)) - histos.fill(HIST("Prof_ipt2_C2Sub2D_Mult_etaA_etaC"), cent, valx, valy, covpt); + float c2Sub = p1kBar[isp][ietaA][ipt] * p1kBar[isp][ietaB][ipt]; + float cov = p1kBarMult[isp][ietaA][ipt] * p1kBar[isp][ietaB][ipt]; - float covet = p1kBarEt[ietaA][ipt] * p1kBarEt[ietaC][ipt]; - if (std::isfinite(covet)) - histos.fill(HIST("Prof_ipt2_C2SubEt2D_Mult_etaA_etaC"), cent, valx, valy, covet); + if (isp == numKInclusive) { // Inclusive + if (ipt == 0) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt0_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt0_GapSum2D"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt0_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt1_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt1_GapSum2D"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt1_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt2_C2Sub2D_Cent_etaA_etaC"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt2_GapSum2D"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt2_Cov2D_Cent_etaA_etaC"), cent, etaValA, etaValB, cov); + } + } else if (isp == numKPion) { // Pi + if (ipt == 0) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt0_GapSum2D_Pi"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt0_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt1_GapSum2D_Pi"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt1_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt2_GapSum2D_Pi"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt2_Cov2D_Cent_etaA_etaC_Pi"), cent, etaValA, etaValB, cov); + } + } else if (isp == numKKaon) { // Ka + if (ipt == 0) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt0_GapSum2D_Ka"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt0_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt1_GapSum2D_Ka"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt1_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt2_GapSum2D_Ka"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt2_Cov2D_Cent_etaA_etaC_Ka"), cent, etaValA, etaValB, cov); + } + } else if (isp == numKProton) { // Pr + if (ipt == 0) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt0_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt0_GapSum2D_Pr"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt0_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 2) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt1_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt1_GapSum2D_Pr"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt1_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, cov); + } else if (ipt == KNpT - 1) { + if (std::isfinite(c2Sub)) { + histos.fill(HIST("Prof_ipt2_C2Sub2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, c2Sub); + histos.fill(HIST("Prof_ipt2_GapSum2D_Pr"), cent, gap, sum, c2Sub); + } + if (std::isfinite(cov)) + histos.fill(HIST("Prof_ipt2_Cov2D_Cent_etaA_etaC_Pr"), cent, etaValA, etaValB, cov); + } + } + } } } } } - PROCESS_SWITCH(RadialFlowDecorr, processDataFluc, "process real data to calculate fluc pT and Et", cfgRunDataFluc); + PROCESS_SWITCH(RadialFlowDecorr, processDataFluc, "process data to calculate fluc pT and Et", cfgRunDataFluc); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)