From b92115bc9d29a4746ce5c3fce63bad69993d4fb6 Mon Sep 17 00:00:00 2001 From: skundu692 Date: Fri, 1 May 2026 15:59:11 +0200 Subject: [PATCH 1/3] Fix Lambda spin correlation selection --- .../Strangeness/lambdaspincorrderived.cxx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx index 742c8b639ac..3aa3841c6fe 100644 --- a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx @@ -856,7 +856,8 @@ struct lambdaspincorrderived { continue; } - auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); + // auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); + auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.globalIndex()); // if pool empty, push and continue if (eventPools[bin].empty()) { @@ -1007,7 +1008,8 @@ struct lambdaspincorrderived { } // push current event into pool - auto sliced = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); + // auto sliced = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); + auto sliced = V0s.sliceBy(tracksPerCollisionV0, collision1.globalIndex()); eventPools[bin].emplace_back(collision1.index(), std::move(sliced)); if ((int)eventPools[bin].size() > nEvtMixing) { eventPools[bin].pop_front(); @@ -1439,7 +1441,8 @@ struct lambdaspincorrderived { continue; } - auto slice = V0s.sliceBy(tracksPerCollisionV0, col.index()); + // auto slice = V0s.sliceBy(tracksPerCollisionV0, col.index()); + auto slice = V0s.sliceBy(tracksPerCollisionV0, col.globalIndex()); for (auto const& t : slice) { if (!selectionV0(t)) { @@ -1642,7 +1645,8 @@ struct lambdaspincorrderived { } const int64_t curColIdx = static_cast(col1.index()); - auto poolA = V0s.sliceBy(tracksPerCollisionV0, col1.index()); + // auto poolA = V0s.sliceBy(tracksPerCollisionV0, col1.index()); + auto poolA = V0s.sliceBy(tracksPerCollisionV0, col1.globalIndex()); for (auto const& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(poolA, poolA))) { if (!selectionV0(t1) || !selectionV0(t2)) { @@ -1850,7 +1854,8 @@ struct lambdaspincorrderived { continue; } - auto slice = V0sMC.sliceBy(tracksPerCollisionV0mc, col.index()); + // auto slice = V0sMC.sliceBy(tracksPerCollisionV0mc, col.index()); + auto slice = V0sMC.sliceBy(tracksPerCollisionV0mc, col.globalIndex()); for (auto const& t : slice) { if (!selectionV0MC(t)) { @@ -2059,7 +2064,8 @@ struct lambdaspincorrderived { } const int64_t curColIdx = static_cast(col1.index()); - auto poolA = V0sMC.sliceBy(tracksPerCollisionV0mc, col1.index()); + // auto poolA = V0sMC.sliceBy(tracksPerCollisionV0mc, col1.index()); + auto poolA = V0sMC.sliceBy(tracksPerCollisionV0mc, col1.globalIndex()); for (auto const& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(poolA, poolA))) { if (!selectionV0MC(t1) || !selectionV0MC(t2)) { From 45cc5dc2451d1b3536f90c8cba33318b5a9ba7f5 Mon Sep 17 00:00:00 2001 From: skundu692 Date: Fri, 1 May 2026 16:07:49 +0200 Subject: [PATCH 2/3] Fix Lambda spin correlation selection --- .../Strangeness/lambdaspincorrderived.cxx | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx index 3aa3841c6fe..742c8b639ac 100644 --- a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx @@ -856,8 +856,7 @@ struct lambdaspincorrderived { continue; } - // auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); - auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.globalIndex()); + auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); // if pool empty, push and continue if (eventPools[bin].empty()) { @@ -1008,8 +1007,7 @@ struct lambdaspincorrderived { } // push current event into pool - // auto sliced = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); - auto sliced = V0s.sliceBy(tracksPerCollisionV0, collision1.globalIndex()); + auto sliced = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); eventPools[bin].emplace_back(collision1.index(), std::move(sliced)); if ((int)eventPools[bin].size() > nEvtMixing) { eventPools[bin].pop_front(); @@ -1441,8 +1439,7 @@ struct lambdaspincorrderived { continue; } - // auto slice = V0s.sliceBy(tracksPerCollisionV0, col.index()); - auto slice = V0s.sliceBy(tracksPerCollisionV0, col.globalIndex()); + auto slice = V0s.sliceBy(tracksPerCollisionV0, col.index()); for (auto const& t : slice) { if (!selectionV0(t)) { @@ -1645,8 +1642,7 @@ struct lambdaspincorrderived { } const int64_t curColIdx = static_cast(col1.index()); - // auto poolA = V0s.sliceBy(tracksPerCollisionV0, col1.index()); - auto poolA = V0s.sliceBy(tracksPerCollisionV0, col1.globalIndex()); + auto poolA = V0s.sliceBy(tracksPerCollisionV0, col1.index()); for (auto const& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(poolA, poolA))) { if (!selectionV0(t1) || !selectionV0(t2)) { @@ -1854,8 +1850,7 @@ struct lambdaspincorrderived { continue; } - // auto slice = V0sMC.sliceBy(tracksPerCollisionV0mc, col.index()); - auto slice = V0sMC.sliceBy(tracksPerCollisionV0mc, col.globalIndex()); + auto slice = V0sMC.sliceBy(tracksPerCollisionV0mc, col.index()); for (auto const& t : slice) { if (!selectionV0MC(t)) { @@ -2064,8 +2059,7 @@ struct lambdaspincorrderived { } const int64_t curColIdx = static_cast(col1.index()); - // auto poolA = V0sMC.sliceBy(tracksPerCollisionV0mc, col1.index()); - auto poolA = V0sMC.sliceBy(tracksPerCollisionV0mc, col1.globalIndex()); + auto poolA = V0sMC.sliceBy(tracksPerCollisionV0mc, col1.index()); for (auto const& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(poolA, poolA))) { if (!selectionV0MC(t1) || !selectionV0MC(t2)) { From da2b8b8c98811c138b87dba0d0281f6851b23dba Mon Sep 17 00:00:00 2001 From: skundu692 Date: Sun, 3 May 2026 11:29:10 +0200 Subject: [PATCH 3/3] Add process function to produce MC table for spincorr analysis --- .../Strangeness/lambdaspincorrelation.cxx | 203 +++++++++++++++++- 1 file changed, 200 insertions(+), 3 deletions(-) diff --git a/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx b/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx index bb35e81c1f9..f20460f7171 100644 --- a/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx +++ b/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx @@ -75,6 +75,7 @@ struct lambdaspincorrelation { // events Configurable cfgEventTypepp{"cfgEventTypepp", false, "Type of collisions"}; + Configurable cfgCentTypepp{"cfgCentTypepp", true, "Type of centrality"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutCentralityMax{"cfgCutCentralityMax", 80.0f, "Accepted maximum Centrality"}; Configurable cfgCutCentralityMin{"cfgCutCentralityMin", 0.0f, "Accepted minimum Centrality"}; @@ -242,7 +243,8 @@ struct lambdaspincorrelation { using EventCandidates = soa::Filtered>; using AllTrackCandidates = soa::Join; using ResoV0s = aod::V0Datas; - + using EventCandidatesMC = soa::Join; + using AllTrackCandidatesMC = soa::Join; void processData(EventCandidates::iterator const& collision, AllTrackCandidates const&, ResoV0s const& V0s) { std::vector lambdaMother, protonDaughter, pionDaughter; @@ -258,7 +260,7 @@ struct lambdaspincorrelation { int numbV0 = 0; // LOGF(info, "event collisions: (%d)", collision.index()); auto centrality = collision.centFT0C(); - if (cfgEventTypepp) + if (cfgCentTypepp) centrality = collision.centFT0M(); auto vz = collision.posZ(); int occupancy = collision.trackOccupancyInTimeRange(); @@ -370,7 +372,7 @@ struct lambdaspincorrelation { int numbV0 = 0; // LOGF(info, "event collisions: (%d)", collision.index()); auto centrality = collision.centFT0C(); - if (cfgEventTypepp) + if (cfgCentTypepp) centrality = collision.centFT0M(); auto vz = collision.posZ(); int occupancy = collision.trackOccupancyInTimeRange(); @@ -465,6 +467,201 @@ struct lambdaspincorrelation { } } PROCESS_SWITCH(lambdaspincorrelation, processMc, "Process montecarlo", true); + + void processMc2(aod::McCollision const&, + soa::SmallGroups const& collisions, + AllTrackCandidatesMC const&, + ResoV0s const& V0s, + aod::McParticles const&) + { + if (collisions.size() == 1) { + + for (const auto& collision : collisions) { + + std::vector lambdaMother, protonDaughter, pionDaughter; + std::vector v0Status = {}; + std::vector doubleStatus = {}; + std::vector v0Cospa = {}; + std::vector v0Radius = {}; + std::vector dcaPositive = {}; + std::vector dcaNegative = {}; + std::vector positiveIndex = {}; + std::vector negativeIndex = {}; + std::vector dcaBetweenDaughter = {}; + int numbV0 = 0; + + auto centrality = collision.centFT0C(); + if (cfgCentTypepp) { + centrality = collision.centFT0M(); + } + + auto vz = collision.posZ(); + int occupancy = collision.trackOccupancyInTimeRange(); + + histos.fill(HIST("hEvtSelInfo"), 0.5); + + if (std::abs(collision.posZ()) < cfgCutVertex && + (!rctCut.requireRCTFlagChecker || rctChecker(collision)) && + + (!cfgEventTypepp || (collision.selection_bit(aod::evsel::kNoSameBunchPileup) && + collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) && + collision.selection_bit(aod::evsel::kNoTimeFrameBorder) && + collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) && + + (!useNoCollInTimeRangeStandard || collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) && + collision.sel8() && + (!useGoodITSLayersAll || collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) && + occupancy < cfgCutOccupancy) { + + histos.fill(HIST("hEvtSelInfo"), 1.5); + + for (const auto& v0 : V0s) { + + auto [lambdaTag, aLambdaTag, isValid] = getLambdaTags(v0, collision); + + if (isValid) { + + auto postrack1 = v0.template posTrack_as(); + auto negtrack1 = v0.template negTrack_as(); + + // Reject candidates whose reconstructed daughters are not MC-labelled. + if (!postrack1.has_mcParticle() || !negtrack1.has_mcParticle()) { + continue; + } + + auto mcPos = postrack1.mcParticle(); + auto mcNeg = negtrack1.mcParticle(); + + // Reject gap/background-event daughters. + if (mcPos.fromBackgroundEvent() || mcNeg.fromBackgroundEvent()) { + continue; + } + + if (lambdaTag) { + histos.fill(HIST("hV0Info"), 0.5); + } + if (aLambdaTag) { + histos.fill(HIST("hV0Info"), 1.5); + } + + if (lambdaTag && aLambdaTag) { + doubleStatus.push_back(true); + if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda) < + std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda)) { + lambdaTag = true; + aLambdaTag = false; + } else { + lambdaTag = false; + aLambdaTag = true; + } + } else { + doubleStatus.push_back(false); + } + + if (lambdaTag) { + histos.fill(HIST("hV0Info"), 2.5); + } + if (aLambdaTag) { + histos.fill(HIST("hV0Info"), 3.5); + } + + positiveIndex.push_back(postrack1.globalIndex()); + negativeIndex.push_back(negtrack1.globalIndex()); + + v0Cospa.push_back(v0.v0cosPA()); + v0Radius.push_back(v0.v0radius()); + dcaPositive.push_back(std::abs(v0.dcapostopv())); + dcaNegative.push_back(std::abs(v0.dcanegtopv())); + dcaBetweenDaughter.push_back(std::abs(v0.dcaV0daughters())); + + if (lambdaTag) { + v0Status.push_back(0); + + proton = ROOT::Math::PxPyPzMVector( + v0.pxpos(), + v0.pypos(), + v0.pzpos(), + o2::constants::physics::MassProton); + + antiPion = ROOT::Math::PxPyPzMVector( + v0.pxneg(), + v0.pyneg(), + v0.pzneg(), + o2::constants::physics::MassPionCharged); + + lambda = proton + antiPion; + + lambdaMother.push_back(lambda); + protonDaughter.push_back(proton); + pionDaughter.push_back(antiPion); + + histos.fill(HIST("hLambdaMass"), lambda.M()); + + } else if (aLambdaTag) { + v0Status.push_back(1); + + antiProton = ROOT::Math::PxPyPzMVector( + v0.pxneg(), + v0.pyneg(), + v0.pzneg(), + o2::constants::physics::MassProton); + + pion = ROOT::Math::PxPyPzMVector( + v0.pxpos(), + v0.pypos(), + v0.pzpos(), + o2::constants::physics::MassPionCharged); + + antiLambda = antiProton + pion; + + lambdaMother.push_back(antiLambda); + protonDaughter.push_back(antiProton); + pionDaughter.push_back(pion); + + histos.fill(HIST("hLambdaMass"), antiLambda.M()); + } + + numbV0 = numbV0 + 1; + } + } + + if (numbV0 > 1 && v0Cospa.size() > 1) { + histos.fill(HIST("hEvtSelInfo"), 2.5); + + lambdaEventmc(centrality, vz); + auto indexEvent = lambdaEventmc.lastIndex(); + + for (auto if1 = lambdaMother.begin(); if1 != lambdaMother.end(); ++if1) { + auto i5 = std::distance(lambdaMother.begin(), if1); + + lambdaDummy = lambdaMother.at(i5); + protonDummy = protonDaughter.at(i5); + pionDummy = pionDaughter.at(i5); + + lambdaPairmc(indexEvent, + v0Status.at(i5), + doubleStatus.at(i5), + v0Cospa.at(i5), + v0Radius.at(i5), + dcaPositive.at(i5), + dcaNegative.at(i5), + dcaBetweenDaughter.at(i5), + lambdaDummy.Pt(), + lambdaDummy.Eta(), + lambdaDummy.Phi(), + lambdaDummy.M(), + protonDummy.Pt(), + protonDummy.Eta(), + protonDummy.Phi(), + positiveIndex.at(i5), + negativeIndex.at(i5)); + } + } + } + } + } + } + PROCESS_SWITCH(lambdaspincorrelation, processMc2, "Process montecarlo2", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) {