From 12b23792119f5ed8be77a7547e8beb8e96bd3fbb Mon Sep 17 00:00:00 2001 From: skundu692 Date: Tue, 11 Nov 2025 13:13:52 +0100 Subject: [PATCH 1/5] fix bug of histogram fill for pid --- PWGLF/Tasks/Resonances/doublephimeson.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Resonances/doublephimeson.cxx b/PWGLF/Tasks/Resonances/doublephimeson.cxx index 27409836425..d5228a98b77 100644 --- a/PWGLF/Tasks/Resonances/doublephimeson.cxx +++ b/PWGLF/Tasks/Resonances/doublephimeson.cxx @@ -770,7 +770,6 @@ struct doublephimeson { histos.fill(HIST("hnsigmaTPCTOFKaon"), t.phid1TPC(), t.phid1TOF(), kpluspt); histos.fill(HIST("hnsigmaTPCKaonPlus"), t.phid1TPC(), kpluspt); histos.fill(HIST("hnsigmaTPCKaonMinus"), t.phid2TPC(), kminuspt); - ++phimult; } if (phimult < 2) @@ -824,6 +823,11 @@ struct doublephimeson { const double kplus1pt = std::hypot(t1.phid1Px(), t1.phid1Py()); const double kminus1pt = std::hypot(t1.phid2Px(), t1.phid2Py()); +<<<<<<< HEAD +======= + + +>>>>>>> cc7c4eeeb (fix bug of histogram fill for pid) if (kplus1pt > maxKaonPt || kminus1pt > maxKaonPt) continue; if (!selectionPID(t1.phid1TPC(), t1.phid1TOF(), t1.phid1TOFHit(), strategyPID1, kplus1pt)) From 8b6427755216f82719e0fab8d019b90732c2f59b Mon Sep 17 00:00:00 2001 From: skundu692 Date: Mon, 10 Nov 2025 09:13:33 +0100 Subject: [PATCH 2/5] Add PID histogram --- PWGLF/Tasks/Resonances/doublephimeson.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGLF/Tasks/Resonances/doublephimeson.cxx b/PWGLF/Tasks/Resonances/doublephimeson.cxx index d5228a98b77..d5b716f82ff 100644 --- a/PWGLF/Tasks/Resonances/doublephimeson.cxx +++ b/PWGLF/Tasks/Resonances/doublephimeson.cxx @@ -770,6 +770,7 @@ struct doublephimeson { histos.fill(HIST("hnsigmaTPCTOFKaon"), t.phid1TPC(), t.phid1TOF(), kpluspt); histos.fill(HIST("hnsigmaTPCKaonPlus"), t.phid1TPC(), kpluspt); histos.fill(HIST("hnsigmaTPCKaonMinus"), t.phid2TPC(), kminuspt); + ++phimult; } if (phimult < 2) From 948e97e00ce48aaa69f1896f481fab8f059ecfe7 Mon Sep 17 00:00:00 2001 From: skundu692 Date: Mon, 10 Nov 2025 19:18:55 +0100 Subject: [PATCH 3/5] Improve both leg bixing --- PWGLF/Tasks/Resonances/doublephimeson.cxx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/PWGLF/Tasks/Resonances/doublephimeson.cxx b/PWGLF/Tasks/Resonances/doublephimeson.cxx index d5b716f82ff..3ebcc507ada 100644 --- a/PWGLF/Tasks/Resonances/doublephimeson.cxx +++ b/PWGLF/Tasks/Resonances/doublephimeson.cxx @@ -824,11 +824,7 @@ struct doublephimeson { const double kplus1pt = std::hypot(t1.phid1Px(), t1.phid1Py()); const double kminus1pt = std::hypot(t1.phid2Px(), t1.phid2Py()); -<<<<<<< HEAD -======= - ->>>>>>> cc7c4eeeb (fix bug of histogram fill for pid) if (kplus1pt > maxKaonPt || kminus1pt > maxKaonPt) continue; if (!selectionPID(t1.phid1TPC(), t1.phid1TOF(), t1.phid1TOFHit(), strategyPID1, kplus1pt)) From 30bc46e2825d6064ead2b147041926c041f9bab7 Mon Sep 17 00:00:00 2001 From: skundu692 Date: Tue, 11 Nov 2025 20:15:06 +0100 Subject: [PATCH 4/5] Fix clang error --- PWGLF/Tasks/Resonances/doublephimeson.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/PWGLF/Tasks/Resonances/doublephimeson.cxx b/PWGLF/Tasks/Resonances/doublephimeson.cxx index 3ebcc507ada..27409836425 100644 --- a/PWGLF/Tasks/Resonances/doublephimeson.cxx +++ b/PWGLF/Tasks/Resonances/doublephimeson.cxx @@ -824,7 +824,6 @@ struct doublephimeson { const double kplus1pt = std::hypot(t1.phid1Px(), t1.phid1Py()); const double kminus1pt = std::hypot(t1.phid2Px(), t1.phid2Py()); - if (kplus1pt > maxKaonPt || kminus1pt > maxKaonPt) continue; if (!selectionPID(t1.phid1TPC(), t1.phid1TOF(), t1.phid1TOFHit(), strategyPID1, kplus1pt)) From 86f3f03e2794bec3c795e8d9a105ea7dc349e07e Mon Sep 17 00:00:00 2001 From: skundu692 Date: Wed, 12 Nov 2025 18:55:48 +0100 Subject: [PATCH 5/5] Fix event mixing bug --- .../Strangeness/lambdaspincorrderived.cxx | 181 +++++++++--------- 1 file changed, 94 insertions(+), 87 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx index 00916c9c709..19f5d11e333 100644 --- a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx @@ -531,7 +531,6 @@ struct lambdaspincorrderived { const ROOT::Math::PtEtaPhiMVector& daughpart1, const ROOT::Math::PtEtaPhiMVector& daughpart2, int datatype, float mixpairweight, int mixedLeg) { - auto lambda1Mass = 0.0; auto lambda2Mass = 0.0; if (!usePDGM) { @@ -622,35 +621,29 @@ struct lambdaspincorrderived { double epsWeightMixedLeg = 1.0; if (useweight && datatype == 1) { // only for ME if (mixedLeg == 1) { - // Only leg 1 is from the mixing pool double w1 = 1.0; - if (tag1 == 0) { // Λ - if (hweight1) { - w1 = hweight1->GetBinContent(hweight1->FindBin(dphi1, deta1, pt1)); - } - } else { // Λbar - if (hweight4) { - w1 = hweight4->GetBinContent(hweight4->FindBin(dphi1, deta1, pt1)); - } - } - if (w1 > 0.0 && std::isfinite(w1)) { - epsWeightMixedLeg = w1; + if (tag1 == 0 && tag2 == 0) { + w1 = hweight1->GetBinContent(hweight1->FindBin(dphi1, deta1, pt1)); + } else if (tag1 == 0 && tag2 == 1) { + w1 = hweight2->GetBinContent(hweight2->FindBin(dphi1, deta1, pt1)); + } else if (tag1 == 1 && tag2 == 0) { + w1 = hweight3->GetBinContent(hweight3->FindBin(dphi1, deta1, pt1)); + } else if (tag1 == 1 && tag2 == 1) { + w1 = hweight4->GetBinContent(hweight4->FindBin(dphi1, deta1, pt1)); } + epsWeightMixedLeg = w1; } else if (mixedLeg == 2) { - // Only leg 2 is from the mixing pool double w2 = 1.0; - if (tag2 == 0) { // Λ - if (hweight12) { - w2 = hweight12->GetBinContent(hweight12->FindBin(dphi2, deta2, pt2)); - } - } else { // Λbar - if (hweight42) { - w2 = hweight42->GetBinContent(hweight42->FindBin(dphi2, deta2, pt2)); - } - } - if (w2 > 0.0 && std::isfinite(w2)) { - epsWeightMixedLeg = w2; + if (tag1 == 0 && tag2 == 0) { + w2 = hweight12->GetBinContent(hweight12->FindBin(dphi2, deta1, pt2)); + } else if (tag1 == 0 && tag2 == 1) { + w2 = hweight22->GetBinContent(hweight22->FindBin(dphi2, deta1, pt2)); + } else if (tag1 == 1 && tag2 == 0) { + w2 = hweight32->GetBinContent(hweight32->FindBin(dphi2, deta1, pt2)); + } else if (tag1 == 1 && tag2 == 1) { + w2 = hweight42->GetBinContent(hweight42->FindBin(dphi2, deta2, pt2)); } + epsWeightMixedLeg = w2; } } @@ -697,19 +690,19 @@ struct lambdaspincorrderived { } else if (datatype == 1) { double weight = mixpairweight; if (useweight) { - if (usebothweight) { - weight = mixpairweight / (epsWeightMixedLeg); - } else { - weight = mixpairweight / (epsWeightMixedLeg); - } + weight = mixpairweight / (epsWeightMixedLeg); } if (weight <= 0.0) { weight = 1.0; } + // LOGF(info, Form("Getting alignment offsets from the CCDB...%2.2f",epsWeightMixedLeg)); histos.fill(HIST("hPtYMix"), particle1.Pt(), particle1.Rapidity(), weight); if (tag1 == 0 && tag2 == 0) { - histos.fill(HIST("ME_LL"), dphi1, deta1, pt1, mixpairweight); - histos.fill(HIST("ME_LL2"), dphi2, deta2, pt2, mixpairweight); + if (mixedLeg == 1) { + histos.fill(HIST("ME_LL"), dphi1, deta1, pt1, weight); + } else if (mixedLeg == 2) { + histos.fill(HIST("ME_LL2"), dphi2, deta2, pt2, weight); + } histos.fill(HIST("hSparseLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); if (useAdditionalHisto) { histos.fill(HIST("hSparseRapLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); @@ -717,8 +710,11 @@ struct lambdaspincorrderived { histos.fill(HIST("hSparsePairMassLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 0 && tag2 == 1) { - histos.fill(HIST("ME_LAL"), dphi1, deta1, pt1, mixpairweight); - histos.fill(HIST("ME_LAL2"), dphi2, deta2, pt2, mixpairweight); + if (mixedLeg == 1) { + histos.fill(HIST("ME_LAL"), dphi1, deta1, pt1, weight); + } else if (mixedLeg == 2) { + histos.fill(HIST("ME_LAL2"), dphi2, deta2, pt2, weight); + } histos.fill(HIST("hSparseLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); if (useAdditionalHisto) { histos.fill(HIST("hSparseRapLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); @@ -726,8 +722,11 @@ struct lambdaspincorrderived { histos.fill(HIST("hSparsePairMassLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 0) { - histos.fill(HIST("ME_ALL"), dphi1, deta1, pt1, mixpairweight); - histos.fill(HIST("ME_ALL2"), dphi2, deta2, pt2, mixpairweight); + if (mixedLeg == 1) { + histos.fill(HIST("ME_ALL"), dphi1, deta1, pt1, weight); + } else if (mixedLeg == 2) { + histos.fill(HIST("ME_ALL2"), dphi2, deta2, pt2, weight); + } histos.fill(HIST("hSparseAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); if (useAdditionalHisto) { histos.fill(HIST("hSparseRapAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); @@ -735,8 +734,11 @@ struct lambdaspincorrderived { histos.fill(HIST("hSparsePairMassAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 1) { - histos.fill(HIST("ME_ALAL"), dphi1, deta1, pt1, mixpairweight); - histos.fill(HIST("ME_ALAL2"), dphi2, deta2, pt2, mixpairweight); + if (mixedLeg == 1) { + histos.fill(HIST("ME_ALAL"), dphi1, deta1, pt1, weight); + } else if (mixedLeg == 2) { + histos.fill(HIST("ME_ALAL2"), dphi2, deta2, pt2, weight); + } histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); if (useAdditionalHisto) { histos.fill(HIST("hSparseRapAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); @@ -1064,17 +1066,17 @@ struct lambdaspincorrderived { } PROCESS_SWITCH(lambdaspincorrderived, processMEV3, "Process data ME (first-leg, pair-3D maps)", false); + // ---------------------- minimal helpers you already use ---------------------- static constexpr int N_STATUS = 2; // v0Status ∈ {0,1} struct MixBinner { - // constructed from the task's configurables; φ is assumed already constrained into [0, 2π) float ptMin, ptMax, ptStep; float etaMin, etaMax, etaStep; float phiMin, phiMax, phiStep; - // Mass binning: [1.09, 1.14) with 50 bins (1e-3 GeV/c^2) + // if you want 1 mass bin (effectively “on/off”), keep nM_=1 static constexpr float mMin = 1.09f; - static constexpr float mMax = 1.14f; // exclusive + static constexpr float mMax = 1.14f; static constexpr int nM_ = 1; static constexpr float mStep = (mMax - mMin) / nM_; @@ -1088,7 +1090,6 @@ struct lambdaspincorrderived { ptStep = (ptStep > 0.f ? ptStep : 0.1f); etaStep = (etaStep > 0.f ? etaStep : 0.1f); phiStep = (phiStep > 0.f ? phiStep : 0.1f); - nPt_ = std::max(1, static_cast(std::floor((ptMax - ptMin) / ptStep + 0.5f))); nEta_ = std::max(1, static_cast(std::floor((etaMax - etaMin) / etaStep + 0.5f))); nPhi_ = std::max(1, static_cast(std::ceil((phiMax - phiMin) / phiStep))); @@ -1108,19 +1109,18 @@ struct lambdaspincorrderived { if (b < 0) return -1; if (b >= nBins) - b = nBins - 1; // clamp exact-top edge + b = nBins - 1; return b; } - inline int ptBin(float pt) const { return binFromValue(pt, ptMin, ptStep, nPt_); } - inline int etaBin(float eta) const { return binFromValue(eta, etaMin, etaStep, nEta_); } - inline int phiBin(float phi) const { return binFromValue(phi, phiMin, phiStep, nPhi_); } // φ already constrained upstream + inline int etaBin(float e) const { return binFromValue(e, etaMin, etaStep, nEta_); } + inline int phiBin(float ph) const { return binFromValue(ph, phiMin, phiStep, nPhi_); } inline int massBin(float m) const { return binFromValue(m, mMin, mStep, nM_); } }; struct BufferCand { - int64_t collisionIdx; // from col.index() - int64_t rowIndex; // global row id in V0s + int64_t collisionIdx; + int64_t rowIndex; uint8_t v0Status; uint16_t ptBin, etaBin, phiBin, mBin; }; @@ -1130,16 +1130,16 @@ struct lambdaspincorrderived { int64_t rowIndex; }; - // 6D key: (colBin, status, pt, eta, phi, mass) static inline size_t linearKey(int colBin, int statBin, int ptBin, int etaBin, int phiBin, int mBin, int nStatus, int nPt, int nEta, int nPhi, int nM) { return ((((((static_cast(colBin) * nStatus + statBin) * nPt + ptBin) * nEta + etaBin) * nPhi + phiBin) * nM + mBin)); } + + // ================================ processMEV4 ================================ void processMEV4(EventCandidates const& collisions, AllTrackCandidates const& V0s) { - // Build binner from your existing configurables MixBinner mb{ ptMin.value, ptMax.value, ptMix.value, // pT range & step v0eta.value, etaMix.value, // |eta| max & step @@ -1156,9 +1156,7 @@ struct lambdaspincorrderived { const size_t nKeys = static_cast(nCol) * nStat * nPt * nEta * nPhi * nM; std::vector> buffer(nKeys); - // ========================= - // PASS 1: fill 6D buffer - // ========================= + // ---------------- PASS 1: fill the 6D buffer ---------------- for (auto const& col : collisions) { const int colBin = colBinning.getBin(std::make_tuple(col.posz(), col.cent())); auto slice = V0s.sliceBy(tracksPerCollisionV0, col.index()); @@ -1178,9 +1176,7 @@ struct lambdaspincorrderived { if (ptB < 0 || etaB < 0 || phiB < 0 || mB < 0) continue; - const size_t key = linearKey(colBin, status, ptB, etaB, phiB, mB, - nStat, nPt, nEta, nPhi, nM); - + const size_t key = linearKey(colBin, status, ptB, etaB, phiB, mB, nStat, nPt, nEta, nPhi, nM); buffer[key].push_back(BufferCand{ .collisionIdx = static_cast(col.index()), .rowIndex = static_cast(t.globalIndex()), @@ -1192,7 +1188,7 @@ struct lambdaspincorrderived { } } - // Helper: get matches for a given candidate (for mixing one leg) + // small helper (kept local) to fetch matches for a given candidate from the same 6D bin auto makeMatchesFor = [&](auto const& cand, int colBinLocal, int64_t curColIdx) -> std::vector { @@ -1209,8 +1205,7 @@ struct lambdaspincorrderived { if (ptB < 0 || etaB < 0 || phiB < 0 || mB < 0) return matches; - const size_t key = linearKey(colBinLocal, status, ptB, etaB, phiB, mB, - nStat, nPt, nEta, nPhi, nM); + const size_t key = linearKey(colBinLocal, status, ptB, etaB, phiB, mB, nStat, nPt, nEta, nPhi, nM); auto const& binVec = buffer[key]; if (binVec.empty()) return matches; @@ -1218,24 +1213,13 @@ struct lambdaspincorrderived { matches.reserve(binVec.size()); for (const auto& bc : binVec) { if (bc.collisionIdx == curColIdx) - continue; // ensure different event + continue; // different event matches.push_back(MatchRef{bc.collisionIdx, bc.rowIndex}); } - - // Optionally cap number of matches by nEvtMixing - const int cap = nEvtMixing.value; - const int n = static_cast(matches.size()); - if (cap > 0 && n > cap) { - std::shuffle(matches.begin(), matches.end(), rng); - matches.resize(cap); - } - return matches; }; - // ========================= - // PASS 2: mixing over SE pairs (mix both legs) - // ========================= + // ---------------- PASS 2: loop over SE pairs and mix both legs ---------------- for (auto const& collision1 : collisions) { const int colBin = colBinning.getBin(std::make_tuple(collision1.posz(), collision1.cent())); auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); @@ -1259,20 +1243,38 @@ struct lambdaspincorrderived { if (t1.pionIndex() == t2.protonIndex()) continue; - // matches for replacing leg 1 and leg 2 - auto matches1 = makeMatchesFor(t1, colBin, curColId); // t1 -> tX - auto matches2 = makeMatchesFor(t2, colBin, curColId); // t2 -> tY + // gather matches for both legs from the same 6D bin + auto matches1 = makeMatchesFor(t1, colBin, curColId); // candidates to replace leg-1 + auto matches2 = makeMatchesFor(t2, colBin, curColId); // candidates to replace leg-2 - const int n1 = static_cast(matches1.size()); - const int n2 = static_cast(matches2.size()); - if (n1 == 0 && n2 == 0) + const int n1Eff = static_cast(matches1.size()); + const int n2Eff = static_cast(matches2.size()); + if (n1Eff == 0 && n2Eff == 0) continue; - // Split "unit" weight between the two modes - const float w1 = (n1 > 0 ? 0.5f / static_cast(n1) : 0.f); - const float w2 = (n2 > 0 ? 0.5f / static_cast(n2) : 0.f); + // per-leg depth (configurable) + int depth = nEvtMixing.value; + if (depth <= 0) + depth = 1; + + const int n1Take = std::min(depth, n1Eff); + const int n2Take = std::min(depth, n2Eff); - // --- Type A: replace leg 1 → (tX, t2) --- + // split unit weight between legs if both have mixes; else single leg gets full + const float w1 = (n1Take > 0 ? ((n2Take > 0 ? 0.5f : 1.0f) / static_cast(n1Take)) : 0.0f); + const float w2 = (n2Take > 0 ? ((n1Take > 0 ? 0.5f : 1.0f) / static_cast(n2Take)) : 0.0f); + + // randomize & truncate per-leg matches to requested depth + if (n1Take > 0) { + std::shuffle(matches1.begin(), matches1.end(), rng); + matches1.resize(n1Take); + } + if (n2Take > 0) { + std::shuffle(matches2.begin(), matches2.end(), rng); + matches2.resize(n2Take); + } + + // --- Type A: replace leg 1 (t1 -> tX), keep t2 for (const auto& m : matches1) { auto tX = V0s.iteratorAt(m.rowIndex); if (!selectionV0(tX)) @@ -1289,10 +1291,13 @@ struct lambdaspincorrderived { const float dPhi = std::fabs(RecoDecay::constrainAngle(lambda1.Phi() - lambda2.Phi(), 0.0F, harmonicDphi)); histos.fill(HIST("deltaPhiMix"), dPhi, w1); - fillHistograms2(tX.v0Status(), t2.v0Status(), lambda1, lambda2, proton1, proton2, 1, w1, 1); + // datatype=1 (ME), mixedLeg=1 + fillHistograms2(tX.v0Status(), t2.v0Status(), + lambda1, lambda2, proton1, proton2, + /*datatype=*/1, /*weight=*/w1, /*mixedLeg=*/1); } - // --- Type B: replace leg 2 → (t1, tY) --- + // --- Type B: replace leg 2 (t2 -> tY), keep t1 for (const auto& m : matches2) { auto tY = V0s.iteratorAt(m.rowIndex); if (!selectionV0(tY)) @@ -1309,13 +1314,15 @@ struct lambdaspincorrderived { const float dPhi = std::fabs(RecoDecay::constrainAngle(lambda1.Phi() - lambda2.Phi(), 0.0F, harmonicDphi)); histos.fill(HIST("deltaPhiMix"), dPhi, w2); - fillHistograms2(t1.v0Status(), tY.v0Status(), lambda1, lambda2, proton1, proton2, 1, w2, 2); + // datatype=1 (ME), mixedLeg=2 + fillHistograms2(t1.v0Status(), tY.v0Status(), + lambda1, lambda2, proton1, proton2, + /*datatype=*/1, /*weight=*/w2, /*mixedLeg=*/2); } } } } - - PROCESS_SWITCH(lambdaspincorrderived, processMEV4, "Process data ME (5d buffer)", false); + PROCESS_SWITCH(lambdaspincorrderived, processMEV4, "Process data ME (6D buffer, both legs mixed, depth-capped)", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) {