From 1399f534d8aac1672db4374f7431758a90fea2b3 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 24 Apr 2026 12:02:55 -0600 Subject: [PATCH 01/11] New hist was added --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 37eb3e0ef6a..25545401f27 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -68,6 +68,7 @@ using BCsRun3 = soa::Join, NCentHists> hDedxVsMomentumVsCentPos{}; std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; +std::array, NCentHists + 1> hDedxVspTMomentumVsCent{}; struct DedxPidAnalysis { @@ -240,6 +241,7 @@ struct DedxPidAnalysis { static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; static constexpr std::string_view DedxvsMomentumvsCentPos[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; static constexpr std::string_view DedxvsMomentumvsCentNeg[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; + static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses + 1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100", "dEdx_vs_pTMomentum_all_Pos"}; // Ncl TPC static constexpr std::string_view NclTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; static constexpr std::string_view NclTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; @@ -477,6 +479,10 @@ struct DedxPidAnalysis { hDedxVsMomentumVsCentPos[i] = registryDeDx.add(DedxvsMomentumvsCentPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(DedxvsMomentumvsCentNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } + + for (int i = 0; i < CentralityClasses + 1; ++i) { + hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + } } registryDeDx.add( @@ -1522,6 +1528,7 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("Tracks_vs_pT_all_cuts"), trk.pt()); float signedP = trk.sign() * getMomentum(trk); + float signedpT = trk.sign() * trk.pt(); // MIP calibration for pions if (getMomentum(trk) >= pionMin && getMomentum(trk) <= pionMax) { @@ -1610,10 +1617,14 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST(DedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Pos"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentPos[centIndex]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hDedxVspTMomentumVsCent[centIndex]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hDedxVspTMomentumVsCent[10]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); } else { registryDeDx.fill(HIST(DedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Neg"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentNeg[centIndex]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hDedxVspTMomentumVsCent[centIndex]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hDedxVspTMomentumVsCent[10]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); } } } From 7e25b0db34bd904e4753baf0f98637734be50e8c Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Tue, 5 May 2026 13:01:22 -0600 Subject: [PATCH 02/11] DCA cuts were changed, mass plots were added --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 158 ++++++++++++++++++++----- 1 file changed, 127 insertions(+), 31 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 25545401f27..ef69d76fce9 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -83,7 +83,6 @@ struct DedxPidAnalysis { static constexpr int EtaIntervals = 8; static constexpr int ParticlesType = 4; static constexpr int CentralityClasses = 10; - float tpcCut = 0.6; float pionMin = 0.35; float pionMax = 0.45; float elTofCut = 0.1; @@ -197,6 +196,11 @@ struct DedxPidAnalysis { Configurable etaMin{"etaMin", -0.8f, "etaMin"}; Configurable etaMax{"etaMax", +0.8f, "etaMax"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; + Configurable nSigmaDCAxy{"nSigmaDCAxy", 3.0, "nSigma DCAxy selection"}; + Configurable dcaXYp0{"dcaXYp0", 0.0105f, "DCAxy formula: p0 + p1/pt^p2"}; + Configurable dcaXYp1{"dcaXYp1", 0.0350f, "DCAxy p1 parameter"}; + Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCA_xy p2 parameter"}; + Configurable nSigmaDCAz{"nSigmaDCAz", 3.0, "nSigma DCAz selection"}; Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; // v0 cuts Configurable v0cospaMin{"v0cospaMin", 0.999f, "Minimum V0 CosPA"}; @@ -215,7 +219,8 @@ struct DedxPidAnalysis { Configurable v0rapidityCut{"v0rapidityCut", 0.5f, "V0 rapidity cut"}; Configurable v0ProperLifetimeCutK0s{"v0ProperLifetimeCutK0s", 20.f, "V0 proper lifetime cut for K0s"}; Configurable v0ProperLifetimeCutLambda{"v0ProperLifetimeCutLambda", 30.f, "V0 proper lifetime cut for Lambda"}; - Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; + Configurable nsigmaMax{"nsigmaMax", 3.0f, "Maximum nsigma cut"}; + Configurable tpcMomentumCut{"tpcMomentumCut", 0.6f, "Momentum threshold above which TOF is required"}; Configurable invMassCutK0s{"invMassCutK0s", 0.015f, "invariant Mass Cut for K0s"}; Configurable invMassCutLambda{"invMassCutLambda", 0.015f, "invariant Mass Cut for Lambda"}; Configurable invMassCutGamma{"invMassCutGamma", 0.015f, "invariant Mass Cut for Gamma"}; @@ -276,8 +281,8 @@ struct DedxPidAnalysis { selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); - selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); - selectedTracks.SetMaxDcaZ(maxDCAz); + // selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); + // selectedTracks.SetMaxDcaZ(maxDCAz); selectedTracks.SetRequireGoldenChi2(true); return selectedTracks; @@ -299,7 +304,8 @@ struct DedxPidAnalysis { LOGF(info, "GoodZvtxFT0vsPV cut disabled"); } if (nINELSelectionMode == NoSelINEL) { - LOGF(info, "INEL cut disabled"); + LOGF(info, "Applying just INEL"); + label = "INEL"; } else if (nINELSelectionMode == SelINELgt0) { LOGF(info, "Applying INEL > 0 cut"); label = "INEL > 0"; @@ -483,6 +489,30 @@ struct DedxPidAnalysis { for (int i = 0; i < CentralityClasses + 1; ++i) { hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); } + + // Invariant Mass + registryDeDx.add("hMassK0s", "Invariant mass K0s;m_{#pi#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 0.4, 0.6}}); + registryDeDx.add("hMassLambda", "Invariant mass #Lambda;m_{p#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 1.08, 1.16}}); + registryDeDx.add("hMassAntiLambda", "Invariant mass #bar{#Lambda};m_{#bar{p}#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 1.08, 1.16}}); + registryDeDx.add("hMassGamma", "Invariant mass #gamma;m_{ee} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 0.0, 0.1}}); + + // Armenteros-Podolanski plot + registryDeDx.add("hArmenterosAll", "Armenteros-Podolanski (all V0s);#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + + // Armenteros-Podolanski plot by particle + registryDeDx.add("hArmenterosK0s", "Armenteros-Podolanski K0s;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosLambda", "Armenteros-Podolanski #Lambda;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosAntiLambda", "Armenteros-Podolanski #bar{#Lambda};#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosGamma", "Armenteros-Podolanski #gamma;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); } registryDeDx.add( @@ -663,6 +693,23 @@ struct DedxPidAnalysis { registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F, {{ptAxis}}); registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F, {{ptAxis}}); + // NCluster distributions + registryDeDx.add("hTPCClustersBefore", "N clusters TPC found Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, Before}"}}); + registryDeDx.add("hTPCClustersAfter", "N clusters TPC found After", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, After}"}}); + + registryDeDx.add("hTPCPIDBefore", "N clusters TPC PID Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, Before}"}}); + registryDeDx.add("hTPCPIDAfter", "N clusters TPC PID After", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, After}"}}); + + // DCA cut + registryDeDx.add("hDCAxyVsPt_before", "DCAxy vs pT before cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + registryDeDx.add("hDCAzVsPt_before", "DCAz vs pT before cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + registryDeDx.add("hDCAxyVsPt_after", "DCAxy vs pT after cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); auto hstat = registryDeDx.get(HIST("evsel")); @@ -721,6 +768,7 @@ struct DedxPidAnalysis { xSec->SetBinLabel(V0TypeGamma, "V0TypeGamma"); xSec->SetBinLabel(V0RapidityGamma, "V0RapidityGamma"); xSec->SetBinLabel(MassCutGamma, "MassCutGamma"); + mySelectionPrim = myTrackSelection(); } @@ -740,7 +788,20 @@ struct DedxPidAnalysis { return true; } - + // DCA xy cut + template + bool passesDCAxyCut(const T1& track) const + { + const float maxDcaXY = nSigmaDCAxy.value * (dcaXYp0.value + dcaXYp1.value / std::pow(track.pt(), dcaXYp2.value)) / 3.0; + return std::abs(track.dcaXY()) < maxDcaXY; + } + // DCA z cut + template + bool passesDCAzCut(const T1& track) const + { + const float maxiDcaZ = nSigmaDCAz.value * (maxDCAz.value) / 3.0; + return std::abs(track.dcaZ()) < maxiDcaZ; + } // Momentum template float getMomentum(const T1& track) @@ -780,7 +841,7 @@ struct DedxPidAnalysis { return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; - /*double sigmap = 0.0; + double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -794,19 +855,20 @@ struct DedxPidAnalysis { sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } - if (ptrack.tpcInnerParam() > tpcCut) { + if (ptrack.tpcInnerParam() > tpcMomentumCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(sigmap) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaMax) return false; } - if (ntrack.tpcInnerParam() > tpcCut) { + if (ntrack.tpcInnerParam() > tpcMomentumCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(sigman) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaMax) return false; - }*/ + } + if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionK0s); @@ -860,7 +922,7 @@ struct DedxPidAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; - /*double sigmap = 0.0; + double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -874,19 +936,19 @@ struct DedxPidAnalysis { sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } - if (ptrack.tpcInnerParam() > tpcCut) { + if (ptrack.tpcInnerParam() > tpcMomentumCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(sigmap) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaMax) return false; } - if (ntrack.tpcInnerParam() > tpcCut) { + if (ntrack.tpcInnerParam() > tpcMomentumCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(sigman) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaMax) return false; - }*/ + } if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionLambda); @@ -935,7 +997,7 @@ struct DedxPidAnalysis { return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; - /*double sigmap = 0.0; + double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -948,19 +1010,19 @@ struct DedxPidAnalysis { sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); sigman = std::hypot(ntrack.tpcNSigmaPr(), ntrack.tofNSigmaPr()); } - if (ptrack.tpcInnerParam() > tpcCut) { + if (ptrack.tpcInnerParam() > tpcMomentumCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(sigmap) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaMax) return false; } - if (ntrack.tpcInnerParam() > tpcCut) { + if (ntrack.tpcInnerParam() > tpcMomentumCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(sigman) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaMax) return false; - }*/ + } if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionAntiLambda); @@ -1011,7 +1073,7 @@ struct DedxPidAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; - /*double sigmap = 0.0; + double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -1025,19 +1087,19 @@ struct DedxPidAnalysis { sigman = std::hypot(ntrack.tpcNSigmaEl(), ntrack.tofNSigmaEl()); } - if (ptrack.tpcInnerParam() > tpcCut) { + if (ptrack.tpcInnerParam() > tpcMomentumCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(sigmap) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaMax) return false; } - if (ntrack.tpcInnerParam() > tpcCut) { + if (ntrack.tpcInnerParam() > tpcMomentumCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(sigman) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaMax) return false; - }*/ + } const float gammaMass = 2 * MassElectron; // GeV/c^2 if (fillHist) @@ -1462,6 +1524,7 @@ struct DedxPidAnalysis { } if (nINELSelectionMode == NoSelINEL) { + registryDeDx.fill(HIST("evsel"), EvCutLabel::INELgt); } else if (nINELSelectionMode == SelINELgt0) { if (!collision.isInelGt0()) return; @@ -1490,10 +1553,28 @@ struct DedxPidAnalysis { for (const auto& trk : tracks) { registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::AllPri); - // track Selection + // Ncl distribution before cuts + registryDeDx.fill(HIST("hTPCClustersBefore"), trk.tpcNClsFound()); + registryDeDx.fill(HIST("hTPCPIDBefore"), trk.tpcNClsPID()); + + // track Selection wo DCA if (!mySelectionPrim.IsSelected(trk)) continue; + // Before DCA cuts + registryDeDx.fill(HIST("hDCAxyVsPt_before"), trk.pt(), trk.dcaXY()); + registryDeDx.fill(HIST("hDCAzVsPt_before"), trk.pt(), trk.dcaZ()); + + // DCA cuts + if (!passesDCAxyCut(trk)) + continue; + if (!passesDCAzCut(trk)) + continue; + + // After DCA cuts + registryDeDx.fill(HIST("hDCAxyVsPt_after"), trk.pt(), trk.dcaXY()); + registryDeDx.fill(HIST("hDCAzVsPt_after"), trk.pt(), trk.dcaZ()); + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); // For pt registryDeDx.fill(HIST("Tracks_vs_pT_all"), trk.pt()); @@ -1527,6 +1608,10 @@ struct DedxPidAnalysis { // For pt + cuts registryDeDx.fill(HIST("Tracks_vs_pT_all_cuts"), trk.pt()); + // Ncl distribution After all cuts + registryDeDx.fill(HIST("hTPCClustersAfter"), trk.tpcNClsFound()); + registryDeDx.fill(HIST("hTPCPIDAfter"), trk.tpcNClsPID()); + float signedP = trk.sign() * getMomentum(trk); float signedpT = trk.sign() * trk.pt(); @@ -1718,12 +1803,17 @@ struct DedxPidAnalysis { fillHist = true; + // Armenteros for all V0 + registryDeDx.fill(HIST("hArmenterosAll"), v0.alpha(), v0.qtarm()); + // K0s Selection if (passedK0Selection(v0, negTrack, posTrack, collision)) { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsK0s"), posTrack.eta(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsK0s"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), negTrack.p(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hMassK0s"), v0.mK0Short()); + registryDeDx.fill(HIST("hArmenterosK0s"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1740,6 +1830,8 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), negTrack.p(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hMassLambda"), v0.mLambda()); + registryDeDx.fill(HIST("hArmenterosLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1756,6 +1848,8 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.p(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hMassAntiLambda"), v0.mAntiLambda()); + registryDeDx.fill(HIST("hArmenterosAntiLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1772,6 +1866,8 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.p(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hMassGamma"), v0.mGamma()); + registryDeDx.fill(HIST("hArmenterosGamma"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); From 460b55d59bceb0fe24dc5fc56db452302f765b73 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 8 May 2026 13:38:28 -0600 Subject: [PATCH 03/11] Histograms for the p to pT conversion were added --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 146 ++++++++++++++++++++++++-- 1 file changed, 138 insertions(+), 8 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index 6aaebebc9dd..f9a8872dc39 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -67,6 +67,7 @@ struct MultiplicityPt { static constexpr int CentBinMax = 100; static constexpr int MultBinMax = 200; static constexpr int RecMultBinMax = 100; + static constexpr int ParticlesType = 4; enum INELCutSelection : int { INEL = 0, @@ -111,6 +112,16 @@ struct MultiplicityPt { Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; + // Histogram names for V0s dE/dx analysis + static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; + static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + // Particle fractions histograms + static constexpr std::string_view ParticleFractionsVsMomentumPos[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Pos", "hFractionVsMomentum_Kaon_Pos", "hFractionVsMomentum_Proton_Pos", "hFractionVsMomentum_Electron_Pos", "hFractionVsMomentum_Muon_Pos"}; + + static constexpr std::string_view ParticleFractionsVsPtPos[ParticlesType + 1] = {"hFractionVsPt_Pion_Pos", "hFractionVsPt_Kaon_Pos", "hFractionVsPt_Proton_Pos", "hFractionVsPt_Electron_Pos", "hFractionVsPt_Muon_Pos"}; + static constexpr std::string_view ParticleFractionsVsMomentumNeg[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Neg", "hFractionVsMomentum_Kaon_Neg", "hFractionVsMomentum_Proton_Neg", "hFractionVsMomentum_Electron_Neg", "hFractionVsMomentum_Muon_Neg"}; + + static constexpr std::string_view ParticleFractionsVsPtNeg[ParticlesType + 1] = {"hFractionVsPt_Pion_Neg", "hFractionVsPt_Kaon_Neg", "hFractionVsPt_Proton_Neg", "hFractionVsPt_Electron_Neg", "hFractionVsPt_Muon_Neg"}; TrackSelection customTrackCuts; TF1* fphiCutLow = nullptr; @@ -346,6 +357,10 @@ void MultiplicityPt::init(InitContext const&) // Axis definitions ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; + AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; + AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; + std::vector centBinningStd = {0., 1., 5., 10., 15., 20., 30., 40., 50., 60., 70., 80., 90., 100.}; AxisSpec centAxis = {centBinningStd, "FT0M Centrality (%)"}; @@ -450,11 +465,47 @@ void MultiplicityPt::init(InitContext const&) ue.add("hEventsReco_Cent", "Reconstructed events vs centrality;FT0M Centrality (%);Counts", HistType::kTH1D, {centAxis}); ue.add("hEventsINEL_Cent", "INEL>0 events vs centrality;FT0M Centrality (%);Counts", HistType::kTH1D, {centAxis}); - ue.add("hNclFoundTPC", "Number of TPC found clusters", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclPIDTPC", "Number of TPC PID clusters", HistType::kTH1D, {{200, 0, 200}}); + ue.add("hNclFoundTPCBefore", "Number of TPC found clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); + ue.add("hNclPIDTPCBefore", "Number of TPC PID clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); + ue.add("hNclFoundTPCAfter", "Number of TPC found after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); + ue.add("hNclPIDTPCAfter", "Number of TPC PID after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); ue.add("hEta", "Track eta;#eta;Counts", HistType::kTH1D, {{20, -0.8, 0.8}}); ue.add("hPhi", "Track phi;#varphi (rad);Counts", HistType::kTH1D, {{64, 0, TwoPI}}); ue.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); + + // De/Dx for ch and v0 particles + for (int i = 0; i < ParticlesType; ++i) { + ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumPos[i])).c_str(), + "dE/dx vs Momentum Positive", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumNeg[i])).c_str(), + "dE/dx vs Momentum Negative", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + } + + // ===== Particle Fractions as function of p and pT ===== + ue.add("ParticleFractions/hTotalCountsVsMomentumPos", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D,{{etaAxis}, {pAxis}}); + ue.add("ParticleFractions/hTotalCountsVsPtPos", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D,{{etaAxis}, {ptAxis}}); + ue.add("ParticleFractions/hTotalCountsVsMomentumNeg", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D,{{etaAxis}, {pAxis}}); + ue.add("ParticleFractions/hTotalCountsVsPtNeg", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis},{ptAxis}}); + + for (int i = 0; i < ParticlesType + 1; ++i) { + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumPos[i])).c_str(), + "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtPos[i])).c_str(), + "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumNeg[i])).c_str(), + "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtNeg[i])).c_str(), + "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + } + // pt vs p + ue.add( + "heta_vs_pt_vs_p_all_Neg", "eta_vs_pT_vs_p", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + ue.add( + "heta_vs_pt_vs_p_all_Pos", "eta_vs_pT_vs_p", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); LOG(info) << "=== Initialization complete ==="; } @@ -679,35 +730,83 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, continue; if (track.collisionId() != collId) continue; - + // Ncl distribution before cuts + ue.fill(HIST("hNclFoundTPCBefore"), track.tpcNClsFound()); + ue.fill(HIST("hNclPIDTPCBefore"), track.tpcNClsPID()); + if (!passesTrackSelection(track, magField)) continue; nTracksInEvent++; - - ue.fill(HIST("hNclFoundTPC"), track.tpcNClsFound()); - ue.fill(HIST("hNclPIDTPC"), track.tpcNClsPID()); + // Ncl distribution before cuts + ue.fill(HIST("hNclFoundTPCAfter"), track.tpcNClsFound()); + ue.fill(HIST("hNclPIDTPCAfter"), track.tpcNClsPID()); ue.fill(HIST("hEta"), track.eta()); ue.fill(HIST("hPhi"), track.phi()); ue.fill(HIST("Inclusive/hPtReco"), track.pt()); - + + // ===== dE/dx and momentum for V0 cross-check histograms ===== + float tpcSignal = track.tpcSignal(); + float momentum = track.p(); // momentum total + float eta = track.eta(); + int charge = track.sign(); + + // dedx for all particles + if (charge > 0) { + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); + ue.fill(HIST("heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); + } else { + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); + ue.fill(HIST("heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); + } + if (track.has_mcParticle()) { const auto& particle = track.mcParticle(); int pdgCode = std::abs(particle.pdgCode()); - + if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { + if (particle.isPhysicalPrimary()) { + // Fill total counts for fractions + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumPos"),eta, momentum); + ue.fill(HIST("ParticleFractions/hTotalCountsVsPtPos"), eta, track.pt()); + }else{ + ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumNeg"),eta, momentum); + ue.fill(HIST("ParticleFractions/hTotalCountsVsPtNeg"), eta, track.pt()); + } + } + } + if (pdgCode == PDG_t::kPiPlus) { ue.fill(HIST("Pion/hPtReco"), track.pt()); if (particle.isPhysicalPrimary()) { ue.fill(HIST("Pion/hPtPrimReco"), track.pt()); ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Pos"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Pos"), eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); + }else{ + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Neg"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Neg"), eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); + } + } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); + } } else if (pdgCode == PDG_t::kKPlus) { ue.fill(HIST("Kaon/hPtReco"), track.pt()); if (particle.isPhysicalPrimary()) { ue.fill(HIST("Kaon/hPtPrimReco"), track.pt()); ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Pos"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Pos"),eta, track.pt()); + }else{ + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Neg"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Neg"),eta, track.pt()); + } } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); } @@ -716,9 +815,40 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, if (particle.isPhysicalPrimary()) { ue.fill(HIST("Proton/hPtPrimReco"), track.pt()); ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Pos"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Pos"),eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); + }else{ + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Neg"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Neg"),eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); + } } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); } + }else if (pdgCode == PDG_t::kElectron) { + if (particle.isPhysicalPrimary()) { + if (charge > 0){ + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Pos"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Pos"),eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Pos"), momentum, tpcSignal, eta); + }else { + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Neg"), momentum, tpcSignal, eta); + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Neg"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Neg"),eta, track.pt()); + } + } + }else if (pdgCode == PDG_t::kMuonPlus) { + if (particle.isPhysicalPrimary()) { + if (charge > 0){ + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Pos"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Pos"),eta, track.pt()); + }else{ + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Neg"),eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Neg"),eta, track.pt()); + } + } } } From 45d71caecc47335e4469fdec497b015a422aba6a Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 8 May 2026 13:40:04 -0600 Subject: [PATCH 04/11] Histograms for the p to pT conversion --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 254 +++++++++++++------------- 1 file changed, 126 insertions(+), 128 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index f9a8872dc39..28531bd0446 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -112,16 +112,16 @@ struct MultiplicityPt { Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; - // Histogram names for V0s dE/dx analysis - static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; - static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; - // Particle fractions histograms - static constexpr std::string_view ParticleFractionsVsMomentumPos[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Pos", "hFractionVsMomentum_Kaon_Pos", "hFractionVsMomentum_Proton_Pos", "hFractionVsMomentum_Electron_Pos", "hFractionVsMomentum_Muon_Pos"}; + // Histogram names for V0s dE/dx analysis + static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; + static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + // Particle fractions histograms + static constexpr std::string_view ParticleFractionsVsMomentumPos[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Pos", "hFractionVsMomentum_Kaon_Pos", "hFractionVsMomentum_Proton_Pos", "hFractionVsMomentum_Electron_Pos", "hFractionVsMomentum_Muon_Pos"}; - static constexpr std::string_view ParticleFractionsVsPtPos[ParticlesType + 1] = {"hFractionVsPt_Pion_Pos", "hFractionVsPt_Kaon_Pos", "hFractionVsPt_Proton_Pos", "hFractionVsPt_Electron_Pos", "hFractionVsPt_Muon_Pos"}; - static constexpr std::string_view ParticleFractionsVsMomentumNeg[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Neg", "hFractionVsMomentum_Kaon_Neg", "hFractionVsMomentum_Proton_Neg", "hFractionVsMomentum_Electron_Neg", "hFractionVsMomentum_Muon_Neg"}; + static constexpr std::string_view ParticleFractionsVsPtPos[ParticlesType + 1] = {"hFractionVsPt_Pion_Pos", "hFractionVsPt_Kaon_Pos", "hFractionVsPt_Proton_Pos", "hFractionVsPt_Electron_Pos", "hFractionVsPt_Muon_Pos"}; + static constexpr std::string_view ParticleFractionsVsMomentumNeg[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Neg", "hFractionVsMomentum_Kaon_Neg", "hFractionVsMomentum_Proton_Neg", "hFractionVsMomentum_Electron_Neg", "hFractionVsMomentum_Muon_Neg"}; - static constexpr std::string_view ParticleFractionsVsPtNeg[ParticlesType + 1] = {"hFractionVsPt_Pion_Neg", "hFractionVsPt_Kaon_Neg", "hFractionVsPt_Proton_Neg", "hFractionVsPt_Electron_Neg", "hFractionVsPt_Muon_Neg"}; + static constexpr std::string_view ParticleFractionsVsPtNeg[ParticlesType + 1] = {"hFractionVsPt_Pion_Neg", "hFractionVsPt_Kaon_Neg", "hFractionVsPt_Proton_Neg", "hFractionVsPt_Electron_Neg", "hFractionVsPt_Muon_Neg"}; TrackSelection customTrackCuts; TF1* fphiCutLow = nullptr; @@ -357,10 +357,9 @@ void MultiplicityPt::init(InitContext const&) // Axis definitions ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; - AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; - AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; - + AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; + AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; + AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; std::vector centBinningStd = {0., 1., 5., 10., 15., 20., 30., 40., 50., 60., 70., 80., 90., 100.}; AxisSpec centAxis = {centBinningStd, "FT0M Centrality (%)"}; @@ -467,45 +466,45 @@ void MultiplicityPt::init(InitContext const&) ue.add("hNclFoundTPCBefore", "Number of TPC found clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); ue.add("hNclPIDTPCBefore", "Number of TPC PID clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclFoundTPCAfter", "Number of TPC found after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclPIDTPCAfter", "Number of TPC PID after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); + ue.add("hNclFoundTPCAfter", "Number of TPC found after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); + ue.add("hNclPIDTPCAfter", "Number of TPC PID after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); ue.add("hEta", "Track eta;#eta;Counts", HistType::kTH1D, {{20, -0.8, 0.8}}); ue.add("hPhi", "Track phi;#varphi (rad);Counts", HistType::kTH1D, {{64, 0, TwoPI}}); ue.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); - - // De/Dx for ch and v0 particles - for (int i = 0; i < ParticlesType; ++i) { - ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumPos[i])).c_str(), - "dE/dx vs Momentum Positive", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); - ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumNeg[i])).c_str(), - "dE/dx vs Momentum Negative", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); - } - - // ===== Particle Fractions as function of p and pT ===== - ue.add("ParticleFractions/hTotalCountsVsMomentumPos", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D,{{etaAxis}, {pAxis}}); - ue.add("ParticleFractions/hTotalCountsVsPtPos", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D,{{etaAxis}, {ptAxis}}); - ue.add("ParticleFractions/hTotalCountsVsMomentumNeg", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D,{{etaAxis}, {pAxis}}); - ue.add("ParticleFractions/hTotalCountsVsPtNeg", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis},{ptAxis}}); - - for (int i = 0; i < ParticlesType + 1; ++i) { - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumPos[i])).c_str(), - "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtPos[i])).c_str(), - "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumNeg[i])).c_str(), - "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtNeg[i])).c_str(), - "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - } - // pt vs p - ue.add( - "heta_vs_pt_vs_p_all_Neg", "eta_vs_pT_vs_p", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); - ue.add( - "heta_vs_pt_vs_p_all_Pos", "eta_vs_pT_vs_p", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); + + // De/Dx for ch and v0 particles + for (int i = 0; i < ParticlesType; ++i) { + ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumPos[i])).c_str(), + "dE/dx vs Momentum Positive", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumNeg[i])).c_str(), + "dE/dx vs Momentum Negative", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + } + + // ===== Particle Fractions as function of p and pT ===== + ue.add("ParticleFractions/hTotalCountsVsMomentumPos", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); + ue.add("ParticleFractions/hTotalCountsVsPtPos", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + ue.add("ParticleFractions/hTotalCountsVsMomentumNeg", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); + ue.add("ParticleFractions/hTotalCountsVsPtNeg", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + + for (int i = 0; i < ParticlesType + 1; ++i) { + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumPos[i])).c_str(), + "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtPos[i])).c_str(), + "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumNeg[i])).c_str(), + "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtNeg[i])).c_str(), + "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + } + // pt vs p + ue.add( + "heta_vs_pt_vs_p_all_Neg", "eta_vs_pT_vs_p", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + ue.add( + "heta_vs_pt_vs_p_all_Pos", "eta_vs_pT_vs_p", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); LOG(info) << "=== Initialization complete ==="; } @@ -730,83 +729,82 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, continue; if (track.collisionId() != collId) continue; - // Ncl distribution before cuts - ue.fill(HIST("hNclFoundTPCBefore"), track.tpcNClsFound()); - ue.fill(HIST("hNclPIDTPCBefore"), track.tpcNClsPID()); - + // Ncl distribution before cuts + ue.fill(HIST("hNclFoundTPCBefore"), track.tpcNClsFound()); + ue.fill(HIST("hNclPIDTPCBefore"), track.tpcNClsPID()); + if (!passesTrackSelection(track, magField)) continue; nTracksInEvent++; - // Ncl distribution before cuts + // Ncl distribution before cuts ue.fill(HIST("hNclFoundTPCAfter"), track.tpcNClsFound()); ue.fill(HIST("hNclPIDTPCAfter"), track.tpcNClsPID()); ue.fill(HIST("hEta"), track.eta()); ue.fill(HIST("hPhi"), track.phi()); ue.fill(HIST("Inclusive/hPtReco"), track.pt()); - - // ===== dE/dx and momentum for V0 cross-check histograms ===== - float tpcSignal = track.tpcSignal(); - float momentum = track.p(); // momentum total - float eta = track.eta(); - int charge = track.sign(); - - // dedx for all particles - if (charge > 0) { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); - } else { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); - } - + + // ===== dE/dx and momentum for V0 cross-check histograms ===== + float tpcSignal = track.tpcSignal(); + float momentum = track.p(); // momentum total + float eta = track.eta(); + int charge = track.sign(); + + // dedx for all particles + if (charge > 0) { + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); + ue.fill(HIST("heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); + } else { + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); + ue.fill(HIST("heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); + } + if (track.has_mcParticle()) { const auto& particle = track.mcParticle(); int pdgCode = std::abs(particle.pdgCode()); - if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { - if (particle.isPhysicalPrimary()) { - // Fill total counts for fractions - if (charge > 0) { - ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumPos"),eta, momentum); - ue.fill(HIST("ParticleFractions/hTotalCountsVsPtPos"), eta, track.pt()); - }else{ - ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumNeg"),eta, momentum); - ue.fill(HIST("ParticleFractions/hTotalCountsVsPtNeg"), eta, track.pt()); - } - } + if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { + if (particle.isPhysicalPrimary()) { + // Fill total counts for fractions + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumPos"), eta, momentum); + ue.fill(HIST("ParticleFractions/hTotalCountsVsPtPos"), eta, track.pt()); + } else { + ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumNeg"), eta, momentum); + ue.fill(HIST("ParticleFractions/hTotalCountsVsPtNeg"), eta, track.pt()); + } } - + } + if (pdgCode == PDG_t::kPiPlus) { ue.fill(HIST("Pion/hPtReco"), track.pt()); if (particle.isPhysicalPrimary()) { ue.fill(HIST("Pion/hPtPrimReco"), track.pt()); ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); - if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Pos"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Pos"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); - }else{ - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Neg"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Neg"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); - } - + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Pos"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Pos"), eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); + } else { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Neg"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Neg"), eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); + } + } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - } } else if (pdgCode == PDG_t::kKPlus) { ue.fill(HIST("Kaon/hPtReco"), track.pt()); if (particle.isPhysicalPrimary()) { ue.fill(HIST("Kaon/hPtPrimReco"), track.pt()); ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); - if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Pos"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Pos"),eta, track.pt()); - }else{ - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Neg"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Neg"),eta, track.pt()); - } + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Pos"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Pos"), eta, track.pt()); + } else { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Neg"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Neg"), eta, track.pt()); + } } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); } @@ -815,40 +813,40 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, if (particle.isPhysicalPrimary()) { ue.fill(HIST("Proton/hPtPrimReco"), track.pt()); ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); - if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Pos"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Pos"),eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); - }else{ - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Neg"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Neg"),eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); - } + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Pos"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Pos"), eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); + } else { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Neg"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Neg"), eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); + } } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); } - }else if (pdgCode == PDG_t::kElectron) { - if (particle.isPhysicalPrimary()) { - if (charge > 0){ - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Pos"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Pos"),eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Pos"), momentum, tpcSignal, eta); - }else { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Neg"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Neg"),eta, track.pt()); - } + } else if (pdgCode == PDG_t::kElectron) { + if (particle.isPhysicalPrimary()) { + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Pos"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Pos"), eta, track.pt()); + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Pos"), momentum, tpcSignal, eta); + } else { + ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Neg"), momentum, tpcSignal, eta); + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Neg"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Neg"), eta, track.pt()); } - }else if (pdgCode == PDG_t::kMuonPlus) { - if (particle.isPhysicalPrimary()) { - if (charge > 0){ - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Pos"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Pos"),eta, track.pt()); - }else{ - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Neg"),eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Neg"),eta, track.pt()); - } + } + } else if (pdgCode == PDG_t::kMuonPlus) { + if (particle.isPhysicalPrimary()) { + if (charge > 0) { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Pos"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Pos"), eta, track.pt()); + } else { + ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Neg"), eta, momentum); + ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Neg"), eta, track.pt()); } + } } } From e2acbfb0f1588c6b74390aec8d9c608438dff25f Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Wed, 13 May 2026 14:34:12 -0600 Subject: [PATCH 05/11] Histograms for the p to pT conversion --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 47 ++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index 28531bd0446..a8e9dad51e5 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -68,6 +68,7 @@ struct MultiplicityPt { static constexpr int MultBinMax = 200; static constexpr int RecMultBinMax = 100; static constexpr int ParticlesType = 4; + static constexpr int ResponseMatrixTypes = 7; enum INELCutSelection : int { INEL = 0, @@ -115,6 +116,9 @@ struct MultiplicityPt { // Histogram names for V0s dE/dx analysis static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + + static constexpr std::string_view EtavspvspTPosPart[ResponseMatrixTypes] = {"heta_vs_pt_vs_p_all_Pos", "heta_vs_pt_vs_p_all_Pos_Pri", "heta_vs_pt_vs_p_all_Pos_Pri_MC", "heta_vs_pt_vs_p_all_Pos_Pri_MC_Part", "heta_vs_pt_vs_p_Pi_Pos", "heta_vs_pt_vs_p_K_Pos", "heta_vs_pt_vs_p_Pr_Pos"}; + static constexpr std::string_view EtavspvspTNegPart[ResponseMatrixTypes] = {"heta_vs_pt_vs_p_all_Neg", "heta_vs_pt_vs_p_all_Neg_Pri", "heta_vs_pt_vs_p_all_Neg_Pri_MC", "heta_vs_pt_vs_p_all_Neg_Pri_MC_Part", "heta_vs_pt_vs_p_Pi_Neg", "heta_vs_pt_vs_p_K_Neg", "heta_vs_pt_vs_p_Pr_Neg"}; // Particle fractions histograms static constexpr std::string_view ParticleFractionsVsMomentumPos[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Pos", "hFractionVsMomentum_Kaon_Pos", "hFractionVsMomentum_Proton_Pos", "hFractionVsMomentum_Electron_Pos", "hFractionVsMomentum_Muon_Pos"}; @@ -481,6 +485,15 @@ void MultiplicityPt::init(InitContext const&) "dE/dx vs Momentum Negative", HistType::kTH3F, {{pAxis}, {dedxAxis}, {etaAxis}}); } + // pt vs p + for (int i = 0; i < ResponseMatrixTypes; ++i) { + ue.add(("ResponseMatrix/" + std::string(EtavspvspTPosPart[i])).c_str(), + "eta vs pT vs p Positive", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + ue.add(("ResponseMatrix/" + std::string(EtavspvspTNegPart[i])).c_str(), + "eta vs pT vs p Negative", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + } // ===== Particle Fractions as function of p and pT ===== ue.add("ParticleFractions/hTotalCountsVsMomentumPos", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); @@ -498,13 +511,6 @@ void MultiplicityPt::init(InitContext const&) ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtNeg[i])).c_str(), "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); } - // pt vs p - ue.add( - "heta_vs_pt_vs_p_all_Neg", "eta_vs_pT_vs_p", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); - ue.add( - "heta_vs_pt_vs_p_all_Pos", "eta_vs_pT_vs_p", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); LOG(info) << "=== Initialization complete ==="; } @@ -753,24 +759,41 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, // dedx for all particles if (charge > 0) { ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); } else { ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); + } + + if (track.mcParticle().isPhysicalPrimary()) { + if (charge > 0) { + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri"), eta, track.pt(), momentum); + } else { + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri"), eta, track.pt(), momentum); + } } if (track.has_mcParticle()) { const auto& particle = track.mcParticle(); int pdgCode = std::abs(particle.pdgCode()); + if (particle.isPhysicalPrimary()) { + if (charge > 0) { + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC"), eta, track.pt(), momentum); + } else { + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC"), eta, track.pt(), momentum); + } + } if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { if (particle.isPhysicalPrimary()) { // Fill total counts for fractions if (charge > 0) { ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumPos"), eta, momentum); ue.fill(HIST("ParticleFractions/hTotalCountsVsPtPos"), eta, track.pt()); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC_Part"), eta, track.pt(), momentum); } else { ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumNeg"), eta, momentum); ue.fill(HIST("ParticleFractions/hTotalCountsVsPtNeg"), eta, track.pt()); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC_Part"), eta, track.pt(), momentum); } } } @@ -784,10 +807,12 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Pos"), eta, momentum); ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Pos"), eta, track.pt()); ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Pos"), eta, track.pt(), momentum); } else { ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Neg"), eta, momentum); ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Neg"), eta, track.pt()); ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Neg"), eta, track.pt(), momentum); } } else { @@ -801,9 +826,11 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, if (charge > 0) { ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Pos"), eta, momentum); ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Pos"), eta, track.pt()); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Pos"), eta, track.pt(), momentum); } else { ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Neg"), eta, momentum); ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Neg"), eta, track.pt()); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Neg"), eta, track.pt(), momentum); } } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); @@ -817,10 +844,12 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Pos"), eta, momentum); ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Pos"), eta, track.pt()); ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Pos"), eta, track.pt(), momentum); } else { ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Neg"), eta, momentum); ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Neg"), eta, track.pt()); ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); + ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Neg"), eta, track.pt(), momentum); } } else { ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); From ebacc3e3e8e75129e905684bf2330ba8eb082344 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Tue, 2 Jun 2026 15:12:20 -0600 Subject: [PATCH 06/11] Histograms with a fine binning was added --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index ef69d76fce9..9de888c5e35 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -69,6 +69,10 @@ static constexpr int NCentHists{10}; std::array, NCentHists> hDedxVsMomentumVsCentPos{}; std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; std::array, NCentHists + 1> hDedxVspTMomentumVsCent{}; +std::array, NCentHists + 1> hMomentumVsEtaPos{}; +std::array, NCentHists + 1> hMomentumVsEtaNeg{}; +std::array, NCentHists + 1> hpTVsEtaPos{}; +std::array, NCentHists + 1> hpTVsEtaNeg{}; struct DedxPidAnalysis { @@ -247,6 +251,8 @@ struct DedxPidAnalysis { static constexpr std::string_view DedxvsMomentumvsCentPos[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; static constexpr std::string_view DedxvsMomentumvsCentNeg[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses + 1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100", "dEdx_vs_pTMomentum_all_Pos"}; + // Fine binnind + static constexpr std::string_view Cent[CentralityClasses + 1] = {"Cent0_1", "Cent1_5", "Cent5_10", "Cent10_15", "Cent15_20", "Cent20_30", "Cent30_40", "Cent40_50", "Cent50_70", "Cent70_100", "MB"}; // Ncl TPC static constexpr std::string_view NclTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; static constexpr std::string_view NclTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; @@ -263,6 +269,7 @@ struct DedxPidAnalysis { Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; ConfigurableAxis centBins{"centBins", {100, 0, 100}, "Binning for centralidad"}; + ConfigurableAxis pFineBins{"pFineBins", {1995, 0.1, 40}, "Binning for momentum"}; // phi cut fits TF1* fphiCutHigh = nullptr; @@ -351,11 +358,13 @@ struct DedxPidAnalysis { LOGF(info, "Centrality clases between %.1f - %.1f", CentClasses[0], CentClasses[10]); AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; - AxisSpec ptAxis = {binP, "pT (GeV/c)"}; + AxisSpec ptAxis = {binP, "#it{p}_{T} (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; AxisSpec pAxisTrack = {binP, "#it{p} (GeV/c)"}; AxisSpec centAxis{centBins, "Undefined multiplicity estimator"}; + AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; + AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; switch (multiplicityEstimator) { case MultSelectionMode::NoMultiplicity: // No multiplicity LOGF(info, "No multiplicity estimator applied"); @@ -488,6 +497,10 @@ struct DedxPidAnalysis { for (int i = 0; i < CentralityClasses + 1; ++i) { hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + hMomentumVsEtaPos[i] = registryDeDx.add((std::string("p_vs_eta_") + std::string(Cent[i]) + "_Pos").c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hMomentumVsEtaNeg[i] = registryDeDx.add((std::string("p_vs_eta_") + std::string(Cent[i]) + "_Neg").c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hpTVsEtaPos[i] = registryDeDx.add((std::string("pT_vs_eta_") + std::string(Cent[i]) + "_Pos").c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + hpTVsEtaNeg[i] = registryDeDx.add((std::string("pT_vs_eta_") + std::string(Cent[i]) + "_Neg").c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); } // Invariant Mass @@ -1704,12 +1717,20 @@ struct DedxPidAnalysis { hDedxVsMomentumVsCentPos[centIndex]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); hDedxVspTMomentumVsCent[centIndex]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); hDedxVspTMomentumVsCent[10]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hMomentumVsEtaPos[centIndex]->Fill(trk.eta(), signedP); + hMomentumVsEtaPos[10]->Fill(trk.eta(), signedP); + hpTVsEtaPos[centIndex]->Fill(trk.eta(), signedpT); + hpTVsEtaPos[10]->Fill(trk.eta(), signedpT); } else { registryDeDx.fill(HIST(DedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Neg"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentNeg[centIndex]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); hDedxVspTMomentumVsCent[centIndex]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); hDedxVspTMomentumVsCent[10]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hMomentumVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedP)); + hMomentumVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedP)); + hpTVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedpT)); + hpTVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedpT)); } } } From 9d64323364f31f00929d74fe6c4ae4f109601405 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Tue, 2 Jun 2026 16:00:31 -0600 Subject: [PATCH 07/11] Added histograms with finer binning --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 263 +++++++++++++------------ 1 file changed, 135 insertions(+), 128 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 9de888c5e35..269895424bb 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -68,11 +68,11 @@ using BCsRun3 = soa::Join, NCentHists> hDedxVsMomentumVsCentPos{}; std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; -std::array, NCentHists + 1> hDedxVspTMomentumVsCent{}; -std::array, NCentHists + 1> hMomentumVsEtaPos{}; -std::array, NCentHists + 1> hMomentumVsEtaNeg{}; -std::array, NCentHists + 1> hpTVsEtaPos{}; -std::array, NCentHists + 1> hpTVsEtaNeg{}; +std::array, NCentHists+1> hDedxVspTMomentumVsCent{}; +std::array, NCentHists+1> hMomentumVsEtaPos{}; +std::array, NCentHists+1> hMomentumVsEtaNeg{}; +std::array, NCentHists+1> hpTVsEtaPos{}; +std::array, NCentHists+1> hpTVsEtaNeg{}; struct DedxPidAnalysis { @@ -200,11 +200,11 @@ struct DedxPidAnalysis { Configurable etaMin{"etaMin", -0.8f, "etaMin"}; Configurable etaMax{"etaMax", +0.8f, "etaMax"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; - Configurable nSigmaDCAxy{"nSigmaDCAxy", 3.0, "nSigma DCAxy selection"}; - Configurable dcaXYp0{"dcaXYp0", 0.0105f, "DCAxy formula: p0 + p1/pt^p2"}; - Configurable dcaXYp1{"dcaXYp1", 0.0350f, "DCAxy p1 parameter"}; - Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCA_xy p2 parameter"}; - Configurable nSigmaDCAz{"nSigmaDCAz", 3.0, "nSigma DCAz selection"}; + Configurable nSigmaDCAxy{"nSigmaDCAxy", 3.0, "nSigma DCAxy selection"}; + Configurable dcaXYp0{"dcaXYp0", 0.0105f, "DCAxy formula: p0 + p1/pt^p2"}; + Configurable dcaXYp1{"dcaXYp1", 0.0350f, "DCAxy p1 parameter"}; + Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCA_xy p2 parameter"}; + Configurable nSigmaDCAz{"nSigmaDCAz", 3.0, "nSigma DCAz selection"}; Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; // v0 cuts Configurable v0cospaMin{"v0cospaMin", 0.999f, "Minimum V0 CosPA"}; @@ -250,9 +250,12 @@ struct DedxPidAnalysis { static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; static constexpr std::string_view DedxvsMomentumvsCentPos[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; static constexpr std::string_view DedxvsMomentumvsCentNeg[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; - static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses + 1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100", "dEdx_vs_pTMomentum_all_Pos"}; - // Fine binnind - static constexpr std::string_view Cent[CentralityClasses + 1] = {"Cent0_1", "Cent1_5", "Cent5_10", "Cent10_15", "Cent15_20", "Cent20_30", "Cent30_40", "Cent40_50", "Cent50_70", "Cent70_100", "MB"}; + static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses+1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100","dEdx_vs_pTMomentum_all_Pos"}; + // Fine binnind + static constexpr std::string_view CentpPos[CentralityClasses+1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos","p_vs_eta_MB_Pos"}; + static constexpr std::string_view CentpNeg[CentralityClasses+1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg","p_vs_eta_MB_Neg"}; + static constexpr std::string_view CentpTPos[CentralityClasses+1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos","pT_vs_eta_MB_Pos"}; + static constexpr std::string_view CentpTNeg[CentralityClasses+1] = {"pT_vs_eta_Cent0_1_Neg", "pT_vs_eta_Cent1_5_Neg", "pT_vs_eta_Cent5_10_Neg", "pT_vs_eta_Cent10_15_Neg", "pT_vs_eta_Cent15_20_Neg", "pT_vs_eta_Cent20_30_Neg", "pT_vs_eta_Cent30_40_Neg", "pT_vs_eta_Cent40_50_Neg", "pT_vs_eta_Cent50_70_Neg", "pT_vs_eta_Cent70_100_Neg","pT_vs_eta_MB_Neg"}; // Ncl TPC static constexpr std::string_view NclTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; static constexpr std::string_view NclTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; @@ -288,15 +291,17 @@ struct DedxPidAnalysis { selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); - // selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); - // selectedTracks.SetMaxDcaZ(maxDCAz); + //selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); + //selectedTracks.SetMaxDcaZ(maxDCAz); selectedTracks.SetRequireGoldenChi2(true); return selectedTracks; } + TrackSelection mySelectionPrim; + void init(InitContext const&) { const char* label = "No INEL selection"; @@ -363,8 +368,8 @@ struct DedxPidAnalysis { AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; AxisSpec pAxisTrack = {binP, "#it{p} (GeV/c)"}; AxisSpec centAxis{centBins, "Undefined multiplicity estimator"}; - AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; - AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; + AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; + AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; switch (multiplicityEstimator) { case MultSelectionMode::NoMultiplicity: // No multiplicity LOGF(info, "No multiplicity estimator applied"); @@ -446,6 +451,7 @@ struct DedxPidAnalysis { "hdEdx_vs_eta_vs_p_Pos_TOF", "dE/dx", HistType::kTH3F, {{etaAxis}, {dedxAxis}, {pAxis}}); + } else { // MIP for pions registryDeDx.add( @@ -494,38 +500,38 @@ struct DedxPidAnalysis { hDedxVsMomentumVsCentPos[i] = registryDeDx.add(DedxvsMomentumvsCentPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(DedxvsMomentumvsCentNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } - - for (int i = 0; i < CentralityClasses + 1; ++i) { - hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); - hMomentumVsEtaPos[i] = registryDeDx.add((std::string("p_vs_eta_") + std::string(Cent[i]) + "_Pos").c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - hMomentumVsEtaNeg[i] = registryDeDx.add((std::string("p_vs_eta_") + std::string(Cent[i]) + "_Neg").c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - hpTVsEtaPos[i] = registryDeDx.add((std::string("pT_vs_eta_") + std::string(Cent[i]) + "_Pos").c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - hpTVsEtaNeg[i] = registryDeDx.add((std::string("pT_vs_eta_") + std::string(Cent[i]) + "_Neg").c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - } - - // Invariant Mass - registryDeDx.add("hMassK0s", "Invariant mass K0s;m_{#pi#pi} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 0.4, 0.6}}); - registryDeDx.add("hMassLambda", "Invariant mass #Lambda;m_{p#pi} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 1.08, 1.16}}); - registryDeDx.add("hMassAntiLambda", "Invariant mass #bar{#Lambda};m_{#bar{p}#pi} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 1.08, 1.16}}); - registryDeDx.add("hMassGamma", "Invariant mass #gamma;m_{ee} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 0.0, 0.1}}); - - // Armenteros-Podolanski plot - registryDeDx.add("hArmenterosAll", "Armenteros-Podolanski (all V0s);#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - - // Armenteros-Podolanski plot by particle - registryDeDx.add("hArmenterosK0s", "Armenteros-Podolanski K0s;#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - registryDeDx.add("hArmenterosLambda", "Armenteros-Podolanski #Lambda;#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - registryDeDx.add("hArmenterosAntiLambda", "Armenteros-Podolanski #bar{#Lambda};#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - registryDeDx.add("hArmenterosGamma", "Armenteros-Podolanski #gamma;#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + + for (int i = 0; i < CentralityClasses+1; ++i) { + hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + hMomentumVsEtaPos[i] = registryDeDx.add(CentpPos[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hMomentumVsEtaNeg[i] = registryDeDx.add(CentpNeg[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hpTVsEtaPos[i] = registryDeDx.add(CentpTPos[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + hpTVsEtaNeg[i] = registryDeDx.add(CentpTNeg[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + } + + // Invariant Mass + registryDeDx.add("hMassK0s", "Invariant mass K0s;m_{#pi#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 0.4, 0.6}}); + registryDeDx.add("hMassLambda", "Invariant mass #Lambda;m_{p#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 1.08, 1.16}}); + registryDeDx.add("hMassAntiLambda", "Invariant mass #bar{#Lambda};m_{#bar{p}#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 1.08, 1.16}}); + registryDeDx.add("hMassGamma", "Invariant mass #gamma;m_{ee} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 0.0, 0.1}}); + + // Armenteros-Podolanski plot + registryDeDx.add("hArmenterosAll", "Armenteros-Podolanski (all V0s);#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + + // Armenteros-Podolanski plot by particle + registryDeDx.add("hArmenterosK0s", "Armenteros-Podolanski K0s;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosLambda", "Armenteros-Podolanski #Lambda;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosAntiLambda", "Armenteros-Podolanski #bar{#Lambda};#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosGamma", "Armenteros-Podolanski #gamma;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); } registryDeDx.add( @@ -705,23 +711,24 @@ struct DedxPidAnalysis { // Tracks vs p registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F, {{ptAxis}}); registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F, {{ptAxis}}); - - // NCluster distributions - registryDeDx.add("hTPCClustersBefore", "N clusters TPC found Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, Before}"}}); - registryDeDx.add("hTPCClustersAfter", "N clusters TPC found After", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, After}"}}); - - registryDeDx.add("hTPCPIDBefore", "N clusters TPC PID Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, Before}"}}); - registryDeDx.add("hTPCPIDAfter", "N clusters TPC PID After", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, After}"}}); - - // DCA cut - registryDeDx.add("hDCAxyVsPt_before", "DCAxy vs pT before cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); - registryDeDx.add("hDCAzVsPt_before", "DCAz vs pT before cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); - registryDeDx.add("hDCAxyVsPt_after", "DCAxy vs pT after cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); - registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + + //NCluster distributions + registryDeDx.add("hTPCClustersBefore", "N clusters TPC found Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, Before}"}}); + registryDeDx.add("hTPCClustersAfter", "N clusters TPC found After", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, After}"}}); + + registryDeDx.add("hTPCPIDBefore", "N clusters TPC PID Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, Before}"}}); + registryDeDx.add("hTPCPIDAfter", "N clusters TPC PID After", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, After}"}}); + + //DCA cut + registryDeDx.add("hDCAxyVsPt_before", "DCAxy vs pT before cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); +registryDeDx.add("hDCAzVsPt_before", "DCAz vs pT before cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); +registryDeDx.add("hDCAxyVsPt_after", "DCAxy vs pT after cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); +registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); @@ -781,7 +788,7 @@ struct DedxPidAnalysis { xSec->SetBinLabel(V0TypeGamma, "V0TypeGamma"); xSec->SetBinLabel(V0RapidityGamma, "V0RapidityGamma"); xSec->SetBinLabel(MassCutGamma, "MassCutGamma"); - + mySelectionPrim = myTrackSelection(); } @@ -801,20 +808,20 @@ struct DedxPidAnalysis { return true; } - // DCA xy cut - template - bool passesDCAxyCut(const T1& track) const - { - const float maxDcaXY = nSigmaDCAxy.value * (dcaXYp0.value + dcaXYp1.value / std::pow(track.pt(), dcaXYp2.value)) / 3.0; - return std::abs(track.dcaXY()) < maxDcaXY; - } - // DCA z cut - template - bool passesDCAzCut(const T1& track) const - { - const float maxiDcaZ = nSigmaDCAz.value * (maxDCAz.value) / 3.0; - return std::abs(track.dcaZ()) < maxiDcaZ; - } + //DCA xy cut + template + bool passesDCAxyCut(const T1& track) const + { + const float maxDcaXY = nSigmaDCAxy.value * (dcaXYp0.value + dcaXYp1.value / std::pow(track.pt(), dcaXYp2.value))/3.0; + return std::abs(track.dcaXY()) < maxDcaXY; + } + //DCA z cut + template + bool passesDCAzCut(const T1& track) const + { + const float maxiDcaZ = nSigmaDCAz.value * (maxDCAz.value)/3.0; + return std::abs(track.dcaZ()) < maxiDcaZ; + } // Momentum template float getMomentum(const T1& track) @@ -881,7 +888,7 @@ struct DedxPidAnalysis { if (std::abs(sigman) > nsigmaMax) return false; } - + if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionK0s); @@ -1537,7 +1544,7 @@ struct DedxPidAnalysis { } if (nINELSelectionMode == NoSelINEL) { - registryDeDx.fill(HIST("evsel"), EvCutLabel::INELgt); + registryDeDx.fill(HIST("evsel"), EvCutLabel::INELgt); } else if (nINELSelectionMode == SelINELgt0) { if (!collision.isInelGt0()) return; @@ -1566,27 +1573,27 @@ struct DedxPidAnalysis { for (const auto& trk : tracks) { registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::AllPri); - // Ncl distribution before cuts - registryDeDx.fill(HIST("hTPCClustersBefore"), trk.tpcNClsFound()); - registryDeDx.fill(HIST("hTPCPIDBefore"), trk.tpcNClsPID()); - + // Ncl distribution before cuts + registryDeDx.fill(HIST("hTPCClustersBefore"), trk.tpcNClsFound()); + registryDeDx.fill(HIST("hTPCPIDBefore"), trk.tpcNClsPID()); + // track Selection wo DCA if (!mySelectionPrim.IsSelected(trk)) continue; - - // Before DCA cuts - registryDeDx.fill(HIST("hDCAxyVsPt_before"), trk.pt(), trk.dcaXY()); - registryDeDx.fill(HIST("hDCAzVsPt_before"), trk.pt(), trk.dcaZ()); - - // DCA cuts - if (!passesDCAxyCut(trk)) - continue; - if (!passesDCAzCut(trk)) - continue; - - // After DCA cuts - registryDeDx.fill(HIST("hDCAxyVsPt_after"), trk.pt(), trk.dcaXY()); - registryDeDx.fill(HIST("hDCAzVsPt_after"), trk.pt(), trk.dcaZ()); + + // Before DCA cuts + registryDeDx.fill(HIST("hDCAxyVsPt_before"), trk.pt(), trk.dcaXY()); + registryDeDx.fill(HIST("hDCAzVsPt_before"), trk.pt(), trk.dcaZ()); + + // DCA cuts + if (!passesDCAxyCut(trk)) + continue; + if (!passesDCAzCut(trk)) + continue; + + // After DCA cuts + registryDeDx.fill(HIST("hDCAxyVsPt_after"), trk.pt(), trk.dcaXY()); + registryDeDx.fill(HIST("hDCAzVsPt_after"), trk.pt(), trk.dcaZ()); registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); // For pt @@ -1620,10 +1627,10 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); // For pt + cuts registryDeDx.fill(HIST("Tracks_vs_pT_all_cuts"), trk.pt()); - - // Ncl distribution After all cuts - registryDeDx.fill(HIST("hTPCClustersAfter"), trk.tpcNClsFound()); - registryDeDx.fill(HIST("hTPCPIDAfter"), trk.tpcNClsPID()); + + // Ncl distribution After all cuts + registryDeDx.fill(HIST("hTPCClustersAfter"), trk.tpcNClsFound()); + registryDeDx.fill(HIST("hTPCPIDAfter"), trk.tpcNClsPID()); float signedP = trk.sign() * getMomentum(trk); float signedpT = trk.sign() * trk.pt(); @@ -1715,22 +1722,22 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST(DedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Pos"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentPos[centIndex]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - hDedxVspTMomentumVsCent[centIndex]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - hDedxVspTMomentumVsCent[10]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - hMomentumVsEtaPos[centIndex]->Fill(trk.eta(), signedP); - hMomentumVsEtaPos[10]->Fill(trk.eta(), signedP); - hpTVsEtaPos[centIndex]->Fill(trk.eta(), signedpT); - hpTVsEtaPos[10]->Fill(trk.eta(), signedpT); + hDedxVspTMomentumVsCent[centIndex]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hDedxVspTMomentumVsCent[10]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hMomentumVsEtaPos[centIndex]->Fill(trk.eta(), signedP); + hMomentumVsEtaPos[10]->Fill(trk.eta(), signedP); + hpTVsEtaPos[centIndex]->Fill(trk.eta(), signedpT); + hpTVsEtaPos[10]->Fill(trk.eta(), signedpT); } else { registryDeDx.fill(HIST(DedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Neg"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentNeg[centIndex]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - hDedxVspTMomentumVsCent[centIndex]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - hDedxVspTMomentumVsCent[10]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - hMomentumVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedP)); - hMomentumVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedP)); - hpTVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedpT)); - hpTVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedpT)); + hDedxVspTMomentumVsCent[centIndex]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hDedxVspTMomentumVsCent[10]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hMomentumVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedP)); + hMomentumVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedP)); + hpTVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedpT)); + hpTVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedpT)); } } } @@ -1823,9 +1830,9 @@ struct DedxPidAnalysis { float signedPneg = negTrack.sign() * getMomentum(negTrack); fillHist = true; - - // Armenteros for all V0 - registryDeDx.fill(HIST("hArmenterosAll"), v0.alpha(), v0.qtarm()); + + // Armenteros for all V0 + registryDeDx.fill(HIST("hArmenterosAll"), v0.alpha(), v0.qtarm()); // K0s Selection if (passedK0Selection(v0, negTrack, posTrack, collision)) { @@ -1833,8 +1840,8 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsK0s"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassK0s"), v0.mK0Short()); - registryDeDx.fill(HIST("hArmenterosK0s"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassK0s"), v0.mK0Short()); + registryDeDx.fill(HIST("hArmenterosK0s"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1851,8 +1858,8 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassLambda"), v0.mLambda()); - registryDeDx.fill(HIST("hArmenterosLambda"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassLambda"), v0.mLambda()); + registryDeDx.fill(HIST("hArmenterosLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1869,8 +1876,8 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassAntiLambda"), v0.mAntiLambda()); - registryDeDx.fill(HIST("hArmenterosAntiLambda"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassAntiLambda"), v0.mAntiLambda()); + registryDeDx.fill(HIST("hArmenterosAntiLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1887,8 +1894,8 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassGamma"), v0.mGamma()); - registryDeDx.fill(HIST("hArmenterosGamma"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassGamma"), v0.mGamma()); + registryDeDx.fill(HIST("hArmenterosGamma"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); From 5a06c3b1636be2ebe3b76921c4f0395fb9479a47 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Tue, 2 Jun 2026 16:01:38 -0600 Subject: [PATCH 08/11] Added histograms with finer binning --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 266 ++++++++++++------------- 1 file changed, 131 insertions(+), 135 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 269895424bb..f38ea80f6ef 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -68,11 +68,11 @@ using BCsRun3 = soa::Join, NCentHists> hDedxVsMomentumVsCentPos{}; std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; -std::array, NCentHists+1> hDedxVspTMomentumVsCent{}; -std::array, NCentHists+1> hMomentumVsEtaPos{}; -std::array, NCentHists+1> hMomentumVsEtaNeg{}; -std::array, NCentHists+1> hpTVsEtaPos{}; -std::array, NCentHists+1> hpTVsEtaNeg{}; +std::array, NCentHists + 1> hDedxVspTMomentumVsCent{}; +std::array, NCentHists + 1> hMomentumVsEtaPos{}; +std::array, NCentHists + 1> hMomentumVsEtaNeg{}; +std::array, NCentHists + 1> hpTVsEtaPos{}; +std::array, NCentHists + 1> hpTVsEtaNeg{}; struct DedxPidAnalysis { @@ -200,11 +200,11 @@ struct DedxPidAnalysis { Configurable etaMin{"etaMin", -0.8f, "etaMin"}; Configurable etaMax{"etaMax", +0.8f, "etaMax"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; - Configurable nSigmaDCAxy{"nSigmaDCAxy", 3.0, "nSigma DCAxy selection"}; - Configurable dcaXYp0{"dcaXYp0", 0.0105f, "DCAxy formula: p0 + p1/pt^p2"}; - Configurable dcaXYp1{"dcaXYp1", 0.0350f, "DCAxy p1 parameter"}; - Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCA_xy p2 parameter"}; - Configurable nSigmaDCAz{"nSigmaDCAz", 3.0, "nSigma DCAz selection"}; + Configurable nSigmaDCAxy{"nSigmaDCAxy", 3.0, "nSigma DCAxy selection"}; + Configurable dcaXYp0{"dcaXYp0", 0.0105f, "DCAxy formula: p0 + p1/pt^p2"}; + Configurable dcaXYp1{"dcaXYp1", 0.0350f, "DCAxy p1 parameter"}; + Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCA_xy p2 parameter"}; + Configurable nSigmaDCAz{"nSigmaDCAz", 3.0, "nSigma DCAz selection"}; Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; // v0 cuts Configurable v0cospaMin{"v0cospaMin", 0.999f, "Minimum V0 CosPA"}; @@ -250,12 +250,12 @@ struct DedxPidAnalysis { static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; static constexpr std::string_view DedxvsMomentumvsCentPos[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; static constexpr std::string_view DedxvsMomentumvsCentNeg[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; - static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses+1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100","dEdx_vs_pTMomentum_all_Pos"}; - // Fine binnind - static constexpr std::string_view CentpPos[CentralityClasses+1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos","p_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpNeg[CentralityClasses+1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg","p_vs_eta_MB_Neg"}; - static constexpr std::string_view CentpTPos[CentralityClasses+1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos","pT_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpTNeg[CentralityClasses+1] = {"pT_vs_eta_Cent0_1_Neg", "pT_vs_eta_Cent1_5_Neg", "pT_vs_eta_Cent5_10_Neg", "pT_vs_eta_Cent10_15_Neg", "pT_vs_eta_Cent15_20_Neg", "pT_vs_eta_Cent20_30_Neg", "pT_vs_eta_Cent30_40_Neg", "pT_vs_eta_Cent40_50_Neg", "pT_vs_eta_Cent50_70_Neg", "pT_vs_eta_Cent70_100_Neg","pT_vs_eta_MB_Neg"}; + static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses + 1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100", "dEdx_vs_pTMomentum_all_Pos"}; + // Fine binnind + static constexpr std::string_view CentpPos[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos", "p_vs_eta_MB_Pos"}; + static constexpr std::string_view CentpNeg[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg", "p_vs_eta_MB_Neg"}; + static constexpr std::string_view CentpTPos[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos", "pT_vs_eta_MB_Pos"}; + static constexpr std::string_view CentpTNeg[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Neg", "pT_vs_eta_Cent1_5_Neg", "pT_vs_eta_Cent5_10_Neg", "pT_vs_eta_Cent10_15_Neg", "pT_vs_eta_Cent15_20_Neg", "pT_vs_eta_Cent20_30_Neg", "pT_vs_eta_Cent30_40_Neg", "pT_vs_eta_Cent40_50_Neg", "pT_vs_eta_Cent50_70_Neg", "pT_vs_eta_Cent70_100_Neg", "pT_vs_eta_MB_Neg"}; // Ncl TPC static constexpr std::string_view NclTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; static constexpr std::string_view NclTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; @@ -291,17 +291,15 @@ struct DedxPidAnalysis { selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); - //selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); - //selectedTracks.SetMaxDcaZ(maxDCAz); + // selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); + // selectedTracks.SetMaxDcaZ(maxDCAz); selectedTracks.SetRequireGoldenChi2(true); return selectedTracks; } - TrackSelection mySelectionPrim; - void init(InitContext const&) { const char* label = "No INEL selection"; @@ -368,8 +366,8 @@ struct DedxPidAnalysis { AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; AxisSpec pAxisTrack = {binP, "#it{p} (GeV/c)"}; AxisSpec centAxis{centBins, "Undefined multiplicity estimator"}; - AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; - AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; + AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; + AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; switch (multiplicityEstimator) { case MultSelectionMode::NoMultiplicity: // No multiplicity LOGF(info, "No multiplicity estimator applied"); @@ -451,7 +449,6 @@ struct DedxPidAnalysis { "hdEdx_vs_eta_vs_p_Pos_TOF", "dE/dx", HistType::kTH3F, {{etaAxis}, {dedxAxis}, {pAxis}}); - } else { // MIP for pions registryDeDx.add( @@ -500,38 +497,38 @@ struct DedxPidAnalysis { hDedxVsMomentumVsCentPos[i] = registryDeDx.add(DedxvsMomentumvsCentPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(DedxvsMomentumvsCentNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } - - for (int i = 0; i < CentralityClasses+1; ++i) { - hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); - hMomentumVsEtaPos[i] = registryDeDx.add(CentpPos[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - hMomentumVsEtaNeg[i] = registryDeDx.add(CentpNeg[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - hpTVsEtaPos[i] = registryDeDx.add(CentpTPos[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - hpTVsEtaNeg[i] = registryDeDx.add(CentpTNeg[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - } - - // Invariant Mass - registryDeDx.add("hMassK0s", "Invariant mass K0s;m_{#pi#pi} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 0.4, 0.6}}); - registryDeDx.add("hMassLambda", "Invariant mass #Lambda;m_{p#pi} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 1.08, 1.16}}); - registryDeDx.add("hMassAntiLambda", "Invariant mass #bar{#Lambda};m_{#bar{p}#pi} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 1.08, 1.16}}); - registryDeDx.add("hMassGamma", "Invariant mass #gamma;m_{ee} (GeV/c^{2});Counts", - HistType::kTH1F, {{200, 0.0, 0.1}}); - - // Armenteros-Podolanski plot - registryDeDx.add("hArmenterosAll", "Armenteros-Podolanski (all V0s);#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - - // Armenteros-Podolanski plot by particle - registryDeDx.add("hArmenterosK0s", "Armenteros-Podolanski K0s;#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - registryDeDx.add("hArmenterosLambda", "Armenteros-Podolanski #Lambda;#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - registryDeDx.add("hArmenterosAntiLambda", "Armenteros-Podolanski #bar{#Lambda};#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); - registryDeDx.add("hArmenterosGamma", "Armenteros-Podolanski #gamma;#alpha;q_{T} (GeV/c)", - HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + + for (int i = 0; i < CentralityClasses + 1; ++i) { + hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + hMomentumVsEtaPos[i] = registryDeDx.add(CentpPos[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hMomentumVsEtaNeg[i] = registryDeDx.add(CentpNeg[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hpTVsEtaPos[i] = registryDeDx.add(CentpTPos[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + hpTVsEtaNeg[i] = registryDeDx.add(CentpTNeg[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + } + + // Invariant Mass + registryDeDx.add("hMassK0s", "Invariant mass K0s;m_{#pi#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 0.4, 0.6}}); + registryDeDx.add("hMassLambda", "Invariant mass #Lambda;m_{p#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 1.08, 1.16}}); + registryDeDx.add("hMassAntiLambda", "Invariant mass #bar{#Lambda};m_{#bar{p}#pi} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 1.08, 1.16}}); + registryDeDx.add("hMassGamma", "Invariant mass #gamma;m_{ee} (GeV/c^{2});Counts", + HistType::kTH1F, {{200, 0.0, 0.1}}); + + // Armenteros-Podolanski plot + registryDeDx.add("hArmenterosAll", "Armenteros-Podolanski (all V0s);#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + + // Armenteros-Podolanski plot by particle + registryDeDx.add("hArmenterosK0s", "Armenteros-Podolanski K0s;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosLambda", "Armenteros-Podolanski #Lambda;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosAntiLambda", "Armenteros-Podolanski #bar{#Lambda};#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); + registryDeDx.add("hArmenterosGamma", "Armenteros-Podolanski #gamma;#alpha;q_{T} (GeV/c)", + HistType::kTH2F, {{200, -1, 1}, {200, 0, 0.3}}); } registryDeDx.add( @@ -711,24 +708,23 @@ struct DedxPidAnalysis { // Tracks vs p registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F, {{ptAxis}}); registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F, {{ptAxis}}); - - //NCluster distributions - registryDeDx.add("hTPCClustersBefore", "N clusters TPC found Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, Before}"}}); - registryDeDx.add("hTPCClustersAfter", "N clusters TPC found After", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, After}"}}); - - registryDeDx.add("hTPCPIDBefore", "N clusters TPC PID Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, Before}"}}); - registryDeDx.add("hTPCPIDAfter", "N clusters TPC PID After", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, After}"}}); - - //DCA cut - registryDeDx.add("hDCAxyVsPt_before", "DCAxy vs pT before cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); -registryDeDx.add("hDCAzVsPt_before", "DCAz vs pT before cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); -registryDeDx.add("hDCAxyVsPt_after", "DCAxy vs pT after cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); -registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); - + + // NCluster distributions + registryDeDx.add("hTPCClustersBefore", "N clusters TPC found Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, Before}"}}); + registryDeDx.add("hTPCClustersAfter", "N clusters TPC found After", HistType::kTH1F, {{200, 0, 200, "N_{cl,found, After}"}}); + + registryDeDx.add("hTPCPIDBefore", "N clusters TPC PID Before", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, Before}"}}); + registryDeDx.add("hTPCPIDAfter", "N clusters TPC PID After", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, After}"}}); + + // DCA cut + registryDeDx.add("hDCAxyVsPt_before", "DCAxy vs pT before cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + registryDeDx.add("hDCAzVsPt_before", "DCAz vs pT before cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + registryDeDx.add("hDCAxyVsPt_after", "DCAxy vs pT after cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); @@ -788,7 +784,7 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA xSec->SetBinLabel(V0TypeGamma, "V0TypeGamma"); xSec->SetBinLabel(V0RapidityGamma, "V0RapidityGamma"); xSec->SetBinLabel(MassCutGamma, "MassCutGamma"); - + mySelectionPrim = myTrackSelection(); } @@ -808,20 +804,20 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA return true; } - //DCA xy cut - template - bool passesDCAxyCut(const T1& track) const - { - const float maxDcaXY = nSigmaDCAxy.value * (dcaXYp0.value + dcaXYp1.value / std::pow(track.pt(), dcaXYp2.value))/3.0; - return std::abs(track.dcaXY()) < maxDcaXY; - } - //DCA z cut - template - bool passesDCAzCut(const T1& track) const - { - const float maxiDcaZ = nSigmaDCAz.value * (maxDCAz.value)/3.0; - return std::abs(track.dcaZ()) < maxiDcaZ; - } + // DCA xy cut + template + bool passesDCAxyCut(const T1& track) const + { + const float maxDcaXY = nSigmaDCAxy.value * (dcaXYp0.value + dcaXYp1.value / std::pow(track.pt(), dcaXYp2.value)) / 3.0; + return std::abs(track.dcaXY()) < maxDcaXY; + } + // DCA z cut + template + bool passesDCAzCut(const T1& track) const + { + const float maxiDcaZ = nSigmaDCAz.value * (maxDCAz.value) / 3.0; + return std::abs(track.dcaZ()) < maxiDcaZ; + } // Momentum template float getMomentum(const T1& track) @@ -888,7 +884,7 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA if (std::abs(sigman) > nsigmaMax) return false; } - + if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionK0s); @@ -1544,7 +1540,7 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA } if (nINELSelectionMode == NoSelINEL) { - registryDeDx.fill(HIST("evsel"), EvCutLabel::INELgt); + registryDeDx.fill(HIST("evsel"), EvCutLabel::INELgt); } else if (nINELSelectionMode == SelINELgt0) { if (!collision.isInelGt0()) return; @@ -1573,27 +1569,27 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA for (const auto& trk : tracks) { registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::AllPri); - // Ncl distribution before cuts - registryDeDx.fill(HIST("hTPCClustersBefore"), trk.tpcNClsFound()); - registryDeDx.fill(HIST("hTPCPIDBefore"), trk.tpcNClsPID()); - + // Ncl distribution before cuts + registryDeDx.fill(HIST("hTPCClustersBefore"), trk.tpcNClsFound()); + registryDeDx.fill(HIST("hTPCPIDBefore"), trk.tpcNClsPID()); + // track Selection wo DCA if (!mySelectionPrim.IsSelected(trk)) continue; - - // Before DCA cuts - registryDeDx.fill(HIST("hDCAxyVsPt_before"), trk.pt(), trk.dcaXY()); - registryDeDx.fill(HIST("hDCAzVsPt_before"), trk.pt(), trk.dcaZ()); - - // DCA cuts - if (!passesDCAxyCut(trk)) - continue; - if (!passesDCAzCut(trk)) - continue; - - // After DCA cuts - registryDeDx.fill(HIST("hDCAxyVsPt_after"), trk.pt(), trk.dcaXY()); - registryDeDx.fill(HIST("hDCAzVsPt_after"), trk.pt(), trk.dcaZ()); + + // Before DCA cuts + registryDeDx.fill(HIST("hDCAxyVsPt_before"), trk.pt(), trk.dcaXY()); + registryDeDx.fill(HIST("hDCAzVsPt_before"), trk.pt(), trk.dcaZ()); + + // DCA cuts + if (!passesDCAxyCut(trk)) + continue; + if (!passesDCAzCut(trk)) + continue; + + // After DCA cuts + registryDeDx.fill(HIST("hDCAxyVsPt_after"), trk.pt(), trk.dcaXY()); + registryDeDx.fill(HIST("hDCAzVsPt_after"), trk.pt(), trk.dcaZ()); registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); // For pt @@ -1627,10 +1623,10 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); // For pt + cuts registryDeDx.fill(HIST("Tracks_vs_pT_all_cuts"), trk.pt()); - - // Ncl distribution After all cuts - registryDeDx.fill(HIST("hTPCClustersAfter"), trk.tpcNClsFound()); - registryDeDx.fill(HIST("hTPCPIDAfter"), trk.tpcNClsPID()); + + // Ncl distribution After all cuts + registryDeDx.fill(HIST("hTPCClustersAfter"), trk.tpcNClsFound()); + registryDeDx.fill(HIST("hTPCPIDAfter"), trk.tpcNClsPID()); float signedP = trk.sign() * getMomentum(trk); float signedpT = trk.sign() * trk.pt(); @@ -1722,22 +1718,22 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA registryDeDx.fill(HIST(DedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Pos"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentPos[centIndex]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - hDedxVspTMomentumVsCent[centIndex]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - hDedxVspTMomentumVsCent[10]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - hMomentumVsEtaPos[centIndex]->Fill(trk.eta(), signedP); - hMomentumVsEtaPos[10]->Fill(trk.eta(), signedP); - hpTVsEtaPos[centIndex]->Fill(trk.eta(), signedpT); - hpTVsEtaPos[10]->Fill(trk.eta(), signedpT); + hDedxVspTMomentumVsCent[centIndex]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hDedxVspTMomentumVsCent[10]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hMomentumVsEtaPos[centIndex]->Fill(trk.eta(), signedP); + hMomentumVsEtaPos[10]->Fill(trk.eta(), signedP); + hpTVsEtaPos[centIndex]->Fill(trk.eta(), signedpT); + hpTVsEtaPos[10]->Fill(trk.eta(), signedpT); } else { registryDeDx.fill(HIST(DedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Neg"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentNeg[centIndex]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - hDedxVspTMomentumVsCent[centIndex]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - hDedxVspTMomentumVsCent[10]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - hMomentumVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedP)); - hMomentumVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedP)); - hpTVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedpT)); - hpTVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedpT)); + hDedxVspTMomentumVsCent[centIndex]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hDedxVspTMomentumVsCent[10]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hMomentumVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedP)); + hMomentumVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedP)); + hpTVsEtaNeg[centIndex]->Fill(trk.eta(), std::abs(signedpT)); + hpTVsEtaNeg[10]->Fill(trk.eta(), std::abs(signedpT)); } } } @@ -1830,9 +1826,9 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA float signedPneg = negTrack.sign() * getMomentum(negTrack); fillHist = true; - - // Armenteros for all V0 - registryDeDx.fill(HIST("hArmenterosAll"), v0.alpha(), v0.qtarm()); + + // Armenteros for all V0 + registryDeDx.fill(HIST("hArmenterosAll"), v0.alpha(), v0.qtarm()); // K0s Selection if (passedK0Selection(v0, negTrack, posTrack, collision)) { @@ -1840,8 +1836,8 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsK0s"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassK0s"), v0.mK0Short()); - registryDeDx.fill(HIST("hArmenterosK0s"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassK0s"), v0.mK0Short()); + registryDeDx.fill(HIST("hArmenterosK0s"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1858,8 +1854,8 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassLambda"), v0.mLambda()); - registryDeDx.fill(HIST("hArmenterosLambda"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassLambda"), v0.mLambda()); + registryDeDx.fill(HIST("hArmenterosLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1876,8 +1872,8 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassAntiLambda"), v0.mAntiLambda()); - registryDeDx.fill(HIST("hArmenterosAntiLambda"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassAntiLambda"), v0.mAntiLambda()); + registryDeDx.fill(HIST("hArmenterosAntiLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1894,8 +1890,8 @@ registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.p(), negTrack.tpcNClsPID()); - registryDeDx.fill(HIST("hMassGamma"), v0.mGamma()); - registryDeDx.fill(HIST("hArmenterosGamma"), v0.alpha(), v0.qtarm()); + registryDeDx.fill(HIST("hMassGamma"), v0.mGamma()); + registryDeDx.fill(HIST("hArmenterosGamma"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(DedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); From a08db2b6ae7f7bdf0e6583798bcb16ecc0dfa7c1 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Tue, 9 Jun 2026 15:12:07 -0600 Subject: [PATCH 09/11] Added histograms with finer binning for MC and make momentum configurable --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 5 +- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 129 ++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index f38ea80f6ef..3181a09495d 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -251,7 +251,7 @@ struct DedxPidAnalysis { static constexpr std::string_view DedxvsMomentumvsCentPos[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; static constexpr std::string_view DedxvsMomentumvsCentNeg[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses + 1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100", "dEdx_vs_pTMomentum_all_Pos"}; - // Fine binnind + // Fine binning static constexpr std::string_view CentpPos[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos", "p_vs_eta_MB_Pos"}; static constexpr std::string_view CentpNeg[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg", "p_vs_eta_MB_Neg"}; static constexpr std::string_view CentpTPos[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos", "pT_vs_eta_MB_Pos"}; @@ -272,6 +272,7 @@ struct DedxPidAnalysis { Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; ConfigurableAxis centBins{"centBins", {100, 0, 100}, "Binning for centralidad"}; + ConfigurableAxis dedxBins{"dedxBins", {100, 0, 100}, "Binning for dedx"}; ConfigurableAxis pFineBins{"pFineBins", {1995, 0.1, 40}, "Binning for momentum"}; // phi cut fits @@ -360,7 +361,7 @@ struct DedxPidAnalysis { } LOGF(info, "Centrality clases between %.1f - %.1f", CentClasses[0], CentClasses[10]); - AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; + AxisSpec dedxAxis = {dedxBins, "dE/dx (a. u.)"}; AxisSpec ptAxis = {binP, "#it{p}_{T} (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index b43f8b1895f..c75d5273692 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -70,6 +70,7 @@ struct MultiplicityPt { static constexpr int RecMultBinMax = 100; static constexpr int ParticlesType = 4; static constexpr int ResponseMatrixTypes = 7; + static constexpr int CentralityClasses = 10; enum INELCutSelection : int { INEL = 0, @@ -114,6 +115,11 @@ struct MultiplicityPt { Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; + ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; + ConfigurableAxis pFineBins{"pFineBins", {1995, 0.1, 40}, "Binning for momentum"}; + ConfigurableAxis dedxBins{"dedxBins", {100, 0, 100}, "Binning for dedx"}; + + std::vector centBinningStd = {0., 1., 5., 10., 15., 20., 30., 40., 50., 70., 100.}; // Histogram names for V0s dE/dx analysis static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; @@ -128,6 +134,12 @@ struct MultiplicityPt { static constexpr std::string_view ParticleFractionsVsPtNeg[ParticlesType + 1] = {"hFractionVsPt_Pion_Neg", "hFractionVsPt_Kaon_Neg", "hFractionVsPt_Proton_Neg", "hFractionVsPt_Electron_Neg", "hFractionVsPt_Muon_Neg"}; + // Fine binning + static constexpr std::string_view CentpPos[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos", "p_vs_eta_MB_Pos"}; + static constexpr std::string_view CentpNeg[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg", "p_vs_eta_MB_Neg"}; + static constexpr std::string_view CentpTPos[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos", "pT_vs_eta_MB_Pos"}; + static constexpr std::string_view CentpTNeg[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Neg", "pT_vs_eta_Cent1_5_Neg", "pT_vs_eta_Cent5_10_Neg", "pT_vs_eta_Cent10_15_Neg", "pT_vs_eta_Cent15_20_Neg", "pT_vs_eta_Cent20_30_Neg", "pT_vs_eta_Cent30_40_Neg", "pT_vs_eta_Cent40_50_Neg", "pT_vs_eta_Cent50_70_Neg", "pT_vs_eta_Cent70_100_Neg", "pT_vs_eta_MB_Neg"}; + TrackSelection customTrackCuts; TF1* fphiCutLow = nullptr; TF1* fphiCutHigh = nullptr; @@ -360,13 +372,12 @@ void MultiplicityPt::init(InitContext const&) } // Axis definitions - ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; + AxisSpec dedxAxis = {dedxBins, "dE/dx (a. u.)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; - - std::vector centBinningStd = {0., 1., 5., 10., 15., 20., 30., 40., 50., 60., 70., 80., 90., 100.}; + AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; + AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; AxisSpec centAxis = {centBinningStd, "FT0M Centrality (%)"}; std::vector centBinningFine; @@ -496,6 +507,13 @@ void MultiplicityPt::init(InitContext const&) {{etaAxis}, {ptAxis}, {pAxis}}); } + for (int i = 0; i < CentralityClasses + 1; ++i) { + ue.add(("Binning/" + std::string(CentpPos[i])).c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + ue.add(("Binning/" + std::string(CentpNeg[i])).c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + ue.add(("Binning/" + std::string(CentpTPos[i])).c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + ue.add(("Binning/" + std::string(CentpTNeg[i])).c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + } + // ===== Particle Fractions as function of p and pT ===== ue.add("ParticleFractions/hTotalCountsVsMomentumPos", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); ue.add("ParticleFractions/hTotalCountsVsPtPos", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {ptAxis}}); @@ -757,13 +775,116 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, float eta = track.eta(); int charge = track.sign(); + int centIndex = -1; + for (int j = 0; j < CentralityClasses; ++j) { + if (cent >= centBinningStd[j] && cent < centBinningStd[j + 1]) { + centIndex = j; + break; + } + } + if (centIndex == -1) + continue; + // dedx for all particles if (charge > 0) { ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); + // binning + ue.fill(HIST("Binning/p_vs_eta_MB_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_MB_Pos"), eta, track.pt()); + + // For centrality + switch (centIndex) { + case 0: + ue.fill(HIST("Binning/p_vs_eta_Cent0_1_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent0_1_Pos"), eta, track.pt()); + break; + case 1: + ue.fill(HIST("Binning/p_vs_eta_Cent1_5_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent1_5_Pos"), eta, track.pt()); + break; + case 2: + ue.fill(HIST("Binning/p_vs_eta_Cent5_10_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent5_10_Pos"), eta, track.pt()); + break; + case 3: + ue.fill(HIST("Binning/p_vs_eta_Cent10_15_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent10_15_Pos"), eta, track.pt()); + break; + case 4: + ue.fill(HIST("Binning/p_vs_eta_Cent15_20_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent15_20_Pos"), eta, track.pt()); + break; + case 5: + ue.fill(HIST("Binning/p_vs_eta_Cent20_30_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent20_30_Pos"), eta, track.pt()); + break; + case 6: + ue.fill(HIST("Binning/p_vs_eta_Cent30_40_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent30_40_Pos"), eta, track.pt()); + break; + case 7: + ue.fill(HIST("Binning/p_vs_eta_Cent40_50_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent40_50_Pos"), eta, track.pt()); + break; + case 8: + ue.fill(HIST("Binning/p_vs_eta_Cent50_70_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent50_70_Pos"), eta, track.pt()); + break; + case 9: + ue.fill(HIST("Binning/p_vs_eta_Cent70_100_Pos"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent70_100_Pos"), eta, track.pt()); + break; + } } else { ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); + // binning + ue.fill(HIST("Binning/p_vs_eta_MB_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_MB_Neg"), eta, track.pt()); + + switch (centIndex) { + case 0: + ue.fill(HIST("Binning/p_vs_eta_Cent0_1_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent0_1_Neg"), eta, track.pt()); + break; + case 1: + ue.fill(HIST("Binning/p_vs_eta_Cent1_5_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent1_5_Neg"), eta, track.pt()); + break; + case 2: + ue.fill(HIST("Binning/p_vs_eta_Cent5_10_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent5_10_Neg"), eta, track.pt()); + break; + case 3: + ue.fill(HIST("Binning/p_vs_eta_Cent10_15_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent10_15_Neg"), eta, track.pt()); + break; + case 4: + ue.fill(HIST("Binning/p_vs_eta_Cent15_20_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent15_20_Neg"), eta, track.pt()); + break; + case 5: + ue.fill(HIST("Binning/p_vs_eta_Cent20_30_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent20_30_Neg"), eta, track.pt()); + break; + case 6: + ue.fill(HIST("Binning/p_vs_eta_Cent30_40_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent30_40_Neg"), eta, track.pt()); + break; + case 7: + ue.fill(HIST("Binning/p_vs_eta_Cent40_50_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent40_50_Neg"), eta, track.pt()); + break; + case 8: + ue.fill(HIST("Binning/p_vs_eta_Cent50_70_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent50_70_Neg"), eta, track.pt()); + break; + case 9: + ue.fill(HIST("Binning/p_vs_eta_Cent70_100_Neg"), eta, momentum); + ue.fill(HIST("Binning/pT_vs_eta_Cent70_100_Neg"), eta, track.pt()); + break; + } } if (track.mcParticle().isPhysicalPrimary()) { From b4bccef7aacc4ae73725914f9d2d757a021062a8 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Thu, 11 Jun 2026 22:09:25 -0600 Subject: [PATCH 10/11] Debug analysis --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 2131 +++++++++++++++---------- 1 file changed, 1281 insertions(+), 850 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index c75d5273692..e721b655ac3 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -13,78 +13,133 @@ /// \file multiplicityPt.cxx /// \brief Analysis to do PID with MC - Full correction factors for pions, kaons, protons +#include "PWGLF/DataModel/LFParticleIdentification.h" #include "PWGLF/DataModel/mcCentrality.h" +#include "PWGLF/DataModel/spectraTOF.h" #include "PWGLF/Utils/inelGt.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/McCollisionExtra.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/Logger.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "TMCProcess.h" +#include "TPDGCode.h" #include -#include -#include #include +#include #include -#include -#include #include +#include +#include #include #include -#include -#include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using namespace o2::constants::math; -using namespace constants::physics; using BCsRun3 = soa::Join; +// Reconstructed collisions joined with MC label + centrality +using ColEvSelsMC = soa::Join; + +// Data collision table (for processData) +using CollisionTableData = soa::Join; + +// Track tables - with TPC PID only +using TrackTableData = soa::Join; + +using TracksMC = soa::Join; + +static constexpr int NCentHists{10}; +static constexpr int NPartHists{5}; +std::array, NCentHists> hDedxVsMomentumVsCentPos{}; +std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; +std::array, NCentHists + 1> hDedxVspTMomentumVsCent{}; +std::array, NCentHists + 1> hMomentumVsEtaPos{}; +std::array, NCentHists + 1> hMomentumVsEtaNeg{}; +std::array, NCentHists + 1> hpTVsEtaPos{}; +std::array, NCentHists + 1> hpTVsEtaNeg{}; +// Total counts +std::array, NCentHists> hTotalMomPosCent{}; +std::array, NCentHists> hTotalMomNegCent{}; +std::array, NCentHists> hTotalPtPosCent{}; +std::array, NCentHists> hTotalPtNegCent{}; +// Counts for particles +std::array, NCentHists + 1>, NPartHists> hFracMomPosCent{}; +std::array, NCentHists + 1>, NPartHists> hFracMomNegCent{}; +std::array, NCentHists + 1>, NPartHists> hFracPtPosCent{}; +std::array, NCentHists + 1>, NPartHists> hFracPtNegCent{}; + struct MultiplicityPt { + // ── Services ────────────────────────────────────────────── Service pdg; Service ccdb; + + // ── Constant values ────────────────────────────────── static constexpr int CentBinMax = 100; - static constexpr int MultBinMax = 200; - static constexpr int RecMultBinMax = 100; - static constexpr int ParticlesType = 4; + static constexpr int NEvLabel = 15; static constexpr int ResponseMatrixTypes = 7; - static constexpr int CentralityClasses = 10; - - enum INELCutSelection : int { - INEL = 0, - INELgt0 = 1, - INELgt1 = 2 - }; + // ── Configurables: event ────────────────────────────────── Configurable isRun3{"isRun3", true, "is Run3 dataset"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgINELCut{"cfgINELCut", 0, "INEL event selection: 0 no sel, 1 INEL>0, 2 INEL>1"}; + Configurable askForCustomTVX{"askForCustomTVX", false, "Ask for custom TVX rather than sel8"}; + Configurable removeITSROFrameBorder{"removeITSROFrameBorder", false, "Remove ITS Read-Out Frame border"}; + Configurable removeNoSameBunchPileup{"removeNoSameBunchPileup", false, "Remove no same bunch pileup"}; + Configurable requireIsGoodZvtxFT0vsPV{"requireIsGoodZvtxFT0vsPV", false, "Require good Z vertex FT0 vs PV"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "Require vertex ITSTPC"}; + Configurable removeNoTimeFrameBorder{"removeNoTimeFrameBorder", false, "Remove no time frame border"}; + + // Gen-level event selection + Configurable selTVXMC{"selTVXMC", true, "Require TVX-equivalent at gen level"}; + Configurable isZvtxPosSelMC{"isZvtxPosSelMC", true, "Require |Zvtx| cfgCutEtaMax{"cfgCutEtaMax", 0.8f, "Max eta range for tracks"}; Configurable cfgCutEtaMin{"cfgCutEtaMin", -0.8f, "Min eta range for tracks"}; + Configurable cfgCutY{"cfgCutY", 0.5f, "Y range for tracks"}; Configurable cfgCutNsigma{"cfgCutNsigma", 3.0f, "nsigma cut range for tracks"}; - + Configurable lastRequiredTrdCluster{"lastRequiredTrdCluster", -1, "Last cluster to require in TRD"}; + Configurable requireTrdOnly{"requireTrdOnly", false, "Require only tracks from TRD"}; + Configurable requireNoTrd{"requireNoTrd", false, "Require tracks without TRD"}; + Configurable multiplicityEstimator{"multiplicityEstimator", 6, + "Multiplicity estimator: 0=NoMult, 1=MultFV0M, 2=MultFT0M, 3=MultFDDM, 4=MultTracklets, 5=MultTPC, 6=MultNTracksPV, 7=MultNTracksPVeta1, 8=CentFT0C, 9=CentFT0M, 10=CentFV0A"}; + + // Track cuts + Configurable enableDCAHistograms{"enableDCAHistograms", false, "Enable DCA histograms"}; Configurable enablePIDHistograms{"enablePIDHistograms", true, "Enable PID histograms"}; Configurable useCustomTrackCuts{"useCustomTrackCuts", true, "Flag to use custom track cuts"}; Configurable itsPattern{"itsPattern", 0, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"}; @@ -97,72 +152,569 @@ struct MultiplicityPt { Configurable minChi2PerClusterTPC{"minChi2PerClusterTPC", 0.5f, "Additional cut on the minimum value of the chi2 per cluster in the TPC"}; Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; Configurable maxDcaXYFactor{"maxDcaXYFactor", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; - Configurable maxDcaZ{"maxDcaZ", 0.1f, "Additional cut on the maximum value of the DCA z"}; + Configurable maxDcaZ{"maxDcaZ", 2.0f, "Additional cut on the maximum value of the DCA z"}; Configurable minTPCNClsFound{"minTPCNClsFound", 70.0f, "min number of found TPC clusters"}; Configurable minTPCNClsPID{"minTPCNClsPID", 130.0f, "min number of PID TPC clusters"}; Configurable nClTPCFoundCut{"nClTPCFoundCut", false, "Apply TPC found clusters cut"}; Configurable nClTPCPIDCut{"nClTPCPIDCut", true, "Apply TPC clusters for PID cut"}; + Configurable minITSnClusters{"minITSnClusters", 5, "minimum number of found ITS clusters"}; + Configurable cfgTrkLowPtCut{"cfgTrkLowPtCut", 0.15f, "Minimum constituent pT"}; - Configurable applyPhiCut{"applyPhiCut", false, "Apply phi sector cut to remove problematic TPC regions"}; + // PID selection + Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; + Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; + Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; + + // Phi cut parameters + Configurable applyPhiCut{"applyPhiCut", true, "Apply phi sector cut"}; Configurable pTthresholdPhiCut{"pTthresholdPhiCut", 2.0f, "pT threshold above which to apply phi cut"}; Configurable phiCutLowParam1{"phiCutLowParam1", 0.119297, "First parameter for low phi cut"}; Configurable phiCutLowParam2{"phiCutLowParam2", 0.000379693, "Second parameter for low phi cut"}; Configurable phiCutHighParam1{"phiCutHighParam1", 0.16685, "First parameter for high phi cut"}; Configurable phiCutHighParam2{"phiCutHighParam2", 0.00981942, "Second parameter for high phi cut"}; - Configurable cfgTrkLowPtCut{"cfgTrkLowPtCut", 0.15f, "Minimum constituent pT"}; + // ── Nch window for multiplicity axis ────────────────────── + Configurable tpcNchAcceptance{"tpcNchAcceptance", 0.8f, + "|eta| window for counting gen. Nch (multiplicity axis)"}; - Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; - Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; - Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; + // ── Histogram binning ──────────────────────────────────── + Configurable nBinsNch{"nBinsNch", 200, "Bins on gen-Nch axis"}; + Configurable maxNch{"maxNch", 200.0f, "Max gen Nch on histogram axis"}; + Configurable nBinsNPV{"nBinsNPV", 600, "N bins ITS tracks"}; + Configurable minNpv{"minNpv", 0, "Min NPV"}; + Configurable maxNpv{"maxNpv", 600, "Max NPV"}; ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; ConfigurableAxis pFineBins{"pFineBins", {1995, 0.1, 40}, "Binning for momentum"}; ConfigurableAxis dedxBins{"dedxBins", {100, 0, 100}, "Binning for dedx"}; - std::vector centBinningStd = {0., 1., 5., 10., 15., 20., 30., 40., 50., 70., 100.}; - // Histogram names for V0s dE/dx analysis - static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; - static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + // ── Custom track-selection object ──────────────────────── + TrackSelection customTrackCuts; + + // ── TF1 pointers for phi cuts ──────────────────────────── + TF1* fphiCutLow = nullptr; + TF1* fphiCutHigh = nullptr; + + // ── Histogram registry ─────────────────────────────────── + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry registryFrac{"registryFrac", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // ── Preslice: group tracks by reco collision ────────────── + Preslice perCollision = aod::track::collisionId; + + // FT0 acceptance for TVX-equivalent gen-level selection + static constexpr float MinFT0A = 3.5f; + static constexpr float MaxFT0A = 4.9f; + static constexpr float MinFT0C = -3.3f; + static constexpr float MaxFT0C = -2.1f; + + static constexpr float MinCharge = 3.0f; + static constexpr int CentralityClasses = 10; + static constexpr double CentClasses[CentralityClasses + 1] = {0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; + static constexpr int ParticleTypes = 4; + // Response Matrix histogram names static constexpr std::string_view EtavspvspTPosPart[ResponseMatrixTypes] = {"heta_vs_pt_vs_p_all_Pos", "heta_vs_pt_vs_p_all_Pos_Pri", "heta_vs_pt_vs_p_all_Pos_Pri_MC", "heta_vs_pt_vs_p_all_Pos_Pri_MC_Part", "heta_vs_pt_vs_p_Pi_Pos", "heta_vs_pt_vs_p_K_Pos", "heta_vs_pt_vs_p_Pr_Pos"}; static constexpr std::string_view EtavspvspTNegPart[ResponseMatrixTypes] = {"heta_vs_pt_vs_p_all_Neg", "heta_vs_pt_vs_p_all_Neg_Pri", "heta_vs_pt_vs_p_all_Neg_Pri_MC", "heta_vs_pt_vs_p_all_Neg_Pri_MC_Part", "heta_vs_pt_vs_p_Pi_Neg", "heta_vs_pt_vs_p_K_Neg", "heta_vs_pt_vs_p_Pr_Neg"}; - // Particle fractions histograms - static constexpr std::string_view ParticleFractionsVsMomentumPos[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Pos", "hFractionVsMomentum_Kaon_Pos", "hFractionVsMomentum_Proton_Pos", "hFractionVsMomentum_Electron_Pos", "hFractionVsMomentum_Muon_Pos"}; - static constexpr std::string_view ParticleFractionsVsPtPos[ParticlesType + 1] = {"hFractionVsPt_Pion_Pos", "hFractionVsPt_Kaon_Pos", "hFractionVsPt_Proton_Pos", "hFractionVsPt_Electron_Pos", "hFractionVsPt_Muon_Pos"}; - static constexpr std::string_view ParticleFractionsVsMomentumNeg[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Neg", "hFractionVsMomentum_Kaon_Neg", "hFractionVsMomentum_Proton_Neg", "hFractionVsMomentum_Electron_Neg", "hFractionVsMomentum_Muon_Neg"}; + // Event counter bins + enum EvCutLabel { + kAllGen = 1, + kTVXequiv, + kVtxZ, + kINELgt0, + kRecoColl, + kRecoSelected + }; - static constexpr std::string_view ParticleFractionsVsPtNeg[ParticlesType + 1] = {"hFractionVsPt_Pion_Neg", "hFractionVsPt_Kaon_Neg", "hFractionVsPt_Proton_Neg", "hFractionVsPt_Electron_Neg", "hFractionVsPt_Muon_Neg"}; + // Particle species enum + enum ParticleSpecies : int { + kPion = 0, + kKaon = 1, + kProton = 2, + kAllCharged = 3, + kNSpecies = 4 + }; - // Fine binning - static constexpr std::string_view CentpPos[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos", "p_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpNeg[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg", "p_vs_eta_MB_Neg"}; - static constexpr std::string_view CentpTPos[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos", "pT_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpTNeg[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Neg", "pT_vs_eta_Cent1_5_Neg", "pT_vs_eta_Cent5_10_Neg", "pT_vs_eta_Cent10_15_Neg", "pT_vs_eta_Cent15_20_Neg", "pT_vs_eta_Cent20_30_Neg", "pT_vs_eta_Cent30_40_Neg", "pT_vs_eta_Cent40_50_Neg", "pT_vs_eta_Cent50_70_Neg", "pT_vs_eta_Cent70_100_Neg", "pT_vs_eta_MB_Neg"}; + enum INELCutSelection : int { + INEL = 0, + INELgt0 = 1, + INELgt1 = 2 + }; - TrackSelection customTrackCuts; - TF1* fphiCutLow = nullptr; - TF1* fphiCutHigh = nullptr; + void init(InitContext const&) + { + // Setup custom track cuts + if (useCustomTrackCuts.value) { + customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); + customTrackCuts.SetRequireITSRefit(requireITS.value); + customTrackCuts.SetRequireTPCRefit(requireTPC.value); + customTrackCuts.SetMinNClustersITS(minITSnClusters.value); + customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); + customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); + customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); + customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); + customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); + customTrackCuts.SetMaxDcaXYPtDep([](float /*pt*/) { return 10000.f; }); + customTrackCuts.SetMaxDcaZ(maxDcaZ.value); + } - HistogramRegistry ue; + // Initialize phi cut functions if enabled + if (applyPhiCut.value) { + fphiCutLow = new TF1("StandardPhiCutLow", + Form("%f/x/x+pi/18.0-%f", + phiCutLowParam1.value, phiCutLowParam2.value), + 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", + Form("%f/x+pi/18.0+%f", + phiCutHighParam1.value, phiCutHighParam2.value), + 0, 50); + LOGF(info, "Phi cut ENABLED for pT > %.1f GeV/c", pTthresholdPhiCut.value); + } - using CollisionTableData = soa::Join; - using TrackTableData = soa::Join; - using TrackTableMC = soa::Join; - using ParticlesMC = aod::McParticles; - using McCollisions = aod::McCollisions; - using RecoCollisions = aod::Collisions; + // Define axes + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec dedxAxis = {dedxBins, "dE/dx (a. u.)"}; + AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; + AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; + AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; + AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; - Preslice perMCCol = aod::mcparticle::mcCollisionId; + const AxisSpec centAxis{centBinningStd, "FT0M Centrality (%)"}; - enum ParticleSpecies : int { - PartPion = 0, - PartKaon = 1, - PartProton = 2, - }; + // Fine centrality binning (100 bins) + std::vector centBinningFine; + for (int i = 0; i <= CentBinMax; i++) { + centBinningFine.push_back(static_cast(i)); + } + const AxisSpec centFineAxis{centBinningFine, "FT0M Centrality (%)"}; + + const AxisSpec nchAxis{nBinsNch.value, 0.f, maxNch.value, + Form("Gen. N_{ch} (|#eta|<%.1f)", tpcNchAcceptance.value)}; + + const AxisSpec npvAxis{nBinsNPV.value, minNpv.value, maxNpv.value, "NPV"}; + const AxisSpec dcaXYAxis{105, -1.05f, 1.05f, "DCA_{xy} (cm)"}; + const AxisSpec zvtxAxis{60, -30.0, 30.0, "Vtx_{z} (cm)"}; + const AxisSpec nclAxis{161, -0.5, 160.5, "N_{cl} TPC"}; + + // ======================================================================== + // EVENT COUNTER AND BASIC HISTOGRAMS + // ======================================================================== + registry.add("EventCounter", ";;Events", kTH1F, {{8, 0.5, 8.5}}); + { + auto h = registry.get(HIST("EventCounter")); + h->GetXaxis()->SetBinLabel(kAllGen, "All gen."); + h->GetXaxis()->SetBinLabel(kTVXequiv, "TVX-equiv."); + h->GetXaxis()->SetBinLabel(kVtxZ, "|Zvtx|GetXaxis()->SetBinLabel(kINELgt0, "INEL>0"); + h->GetXaxis()->SetBinLabel(kRecoColl, ">=1 reco coll."); + h->GetXaxis()->SetBinLabel(kRecoSelected, ">=1 reco+sel."); + } + + registry.add("NumberOfRecoCollisions", "Reco collisions per gen. collision;N_{reco};Entries", + kTH1F, {{10, -0.5, 9.5}}); + registry.add("zPosMC", "Gen. Vtx_{z} (evts w/ >=1 reco+sel. coll.);Vtx_{z} (cm);Entries", + kTH1F, {zvtxAxis}); + registry.add("zPosReco", "Reco. Vtx_{z} (selected);Vtx_{z} (cm);Entries", + kTH1F, {zvtxAxis}); + registry.add("T0Ccent", "FT0M centrality (selected);Centrality (%);Entries", + kTH1F, {centAxis}); + registry.add("T0CcentVsFoundFT0", "Found(1.5) NOT Found(0.5);;Status;", kTH2F, {{centAxis, {2, 0, 2}}}); + registry.add("T0CcentVsFoundFT0AndTVX", "Found(1.5) NOT Found(0.5);;Status;", kTH2F, {{centAxis, {2, 0, 2}}}); + registry.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", kTH1F, {{40, -20.0, 20.0}}); + registry.add("hvtxZmc", "MC vertex Z;Vertex Z (cm);Events", kTH1F, {{40, -20.0, 20.0}}); + + // ======================================================================== + // CENTRALITY DIAGNOSTIC HISTOGRAMS + // ======================================================================== + registry.add("Centrality/hCentRaw", "Raw FT0M Centrality (no cuts);Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentAfterVtx", "Centrality after vertex cut;Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentAfterINEL", "Centrality after INEL cut;Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentAfterAll", "Centrality after all cuts;Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentVsMult", "Centrality vs Generated Multiplicity;Centrality (%);N_{ch}^{gen}", + kTH2D, {centFineAxis, nchAxis}); + registry.add("Centrality/hMultVsCent", "Generated Multiplicity vs Centrality;N_{ch}^{gen};Centrality (%)", + kTH2D, {nchAxis, centFineAxis}); + registry.add("Centrality/hCentVsVz", "Centrality vs Vertex Z;Centrality (%);V_{z} (cm)", + kTH2D, {centFineAxis, {40, -20, 20}}); + registry.add("Centrality/hRecoMultVsCent", "Reconstructed Track Multiplicity vs Centrality;Centrality (%);N_{tracks}^{reco}", + kTH2D, {centFineAxis, {100, 0, 100}}); + registry.add("Centrality/hVertexResVsCent", "Vertex Resolution vs Centrality;Centrality (%);V_{z} resolution (cm)", + kTH2D, {centFineAxis, {100, -1, 1}}); + registry.add("NchVsNPV", ";Nch; NPV;", kTH2D, {{npvAxis, nchAxis}}); + registry.add("ExcludedEvtVsNch", ";Nch;Entries;", kTH1F, {nchAxis}); + registry.add("ExcludedEvtVsNPV", ";NPV;Entries;", kTH1F, {npvAxis}); + + // ======================================================================== + // INEL CLASS HISTOGRAMS + // ======================================================================== + registry.add("INEL/hINELClass", "INEL Class for MC Collisions;INEL Class;Counts", + kTH1D, {{3, 0.5, 3.5}}); + auto hINEL = registry.get(HIST("INEL/hINELClass")); + hINEL->GetXaxis()->SetBinLabel(1, "INEL0"); + hINEL->GetXaxis()->SetBinLabel(2, "INEL>0"); + hINEL->GetXaxis()->SetBinLabel(3, "INEL>1"); + registry.add("INEL/hINELVsCent", "INEL Class vs Centrality;Centrality (%);INEL Class", + kTH2D, {centFineAxis, {3, 0.5, 3.5}}); + + // ======================================================================== + // CUT FLOW HISTOGRAMS + // ======================================================================== + registry.add("CutFlow/hCutStats", "Cut Statistics;Cut Stage;Counts", + kTH1D, {{6, 0.5, 6.5}}); + auto hCut = registry.get(HIST("CutFlow/hCutStats")); + hCut->GetXaxis()->SetBinLabel(1, "All reco events"); + hCut->GetXaxis()->SetBinLabel(2, "Has MC match"); + hCut->GetXaxis()->SetBinLabel(3, "Has centrality"); + hCut->GetXaxis()->SetBinLabel(4, "Pass vertex"); + hCut->GetXaxis()->SetBinLabel(5, "Pass INEL"); + hCut->GetXaxis()->SetBinLabel(6, "Selected"); + registry.add("CutFlow/hCentPerCut", "Centrality Distribution at Each Cut;Cut Stage;Centrality (%)", + kTH2D, {{6, 0.5, 6.5}, centFineAxis}); + registry.add("evsel", "Event selection", HistType::kTH1D, {{20, 0.5, 20.5}}); + auto hEvSel = registry.get(HIST("evsel")); + for (int i = 1; i <= NEvLabel; i++) { + hEvSel->GetXaxis()->SetBinLabel(i, Form("Step %d", i)); + } + + // ======================================================================== + // MC COLLISION HISTOGRAMS + // ======================================================================== + registry.add("MC/GenRecoCollisions", "Generated and Reconstructed MC Collisions", + kTH1D, {{10, 0.5, 10.5}}); + auto hColl = registry.get(HIST("MC/GenRecoCollisions")); + hColl->GetXaxis()->SetBinLabel(1, "Collisions generated"); + hColl->GetXaxis()->SetBinLabel(2, "Collisions reconstructed"); + hColl->GetXaxis()->SetBinLabel(3, "INEL>0"); + hColl->GetXaxis()->SetBinLabel(4, "INEL>1"); + registry.add("NchMCcentVsTVX", ";Passed(1.5) NOT Passed(0.5);", kTH2F, {{nchAxis, {2, 0, 2}}}); + registry.add("Centrality_AllRecoEvt", "Generated Events Irrespective of number of reconstructions;Centrality;Entries", kTH1F, {centAxis}); + registry.add("Centrality_WRecoEvt", "Generated Events With at least One Rec. Collision;Centrality;Entries", kTH1F, {centAxis}); + registry.add("Centrality_WRecoEvtWSelCri", "Generated Events With at least One Rec. Collision + Sel. criteria;Centrality;Entries", kTH1F, {centAxis}); + + // ======================================================================== + // 2D and 3D CORRELATION HISTOGRAMS + // ======================================================================== + registry.add("NchMCVsCent", "Gen. N_{ch} vs FT0M centrality (reco+sel. evts);FT0M Centrality (%);Gen. N_{ch}", + kTH2F, {{centAxis, nchAxis}}); + registry.add("NchMCVsCentVsPt", "pT vs Gen. N_{ch} vs FT0M centrality;FT0M Centrality (%);Gen. N_{ch};#it{p}_{T}", + kTH3F, {{centAxis, nchAxis, ptAxis}}); + registry.add("hEta", "Track eta;#eta;Counts", kTH1D, {{20, -0.8, 0.8}}); + registry.add("hPhi", "Track phi;#varphi (rad);Counts", kTH1D, {{64, 0, o2::constants::math::TwoPI}}); + registry.add("EtaVsPhi", ";#eta;#varphi;", kTH2F, {{50, -1.0, 1.0}, {100, 0, o2::constants::math::TwoPI}}); + + // ======================================================================== + // EVENT LOSS HISTOGRAMS + // ======================================================================== + registry.add("NchMC_AllGen", "EVENT LOSS denom.;Gen. N_{ch};Entries", kTH1F, {nchAxis}); + registry.add("NchMC_WithRecoEvt", "EVENT LOSS numer.;Gen. N_{ch};Entries", kTH1F, {nchAxis}); + registry.add("MC/EventLoss/NchGenerated", "Generated charged multiplicity;N_{ch}^{gen};Counts", kTH1D, {nchAxis}); + registry.add("MC/EventLoss/NchGenerated_PhysicsSelected", "Generated charged multiplicity (physics selected);N_{ch}^{gen};Counts", kTH1D, {nchAxis}); + registry.add("MC/EventLoss/NchGenerated_Reconstructed", "Generated charged multiplicity (reconstructed);N_{ch}^{gen};Counts", kTH1D, {nchAxis}); + registry.add("MC/EventLoss/GenMultVsCent", "Generated charged particles vs FT0M centrality;FT0M Centrality (%);N_{ch}^{gen}", kTH2D, {centAxis, nchAxis}); + registry.add("MC/EventLoss/GenMultVsCent_Selected", "Generated vs FT0M centrality (selected);FT0M Centrality (%);N_{ch}^{gen}", kTH2D, {centAxis, nchAxis}); + registry.add("MC/EventLoss/GenMultVsCent_Rejected", "Generated vs FT0M centrality (rejected);FT0M Centrality (%);N_{ch}^{gen}", kTH2D, {centAxis, nchAxis}); + registry.add("hEventLossBreakdown", "Event loss breakdown", kTH1D, {{4, 0.5, 4.5}}); + auto hLoss = registry.get(HIST("hEventLossBreakdown")); + hLoss->GetXaxis()->SetBinLabel(1, "Physics selected"); + hLoss->GetXaxis()->SetBinLabel(2, "Reconstructed"); + hLoss->GetXaxis()->SetBinLabel(3, "Selected"); + hLoss->GetXaxis()->SetBinLabel(4, "Final efficiency"); + + // ======================================================================== + // SIGNAL LOSS HISTOGRAMS + // ======================================================================== + const std::vector speciesNames = {"Pi", "Ka", "Pr", "All"}; + for (int i = 0; i < ParticleTypes; ++i) { + const std::string& name = speciesNames[i]; + registry.add(Form("Pt%sVsNchMC_AllGen", name.c_str()), + Form("SIGNAL LOSS denom. (%s): all gen. evts.;#it{p}_{T};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + registry.add(Form("Pt%sVsNchMC_WithRecoEvt", name.c_str()), + Form("SIGNAL LOSS numer. (%s): gen. evts. w/ >=1 reco+sel.;#it{p}_{T};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + } + + // ======================================================================== + // TRACKING EFFICIENCY HISTOGRAMS + // ======================================================================== + for (int i = 0; i < ParticleTypes; ++i) { + const std::string& name = speciesNames[i]; + registry.add(Form("Pt%sVsCentMC_WithRecoEvt", name.c_str()), + Form("EFF denom. (%s): gen pT in reco+sel. evts.;#it{p}_{T}^{gen};FT0M Cent. (%s)", name.c_str(), ")"), + kTH2F, {{ptAxis, centAxis}}); + registry.add(Form("Pt%sVsCent_WithRecoEvt", name.c_str()), + Form("EFF numer. (%s): reco primaries (gen pT);#it{p}_{T}^{gen};FT0M Cent. (%s)", name.c_str(), ")"), + kTH2F, {{ptAxis, centAxis}}); + registry.add(Form("PtGen%sVsNchMC_WithRecoEvt", name.c_str()), + Form("EFF denom. (%s) vs gen Nch;#it{p}_{T}^{gen};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + registry.add(Form("PtGen%sVsNchMC_RecoTrk", name.c_str()), + Form("EFF numer. (%s) vs gen Nch;#it{p}_{T}^{gen};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + } + + // ======================================================================== + // MC CLOSURE HISTOGRAMS + // ======================================================================== + registry.add("MCclosure_PtMCPiVsNchMC", "MC closure Pi (gen);#it{p}_{T}^{gen};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtMCKaVsNchMC", "MC closure Ka (gen);#it{p}_{T}^{gen};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtMCPrVsNchMC", "MC closure Pr (gen);#it{p}_{T}^{gen};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtPiVsNchMC", "MC closure Pi (reco);#it{p}_{T}^{reco};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtKaVsNchMC", "MC closure Ka (reco);#it{p}_{T}^{reco};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtPrVsNchMC", "MC closure Pr (reco);#it{p}_{T}^{reco};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MC/GenPtVsNch", "Generated pT vs Multiplicity;#it{p}_{T};N_{ch}^{gen}", kTH2D, {ptAxis, nchAxis}); + registry.add("MC/GenPtVsNch_PhysicsSelected", "Generated pT vs Multiplicity (physics selected);#it{p}_{T};N_{ch}^{gen}", kTH2D, {ptAxis, nchAxis}); + + // ======================================================================== + // DCA HISTOGRAMS FOR PRIMARY FRACTION + // ======================================================================== + registry.add("dcaVsPtPi", "PRIMARY FRAC. (Pi) - primaries;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPr", "PRIMARY FRAC. (Pr) - primaries;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPiDec", "PRIMARY FRAC. (Pi) - sec. from decays;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPrDec", "PRIMARY FRAC. (Pr) - sec. from decays;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPiMat", "PRIMARY FRAC. (Pi) - sec. from material;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPrMat", "PRIMARY FRAC. (Pr) - sec. from material;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + + // ======================================================================== + // MEASURED SPECTRA + // ======================================================================== + for (int i = 0; i < ParticleTypes; ++i) { + const std::string& name = speciesNames[i]; + registry.add(Form("Pt%sMeasuredVsCent", name.c_str()), + Form("Measured %s (PID);#it{p}_{T};FT0M Centrality (%s)", name.c_str(), ")"), + kTH2F, {{ptAxis, centAxis}}); + registry.add(Form("Pt%sMeasuredVsNch", name.c_str()), + Form("Measured %s (PID) vs gen Nch;#it{p}_{T};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + } + + // ======================================================================== + // TPC CLUSTER HISTOGRAMS + // ======================================================================== + registry.add("hNclFoundTPC", "Number of TPC found clusters;N_{cl, found};Counts", kTH1D, {nclAxis}); + registry.add("hNclPIDTPC", "Number of TPC PID clusters;N_{cl, PID};Counts", kTH1D, {nclAxis}); + registry.add("hNclFoundTPCvsPt", "TPC found clusters vs pT;#it{p}_{T};N_{cl,found}", kTH2D, {ptAxis, nclAxis}); + registry.add("hNclPIDTPCvsPt", "TPC PID clusters vs pT;#it{p}_{T};N_{cl,PID}", kTH2D, {ptAxis, nclAxis}); + + // ======================================================================== + // INCLUSIVE HISTOGRAMS + // ======================================================================== + registry.add("Inclusive/hPtPrimGenAll", "All generated primaries (no cuts);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimBadVertex", "Generated primaries (bad vertex);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimGen", "Generated primaries (after physics selection);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimRecoEv", "Generated primaries (reco events);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimGoodEv", "Generated primaries (good events);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtNumEff", "Tracking efficiency numerator;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtDenEff", "Tracking efficiency denominator;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtAllReco", "All reconstructed tracks;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimReco", "Reconstructed primaries;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtSecReco", "Reconstructed secondaries;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtMeasured", "All measured tracks;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtMeasuredVsCent", "All measured tracks (PID) vs centrality;#it{p}_{T};FT0M Centrality (%s)", kTH2D, {ptAxis, centAxis}); + registry.add("Inclusive/hPtMeasuredVsMult", "All measured tracks vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + + // Inclusive vs Multiplicity + registry.add("Inclusive/hPtPrimGenAllVsMult", "All generated primaries vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimBadVertexVsMult", "Generated primaries (bad vertex) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimGenVsMult", "Generated primaries (after phys sel) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimRecoEvVsMult", "Generated primaries (reco events) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimGoodEvVsMult", "Generated primaries (good events) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtNumEffVsMult", "Tracking efficiency numerator vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtDenEffVsMult", "Tracking efficiency denominator vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtAllRecoVsMult", "All reconstructed tracks vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimRecoVsMult", "Reconstructed primaries vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtSecRecoVsMult", "Reconstructed secondaries vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + + // ======================================================================== + // PER-SPECIES INCLUSIVE HISTOGRAMS + // ======================================================================== + const std::array particleNames = {"Pion", "Kaon", "Proton"}; + const std::array particleSymbols = {"#pi^{#pm}", "K^{#pm}", "p+#bar{p}"}; + + for (int iSpecies = 0; iSpecies < ParticleTypes - 1; ++iSpecies) { + const auto& name = particleNames[iSpecies]; + const auto& symbol = particleSymbols[iSpecies]; + + registry.add(Form("%s/hPtPrimGenAll", name.c_str()), + Form("All generated %s (no cuts);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimBadVertex", name.c_str()), + Form("Generated %s (bad vertex);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimGen", name.c_str()), + Form("Generated %s (after physics selection);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimRecoEv", name.c_str()), + Form("Generated %s (reco events);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimGoodEv", name.c_str()), + Form("Generated %s (good events);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtNumEff", name.c_str()), + Form("%s tracking efficiency numerator;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtDenEff", name.c_str()), + Form("%s tracking efficiency denominator;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtAllReco", name.c_str()), + Form("All reconstructed %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimReco", name.c_str()), + Form("Reconstructed primary %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtSecReco", name.c_str()), + Form("Reconstructed secondary %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtMeasured", name.c_str()), + Form("Measured %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + + // Per-species vs multiplicity + registry.add(Form("%s/hPtPrimGenAllVsMult", name.c_str()), + Form("All generated %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimBadVertexVsMult", name.c_str()), + Form("Generated %s (bad vertex) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimGenVsMult", name.c_str()), + Form("Generated %s (after phys sel) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimRecoEvVsMult", name.c_str()), + Form("Generated %s (reco events) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimGoodEvVsMult", name.c_str()), + Form("Generated %s (good events) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtNumEffVsMult", name.c_str()), + Form("%s tracking eff numerator vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtDenEffVsMult", name.c_str()), + Form("%s tracking eff denominator vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtAllRecoVsMult", name.c_str()), + Form("All reconstructed %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimRecoVsMult", name.c_str()), + Form("Reconstructed primary %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtSecRecoVsMult", name.c_str()), + Form("Reconstructed secondary %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtMeasuredVsMult", name.c_str()), + Form("Measured %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + } + + // ======================================================================== + // PID HISTOGRAMS + // ======================================================================== + registry.add("PtResolution", "pT resolution;#it{p}_{T}^{gen};(p_{T}^{reco}-p_{T}^{gen})/p_{T}^{gen}", + kTH2F, {{ptAxis, {100, -1.0, 1.0}}}); + + if (enablePIDHistograms) { + registry.add("Pion/hNsigmaTPC", "Pion TPC n#sigma;#it{p}_{T};n#sigma_{TPC}", + kTH2D, {{ptAxis, {200, -10, 10}}}); + registry.add("Kaon/hNsigmaTPC", "Kaon TPC n#sigma;#it{p}_{T};n#sigma_{TPC}", + kTH2D, {{ptAxis, {200, -10, 10}}}); + registry.add("Proton/hNsigmaTPC", "Proton TPC n#sigma;#it{p}_{T};n#sigma_{TPC}", + kTH2D, {{ptAxis, {200, -10, 10}}}); + } + // ======================================================================== + // PHI CUT MONITORING + // ======================================================================== + if (applyPhiCut.value) { + registry.add("PhiCut/hPtVsPhiPrimeBefore", "pT vs #phi' before cut;p_{T};#phi'", + kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); + registry.add("PhiCut/hPtVsPhiPrimeAfter", "pT vs #phi' after cut;p_{T};#phi'", + kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); + } + + // ======================================================================== + // CALIBRATION HISTOGRAMS + // ======================================================================== + registry.add("Calibration/hRawMultiplicity", "Raw multiplicity distribution;N_{ch};Events", + kTH1D, {{150, 0, 150}}); + + // ======================================================================== + // DEDX VS MOMENTUM HISTOGRAMS + // ======================================================================== + const std::array centNames = { + "Cent0_1", "Cent1_5", "Cent5_10", "Cent10_15", "Cent15_20", + "Cent20_30", "Cent30_40", "Cent40_50", "Cent50_70", "Cent70_100", "MB"}; + const std::array v0Names = { + "all", "Pi_v0", "Pr_v0", "El_v0"}; + for (int i = 0; i < ParticleTypes; ++i) { + const auto& part = v0Names[i]; + registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Pos", part.c_str()), + "dE/dx vs Momentum Positive", kTH3F, {{pAxis}, {dedxAxis}, {etaAxis}}); + registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Neg", part.c_str()), + "dE/dx vs Momentum Negative", kTH3F, {{pAxis}, {dedxAxis}, {etaAxis}}); + } + for (int i = 0; i < CentralityClasses; ++i) { + const auto& cent = centNames[i]; + hDedxVsMomentumVsCentPos[i] = registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Pos", cent.c_str()), "dE/dx vs Momentum Positive", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + hDedxVsMomentumVsCentNeg[i] = registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Neg", cent.c_str()), "dE/dx vs Momentum Negative", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + } + for (int i = 0; i < CentralityClasses + 1; ++i) { + const auto& cent = centNames[i]; + hDedxVspTMomentumVsCent[i] = registry.add(Form("DedxVsMomentum/dEdx_vs_pT_%s", cent.c_str()), "dE/dx vs pT", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + } + // ======================================================================== + // RESPONSE MATRIX HISTOGRAMS + // ======================================================================== + for (int i = 0; i < ResponseMatrixTypes; ++i) { + registry.add(("ResponseMatrix/" + std::string(EtavspvspTPosPart[i])).c_str(), + "eta vs pT vs p Positive", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + registry.add(("ResponseMatrix/" + std::string(EtavspvspTNegPart[i])).c_str(), + "eta vs pT vs p Negative", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + } + // ======================================================================== + // FINNER BINNING HISTOGRAMS + // ======================================================================== + for (int i = 0; i < CentralityClasses + 1; ++i) { + const auto& cent = centNames[i]; + hMomentumVsEtaPos[i] = registry.add(Form("Binning/p_vs_eta_%s_Pos", cent.c_str()), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hMomentumVsEtaNeg[i] = registry.add(Form("Binning/p_vs_eta_%s_Neg", cent.c_str()), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hpTVsEtaPos[i] = registry.add(Form("Binning/pT_vs_eta_%s_Pos", cent.c_str()), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + hpTVsEtaNeg[i] = registry.add(Form("Binning/pT_vs_eta_%s_Neg", cent.c_str()), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + } + + // ======================================================================== + // PARTICLE FRACTIONS HISTOGRAMS + // ======================================================================== + const std::array partName = {"Pion", "Kaon", "Proton", "Electron", "Muon"}; + for (int ic = 0; ic < NCentHists + 1; ++ic) { + const auto& cent = centNames[ic]; + hTotalMomPosCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsMomentumPos_%s", cent.c_str()), + "Total counts vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hTotalMomNegCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsMomentumNeg_%s", cent.c_str()), + "Total counts vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hTotalPtPosCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsPtPos_%s", cent.c_str()), + "Total counts vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + hTotalPtNegCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsPtNeg_%s", cent.c_str()), + "Total counts vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + + for (int ip = 0; ip < NPartHists; ++ip) { + const auto& part = partName[ip]; + hFracMomPosCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsMomentum_%s_Pos_%s", part.c_str(), cent.c_str()), + "Fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hFracMomNegCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsMomentum_%s_Neg_%s", part.c_str(), cent.c_str()), + "Fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hFracPtPosCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsPt_%s_Pos_%s", part.c_str(), cent.c_str()), + "Fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + hFracPtNegCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsPt_%s_Neg_%s", part.c_str(), cent.c_str()), + "Fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + } + } + + LOG(info) << "=== MultiplicityPt initialized with ALL histograms (including dE/dx) ==="; + LOG(info) << "tpcNchAcceptance = " << tpcNchAcceptance.value; + LOG(info) << "cfgINELCut = " << cfgINELCut.value; + LOG(info) << "selTVXMC = " << selTVXMC.value; + LOG(info) << "applyPhiCut = " << applyPhiCut.value; + LOG(info) << "maxDcaZ = " << maxDcaZ.value; + } + + // Get magnetic field from CCDB int getMagneticField(uint64_t timestamp) { static o2::parameters::GRPMagField* grpo = nullptr; @@ -172,941 +724,820 @@ struct MultiplicityPt { LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); return 0; } - LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); } return grpo->getNominalL3Field(); } + // Transform phi for phi cut float getTransformedPhi(const float phi, const int charge, const float magField) const { float transformedPhi = phi; - if (magField < 0) + if (magField < 0) { transformedPhi = o2::constants::math::TwoPI - transformedPhi; - if (charge < 0) + } + if (charge < 0) { transformedPhi = o2::constants::math::TwoPI - transformedPhi; + } transformedPhi += o2::constants::math::PI / 18.0f; transformedPhi = std::fmod(transformedPhi, o2::constants::math::PI / 9.0f); return transformedPhi; } - template - bool passedPhiCut(const TrackType& track, float magField) const + // Check phi cut + template + bool passedPhiCut(const T& track, float magField) const { if (!applyPhiCut.value) return true; if (track.pt() < pTthresholdPhiCut.value) return true; - float phi = track.phi(); - int charge = track.sign(); + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); - if (magField < 0) - phi = o2::constants::math::TwoPI - phi; - if (charge < 0) - phi = o2::constants::math::TwoPI - phi; - phi += o2::constants::math::PI / 18.0f; - phi = std::fmod(phi, o2::constants::math::PI / 9.0f); - - if (phi < fphiCutHigh->Eval(track.pt()) && phi > fphiCutLow->Eval(track.pt())) + if (phiPrime < fphiCutHigh->Eval(track.pt()) && phiPrime > fphiCutLow->Eval(track.pt())) { return false; - return true; - } - - template - int countGeneratedChargedPrimaries(const ParticleContainer& particles, float etaMax, float ptMin) const - { - int count = 0; - for (const auto& particle : particles) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - continue; - if (!particle.isPhysicalPrimary()) - continue; - if (std::abs(particle.eta()) > etaMax) - continue; - if (particle.pt() < ptMin) - continue; - count++; } - return count; - } - - template - bool passedNClTPCFoundCut(const T& trk) const - { - return !nClTPCFoundCut.value || trk.tpcNClsFound() >= minTPCNClsFound.value; + return true; } template - bool passedNClTPCPIDCut(const T& trk) const + bool passesTrackSelectionNoDCA(const T& track) const { - return !nClTPCPIDCut.value || trk.tpcNClsPID() >= minTPCNClsPID.value; - } + if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) + return false; + if (track.pt() < cfgTrkLowPtCut.value) + return false; + if (track.tpcChi2NCl() < minChi2PerClusterTPC.value || track.tpcChi2NCl() > maxChi2PerClusterTPC.value) + return false; - template - bool passesCutWoDCA(TrackType const& track) const - { if (useCustomTrackCuts.value) { for (int i = 0; i < static_cast(TrackSelection::TrackCuts::kNCuts); i++) { - if (i == static_cast(TrackSelection::TrackCuts::kDCAxy) || - i == static_cast(TrackSelection::TrackCuts::kDCAz)) + if (i == static_cast(TrackSelection::TrackCuts::kDCAxy)) continue; if (!customTrackCuts.IsSelected(track, static_cast(i))) return false; } - return true; - } - return track.isGlobalTrackWoDCA(); - } - - template - bool passesDCAxyCut(TrackType const& track) const - { - if (useCustomTrackCuts.value) { - if (!passesCutWoDCA(track)) + } else { + if (!track.isGlobalTrackWoDCA()) return false; - constexpr float DcaXYConst = 0.0105f; - constexpr float DcaXYPtScale = 0.0350f; - constexpr float DcaXYPtPower = 1.1f; - const float maxDcaXY = maxDcaXYFactor.value * (DcaXYConst + DcaXYPtScale / std::pow(track.pt(), DcaXYPtPower)); - return std::abs(track.dcaXY()) <= maxDcaXY; } - return track.isGlobalTrack(); - } - template - bool passesTrackSelection(TrackType const& track, float magField = 0) const - { - if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) - return false; - if (track.tpcChi2NCl() < minChi2PerClusterTPC.value || track.tpcChi2NCl() > maxChi2PerClusterTPC.value) - return false; - if (!passesCutWoDCA(track)) + if (nClTPCFoundCut.value && track.tpcNClsFound() < minTPCNClsFound.value) return false; - if (!passesDCAxyCut(track)) - return false; - if (!passedNClTPCFoundCut(track)) - return false; - if (!passedNClTPCPIDCut(track)) - return false; - if (!passedPhiCut(track, magField)) + if (nClTPCPIDCut.value && track.tpcNClsPID() < minTPCNClsPID.value) return false; + return true; } - template - bool passesPIDSelection(const TrackType& track, int species) const + template + bool passesDCAxyCut(const T& track) const { - float nsigmaTPC = 0.f; - float cutValue = 0.f; - - if (species == PartPion) { - nsigmaTPC = track.tpcNSigmaPi(); - cutValue = cfgCutNsigmaPi.value; - } else if (species == PartKaon) { - nsigmaTPC = track.tpcNSigmaKa(); - cutValue = cfgCutNsigmaKa.value; - } else if (species == PartProton) { - nsigmaTPC = track.tpcNSigmaPr(); - cutValue = cfgCutNsigmaPr.value; - } + constexpr float C = 0.0105f, S = 0.0350f, P = 1.1f; + const float maxDCAxy = maxDcaXYFactor.value * (C + S / std::pow(track.pt(), P)); + return std::abs(track.dcaXY()) <= maxDCAxy; + } - return std::abs(nsigmaTPC) < cutValue; + // Full track selection + template + bool passesTrackSelection(const T& track) const + { + return passesTrackSelectionNoDCA(track) && passesDCAxyCut(track); } - template - bool isGoodPrimary(ParticleType const& particle) const + template + bool isEventSelected(const C& col) const { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) + if (askForCustomTVX.value) { + if (!col.selection_bit(aod::evsel::kIsTriggerTVX)) + return false; + } else { + if (!col.sel8()) + return false; + } + if (removeITSROFrameBorder.value && !col.selection_bit(aod::evsel::kNoITSROFrameBorder)) + return false; + if (removeNoSameBunchPileup.value && !col.selection_bit(aod::evsel::kNoSameBunchPileup)) + return false; + if (requireIsGoodZvtxFT0vsPV.value && !col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) return false; - if (!particle.isPhysicalPrimary()) + if (requireIsVertexITSTPC.value && !col.selection_bit(aod::evsel::kIsVertexITSTPC)) return false; - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) + if (removeNoTimeFrameBorder.value && !col.selection_bit(aod::evsel::kNoTimeFrameBorder)) return false; - if (particle.pt() < cfgTrkLowPtCut.value) + if (std::abs(col.posZ()) > cfgCutVertex.value) return false; return true; } - void processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks, BCsRun3 const& bcs); - PROCESS_SWITCH(MultiplicityPt, processData, "process data", false); - - void processMC(TrackTableMC const& tracks, aod::McParticles const& particles, aod::McCollisions const& mcCollisions, - RecoCollisions const& collisions, aod::McCollisionLabels const& labels, aod::McCentFT0Ms const& centTable, BCsRun3 const& bcs); - PROCESS_SWITCH(MultiplicityPt, processMC, "process MC", true); - - void init(InitContext const&); - void endOfStream(EndOfStreamContext& /*eos*/) {} -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} - -void MultiplicityPt::init(InitContext const&) -{ - LOG(info) << "=================================================="; - LOG(info) << "Initializing MultiplicityPt task - FULL CORRECTION FACTORS"; - LOG(info) << "=================================================="; - - if (applyPhiCut.value) { - fphiCutLow = new TF1("StandardPhiCutLow", Form("%f/x/x+pi/18.0-%f", phiCutLowParam1.value, phiCutLowParam2.value), 0, 50); - fphiCutHigh = new TF1("StandardPhiCutHigh", Form("%f/x+pi/18.0+%f", phiCutHighParam1.value, phiCutHighParam2.value), 0, 50); + template + bool isEventSelectedMC(const C& col) const + { + if (std::abs(col.posZ()) > cfgCutVertex.value) + return false; + return true; } - if (useCustomTrackCuts.value) { - customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); - customTrackCuts.SetRequireITSRefit(requireITS.value); - customTrackCuts.SetRequireTPCRefit(requireTPC.value); - customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); - customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); - customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); - customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); - customTrackCuts.SetMinNClustersTPC(minTPCNClsFound.value); - customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); - customTrackCuts.SetMaxDcaXYPtDep([](float /*pt*/) { return 10000.f; }); - customTrackCuts.SetMaxDcaZ(maxDcaZ.value); - customTrackCuts.print(); + template + int bestPIDHypothesis(const T& track) const + { + const float nsPi = std::abs(track.tpcNSigmaPi()); + const float nsKa = std::abs(track.tpcNSigmaKa()); + const float nsPr = std::abs(track.tpcNSigmaPr()); + float best = 999.f; + int id = -1; + if (nsPi < cfgCutNsigmaPi.value && nsPi < best) { + best = nsPi; + id = kPion; + } + if (nsKa < cfgCutNsigmaKa.value && nsKa < best) { + best = nsKa; + id = kKaon; + } + if (nsPr < cfgCutNsigmaPr.value && nsPr < best) { + best = nsPr; + id = kProton; + } + return id; } - // Axis definitions - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec dedxAxis = {dedxBins, "dE/dx (a. u.)"}; - AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; - AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; - AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; - AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; - AxisSpec centAxis = {centBinningStd, "FT0M Centrality (%)"}; - - std::vector centBinningFine; - for (int i = 0; i <= CentBinMax; i++) - centBinningFine.push_back(static_cast(i)); - AxisSpec centFineAxis = {centBinningFine, "FT0M Centrality (%)"}; - - std::vector multBins; - for (int i = 0; i <= MultBinMax; i++) - multBins.push_back(static_cast(i)); - AxisSpec multAxis = {multBins, "N_{ch}^{gen} (|#eta|<0.8)"}; - - std::vector recoMultBins; - for (int i = 0; i <= RecMultBinMax; i++) - recoMultBins.push_back(static_cast(i)); - AxisSpec recoMultAxis = {recoMultBins, "N_{ch}^{reco}"}; - - ue.add("Centrality/hCentRaw", "Raw FT0M Centrality;Centrality (%);Counts", HistType::kTH1D, {centFineAxis}); - ue.add("Centrality/hCentAfterVtx", "Centrality after vertex cut;Centrality (%);Counts", HistType::kTH1D, {centFineAxis}); - ue.add("Centrality/hCentAfterAll", "Centrality after all cuts;Centrality (%);Counts", HistType::kTH1D, {centFineAxis}); - ue.add("Centrality/hCentVsMult", "Centrality vs Generated Multiplicity;Centrality (%);N_{ch}^{gen}", HistType::kTH2D, {centFineAxis, multAxis}); - ue.add("Centrality/hMultVsCent", "Generated Multiplicity vs Centrality;N_{ch}^{gen};Centrality (%)", HistType::kTH2D, {multAxis, centFineAxis}); - ue.add("Centrality/hRecoMultVsCent", "Reconstructed Track Multiplicity vs Centrality;Centrality (%);N_{tracks}^{reco}", HistType::kTH2D, {centFineAxis, recoMultAxis}); - - ue.add("CutFlow/hCutStats", "Cut Statistics;Cut Stage;Counts", HistType::kTH1D, {{5, 0.5, 5.5}}); - auto hCut = ue.get(HIST("CutFlow/hCutStats")); - hCut->GetXaxis()->SetBinLabel(1, "All collisions"); - hCut->GetXaxis()->SetBinLabel(2, "Has MC match"); - hCut->GetXaxis()->SetBinLabel(3, "Has centrality"); - hCut->GetXaxis()->SetBinLabel(4, "Pass vertex"); - hCut->GetXaxis()->SetBinLabel(5, "Selected"); - - ue.add("hEventLossBreakdown", "Event loss breakdown", HistType::kTH1D, {{3, 0.5, 3.5}}); - auto hLoss = ue.get(HIST("hEventLossBreakdown")); - hLoss->GetXaxis()->SetBinLabel(1, "Physics selected"); - hLoss->GetXaxis()->SetBinLabel(2, "Reconstructed"); - hLoss->GetXaxis()->SetBinLabel(3, "Selected"); - - ue.add("MC/GenRecoCollisions", "Generated and Reconstructed MC Collisions", HistType::kTH1D, {{5, 0.5, 5.5}}); - auto hColl = ue.get(HIST("MC/GenRecoCollisions")); - hColl->GetXaxis()->SetBinLabel(1, "Collisions generated"); - hColl->GetXaxis()->SetBinLabel(2, "INEL>0"); - hColl->GetXaxis()->SetBinLabel(3, "INEL>1"); - hColl->GetXaxis()->SetBinLabel(4, "Reconstructed"); - hColl->GetXaxis()->SetBinLabel(5, "Selected"); - - ue.add("MC/EventLoss/GenMultVsCent", "Generated charged particles vs FT0M centrality;FT0M Centrality (%);N_{ch}^{gen}", HistType::kTH2D, {centAxis, multAxis}); - ue.add("MC/EventLoss/GenMultVsCent_Selected", "Generated vs FT0M centrality (selected events);FT0M Centrality (%);N_{ch}^{gen}", HistType::kTH2D, {centAxis, multAxis}); - - ue.add("Inclusive/hPtGen", "Generated primaries (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtReco", "All reconstructed tracks (track selection only);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimReco", "Reconstructed primaries (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtSecReco", "Reconstructed secondaries (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - - ue.add("Pion/hPtPrimGenAll", "All generated #pi^{#pm} (no cuts);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtGenINEL", "Generated #pi^{#pm} in INEL>0 events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtGenRecoEvent", "Generated #pi^{#pm} in reconstructed events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtGen", "Generated #pi^{#pm} (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtReco", "Reconstructed #pi^{#pm} (MC matched, any status);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtPrimReco", "Reconstructed primary #pi^{#pm} (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtMeasured", "Measured #pi^{#pm} (PID selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - - ue.add("Pion/hPtGenRecoEvent_Mult", "Generated #pi^{#pm} in reconstructed events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - ue.add("Pion/hPtGenINEL_Mult", "Generated #pi^{#pm} in INEL>0 events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - - if (enablePIDHistograms) { - ue.add("Pion/hNsigmaTPC", "TPC n#sigma #pi^{#pm};#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", HistType::kTH2D, {ptAxis, {200, -10, 10}}); + int countGeneratedChargedPrimaries(const aod::McParticles& particles, float etaMax) const + { + int count = 0; + for (const auto& particle : particles) { + auto* pdgPart = pdg->GetParticle(particle.pdgCode()); + if (!pdgPart || std::abs(pdgPart->Charge()) < MinCharge) + continue; + if (!particle.isPhysicalPrimary()) + continue; + if (std::abs(particle.eta()) > etaMax) + continue; + if (particle.pt() < cfgTrkLowPtCut.value) + continue; + count++; + } + return count; } - ue.add("Kaon/hPtPrimGenAll", "All generated K^{#pm} (no cuts);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtGenINEL", "Generated K^{#pm} in INEL>0 events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtGenRecoEvent", "Generated K^{#pm} in reconstructed events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtGen", "Generated K^{#pm} (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtReco", "Reconstructed K^{#pm} (MC matched, any status);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtPrimReco", "Reconstructed primary K^{#pm} (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtMeasured", "Measured K^{#pm} (PID selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); + void processSim(aod::McCollisions::iterator const& mcCollision, + soa::SmallGroups const& collisions, + aod::McParticles const& mcParticles, + TracksMC const& tracksMC, + BCsRun3 const& /*bcs*/) + { + registry.fill(HIST("EventCounter"), kAllGen); - ue.add("Kaon/hPtGenRecoEvent_Mult", "Generated K^{#pm} in reconstructed events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - ue.add("Kaon/hPtGenINEL_Mult", "Generated K^{#pm} in INEL>0 events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); + int nChFT0A = 0, nChFT0C = 0; + int nChINEL = 0; + int nChMCEta = 0; + std::vector particlePtBySpecies[4]; // Pi, Ka, Pr, All + std::vector particlePtAll; - if (enablePIDHistograms) { - ue.add("Kaon/hNsigmaTPC", "TPC n#sigma K^{#pm};#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", HistType::kTH2D, {ptAxis, {200, -10, 10}}); - } + // Store particle pT for MC closure + std::vector mcPiPt, mcKaPt, mcPrPt; - ue.add("Proton/hPtPrimGenAll", "All generated p+#bar{p} (no cuts);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtGenINEL", "Generated p+#bar{p} in INEL>0 events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtGenRecoEvent", "Generated p+#bar{p} in reconstructed events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtGen", "Generated p+#bar{p} (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtReco", "Reconstructed p+#bar{p} (MC matched, any status);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtPrimReco", "Reconstructed primary p+#bar{p} (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtMeasured", "Measured p+#bar{p} (PID selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); + for (const auto& particle : mcParticles) { + auto* pdgPart = pdg->GetParticle(particle.pdgCode()); + if (!pdgPart || std::abs(pdgPart->Charge()) < MinCharge) + continue; + if (!particle.isPhysicalPrimary()) + continue; - ue.add("Proton/hPtGenRecoEvent_Mult", "Generated p+#bar{p} in reconstructed events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - ue.add("Proton/hPtGenINEL_Mult", "Generated p+#bar{p} in INEL>0 events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); + const float eta = particle.eta(); + const float pt = particle.pt(); + + if (eta > MinFT0A && eta < MaxFT0A) + nChFT0A++; + if (eta > MinFT0C && eta < MaxFT0C) + nChFT0C++; + if (std::abs(eta) < 1.0f) + nChINEL++; + + if (std::abs(eta) < tpcNchAcceptance.value) { + nChMCEta++; + + const int absPDG = std::abs(particle.pdgCode()); + if (absPDG == PDG_t::kPiPlus) { + particlePtBySpecies[kPion].push_back(pt); + mcPiPt.push_back(pt); + } else if (absPDG == PDG_t::kKPlus) { + particlePtBySpecies[kKaon].push_back(pt); + mcKaPt.push_back(pt); + } else if (absPDG == PDG_t::kProton) { + particlePtBySpecies[kProton].push_back(pt); + mcPrPt.push_back(pt); + } + particlePtAll.push_back(pt); + } + } - if (enablePIDHistograms) { - ue.add("Proton/hNsigmaTPC", "TPC n#sigma p+#bar{p};#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", HistType::kTH2D, {ptAxis, {200, -10, 10}}); - } + // Fill NchMCcentVsTVX before TVX selection + registry.fill(HIST("NchMCcentVsTVX"), nChMCEta, 0.5); - ue.add("hEventsReco_Cent", "Reconstructed events vs centrality;FT0M Centrality (%);Counts", HistType::kTH1D, {centAxis}); - ue.add("hEventsINEL_Cent", "INEL>0 events vs centrality;FT0M Centrality (%);Counts", HistType::kTH1D, {centAxis}); - - ue.add("hNclFoundTPCBefore", "Number of TPC found clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclPIDTPCBefore", "Number of TPC PID clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclFoundTPCAfter", "Number of TPC found after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclPIDTPCAfter", "Number of TPC PID after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hEta", "Track eta;#eta;Counts", HistType::kTH1D, {{20, -0.8, 0.8}}); - ue.add("hPhi", "Track phi;#varphi (rad);Counts", HistType::kTH1D, {{64, 0, TwoPI}}); - ue.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); - - // De/Dx for ch and v0 particles - for (int i = 0; i < ParticlesType; ++i) { - ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumPos[i])).c_str(), - "dE/dx vs Momentum Positive", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); - ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumNeg[i])).c_str(), - "dE/dx vs Momentum Negative", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); - } - // pt vs p - for (int i = 0; i < ResponseMatrixTypes; ++i) { - ue.add(("ResponseMatrix/" + std::string(EtavspvspTPosPart[i])).c_str(), - "eta vs pT vs p Positive", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); - ue.add(("ResponseMatrix/" + std::string(EtavspvspTNegPart[i])).c_str(), - "eta vs pT vs p Negative", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); - } + if (selTVXMC.value && !(nChFT0A > 0 && nChFT0C > 0)) + return; + registry.fill(HIST("NchMCcentVsTVX"), nChMCEta, 1.5); + registry.fill(HIST("EventCounter"), kTVXequiv); - for (int i = 0; i < CentralityClasses + 1; ++i) { - ue.add(("Binning/" + std::string(CentpPos[i])).c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - ue.add(("Binning/" + std::string(CentpNeg[i])).c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - ue.add(("Binning/" + std::string(CentpTPos[i])).c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - ue.add(("Binning/" + std::string(CentpTNeg[i])).c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - } + if (isZvtxPosSelMC.value && std::abs(mcCollision.posZ()) > cfgCutVertex.value) + return; + registry.fill(HIST("EventCounter"), kVtxZ); - // ===== Particle Fractions as function of p and pT ===== - ue.add("ParticleFractions/hTotalCountsVsMomentumPos", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add("ParticleFractions/hTotalCountsVsPtPos", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - ue.add("ParticleFractions/hTotalCountsVsMomentumNeg", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add("ParticleFractions/hTotalCountsVsPtNeg", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - - for (int i = 0; i < ParticlesType + 1; ++i) { - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumPos[i])).c_str(), - "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtPos[i])).c_str(), - "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumNeg[i])).c_str(), - "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtNeg[i])).c_str(), - "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - } + if (cfgINELCut.value == 1 && nChINEL == 0) + return; + if (cfgINELCut.value == INELgt1 && nChINEL < INELgt1) + return; + registry.fill(HIST("EventCounter"), kINELgt0); - LOG(info) << "=== Initialization complete ==="; -} + const float nchF = static_cast(nChMCEta); -void MultiplicityPt::processMC(TrackTableMC const& tracks, - aod::McParticles const& particles, - aod::McCollisions const& mcCollisions, - RecoCollisions const& collisions, - aod::McCollisionLabels const& labels, - aod::McCentFT0Ms const& centTable, - BCsRun3 const& /*bcs*/) -{ + // Fill event loss denominator and MC closure + registry.fill(HIST("NchMC_AllGen"), nchF); + registry.fill(HIST("MC/EventLoss/NchGenerated"), nchF); - std::map mcCollisionToNch; - std::set physicsSelectedMCCollisions; - std::map mcCollisionToINELClass; - std::set inel0MCCollisions; - std::map mcCollToCentFromReco; // MC collision ID -> centrality from reco + for (const float& pt : mcPiPt) { + registry.fill(HIST("MCclosure_PtMCPiVsNchMC"), pt, nchF); + registry.fill(HIST("MC/GenPtVsNch"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("MCclosure_PtMCKaVsNchMC"), pt, nchF); + registry.fill(HIST("MC/GenPtVsNch"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("MCclosure_PtMCPrVsNchMC"), pt, nchF); + registry.fill(HIST("MC/GenPtVsNch"), pt, nchF); + } - ue.fill(HIST("MC/GenRecoCollisions"), 1.f, mcCollisions.size()); + // Fill physics-selected histograms (after vertex and INEL cuts) + registry.fill(HIST("MC/EventLoss/NchGenerated_PhysicsSelected"), nchF); + for (const float& pt : mcPiPt) { + registry.fill(HIST("MC/GenPtVsNch_PhysicsSelected"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("MC/GenPtVsNch_PhysicsSelected"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("MC/GenPtVsNch_PhysicsSelected"), pt, nchF); + } - for (const auto& mcCollision : mcCollisions) { - int64_t mcCollId = mcCollision.globalIndex(); - auto particlesInCollision = particles.sliceBy(perMCCol, mcCollId); + // Fill signal loss denominators + for (const float& pt : particlePtBySpecies[kPion]) { + registry.fill(HIST("PtPiVsNchMC_AllGen"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kKaon]) { + registry.fill(HIST("PtKaVsNchMC_AllGen"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kProton]) { + registry.fill(HIST("PtPrVsNchMC_AllGen"), pt, nchF); + } + for (const float& pt : particlePtAll) { + registry.fill(HIST("PtAllVsNchMC_AllGen"), pt, nchF); + } - // Check if event has at least 1 particle in acceptance (INEL>0) - bool hasParticleInAcceptance = false; - for (const auto& particle : particlesInCollision) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - continue; - if (!particle.isPhysicalPrimary()) - continue; - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) - continue; - if (particle.pt() < cfgTrkLowPtCut.value) - continue; - hasParticleInAcceptance = true; - break; + // Fill inclusive histograms - all generated + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtPrimGenAll"), pt); + registry.fill(HIST("Inclusive/hPtPrimGenAllVsMult"), pt, nchF); + } + for (const float& pt : mcPiPt) { + registry.fill(HIST("Pion/hPtPrimGenAll"), pt); + registry.fill(HIST("Pion/hPtPrimGenAllVsMult"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("Kaon/hPtPrimGenAll"), pt); + registry.fill(HIST("Kaon/hPtPrimGenAllVsMult"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("Proton/hPtPrimGenAll"), pt); + registry.fill(HIST("Proton/hPtPrimGenAllVsMult"), pt, nchF); } - if (hasParticleInAcceptance) { - inel0MCCollisions.insert(mcCollId); + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtPrimGen"), pt); + registry.fill(HIST("Inclusive/hPtPrimGenVsMult"), pt, nchF); } - int nGenCharged = countGeneratedChargedPrimaries(particlesInCollision, cfgCutEtaMax.value, cfgTrkLowPtCut.value); - mcCollisionToNch[mcCollId] = nGenCharged; - - bool inel0 = o2::pwglf::isINELgt0mc(particlesInCollision, pdg); - bool inel1 = o2::pwglf::isINELgt1mc(particlesInCollision, pdg); - int inelClass = inel1 ? 2 : (inel0 ? 1 : 0); - mcCollisionToINELClass[mcCollId] = inelClass; - - bool physicsSelected = (std::abs(mcCollision.posZ()) <= cfgCutVertex.value); - if (cfgINELCut.value == INELgt0 && !inel0) - physicsSelected = false; - if (cfgINELCut.value == INELgt1 && !inel1) - physicsSelected = false; - - if (physicsSelected) { - physicsSelectedMCCollisions.insert(mcCollId); - if (inel0) - ue.fill(HIST("MC/GenRecoCollisions"), 2.f); - if (inel1) - ue.fill(HIST("MC/GenRecoCollisions"), 3.f); + const int nRecColls = collisions.size(); + registry.fill(HIST("NumberOfRecoCollisions"), nRecColls); + + if (nRecColls == 0) + return; + registry.fill(HIST("EventCounter"), kRecoColl); + + int biggestNContribs = -1; + int bestCollisionIndex = -1; + for (const auto& col : collisions) { + if (col.numContrib() > biggestNContribs) { + biggestNContribs = col.numContrib(); + bestCollisionIndex = col.globalIndex(); + } } - // Fill generated particle spectra - for (const auto& particle : particlesInCollision) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) + for (const auto& collision : collisions) { + if (collision.globalIndex() != bestCollisionIndex) continue; - if (!particle.isPhysicalPrimary()) + if (!isEventSelectedMC(collision)) continue; - int pdgCode = std::abs(particle.pdgCode()); - float pt = particle.pt(); + registry.fill(HIST("EventCounter"), kRecoSelected); + + const float centrality = collision.centFT0M(); - // Fill hPtPrimGenAll for ALL generated particles (NO CUTS) - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtPrimGenAll"), pt); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtPrimGenAll"), pt); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtPrimGenAll"), pt); + float magField = 0.f; + if (applyPhiCut.value) { + const auto& bc = collision.foundBC_as(); + magField = static_cast(getMagneticField(bc.timestamp())); } - // Fill hPtGenINEL for particles in INEL>0 events (with acceptance cuts) - if (hasParticleInAcceptance) { - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) - continue; - if (particle.pt() < cfgTrkLowPtCut.value) - continue; + // Fill centrality and correlation histograms + registry.fill(HIST("Centrality/hCentRaw"), centrality); + registry.fill(HIST("NchMCVsCent"), centrality, nchF); + registry.fill(HIST("Centrality/hCentVsMult"), centrality, nchF); + registry.fill(HIST("Centrality/hMultVsCent"), nchF, centrality); + registry.fill(HIST("Centrality/hCentVsVz"), centrality, collision.posZ()); + registry.fill(HIST("Centrality_WRecoEvt"), centrality); + registry.fill(HIST("Centrality_WRecoEvtWSelCri"), centrality); + + for (const float& pt : particlePtAll) { + registry.fill(HIST("NchMCVsCentVsPt"), centrality, nchF, pt); + } - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtGenINEL"), pt); - ue.fill(HIST("Pion/hPtGenINEL_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtGenINEL"), pt); - ue.fill(HIST("Kaon/hPtGenINEL_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtGenINEL"), pt); - ue.fill(HIST("Proton/hPtGenINEL_Mult"), pt, nGenCharged); - } + registry.fill(HIST("NchMC_WithRecoEvt"), nchF); + registry.fill(HIST("MC/EventLoss/NchGenerated_Reconstructed"), nchF); + registry.fill(HIST("MC/EventLoss/GenMultVsCent"), centrality, nchF); + registry.fill(HIST("zPosMC"), mcCollision.posZ()); + registry.fill(HIST("zPosReco"), collision.posZ()); + registry.fill(HIST("T0Ccent"), centrality); + + if (collision.has_foundFT0()) { + registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 1.5); + } else { + registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 0.5); + } + if (collision.has_foundFT0() && collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + registry.fill(HIST("T0CcentVsFoundFT0AndTVX"), centrality, 1.5); + } else { + registry.fill(HIST("T0CcentVsFoundFT0AndTVX"), centrality, 0.5); } - // Apply acceptance cuts for physics-selected spectra - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) - continue; - if (particle.pt() < cfgTrkLowPtCut.value) - continue; + // Fill inclusive histograms for reco events + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtPrimRecoEv"), pt); + registry.fill(HIST("Inclusive/hPtPrimRecoEvVsMult"), pt, nchF); + registry.fill(HIST("Inclusive/hPtPrimGoodEv"), pt); + registry.fill(HIST("Inclusive/hPtPrimGoodEvVsMult"), pt, nchF); + } - // Fill generated spectra (physics selected only) - if (physicsSelected) { - ue.fill(HIST("Inclusive/hPtGen"), pt); + // Fill signal loss numerators and efficiency denominators + for (const float& pt : particlePtBySpecies[kPion]) { + registry.fill(HIST("PtPiVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtPiVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenPiVsNchMC_WithRecoEvt"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kKaon]) { + registry.fill(HIST("PtKaVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtKaVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenKaVsNchMC_WithRecoEvt"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kProton]) { + registry.fill(HIST("PtPrVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtPrVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenPrVsNchMC_WithRecoEvt"), pt, nchF); + } + for (const float& pt : particlePtAll) { + registry.fill(HIST("PtAllVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtAllVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenAllVsNchMC_WithRecoEvt"), pt, nchF); + } - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtGen"), pt); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtGen"), pt); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtGen"), pt); - } + // Fill efficiency denominator histograms + for (const float& pt : mcPiPt) { + registry.fill(HIST("Pion/hPtDenEff"), pt); + registry.fill(HIST("Pion/hPtDenEffVsMult"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("Kaon/hPtDenEff"), pt); + registry.fill(HIST("Kaon/hPtDenEffVsMult"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("Proton/hPtDenEff"), pt); + registry.fill(HIST("Proton/hPtDenEffVsMult"), pt, nchF); + } + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtDenEff"), pt); + registry.fill(HIST("Inclusive/hPtDenEffVsMult"), pt, nchF); } - } - } - std::map recoToMcMap; - std::map recoToCentMap; + const auto& groupedTracks = tracksMC.sliceBy(perCollision, collision.globalIndex()); - size_t nPairs = std::min(labels.size(), collisions.size()); - for (size_t i = 0; i < nPairs; ++i) { - const auto& collision = collisions.iteratorAt(i); - const auto& label = labels.iteratorAt(i); - recoToMcMap[collision.globalIndex()] = label.mcCollisionId(); - } + for (const auto& track : groupedTracks) { + if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) + continue; + if (track.pt() < cfgTrkLowPtCut.value) + continue; + if (!track.has_mcParticle()) + continue; - size_t nCentPairs = std::min(centTable.size(), collisions.size()); - for (size_t i = 0; i < nCentPairs; ++i) { - const auto& collision = collisions.iteratorAt(i); - const auto& cent = centTable.iteratorAt(i); - float centValue = cent.centFT0M(); - recoToCentMap[collision.globalIndex()] = centValue; - ue.fill(HIST("Centrality/hCentRaw"), centValue); - } + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeBefore"), track.pt(), phiPrime); + } - std::set reconstructedMCCollisions; - std::set selectedMCCollisions; - - for (const auto& collision : collisions) { - ue.fill(HIST("CutFlow/hCutStats"), 1); - - int64_t collId = collision.globalIndex(); - - // MC matching - auto mcIt = recoToMcMap.find(collId); - if (mcIt == recoToMcMap.end()) - continue; - ue.fill(HIST("CutFlow/hCutStats"), 2); - - int64_t mcCollId = mcIt->second; - auto nchIt = mcCollisionToNch.find(mcCollId); - if (nchIt == mcCollisionToNch.end()) - continue; - int nGenCharged = nchIt->second; - - auto inelIt = mcCollisionToINELClass.find(mcCollId); - int inelClass = (inelIt != mcCollisionToINELClass.end()) ? inelIt->second : 0; - - // Centrality - auto centIt = recoToCentMap.find(collId); - if (centIt == recoToCentMap.end()) - continue; - ue.fill(HIST("CutFlow/hCutStats"), 3); - - float cent = centIt->second; - if (cent < 0 || cent > CentBinMax) - continue; - - // Store centrality for this MC collision (used later for MC truth plots) - mcCollToCentFromReco[mcCollId] = cent; - - // Vertex cut - bool passVertex = std::abs(collision.posZ()) <= cfgCutVertex.value; - if (!passVertex) - continue; - ue.fill(HIST("CutFlow/hCutStats"), 4); - ue.fill(HIST("Centrality/hCentAfterVtx"), cent); - - // INEL cut - bool passINEL = true; - if (cfgINELCut.value == INELgt0 && inelClass < INELgt0) - passINEL = false; - if (cfgINELCut.value == INELgt1 && inelClass < INELgt1) - passINEL = false; - if (!passINEL) - continue; - - // Event passed all cuts - ue.fill(HIST("CutFlow/hCutStats"), 5); - ue.fill(HIST("Centrality/hCentAfterAll"), cent); - - ue.fill(HIST("MC/EventLoss/GenMultVsCent_Selected"), cent, nGenCharged); - ue.fill(HIST("Centrality/hCentVsMult"), cent, nGenCharged); - ue.fill(HIST("Centrality/hMultVsCent"), nGenCharged, cent); - ue.fill(HIST("hvtxZ"), collision.posZ()); - - selectedMCCollisions.insert(mcCollId); - reconstructedMCCollisions.insert(mcCollId); - - // Get magnetic field for phi cut - float magField = 0; - if (applyPhiCut.value) { - const auto& bc = collision.bc_as(); - magField = getMagneticField(bc.timestamp()); - } + const auto& particle = track.mcParticle(); + auto* pdgPart = pdg->GetParticle(particle.pdgCode()); + if (!pdgPart || std::abs(pdgPart->Charge()) < MinCharge) + continue; - int nTracksInEvent = 0; + const bool isPrimary = particle.isPhysicalPrimary(); + const bool isDecay = (!isPrimary) && (particle.getProcess() == TMCProcess::kPDecay); + const bool isMaterial = (!isPrimary) && (!isDecay); + (void)isMaterial; + const int absPDG = std::abs(particle.pdgCode()); + const bool isPi = (absPDG == PDG_t::kPiPlus); + const bool isKa = (absPDG == PDG_t::kKPlus); + const bool isPr = (absPDG == PDG_t::kProton); + + float momentum = track.p(); + float tpcSignal = track.tpcSignal(); + float eta = track.eta(); + int charge = track.sign(); + + int centIndex = -1; + for (int j = 0; j < CentralityClasses; ++j) { + if (centrality >= centBinningStd[j] && centrality < centBinningStd[j + 1]) { + centIndex = j; + break; + } + } + if (centIndex == -1) + continue; - for (const auto& track : tracks) { - if (!track.has_collision()) - continue; - if (track.collisionId() != collId) - continue; - // Ncl distribution before cuts - ue.fill(HIST("hNclFoundTPCBefore"), track.tpcNClsFound()); - ue.fill(HIST("hNclPIDTPCBefore"), track.tpcNClsPID()); + // ==================================================================== + // DEDX VS MOMENTUM HISTOGRAMS FILLING - ALL TRACKS + // ==================================================================== + hDedxVspTMomentumVsCent[10]->Fill(track.pt(), tpcSignal, eta); + if (charge > 0) { + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); + hDedxVsMomentumVsCentPos[centIndex]->Fill(momentum, tpcSignal, eta); + hDedxVspTMomentumVsCent[centIndex]->Fill(track.pt(), tpcSignal, eta); + hMomentumVsEtaPos[centIndex]->Fill(eta, momentum); + hMomentumVsEtaPos[10]->Fill(eta, momentum); + hpTVsEtaPos[centIndex]->Fill(eta, track.pt()); + hpTVsEtaPos[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); + } else { + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); + hDedxVsMomentumVsCentNeg[centIndex]->Fill(momentum, tpcSignal, eta); + hDedxVspTMomentumVsCent[centIndex]->Fill(track.pt(), tpcSignal, eta); + hMomentumVsEtaNeg[centIndex]->Fill(eta, momentum); + hMomentumVsEtaNeg[10]->Fill(eta, momentum); + hpTVsEtaNeg[centIndex]->Fill(eta, track.pt()); + hpTVsEtaNeg[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); + } - if (!passesTrackSelection(track, magField)) - continue; + if (isPrimary) { + if (charge > 0) { + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri"), eta, track.pt(), momentum); + } else { + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri"), eta, track.pt(), momentum); + } + } - nTracksInEvent++; - // Ncl distribution before cuts - ue.fill(HIST("hNclFoundTPCAfter"), track.tpcNClsFound()); - ue.fill(HIST("hNclPIDTPCAfter"), track.tpcNClsPID()); - ue.fill(HIST("hEta"), track.eta()); - ue.fill(HIST("hPhi"), track.phi()); - ue.fill(HIST("Inclusive/hPtReco"), track.pt()); - - // ===== dE/dx and momentum for V0 cross-check histograms ===== - float tpcSignal = track.tpcSignal(); - float momentum = track.p(); // momentum total - float eta = track.eta(); - int charge = track.sign(); - - int centIndex = -1; - for (int j = 0; j < CentralityClasses; ++j) { - if (cent >= centBinningStd[j] && cent < centBinningStd[j + 1]) { - centIndex = j; - break; + registry.fill(HIST("hEta"), track.eta()); + registry.fill(HIST("hPhi"), track.phi()); + registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + + // Fill TPC cluster histograms + registry.fill(HIST("hNclFoundTPC"), track.tpcNClsFound()); + registry.fill(HIST("hNclPIDTPC"), track.tpcNClsPID()); + registry.fill(HIST("hNclFoundTPCvsPt"), track.pt(), track.tpcNClsFound()); + registry.fill(HIST("hNclPIDTPCvsPt"), track.pt(), track.tpcNClsPID()); + + // Fill inclusive reconstructed histograms + registry.fill(HIST("Inclusive/hPtAllReco"), track.pt()); + registry.fill(HIST("Inclusive/hPtAllRecoVsMult"), track.pt(), nchF); + + if (isPi) { + registry.fill(HIST("Pion/hPtAllReco"), track.pt()); + registry.fill(HIST("Pion/hPtAllRecoVsMult"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("Kaon/hPtAllReco"), track.pt()); + registry.fill(HIST("Kaon/hPtAllRecoVsMult"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("Proton/hPtAllReco"), track.pt()); + registry.fill(HIST("Proton/hPtAllRecoVsMult"), track.pt(), nchF); } - } - if (centIndex == -1) - continue; - // dedx for all particles - if (charge > 0) { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); - // binning - ue.fill(HIST("Binning/p_vs_eta_MB_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_MB_Pos"), eta, track.pt()); - - // For centrality - switch (centIndex) { - case 0: - ue.fill(HIST("Binning/p_vs_eta_Cent0_1_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent0_1_Pos"), eta, track.pt()); - break; - case 1: - ue.fill(HIST("Binning/p_vs_eta_Cent1_5_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent1_5_Pos"), eta, track.pt()); - break; - case 2: - ue.fill(HIST("Binning/p_vs_eta_Cent5_10_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent5_10_Pos"), eta, track.pt()); - break; - case 3: - ue.fill(HIST("Binning/p_vs_eta_Cent10_15_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent10_15_Pos"), eta, track.pt()); - break; - case 4: - ue.fill(HIST("Binning/p_vs_eta_Cent15_20_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent15_20_Pos"), eta, track.pt()); - break; - case 5: - ue.fill(HIST("Binning/p_vs_eta_Cent20_30_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent20_30_Pos"), eta, track.pt()); - break; - case 6: - ue.fill(HIST("Binning/p_vs_eta_Cent30_40_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent30_40_Pos"), eta, track.pt()); - break; - case 7: - ue.fill(HIST("Binning/p_vs_eta_Cent40_50_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent40_50_Pos"), eta, track.pt()); - break; - case 8: - ue.fill(HIST("Binning/p_vs_eta_Cent50_70_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent50_70_Pos"), eta, track.pt()); - break; - case 9: - ue.fill(HIST("Binning/p_vs_eta_Cent70_100_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent70_100_Pos"), eta, track.pt()); - break; + if (passesTrackSelectionNoDCA(track)) { + if (isPrimary) { + if (isPi) + registry.fill(HIST("dcaVsPtPi"), track.pt(), track.dcaXY(), centrality); + if (isPr) + registry.fill(HIST("dcaVsPtPr"), track.pt(), track.dcaXY(), centrality); + } else if (isDecay) { + if (isPi) + registry.fill(HIST("dcaVsPtPiDec"), track.pt(), track.dcaXY(), centrality); + if (isPr) + registry.fill(HIST("dcaVsPtPrDec"), track.pt(), track.dcaXY(), centrality); + } else { + if (isPi) + registry.fill(HIST("dcaVsPtPiMat"), track.pt(), track.dcaXY(), centrality); + if (isPr) + registry.fill(HIST("dcaVsPtPrMat"), track.pt(), track.dcaXY(), centrality); + } } - } else { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); - // binning - ue.fill(HIST("Binning/p_vs_eta_MB_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_MB_Neg"), eta, track.pt()); - - switch (centIndex) { - case 0: - ue.fill(HIST("Binning/p_vs_eta_Cent0_1_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent0_1_Neg"), eta, track.pt()); - break; - case 1: - ue.fill(HIST("Binning/p_vs_eta_Cent1_5_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent1_5_Neg"), eta, track.pt()); - break; - case 2: - ue.fill(HIST("Binning/p_vs_eta_Cent5_10_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent5_10_Neg"), eta, track.pt()); - break; - case 3: - ue.fill(HIST("Binning/p_vs_eta_Cent10_15_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent10_15_Neg"), eta, track.pt()); - break; - case 4: - ue.fill(HIST("Binning/p_vs_eta_Cent15_20_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent15_20_Neg"), eta, track.pt()); - break; - case 5: - ue.fill(HIST("Binning/p_vs_eta_Cent20_30_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent20_30_Neg"), eta, track.pt()); - break; - case 6: - ue.fill(HIST("Binning/p_vs_eta_Cent30_40_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent30_40_Neg"), eta, track.pt()); - break; - case 7: - ue.fill(HIST("Binning/p_vs_eta_Cent40_50_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent40_50_Neg"), eta, track.pt()); - break; - case 8: - ue.fill(HIST("Binning/p_vs_eta_Cent50_70_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent50_70_Neg"), eta, track.pt()); - break; - case 9: - ue.fill(HIST("Binning/p_vs_eta_Cent70_100_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent70_100_Neg"), eta, track.pt()); - break; + + if (!passesTrackSelection(track)) + continue; + + if (applyPhiCut.value && !passedPhiCut(track, magField)) + continue; + + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeAfter"), track.pt(), phiPrime); } - } - if (track.mcParticle().isPhysicalPrimary()) { - if (charge > 0) { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri"), eta, track.pt(), momentum); + // Fill efficiency numerators (reconstructed primaries) + if (isPrimary) { + registry.fill(HIST("PtResolution"), particle.pt(), + (track.pt() - particle.pt()) / particle.pt()); + + registry.fill(HIST("Inclusive/hPtNumEff"), particle.pt()); + registry.fill(HIST("Inclusive/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + registry.fill(HIST("Inclusive/hPtPrimRecoVsMult"), track.pt(), nchF); + + if (isPi) { + registry.fill(HIST("Pion/hPtNumEff"), particle.pt()); + registry.fill(HIST("Pion/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Pion/hPtPrimReco"), track.pt()); + registry.fill(HIST("Pion/hPtPrimRecoVsMult"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("Kaon/hPtNumEff"), particle.pt()); + registry.fill(HIST("Kaon/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Kaon/hPtPrimReco"), track.pt()); + registry.fill(HIST("Kaon/hPtPrimRecoVsMult"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("Proton/hPtNumEff"), particle.pt()); + registry.fill(HIST("Proton/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Proton/hPtPrimReco"), track.pt()); + registry.fill(HIST("Proton/hPtPrimRecoVsMult"), track.pt(), nchF); + } + + // Fill efficiency numerator histograms + if (isPi) { + registry.fill(HIST("PtPiVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenPiVsNchMC_RecoTrk"), particle.pt(), nchF); + registry.fill(HIST("MCclosure_PtPiVsNchMC"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("PtKaVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenKaVsNchMC_RecoTrk"), particle.pt(), nchF); + registry.fill(HIST("MCclosure_PtKaVsNchMC"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("PtPrVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenPrVsNchMC_RecoTrk"), particle.pt(), nchF); + registry.fill(HIST("MCclosure_PtPrVsNchMC"), track.pt(), nchF); + } + registry.fill(HIST("PtAllVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenAllVsNchMC_RecoTrk"), particle.pt(), nchF); } else { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri"), eta, track.pt(), momentum); + // Fill secondary particle histograms + registry.fill(HIST("Inclusive/hPtSecReco"), track.pt()); + registry.fill(HIST("Inclusive/hPtSecRecoVsMult"), track.pt(), nchF); + if (isPi) { + registry.fill(HIST("Pion/hPtSecReco"), track.pt()); + registry.fill(HIST("Pion/hPtSecRecoVsMult"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("Kaon/hPtSecReco"), track.pt()); + registry.fill(HIST("Kaon/hPtSecRecoVsMult"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("Proton/hPtSecReco"), track.pt()); + registry.fill(HIST("Proton/hPtSecRecoVsMult"), track.pt(), nchF); + } } - } - if (track.has_mcParticle()) { - const auto& particle = track.mcParticle(); - int pdgCode = std::abs(particle.pdgCode()); - if (particle.isPhysicalPrimary()) { + // ==================================================================== + // DEDX VS MOMENTUM HISTOGRAMS FILLING - PARTICLE SPECIFIC + // ==================================================================== + if (track.has_mcParticle() && isPrimary) { + int pdgCode = std::abs(particle.pdgCode()); + if (charge > 0) { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC"), eta, track.pt(), momentum); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC"), eta, track.pt(), momentum); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC"), eta, track.pt(), momentum); } - } - if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { - if (particle.isPhysicalPrimary()) { - // Fill total counts for fractions + + if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || + pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumPos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hTotalCountsVsPtPos"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC_Part"), eta, track.pt(), momentum); + hTotalMomPosCent[centIndex]->Fill(eta, momentum); + hTotalMomPosCent[10]->Fill(eta, momentum); + hTotalPtPosCent[centIndex]->Fill(eta, track.pt()); + hTotalPtPosCent[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC_Part"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumNeg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hTotalCountsVsPtNeg"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC_Part"), eta, track.pt(), momentum); + hTotalMomNegCent[centIndex]->Fill(eta, momentum); + hTotalMomNegCent[10]->Fill(eta, momentum); + hTotalPtNegCent[centIndex]->Fill(eta, track.pt()); + hTotalPtNegCent[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC_Part"), eta, track.pt(), momentum); } } - } - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtReco"), track.pt()); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Pion/hPtPrimReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + if (pdgCode == PDG_t::kPiPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Pos"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Pos"), eta, track.pt(), momentum); + hFracMomPosCent[0][centIndex]->Fill(eta, momentum); + hFracMomPosCent[0][10]->Fill(eta, momentum); + hFracPtPosCent[0][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[0][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Pos"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Neg"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Neg"), eta, track.pt(), momentum); + hFracMomNegCent[0][centIndex]->Fill(eta, momentum); + hFracMomNegCent[0][10]->Fill(eta, momentum); + hFracPtNegCent[0][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[0][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Neg"), eta, track.pt(), momentum); } - - } else { - ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - } - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtReco"), track.pt()); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Kaon/hPtPrimReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + } else if (pdgCode == PDG_t::kKPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Pos"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Pos"), eta, track.pt(), momentum); + hFracMomPosCent[1][centIndex]->Fill(eta, momentum); + hFracMomPosCent[1][10]->Fill(eta, momentum); + hFracPtPosCent[1][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[1][10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Pos"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Neg"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Neg"), eta, track.pt(), momentum); + hFracMomNegCent[1][centIndex]->Fill(eta, momentum); + hFracMomNegCent[1][10]->Fill(eta, momentum); + hFracPtNegCent[1][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[1][10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Neg"), eta, track.pt(), momentum); } - } else { - ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - } - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtReco"), track.pt()); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Proton/hPtPrimReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + } else if (pdgCode == PDG_t::kProton) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Pos"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Pos"), eta, track.pt(), momentum); + hFracMomPosCent[2][centIndex]->Fill(eta, momentum); + hFracMomPosCent[2][10]->Fill(eta, momentum); + hFracPtPosCent[2][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[2][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Pos"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Neg"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Neg"), eta, track.pt(), momentum); + hFracMomNegCent[2][centIndex]->Fill(eta, momentum); + hFracMomNegCent[2][10]->Fill(eta, momentum); + hFracPtNegCent[2][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[2][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Neg"), eta, track.pt(), momentum); } - } else { - ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - } - } else if (pdgCode == PDG_t::kElectron) { - if (particle.isPhysicalPrimary()) { + } else if (pdgCode == PDG_t::kElectron) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Pos"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Pos"), momentum, tpcSignal, eta); + hFracMomPosCent[3][centIndex]->Fill(eta, momentum); + hFracMomPosCent[3][10]->Fill(eta, momentum); + hFracPtPosCent[3][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[3][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Pos"), momentum, tpcSignal, eta); } else { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Neg"), eta, track.pt()); + hFracMomNegCent[3][centIndex]->Fill(eta, momentum); + hFracMomNegCent[3][10]->Fill(eta, momentum); + hFracPtNegCent[3][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[3][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Neg"), momentum, tpcSignal, eta); } - } - } else if (pdgCode == PDG_t::kMuonPlus) { - if (particle.isPhysicalPrimary()) { + } else if (pdgCode == PDG_t::kMuonPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Pos"), eta, track.pt()); + hFracMomPosCent[4][centIndex]->Fill(eta, momentum); + hFracMomPosCent[4][10]->Fill(eta, momentum); + hFracPtPosCent[4][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[4][10]->Fill(eta, track.pt()); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Neg"), eta, track.pt()); + hFracMomNegCent[4][centIndex]->Fill(eta, momentum); + hFracMomNegCent[4][10]->Fill(eta, momentum); + hFracPtNegCent[4][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[4][10]->Fill(eta, track.pt()); } } } - } - if (passesPIDSelection(track, PartPion)) { - ue.fill(HIST("Pion/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); - } - } + // PID and measured spectra + const int species = bestPIDHypothesis(track); - if (passesPIDSelection(track, PartKaon)) { - ue.fill(HIST("Kaon/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); - } - } + registry.fill(HIST("Inclusive/hPtMeasured"), track.pt()); + registry.fill(HIST("Inclusive/hPtMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Inclusive/hPtMeasuredVsMult"), track.pt(), nchF); - if (passesPIDSelection(track, PartProton)) { - ue.fill(HIST("Proton/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); + if (species == kPion) { + registry.fill(HIST("PtPiMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtPiMeasuredVsNch"), track.pt(), nchF); + registry.fill(HIST("Pion/hPtMeasured"), track.pt()); + registry.fill(HIST("Pion/hPtMeasuredVsMult"), track.pt(), nchF); + if (enablePIDHistograms) { + registry.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); + } + } else if (species == kKaon) { + registry.fill(HIST("PtKaMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtKaMeasuredVsNch"), track.pt(), nchF); + registry.fill(HIST("Kaon/hPtMeasured"), track.pt()); + registry.fill(HIST("Kaon/hPtMeasuredVsMult"), track.pt(), nchF); + if (enablePIDHistograms) { + registry.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); + } + } else if (species == kProton) { + registry.fill(HIST("PtPrMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtPrMeasuredVsNch"), track.pt(), nchF); + registry.fill(HIST("Proton/hPtMeasured"), track.pt()); + registry.fill(HIST("Proton/hPtMeasuredVsMult"), track.pt(), nchF); + if (enablePIDHistograms) { + registry.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); + } } + + registry.fill(HIST("PtAllMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtAllMeasuredVsNch"), track.pt(), nchF); } + break; } - - ue.fill(HIST("Centrality/hRecoMultVsCent"), cent, nTracksInEvent); } + PROCESS_SWITCH(MultiplicityPt, processSim, "Process MC simulation", true); - for (const auto& mcCollision : mcCollisions) { - int64_t mcCollId = mcCollision.globalIndex(); - - if (reconstructedMCCollisions.find(mcCollId) == reconstructedMCCollisions.end()) - continue; + void processData(CollisionTableData::iterator const& collision, + TrackTableData const& tracks, + BCsRun3 const& bcs) + { + (void)bcs; - auto centIt = mcCollToCentFromReco.find(mcCollId); - if (centIt == mcCollToCentFromReco.end()) - continue; + if (!isEventSelected(collision)) + return; - auto nchIt = mcCollisionToNch.find(mcCollId); - int nGenCharged = (nchIt != mcCollisionToNch.end()) ? nchIt->second : 0; + const float centrality = collision.centFT0M(); - auto particlesInCollision = particles.sliceBy(perMCCol, mcCollId); + float magField = 0; + if (applyPhiCut.value) { + const auto& bc = collision.bc_as(); + magField = getMagneticField(bc.timestamp()); + } - for (const auto& particle : particlesInCollision) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - continue; - if (!particle.isPhysicalPrimary()) - continue; + registry.fill(HIST("hvtxZ"), collision.posZ()); - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) + for (const auto& track : tracks) { + if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) continue; - if (particle.pt() < cfgTrkLowPtCut.value) + if (track.pt() < cfgTrkLowPtCut.value) continue; - int pdgCode = std::abs(particle.pdgCode()); - float pt = particle.pt(); - - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtGenRecoEvent"), pt); - ue.fill(HIST("Pion/hPtGenRecoEvent_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtGenRecoEvent"), pt); - ue.fill(HIST("Kaon/hPtGenRecoEvent_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtGenRecoEvent"), pt); - ue.fill(HIST("Proton/hPtGenRecoEvent_Mult"), pt, nGenCharged); + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeBefore"), track.pt(), phiPrime); } - } - } - for (const auto& mcCollId : inel0MCCollisions) { - auto centIt = mcCollToCentFromReco.find(mcCollId); - if (centIt != mcCollToCentFromReco.end()) { - float cent = centIt->second; - int nGenCharged = mcCollisionToNch[mcCollId]; - ue.fill(HIST("MC/EventLoss/GenMultVsCent"), cent, nGenCharged); - ue.fill(HIST("hEventsINEL_Cent"), cent); - } - } + if (!passesTrackSelection(track)) + continue; - for (const auto& mcCollId : reconstructedMCCollisions) { - auto centIt = mcCollToCentFromReco.find(mcCollId); - if (centIt != mcCollToCentFromReco.end()) { - ue.fill(HIST("hEventsReco_Cent"), centIt->second); - } - } + if (applyPhiCut.value && !passedPhiCut(track, magField)) + continue; - ue.fill(HIST("hEventLossBreakdown"), 1.f, physicsSelectedMCCollisions.size()); - ue.fill(HIST("hEventLossBreakdown"), 2.f, reconstructedMCCollisions.size()); - ue.fill(HIST("hEventLossBreakdown"), 3.f, selectedMCCollisions.size()); + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeAfter"), track.pt(), phiPrime); + } - ue.fill(HIST("MC/GenRecoCollisions"), 4.f, reconstructedMCCollisions.size()); - ue.fill(HIST("MC/GenRecoCollisions"), 5.f, selectedMCCollisions.size()); + registry.fill(HIST("hEta"), track.eta()); + registry.fill(HIST("hPhi"), track.phi()); + registry.fill(HIST("Inclusive/hPtMeasured"), track.pt()); + registry.fill(HIST("Inclusive/hPtMeasuredVsCent"), track.pt(), centrality); - LOG(info) << "\n=== EVENT STATISTICS ==="; - LOG(info) << "INEL>0 MC collisions: " << inel0MCCollisions.size(); - LOG(info) << "Physics selected MC collisions: " << physicsSelectedMCCollisions.size(); - LOG(info) << "Reconstructed collisions: " << reconstructedMCCollisions.size(); - LOG(info) << "Selected collisions: " << selectedMCCollisions.size(); + const int species = bestPIDHypothesis(track); + if (species == kPion) { + registry.fill(HIST("PtPiMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Pion/hPtMeasured"), track.pt()); + if (enablePIDHistograms) { + registry.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); + } + } else if (species == kKaon) { + registry.fill(HIST("PtKaMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Kaon/hPtMeasured"), track.pt()); + if (enablePIDHistograms) { + registry.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); + } + } else if (species == kProton) { + registry.fill(HIST("PtPrMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Proton/hPtMeasured"), track.pt()); + if (enablePIDHistograms) { + registry.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); + } + } - if (physicsSelectedMCCollisions.size() > 0) { - float efficiency = 100.f * selectedMCCollisions.size() / physicsSelectedMCCollisions.size(); - LOG(info) << "Final efficiency: " << efficiency << "%"; + registry.fill(HIST("PtAllMeasuredVsCent"), track.pt(), centrality); + } } -} + PROCESS_SWITCH(MultiplicityPt, processData, "Process data", false); +}; -void MultiplicityPt::processData(CollisionTableData::iterator const& /*collision*/, - TrackTableData const& /*tracks*/, - BCsRun3 const& /*bcs*/) +// ============================================================ +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + return WorkflowSpec{adaptAnalysisTask(cfgc)}; } From 1d3bced1277d89a1cb7e3f9876bf09081a164a1e Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Thu, 11 Jun 2026 22:27:13 -0600 Subject: [PATCH 11/11] Applied clang format --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index e721b655ac3..f5ad892bd5c 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -29,20 +29,20 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/Logger.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "TMCProcess.h" -#include "TPDGCode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include +#include +#include #include #include