Skip to content

Commit 01cf580

Browse files
authored
[PWGLF] Add minimum separation variable among daughter kaons (#13705)
1 parent 2d22c47 commit 01cf580

File tree

1 file changed

+38
-90
lines changed

1 file changed

+38
-90
lines changed

PWGLF/Tasks/Resonances/doublephimeson.cxx

Lines changed: 38 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ struct doublephimeson {
106106
const AxisSpec thnAxisCosTheta{configThnAxisCosTheta, "cos #theta"};
107107
const AxisSpec thnAxisNumPhi{configThnAxisNumPhi, "Number of phi meson"};
108108

109-
histos.add("SEMassUnlike", "SEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisdeltapt, thnAxisPt, thnAxisDeltaR, thnAxisInvMassDeltaPhi, thnAxisNumPhi});
109+
histos.add("SEMassUnlike", "SEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisDeltaR, thnAxisPt, thnAxisDeltaR, thnAxisInvMassDeltaPhi, thnAxisNumPhi});
110110
// histos.add("SEMassLike", "SEMassLike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaR, thnAxisInvMassPhi, thnAxisInvMassPhi, thnAxisNumPhi});
111111
histos.add("MEMassUnlike", "MEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaR, thnAxisInvMassDeltaPhi});
112112
}
@@ -762,6 +762,7 @@ struct doublephimeson {
762762
}
763763
if (phimult < 2)
764764
return;
765+
765766
// --- helpers ---
766767
constexpr double mPhiPDG = 1.019461; // GeV/c^2
767768

@@ -776,20 +777,35 @@ struct doublephimeson {
776777
return std::sqrt(dphi * dphi + deta * deta);
777778
};
778779

779-
// anti-merging: same-sign kaons must be separated
780-
const auto passDaughterDR = [&](const ROOT::Math::PtEtaPhiMVector& kplusA,
781-
const ROOT::Math::PtEtaPhiMVector& kplusB,
782-
const ROOT::Math::PtEtaPhiMVector& kminusA,
783-
const ROOT::Math::PtEtaPhiMVector& kminusB,
784-
double thr) {
780+
// minimum ΔR among all kaons in the candidate (4 kaons → 6 combinations)
781+
const auto minKaonDeltaR = [&](const ROOT::Math::PtEtaPhiMVector& kplusA,
782+
const ROOT::Math::PtEtaPhiMVector& kplusB,
783+
const ROOT::Math::PtEtaPhiMVector& kminusA,
784+
const ROOT::Math::PtEtaPhiMVector& kminusB) {
785+
// same-sign first (keep your QA histos)
785786
const double dRkplus = deltaR(kplusA.Phi(), kplusA.Eta(), kplusB.Phi(), kplusB.Eta());
786787
const double dRkminus = deltaR(kminusA.Phi(), kminusA.Eta(), kminusB.Phi(), kminusB.Eta());
787788
histos.fill(HIST("hDeltaRkaonplus"), dRkplus);
788789
histos.fill(HIST("hDeltaRkaonminus"), dRkminus);
789-
return (dRkplus > thr) && (dRkminus > thr);
790+
791+
// all other combinations
792+
const double dR_k1p_k1m = deltaR(kplusA.Phi(), kplusA.Eta(), kminusA.Phi(), kminusA.Eta());
793+
const double dR_k1p_k2m = deltaR(kplusA.Phi(), kplusA.Eta(), kminusB.Phi(), kminusB.Eta());
794+
const double dR_k2p_k1m = deltaR(kplusB.Phi(), kplusB.Eta(), kminusA.Phi(), kminusA.Eta());
795+
const double dR_k2p_k2m = deltaR(kplusB.Phi(), kplusB.Eta(), kminusB.Phi(), kminusB.Eta());
796+
797+
double minDR = dRkplus;
798+
minDR = std::min(minDR, dRkminus);
799+
minDR = std::min(minDR, dR_k1p_k1m);
800+
minDR = std::min(minDR, dR_k1p_k2m);
801+
minDR = std::min(minDR, dR_k2p_k1m);
802+
minDR = std::min(minDR, dR_k2p_k2m);
803+
return minDR;
790804
};
805+
791806
// --- collect candidates once ---
792807
std::vector<ROOT::Math::PtEtaPhiMVector> pairV, phi1V, phi2V, kplus1V, kplus2V, kminus1V, kminus2V;
808+
std::vector<double> minDRV; // store minimum ΔR for each pair
793809

794810
for (auto const& t1 : phitracks) {
795811
const double kplus1pt = std::hypot(t1.phid1Px(), t1.phid1Py());
@@ -858,13 +874,12 @@ struct doublephimeson {
858874
if (pair.M() < minExoticMass || pair.M() > maxExoticMass)
859875
continue;
860876

861-
// daughter anti-merging
877+
// daughter ΔR QA and minΔR (NO CUT anymore)
862878
ROOT::Math::PtEtaPhiMVector k1pV(k1p.Pt(), k1p.Eta(), k1p.Phi(), 0.493);
863879
ROOT::Math::PtEtaPhiMVector k1mV(k1m.Pt(), k1m.Eta(), k1m.Phi(), 0.493);
864880
ROOT::Math::PtEtaPhiMVector k2pV(k2p.Pt(), k2p.Eta(), k2p.Phi(), 0.493);
865881
ROOT::Math::PtEtaPhiMVector k2mV(k2m.Pt(), k2m.Eta(), k2m.Phi(), 0.493);
866-
if (!passDaughterDR(k1pV, k2pV, k1mV, k2mV, daughterDeltaR))
867-
continue;
882+
const double minDR = minKaonDeltaR(k1pV, k2pV, k1mV, k2mV);
868883

869884
// store for one-pass fill
870885
pairV.emplace_back(pair.Pt(), pair.Eta(), pair.Phi(), pair.M());
@@ -874,6 +889,7 @@ struct doublephimeson {
874889
kminus1V.emplace_back(k1m.Pt(), k1m.Eta(), k1m.Phi(), 0.493);
875890
kplus2V.emplace_back(k2p.Pt(), k2p.Eta(), k2p.Phi(), 0.493);
876891
kminus2V.emplace_back(k2m.Pt(), k2m.Eta(), k2m.Phi(), 0.493);
892+
minDRV.emplace_back(minDR); // per-candidate minimum ΔR of kaons
877893
}
878894
}
879895

@@ -886,91 +902,23 @@ struct doublephimeson {
886902
p1.SetPtEtaPhiM(phi1V[i].Pt(), phi1V[i].Eta(), phi1V[i].Phi(), phi1V[i].M());
887903
p2.SetPtEtaPhiM(phi2V[i].Pt(), phi2V[i].Eta(), phi2V[i].Phi(), phi2V[i].M());
888904
pair.SetPtEtaPhiM(pairV[i].Pt(), pairV[i].Eta(), pairV[i].Phi(), pairV[i].M());
905+
889906
const double dM = deltaMPhi(p1.M(), p2.M());
890907
const double M = pair.M();
891-
// const double pT = pair.Pt();
892908
const double dR = deltaR(p1.Phi(), p1.Eta(), p2.Phi(), p2.Eta());
893-
histos.fill(HIST("SEMassUnlike"), M, std::abs(p1.Pt() - p2.Pt()) / pair.Pt(), pair.Pt(), dR, dM, pairV.size());
909+
const double minDR = minDRV[i];
910+
911+
// NOTE: second axis is now minΔR(all kaons), ΔpT/pT has been removed
912+
histos.fill(HIST("SEMassUnlike"),
913+
M,
914+
minDR,
915+
pair.Pt(),
916+
dR,
917+
dM,
918+
pairV.size());
894919
}
895920
}
896921
PROCESS_SWITCH(doublephimeson, processopti3, "Process Optimized same event", false);
897-
898-
SliceCache cache;
899-
using BinningTypeVertexContributor = ColumnBinningPolicy<aod::collision::PosZ, aod::collision::NumContrib>;
900-
void processMixedEvent(aod::RedPhiEvents& collisions, aod::PhiTracks& phitracks)
901-
{
902-
auto tracksTuple = std::make_tuple(phitracks);
903-
BinningTypeVertexContributor binningOnPositions{{CfgVtxBins, CfgMultBins}, true};
904-
SameKindPair<aod::RedPhiEvents, aod::PhiTracks, BinningTypeVertexContributor> pair{binningOnPositions, nEvtMixing, -1, collisions, tracksTuple, &cache};
905-
906-
for (auto& [collision1, tracks1, collision2, tracks2] : pair) {
907-
if (collision1.index() == collision2.index()) {
908-
continue;
909-
}
910-
for (auto& [phitrackd1, phitrackd2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) {
911-
if (phitrackd1.phiMass() < minPhiMass1 || phitrackd1.phiMass() > maxPhiMass1) {
912-
continue;
913-
}
914-
if (phitrackd2.phiMass() < minPhiMass2 || phitrackd2.phiMass() > maxPhiMass2) {
915-
continue;
916-
}
917-
auto kaonplusd1pt = TMath::Sqrt(phitrackd1.phid1Px() * phitrackd1.phid1Px() + phitrackd1.phid1Py() * phitrackd1.phid1Py());
918-
auto kaonminusd1pt = TMath::Sqrt(phitrackd1.phid2Px() * phitrackd1.phid2Px() + phitrackd1.phid2Py() * phitrackd1.phid2Py());
919-
auto kaonplusd2pt = TMath::Sqrt(phitrackd2.phid1Px() * phitrackd2.phid1Px() + phitrackd2.phid1Py() * phitrackd2.phid1Py());
920-
auto kaonminusd2pt = TMath::Sqrt(phitrackd2.phid2Px() * phitrackd2.phid2Px() + phitrackd2.phid2Py() * phitrackd2.phid2Py());
921-
if (kaonplusd1pt > maxKaonPt) {
922-
continue;
923-
}
924-
if (kaonminusd1pt > maxKaonPt) {
925-
continue;
926-
}
927-
if (kaonplusd2pt > maxKaonPt) {
928-
continue;
929-
}
930-
if (kaonminusd2pt > maxKaonPt) {
931-
continue;
932-
}
933-
if (!selectionPID(phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), phitrackd1.phid1TOFHit(), strategyPID1, kaonplusd1pt)) {
934-
continue;
935-
}
936-
if (!selectionPID(phitrackd1.phid2TPC(), phitrackd1.phid2TOF(), phitrackd1.phid2TOFHit(), strategyPID1, kaonminusd1pt)) {
937-
continue;
938-
}
939-
Phid1.SetXYZM(phitrackd1.phiPx(), phitrackd1.phiPy(), phitrackd1.phiPz(), phitrackd1.phiMass());
940-
if (!selectionPID(phitrackd2.phid1TPC(), phitrackd2.phid1TOF(), phitrackd2.phid1TOFHit(), strategyPID2, kaonplusd2pt)) {
941-
continue;
942-
}
943-
if (!selectionPID(phitrackd2.phid2TPC(), phitrackd2.phid2TOF(), phitrackd2.phid2TOFHit(), strategyPID2, kaonminusd2pt)) {
944-
continue;
945-
}
946-
Phid2.SetXYZM(phitrackd2.phiPx(), phitrackd2.phiPy(), phitrackd2.phiPz(), phitrackd2.phiMass());
947-
exotic = Phid1 + Phid2;
948-
949-
Phi1kaonplus.SetXYZM(phitrackd1.phid1Px(), phitrackd1.phid1Py(), phitrackd1.phid1Pz(), 0.493);
950-
Phi1kaonminus.SetXYZM(phitrackd1.phid2Px(), phitrackd1.phid2Py(), phitrackd1.phid2Pz(), 0.493);
951-
Phi2kaonplus.SetXYZM(phitrackd2.phid1Px(), phitrackd2.phid1Py(), phitrackd2.phid1Pz(), 0.493);
952-
Phi2kaonminus.SetXYZM(phitrackd2.phid2Px(), phitrackd2.phid2Py(), phitrackd2.phid2Pz(), 0.493);
953-
auto deltaRd1 = TMath::Sqrt(TMath::Power(Phi1kaonplus.Phi() - Phi2kaonplus.Phi(), 2.0) + TMath::Power(Phi1kaonplus.Eta() - Phi2kaonplus.Eta(), 2.0));
954-
auto deltaRd2 = TMath::Sqrt(TMath::Power(Phi1kaonminus.Phi() - Phi2kaonminus.Phi(), 2.0) + TMath::Power(Phi1kaonminus.Eta() - Phi2kaonminus.Eta(), 2.0));
955-
auto deltaR = TMath::Sqrt(TMath::Power(Phid1.Phi() - Phid2.Phi(), 2.0) + TMath::Power(Phid1.Eta() - Phid2.Eta(), 2.0));
956-
// auto costheta = (Phid1.Px() * Phid2.Px() + Phid1.Py() * Phid2.Py() + Phid1.Pz() * Phid2.Pz()) / (Phid1.P() * Phid2.P());
957-
auto deltam = TMath::Sqrt(TMath::Power(Phid1.M() - 1.0192, 2.0) + TMath::Power(Phid2.M() - 1.0192, 2.0));
958-
if (deltaRd1 < daughterDeltaR) {
959-
continue;
960-
}
961-
if (deltaRd2 < daughterDeltaR) {
962-
continue;
963-
}
964-
if (!isDeep) {
965-
histos.fill(HIST("MEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, deltam);
966-
}
967-
if (isDeep) {
968-
histos.fill(HIST("MEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, deltam);
969-
}
970-
}
971-
}
972-
}
973-
PROCESS_SWITCH(doublephimeson, processMixedEvent, "Process EventMixing for combinatorial background", false);
974922
};
975923

976924
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask<doublephimeson>(cfgc)}; }

0 commit comments

Comments
 (0)