From 7db7698f9f3b40d56c48c6c3961c8a9d126d970d Mon Sep 17 00:00:00 2001 From: Alicja Plachta Date: Thu, 5 Feb 2026 21:37:39 +0100 Subject: [PATCH] Updates in V0 task: debug histograms, daughter pT cuts, optional mass cut --- .../femtoUniversePairTaskTrackV0Extended.cxx | 222 ++++++++++++++++-- 1 file changed, 207 insertions(+), 15 deletions(-) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index 8879f088f7c..0be6caeba2a 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -109,6 +109,12 @@ struct FemtoUniversePairTaskTrackV0Extended { Configurable confHPtPart2{"confHPtPart2", 4.0f, "higher limit for pt of particle 2"}; Configurable confLPtPart2{"confLPtPart2", 0.3f, "lower limit for pt of particle 2"}; Configurable confUseStrangenessTOF{"confUseStrangenessTOF", true, "Use strangeness TOF for cascade PID"}; + Configurable confHPtChildProton{"confHPtChildProton", 10.0f, "Higher limit for pt of children protons/antiprotons"}; + Configurable confLPtChildProton{"confLPtChildProton", 0.f, "Lower limit for pt of children protons/antiprotons"}; + Configurable confHPtChildPion{"confHPtChildPion", 10.0f, "Higher limit for pt of children pions"}; + Configurable confLPtChildPion{"confLPtChildPion", 0.f, "Lower limit for pt of children pions"}; + Configurable confV0DuplCosPA{"confV0DuplCosPA", false, "Use cosPA instead of inv. mass as a deciding factor in rejecting a V0 in V0V0 pairs"}; + Configurable confAddInvMassCheck{"confAddInvMassCheck", false, "Apply additional cut separate for mLambda and mAntiLambda"}; } ConfV0Selection; /// Partition for particle 2 using extended table @@ -139,6 +145,7 @@ struct FemtoUniversePairTaskTrackV0Extended { /// Correlation part // Configurable confTrackChoicePartTwo{"confTrackChoicePartTwo", 1, "0:Proton, 1:Pion, 2:Kaon"}; //not used Configurable confIsMC{"confIsMC", false, "Enable additional Histograms in the case of a MonteCarlo Run"}; + Configurable confIsDebug{"confIsDebug", false, "Enable additional histograms (e.g. three-momentum)"}; Configurable confUse3D{"confUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; Configurable confUseCent{"confUseCent", false, "Use centrality in place of multiplicity"}; ConfigurableAxis confMultBins{"confMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; @@ -271,6 +278,21 @@ struct FemtoUniversePairTaskTrackV0Extended { qaRegistry.add("V0Type2/hInvMassLambdaVsCent", "; Centrality; M_{#Lambda}; Entries", kTH2F, {confMultBins, {2000, 1.f, 3.f}}); qaRegistry.add("V0Type1/hInvMassAntiLambdaVsCent", "; Centrality; M_{#Lambda}; Entries", kTH2F, {confMultBins, {2000, 1.f, 3.f}}); qaRegistry.add("V0Type2/hInvMassAntiLambdaVsCent", "; Centrality; M_{#Lambda}; Entries", kTH2F, {confMultBins, {2000, 1.f, 3.f}}); + + if (confIsDebug && doprocessSameEventV0) { + qaRegistry.add("SameEvent/hPtPosDaugh", "; #it{p}_{T}^{1} (GeV/c); #it{p}_{T}^{2} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + qaRegistry.add("SameEvent/hPtNegDaugh", "; #it{p}_{T}^{1} (GeV/c); #it{p}_{T}^{2} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + qaRegistry.add("SameEvent/hDaughMomPart1", "; #it{p}_{T}^{+} (GeV/c); #it{p}_{T}^{-} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + qaRegistry.add("SameEvent/hDaughMomPart2", "; #it{p}_{T}^{+} (GeV/c); #it{p}_{T}^{-} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + } + + if (confIsDebug && doprocessMixedEventV0) { + qaRegistry.add("MixedEvent/hPtPosDaugh", "; #it{p}_{T}^{1} (GeV/c); #it{p}_{T}^{2} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + qaRegistry.add("MixedEvent/hPtNegDaugh", "; #it{p}_{T}^{1} (GeV/c); #it{p}_{T}^{2} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + qaRegistry.add("MixedEvent/hDaughMomPart1", "; #it{p}_{T}^{+} (GeV/c); #it{p}_{T}^{-} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + qaRegistry.add("MixedEvent/hDaughMomPart2", "; #it{p}_{T}^{+} (GeV/c); #it{p}_{T}^{-} (GeV/c)", kTH2F, {{500, 0, 5}, {500, 0, 5}}); + } + trackHistoV0Type1.init(&qaRegistry, ConfV0Selection.confV0TempFitVarpTBins, ConfV0Selection.confV0TempFitVarBins, confIsMC, ConfV0Selection.confV0PDGCodePartTwo, true, "V0Type1"); posChildV0Type1.init(&qaRegistry, ConfV0Selection.confChildTempFitVarpTBins, ConfV0Selection.confChildTempFitVarBins, false, 0, true, "posChildV0Type1"); negChildV0Type1.init(&qaRegistry, ConfV0Selection.confChildTempFitVarpTBins, ConfV0Selection.confChildTempFitVarBins, false, 0, true, "negChildV0Type1"); @@ -374,12 +396,27 @@ struct FemtoUniversePairTaskTrackV0Extended { eventHisto.fillQA(col); + float v0DaughPtLowTable[3][2] = {{ConfV0Selection.confLPtChildProton, ConfV0Selection.confLPtChildPion}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildProton}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildPion}}; + float v0DaughPtHighTable[3][2] = {{ConfV0Selection.confHPtChildProton, ConfV0Selection.confHPtChildPion}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildProton}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildPion}}; + /// Histogramming same event for (const auto& part : groupPartsTwo) { if (!invMLambda(part.mLambda(), part.mAntiLambda())) continue; const auto& posChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); + + if (posChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + continue; + } + + if (ConfV0Selection.confAddInvMassCheck) { + const float pMass = ConfV0Selection.confV0Type1 ? part.mAntiLambda() : part.mLambda(); + if (pMass < ConfV0Selection.confV0InvMassLowLimit || pMass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } + /// Daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { if (!isParticleTPC(posChild, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTPC(negChild, V0ChildTable[ConfV0Selection.confV0Type1][1])) @@ -403,7 +440,6 @@ struct FemtoUniversePairTaskTrackV0Extended { if ((posChild.pidCut() & (8u << V0ChildTable[ConfV0Selection.confV0Type1][0])) == 0 || (negChild.pidCut() & (8u << V0ChildTable[ConfV0Selection.confV0Type1][1])) == 0) continue; } - trackHistoPartTwo.fillQA(part); posChildHistos.fillQA(posChild); negChildHistos.fillQA(negChild); @@ -454,13 +490,12 @@ struct FemtoUniversePairTaskTrackV0Extended { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - if (confIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { - continue; - } - } + const auto& posChild = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + continue; + } /// Daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { @@ -483,6 +518,19 @@ struct FemtoUniversePairTaskTrackV0Extended { } } + if (ConfV0Selection.confAddInvMassCheck) { + const float pMass = ConfV0Selection.confV0Type1 ? p2.mAntiLambda() : p2.mLambda(); + if (pMass < ConfV0Selection.confV0InvMassLowLimit || pMass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } + + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { + continue; + } + } + float weight = 1.0f; if (plocalEffp1) weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(p1.pt(), p1.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(p2.pt(), p2.eta())); @@ -503,12 +551,18 @@ struct FemtoUniversePairTaskTrackV0Extended { eventHisto.fillQA(col); + float v0DaughPtLowTable[3][2] = {{ConfV0Selection.confLPtChildProton, ConfV0Selection.confLPtChildPion}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildProton}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildPion}}; + float v0DaughPtHighTable[3][2] = {{ConfV0Selection.confHPtChildProton, ConfV0Selection.confHPtChildPion}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildProton}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildPion}}; + /// Histogramming same event for first V0 particle for (const auto& part : groupPartsTwo) { if (!invMLambda(part.mLambda(), part.mAntiLambda())) continue; const auto& posChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + continue; + } /// Check daughters of first V0 particle if constexpr (std::experimental::is_detected::value) { @@ -516,6 +570,13 @@ struct FemtoUniversePairTaskTrackV0Extended { continue; if (!isParticleTOF(posChild, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTOF(negChild, V0ChildTable[ConfV0Selection.confV0Type1][1])) continue; + + if (ConfV0Selection.confAddInvMassCheck) { + const float pMass = ConfV0Selection.confV0Type1 ? part.mAntiLambda() : part.mLambda(); + if (pMass < ConfV0Selection.confV0InvMassLowLimit || pMass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } trackHistoV0Type1.fillQABase(part, HIST("V0Type1")); posChildV0Type1.fillQABase(posChild, HIST("posChildV0Type1")); negChildV0Type1.fillQABase(negChild, HIST("negChildV0Type1")); @@ -546,12 +607,23 @@ struct FemtoUniversePairTaskTrackV0Extended { continue; const auto& posChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][0] || negChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][1] || posChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][0] || negChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][1]) { + continue; + } + /// Check daughters of second V0 particle if constexpr (std::experimental::is_detected::value) { if (!isParticleTPC(posChild, V0ChildTable[ConfV0Selection.confV0Type2][0]) || !isParticleTPC(negChild, V0ChildTable[ConfV0Selection.confV0Type2][1])) continue; if (!isParticleTOF(posChild, V0ChildTable[ConfV0Selection.confV0Type2][0]) || !isParticleTOF(negChild, V0ChildTable[ConfV0Selection.confV0Type2][1])) continue; + + if (ConfV0Selection.confAddInvMassCheck) { + const float pMass = ConfV0Selection.confV0Type2 ? part.mAntiLambda() : part.mLambda(); + if (pMass < ConfV0Selection.confV0InvMassLowLimit || pMass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } trackHistoV0Type2.fillQABase(part, HIST("V0Type2")); posChildV0Type2.fillQABase(posChild, HIST("posChildV0Type2")); negChildV0Type2.fillQABase(negChild, HIST("negChildV0Type2")); @@ -583,13 +655,30 @@ struct FemtoUniversePairTaskTrackV0Extended { // V0 inv mass cut for p2 if (!invMLambda(p2.mLambda(), p2.mAntiLambda())) return; + + if (ConfV0Selection.confAddInvMassCheck) { + const float p1Mass = ConfV0Selection.confV0Type1 ? p1.mAntiLambda() : p1.mLambda(); + const float p2Mass = ConfV0Selection.confV0Type2 ? p2.mAntiLambda() : p2.mLambda(); + if (p1Mass < ConfV0Selection.confV0InvMassLowLimit || p1Mass > ConfV0Selection.confV0InvMassUpLimit || p2Mass < ConfV0Selection.confV0InvMassLowLimit || p2Mass > ConfV0Selection.confV0InvMassUpLimit) { + return; + } + } + // track cleaning & checking for duplicate pairs if (!pairCleanerV0.isCleanPair(p1, p2, parts)) { // mark for rejection the cascade that shares a daughter with another cascade and has an invariant mass further from default value - if (std::abs(p1.mLambda() - v0InvMass[ConfV0Selection.confV0Type1]) < std::abs(p2.mLambda() - v0InvMass[ConfV0Selection.confV0Type2])) { - v0Duplicates.insert(p2.globalIndex()); + if (!ConfV0Selection.confV0DuplCosPA) { + if (std::abs(p1.mLambda() - v0InvMass[ConfV0Selection.confV0Type1]) < std::abs(p2.mLambda() - v0InvMass[ConfV0Selection.confV0Type2])) { + v0Duplicates.insert(p2.globalIndex()); + } else { + v0Duplicates.insert(p1.globalIndex()); + } } else { - v0Duplicates.insert(p1.globalIndex()); + if (std::abs(p1.tempFitVar() - 1) < std::abs(p2.tempFitVar() - 1)) { + v0Duplicates.insert(p2.globalIndex()); + } else { + v0Duplicates.insert(p1.globalIndex()); + } } } }; @@ -606,6 +695,10 @@ struct FemtoUniversePairTaskTrackV0Extended { const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild1.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild1.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild1.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild1.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + return false; + } + /// p1 daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { if (!isParticleTPC(posChild1, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTPC(negChild1, V0ChildTable[ConfV0Selection.confV0Type1][1])) @@ -626,6 +719,10 @@ struct FemtoUniversePairTaskTrackV0Extended { const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild2.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][0] || negChild2.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][1] || posChild2.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][0] || negChild2.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][1]) { + return false; + } + /// p2 daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { if (!isParticleTPC(posChild2, V0ChildTable[ConfV0Selection.confV0Type2][0]) || !isParticleTPC(negChild2, V0ChildTable[ConfV0Selection.confV0Type2][1])) @@ -644,6 +741,14 @@ struct FemtoUniversePairTaskTrackV0Extended { } } + if (ConfV0Selection.confAddInvMassCheck) { + const float p1Mass = ConfV0Selection.confV0Type1 ? p1.mAntiLambda() : p1.mLambda(); + const float p2Mass = ConfV0Selection.confV0Type2 ? p2.mAntiLambda() : p2.mLambda(); + if (p1Mass < ConfV0Selection.confV0InvMassLowLimit || p1Mass > ConfV0Selection.confV0InvMassUpLimit || p2Mass < ConfV0Selection.confV0InvMassLowLimit || p2Mass > ConfV0Selection.confV0InvMassUpLimit) { + return false; + } + } + if (confIsCPR.value) { if (confRectV0V0CPR && pairCloseRejectionV0.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { return false; @@ -652,6 +757,13 @@ struct FemtoUniversePairTaskTrackV0Extended { } } + if (confIsDebug && doprocessSameEventV0) { + qaRegistry.fill(HIST("SameEvent/hPtPosDaugh"), posChild1.pt(), posChild2.pt()); + qaRegistry.fill(HIST("SameEvent/hPtNegDaugh"), negChild1.pt(), negChild2.pt()); + qaRegistry.fill(HIST("SameEvent/hDaughMomPart1"), posChild1.pt(), negChild1.pt()); + qaRegistry.fill(HIST("SameEvent/hDaughMomPart2"), posChild2.pt(), negChild2.pt()); + } + if constexpr (std::is_same::value) sameEventCont.setPair(p1, p2, multCol, confUse3D); else @@ -827,6 +939,9 @@ struct FemtoUniversePairTaskTrackV0Extended { ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + float v0DaughPtLowTable[3][2] = {{ConfV0Selection.confLPtChildProton, ConfV0Selection.confLPtChildPion}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildProton}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildPion}}; + float v0DaughPtHighTable[3][2] = {{ConfV0Selection.confHPtChildProton, ConfV0Selection.confHPtChildPion}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildProton}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildPion}}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); @@ -855,6 +970,10 @@ struct FemtoUniversePairTaskTrackV0Extended { const auto& posChild = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + continue; + } + /// Daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { if (!isParticleTPC(posChild, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTPC(negChild, V0ChildTable[ConfV0Selection.confV0Type1][1])) @@ -873,6 +992,13 @@ struct FemtoUniversePairTaskTrackV0Extended { } } + if (ConfV0Selection.confAddInvMassCheck) { + const float pMass = ConfV0Selection.confV0Type1 ? p2.mAntiLambda() : p2.mLambda(); + if (pMass < ConfV0Selection.confV0InvMassLowLimit || pMass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } + // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; @@ -913,6 +1039,9 @@ struct FemtoUniversePairTaskTrackV0Extended { ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + float v0DaughPtLowTable[3][2] = {{ConfV0Selection.confLPtChildProton, ConfV0Selection.confLPtChildPion}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildProton}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildPion}}; + float v0DaughPtHighTable[3][2] = {{ConfV0Selection.confHPtChildProton, ConfV0Selection.confHPtChildPion}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildProton}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildPion}}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); @@ -938,6 +1067,11 @@ struct FemtoUniversePairTaskTrackV0Extended { const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); + + if (posChild1.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild1.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild1.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild1.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + continue; + } + /// Daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { if (!isParticleTPC(posChild1, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTPC(negChild1, V0ChildTable[ConfV0Selection.confV0Type1][1])) @@ -958,6 +1092,10 @@ struct FemtoUniversePairTaskTrackV0Extended { const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild2.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][0] || negChild2.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][1] || posChild2.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][0] || negChild2.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][1]) { + continue; + } + /// Daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { if (!isParticleTPC(posChild2, V0ChildTable[ConfV0Selection.confV0Type2][0]) || !isParticleTPC(negChild2, V0ChildTable[ConfV0Selection.confV0Type2][1])) @@ -976,6 +1114,14 @@ struct FemtoUniversePairTaskTrackV0Extended { } } + if (ConfV0Selection.confAddInvMassCheck) { + const float p1Mass = ConfV0Selection.confV0Type1 ? p1.mAntiLambda() : p1.mLambda(); + const float p2Mass = ConfV0Selection.confV0Type2 ? p2.mAntiLambda() : p2.mLambda(); + if (p1Mass < ConfV0Selection.confV0InvMassLowLimit || p1Mass > ConfV0Selection.confV0InvMassUpLimit || p2Mass < ConfV0Selection.confV0InvMassLowLimit || p2Mass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } + // track cleaning if (!pairCleanerV0.isCleanPair(p1, p2, parts)) { continue; @@ -988,6 +1134,13 @@ struct FemtoUniversePairTaskTrackV0Extended { } } + if (confIsDebug && doprocessMixedEventV0) { + qaRegistry.fill(HIST("MixedEvent/hPtPosDaugh"), posChild1.pt(), posChild2.pt()); + qaRegistry.fill(HIST("MixedEvent/hPtNegDaugh"), negChild1.pt(), negChild2.pt()); + qaRegistry.fill(HIST("MixedEvent/hDaughMomPart1"), posChild1.pt(), negChild1.pt()); + qaRegistry.fill(HIST("MixedEvent/hDaughMomPart2"), posChild2.pt(), negChild2.pt()); + } + if constexpr (std::is_same::value) mixedEventCont.setPair(p1, p2, multCol, confUse3D); else @@ -1186,6 +1339,9 @@ struct FemtoUniversePairTaskTrackV0Extended { ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + float v0DaughPtLowTable[3][2] = {{ConfV0Selection.confLPtChildProton, ConfV0Selection.confLPtChildPion}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildProton}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildPion}}; + float v0DaughPtHighTable[3][2] = {{ConfV0Selection.confHPtChildProton, ConfV0Selection.confHPtChildPion}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildProton}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildPion}}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { auto groupPartsOne = partsOneMCRecoFull->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); auto groupPartsTwo = partsTwoMCRecoFull->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); @@ -1205,11 +1361,24 @@ struct FemtoUniversePairTaskTrackV0Extended { if (!isParticleCombined(p1, ConfTrkSelection.confTrackChoicePartOne)) continue; - const auto& posChild = parts.iteratorAt(p2.globalIndex() - 2); - const auto& negChild = parts.iteratorAt(p2.globalIndex() - 1); + const auto& posChild = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + continue; + } + /// Daughters that do not pass this condition are not selected if (!isParticleTPC(posChild, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTPC(negChild, V0ChildTable[ConfV0Selection.confV0Type1][1])) continue; + if (!isParticleTOF(posChild, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTOF(negChild, V0ChildTable[ConfV0Selection.confV0Type1][1])) + continue; + + if (ConfV0Selection.confAddInvMassCheck) { + const float pMass = ConfV0Selection.confV0Type1 ? p2.mAntiLambda() : p2.mLambda(); + if (pMass < ConfV0Selection.confV0InvMassLowLimit || pMass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { @@ -1247,6 +1416,9 @@ struct FemtoUniversePairTaskTrackV0Extended { ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + float v0DaughPtLowTable[3][2] = {{ConfV0Selection.confLPtChildProton, ConfV0Selection.confLPtChildPion}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildProton}, {ConfV0Selection.confLPtChildPion, ConfV0Selection.confLPtChildPion}}; + float v0DaughPtHighTable[3][2] = {{ConfV0Selection.confHPtChildProton, ConfV0Selection.confHPtChildPion}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildProton}, {ConfV0Selection.confHPtChildPion, ConfV0Selection.confHPtChildPion}}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { auto groupPartsOne = partsTwoMCRecoFull->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); auto groupPartsTwo = partsTwoMCRecoFull->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); @@ -1268,17 +1440,37 @@ struct FemtoUniversePairTaskTrackV0Extended { continue; } - const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2); - const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1); + const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild1.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][0] || negChild1.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type1][1] || posChild1.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][0] || negChild1.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type1][1]) { + continue; + } + /// Daughters that do not pass this condition are not selected if (!isParticleTPC(posChild1, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTPC(negChild1, V0ChildTable[ConfV0Selection.confV0Type1][1])) continue; + if (!isParticleTOF(posChild1, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTOF(negChild1, V0ChildTable[ConfV0Selection.confV0Type1][1])) + continue; + + const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + if (posChild2.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][0] || negChild2.pt() < v0DaughPtLowTable[ConfV0Selection.confV0Type2][1] || posChild2.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][0] || negChild2.pt() > v0DaughPtHighTable[ConfV0Selection.confV0Type2][1]) { + continue; + } - const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 2); - const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 1); /// Daughters that do not pass this condition are not selected if (!isParticleTPC(posChild2, V0ChildTable[ConfV0Selection.confV0Type2][0]) || !isParticleTPC(negChild2, V0ChildTable[ConfV0Selection.confV0Type2][1])) continue; + if (!isParticleTOF(negChild2, V0ChildTable[ConfV0Selection.confV0Type1][0]) || !isParticleTOF(negChild2, V0ChildTable[ConfV0Selection.confV0Type1][1])) + continue; + + if (ConfV0Selection.confAddInvMassCheck) { + const float p1Mass = ConfV0Selection.confV0Type1 ? p1.mAntiLambda() : p1.mLambda(); + const float p2Mass = ConfV0Selection.confV0Type2 ? p2.mAntiLambda() : p2.mLambda(); + if (p1Mass < ConfV0Selection.confV0InvMassLowLimit || p1Mass > ConfV0Selection.confV0InvMassUpLimit || p2Mass < ConfV0Selection.confV0InvMassLowLimit || p2Mass > ConfV0Selection.confV0InvMassUpLimit) { + continue; + } + } // track cleaning if (!pairCleanerV0.isCleanPair(p1, p2, parts)) {