From 017f5b14cb30ac68275050cf0fd3c68c3880d689 Mon Sep 17 00:00:00 2001 From: suyoupeng <109774812+15071832337@users.noreply.github.com> Date: Sat, 26 Sep 2026 23:09:54 +0800 Subject: [PATCH] Add files via upload --- .../Strangeness/lambdaspincorrderived.cxx | 953 ++++++------------ 1 file changed, 284 insertions(+), 669 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx index 2f75bd83291..408b6be942e 100644 --- a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -60,6 +59,61 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; +static inline double getKStar( + const ROOT::Math::PtEtaPhiMVector& p1, + const ROOT::Math::PtEtaPhiMVector& p2) +{ + const auto pair = p1 + p2; + + ROOT::Math::Boost boostToPairCM(pair.BoostToCM()); + const auto p1CM = boostToPairCM(p1); + + return std::sqrt( + p1CM.Px() * p1CM.Px() + + p1CM.Py() * p1CM.Py() + + p1CM.Pz() * p1CM.Pz()); +} + +struct PionKin { + double pt, eta, phi; +}; + +static inline PionKin getPionKinematics( + double lambdaPt, double lambdaEta, double lambdaPhi, + double protonPt, double protonEta, double protonPhi) +{ + // const double mP = o2::constants::physics::MassProton; + + // Λ momentum energy + const double pxL = lambdaPt * std::cos(lambdaPhi); + const double pyL = lambdaPt * std::sin(lambdaPhi); + const double pzL = lambdaPt * std::sinh(lambdaEta); + // const double EL = std::sqrt(pxL*pxL + pyL*pyL + pzL*pzL + lambdaMass*lambdaMass); + + // proton momentum and energy + const double pxP = protonPt * std::cos(protonPhi); + const double pyP = protonPt * std::sin(protonPhi); + const double pzP = protonPt * std::sinh(protonEta); + // const double EP = std::sqrt(pxP*pxP + pyP*pyP + pzP*pzP + mP*mP); + + // π momentum and energy + const double pxPi = pxL - pxP; + const double pyPi = pyL - pyP; + const double pzPi = pzL - pzP; + + PionKin out; + out.pt = std::sqrt(pxPi * pxPi + pyPi * pyPi); + + if (out.pt < 1e-6) { + out.eta = 0.0; + out.phi = 0.0; + return out; + } + out.eta = std::asinh(pzPi / out.pt); + out.phi = std::atan2(pyPi, pxPi); + return out; +} + namespace mcacc { // event @@ -199,11 +253,6 @@ struct lambdaspincorrderived { "ConfWeightPaths", std::vector{}, "Replaced-leg CCDB paths in order: REP_LL_leg1,REP_UL_leg1,REP_ALAL_leg1,REP_LL_leg2,REP_UL_leg2,REP_ALAL_leg2"}; - Configurable useConditionedSEWeight{"useConditionedSEWeight", false, "Use replacement weights derived from successful SE targets only"}; - Configurable> ConfConditionedWeightPaths{ - "ConfConditionedWeightPaths", - std::vector{}, - "Conditioned CCDB paths in order: REP/SUC_TGT for LL_leg1,UL_leg1,ALAL_leg1,LL_leg2,UL_leg2,ALAL_leg2"}; Configurable> ConfFixedWeightPaths{ "ConfFixedWeightPaths", std::vector{}, @@ -270,19 +319,25 @@ struct lambdaspincorrderived { // Output-control switches. Keep the final mass-mass-costheta sparse on by default, // but allow heavy QA/additional sparses to be disabled in production. - Configurable fillBasicQAHistos{"fillBasicQAHistos", true, "Fill light QA histograms: pT-y, phi-eta, centrality, dphi, pt/eta vs cent"}; - Configurable fillReplacementQAHistos{"fillReplacementQAHistos", true, "Fill raw TGT/REP single-candidate replacement QA maps"}; - Configurable fillFixedLegQAHistos{"fillFixedLegQAHistos", false, "Fill fixed-leg TGT/SUC QA maps"}; - Configurable fillWeightQAHistos{"fillWeightQAHistos", false, "Fill weighted/final-weighted REP/FIX QA maps"}; - Configurable fillAnalysisSparses{"fillAnalysisSparses", false, "Fill extra deltaR/deltaRap/deltaPhi Analysis THnSparse objects"}; - Configurable fillAdditionalSparses{"fillAdditionalSparses", false, "Fill extra rapidity/dphi/pair-mass THnSparse objects"}; - Configurable checkDoubleStatus{"checkDoubleStatus", 0, "Check Double status"}; + + struct : ConfigurableGroup { + Configurable fillBasicQAHistos{"fillBasicQAHistos", true, "Fill light QA histograms: pT-y, phi-eta, centrality, dphi, pt/eta vs cent"}; + Configurable fillReplacementQAHistos{"fillReplacementQAHistos", true, "Fill raw TGT/REP single-candidate replacement QA maps"}; + Configurable fillFixedLegQAHistos{"fillFixedLegQAHistos", false, "Fill fixed-leg TGT/SUC QA maps"}; + Configurable fillWeightQAHistos{"fillWeightQAHistos", true, "Fill weighted/final-weighted REP/FIX QA maps"}; + Configurable fillAnalysisSparses{"fillAnalysisSparses", false, "Fill extra deltaR/deltaRap/deltaPhi Analysis THnSparse objects"}; + Configurable fillAdditionalSparses{"fillAdditionalSparses", false, "Fill extra rapidity/dphi/pair-mass THnSparse objects"}; + Configurable checkDoubleStatus{"checkDoubleStatus", 0, "Check Double status"}; + + Configurable fillkStarSparses{"fillkStarSparses", true, "Fill extra deltaR/deltaRap/deltaPhi kStar THnSparse objects"}; + + } fillHistConfig; Configurable ptMin{"ptMin", 0.5, "V0 Pt minimum"}; Configurable ptMax{"ptMax", 3.0, "V0 Pt maximum"}; Configurable MassMin{"MassMin", 1.09, "V0 Mass minimum"}; Configurable MassMax{"MassMax", 1.14, "V0 Mass maximum"}; - Configurable v0etaMixBuffer{"v0etaMixBuffer", 0.8, "Eta cut on mix event buffer"}; + Configurable rapidity{"rapidity", 0.5, "Rapidity cut on lambda"}; Configurable v0eta{"v0eta", 0.8, "Eta cut on lambda"}; @@ -295,28 +350,10 @@ struct lambdaspincorrderived { Configurable dcaPion{"dcaPion", 0.2, "DCA Pion"}; Configurable dcaDaughters{"dcaDaughters", 1.0, "DCA between daughters"}; Configurable dcaV0ToPV{"dcaV0ToPV", 1.2, "DCA V0 to PV cut on lambda"}; + Configurable v0etaMixBuffer{"v0etaMixBuffer", 0.8, "Eta cut on mix event buffer"}; } v0Configurations; - struct : ConfigurableGroup { - std::string prefix = "closePairQA"; - - Configurable fillClosePairQA{ - "fillClosePairQA", - true, - "Fill daughter deta-dphi vs Lambda-Lambda deltaR close-pair QA"}; - - ConfigurableAxis axClosePairDEta{ - "axClosePairDEta", - {100, -0.2, 0.2}, - "#Delta#eta daughter"}; - - ConfigurableAxis axClosePairDPhi{ - "axClosePairDPhi", - {100, -0.2, 0.2}, - "#Delta#varphi daughter"}; - } cfgClosePairQA; - // Event Mixing Configurable cosDef{"cosDef", 1, "Defination of cos"}; @@ -336,27 +373,18 @@ struct lambdaspincorrderived { ConfigurableAxis configThnAxisPhi{"configThnAxisPhi", {VARIABLE_WIDTH, 0.0, 2.0 * TMath::Pi()}, "Phi"}; ConfigurableAxis configThnAxisDeltaPhi{"configThnAxisDeltaPhi", {VARIABLE_WIDTH, 0.0, TMath::Pi() / 6, 2.0 * TMath::Pi() / 6, 3.0 * TMath::Pi() / 6, 4.0 * TMath::Pi() / 6, 5.0 * TMath::Pi() / 6, TMath::Pi()}, "Delta Phi"}; - ConfigurableAxis configThnAxisDeltaR{"configThnAxisDeltaR", {VARIABLE_WIDTH, 0.0, 0.4, 0.8, 1.2, 2.0, 3.1, 4.0}, "Delta R"}; + ConfigurableAxis configThnAxisDeltaR{"configThnAxisDeltaR", {VARIABLE_WIDTH, 0.0, 0.5, 1.2, 2.0, 3.1, 4.0}, "Delta R"}; + ConfigurableAxis configThnAxisDeltaRnew{"configThnAxisDeltaRnew", {VARIABLE_WIDTH, 0.0, 0.4, 0.8, 1.2, 1.8, 2.4, 3.1}, "Delta R"}; ConfigurableAxis configThnAxisDeltaRap{"configThnAxisDeltaRap", {VARIABLE_WIDTH, 0.0, 0.2, 0.5, 1.0, 1.6}, "Delta Rap"}; + ConfigurableAxis configThnAxisKStar{"configThnAxisKStar", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 1.0}, "#it{k}^{*} (GeV/#it{c})"}; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // ------------------------- // Systematics control // ------------------------- - struct SysFromDeltaPtDeltaEtaDeltaPhi { - // Mixed -event kinematic cut - float minDeltaPt; - float maxDelatPt; - - float minDeltaEta; - float maxDeltaEta; - - float minDeltaPhi; - float maxDeltaPhi; - }; - struct SysCuts { // Topology cut float maxDcaDaughters; @@ -456,13 +484,55 @@ struct lambdaspincorrderived { void init(o2::framework::InitContext&) { + + // Laura: Δη–Δφ for same-charge ΛΛ in the first ΔR bin + const int nBinsDEta = 80; + const double dEtaMin = -0.15; + const double dEtaMax = 0.15; + + const int nBinsDPhi = 80; + const double dPhiMin = -0.15; + const double dPhiMax = 0.15; + + histos.add("hDEtaDPhiKStar_pp_SE", + "p-p #Delta#eta vs #Delta#phi vs #DeltaR vs #it{k}^{*} (same-charge #Lambda#Lambda);#Delta#eta;#Delta#phi;#DeltaR;#it{k}^{*}", + HistType::kTHnSparseF, + {{nBinsDEta, dEtaMin, dEtaMax}, + {nBinsDPhi, dPhiMin, dPhiMax}, + {configThnAxisDeltaRnew}, + {configThnAxisKStar}}); + + histos.add("hDEtaDPhiKStar_pipi_SE", + "#pi-#pi #Delta#eta vs #Delta#phi vs #DeltaR vs #it{k}^{*} (same-charge #Lambda#Lambda);#Delta#eta;#Delta#phi;#DeltaR;#it{k}^{*}", + HistType::kTHnSparseF, + {{nBinsDEta, dEtaMin, dEtaMax}, + {nBinsDPhi, dPhiMin, dPhiMax}, + {configThnAxisDeltaRnew}, + {configThnAxisKStar}}); + + histos.add("hDEtaDPhiKStar_ppi_SE", + "p-#pi #Delta#eta vs #Delta#phi vs #DeltaR vs #it{k}^{*} (same-charge #Lambda#Lambda);#Delta#eta;#Delta#phi;#DeltaR;#it{k}^{*}", + HistType::kTHnSparseF, + {{nBinsDEta, dEtaMin, dEtaMax}, + {nBinsDPhi, dPhiMin, dPhiMax}, + {configThnAxisDeltaRnew}, + {configThnAxisKStar}}); + + histos.add("hDEtaDPhiKStar_pip_SE", + "#pi-p #Delta#eta vs #Delta#phi vs #DeltaR vs #it{k}^{*} (same-charge #Lambda#Lambda);#Delta#eta;#Delta#phi;#DeltaR;#it{k}^{*}", + HistType::kTHnSparseF, + {{nBinsDEta, dEtaMin, dEtaMax}, + {nBinsDPhi, dPhiMin, dPhiMax}, + {configThnAxisDeltaRnew}, + {configThnAxisKStar}}); + buildSystematicCuts(); nSysTotal = (int)sysCuts.size(); // or whatever vector you fill LOGF(info, "sysCuts.size()=%zu nSysTotal=%d", sysCuts.size(), nSysTotal); const AxisSpec thnAxisSys{nSysTotal, -0.5f, float(nSysTotal) - 0.5f, "sysId"}; - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.add("hPtRadiusV0", "V0 QA;#it{p}_{T}^{V0} (GeV/#it{c});V0 decay radius (cm)", kTH2F, {{100, 0.0, 10.0}, {120, 0.0, 45.0}}); histos.add("hPtYSame", "hPtYSame", kTH2F, {{100, 0.0, 10.0}, {200, -1.0, 1.0}}); histos.add("hPtYMix", "hPtYMix", kTH2F, {{100, 0.0, 10.0}, {200, -1.0, 1.0}}); @@ -475,59 +545,7 @@ struct lambdaspincorrderived { histos.add("etaCent", "etaCent", HistType::kTH2D, {{32, -0.8, 0.8}, {8, 0.0, 80.0}}, true); } - if (cfgClosePairQA.fillClosePairQA) { - histos.add( - "hClosePairPP_kStar020", - "p_{1}-p_{2}, k* > 0.2 GeV/c;#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - histos.add( - "hClosePairPiPi_kStar020", - "#pi_{1}-#pi_{2}, k* > 0.2 GeV/c;#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - histos.add( - "hClosePairPPi_kStar020", - "p_{1}-#pi_{2}, k* > 0.2 GeV/c;#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - histos.add( - "hClosePairPiP_kStar020", - "#pi_{1}-p_{2}, k* > 0.2 GeV/c;#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - - histos.add( - "hClosePairPP", - "p_{1}-p_{2};#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - histos.add( - "hClosePairPiPi", - "#pi_{1}-#pi_{2};#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - histos.add( - "hClosePairPPi", - "p_{1}-#pi_{2};#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - histos.add( - "hClosePairPiP", - "#pi_{1}-p_{2};#Delta#eta;#Delta#varphi;#DeltaR_{#Lambda#Lambda}", - HistType::kTH3D, - {cfgClosePairQA.axClosePairDEta, cfgClosePairQA.axClosePairDPhi, configThnAxisDeltaR}, - true); - } - - if (fillWeightQAHistos) { + if (fillHistConfig.fillWeightQAHistos) { // QA for weighting histos.add("REP_LL_leg1_weighted", "Weighted repl LL leg1;#phi;y/#eta;p_{T}", @@ -561,7 +579,7 @@ struct lambdaspincorrderived { "Weighted repl ALAL leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); } - if (fillFixedLegQAHistos) { + if (fillHistConfig.fillFixedLegQAHistos) { // Fixed-leg QA for replacement-leg bias check. // For repLeg1: leg1 is replaced, fixed leg is original leg2. // For repLeg2: leg2 is replaced, fixed leg is original leg1. @@ -597,7 +615,7 @@ struct lambdaspincorrderived { histos.add("hNUAWeightLambda", "Lambda NUA weight", kTH1D, {{200, 0.0, 5.0}}); histos.add("hNUAWeightAntiLambda", "AntiLambda NUA weight", kTH1D, {{200, 0.0, 5.0}}); - if (fillReplacementQAHistos) { + if (fillHistConfig.fillReplacementQAHistos) { // --- target/replacement single-leg occupancy maps for replacement correction histos.add("TGT_LL_leg1", "Target LL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); histos.add("TGT_LAL_leg1", "Target LAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); @@ -614,25 +632,12 @@ struct lambdaspincorrderived { histos.add("TGT_ALL_leg2", "Target ALL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); histos.add("TGT_ALAL_leg2", "Target ALAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - // Target candidates restricted to branches for which at least one valid - // replacement was found. Use REP/SUC_TGT as the conditioned matching - // efficiency when SE itself is restricted to replacement-found pairs. - histos.add("SUC_TGT_LL_leg1", "Successful target LL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("SUC_TGT_LAL_leg1", "Successful target LAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("SUC_TGT_ALL_leg1", "Successful target ALL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("SUC_TGT_ALAL_leg1", "Successful target ALAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - - histos.add("SUC_TGT_LL_leg2", "Successful target LL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("SUC_TGT_LAL_leg2", "Successful target LAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("SUC_TGT_ALL_leg2", "Successful target ALL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("SUC_TGT_ALAL_leg2", "Successful target ALAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("REP_LL_leg2", "Repl LL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); histos.add("REP_LAL_leg2", "Repl LAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); histos.add("REP_ALL_leg2", "Repl ALL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); histos.add("REP_ALAL_leg2", "Repl ALAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); } - if (fillWeightQAHistos) { + if (fillHistConfig.fillWeightQAHistos) { // Final-weighted QA: filled with the exact same mixing correction weight // used for the mixed-event sparse, excluding NUA. // Correction categories are LL, UL=(LAL+ALL), ALAL. @@ -656,141 +661,6 @@ struct lambdaspincorrderived { histos.add("hSparseLambdaAntiLambda", "hSparseLambdaAntiLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); histos.add("hSparseAntiLambdaLambda", "hSparseAntiLambdLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); histos.add("hSparseAntiLambdaAntiLambda", "hSparseAntiLambdaAntiLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - // ============================================================ - // cos^2(theta*) sparses - // ============================================================ - - // Same event - histos.add("hSparseLambdaLambdaCos2", - "hSparseLambdaLambdaCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseLambdaAntiLambdaCos2", - "hSparseLambdaAntiLambdaCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaLambdaCos2", - "hSparseAntiLambdaLambdaCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaAntiLambdaCos2", - "hSparseAntiLambdaAntiLambdaCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - // Mixed event - histos.add("hSparseLambdaLambdaMixedCos2", - "hSparseLambdaLambdaMixedCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseLambdaAntiLambdaMixedCos2", - "hSparseLambdaAntiLambdaMixedCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaLambdaMixedCos2", - "hSparseAntiLambdaLambdaMixedCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaAntiLambdaMixedCos2", - "hSparseAntiLambdaAntiLambdaMixedCos2", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - // ============================================================ - // cos^3(theta*) sparses - // ============================================================ - - // Same event -- useful QA / future higher moment - histos.add("hSparseLambdaLambdaCos3", - "hSparseLambdaLambdaCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseLambdaAntiLambdaCos3", - "hSparseLambdaAntiLambdaCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaLambdaCos3", - "hSparseAntiLambdaLambdaCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaAntiLambdaCos3", - "hSparseAntiLambdaAntiLambdaCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - // Mixed event -- needed for linearity test - histos.add("hSparseLambdaLambdaMixedCos3", - "hSparseLambdaLambdaMixedCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseLambdaAntiLambdaMixedCos3", - "hSparseLambdaAntiLambdaMixedCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaLambdaMixedCos3", - "hSparseAntiLambdaLambdaMixedCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - - histos.add("hSparseAntiLambdaAntiLambdaMixedCos3", - "hSparseAntiLambdaAntiLambdaMixedCos3", - HistType::kTHnSparseF, - {configThnAxisInvMass, configThnAxisInvMass, - configThnAxisPol, configThnAxisR}, - true); - // Original same-event pairs split by whether the ME replacement search - // succeeds. These use the original SE pair variables and the ordinary - // SE NUA weight; no mixing or replacement-efficiency weight is applied. - histos.add("hSparseLambdaLambdaSEReplacementFound", "hSparseLambdaLambdaSEReplacementFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - histos.add("hSparseLambdaAntiLambdaSEReplacementFound", "hSparseLambdaAntiLambdaSEReplacementFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - histos.add("hSparseAntiLambdaLambdaSEReplacementFound", "hSparseAntiLambdaLambdaSEReplacementFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - histos.add("hSparseAntiLambdaAntiLambdaSEReplacementFound", "hSparseAntiLambdaAntiLambdaSEReplacementFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - - histos.add("hSparseLambdaLambdaSEReplacementNotFound", "hSparseLambdaLambdaSEReplacementNotFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - histos.add("hSparseLambdaAntiLambdaSEReplacementNotFound", "hSparseLambdaAntiLambdaSEReplacementNotFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - histos.add("hSparseAntiLambdaLambdaSEReplacementNotFound", "hSparseAntiLambdaLambdaSEReplacementNotFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - histos.add("hSparseAntiLambdaAntiLambdaSEReplacementNotFound", "hSparseAntiLambdaAntiLambdaSEReplacementNotFound", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); histos.add("hSparseLambdaLambdaMixed", "hSparseLambdaLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); histos.add("hSparseLambdaAntiLambdaMixed", "hSparseLambdaAntiLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); @@ -808,7 +678,20 @@ struct lambdaspincorrderived { histos.add("hSparseAntiLambdaLambdaMixedSys", "hSparseAntiLambdaLambdaMixedSys", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, thnAxisSys}, true); histos.add("hSparseAntiLambdaAntiLambdaMixedSys", "hSparseAntiLambdaAntiLambdaMixedSys", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, thnAxisSys}, true); - if (fillAnalysisSparses) { + if (fillHistConfig.fillkStarSparses) { + + histos.add("hSparseLambdaLambda_kStar", "hSparseLambdaLambda_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, configThnAxisKStar}, true); + histos.add("hSparseLambdaAntiLambda_kStar", "hSparseLambdaAntiLambda_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, configThnAxisKStar}, true); + histos.add("hSparseAntiLambdaLambda_kStar", "hSparseAntiLambdaLambda_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, configThnAxisKStar}, true); + histos.add("hSparseAntiLambdaAntiLambda_kStar", "hSparseAntiLambdaAntiLambda_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, configThnAxisKStar}, true); + + histos.add("hSparseLambdaLambdaMixed_kStar", "hSparseLambdaLambdaMixed_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, configThnAxisKStar}, true); + // histos.add("hSparseLambdaAntiLambdaMixed_kStar", "hSparseLambdaAntiLambdaMixed_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR,configThnAxisKStar}, true); + // histos.add("hSparseAntiLambdaLambdaMixed_kStar", "hSparseAntiLambdaLambdaMixed_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR,configThnAxisKStar}, true); + histos.add("hSparseAntiLambdaAntiLambdaMixed_kStar", "hSparseAntiLambdaAntiLambdaMixed_kStar", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR, configThnAxisKStar}, true); + } + + if (fillHistConfig.fillAnalysisSparses) { histos.add("hSparseLambdaLambdaAnalysis", "hSparseLambdaLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); histos.add("hSparseLambdaAntiLambdaAnalysis", "hSparseLambdaAntiLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); histos.add("hSparseAntiLambdaLambdaAnalysis", "hSparseAntiLambdLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); @@ -820,7 +703,7 @@ struct lambdaspincorrderived { histos.add("hSparseAntiLambdaAntiLambdaMixedAnalysis", "hSparseAntiLambdaAntiLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.add("hSparseRapLambdaLambda", "hSparseRapLambdaLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisRapidity}, true); histos.add("hSparseRapLambdaAntiLambda", "hSparseRapLambdaAntiLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisRapidity}, true); histos.add("hSparseRapAntiLambdaLambda", "hSparseRapAntiLambdLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisRapidity}, true); @@ -858,18 +741,12 @@ struct lambdaspincorrderived { ccdb->setCreatedNotAfter(cfgCcdbParam.nolaterthan.value); LOGF(info, "Getting alignment offsets from the CCDB (check carefully)..."); if (useweight) { - if (cfgCcdbParam.useConditionedSEWeight && cfgCcdbParam.useFixedWeight) { - LOGF(fatal, "useFixedWeight must be false with useConditionedSEWeight: the fixed leg already belongs to the successful SE subset"); - } - const auto& repPaths = cfgCcdbParam.useConditionedSEWeight - ? cfgCcdbParam.ConfConditionedWeightPaths.value - : cfgCcdbParam.ConfWeightPaths.value; - const char* activePathName = cfgCcdbParam.useConditionedSEWeight ? "ConfConditionedWeightPaths" : "ConfWeightPaths"; + const auto& repPaths = cfgCcdbParam.ConfWeightPaths.value; if (repPaths.size() < 6) { - LOGF(fatal, "%s must contain 6 paths: LL_leg1, UL_leg1, ALAL_leg1, LL_leg2, UL_leg2, ALAL_leg2. Found %zu", activePathName, repPaths.size()); + LOGF(fatal, "ConfWeightPaths must contain 6 paths: REP_LL_leg1, REP_UL_leg1, REP_ALAL_leg1, REP_LL_leg2, REP_UL_leg2, REP_ALAL_leg2. Found %zu", repPaths.size()); } for (size_t i = 0; i < repPaths.size(); ++i) { - LOGF(info, "%s[%zu] = '%s'", activePathName, i, repPaths[i].c_str()); + LOGF(info, "ConfWeightPaths[%zu] = '%s'", i, repPaths[i].c_str()); } auto loadRep = [&](int idx, const char* name) -> TH3D* { @@ -952,7 +829,7 @@ struct lambdaspincorrderived { if (candidate.v0Cospa() < v0Configurations.cosPA) { return false; } - if (checkDoubleStatus && candidate.doubleStatus()) { + if (fillHistConfig.checkDoubleStatus && candidate.doubleStatus()) { return false; } if (candidate.v0Radius() > v0Configurations.radiusMax) { @@ -997,7 +874,7 @@ struct lambdaspincorrderived { if (candidate.v0Cospa() < SysCuts.mincosPA) { return false; } - if (checkDoubleStatus && candidate.doubleStatus()) { + if (fillHistConfig.checkDoubleStatus && candidate.doubleStatus()) { return false; } if (candidate.v0Radius() > SysCuts.maxRadius) { @@ -1083,20 +960,6 @@ struct lambdaspincorrderived { } return w; } - static inline double getKStar( - const ROOT::Math::PtEtaPhiMVector& p1, - const ROOT::Math::PtEtaPhiMVector& p2) - { - const auto pair = p1 + p2; - - ROOT::Math::Boost boostToPairCM{pair.BoostToCM()}; - const auto p1CM = boostToPairCM(p1); - - return std::sqrt( - p1CM.Px() * p1CM.Px() + - p1CM.Py() * p1CM.Py() + - p1CM.Pz() * p1CM.Pz()); - } int getWeightCategory(int tag1, int tag2) const { @@ -1123,7 +986,7 @@ struct lambdaspincorrderived { // for the mixed-event sparse, before the NUA factor is applied. // mapLeg = physical replacement branch used for the CCDB map (1 or 2) // replacedPos = position of the replaced candidate after possible L#bar{L} reordering (1 or 2) - if (!fillWeightQAHistos) { + if (!fillHistConfig.fillWeightQAHistos) { return; } if (!std::isfinite(weight) || weight <= 0.0) { @@ -1215,6 +1078,24 @@ struct lambdaspincorrderived { lambda2Mass = o2::constants::physics::MassLambda; } + const auto pion1 = getPionKinematics( + particle1.Pt(), particle1.Eta(), particle1.Phi(), + daughpart1.Pt(), daughpart1.Eta(), daughpart1.Phi()); + + const auto pion2 = getPionKinematics( + particle2.Pt(), particle2.Eta(), particle2.Phi(), + daughpart2.Pt(), daughpart2.Eta(), daughpart2.Phi()); + + const auto pion1Vec = ROOT::Math::PtEtaPhiMVector( + pion1.pt, pion1.eta, pion1.phi, o2::constants::physics::MassPionCharged); + const auto pion2Vec = ROOT::Math::PtEtaPhiMVector( + pion2.pt, pion2.eta, pion2.phi, o2::constants::physics::MassPionCharged); + + const double kStar_pp = getKStar(daughpart1, daughpart2); + const double kStar_pipi = getKStar(pion1Vec, pion2Vec); + const double kStar_ppi = getKStar(daughpart1, pion2Vec); + const double kStar_pip = getKStar(pion1Vec, daughpart2); + auto particle1Dummy = ROOT::Math::PtEtaPhiMVector(particle1.Pt(), particle1.Eta(), particle1.Phi(), lambda1Mass); auto particle2Dummy = ROOT::Math::PtEtaPhiMVector(particle2.Pt(), particle2.Eta(), particle2.Phi(), lambda2Mass); auto pairDummy = particle1Dummy + particle2Dummy; @@ -1264,8 +1145,7 @@ struct lambdaspincorrderived { cosDeltaTheta_hel = -111.0; double cosThetaDiff = (cosDef == 0) ? cosDeltaTheta_STAR_naive : cosDeltaTheta_hel; - const double cosThetaDiff2 = cosThetaDiff * cosThetaDiff; - const double cosThetaDiff3 = cosThetaDiff2 * cosThetaDiff; + double pt1 = particle1.Pt(); double dphi1 = RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic); double deta1 = particle1.Eta(); @@ -1367,68 +1247,95 @@ struct lambdaspincorrderived { if (datatype == 0) { const double weight = pairNUAWeight; + + // ---- Δη–Δφ for same-charge ΛΛ, first ΔR bin ---- + if (tag1 == tag2) { + if (particle1.M() > 1.11 && particle1.M() < 1.12 && + particle2.M() > 1.11 && particle2.M() < 1.12) { + + if (deltaR >= 0.0 && deltaR < 3.1) { + + histos.fill(HIST("hDEtaDPhiKStar_pp_SE"), + daughpart1.Eta() - daughpart2.Eta(), + deltaPhiMinusPiToPi(daughpart1.Phi(), daughpart2.Phi()), + deltaR, + kStar_pp); + + histos.fill(HIST("hDEtaDPhiKStar_pipi_SE"), + pion1.eta - pion2.eta, + deltaPhiMinusPiToPi(pion1.phi, pion2.phi), + deltaR, + kStar_pipi); + + histos.fill(HIST("hDEtaDPhiKStar_ppi_SE"), + daughpart1.Eta() - pion2.eta, + deltaPhiMinusPiToPi(daughpart1.Phi(), pion2.phi), + deltaR, + kStar_ppi); + + histos.fill(HIST("hDEtaDPhiKStar_pip_SE"), + pion1.eta - daughpart2.Eta(), + deltaPhiMinusPiToPi(pion1.phi, daughpart2.Phi()), + deltaR, + kStar_pip); + } + } + } + if (tag1 == 0 && tag2 == 0) { - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("hPtYSame"), particle1.Pt(), particle1.Rapidity(), nuaWeight1); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("hPhiEtaSame"), dphi1, particle1.Eta(), nuaWeight1); histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaLambdaCos2"), particle1.M(), particle2.M(), cosThetaDiff2, deltaR, weight); - histos.fill(HIST("hSparseLambdaLambdaCos3"), particle1.M(), particle2.M(), cosThetaDiff3, deltaR, weight); - if (fillAnalysisSparses) { + + if (fillHistConfig.fillkStarSparses) { + histos.fill(HIST("hSparseLambdaLambda_kStar"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, kStar_pp, weight); + } + + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseLambdaLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 0 && tag2 == 1) { histos.fill(HIST("hSparseLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaAntiLambdaCos2"), particle1.M(), particle2.M(), cosThetaDiff2, deltaR, weight); - histos.fill(HIST("hSparseLambdaAntiLambdaCos3"), particle1.M(), particle2.M(), cosThetaDiff3, deltaR, weight); - if (fillAnalysisSparses) { + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseLambdaAntiLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } + } else if (tag1 == 1 && tag2 == 0) { histos.fill(HIST("hSparseAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaLambdaCos2"), - particle1.M(), particle2.M(), - cosThetaDiff2, deltaR, weight); - - histos.fill(HIST("hSparseAntiLambdaLambdaCos3"), - particle1.M(), particle2.M(), - cosThetaDiff3, deltaR, weight); - if (fillAnalysisSparses) { + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseAntiLambdaLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 1) { histos.fill(HIST("hSparseAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaAntiLambdaCos2"), - particle1.M(), particle2.M(), - cosThetaDiff2, deltaR, weight); - - histos.fill(HIST("hSparseAntiLambdaAntiLambdaCos3"), - particle1.M(), particle2.M(), - cosThetaDiff3, deltaR, weight); - if (fillAnalysisSparses) { + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseAntiLambdaAntiLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } + + if (fillHistConfig.fillkStarSparses) { + histos.fill(HIST("hSparseAntiLambdaAntiLambda_kStar"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, kStar_pp, weight); + } } } else if (datatype == 1) { @@ -1458,24 +1365,21 @@ struct lambdaspincorrderived { if (tag1 == 0 && tag2 == 0) { if (replacedLeg == 1 || replacedLeg == 2) { - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("hPtYMix"), particle1.Pt(), particle1.Rapidity(), nuaWeight1 * mixpairweight); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("hPhiEtaMix"), dphi1, particle1.Eta(), nuaWeight1 * mixpairweight); } histos.fill(HIST("hSparseLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaLambdaMixedCos2"), - particle1.M(), particle2.M(), - cosThetaDiff2, deltaR, weight); - histos.fill(HIST("hSparseLambdaLambdaMixedCos3"), - particle1.M(), particle2.M(), - cosThetaDiff3, deltaR, weight); + if (fillHistConfig.fillkStarSparses) { + histos.fill(HIST("hSparseLambdaLambdaMixed_kStar"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, kStar_pp, weight); + } - if (fillAnalysisSparses) { + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseLambdaLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); @@ -1483,156 +1387,41 @@ struct lambdaspincorrderived { } else if (tag1 == 0 && tag2 == 1) { histos.fill(HIST("hSparseLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaAntiLambdaMixedCos2"), - particle1.M(), particle2.M(), - cosThetaDiff2, deltaR, weight); - - histos.fill(HIST("hSparseLambdaAntiLambdaMixedCos3"), - particle1.M(), particle2.M(), - cosThetaDiff3, deltaR, weight); - if (fillAnalysisSparses) { + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseLambdaAntiLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 0) { histos.fill(HIST("hSparseAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaLambdaMixedCos2"), - particle1.M(), particle2.M(), - cosThetaDiff2, deltaR, weight); - - histos.fill(HIST("hSparseAntiLambdaLambdaMixedCos3"), - particle1.M(), particle2.M(), - cosThetaDiff3, deltaR, weight); - if (fillAnalysisSparses) { + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseAntiLambdaLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 1) { histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixedCos2"), - particle1.M(), particle2.M(), - cosThetaDiff2, deltaR, weight); - - histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixedCos3"), - particle1.M(), particle2.M(), - cosThetaDiff3, deltaR, weight); - if (fillAnalysisSparses) { + if (fillHistConfig.fillAnalysisSparses) { histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); } - if (useAdditionalHisto || fillAdditionalSparses) { + if (useAdditionalHisto || fillHistConfig.fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } + if (fillHistConfig.fillkStarSparses) { + histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixed_kStar"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, kStar_pp, weight); + } } } } - void fillSEReplacementOutcomeSparse( - int tag1, int tag2, - const ROOT::Math::PtEtaPhiMVector& particle1, - const ROOT::Math::PtEtaPhiMVector& particle2, - const ROOT::Math::PtEtaPhiMVector& daughter1, - const ROOT::Math::PtEtaPhiMVector& daughter2, - bool replacementFound) - { - const double lambda1Mass = usePDGM ? o2::constants::physics::MassLambda : particle1.M(); - const double lambda2Mass = usePDGM ? o2::constants::physics::MassLambda : particle2.M(); - - const auto particle1Dummy = ROOT::Math::PtEtaPhiMVector(particle1.Pt(), particle1.Eta(), particle1.Phi(), lambda1Mass); - const auto particle2Dummy = ROOT::Math::PtEtaPhiMVector(particle2.Pt(), particle2.Eta(), particle2.Phi(), lambda2Mass); - const auto pairDummy = particle1Dummy + particle2Dummy; - ROOT::Math::Boost boostPairToCM{pairDummy.BoostToCM()}; - - const auto lambda1CM = boostPairToCM(particle1Dummy); - const auto lambda2CM = boostPairToCM(particle2Dummy); - ROOT::Math::Boost boostLambda1ToCM{lambda1CM.BoostToCM()}; - ROOT::Math::Boost boostLambda2ToCM{lambda2CM.BoostToCM()}; - - const auto proton1PairCM = boostPairToCM(daughter1); - const auto proton2PairCM = boostPairToCM(daughter2); - const auto proton1LambdaRF = boostLambda1ToCM(proton1PairCM); - const auto proton2LambdaRF = boostLambda2ToCM(proton2PairCM); - - ROOT::Math::Boost boostL1LabToRF{particle1Dummy.BoostToCM()}; - ROOT::Math::Boost boostL2LabToRF{particle2Dummy.BoostToCM()}; - const auto proton1LRF = boostL1LabToRF(daughter1); - const auto proton2LRF = boostL2LabToRF(daughter2); - - const TVector3 u1 = TVector3(proton1LRF.Px(), proton1LRF.Py(), proton1LRF.Pz()).Unit(); - const TVector3 u2 = TVector3(proton2LRF.Px(), proton2LRF.Py(), proton2LRF.Pz()).Unit(); - const TVector3 k1 = TVector3(proton1LambdaRF.Px(), proton1LambdaRF.Py(), proton1LambdaRF.Pz()).Unit(); - const TVector3 k2 = TVector3(proton2LambdaRF.Px(), proton2LambdaRF.Py(), proton2LambdaRF.Pz()).Unit(); - - double cosThetaDiff = (cosDef == 0) ? u1.Dot(u2) : k1.Dot(k2); - if (cosThetaDiff > 1.0) { - cosThetaDiff = 111.0; - } else if (cosThetaDiff < -1.0) { - cosThetaDiff = -111.0; - } - - const double dphi1 = RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic); - const double dphi2 = RecoDecay::constrainAngle(particle2.Phi(), 0.0F, harmonic); - const double dphiPair = RecoDecay::constrainAngle(dphi1 - dphi2, -TMath::Pi(), harmonicDphi); - const double deltaRap = std::abs(particle1.Rapidity() - particle2.Rapidity()); - const double deltaR = TMath::Sqrt(deltaRap * deltaRap + dphiPair * dphiPair); - - // Match the ordinary SE sparse exactly. This is only the established SE - // NUA correction, not an ME-availability or replacement-candidate weight. - const double pairNUAWeight = getNUAWeight(tag1, particle1.Phi(), particle1.Eta()) * - getNUAWeight(tag2, particle2.Phi(), particle2.Eta()); - - if (replacementFound) { - if (tag1 == 0 && tag2 == 0) { - histos.fill(HIST("hSparseLambdaLambdaSEReplacementFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } else if (tag1 == 0 && tag2 == 1) { - histos.fill(HIST("hSparseLambdaAntiLambdaSEReplacementFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } else if (tag1 == 1 && tag2 == 0) { - histos.fill(HIST("hSparseAntiLambdaLambdaSEReplacementFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } else if (tag1 == 1 && tag2 == 1) { - histos.fill(HIST("hSparseAntiLambdaAntiLambdaSEReplacementFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } - return; - } - - if (tag1 == 0 && tag2 == 0) { - histos.fill(HIST("hSparseLambdaLambdaSEReplacementNotFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } else if (tag1 == 0 && tag2 == 1) { - histos.fill(HIST("hSparseLambdaAntiLambdaSEReplacementNotFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } else if (tag1 == 1 && tag2 == 0) { - histos.fill(HIST("hSparseAntiLambdaLambdaSEReplacementNotFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } else if (tag1 == 1 && tag2 == 1) { - histos.fill(HIST("hSparseAntiLambdaAntiLambdaSEReplacementNotFound"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, pairNUAWeight); - } - } - - template - void fillSEReplacementOutcome(T1 const& first, T2 const& second, bool replacementFound) - { - const auto firstLambda = ROOT::Math::PtEtaPhiMVector(first.lambdaPt(), first.lambdaEta(), first.lambdaPhi(), first.lambdaMass()); - const auto firstProton = ROOT::Math::PtEtaPhiMVector(first.protonPt(), first.protonEta(), first.protonPhi(), o2::constants::physics::MassProton); - const auto secondLambda = ROOT::Math::PtEtaPhiMVector(second.lambdaPt(), second.lambdaEta(), second.lambdaPhi(), second.lambdaMass()); - const auto secondProton = ROOT::Math::PtEtaPhiMVector(second.protonPt(), second.protonEta(), second.protonPhi(), o2::constants::physics::MassProton); - const int firstStatus = first.v0Status(); - const int secondStatus = second.v0Status(); - - // Keep the same unlike-sign ordering used by processData: Lambda first, - // AntiLambda second. - if (firstStatus == 1 && secondStatus == 0) { - fillSEReplacementOutcomeSparse(0, 1, secondLambda, firstLambda, secondProton, firstProton, replacementFound); - return; - } - fillSEReplacementOutcomeSparse(firstStatus, secondStatus, firstLambda, secondLambda, firstProton, secondProton, replacementFound); - } - void fillHistogramsSys(int tag1, int tag2, const ROOT::Math::PtEtaPhiMVector& particle1, const ROOT::Math::PtEtaPhiMVector& particle2, const ROOT::Math::PtEtaPhiMVector& daughpart1, const ROOT::Math::PtEtaPhiMVector& daughpart2, @@ -1894,13 +1683,13 @@ struct lambdaspincorrderived { if (!selectionV0(v0)) { continue; } - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("hPtRadiusV0"), v0.lambdaPt(), v0.v0Radius()); } - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("ptCent"), v0.lambdaPt(), centrality); } - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("etaCent"), v0.lambdaEta(), centrality); } proton = ROOT::Math::PtEtaPhiMVector(v0.protonPt(), v0.protonEta(), v0.protonPhi(), o2::constants::physics::MassProton); @@ -1922,56 +1711,14 @@ struct lambdaspincorrderived { } if (hasSharedDaughters(v0, v02)) continue; - proton2 = ROOT::Math::PtEtaPhiMVector(v02.protonPt(), v02.protonEta(), v02.protonPhi(), o2::constants::physics::MassProton); lambda2 = ROOT::Math::PtEtaPhiMVector(v02.lambdaPt(), v02.lambdaEta(), v02.lambdaPhi(), v02.lambdaMass()); - const double kStar = getKStar(lambda, lambda2); - - // Close-pair QA for same-sign Lambda pairs in the signal mass window. - if (cfgClosePairQA.fillClosePairQA && - v0.v0Status() == v02.v0Status() && - v0.lambdaMass() > 1.11f && v0.lambdaMass() < 1.12f && - v02.lambdaMass() > 1.11f && v02.lambdaMass() < 1.12f) { - // Keep the parent DeltaR definition identical to the main analysis. - const double dPhiLL = deltaPhiMinusPiToPi(lambda.Phi(), lambda2.Phi()); - const double dYLL = lambda.Rapidity() - lambda2.Rapidity(); - const double deltaRLL = std::sqrt(dYLL * dYLL + dPhiLL * dPhiLL); - - // Lambda = proton + pion. - const auto pion1 = lambda - proton; - const auto pion2 = lambda2 - proton2; - - const double dEtaPP = proton.Eta() - proton2.Eta(); - const double dPhiPP = deltaPhiMinusPiToPi(proton.Phi(), proton2.Phi()); - histos.fill(HIST("hClosePairPP"), dEtaPP, dPhiPP, deltaRLL); - if (kStar > 0.20) { - histos.fill(HIST("hClosePairPP_kStar020"), dEtaPP, dPhiPP, deltaRLL); - } - - const double dEtaPiPi = pion1.Eta() - pion2.Eta(); - const double dPhiPiPi = deltaPhiMinusPiToPi(pion1.Phi(), pion2.Phi()); - histos.fill(HIST("hClosePairPiPi"), dEtaPiPi, dPhiPiPi, deltaRLL); - if (kStar > 0.20) { - histos.fill(HIST("hClosePairPiPi_kStar020"), dEtaPiPi, dPhiPiPi, deltaRLL); - } - - const double dEtaPPi = proton.Eta() - pion2.Eta(); - const double dPhiPPi = deltaPhiMinusPiToPi(proton.Phi(), pion2.Phi()); - histos.fill(HIST("hClosePairPPi"), dEtaPPi, dPhiPPi, deltaRLL); - if (kStar > 0.20) { - histos.fill(HIST("hClosePairPPi_kStar020"), dEtaPPi, dPhiPPi, deltaRLL); - } - - const double dEtaPiP = pion1.Eta() - proton2.Eta(); - const double dPhiPiP = deltaPhiMinusPiToPi(pion1.Phi(), proton2.Phi()); - histos.fill(HIST("hClosePairPiP"), dEtaPiP, dPhiPiP, deltaRLL); - if (kStar > 0.20) { - histos.fill(HIST("hClosePairPiP_kStar020"), dEtaPiP, dPhiPiP, deltaRLL); + if ((v0.v0Status() == 0 && v02.v0Status() == 1) || (v0.v0Status() == 1 && v02.v0Status() == 0)) { + if (fillHistConfig.fillBasicQAHistos) { + histos.fill(HIST("deltaPhiSame"), RecoDecay::constrainAngle(v0.lambdaPhi() - v02.lambdaPhi(), -TMath::Pi(), harmonicDphi)); } } - if ((v0.v0Status() == 0 && v02.v0Status() == 1) || (v0.v0Status() == 1 && v02.v0Status() == 0)) - if (fillBasicQAHistos) - histos.fill(HIST("deltaPhiSame"), RecoDecay::constrainAngle(v0.lambdaPhi() - v02.lambdaPhi(), -TMath::Pi(), harmonicDphi)); + // const int ptype = pairTypeCode(v0.v0Status(), v02.v0Status()); if (v0.v0Status() == 0 && v02.v0Status() == 0) { fillHistograms(0, 0, lambda, lambda2, proton, proton2, 0, 1.0); @@ -2058,7 +1805,7 @@ struct lambdaspincorrderived { void fillReplacementControlMap(int tag1, int tag2, int leg, bool isTarget, LV const& particle, float weight) { - if (!fillReplacementQAHistos) { + if (!fillHistConfig.fillReplacementQAHistos) { return; } const double pt = particle.Pt(); @@ -2123,41 +1870,6 @@ struct lambdaspincorrderived { return; } } - - template - void fillSuccessfulTargetControlMap(int tag1, int tag2, int leg, LV const& targetParticle, float weight) - { - if (!fillReplacementQAHistos) { - return; - } - const double pt = targetParticle.Pt(); - const double phi = RecoDecay::constrainAngle(targetParticle.Phi(), 0.0F, harmonic); - const double etaOrY = userapidity ? targetParticle.Rapidity() : targetParticle.Eta(); - - if (leg == 1) { - if (tag1 == 0 && tag2 == 0) - histos.fill(HIST("SUC_TGT_LL_leg1"), phi, etaOrY, pt, weight); - else if (tag1 == 0 && tag2 == 1) - histos.fill(HIST("SUC_TGT_LAL_leg1"), phi, etaOrY, pt, weight); - else if (tag1 == 1 && tag2 == 0) - histos.fill(HIST("SUC_TGT_ALL_leg1"), phi, etaOrY, pt, weight); - else if (tag1 == 1 && tag2 == 1) - histos.fill(HIST("SUC_TGT_ALAL_leg1"), phi, etaOrY, pt, weight); - return; - } - - if (leg == 2) { - if (tag1 == 0 && tag2 == 0) - histos.fill(HIST("SUC_TGT_LL_leg2"), phi, etaOrY, pt, weight); - else if (tag1 == 0 && tag2 == 1) - histos.fill(HIST("SUC_TGT_LAL_leg2"), phi, etaOrY, pt, weight); - else if (tag1 == 1 && tag2 == 0) - histos.fill(HIST("SUC_TGT_ALL_leg2"), phi, etaOrY, pt, weight); - else if (tag1 == 1 && tag2 == 1) - histos.fill(HIST("SUC_TGT_ALAL_leg2"), phi, etaOrY, pt, weight); - } - } - template void fillFixedLegControlMap(int tag1, int tag2, int repLeg, @@ -2165,7 +1877,7 @@ struct lambdaspincorrderived { LV const& fixedParticle, float weight) { - if (!fillFixedLegQAHistos) { + if (!fillHistConfig.fillFixedLegQAHistos) { return; } const double pt = fixedParticle.Pt(); @@ -2243,6 +1955,15 @@ struct lambdaspincorrderived { auto poolA = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); + // if pool empty, push and continue + if (eventPools[bin].empty()) { + eventPools[bin].emplace_back(collision1.index(), std::move(poolA)); + if ((int)eventPools[bin].size() > nEvtMixing) { + eventPools[bin].pop_front(); + } + continue; + } + for (const auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(poolA, poolA))) { if (!selectionV0(t1) || !selectionV0(t2)) { continue; @@ -2307,12 +2028,9 @@ struct lambdaspincorrderived { } if (totalRepl <= 0) { - fillSEReplacementOutcome(t1, t2, false); continue; } - fillSEReplacementOutcome(t1, t2, true); - const float wBase = 1.0f / static_cast(totalRepl); // Single-track replacement target must use the same branch normalization @@ -2348,9 +2066,6 @@ struct lambdaspincorrderived { // -------- leg-1 replacement: (tX, t2) if (doMixLeg1) { if (tX.v0Status() == t1.v0Status() && checkKinematics(t1, tX)) { - fillSuccessfulTargetControlMap(t1.v0Status(), t2.v0Status(), 1, - ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), - wBase); fillReplacementControlMap(tX.v0Status(), t2.v0Status(), 1, false, ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()), wBase); @@ -2368,7 +2083,7 @@ struct lambdaspincorrderived { RecoDecay::constrainAngle(lambda2.Phi(), 0.0F, harmonic), -TMath::Pi(), harmonicDphi); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, wBase); fillHistograms(tX.v0Status(), t2.v0Status(), lambda, lambda2, proton, proton2, @@ -2379,9 +2094,6 @@ struct lambdaspincorrderived { // -------- leg-2 replacement: (t1, tX) if (doMixLeg2) { if (tX.v0Status() == t2.v0Status() && checkKinematics(t2, tX)) { - fillSuccessfulTargetControlMap(t1.v0Status(), t2.v0Status(), 2, - ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), - wBase); fillReplacementControlMap(t1.v0Status(), tX.v0Status(), 2, false, ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()), wBase); @@ -2399,7 +2111,7 @@ struct lambdaspincorrderived { RecoDecay::constrainAngle(lambda2.Phi(), 0.0F, harmonic), -TMath::Pi(), harmonicDphi); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, wBase); fillHistograms(t1.v0Status(), tX.v0Status(), lambda, lambda2, proton, proton2, @@ -2600,14 +2312,6 @@ struct lambdaspincorrderived { int replacedLeg = 1; int age = 0; uint64_t seed = 0; - uint64_t outcomeId = 0; - }; - - struct PendingSEReplacementOutcome { - StoredV6Candidate first; - StoredV6Candidate second; - int remainingBranches = 0; - bool replacementFound = false; }; template @@ -2620,23 +2324,21 @@ struct lambdaspincorrderived { static_cast(t.protonIndex()), static_cast(t.pionIndex())}; } - template - void fillV6MixedBranch(TRep const& replacement, TTarget const& target, TFixed const& fixed, int replacedLeg, float controlWeight, float mixWeight) + template + void fillV6MixedBranch(TRep const& replacement, TFixed const& fixed, int replacedLeg, float controlWeight, float mixWeight) { const auto repProton = ROOT::Math::PtEtaPhiMVector(replacement.protonPt(), replacement.protonEta(), replacement.protonPhi(), o2::constants::physics::MassProton); const auto repLambda = ROOT::Math::PtEtaPhiMVector(replacement.lambdaPt(), replacement.lambdaEta(), replacement.lambdaPhi(), replacement.lambdaMass()); const auto fixedProton = ROOT::Math::PtEtaPhiMVector(fixed.protonPt(), fixed.protonEta(), fixed.protonPhi(), o2::constants::physics::MassProton); const auto fixedLambda = ROOT::Math::PtEtaPhiMVector(fixed.lambdaPt(), fixed.lambdaEta(), fixed.lambdaPhi(), fixed.lambdaMass()); - const auto targetLambda = ROOT::Math::PtEtaPhiMVector(target.lambdaPt(), target.lambdaEta(), target.lambdaPhi(), target.lambdaMass()); const int repStatus = replacement.v0Status(); const int fixedStatus = fixed.v0Status(); if (replacedLeg == 1) { - fillSuccessfulTargetControlMap(target.v0Status(), fixedStatus, 1, targetLambda, controlWeight); fillReplacementControlMap(repStatus, fixedStatus, 1, false, repLambda, controlWeight); fillFixedLegControlMap(repStatus, fixedStatus, 1, false, fixedLambda, controlWeight); if ((repStatus == 0 && fixedStatus == 1) || (repStatus == 1 && fixedStatus == 0)) { - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("deltaPhiMix"), deltaPhiMinusPiToPi((float)repLambda.Phi(), (float)fixedLambda.Phi()), mixWeight); } } @@ -2650,10 +2352,9 @@ struct lambdaspincorrderived { return; } - fillSuccessfulTargetControlMap(fixedStatus, target.v0Status(), 2, targetLambda, controlWeight); fillReplacementControlMap(fixedStatus, repStatus, 2, false, repLambda, controlWeight); fillFixedLegControlMap(fixedStatus, repStatus, 2, false, fixedLambda, controlWeight); - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("deltaPhiMix"), deltaPhiMinusPiToPi((float)fixedLambda.Phi(), (float)repLambda.Phi()), mixWeight); } if (fixedStatus == 0 && repStatus == 1) { @@ -2715,38 +2416,10 @@ struct lambdaspincorrderived { struct V6PendingState { std::deque data; std::deque mc; - std::unordered_map dataOutcomes; - uint64_t nextOutcomeId = 1; }; V6PendingState v6Pending; - void finalizePendingSEReplacementOutcome(uint64_t outcomeId, bool replacementFound) - { - if (outcomeId == 0) { - return; - } - auto outcomeIt = v6Pending.dataOutcomes.find(outcomeId); - if (outcomeIt == v6Pending.dataOutcomes.end()) { - return; - } - - auto& outcome = outcomeIt->second; - if (replacementFound && !outcome.replacementFound) { - fillSEReplacementOutcome(outcome.first, outcome.second, true); - outcome.replacementFound = true; - } - - --outcome.remainingBranches; - if (outcome.remainingBranches > 0) { - return; - } - if (!outcome.replacementFound) { - fillSEReplacementOutcome(outcome.first, outcome.second, false); - } - v6Pending.dataOutcomes.erase(outcomeIt); - } - template StoredV6CandidateMC storeV6CandidateMC(T const& t) const { @@ -2757,22 +2430,20 @@ struct lambdaspincorrderived { static_cast(mcacc::prIdx(t)), static_cast(mcacc::piIdx(t))}; } - template - void fillV6MixedBranchMC(TRep const& replacement, TTarget const& target, TFixed const& fixed, int replacedLeg, float controlWeight, float mixWeight) + template + void fillV6MixedBranchMC(TRep const& replacement, TFixed const& fixed, int replacedLeg, float controlWeight, float mixWeight) { const auto repProton = ROOT::Math::PtEtaPhiMVector(mcacc::prPt(replacement), mcacc::prEta(replacement), mcacc::prPhi(replacement), o2::constants::physics::MassProton); const auto repLambda = ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(replacement), mcacc::lamEta(replacement), mcacc::lamPhi(replacement), mcacc::lamMass(replacement)); const auto fixedProton = ROOT::Math::PtEtaPhiMVector(mcacc::prPt(fixed), mcacc::prEta(fixed), mcacc::prPhi(fixed), o2::constants::physics::MassProton); const auto fixedLambda = ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(fixed), mcacc::lamEta(fixed), mcacc::lamPhi(fixed), mcacc::lamMass(fixed)); - const auto targetLambda = ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(target), mcacc::lamEta(target), mcacc::lamPhi(target), mcacc::lamMass(target)); const int repStatus = mcacc::v0Status(replacement); const int fixedStatus = mcacc::v0Status(fixed); if (replacedLeg == 1) { - fillSuccessfulTargetControlMap(mcacc::v0Status(target), fixedStatus, 1, targetLambda, controlWeight); fillReplacementControlMap(repStatus, fixedStatus, 1, false, repLambda, controlWeight); fillFixedLegControlMap(repStatus, fixedStatus, 1, false, fixedLambda, controlWeight); - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("deltaPhiMix"), deltaPhiMinusPiToPi((float)repLambda.Phi(), (float)fixedLambda.Phi()), mixWeight); } if (repStatus == 0 && fixedStatus == 1) { @@ -2785,10 +2456,9 @@ struct lambdaspincorrderived { return; } - fillSuccessfulTargetControlMap(fixedStatus, mcacc::v0Status(target), 2, targetLambda, controlWeight); fillReplacementControlMap(fixedStatus, repStatus, 2, false, repLambda, controlWeight); fillFixedLegControlMap(fixedStatus, repStatus, 2, false, fixedLambda, controlWeight); - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("deltaPhiMix"), deltaPhiMinusPiToPi((float)fixedLambda.Phi(), (float)repLambda.Phi()), mixWeight); } if (fixedStatus == 0 && repStatus == 1) { @@ -2826,7 +2496,7 @@ struct lambdaspincorrderived { if (mcacc::v0CosPA(candidate) < v0Configurations.cosPA) { return false; } - if (checkDoubleStatus && mcacc::doubleStatus(candidate)) { + if (fillHistConfig.checkDoubleStatus && mcacc::doubleStatus(candidate)) { return false; } if (mcacc::v0Radius(candidate) > v0Configurations.radiusMax) { @@ -2923,13 +2593,13 @@ struct lambdaspincorrderived { if (!selectionV0MC(v0)) { continue; } - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("hPtRadiusV0"), mcacc::lamPt(v0), mcacc::v0Radius(v0)); } - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("ptCent"), mcacc::lamPt(v0), centrality); } - if (fillBasicQAHistos) { + if (fillHistConfig.fillBasicQAHistos) { histos.fill(HIST("etaCent"), mcacc::lamEta(v0), centrality); } @@ -3104,7 +2774,7 @@ struct lambdaspincorrderived { ptMin.value, ptMax.value, ptMix.value, - v0etaMixBuffer.value, + v0Configurations.v0etaMixBuffer.value, etaMix.value, phiMix.value, MassMin.value, @@ -3331,13 +3001,11 @@ struct lambdaspincorrderived { size_t pendingAdded = 0; if (!cfgV6CarryUnmatched) { v6Pending.data.clear(); - v6Pending.dataOutcomes.clear(); } else { for (auto it = v6Pending.data.begin(); it != v6Pending.data.end();) { auto& pending = *it; ++pending.age; if (cfgV6MaxPendingAge.value > 0 && pending.age > cfgV6MaxPendingAge.value) { - finalizePendingSEReplacementOutcome(pending.outcomeId, false); ++pendingExpired; it = v6Pending.data.erase(it); continue; @@ -3382,10 +3050,9 @@ struct lambdaspincorrderived { if (hasSharedDaughters(replacement, pending.target) || hasSharedDaughters(replacement, pending.fixed)) { continue; } - fillV6MixedBranch(replacement, pending.target, pending.fixed, pending.replacedLeg, controlWeight, mixWeight); + fillV6MixedBranch(replacement, pending.fixed, pending.replacedLeg, controlWeight, mixWeight); } ++pendingMatched; - finalizePendingSEReplacementOutcome(pending.outcomeId, true); it = v6Pending.data.erase(it); } } @@ -3496,50 +3163,23 @@ struct lambdaspincorrderived { } } - const bool replacementFoundNow = nFill1 > 0 || nFill2 > 0; - std::vector branchesToCarry; - branchesToCarry.reserve(2); if (cfgV6CarryUnmatched) { const auto hasPendingSpace = [&]() { - return cfgV6MaxPendingBranches.value <= 0 || - static_cast(v6Pending.data.size() + branchesToCarry.size()) < cfgV6MaxPendingBranches.value; + return cfgV6MaxPendingBranches.value <= 0 || static_cast(v6Pending.data.size()) < cfgV6MaxPendingBranches.value; }; if (doMixLeg1 && nFill1 == 0 && hasPendingSpace()) { - branchesToCarry.push_back({storeV6Candidate(t1, curColIdx), storeV6Candidate(t2, curColIdx), colBin, 1, 0, - static_cast(t1.globalIndex()) ^ splitmix64(static_cast(t2.globalIndex())) ^ splitmix64(static_cast(curColIdx)), 0}); + v6Pending.data.push_back({storeV6Candidate(t1, curColIdx), storeV6Candidate(t2, curColIdx), colBin, 1, 0, + static_cast(t1.globalIndex()) ^ splitmix64(static_cast(t2.globalIndex())) ^ splitmix64(static_cast(curColIdx))}); + ++pendingAdded; } if (doMixLeg2 && nFill2 == 0 && hasPendingSpace()) { - branchesToCarry.push_back({storeV6Candidate(t2, curColIdx), storeV6Candidate(t1, curColIdx), colBin, 2, 0, - static_cast(t2.globalIndex()) ^ splitmix64(static_cast(t1.globalIndex())) ^ splitmix64(static_cast(curColIdx)), 0}); - } - } - - if (replacementFoundNow) { - fillSEReplacementOutcome(t1, t2, true); - } else if (branchesToCarry.empty()) { - // No accepted replacement exists and there is no pending branch that - // could still find one in a later data frame. - fillSEReplacementOutcome(t1, t2, false); - } else { - uint64_t outcomeId = v6Pending.nextOutcomeId++; - if (outcomeId == 0) { - outcomeId = v6Pending.nextOutcomeId++; - } - v6Pending.dataOutcomes.emplace( - outcomeId, - PendingSEReplacementOutcome{storeV6Candidate(t1, curColIdx), storeV6Candidate(t2, curColIdx), - static_cast(branchesToCarry.size()), false}); - for (auto& branch : branchesToCarry) { - branch.outcomeId = outcomeId; + v6Pending.data.push_back({storeV6Candidate(t2, curColIdx), storeV6Candidate(t1, curColIdx), colBin, 2, 0, + static_cast(t2.globalIndex()) ^ splitmix64(static_cast(t1.globalIndex())) ^ splitmix64(static_cast(curColIdx))}); + ++pendingAdded; } } - for (auto& branch : branchesToCarry) { - v6Pending.data.push_back(std::move(branch)); - ++pendingAdded; - } - - if (!replacementFoundNow) { + if (nFill1 <= 0 && nFill2 <= 0) { continue; } // Residual-weight QA needs a leg-specific normalization: @@ -3579,9 +3219,6 @@ struct lambdaspincorrderived { continue; if (hasSharedDaughters(tX, t2)) continue; - fillSuccessfulTargetControlMap(t1.v0Status(), t2.v0Status(), 1, - ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), - wSELeg1); fillReplacementControlMap(tX.v0Status(), t2.v0Status(), 1, false, ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()), wSELeg1); @@ -3600,7 +3237,7 @@ struct lambdaspincorrderived { const float meWeight = finalMixWeightLeg1; const float dPhi = deltaPhiMinusPiToPi((float)lambda.Phi(), (float)lambda2.Phi()); if ((tX.v0Status() == 0 && t2.v0Status() == 1) || (tX.v0Status() == 1 && t2.v0Status() == 0)) - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = tX.v0Status(); const int s2 = t2.v0Status(); @@ -3633,9 +3270,6 @@ struct lambdaspincorrderived { continue; if (hasSharedDaughters(tY, t2)) continue; - fillSuccessfulTargetControlMap(t1.v0Status(), t2.v0Status(), 2, - ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), - wSELeg2); fillReplacementControlMap(t1.v0Status(), tY.v0Status(), 2, false, ROOT::Math::PtEtaPhiMVector(tY.lambdaPt(), tY.lambdaEta(), tY.lambdaPhi(), tY.lambdaMass()), wSELeg2); @@ -3652,7 +3286,7 @@ struct lambdaspincorrderived { // const int ptype = pairTypeCode(t1.v0Status(), tY.v0Status()); const float meWeight = finalMixWeightLeg2; const float dPhi = deltaPhiMinusPiToPi((float)lambda.Phi(), (float)lambda2.Phi()); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = t1.v0Status(); const int s2 = tY.v0Status(); @@ -3680,7 +3314,7 @@ struct lambdaspincorrderived { ptMin.value, ptMax.value, ptMix.value, - v0etaMixBuffer.value, + v0Configurations.v0etaMixBuffer.value, etaMix.value, phiMix.value, MassMin.value, @@ -3979,7 +3613,7 @@ struct lambdaspincorrderived { if (hasSharedDaughters(replacement, pending.target) || hasSharedDaughters(replacement, pending.fixed)) { continue; } - fillV6MixedBranch(replacement, pending.target, pending.fixed, pending.replacedLeg, controlWeight, mixWeight); + fillV6MixedBranch(replacement, pending.fixed, pending.replacedLeg, controlWeight, mixWeight); } ++pendingMatched; it = v6Pending.data.erase(it); @@ -4160,9 +3794,6 @@ struct lambdaspincorrderived { if (hasSharedDaughters(tX, t2)) continue; - fillSuccessfulTargetControlMap(t1.v0Status(), t2.v0Status(), 1, - ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), - wSELeg1); fillReplacementControlMap(tX.v0Status(), t2.v0Status(), 1, false, ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()), wSELeg1); @@ -4178,7 +3809,7 @@ struct lambdaspincorrderived { const float meWeight = finalMixWeightLeg1; const float dPhi = deltaPhiMinusPiToPi((float)lambda.Phi(), (float)lambda2.Phi()); if ((tX.v0Status() == 0 && t2.v0Status() == 1) || (tX.v0Status() == 1 && t2.v0Status() == 0)) - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = tX.v0Status(); @@ -4216,9 +3847,6 @@ struct lambdaspincorrderived { if (hasSharedDaughters(tY, t2)) continue; - fillSuccessfulTargetControlMap(t1.v0Status(), t2.v0Status(), 2, - ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), - wSELeg2); fillReplacementControlMap(t1.v0Status(), tY.v0Status(), 2, false, ROOT::Math::PtEtaPhiMVector(tY.lambdaPt(), tY.lambdaEta(), tY.lambdaPhi(), tY.lambdaMass()), wSELeg2); @@ -4233,7 +3861,7 @@ struct lambdaspincorrderived { const float meWeight = finalMixWeightLeg2; const float dPhi = deltaPhiMinusPiToPi((float)lambda.Phi(), (float)lambda2.Phi()); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = t1.v0Status(); @@ -4267,7 +3895,7 @@ struct lambdaspincorrderived { ptMin.value, ptMax.value, ptMix.value, - v0etaMixBuffer.value, + v0Configurations.v0etaMixBuffer.value, etaMix.value, phiMix.value, MassMin.value, @@ -4549,7 +4177,7 @@ struct lambdaspincorrderived { if (hasSharedDaughtersMC(replacement, pending.target) || hasSharedDaughtersMC(replacement, pending.fixed)) { continue; } - fillV6MixedBranchMC(replacement, pending.target, pending.fixed, pending.replacedLeg, controlWeight, mixWeight); + fillV6MixedBranchMC(replacement, pending.fixed, pending.replacedLeg, controlWeight, mixWeight); } ++pendingMatchedMC; it = v6Pending.mc.erase(it); @@ -4713,9 +4341,6 @@ struct lambdaspincorrderived { continue; if (hasSharedDaughtersMC(tX, t2)) continue; - fillSuccessfulTargetControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 1, - ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t1), mcacc::lamEta(t1), mcacc::lamPhi(t1), mcacc::lamMass(t1)), - wSELeg1); fillReplacementControlMap(mcacc::v0Status(tX), mcacc::v0Status(t2), 1, false, ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(tX), mcacc::lamEta(tX), mcacc::lamPhi(tX), mcacc::lamMass(tX)), wSELeg1); @@ -4739,7 +4364,7 @@ struct lambdaspincorrderived { // const int ptype = pairTypeCode(mcacc::v0Status(tX), mcacc::v0Status(t2)); const float meWeight = finalMixWeightLeg1; const float dPhi = deltaPhiMinusPiToPi((float)lX.Phi(), (float)l2.Phi()); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = mcacc::v0Status(tX); const int s2 = mcacc::v0Status(t2); @@ -4771,9 +4396,6 @@ struct lambdaspincorrderived { continue; if (hasSharedDaughtersMC(tY, t2)) continue; - fillSuccessfulTargetControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 2, - ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t2), mcacc::lamEta(t2), mcacc::lamPhi(t2), mcacc::lamMass(t2)), - wSELeg2); fillReplacementControlMap(mcacc::v0Status(t1), mcacc::v0Status(tY), 2, false, ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(tY), mcacc::lamEta(tY), mcacc::lamPhi(tY), mcacc::lamMass(tY)), wSELeg2); @@ -4797,7 +4419,7 @@ struct lambdaspincorrderived { // const int ptype = pairTypeCode(mcacc::v0Status(t1), mcacc::v0Status(tY)); const float meWeight = finalMixWeightLeg2; const float dPhi = deltaPhiMinusPiToPi((float)l1.Phi(), (float)lY.Phi()); - if (fillBasicQAHistos) + if (fillHistConfig.fillBasicQAHistos) histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = mcacc::v0Status(t1); const int s2 = mcacc::v0Status(tY); @@ -4825,13 +4447,6 @@ struct lambdaspincorrderived { if (cfgV6LogPending) { LOGF(info, "MEV6 end of stream: unmatchedData=%zu unmatchedMC=%zu", v6Pending.data.size(), v6Pending.mc.size()); } - for (auto& [outcomeId, outcome] : v6Pending.dataOutcomes) { - static_cast(outcomeId); - if (!outcome.replacementFound) { - fillSEReplacementOutcome(outcome.first, outcome.second, false); - } - } - v6Pending.dataOutcomes.clear(); v6Pending.data.clear(); v6Pending.mc.clear(); }