From c892d44920cc267d4ff49173e5c91ee3e755fbc2 Mon Sep 17 00:00:00 2001 From: Soumyadip Ghosh Date: Sun, 9 Aug 2026 17:26:36 +0530 Subject: [PATCH 1/4] Enhance PID QA and histogram configurations Added PID response configurations and QA histograms for TPC and TOF. Updated multiplicity and centrality axes for histograms. --- .../Tasks/longrangecorrDerived.cxx | 147 +++++++++++++++++- 1 file changed, 144 insertions(+), 3 deletions(-) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx index c49559df02c..7471acec39b 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx @@ -25,6 +25,8 @@ #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/McCollisionExtra.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" #include @@ -62,6 +64,9 @@ using namespace o2::aod::evsel; using namespace o2::constants::math; auto static constexpr KminCharge = 3.0f; +auto static constexpr KPidMaskPion = 2; +auto static constexpr KPidMaskKaon = 4; +auto static constexpr KPidMaskProton = 8; struct LongrangecorrDerived { @@ -105,14 +110,25 @@ struct LongrangecorrDerived { Configurable cfgRequireFt0aInnerRing{"cfgRequireFt0aInnerRing", false, "Consider FT0A Inner Ring"}; Configurable cfgRequireFt0cOuterRing{"cfgRequireFt0cOuterRing", false, "Consider FT0C Outer Ring"}; Configurable cfgRequireFt0cInnerRing{"cfgRequireFt0cInnerRing", false, "Consider FT0C Inner Ring"}; + + Configurable cfgTofPidPtCut{"cfgTofPidPtCut", 0.4f, "Minimum pt to use TOF N-sigma"}; + Configurable cfgPidNsigmaMax{"cfgPidNsigmaMax", 1.5f, "Maximum n-sigma for PID"}; + Configurable cfgPidNsigmaMin{"cfgPidNsigmaMin", -1.5f, "Minimum n-sigma for PID"}; + Configurable cfgGetNsigmaQA{"cfgGetNsigmaQA", true, "Get QA histograms for PID selection"}; + Configurable cfgGetdEdx{"cfgGetdEdx", true, "Get dEdx histograms for TPC signal"}; + } cfgSel; struct : ConfigurableGroup { ConfigurableAxis axisMultQA{"axisMultQA", {500, -0.5, 499.5}, "multiplicity QA axis"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 10, 15, 25, 50, 60, 1000}, "multiplicity axis"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 26, 46, 133, 1000}, "multiplicity axis"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, "Centrality (%)"}; + ConfigurableAxis axisPhi{"axisPhi", {96, 0, TwoPI}, "#phi axis"}; ConfigurableAxis axisEtaTrig{"axisEtaTrig", {40, -1., 1.}, "#eta trig axis"}; ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"}; + ConfigurableAxis axisPtQA{"axisPtQA", {50, 0.0, 8.0}, "pt axis for PID QA histograms"}; + ConfigurableAxis axisVtxZ{"axisVtxZ", {40, -20, 20}, "vertex axis"}; ConfigurableAxis axisEtaAssoc{"axisEtaAssoc", {96, 3.5, 4.9}, "#eta assoc axis"}; ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; @@ -138,6 +154,11 @@ struct LongrangecorrDerived { ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {1, 0.5, 8.0}, "pt axis for efficiency histograms"}; + + ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {80, -5, 5}, "nsigmaTPC axis"}; + ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"}; + ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "dEdx axis for TPC"}; + } cfgAxis; Configurable cfgFv0Cut{"cfgFv0Cut", 50.0f, "FV0A threshold"}; @@ -265,6 +286,39 @@ struct LongrangecorrDerived { myTrackFilter.SetMaxChi2PerClusterTPC(cfgSel.cfgTpcMaxChi2PerCluster); myTrackFilter.SetMaxDcaZ(cfgSel.cfgTpcMaxDcaZ); myTrackFilter.print(); + + if (cfgSel.cfgGetNsigmaQA && (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton)) { + + if (cfgSel.isUseCentEst) { // CENTRALITY MODE + histos.add("TofTpcNsigma_before", "TPC vs TOF n#sigma Before Cuts;Centrality (%);p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF}); + + histos.add("TofTpcNsigma_after", "TPC vs TOF n#sigma After Cuts;Centrality (%);p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF}); + + if (cfgSel.cfgGetdEdx) { + histos.add("TpcdEdx_ptwise", "TPC dE/dx Before Cuts;Centrality (%);p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF}); + + histos.add("TpcdEdx_ptwise_afterCut", "TPC dE/dx After Cuts;Centrality (%);p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF}); + } + } else { // MULTIPLICITY MODE + histos.add("TofTpcNsigma_before", "TPC vs TOF n#sigma Before Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF}); + + histos.add("TofTpcNsigma_after", "TPC vs TOF n#sigma After Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF}); + + if (cfgSel.cfgGetdEdx) { + histos.add("TpcdEdx_ptwise", "TPC dE/dx Before Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF}); + + histos.add("TpcdEdx_ptwise_afterCut", "TPC dE/dx After Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}", + kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF}); + } + } + } } void loadEffCorrection(uint64_t timestamp) @@ -277,7 +331,7 @@ struct LongrangecorrDerived { if (hTrkEff == nullptr) { LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgSel.cfgEffccdbPath.value.c_str()); } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff); + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgEffccdbPath.value.c_str(), static_cast(hTrkEff)); } if (cfgSel.cfgAccccdbPath.value.empty() == false) { @@ -285,7 +339,7 @@ struct LongrangecorrDerived { if (hTrkAcc == nullptr) { LOGF(fatal, "Could not load NUA histogram for trigger particles from %s", cfgSel.cfgAccccdbPath.value.c_str()); } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgAccccdbPath.value.c_str(), (void*)hTrkAcc); + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgAccccdbPath.value.c_str(), static_cast(hTrkAcc)); } fLoadTrkEffCorr = true; @@ -1020,6 +1074,92 @@ struct LongrangecorrDerived { } } + using CollStandardTable = soa::Join; + using TrksStandardTable = soa::Join; + + void processPIDQA(CollsTable const& lrCollisions, TrksStandardTable const& standardTracks) + { + for (auto const& col : lrCollisions) { + + if (std::abs(col.posZ()) >= cfgSel.cfgVtxCut) { + continue; + } + + // EXTRACT CENTRALITY/MULTIPLICITY + float multiplicity = 1.0f; + if constexpr (requires { col.centrality(); }) { + if (cfgSel.isUseCentEst) + multiplicity = col.centrality(); + else + multiplicity = col.multiplicity(); + } else { + multiplicity = col.multiplicity(); + } + + auto tracks = standardTracks.sliceByCached(aod::track::collisionId, col.globalIndex(), this->cache); + + for (auto const& track : tracks) { + if (!track.isGlobalTrack()) + continue; + if (!myTrackFilter.IsSelected(track)) + continue; + + float tpcNsig = 0.0f, tofNsig = 0.0f; + if (cfgSel.cfgPidMask & KPidMaskPion) { + tpcNsig = track.tpcNSigmaPi(); + tofNsig = track.tofNSigmaPi(); + } else if (cfgSel.cfgPidMask & KPidMaskKaon) { + tpcNsig = track.tpcNSigmaKa(); + tofNsig = track.tofNSigmaKa(); + } else if (cfgSel.cfgPidMask & KPidMaskProton) { + tpcNsig = track.tpcNSigmaPr(); + tofNsig = track.tofNSigmaPr(); + } + + // FILL BEFORE CUTS + if (cfgSel.cfgGetNsigmaQA && (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton)) { + histos.fill(HIST("TofTpcNsigma_before"), multiplicity, track.pt(), tpcNsig, tofNsig); + if (cfgSel.cfgGetdEdx) { + histos.fill(HIST("TpcdEdx_ptwise"), multiplicity, track.pt(), track.tpcSignal(), tofNsig); + } + } + + bool isTpcPion = (track.tpcNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPi() < cfgSel.cfgPidNsigmaMax); + bool isTpcKaon = (track.tpcNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaKa() < cfgSel.cfgPidNsigmaMax); + bool isTpcProton = (track.tpcNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPr() < cfgSel.cfgPidNsigmaMax); + + bool isTofPion = (track.tofNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPi() < cfgSel.cfgPidNsigmaMax); + bool isTofKaon = (track.tofNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaKa() < cfgSel.cfgPidNsigmaMax); + bool isTofProton = (track.tofNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPr() < cfgSel.cfgPidNsigmaMax); + + bool isPion = false, isKaon = false, isProton = false; + if (track.pt() > cfgSel.cfgTofPidPtCut && track.hasTOF()) { + isPion = isTofPion && isTpcPion; + isKaon = isTofKaon && isTpcKaon; + isProton = isTofProton && isTpcProton; + } else if (!(track.pt() > cfgSel.cfgTofPidPtCut && !track.hasTOF())) { + isPion = isTpcPion; + isKaon = isTpcKaon; + isProton = isTpcProton; + } + + if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) { + isPion = isKaon = isProton = false; + } + + bool isTargetParticle = ((cfgSel.cfgPidMask & KPidMaskPion) && isPion) || ((cfgSel.cfgPidMask & KPidMaskKaon) && isKaon) || ((cfgSel.cfgPidMask & KPidMaskProton) && isProton); + + // FILL AFTER CUTS + if (cfgSel.cfgGetNsigmaQA && isTargetParticle) { + histos.fill(HIST("TofTpcNsigma_after"), multiplicity, track.pt(), tpcNsig, tofNsig); + if (cfgSel.cfgGetdEdx) { + histos.fill(HIST("TpcdEdx_ptwise_afterCut"), multiplicity, track.pt(), track.tpcSignal(), tofNsig); + } + } + } + } + } + PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aSE, "same event TPC vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aME, "mixed event TPC vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processTpcft0cSE, "same event TPC vs FT0C", false); @@ -1067,6 +1207,7 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cSE, "same MC gen event FT0A vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cME, "mixed MC gen event FT0A vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processTPCtrackEff, "process TPC track efficiency", false); + PROCESS_SWITCH(LongrangecorrDerived, processPIDQA, "process PID QA on standard AODs", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From d917217a39f6a43200e5d218b0137912dde4d93b Mon Sep 17 00:00:00 2001 From: Soumyadip Ghosh Date: Tue, 25 Aug 2026 20:19:47 +0530 Subject: [PATCH 2/4] Enhance longrangecorrDerived with MC axes and processing Added new configurable axes for MC particle properties and updated histogram definitions to include these axes. Introduced new processing functions for V0 and mixed events. --- .../Tasks/longrangecorrDerived.cxx | 124 +++++++++++++++++- 1 file changed, 120 insertions(+), 4 deletions(-) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx index 7471acec39b..cdc9e8568a2 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -159,6 +160,9 @@ struct LongrangecorrDerived { ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"}; ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "dEdx axis for TPC"}; + ConfigurableAxis axisMcPt{"axisMcPt", {100, 0.2, 10.0}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisMcEta{"axisMcEta", {100, -0.8, 0.8}, "#eta"}; + ConfigurableAxis axisMcPhi{"axisMcPhi", {100, 0., TwoPI}, "#phi"}; } cfgAxis; Configurable cfgFv0Cut{"cfgFv0Cut", 50.0f, "FV0A threshold"}; @@ -246,7 +250,7 @@ struct LongrangecorrDerived { histos.add("Trig_pt", "Trig_pt", kTH1D, {cfgAxis.axisPtTrigger}); histos.add("Trig_pt_corrected", "Trig_pt_corrected", kTH1D, {cfgAxis.axisPtTrigger}); histos.add("Trig_invMass", "Trig_invMass", kTH1D, {cfgAxis.axisInvMassQA}); - histos.add("Trig_hist", "Trig_hist", kTHnSparseF, {cfgAxis.axisSample, cfgAxis.axisVtxZ, cfgAxis.axisMultiplicity, cfgAxis.axisPtTrigger, cfgAxis.axisInvMass}); + histos.add("Trig_hist", "Trigger Track Properties;Sample;Vertex Z (cm);Multiplicity;p_{T} (GeV/c);Invariant Mass (GeV/c^{2})", kTHnSparseF, {cfgAxis.axisSample, cfgAxis.axisVtxZ, cfgAxis.axisMultiplicity, cfgAxis.axisPtTrigger, cfgAxis.axisInvMass}); histos.add("Trig_amp", "Trig_amp", kTH1D, {cfgAxis.axisAmplitude}); histos.add("Channel_vs_Trig_amp", "Channel_vs_Trig_amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); @@ -275,6 +279,11 @@ struct LongrangecorrDerived { if (doprocessTPCtrackEff) { histos.add("hGenMCdndpt", "hGenMCdndpt", kTH3D, {cfgAxis.axisVtxZ, cfgAxis.axisEtaEfficiency, cfgAxis.axisPtEfficiency}); histos.add("hRecMCdndpt", "hRecMCdndpt", kTH3D, {cfgAxis.axisVtxZ, cfgAxis.axisEtaEfficiency, cfgAxis.axisPtEfficiency}); + + if (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton) { + histos.add("hMCGen_PidPtEtaPhi", "MC Gen Target", kTH3D, {cfgAxis.axisMcPt, cfgAxis.axisMcEta, cfgAxis.axisMcPhi}); + histos.add("hMCRec_PidPtEtaPhi", "MC Rec Target", kTH3D, {cfgAxis.axisMcPt, cfgAxis.axisMcEta, cfgAxis.axisMcPhi}); + } } myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, @@ -770,6 +779,16 @@ struct LongrangecorrDerived { processSame(col, tracks, ft0as); } + void processV0ft0cSE(CollsTable::iterator const& col, V0TrksTable const& tracks, Ft0cTrksTable const& ft0cs) + { + processSame(col, tracks, ft0cs); + } + + void processV0tpcSE(CollsTable::iterator const& col, V0TrksTable const& v0s, TrksTable const& tracks) + { + processSame(col, v0s, tracks); + } + void processV0mftSE(CollsTable::iterator const& col, V0TrksTable const& tracks, MftTrksTable const& mfts) { processSame(col, tracks, mfts); @@ -805,6 +824,16 @@ struct LongrangecorrDerived { processMixed(cols, tracks, ft0as); } + void processV0ft0cME(CollsTable const& cols, V0TrksTable const& tracks, Ft0cTrksTable const& ft0cs) + { + processMixed(cols, tracks, ft0cs); + } + + void processV0tpcME(CollsTable const& cols, V0TrksTable const& v0s, TrksTable const& tracks) + { + processMixed(cols, v0s, tracks); + } + void processV0mftME(CollsTable const& cols, V0TrksTable const& tracks, MftTrksTable const& mfts) { processMixed(cols, tracks, mfts); @@ -855,6 +884,11 @@ struct LongrangecorrDerived { processSame(col, tracks, ft0as); } + void processUpcV0ft0cSE(UpcCollsTable::iterator const& col, V0TrksUpcTable const& tracks, Ft0cTrksUpcTable const& ft0cs) + { + processSame(col, tracks, ft0cs); + } + void processUpcV0mftSE(UpcCollsTable::iterator const& col, V0TrksUpcTable const& tracks, MftTrksUpcTable const& mfts) { if (!isUpcEventSelected(col)) { @@ -888,6 +922,11 @@ struct LongrangecorrDerived { processMixed(cols, tracks, ft0as); } + void processUpcV0ft0cME(UpcCollsTable const& cols, V0TrksUpcTable const& tracks, Ft0cTrksUpcTable const& ft0cs) + { + processMixed(cols, tracks, ft0cs); + } + void processUpcV0mftME(UpcCollsTable const& cols, V0TrksUpcTable const& tracks, MftTrksUpcTable const& mfts) { processMixed(cols, tracks, mfts); @@ -963,6 +1002,16 @@ struct LongrangecorrDerived { processMcGenSame(mccollision, mfts, ft0as); } + void processMcGenV0ft0aSE(McCollsTable::iterator const& mccollision, McTrksTable const& tracks, McFt0aTrksTable const& ft0as) + { + processMcGenSame(mccollision, tracks, ft0as); + } + + void processMcGenV0ft0cSE(McCollsTable::iterator const& mccollision, McTrksTable const& tracks, McFt0cTrksTable const& ft0cs) + { + processMcGenSame(mccollision, tracks, ft0cs); + } + void processMcGenFt0aft0cSE(McCollsTable::iterator const& mccollision, McFt0aTrksTable const& ft0as, McFt0cTrksTable const& ft0cs) { processMcGenSame(mccollision, ft0as, ft0cs); @@ -988,6 +1037,16 @@ struct LongrangecorrDerived { processMcGenMixed(mccollisions, mfts, ft0as); } + void processMcGenV0ft0aME(McCollsTable const& mccollisions, McTrksTable const& tracks, McFt0aTrksTable const& ft0as) + { + processMcGenMixed(mccollisions, tracks, ft0as); + } + + void processMcGenV0ft0cME(McCollsTable const& mccollisions, McTrksTable const& tracks, McFt0cTrksTable const& ft0cs) + { + processMcGenMixed(mccollisions, tracks, ft0cs); + } + void processMcGenFt0aft0cME(McCollsTable const& mccollisions, McFt0aTrksTable const& ft0as, McFt0cTrksTable const& ft0cs) { processMcGenMixed(mccollisions, ft0as, ft0cs); @@ -995,7 +1054,7 @@ struct LongrangecorrDerived { using ColMCTrueTable = soa::Join; using ColMCRecTable = soa::SmallGroups>; - using TrksMCRecTable = soa::Join; + using TrksMCRecTable = soa::Join; Preslice perColMidtrack = aod::track::collisionId; template @@ -1039,7 +1098,6 @@ struct LongrangecorrDerived { continue; if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) continue; - auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); atLeastOne = true; } for (const auto& particle : mcparticles) { @@ -1048,9 +1106,23 @@ struct LongrangecorrDerived { particle.pt() < cfgSel.cfgPtCutMin || particle.pt() > cfgSel.cfgPtCutMax) continue; - if (atLeastOne) + if (atLeastOne) { histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), particle.eta(), particle.pt()); + + if (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton) { + auto pdgcode = std::abs(particle.pdgCode()); + + bool isTargetGen = (cfgSel.cfgPidMask == KPidMaskPion && pdgcode == PDG_t::kPiPlus) || + (cfgSel.cfgPidMask == KPidMaskKaon && pdgcode == PDG_t::kKPlus) || + (cfgSel.cfgPidMask == KPidMaskProton && pdgcode == PDG_t::kProton); + + if (isTargetGen) { + histos.fill(HIST("hMCGen_PidPtEtaPhi"), particle.pt(), particle.eta(), particle.phi()); + } + } + } } + for (const auto& RecCol : RecCols) { if (!isEventSelected(RecCol)) continue; @@ -1069,6 +1141,40 @@ struct LongrangecorrDerived { continue; if (particle.isPhysicalPrimary()) { histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), particle.eta(), particle.pt()); + + bool isTpcPion = (track.tpcNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPi() < cfgSel.cfgPidNsigmaMax); + bool isTpcKaon = (track.tpcNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaKa() < cfgSel.cfgPidNsigmaMax); + bool isTpcProton = (track.tpcNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPr() < cfgSel.cfgPidNsigmaMax); + + bool isTofPion = (track.tofNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPi() < cfgSel.cfgPidNsigmaMax); + bool isTofKaon = (track.tofNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaKa() < cfgSel.cfgPidNsigmaMax); + bool isTofProton = (track.tofNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPr() < cfgSel.cfgPidNsigmaMax); + + bool isPion = false, isKaon = false, isProton = false; + + if (track.pt() > cfgSel.cfgTofPidPtCut && track.hasTOF()) { + isPion = isTofPion && isTpcPion; + isKaon = isTofKaon && isTpcKaon; + isProton = isTofProton && isTpcProton; + } else if (!(track.pt() > cfgSel.cfgTofPidPtCut && !track.hasTOF())) { + isPion = isTpcPion; + isKaon = isTpcKaon; + isProton = isTpcProton; + } + + if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) { + isPion = isKaon = isProton = false; + } + + if (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton) { + bool isTargetRec = (cfgSel.cfgPidMask == KPidMaskPion && isPion) || + (cfgSel.cfgPidMask == KPidMaskKaon && isKaon) || + (cfgSel.cfgPidMask == KPidMaskProton && isProton); + + if (isTargetRec) { + histos.fill(HIST("hMCRec_PidPtEtaPhi"), particle.pt(), particle.eta(), particle.phi()); + } + } } } } @@ -1170,6 +1276,10 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processMftft0aME, "mixed event MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processV0ft0aSE, "same event V0 vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processV0ft0aME, "mixed event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0ft0cSE, "same event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0ft0cME, "mixed event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0tpcSE, "same event V0 vs TPC", false); + PROCESS_SWITCH(LongrangecorrDerived, processV0tpcME, "mixed event V0 vs TPC", false); PROCESS_SWITCH(LongrangecorrDerived, processV0mftSE, "same event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processV0mftME, "mixed event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processFt0aft0cSE, "same event FT0A vs FT0C", false); @@ -1184,6 +1294,8 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processUpcMftft0aME, "mixed UPC event MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0aSE, "same UPC event V0 vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0aME, "mixed UPC event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0cSE, "same UPC event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processUpcV0ft0cME, "mixed UPC event V0 vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0mftSE, "same UPC event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processUpcV0mftME, "mixed UPC event V0 vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processMcTpcft0aSE, "same MC event TPC vs FT0A", false); @@ -1204,6 +1316,10 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processMcGenTpcmftME, "mixed MC gen event TPC vs MFT", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenMftft0aSE, "same MC gen event MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenMftft0aME, "mixed MC gen event MFT vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0aSE, "same MC gen event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0aME, "mixed MC gen event V0 vs FT0A", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0cSE, "same MC gen event V0 vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processMcGenV0ft0cME, "mixed MC gen event V0 vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cSE, "same MC gen event FT0A vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cME, "mixed MC gen event FT0A vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processTPCtrackEff, "process TPC track efficiency", false); From 389601ef4253d7e43ba902e7ff28bedb724b5359 Mon Sep 17 00:00:00 2001 From: Soumyadip Ghosh Date: Wed, 26 Aug 2026 00:05:41 +0530 Subject: [PATCH 3/4] Enhance V0 selection and add new histograms Added new configurable parameters for V0 selection and updated the processV0QA function to include additional histogram filling for V0 candidates. Enhanced selection criteria for K0s and Lambda candidates with PID cuts. --- .../TableProducer/longrangeMaker.cxx | 175 ++++++++++++++++-- 1 file changed, 157 insertions(+), 18 deletions(-) diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx index 5a11c2ae50d..d7deb6bcc56 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx @@ -207,6 +207,9 @@ struct LongrangeMaker { Configurable minV0DcaPiLambda{"minV0DcaPiLambda", 0.2f, "Min V0 pion DCA for Lambda"}; Configurable minV0DcaPr{"minV0DcaPr", 0.07f, "Min V0 proton DCA for Lambda"}; Configurable maxLambdaLifeTime{"maxLambdaLifeTime", 30.0f, "Maximum Lambda lifetime (in cm)"}; + + Configurable rejK0sMassWindow{"rejK0sMassWindow", 0.012f, "K0s mass rejection window for Lambda (12 MeV/c^2)"}; + Configurable cfgQAV0Mask{"cfgQAV0Mask", 7, "Bitmask for V0 QA: 1=K0s, 2=Lambda, 4=ALambda, 7=All"}; } cfgv0trksel; struct : ConfigurableGroup { @@ -216,6 +219,23 @@ struct LongrangeMaker { ConfigurableAxis axisMFTAmbDegree{"axisMFTAmbDegree", {50, -0.5, 49.5}, "Track Ambiguity axis"}; ConfigurableAxis axisEta = {"axisEta", {100, -5, 5}, "eta axis"}; ConfigurableAxis axisPhi{"axisPhi", {72, 0, TwoPI}, "#phi axis"}; + + ConfigurableAxis axisV0Species{"axisV0Species", {3, -0.5, 2.5}, "V0 Species (0=K0s, 1=#Lambda, 2=#bar{#Lambda})"}; + ConfigurableAxis axisAlpha{"axisAlpha", {100, -1.0, 1.0}, "Armenteros #alpha"}; + ConfigurableAxis axisQt{"axisQt", {100, 0.0, 0.42}, "Armenteros q_{T} (GeV/c)"}; + ConfigurableAxis axisV0Pt{"axisV0Pt", {100, 0.0, 10.0}, "V0 p_{T} (GeV/c)"}; + ConfigurableAxis axisMass{"axisMass", {150, 0.4, 1.2}, "Invariant Mass (GeV/c^{2})"}; + ConfigurableAxis axisDcaV0Dau{"axisDcaV0Dau", {100, 0.0, 1.5}, "DCA between V0 Daughters (cm)"}; + ConfigurableAxis axisDcaPosToPv{"axisDcaPosToPv", {100, 0.0, 10.0}, "DCA Pos-Prong to PV (cm)"}; + ConfigurableAxis axisDcaNegToPv{"axisDcaNegToPv", {100, 0.0, 10.0}, "DCA Neg-Prong to PV (cm)"}; + ConfigurableAxis axisDcaV0ToPv{"axisDcaV0ToPv", {100, 0.0, 5.0}, "DCA V0 to PV (cm)"}; + ConfigurableAxis axisCosPA{"axisCosPA", {100, 0.97, 1.0}, "Cosine of Pointing Angle (cos#theta_{PA})"}; + ConfigurableAxis axisRadius{"axisRadius", {100, 0.0, 100.0}, "V0 2D Decay Radius (cm)"}; + ConfigurableAxis axisCtau{"axisCtau", {100, 0.0, 50.0}, "Proper Lifetime c#tau (cm)"}; + + ConfigurableAxis axisPQA{"axisPQA", {100, 0.0, 10.0}, "p (GeV/c)"}; + ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "TPC dE/dx (a.u.)"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 25, 30, 40, 50, 60, 80, 100, 150, 200}, "Multiplicity / Centrality"}; } cfgAxis; Configurable> itsNsigmaPidCut{"itsNsigmaPidCut", std::vector{3, 2.5, 2, -3, -2.5, -2}, "ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; @@ -315,6 +335,17 @@ struct LongrangeMaker { histos.add("FT0C_Channel_vs_phi", "FT0C_Channel_vs_phi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisChannel}); histos.add("h3DVtxZetaPhi", "", kTH3D, {{20, -10, 10}, {16, -0.8, +0.8}, {100, 0., TwoPI}}); + histos.add("hArmenteros_before", "Armenteros-Podolanski (Before Cuts);#alpha;q_{T} (GeV/c)", kTH2D, {cfgAxis.axisAlpha, cfgAxis.axisQt}); + histos.add("hArmenteros_after", "Armenteros-Podolanski (After Cuts);V0 Species;#alpha;q_{T} (GeV/c)", kTH3D, {cfgAxis.axisV0Species, cfgAxis.axisAlpha, cfgAxis.axisQt}); + histos.add("hTopoQA", "V0 Topological and Kinematic QA;V0 Species;DCA between V0 Daughters (cm);DCA Pos-Prong to PV (cm);DCA Neg-Prong to PV (cm);DCA V0 to PV (cm);Cosine of Pointing Angle (cos#theta_{PA});V0 2D Decay Radius (cm);Proper Lifetime c#tau (cm);V0 p_{T} (GeV/c);Invariant Mass (GeV/c^{2})", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisDcaV0Dau, cfgAxis.axisDcaPosToPv, cfgAxis.axisDcaNegToPv, cfgAxis.axisDcaV0ToPv, cfgAxis.axisCosPA, cfgAxis.axisRadius, cfgAxis.axisCtau, cfgAxis.axisV0Pt, cfgAxis.axisMass}); + + // V0 Daughter dE/dx Histograms + histos.add("hTpcdEdx_pos_before", "Pos-prong dE/dx Before PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + histos.add("hTpcdEdx_neg_before", "Neg-prong dE/dx Before PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + + histos.add("hTpcdEdx_pos_after", "Pos-prong dE/dx After PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + histos.add("hTpcdEdx_neg_after", "Neg-prong dE/dx After PID;V0 Species;Multiplicity;p (GeV/c);TPC dE/dx", kTHnSparseF, {cfgAxis.axisV0Species, cfgAxis.axisMultiplicity, cfgAxis.axisPQA, cfgAxis.axisTpcSignal}); + myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); myTrackFilter.SetPtRange(cfgtrksel.cfgPtCutMin, cfgtrksel.cfgPtCutMax); @@ -1004,6 +1035,86 @@ struct LongrangeMaker { } } + void processV0QA(CollTable::iterator const& col, aod::V0Datas const& V0s, TrksTable const& tracks) + { + if (!isEventSelected(col)) { + return; + } + + float multiplicity = selColCent(col); + if (multiplicity == -1) { + multiplicity = countNTracks(tracks, col.posZ()); + } + + bool checkK0s = (cfgv0trksel.cfgQAV0Mask & 1); + bool checkLam = (cfgv0trksel.cfgQAV0Mask & 2); + bool checkALam = (cfgv0trksel.cfgQAV0Mask & 4); + + for (const auto& v0 : V0s) { + if (!isSelectV0Track(v0)) { + continue; + } + + auto posTrack = v0.template posTrack_as(); + auto negTrack = v0.template negTrack_as(); + float posP = posTrack.p(); + float negP = negTrack.p(); + float posSignal = posTrack.tpcSignal(); + float negSignal = negTrack.tpcSignal(); + + histos.fill(HIST("hArmenteros_before"), v0.alpha(), v0.qtarm()); + + // Evaluate topology ONLY (PID disabled) + bool isK0sTopoOnly = checkK0s && isSelectK0s(col, v0, false); + bool isLamTopoOnly = checkLam && isSelectLambda(col, v0, false); + bool isAlamTopoOnly = checkALam && isSelectLambda(col, v0, false); + + // Evaluate full selection (PID enabled) + bool isK0sTag = checkK0s && isSelectK0s(col, v0, true); + bool lambdaTag = checkLam && isSelectLambda(col, v0, true); + bool antilambdaTag = checkALam && isSelectLambda(col, v0, true); + + // ---------------- K0s ---------------- + if (isK0sTopoOnly) { + histos.fill(HIST("hTpcdEdx_pos_before"), 0.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_before"), 0.0f, multiplicity, negP, negSignal); + } + if (isK0sTag) { + histos.fill(HIST("hTpcdEdx_pos_after"), 0.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_after"), 0.0f, multiplicity, negP, negSignal); + histos.fill(HIST("hArmenteros_after"), 0.0f, v0.alpha(), v0.qtarm()); + float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassK0; + histos.fill(HIST("hTopoQA"), 0.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mK0Short()); + } + + // -------------- Lambda --------------- + if (isLamTopoOnly) { + histos.fill(HIST("hTpcdEdx_pos_before"), 1.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_before"), 1.0f, multiplicity, negP, negSignal); + } + if (lambdaTag) { + histos.fill(HIST("hTpcdEdx_pos_after"), 1.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_after"), 1.0f, multiplicity, negP, negSignal); + histos.fill(HIST("hArmenteros_after"), 1.0f, v0.alpha(), v0.qtarm()); + float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda; + histos.fill(HIST("hTopoQA"), 1.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mLambda()); + } + + // ----------- Anti-Lambda ------------- + if (isAlamTopoOnly) { + histos.fill(HIST("hTpcdEdx_pos_before"), 2.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_before"), 2.0f, multiplicity, negP, negSignal); + } + if (antilambdaTag) { + histos.fill(HIST("hTpcdEdx_pos_after"), 2.0f, multiplicity, posP, posSignal); + histos.fill(HIST("hTpcdEdx_neg_after"), 2.0f, multiplicity, negP, negSignal); + histos.fill(HIST("hArmenteros_after"), 2.0f, v0.alpha(), v0.qtarm()); + float ctau = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda; + histos.fill(HIST("hTopoQA"), 2.0f, v0.dcaV0daughters(), std::abs(v0.dcapostopv()), std::abs(v0.dcanegtopv()), std::abs(v0.dcav0topv()), v0.v0cosPA(), v0.v0radius(), ctau, v0.pt(), v0.mAntiLambda()); + } + } + } + template bool isGenPartSelected(CheckGenPart const& particle) { @@ -1306,7 +1417,7 @@ struct LongrangeMaker { } template - bool isSelectK0s(Collision const& col, const V0candidate& v0) + bool isSelectK0s(Collision const& col, const V0candidate& v0, bool applyPidCut = true) { const auto& posTrack = v0.template posTrack_as(); const auto& negTrack = v0.template negTrack_as(); @@ -1316,7 +1427,7 @@ struct LongrangeMaker { if (v0.mK0Short() < cfgv0trksel.minK0sMass || v0.mK0Short() > cfgv0trksel.maxK0sMass) { return false; } - if ((v0.qtarm() / std::abs(v0.alpha())) < cfgv0trksel.minqtArmenterosForK0s) { + if (v0.qtarm() < (cfgv0trksel.minqtArmenterosForK0s * std::abs(v0.alpha()))) { return false; } if (v0.v0radius() > cfgv0trksel.maxK0sRadius || v0.v0radius() < cfgv0trksel.minK0sRadius) { @@ -1331,25 +1442,40 @@ struct LongrangeMaker { if (std::abs(ctauK0s) > cfgv0trksel.maxK0sLifeTime) { return false; } - if (((std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts))) { - return false; + if (applyPidCut) { + if (std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts || + std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) { + return false; + } } - if ((std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiK0s || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiK0s)) { + if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiK0s || + std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiK0s) { return false; } return true; } template - bool isSelectLambda(Collision const& col, const V0candidate& v0) + bool isSelectLambda(Collision const& col, const V0candidate& v0, bool applyPidCut = true) { const auto& posTrack = v0.template posTrack_as(); const auto& negTrack = v0.template negTrack_as(); float ctauLambda = v0.distovertotmom(col.posX(), col.posY(), col.posZ()) * o2::constants::physics::MassLambda; - if ((v0.mLambda() < cfgv0trksel.minLambdaMass || v0.mLambda() > cfgv0trksel.maxLambdaMass) && - (v0.mAntiLambda() < cfgv0trksel.minLambdaMass || v0.mAntiLambda() > cfgv0trksel.maxLambdaMass)) { + + if constexpr (pid == KindOfV0::kLambda) { + if (v0.mLambda() < cfgv0trksel.minLambdaMass || v0.mLambda() > cfgv0trksel.maxLambdaMass) { + return false; + } + } else if constexpr (pid == KindOfV0::kAntiLambda) { + if (v0.mAntiLambda() < cfgv0trksel.minLambdaMass || v0.mAntiLambda() > cfgv0trksel.maxLambdaMass) { + return false; + } + } + + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0) < cfgv0trksel.rejK0sMassWindow) { return false; } + if (v0.v0radius() > cfgv0trksel.maxLambdaRadius || v0.v0radius() < cfgv0trksel.minLambdaRadius) { return false; } @@ -1359,17 +1485,29 @@ struct LongrangeMaker { if (v0.dcaV0daughters() > cfgv0trksel.maxDcaV0DauLambda) { return false; } - if (pid == KindOfV0::kLambda && (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPr || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiLambda)) { - return false; - } - if (pid == KindOfV0::kAntiLambda && (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiLambda || std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPr)) { - return false; - } - if (pid == KindOfV0::kLambda && ((std::abs(posTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts))) { - return false; + if constexpr (pid == KindOfV0::kLambda) { + if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPr || + std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPiLambda) { + return false; + } + } else if constexpr (pid == KindOfV0::kAntiLambda) { + if (std::abs(v0.dcapostopv()) < cfgv0trksel.minV0DcaPiLambda || + std::abs(v0.dcanegtopv()) < cfgv0trksel.minV0DcaPr) { + return false; + } } - if (pid == KindOfV0::kAntiLambda && ((std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts))) { - return false; + if (applyPidCut) { + if constexpr (pid == KindOfV0::kLambda) { + if (std::abs(posTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts || + std::abs(negTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts) { + return false; + } + } else if constexpr (pid == KindOfV0::kAntiLambda) { + if (std::abs(posTrack.tpcNSigmaPi()) > cfgv0trksel.daughPIDCuts || + std::abs(negTrack.tpcNSigmaPr()) > cfgv0trksel.daughPIDCuts) { + return false; + } + } } if (std::abs(ctauLambda) > cfgv0trksel.maxLambdaLifeTime) { return false; @@ -1411,6 +1549,7 @@ struct LongrangeMaker { PROCESS_SWITCH(LongrangeMaker, processUpc, "process UPC collisions", false); PROCESS_SWITCH(LongrangeMaker, processMCGen, "process MC generated collisions", false); PROCESS_SWITCH(LongrangeMaker, processMCRec, "process MC both gen and rec collisions", false); + PROCESS_SWITCH(LongrangeMaker, processV0QA, "process V0 QA histograms", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From f49cf35ec1cab42b09edf6cbc3f66ffe13c4410b Mon Sep 17 00:00:00 2001 From: Soumyadip Ghosh Date: Wed, 26 Aug 2026 00:26:53 +0530 Subject: [PATCH 4/4] Fix variable initialization and update multiplicity calculation --- .../TableProducer/longrangeMaker.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx index d7deb6bcc56..e6bbb5e8d7f 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx @@ -248,7 +248,7 @@ struct LongrangeMaker { Service pdg; o2::ccdb::CcdbApi ccdbApi; o2::ft0::Geometry ft0Det; - std::vector* offsetFT0; + std::vector* offsetFT0{nullptr}; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; TrackSelection myTrackFilter; @@ -847,9 +847,9 @@ struct LongrangeMaker { } } auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); - float multiplicity = countNTracks(recTracksPart, RecCol.posZ()); + float recMultiplicity = countNTracks(recTracksPart, RecCol.posZ()); float centrality = selColCent(RecCol); - lrcollision(bc.runNumber(), RecCol.posZ(), multiplicity, centrality, bc.timestamp()); + lrcollision(bc.runNumber(), RecCol.posZ(), recMultiplicity, centrality, bc.timestamp()); lrcollisionMcLabel(RecCol.mcCollisionId()); // track loop @@ -1525,7 +1525,7 @@ struct LongrangeMaker { if (hTrkEff == nullptr) { LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgtrksel.cfgEffccdbPath.value.c_str()); } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff); + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), static_cast(hTrkEff)); } fLoadTrkEffCorr = true; }