From 18b551f99302c6786c67a973984e88086511d0c7 Mon Sep 17 00:00:00 2001 From: Sushanta Tripathy Date: Thu, 5 Mar 2026 13:10:10 +0100 Subject: [PATCH] Fixing minor bugs --- .../Tasks/nucleibalance.cxx | 128 ++++++++++++++---- 1 file changed, 98 insertions(+), 30 deletions(-) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx index 6eb1425355d..c905bda396d 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx @@ -24,18 +24,18 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -1707,7 +1707,8 @@ struct Lambdastarproxy { Configurable lstarMixZvtxMax{"lstarMixZvtxMax", float{MixZvtxMaxDefault}, "Max |Δzvtx| (cm) for event mixing"}; Configurable lstarMixMultMax{"lstarMixMultMax", float{MixMultMaxDefault}, "Max |Δmult| for event mixing"}; Configurable lstarEnablePidQA{"lstarEnablePidQA", 0, "Enable PID QA histograms (dE/dx, TOF #beta, proxy invariant-mass QA, etc.): 1 = ON, 0 = OFF"}; - Configurable lstarEnableSparse{"lstarEnableSparse", 0, "Enable THnSparse invariant-mass histograms (#Lambda^{*} pK and proxy); 1 = ON, 0 = OFF"}; + Configurable lstarEnableSparse{"lstarEnableSparse", 1, "Enable THnSparse invariant-mass histograms (#Lambda^{*} pK and proxy); 1 = ON, 0 = OFF"}; + Configurable lstarLambdaAbsYMax{"lstarLambdaAbsYMax", 0.5f, "Max |y_{pK}| (or y_{proxy K}) for #Lambda^{*} candidates"}; struct KaonCand { float px, py, pz; @@ -1719,6 +1720,11 @@ struct Lambdastarproxy { int charge; int tid; }; + struct ProtonCand { + float px, py, pz; + int charge; + int tid; + }; // Helpers for invariant-mass kinematics static float phiFromPxPy(float px, float py) @@ -2004,7 +2010,7 @@ struct Lambdastarproxy { // Deuteron-proxy invariant mass (p_{proxy} from d/2 combined with K) histos.add("hDeuteronProxyMass", - "#Lambda^{*} proxy invariant mass from (d/2 + K);M_{pK} (GeV/c^{2});Counts", + "#Lambda^{*} proxy invariant mass from (d/2 + K);M_{p_{proxy}K} (GeV/c^{2});Counts", HistType::kTH1F, {massAxis}); // TPC dE/dx vs total momentum @@ -2405,8 +2411,10 @@ struct Lambdastarproxy { std::vector kaonCands; std::vector proxyCands; + std::vector protonCands; kaonCands.reserve(128); proxyCands.reserve(32); + protonCands.reserve(128); float eventMultFallback = 0.f; // fallback mixing variable: number of selected charged tracks (after quality cuts) @@ -2507,7 +2515,9 @@ struct Lambdastarproxy { // PID for deuteron candidates const float nsTPCDe = trkD.tpcNSigmaDe(); const float nsTOFDe = trkD.tofNSigmaDe(); - const bool isDeuteron = (std::abs(nsTPCDe) < lstarCutNsigmaTPCDe.value) && (std::abs(nsTOFDe) < lstarCutNsigmaTOFDe.value); + const bool hasTofDe = hasTOFMatch(trkD); + const bool isDeuteron = (std::abs(nsTPCDe) < lstarCutNsigmaTPCDe.value) && + (!hasTofDe || (std::abs(nsTOFDe) < lstarCutNsigmaTOFDe.value)); if (!isDeuteron) { continue; } @@ -2537,6 +2547,38 @@ struct Lambdastarproxy { proxyCands.push_back(ProxyCand{pxProxy, pyProxy, pzProxy, static_cast(trkD.sign()), static_cast(trkD.globalIndex())}); } + // Proton candidates (for genuine pK #Lambda^{*} reconstruction) + for (auto const& trkP : tracks) { + if (trkP.pt() < lstarCutPtMin.value || std::abs(trkP.eta()) > lstarCutEtaMax.value) { + continue; + } + if (!passTrackQuality(trkP)) { + continue; + } + if (trkP.sign() == 0) { + continue; + } + + const float nsTPCPr = trkP.tpcNSigmaPr(); + const float nsTOFPr = trkP.tofNSigmaPr(); + const bool hasTofPr = hasTOFMatch(trkP); + const bool isProton = (std::abs(nsTPCPr) < lstarCutNsigmaTPCPr.value) && + (!hasTofPr || (std::abs(nsTOFPr) < lstarCutNsigmaTOFPr.value)); + if (!isProton) { + continue; + } + + const float ptP = trkP.pt(); + const float etaP = trkP.eta(); + const float phiP = trkP.phi(); + + const float pxP = ptP * std::cos(phiP); + const float pyP = ptP * std::sin(phiP); + const float pzP = ptP * std::sinh(etaP); + + protonCands.push_back(ProtonCand{pxP, pyP, pzP, static_cast(trkP.sign()), static_cast(trkP.globalIndex())}); + } + // Kaon candidates for (auto const& trkK : tracks) { if (trkK.pt() < lstarCutPtMin.value || std::abs(trkK.eta()) > lstarCutEtaMax.value) { @@ -2552,7 +2594,9 @@ struct Lambdastarproxy { // PID for kaon candidates const float nsTPCK = trkK.tpcNSigmaKa(); const float nsTOFK = trkK.tofNSigmaKa(); - const bool isKaon = (std::abs(nsTPCK) < lstarCutNsigmaTPCKaon.value) && (std::abs(nsTOFK) < lstarCutNsigmaTOFKaon.value); + const bool hasTofK = hasTOFMatch(trkK); + const bool isKaon = (std::abs(nsTPCK) < lstarCutNsigmaTPCKaon.value) && + (!hasTofK || (std::abs(nsTOFK) < lstarCutNsigmaTOFKaon.value)); if (!isKaon) { continue; } @@ -2595,12 +2639,14 @@ struct Lambdastarproxy { return; } - // --- SAME-EVENT: proxy (d/2) + K --- - for (auto const& pr : proxyCands) { + // --- SAME-EVENT: genuine pK #Lambda^{*} candidates --- + for (auto const& pr : protonCands) { for (auto const& k : kaonCands) { - if (pr.tid == k.tid) - continue; // sanity check: should never match, but just in case of bug in candidate-building logic - const double mass = invariantMass(pr.px, pr.py, pr.pz, MassProton, k.px, k.py, k.pz, MassKaonCharged); + if (pr.tid == k.tid) { + continue; + } + const double mass = invariantMass(pr.px, pr.py, pr.pz, MassProton, + k.px, k.py, k.pz, MassKaonCharged); const float pxTot = pr.px + k.px; const float pyTot = pr.py + k.py; @@ -2608,17 +2654,16 @@ struct Lambdastarproxy { const float ptPair = std::sqrt(pxTot * pxTot + pyTot * pyTot); const float phiPair = phiFromPxPy(pxTot, pyTot); - const double eTot = std::sqrt(mass * mass + static_cast(pxTot) * pxTot + static_cast(pyTot) * pyTot + static_cast(pzTot) * pzTot); + const double eTot = std::sqrt(mass * mass + static_cast(pxTot) * pxTot + + static_cast(pyTot) * pyTot + static_cast(pzTot) * pzTot); const float yPair = rapidityFromEPz(eTot, pzTot); - // Inclusive invariant-mass spectrum for the #Lambda^{*} proxy - histos.fill(HIST("hDeuteronProxyMass"), mass); - if (lstarEnableSparse.value != 0) { - histos.fill(HIST("hLambdaStarProxySparse"), mass, ptPair, yPair, phiPair, eventMult); + if (std::abs(yPair) > lstarLambdaAbsYMax.value) { + continue; } - const bool unlikeSign = (pr.charge * k.charge) < 0; - if (unlikeSign) { + const bool unlikeSignPK = (pr.charge * k.charge) < 0; + if (unlikeSignPK) { histos.fill(HIST("hInvMassPKUnlike"), mass); histos.fill(HIST("hInvMassPKUnlikeVsPt"), mass, ptPair); if (lstarEnableSparse.value != 0) { @@ -2634,6 +2679,30 @@ struct Lambdastarproxy { } } + // --- SAME-EVENT: proxy (d/2) + K --- + for (auto const& pr : proxyCands) { + for (auto const& k : kaonCands) { + if (pr.tid == k.tid) + continue; // sanity check: should never match, but just in case of bug in candidate-building logic + const double mass = invariantMass(pr.px, pr.py, pr.pz, MassProton, k.px, k.py, k.pz, MassKaonCharged); + + const float pxTot = pr.px + k.px; + const float pyTot = pr.py + k.py; + const float pzTot = pr.pz + k.pz; + const float ptPair = std::sqrt(pxTot * pxTot + pyTot * pyTot); + const float phiPair = phiFromPxPy(pxTot, pyTot); + + const double eTot = std::sqrt(mass * mass + static_cast(pxTot) * pxTot + static_cast(pyTot) * pyTot + static_cast(pzTot) * pzTot); + const float yPair = rapidityFromEPz(eTot, pzTot); + + // Inclusive invariant-mass spectrum for the #Lambda^{*} proxy (d/2 + K) + histos.fill(HIST("hDeuteronProxyMass"), mass); + if (lstarEnableSparse.value != 0) { + histos.fill(HIST("hLambdaStarProxySparse"), mass, ptPair, yPair, phiPair, eventMult); + } + } + } + // --- MIXED-EVENT: current proxies + previous-event kaons --- for (auto const& prev : mLStarMixEvents) { if (std::abs(prev.zvtx - collision.posZ()) > lstarMixZvtxMax.value) @@ -2664,9 +2733,8 @@ struct Lambdastarproxy { const double eTot = std::sqrt(mass * mass + static_cast(pxTot) * pxTot + static_cast(pyTot) * pyTot + static_cast(pzTot) * pzTot); const float yPair = rapidityFromEPz(eTot, pzTot); - // Fill mixed-event THnSparse + // Fill mixed-event THnSparse (proxy only) if (lstarEnableSparse.value != 0) { - histos.fill(HIST("hLambdaStarPKMixedSparse"), mass, ptPair, yPair, phiPair, eventMult); histos.fill(HIST("hLambdaStarProxyMixedSparse"), mass, ptPair, yPair, phiPair, eventMult); } }