From 5aade88d8062c418ba2afcaae94dffdf47c61d3a Mon Sep 17 00:00:00 2001 From: Alicja Plachta Date: Wed, 15 Apr 2026 11:27:29 +0200 Subject: [PATCH 1/3] Add gamma pair rejection in track-track tasks --- ...iversePairTaskTrackTrackMultKtExtended.cxx | 45 +++++++++++++++++-- ...irTaskTrackTrackSpherHarMultKtExtended.cxx | 38 ++++++++++++++++ 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx index 2fc0a3543b9..4a4c895dbe3 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx @@ -189,6 +189,10 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { Configurable cfgProcessKtBins{"cfgProcessKtBins", false, "Process kstar histograms in kT bins (if 'cfgProcessMultBins' is false, it will not be processed regardless of 'cfgProcessKtBins' state)"}; Configurable cfgProcessKtMt3DCF{"cfgProcessKtMt3DCF", false, "Process 3D histograms in kT and MultBins"}; + Configurable confRejectGammaPair{"confRejectGammaPair", false, "Additional check to reject e+e- pairs base on theta and minv"}; + Configurable confMaxEEMinv{"confMaxEEMinv", 0.002, "Max. minv of e-e+ pair for gamma pair rejection"}; + Configurable confMaxDTheta{"confMaxDTheta", 0.008, "Max. DeltaTheta of pair for gamma pair rejection"}; + FemtoUniverseFemtoContainer sameEventCont; FemtoUniverseFemtoContainer mixedEventCont; @@ -332,6 +336,31 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { return false; } + template + bool rejectGammaPair(PartType track1, PartType track2) + { + double me = 0.000511; + + double magTrack1 = track1.px() * track1.px() + track1.py() * track1.py() + track1.pz() * track1.pz(); + double magTrack2 = track2.px() * track2.px() + track2.py() * track2.py() + track2.pz() * track2.pz(); + double dotTr1Tr2 = track1.px() * track2.px() + track1.py() * track2.py() + track1.pz() * track2.pz(); + + if ((track1.sign() * track2.sign()) < 0.0) { + double theta1 = track1.theta(); + double theta2 = track2.theta(); + double dtheta = TMath::Abs(theta1 - theta2); + + double e1 = TMath::Sqrt(me * me + magTrack1); + double e2 = TMath::Sqrt(me * me + magTrack2); + + double minv = 2 * me * me + 2 * (e1 * e2 - dotTr1Tr2); + if ((TMath::Abs(minv) < confMaxEEMinv) && (dtheta < confMaxDTheta)) { + return false; + } + } + return true; + } + void init(InitContext&) { eventHisto.init(&qaRegistry); @@ -477,6 +506,10 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { continue; } + if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + continue; + } + if (confIsCPR.value) { double rand; auto part1 = p1; @@ -670,6 +703,10 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { continue; } + if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + continue; + } + if (confIsCPR.value) { double rand; auto part1 = p1; @@ -752,7 +789,7 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { void processMixedEvent(soa::Filtered const& cols, FilteredFemtoFullParticles const& parts) { - for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, confNEventsMix, -1, cols, cols)) { const int multiplicityCol = collision1.multV0M(); if (confFillDebug) { @@ -793,7 +830,7 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { FemtoRecoParticles const& parts, o2::aod::FdMCParticles const&) { - for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, confNEventsMix, -1, cols, cols)) { const int multiplicityCol = collision1.multV0M(); if (confFillDebug) { @@ -902,7 +939,7 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { } }; - for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, confNEventsMix, -1, cols, cols)) { const int multiplicityCol = collision1.multV0M(); if (confFillDebug) { mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); @@ -994,7 +1031,7 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { void processFractionsMCTruth(o2::aod::FdCollisions const& cols, FemtoTruthParticles const&) { - for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, confNEventsMix, -1, cols, cols)) { const int multiplicityCol = collision1.multV0M(); if (confFillDebug) { diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index f5a4409a2e7..def4cd98fee 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -216,6 +216,10 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { Configurable cfgProcessKtBins{"cfgProcessKtBins", true, "Process kstar histograms in kT bins (if cfgProcessMultBins is set false, this will not be processed regardless this Configurable state)"}; Configurable cfgProcessKtMt3DCF{"cfgProcessKtMt3DCF", false, "Process 3D histograms in kT and Mult bins"}; + Configurable confRejectGammaPair{"confRejectGammaPair", false, "Additional check to reject e+e- pairs base on theta and minv"}; + Configurable confMaxEEMinv{"confMaxEEMinv", 0.002, "Max. minv of e-e+ pair for gamma pair rejection"}; + Configurable confMaxDTheta{"confMaxDTheta", 0.008, "Max. DeltaTheta of pair for gamma pair rejection"}; + FemtoUniverseSHContainer sameEventCont; FemtoUniverseSHContainer mixedEventCont; @@ -411,6 +415,31 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { return false; } + template + bool rejectGammaPair(PartType track1, PartType track2) + { + double me = 0.000511; + + double magTrack1 = track1.px() * track1.px() + track1.py() * track1.py() + track1.pz() * track1.pz(); + double magTrack2 = track2.px() * track2.px() + track2.py() * track2.py() + track2.pz() * track2.pz(); + double dotTr1Tr2 = track1.px() * track2.px() + track1.py() * track2.py() + track1.pz() * track2.pz(); + + if ((track1.sign() * track2.sign()) < 0.0) { + double theta1 = track1.theta(); + double theta2 = track2.theta(); + double dtheta = TMath::Abs(theta1 - theta2); + + double e1 = TMath::Sqrt(me * me + magTrack1); + double e2 = TMath::Sqrt(me * me + magTrack2); + + double minv = 2 * me * me + 2 * (e1 * e2 - dotTr1Tr2); + if ((TMath::Abs(minv) < confMaxEEMinv) && (dtheta < confMaxDTheta)) { + return false; + } + } + return true; + } + void init(InitContext&) { eventHisto.init(&qaRegistry); @@ -536,6 +565,10 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } + if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + continue; + } + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); float lastElement = confKtKstarBins.value.back(); float firstRealElement = confKtKstarBins.value[1]; @@ -565,6 +598,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } + sameEventMultCont.fillMultNumDen(p1, p2, femto_universe_sh_container::EventType::same, 2, multCol, kT, twotracksconfigs.confisIdenLCMS, twotracksconfigs.confIs1D, twotracksconfigs.confIsWeight, twotracksconfigs.confisIdenPRF); } } else { @@ -937,6 +971,10 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } + if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + continue; + } + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); float lastElement = confKtKstarBins.value.back(); float firstRealElement = confKtKstarBins.value[1]; From d8b682792cf9524a6b5d794624c2f1af97175309 Mon Sep 17 00:00:00 2001 From: Alicja Plachta Date: Wed, 15 Apr 2026 12:06:26 +0200 Subject: [PATCH 2/3] Use o2::constants::physics::MassElectron --- .../Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx | 5 ++++- ...femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx index 4a4c895dbe3..32681cfc068 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx @@ -193,6 +193,9 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { Configurable confMaxEEMinv{"confMaxEEMinv", 0.002, "Max. minv of e-e+ pair for gamma pair rejection"}; Configurable confMaxDTheta{"confMaxDTheta", 0.008, "Max. DeltaTheta of pair for gamma pair rejection"}; + ConfigurableAxis confDeltaEtaAxis{"confDeltaEtaAxis", {100, -0.15, 0.15}, "DeltaEta"}; + ConfigurableAxis confDeltaPhiStarAxis{"confDeltaPhiStarAxis", {100, -0.15, 0.15}, "DeltaPhiStar"}; + FemtoUniverseFemtoContainer sameEventCont; FemtoUniverseFemtoContainer mixedEventCont; @@ -339,7 +342,7 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { template bool rejectGammaPair(PartType track1, PartType track2) { - double me = 0.000511; + double me = o2::constants::physics::MassElectron; double magTrack1 = track1.px() * track1.px() + track1.py() * track1.py() + track1.pz() * track1.pz(); double magTrack2 = track2.px() * track2.px() + track2.py() * track2.py() + track2.pz() * track2.pz(); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index def4cd98fee..ae11c10ff22 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -418,7 +418,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { template bool rejectGammaPair(PartType track1, PartType track2) { - double me = 0.000511; + double me = o2::constants::physics::MassElectron; double magTrack1 = track1.px() * track1.px() + track1.py() * track1.py() + track1.pz() * track1.pz(); double magTrack2 = track2.px() * track2.px() + track2.py() * track2.py() + track2.pz() * track2.pz(); From 464cb1f9a27ea83c83b56236c8ec3e2519742476 Mon Sep 17 00:00:00 2001 From: Alicja Plachta Date: Wed, 15 Apr 2026 17:29:57 +0200 Subject: [PATCH 3/3] Move gamma pair rejection function to header file --- .../Core/FemtoUniverseDetaDphiStar.h | 25 ++++++++++++ ...iversePairTaskTrackTrackMultKtExtended.cxx | 39 ++++--------------- ...irTaskTrackTrackSpherHarMultKtExtended.cxx | 29 +------------- 3 files changed, 34 insertions(+), 59 deletions(-) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h index 3a7738b2cc1..310a9d942e3 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h @@ -694,6 +694,31 @@ class FemtoUniverseDetaDphiStar } } + template + bool isGammaPair(PartType track1, PartType track2, double maxEEMinv, double maxDTheta) + { + double me = o2::constants::physics::MassElectron; + + double magTrack1 = track1.px() * track1.px() + track1.py() * track1.py() + track1.pz() * track1.pz(); + double magTrack2 = track2.px() * track2.px() + track2.py() * track2.py() + track2.pz() * track2.pz(); + double dotTr1Tr2 = track1.px() * track2.px() + track1.py() * track2.py() + track1.pz() * track2.pz(); + + if ((track1.sign() * track2.sign()) < 0.0) { + double theta1 = track1.theta(); + double theta2 = track2.theta(); + double dtheta = TMath::Abs(theta1 - theta2); + + double e1 = TMath::Sqrt(me * me + magTrack1); + double e2 = TMath::Sqrt(me * me + magTrack2); + + double minv = 2 * me * me + 2 * (e1 * e2 - dotTr1Tr2); + if ((TMath::Abs(minv) < maxEEMinv) && (dtheta < maxDTheta)) { + return true; + } + } + return false; + } + /// Check if pair is close or not template void ClosePairqLCMS(Part const& part1, Part const& part2, float lmagfield, uint8_t ChosenEventType, double qlcms) // add typename Parts and variable parts for adding MClabels diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx index 32681cfc068..72b22ed0807 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx @@ -339,31 +339,6 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { return false; } - template - bool rejectGammaPair(PartType track1, PartType track2) - { - double me = o2::constants::physics::MassElectron; - - double magTrack1 = track1.px() * track1.px() + track1.py() * track1.py() + track1.pz() * track1.pz(); - double magTrack2 = track2.px() * track2.px() + track2.py() * track2.py() + track2.pz() * track2.pz(); - double dotTr1Tr2 = track1.px() * track2.px() + track1.py() * track2.py() + track1.pz() * track2.pz(); - - if ((track1.sign() * track2.sign()) < 0.0) { - double theta1 = track1.theta(); - double theta2 = track2.theta(); - double dtheta = TMath::Abs(theta1 - theta2); - - double e1 = TMath::Sqrt(me * me + magTrack1); - double e2 = TMath::Sqrt(me * me + magTrack2); - - double minv = 2 * me * me + 2 * (e1 * e2 - dotTr1Tr2); - if ((TMath::Abs(minv) < confMaxEEMinv) && (dtheta < confMaxDTheta)) { - return false; - } - } - return true; - } - void init(InitContext&) { eventHisto.init(&qaRegistry); @@ -509,7 +484,12 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { continue; } - if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + if (confRejectGammaPair && pairCloseRejection.isGammaPair(p1, p2, confMaxEEMinv, confMaxDTheta)) { + continue; + } + + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } @@ -533,11 +513,6 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { } } - // track cleaning - if (!pairCleaner.isCleanPair(p1, p2, parts)) { - continue; - } - float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass2); float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); @@ -706,7 +681,7 @@ struct FemtoUniversePairTaskTrackTrackMultKtExtended { continue; } - if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + if (confRejectGammaPair && pairCloseRejection.isGammaPair(p1, p2, confMaxEEMinv, confMaxDTheta)) { continue; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index ae11c10ff22..30ea4eb0f49 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -415,31 +415,6 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { return false; } - template - bool rejectGammaPair(PartType track1, PartType track2) - { - double me = o2::constants::physics::MassElectron; - - double magTrack1 = track1.px() * track1.px() + track1.py() * track1.py() + track1.pz() * track1.pz(); - double magTrack2 = track2.px() * track2.px() + track2.py() * track2.py() + track2.pz() * track2.pz(); - double dotTr1Tr2 = track1.px() * track2.px() + track1.py() * track2.py() + track1.pz() * track2.pz(); - - if ((track1.sign() * track2.sign()) < 0.0) { - double theta1 = track1.theta(); - double theta2 = track2.theta(); - double dtheta = TMath::Abs(theta1 - theta2); - - double e1 = TMath::Sqrt(me * me + magTrack1); - double e2 = TMath::Sqrt(me * me + magTrack2); - - double minv = 2 * me * me + 2 * (e1 * e2 - dotTr1Tr2); - if ((TMath::Abs(minv) < confMaxEEMinv) && (dtheta < confMaxDTheta)) { - return false; - } - } - return true; - } - void init(InitContext&) { eventHisto.init(&qaRegistry); @@ -565,7 +540,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } - if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + if (confRejectGammaPair && pairCloseRejection.isGammaPair(p1, p2, confMaxEEMinv, confMaxDTheta)) { continue; } @@ -971,7 +946,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } - if (confRejectGammaPair && !rejectGammaPair(p1, p2)) { + if (confRejectGammaPair && pairCloseRejection.isGammaPair(p1, p2, confMaxEEMinv, confMaxDTheta)) { continue; }