Skip to content

Commit 017dc0e

Browse files
[PWGLF] Added effeciency calculation for polarisation study (#18028)
1 parent 3c23e7d commit 017dc0e

1 file changed

Lines changed: 110 additions & 16 deletions

File tree

‎PWGLF/Tasks/Resonances/lambda1520pbpb.cxx‎

Lines changed: 110 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -269,21 +269,24 @@ struct Lambda1520pbpb {
269269
histos.add("QAafter/Kaon/h2d_Kapr_nsigma_tof_p", " Kaons proton", kTH2F, {axisPpid, axisTOFNsigma});
270270
histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_vs_tpc", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma});
271271

272-
// Analysis
273-
if (!doprocessMC) {
274-
int nActiveFrames = static_cast<int>(cActivateHelicityFrame) +
275-
static_cast<int>(cActivateCollinsSoperFrame) +
276-
static_cast<int>(cActivateProductionFrame) +
277-
static_cast<int>(cActivateBeamAxisFrame) +
278-
static_cast<int>(cActivateRandomFrame);
279-
280-
bool polActive = nActiveFrames > 0;
272+
// ── Polarization-frame activation (shared by data and MC booking) ───────
273+
int nActiveFrames = static_cast<int>(cActivateHelicityFrame) +
274+
static_cast<int>(cActivateCollinsSoperFrame) +
275+
static_cast<int>(cActivateProductionFrame) +
276+
static_cast<int>(cActivateBeamAxisFrame) +
277+
static_cast<int>(cActivateRandomFrame);
278+
279+
bool polActive = nActiveFrames > 0;
280+
281+
if (nActiveFrames > 1) {
282+
LOG(fatal) << "Multiple polarization frames activated, but axisPolFrame was removed! "
283+
<< "Please activate only ONE frame at a time to prevent data mixing in the 4D sparse.";
284+
}
281285

282-
if (nActiveFrames > 1) {
283-
LOG(fatal) << "Multiple polarization frames activated, but axisPolFrame was removed! "
284-
<< "Please activate only ONE frame at a time to prevent data mixing in the 4D sparse.";
285-
}
286+
const AxisSpec axisCosTheta{cCosThetaBins, "cos#theta*"};
286287

288+
// Analysis
289+
if (!doprocessMC) {
287290
if (!polActive) {
288291
histos.add("Analysis/h4d_lstar_invm_US_PM", "THn #Lambda(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisOccupancy});
289292
histos.add("Analysis/h4d_lstar_invm_US_MP", "THn #bar #Lambda(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisOccupancy});
@@ -305,8 +308,6 @@ struct Lambda1520pbpb {
305308

306309
// ── 4D Polarization / cosThetaStar histograms ──────────────────────────
307310
if (polActive) {
308-
const AxisSpec axisCosTheta{cCosThetaBins, "cos#theta*"};
309-
310311
histos.add("Analysis/h4d_pol_US_PM", "cos#theta* #Lambda(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisCosTheta});
311312
histos.add("Analysis/h4d_pol_US_MP", "cos#theta* #bar{#Lambda}(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisCosTheta});
312313
histos.add("Analysis/h4d_pol_LS_PP", "cos#theta* Like Signs p K^{+}", kTHnSparseF, {axisInvM, axisPt, axisCent, axisCosTheta});
@@ -340,6 +341,20 @@ struct Lambda1520pbpb {
340341
histos.add("Analysis/h3d_rec_lstar_MP", "Reconstructed #bar{#Lambda}(1520) p_{T}", kTHnSparseF, {axisInvM, axisPt, axisCent});
341342
histos.add("Analysis/h3d_reso_lstar_PM", "Resolution #Lambda(1520) p_{T}", kTHnSparseF, {{200, -0.05, 0.05}, axisPt, axisCent});
342343
histos.add("Analysis/h3d_reso_lstar_MP", "Resolution #bar{#Lambda}(1520) p_{T}", kTHnSparseF, {{200, -0.05, 0.05}, axisPt, axisCent});
344+
345+
if (polActive) {
346+
const AxisSpec axisMassRes{200, -0.05, 0.05, "M_{rec} - M_{gen} (GeV/#it{c}^{2})"};
347+
348+
histos.add("Analysis/h4d_pol_rec_PM", "cos#theta* Reconstructed (truth-matched) #Lambda(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisCosTheta});
349+
histos.add("Analysis/h4d_pol_rec_MP", "cos#theta* Reconstructed (truth-matched) #bar{#Lambda}(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisCosTheta});
350+
histos.add("Analysis/h4d_pol_reso_PM", "cos#theta* vs mass resolution #Lambda(1520)", kTHnSparseF, {axisMassRes, axisPt, axisCent, axisCosTheta});
351+
histos.add("Analysis/h4d_pol_reso_MP", "cos#theta* vs mass resolution #bar{#Lambda}(1520)", kTHnSparseF, {axisMassRes, axisPt, axisCent, axisCosTheta});
352+
}
353+
}
354+
355+
if (doprocessMCGenPol && polActive) {
356+
histos.add("Analysis/h4d_pol_gen_PM", "cos#theta* Generated (truth) #Lambda(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisCosTheta});
357+
histos.add("Analysis/h4d_pol_gen_MP", "cos#theta* Generated (truth) #bar{#Lambda}(1520)", kTHnSparseF, {axisInvM, axisPt, axisCent, axisCosTheta});
343358
}
344359

345360
if (doprocessMCGen) {
@@ -591,7 +606,10 @@ struct Lambda1520pbpb {
591606
Rotated,
592607
Mixed,
593608
LikeSign,
594-
LikeSignMixed };
609+
LikeSignMixed,
610+
McTrue,
611+
McTrueRes,
612+
GenTrue };
595613

596614
template <PolBkgMode Mode>
597615
void fillPolarization(float candMass, float candPt,
@@ -629,6 +647,21 @@ struct Lambda1520pbpb {
629647
histos.fill(HIST("Analysis/h4d_pol_LS_PP_mix"), candMass, candPt, mult, cosTheta);
630648
else
631649
histos.fill(HIST("Analysis/h4d_pol_LS_MM_mix"), candMass, candPt, mult, cosTheta);
650+
} else if constexpr (Mode == PolBkgMode::McTrue) {
651+
if (protonIsPositive)
652+
histos.fill(HIST("Analysis/h4d_pol_rec_PM"), candMass, candPt, mult, cosTheta);
653+
else
654+
histos.fill(HIST("Analysis/h4d_pol_rec_MP"), candMass, candPt, mult, cosTheta);
655+
} else if constexpr (Mode == PolBkgMode::McTrueRes) {
656+
if (protonIsPositive)
657+
histos.fill(HIST("Analysis/h4d_pol_reso_PM"), candMass, candPt, mult, cosTheta);
658+
else
659+
histos.fill(HIST("Analysis/h4d_pol_reso_MP"), candMass, candPt, mult, cosTheta);
660+
} else if constexpr (Mode == PolBkgMode::GenTrue) {
661+
if (protonIsPositive)
662+
histos.fill(HIST("Analysis/h4d_pol_gen_PM"), candMass, candPt, mult, cosTheta);
663+
else
664+
histos.fill(HIST("Analysis/h4d_pol_gen_MP"), candMass, candPt, mult, cosTheta);
632665
} else {
633666
if (protonIsPositive)
634667
histos.fill(HIST("Analysis/h4d_pol_US_PM"), candMass, candPt, mult, cosTheta);
@@ -975,6 +1008,17 @@ struct Lambda1520pbpb {
9751008
histos.fill(HIST("Analysis/h3d_rec_lstar_MP"), candMass, candPt, mult);
9761009
histos.fill(HIST("Analysis/h3d_reso_lstar_MP"), candMassRes, candPt, mult);
9771010
}
1011+
1012+
if (polActive) {
1013+
float eProton = std::sqrt(pxPr * pxPr + pyPr * pyPr + pzPr * pzPr + MassProton * MassProton);
1014+
float eKaon = std::sqrt(pxKa * pxKa + pyKa * pyKa + pzKa * pzKa + MassKaonCharged * MassKaonCharged);
1015+
std::array<float, 3> protonP = {pxPr, pyPr, pzPr};
1016+
std::array<float, 3> kaonP = {pxKa, pyKa, pzKa};
1017+
std::array<float, 3> motherP = {pxPr + pxKa, pyPr + pyKa, pzPr + pzKa};
1018+
float motherE = eProton + eKaon;
1019+
fillPolarization<PolBkgMode::McTrue>(candMass, candPt, motherP, motherE, protonP, eProton, kaonP, eKaon, mult, trkPr.motherPDG() > 0);
1020+
fillPolarization<PolBkgMode::McTrueRes>(candMassRes, candPt, motherP, motherE, protonP, eProton, kaonP, eKaon, mult, trkPr.motherPDG() > 0);
1021+
}
9781022
}
9791023
}
9801024
}
@@ -1073,6 +1117,56 @@ struct Lambda1520pbpb {
10731117
}
10741118
PROCESS_SWITCH(Lambda1520pbpb, processMC, "Process Event for MC", false);
10751119

1120+
void processMCGenPol(ResoMCCols::iterator const& collision, aod::ResoMCParents const& resoParents, aod::McParticles const& mcParticles)
1121+
{
1122+
auto mult = collision.cent();
1123+
bool polActive = static_cast<bool>(cActivateHelicityFrame) ||
1124+
static_cast<bool>(cActivateCollinsSoperFrame) ||
1125+
static_cast<bool>(cActivateProductionFrame) ||
1126+
static_cast<bool>(cActivateBeamAxisFrame) ||
1127+
static_cast<bool>(cActivateRandomFrame);
1128+
if (!polActive)
1129+
return;
1130+
1131+
for (auto const& part : resoParents) {
1132+
if (std::abs(part.pdgCode()) != lambda1520id)
1133+
continue;
1134+
float yshift = std::abs(part.y()) - cfgRapidityShift;
1135+
if (std::abs(yshift) > cfgRapidityCut)
1136+
continue;
1137+
1138+
bool pass1 = std::abs(part.daughterPDG1()) == kProton || std::abs(part.daughterPDG2()) == kProton;
1139+
bool pass2 = std::abs(part.daughterPDG1()) == kKPlus || std::abs(part.daughterPDG2()) == kKPlus;
1140+
if (!pass1 || !pass2)
1141+
continue;
1142+
1143+
std::array<float, 3> pvec = {part.px(), part.py(), part.pz()};
1144+
float mass = RecoDecay::m(pvec, part.e());
1145+
1146+
auto motherMc = mcParticles.iteratorAt(part.mcParticleId());
1147+
bool foundProton = false, foundKaon = false;
1148+
std::array<float, 3> protonP{}, kaonP{};
1149+
float protonE = 0.f, kaonE = 0.f;
1150+
for (auto const& dau : motherMc.daughters_as<aod::McParticles>()) {
1151+
if (!foundProton && std::abs(dau.pdgCode()) == kProton) {
1152+
protonP = {dau.px(), dau.py(), dau.pz()};
1153+
protonE = dau.e();
1154+
foundProton = true;
1155+
} else if (!foundKaon && std::abs(dau.pdgCode()) == kKPlus) {
1156+
kaonP = {dau.px(), dau.py(), dau.pz()};
1157+
kaonE = dau.e();
1158+
foundKaon = true;
1159+
}
1160+
}
1161+
if (!foundProton || !foundKaon)
1162+
continue;
1163+
1164+
std::array<float, 3> motherP = {part.px(), part.py(), part.pz()};
1165+
fillPolarization<PolBkgMode::GenTrue>(mass, part.pt(), motherP, part.e(), protonP, protonE, kaonP, kaonE, mult, part.pdgCode() > 0);
1166+
}
1167+
}
1168+
PROCESS_SWITCH(Lambda1520pbpb, processMCGenPol, "Standalone generator-level polarization pass (run separately from processMC)", false);
1169+
10761170
void processMCGen(ResoMCCols::iterator const& collision, aod::ResoMCParents const& resoParents)
10771171
{
10781172
float centrality = collision.cent();

0 commit comments

Comments
 (0)