From 5bb1afe17f19e554649b941b543f0077159c6f1b Mon Sep 17 00:00:00 2001 From: sarjeeta gami Date: Wed, 23 Sep 2026 16:17:29 +0530 Subject: [PATCH 1/3] [PWGLF] Add production plane and random plane, plus the phi part for cross-checks, in kstarpbpb.cxx; clean up phianalysisrun3pbpb --- PWGLF/Tasks/Resonances/kstarpbpb.cxx | 850 ++++++++++++++---- .../Tasks/Resonances/phianalysisrun3pbpb.cxx | 678 +++----------- 2 files changed, 788 insertions(+), 740 deletions(-) diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index 0a36e123a3d..732a5a65717 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -21,6 +21,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -39,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -49,7 +52,9 @@ #include #include #include +#include +#include #include #include #include @@ -132,6 +137,39 @@ struct Kstarpbpb { Configurable cfgOccupancyCut{"cfgOccupancyCut", 500, "Occupancy cut"}; Configurable useWeight{"useWeight", false, "use EP dep effi weight"}; Configurable useSP{"useSP", false, "use SP"}; + // spin-alignment quantization axis + Configurable cfgSAFrame{"cfgSAFrame", 0, "SA quantization axis: 0 = event plane (FT0C), 1 = production plane, 2 = random event plane"}; + Configurable cfgRndSeed{"cfgRndSeed", 0, "Seed for random event plane (0 = unique seed per job)"}; + Configurable cfgEPNormalHarmonic{"cfgEPNormalHarmonic", 2.0f, "EP normal = (sin(n*Psi), -cos(n*Psi), 0); n = 2 is the previous behaviour, n = 1 is the normal to the Psi2 plane"}; + + // phi(1020) spin alignment: event selection is the K* one; track/PID selections and defaults identical to PWGLF/Tasks/Resonances/phipbpb.cxx + // (JSON keys follow the O2 linter naming rules, so removeFakeTrack, confFakeKaonCut and nsigmaCutTPC differ from the phipbpb.cxx spelling) + struct : ConfigurableGroup { + std::string prefix = "phiSA"; + Configurable removeFakeTrack{"removeFakeTrack", true, "Remove fake track from momentum difference"}; + Configurable confFakeKaonCut{"confFakeKaonCut", 0.1, "Cut based on track from momentum difference"}; + Configurable useGlobalTrack{"useGlobalTrack", true, "use Global track"}; + Configurable useDcaSyst{"useDcaSyst", false, "useDcaSyst"}; + Configurable cfgCutTOFBeta{"cfgCutTOFBeta", 0.0, "cut TOF beta"}; + Configurable nsigmaCutTPC{"nsigmaCutTPC", 3.0, "Value of the TPC Nsigma cut"}; + Configurable nsigmaCutTOF{"nsigmaCutTOF", 3.0, "Value of the TOF Nsigma cut"}; + Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; + Configurable cfgTPCcluster{"cfgTPCcluster", 70, "Number of TPC cluster"}; + Configurable cfgTPCSharedcluster{"cfgTPCSharedcluster", 0.4, "Maximum Number of TPC shared cluster"}; + Configurable isDeepAngle{"isDeepAngle", false, "Deep Angle cut"}; + Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; + Configurable ispTdepPID{"ispTdepPID", true, "pT dependent PID"}; + Configurable isTOFOnly{"isTOFOnly", false, "use TOF only PID"}; + Configurable confRapidity{"confRapidity", 0.5, "Rapidity cut"}; + Configurable genacceptancecut{"genacceptancecut", true, "use acceptance cut for generated"}; + Configurable avoidsplitrackMC{"avoidsplitrackMC", false, "avoid split track in MC"}; + ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {120, 0.98, 1.1}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis configThnAxisPt{"configThnAxisPt", {100, 0.0, 10.}, "#it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis configThnAxisCosThetaStar{"configThnAxisCosThetaStar", {10, -1.0, 1.}, "cos(#vartheta)"}; + ConfigurableAxis configThnAxisCentrality{"configThnAxisCentrality", {8, 0., 80}, "Centrality"}; + ConfigurableAxis configThnAxisRapidity{"configThnAxisRapidity", {8, 0, 0.8}, "Rapidity"}; + ConfigurableAxis configThnAxisSA{"configThnAxisSA", {200, -1, 1}, "SA"}; + } phiSA; Configurable cfgMinTrackPt{"cfgMinTrackPt", 0.15f, "Minimum track pT"}; @@ -168,12 +206,12 @@ struct Kstarpbpb { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - // Event selection cuts - Alex - TF1* fMultPVCutLow = nullptr; - TF1* fMultPVCutHigh = nullptr; - TF1* fMultCutLow = nullptr; - TF1* fMultCutHigh = nullptr; - TF1* fMultMultPVCut = nullptr; + enum SAFrame : int { + kEventPlane = 0, + kProductionPlane = 1, + kRandomEventPlane = 2 + }; + TRandom3 rndGen; void init(o2::framework::InitContext&) { @@ -182,52 +220,77 @@ struct Kstarpbpb { rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + if (cfgSAFrame.value < kEventPlane || cfgSAFrame.value > kRandomEventPlane) { + LOGF(fatal, "cfgSAFrame = %d not supported (0 = event plane, 1 = production plane, 2 = random event plane)", cfgSAFrame.value); + } + rndGen.SetSeed(cfgRndSeed); + std::vector occupancyBinning = {0.0, 500.0, 1000.0, 1500.0, 2000.0, 3000.0, 4000.0, 5000.0, 50000.0}; AxisSpec phiAxis = {500, -6.28, 6.28, "phi"}; AxisSpec resAxis = {6000, -30, 30, "Res"}; AxisSpec centAxis = {8, 0, 80, "V0M (%)"}; AxisSpec occupancyAxis = {occupancyBinning, "Occupancy"}; - histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); - if (!fillSA) { - histos.add("hSparseV2SASameEvent_V2", "hSparseV2SASameEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - } - if (fillRotation) { + AxisSpec vzAxis = {400, -20.0, 20.0, "Z_{vtx} (cm)"}; + AxisSpec qvecAxis = {200, 0, 20, "q"}; + if (doprocessSE) { + histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); if (!fillSA) { + histos.add("hSparseV2SASameEvent_V2", "hSparseV2SASameEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); + } + if (fillRotation && !fillSA) { histos.add("hRotation", "hRotation", kTH1F, {{360, 0.0, o2::constants::math::TwoPI}}); histos.add("hSparseV2SASameEventRotational_V2", "hSparseV2SASameEventRotational_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); } + if (fillSA) { + histos.add("hSparseSAvsrapsameunlike", "hSparseSAvsrapsameunlike", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); + histos.add("hSparseSAvsrapsamelike", "hSparseSAvsrapsamelike", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); + if (fillRotation) { + histos.add("hSparseSAvsraprot", "hSparseSAvsraprot", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); + } + if (cfgSAFrame.value == kRandomEventPlane) { + histos.add("hPsiRandom", "Random event plane angle", kTH2F, {centAxis, phiAxis}); + } + } } - if (fillSA) { - histos.add("hSparseSAvsrapsameunlike", "hSparseSAvsrapsameunlike", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); - histos.add("hSparseSAvsrapsamelike", "hSparseSAvsrapsamelike", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); - histos.add("hSparseSAvsraprot", "hSparseSAvsraprot", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); - histos.add("hSparseSAvsrapmix", "hSparseSAvsrapmix", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); + if (doprocessMixedEvent) { + if (!fillSA) { + histos.add("hSparseV2SAMixedEvent_V2", "hSparseV2SAMixedEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); + } + if (fillSA) { + histos.add("hSparseSAvsrapmix", "hSparseSAvsrapmix", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); + } } - histos.add("hSparseV2SAGen_V2", "hSparseV2SAGen_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("hSparseV2SARec_V2", "hSparseV2SARec_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("hpt", "hpt", kTH1F, {configThnAxisPt}); - histos.add("hMC", "MC Event statistics", kTH1F, {{10, 0.0f, 10.0f}}); - histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {{100, 0.0f, 10.0f}}); - histos.add("CentPercentileMCRecHist", "MC Centrality", kTH1F, {{100, 0.0f, 100.0f}}); - histos.add("hSparseV2SAMixedEvent_V2", "hSparseV2SAMixedEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {configThnAxisPt, configThnAxisCentrality}); - histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {configThnAxisPt, configThnAxisCentrality}); - histos.add("hImpactParameter", "Impact parameter", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("hEventPlaneAngle", "hEventPlaneAngle", kTH1F, {{200, -o2::constants::math::TwoPI, o2::constants::math::TwoPI}}); - histos.add("hSparseKstarMCGenWeight", "hSparseKstarMCGenWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecWeight", "hSparseKstarMCRecWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCGenKaonWeight", "hSparseKstarMCGenKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecKaonWeight", "hSparseKstarMCRecKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecKaonMissMatchWeight", "hSparseKstarMCRecKaonMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCGenPionWeight", "hSparseKstarMCGenPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecPionWeight", "hSparseKstarMCRecPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecPionMissMatchWeight", "hSparseKstarMCRecPionMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCGenSA", "hSparseKstarMCGenSA", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); - histos.add("hSparseKstarMCGenCosThetaStar_effy", "hSparseKstarMCGenCosThetaStar_effy", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); - histos.add("hSparseKstarMCRecSA", "hSparseKstarMCRecSA", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); - histos.add("hSparseKstarMCRecCosThetaStar_effy", "hSparseKstarMCRecCosThetaStar_effy", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); - if (additionalQAplots1) { + + if (doprocessMC) { + histos.add("hSparseV2SAGen_V2", "hSparseV2SAGen_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); + histos.add("hSparseV2SARec_V2", "hSparseV2SARec_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); + histos.add("hpt", "hpt", kTH1F, {configThnAxisPt}); + histos.add("hMC", "MC Event statistics", kTH1F, {{10, 0.0f, 10.0f}}); + histos.add("CentPercentileMCRecHist", "MC Centrality", kTH1F, {{100, 0.0f, 100.0f}}); + histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {configThnAxisPt, configThnAxisCentrality}); + histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {configThnAxisPt, configThnAxisCentrality}); + histos.add("hSparseKstarMCGenSA", "hSparseKstarMCGenSA", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); + histos.add("hSparseKstarMCGenCosThetaStar_effy", "hSparseKstarMCGenCosThetaStar_effy", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); + histos.add("hSparseKstarMCRecSA", "hSparseKstarMCRecSA", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); + histos.add("hSparseKstarMCRecCosThetaStar_effy", "hSparseKstarMCRecCosThetaStar_effy", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); + } + + if (doprocessMCkstarWeight) { + histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {{100, 0.0f, 10.0f}}); + histos.add("hImpactParameter", "Impact parameter", kTH1F, {{200, 0.0f, 20.0f}}); + histos.add("hEventPlaneAngle", "hEventPlaneAngle", kTH1F, {{200, -o2::constants::math::TwoPI, o2::constants::math::TwoPI}}); + histos.add("hSparseKstarMCGenWeight", "hSparseKstarMCGenWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecWeight", "hSparseKstarMCRecWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCGenKaonWeight", "hSparseKstarMCGenKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecKaonWeight", "hSparseKstarMCRecKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecKaonMissMatchWeight", "hSparseKstarMCRecKaonMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCGenPionWeight", "hSparseKstarMCGenPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecPionWeight", "hSparseKstarMCRecPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecPionMissMatchWeight", "hSparseKstarMCRecPionMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + } + + if (doprocessSE && additionalQAplots1) { histos.add("hFTOCvsTPCSelected", "Mult correlation FT0C vs. TPC after selection", kTH2F, {{80, 0.0f, 80.0f}, {100, -0.5f, 5999.5f}}); histos.add("hCentrality", "Centrality distribution", kTH1F, {{200, 0.0, 200.0}}); histos.add("hOccupancy", "Occupancy distribution", kTH1F, {occupancyAxis}); @@ -244,8 +307,14 @@ struct Kstarpbpb { histos.add("ResTrackSPFT0CTPC", "ResTrackSPFT0CTPC", kTH3F, {centAxis, occupancyAxis, resAxis}); histos.add("ResTrackSPFT0CFT0A", "ResTrackSPFT0CFT0A", kTH3F, {centAxis, occupancyAxis, resAxis}); histos.add("ResTrackSPFT0ATPC", "ResTrackSPFT0ATPC", kTH3F, {centAxis, occupancyAxis, resAxis}); + histos.add("hQFT0CvsCent", "q_{FT0C} vs centrality", kTH2F, {centAxis, qvecAxis}); + histos.add("hQFT0CvsVz", "q_{FT0C} vs Z_{vtx}", kTH2F, {vzAxis, qvecAxis}); + histos.add("hQFT0AvsCent", "q_{FT0A} vs centrality", kTH2F, {centAxis, qvecAxis}); + histos.add("hQFT0AvsVz", "q_{FT0A} vs Z_{vtx}", kTH2F, {vzAxis, qvecAxis}); + histos.add("hQTPCvsCent", "q_{TPC} vs centrality", kTH2F, {centAxis, qvecAxis}); + histos.add("hQTPCvsVz", "q_{TPC} vs Z_{vtx}", kTH2F, {vzAxis, qvecAxis}); } - if (additionalQAplots) { + if (doprocessSE && additionalQAplots) { // DCA QA histos.add("QAbefore/trkDCAxyka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); histos.add("QAbefore/trkDCAzka", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); @@ -276,11 +345,45 @@ struct Kstarpbpb { histos.add("QAafter/TPC_Nsigma_allpi", "TPC NSigma for pion;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{pion};", {HistType::kTH3D, {{200, 0.0, 20.0}, {100, -6, 6}, {100, 0.0, 100.0}}}); } - histos.add("hMassSameEventLikeNN", "Same-event like-sign (--) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); - histos.add("hMassSameEventLikePP", "Same-event like-sign (++) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); - histos.add("hMassMixedEventLikeNN", "Mixed-event like-sign (--) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); - histos.add("hMassMixedEventLikePP", "Mixed-event like-sign (++) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); - histos.add("hMassMixedEventUnlike", "Mixed-event unlike-sign mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + if (doprocessSE) { + histos.add("hMassSameEventLikeNN", "Same-event like-sign (--) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + histos.add("hMassSameEventLikePP", "Same-event like-sign (++) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + } + if (doprocessMixedEvent) { + histos.add("hMassMixedEventLikeNN", "Mixed-event like-sign (--) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + histos.add("hMassMixedEventLikePP", "Mixed-event like-sign (++) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + histos.add("hMassMixedEventUnlike", "Mixed-event unlike-sign mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + } + + // phi(1020) spin alignment, same names and binning as phipbpb.cxx + if (doprocessSEPhi || doprocessMEPhi || doprocessMCPhi) { + const AxisSpec thnAxisInvMassPhi{phiSA.configThnAxisInvMass, "#it{M} (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisPtPhi{phiSA.configThnAxisPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec thnAxisCosThetaStarPhi{phiSA.configThnAxisCosThetaStar, "cos(#vartheta_{OP})"}; + const AxisSpec thnAxisCentralityPhi{phiSA.configThnAxisCentrality, "Centrality (%)"}; + const AxisSpec thnAxisRapidityPhi{phiSA.configThnAxisRapidity, "Rapidity"}; + const AxisSpec thnAxisSAPhi{phiSA.configThnAxisSA, "SA"}; + if (cfgSAFrame.value == kRandomEventPlane) { + histos.add("phi/hPsiRandom", "Random event plane angle", kTH2F, {centAxis, phiAxis}); + } + if (doprocessSEPhi) { + histos.add("phi/hSparseV2SameEventSA", "hSparseV2SameEventSA", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisSAPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + histos.add("phi/hSparseV2SameEventCosThetaStar", "hSparseV2SameEventCosThetaStar", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisCosThetaStarPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + } + if (doprocessMEPhi) { + histos.add("phi/hSparseV2MixedEventSA", "hSparseV2MixedEventSA", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisSAPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + histos.add("phi/hSparseV2MixedEventCosThetaStar", "hSparseV2MixedEventCosThetaStar", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisCosThetaStarPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + } + if (doprocessMCPhi) { + histos.add("phi/hMC", "MC Event statistics", kTH1F, {{10, 0.0f, 10.0f}}); + histos.add("phi/h1PhiRecsplit", "Phi meson Rec split", kTH1F, {{100, 0.0f, 10.0f}}); + histos.add("phi/CentPercentileMCRecHist", "MC Centrality", kTH1F, {{100, 0.0f, 100.0f}}); + histos.add("phi/hSparseV2MCGenSA", "hSparseV2SameEventSA", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisSAPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + histos.add("phi/hSparseV2MCGenCosThetaStar_effy", "hSparseV2SameEventCosThetaStar_effy", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisCosThetaStarPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + histos.add("phi/hSparseV2MCRecSA", "hSparseV2SameEventSA", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisSAPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + histos.add("phi/hSparseV2MCRecCosThetaStar_effy", "hSparseV2SameEventCosThetaStar_effy", HistType::kTHnSparseD, {thnAxisInvMassPhi, thnAxisPtPhi, thnAxisCosThetaStarPhi, thnAxisRapidityPhi, thnAxisCentralityPhi}); + } + } ccdb->setURL(cfgCcdbParam.cfgURL); ccdbApi.init("http://alice-ccdb.cern.ch"); @@ -289,8 +392,8 @@ struct Kstarpbpb { ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); } - double massKa = o2::constants::physics::MassKPlus; - double massPi = o2::constants::physics::MassPiMinus; + static constexpr double MassKa = o2::constants::physics::MassKPlus; + static constexpr double MassPi = o2::constants::physics::MassPiMinus; template bool selectionTrack(const T& candidate) @@ -403,6 +506,204 @@ struct Kstarpbpb { } return result; } + + // event-level plane angle for SA: reconstructed Psi2 (event plane) or a random angle (random event plane) + double getSAEventAngle(double psiEP) + { + if (cfgSAFrame.value == kRandomEventPlane) { + return rndGen.Uniform(-o2::constants::math::PIHalf, o2::constants::math::PIHalf); + } + return psiEP; + } + + // in-plane angle of the SA plane, used for the cos(2(phi* - Psi)) variable + double getSAPlaneAngle(const ROOT::Math::PxPyPzMVector& mother, double psiSA) + { + if (cfgSAFrame.value == kProductionPlane) { + return mother.Phi(); // production plane is spanned by the beam axis and the mother momentum + } + return psiSA; + } + + // quantization axis = normal to the SA plane + ROOT::Math::XYZVector getSAAxis(const ROOT::Math::PxPyPzMVector& mother, double psiSA) + { + if (cfgSAFrame.value == kProductionPlane) { + return ROOT::Math::XYZVector(0., 0., 1.).Cross(mother.Vect()).Unit(); // z x p + } + return ROOT::Math::XYZVector(std::sin(cfgEPNormalHarmonic.value * psiSA), -std::cos(cfgEPNormalHarmonic.value * psiSA), 0.); + } + + // ---------------- event selection, common to all K* and phi(1020) process functions ---------------- + template + bool selectionEventRCT(const TCollision& collision) + { + return !rctCut.requireRCTFlagChecker || rctCut.rctChecker(collision); + } + + // additionalEvSel1-4 (data and reconstructed MC) + template + bool selectionEventBits(const TCollision& collision) + { + if (additionalEvSel1 && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return false; + } + if (additionalEvSel2 && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return false; + } + if (additionalEvSel3 && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + return true; + } + + // sel8, EP trigger and additionalEvSel1-4 + template + bool selectionEventCuts(const TCollision& collision) + { + return collision.sel8() && collision.triggereventep() && selectionEventBits(collision); + } + + // full data event selection without the occupancy cut + template + bool selectionEvent(const TCollision& collision) + { + return selectionEventRCT(collision) && selectionEventCuts(collision); + } + + template + bool selectionOccupancy(const TCollision& collision) + { + return !(fillOccupancy && collision.trackOccupancyInTimeRange() > cfgOccupancyCut); + } + + // mixed-event pair; occupancy rejects the pair only if both events are above the cut + template + bool selectionEventPairME(const TCollision& collision1, const TCollision& collision2) + { + if (!selectionEvent(collision1) || !selectionEvent(collision2)) { + return false; + } + if (collision1.bcId() == collision2.bcId()) { + return false; + } + return !(fillOccupancy && collision1.trackOccupancyInTimeRange() >= cfgOccupancyCut && collision2.trackOccupancyInTimeRange() >= cfgOccupancyCut); + } + + // ---------------- phi(1020) track and PID selections, identical to phipbpb.cxx ---------------- + + template + bool selectionTrackPhi(const T& candidate) + { + // table-level PIDcutFilter of phipbpb.cxx, applied here because this task also selects pions + if (!(std::abs(candidate.tpcNSigmaKa()) < phiSA.nsigmaCutTPC)) { + return false; + } + if (phiSA.useGlobalTrack && !phiSA.useDcaSyst && !(candidate.isGlobalTrack() && candidate.isPVContributor() && candidate.itsNCls() > phiSA.cfgITScluster && candidate.tpcNClsCrossedRows() > phiSA.cfgTPCcluster && candidate.tpcFractionSharedCls() < phiSA.cfgTPCSharedcluster)) { + return false; + } + if (phiSA.useGlobalTrack && phiSA.useDcaSyst && !(candidate.itsNCls() > phiSA.cfgITScluster && candidate.tpcNClsCrossedRows() > phiSA.cfgTPCcluster && candidate.tpcFractionSharedCls() < phiSA.cfgTPCSharedcluster)) { + return false; + } + if (!phiSA.useGlobalTrack && !(candidate.tpcNClsFound() > phiSA.cfgTPCcluster)) { + return false; + } + return true; + } + + static constexpr float PhiTPCOnlyPt = 0.5f; + template + bool selectionPIDpTdependentPhi(const T& candidate) + { + if (candidate.pt() < PhiTPCOnlyPt && std::abs(candidate.tpcNSigmaKa()) < phiSA.nsigmaCutTPC) { + return true; + } + if (candidate.pt() >= PhiTPCOnlyPt && candidate.hasTOF() && candidate.beta() > phiSA.cfgCutTOFBeta && std::abs(candidate.tpcNSigmaKa()) < phiSA.nsigmaCutTPC && std::abs(candidate.tofNSigmaKa()) < phiSA.nsigmaCutTOF) { + return true; + } + if (!phiSA.useGlobalTrack && !candidate.hasTPC()) { + return true; + } + return false; + } + + template + bool selectionPIDPhi(const T& candidate) + { + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < phiSA.nsigmaCutTPC) { + return true; + } + if (candidate.hasTOF() && candidate.beta() > phiSA.cfgCutTOFBeta && std::abs(candidate.tpcNSigmaKa()) < phiSA.nsigmaCutTPC && std::abs(candidate.tofNSigmaKa()) < phiSA.nsigmaCutTOF) { + return true; + } + return false; + } + + template + bool selectionPIDTOFOnlyPhi(const T& candidate) + { + return candidate.hasTOF() && candidate.beta() > phiSA.cfgCutTOFBeta && std::abs(candidate.tofNSigmaKa()) < phiSA.nsigmaCutTOF; + } + + // data PID: pT-dependent, standard or TOF-only + template + bool selectionKaonPhi(const T& candidate) + { + if (phiSA.ispTdepPID && !phiSA.isTOFOnly && !selectionPIDpTdependentPhi(candidate)) { + return false; + } + if (!phiSA.ispTdepPID && !phiSA.isTOFOnly && !selectionPIDPhi(candidate)) { + return false; + } + if (phiSA.isTOFOnly && !selectionPIDTOFOnlyPhi(candidate)) { + return false; + } + return true; + } + + static constexpr float PhiITSMaxP = 1.0f; + static constexpr float PhiITSNSigma = 2.5f; + template + bool selectionITSPhi(const T& candidate) + { + if (phiSA.useGlobalTrack && candidate.p() < PhiITSMaxP) { + auto nSigmaITS = itsResponse.nSigmaITS(candidate); + if (!(nSigmaITS > -PhiITSNSigma && nSigmaITS < PhiITSNSigma)) { + return false; + } + } + return true; + } + + // deep angle cut on pair to remove photon conversion + template + bool selectionPairPhi(const T1& candidate1, const T2& candidate2) + { + double pt1 = candidate1.pt(), pt2 = candidate2.pt(); + double pz1 = candidate1.pz(), pz2 = candidate2.pz(); + double p1 = candidate1.p(), p2 = candidate2.p(); + double angle = std::acos(std::clamp((pt1 * pt2 + pz1 * pz2) / (p1 * p2), -1.0, 1.0)); // clamp = TMath::ACos behaviour + return !(phiSA.isDeepAngle && angle < phiSA.cfgDeepAngle); + } + + template + bool isFakeKaonPhi(T const& track) + { + return std::abs(track.p() - track.tpcInnerParam()) > phiSA.confFakeKaonCut; + } + + // phipbpb.cxx builds the EP-frame MC efficiency with the in-plane vector at Psi = 0 (x axis); kept for identical results + ROOT::Math::XYZVector getSAAxisPhiMC(const ROOT::Math::PxPyPzMVector& mother, double psiSA) + { + if (cfgSAFrame.value == kEventPlane) { + return ROOT::Math::XYZVector(std::cos(2.0 * psiSA), std::sin(2.0 * psiSA), 0.); + } + return getSAAxis(mother, psiSA); + } + template bool isFakeKaon(T const& track, int /*PID*/) { @@ -418,45 +719,29 @@ struct Kstarpbpb { {6, -HalfPI, HalfPI}, "event plane angle"}; ConfigurableAxis axisOccup{"axisOccup", {20, -0.5, 40000.0}, "occupancy axis"}; - double v2 = 0.; - double v2Rot = 0.; using BinningTypeVertexContributor = ColumnBinningPolicy; - ROOT::Math::PxPyPzMVector kstarMother, fourVecDauCM, daughter1, daughter2, kaonrot, kstarrot, kaonPlus, pionMinus; - ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY, eventplaneVec, eventplaneVecNorm; - ROOT::Math::PxPyPzMVector daughter2rot, fourVecDauCMrot; - ROOT::Math::XYZVector threeVecDauCMrot, threeVecDauCMXYrot; int currentRunNumber = -999; int lastRunNumber = -999; TH2D* hweight = nullptr; + o2::aod::ITSResponse itsResponse; void processSE(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) { + // scratch vectors: local to this call, never carry state across events/tracks + ROOT::Math::PxPyPzMVector kstarMother, fourVecDauCM, daughter1, daughter2, kaonrot, kstarrot; + ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY, eventplaneVecNorm; + ROOT::Math::PxPyPzMVector fourVecDauCMrot; + ROOT::Math::XYZVector threeVecDauCMrot, threeVecDauCMXYrot; + double v2 = 0.; + double v2Rot = 0.; + histos.fill(HIST("hEvtSelInfo"), 0.5); - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision)) { + if (!selectionEventRCT(collision)) { return; } histos.fill(HIST("hEvtSelInfo"), 1.5); - if (!collision.sel8()) { - return; - } - if (!collision.triggereventep()) { - return; - } - if (additionalEvSel1 && - !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - return; - } - if (additionalEvSel2 && - !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { - return; - } - if (additionalEvSel3 && - !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { - return; - } - if (additionalEvSel4 && - !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (!selectionEventCuts(collision)) { return; } histos.fill(HIST("hEvtSelInfo"), 2.5); @@ -469,7 +754,7 @@ struct Kstarpbpb { auto qFT0C = collision.qFT0C(); auto qFT0A = collision.qFT0A(); auto qTPC = collision.qTPC(); - if (fillOccupancy && occupancy > cfgOccupancyCut) { + if (!selectionOccupancy(collision)) { return; } histos.fill(HIST("hEvtSelInfo"), 3.5); @@ -487,6 +772,17 @@ struct Kstarpbpb { histos.fill(HIST("hCentrality"), centrality); histos.fill(HIST("hOccupancy"), occupancy); histos.fill(HIST("hVtxZ"), collision.posZ()); + histos.fill(HIST("hQFT0CvsCent"), centrality, qFT0C); + histos.fill(HIST("hQFT0CvsVz"), collision.posZ(), qFT0C); + histos.fill(HIST("hQFT0AvsCent"), centrality, qFT0A); + histos.fill(HIST("hQFT0AvsVz"), collision.posZ(), qFT0A); + histos.fill(HIST("hQTPCvsCent"), centrality, qTPC); + histos.fill(HIST("hQTPCvsVz"), collision.posZ(), qTPC); + } + // one angle per event: Psi2 from FT0C, or a random angle for the random-EP null test + auto psiSA = getSAEventAngle(psiFT0C); + if (fillSA && cfgSAFrame.value == kRandomEventPlane) { + histos.fill(HIST("hPsiRandom"), centrality, psiSA); } auto bc = collision.bc_as(); currentRunNumber = collision.bc_as().runNumber(); @@ -554,8 +850,8 @@ struct Kstarpbpb { weight2 = 1; } } - daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassPi); kstarMother = daughter1 + daughter2; if (std::abs(kstarMother.Rapidity()) > confRapidity) { continue; @@ -603,9 +899,8 @@ struct Kstarpbpb { fourVecDauCM = boost(daughter1); threeVecDauCM = fourVecDauCM.Vect(); threeVecDauCMXY = ROOT::Math::XYZVector(threeVecDauCM.X(), threeVecDauCM.Y(), 0.); - eventplaneVec = ROOT::Math::XYZVector(std::cos(2.0 * psiFT0C), std::sin(2.0 * psiFT0C), 0); - eventplaneVecNorm = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); - auto cosPhistarminuspsi = getPhiInRange(fourVecDauCM.Phi() - psiFT0C); + eventplaneVecNorm = getSAAxis(kstarMother, psiSA); + auto cosPhistarminuspsi = getPhiInRange(fourVecDauCM.Phi() - getSAPlaneAngle(kstarMother, psiSA)); auto sa = std::cos(2.0 * cosPhistarminuspsi); auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); @@ -634,7 +929,7 @@ struct Kstarpbpb { } auto rotkaonPx = track1.px() * std::cos(rotangle) - track1.py() * std::sin(rotangle); auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); - kaonrot = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); + kaonrot = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), MassKa); kstarrot = kaonrot + daughter2; if (std::abs(kstarrot.Rapidity()) > confRapidity) { continue; @@ -656,9 +951,11 @@ struct Kstarpbpb { fourVecDauCMrot = boost(kaonrot); threeVecDauCMrot = fourVecDauCMrot.Vect(); threeVecDauCMXYrot = ROOT::Math::XYZVector(threeVecDauCMrot.X(), threeVecDauCMrot.Y(), 0.); - auto cosPhistarminuspsirot = getPhiInRange(fourVecDauCMrot.Phi() - psiFT0C); + // production-plane axis must follow the rotated candidate + auto saAxisRot = getSAAxis(kstarrot, psiSA); + auto cosPhistarminuspsirot = getPhiInRange(fourVecDauCMrot.Phi() - getSAPlaneAngle(kstarrot, psiSA)); auto sarot = std::cos(2.0 * cosPhistarminuspsirot); - auto cosThetaStarrot = eventplaneVecNorm.Dot(threeVecDauCMrot) / std::sqrt(threeVecDauCMrot.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); + auto cosThetaStarrot = saAxisRot.Dot(threeVecDauCMrot) / std::sqrt(threeVecDauCMrot.Mag2()) / std::sqrt(saAxisRot.Mag2()); if (usepolar) { histos.fill(HIST("hSparseSAvsraprot"), kstarrot.M(), kstarrot.Pt(), cosThetaStarrot, kstarrot.Rapidity(), centrality); } else { @@ -675,48 +972,16 @@ struct Kstarpbpb { void processMixedEvent(EventCandidates const& collisions, TrackCandidates const& tracks) { + // scratch vectors: local to this call, never carry state across pairs + ROOT::Math::PxPyPzMVector kstarMother, fourVecDauCM, daughter1, daughter2; + ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY, eventplaneVecNorm; + double v2 = 0.; auto tracksTuple = std::make_tuple(tracks); BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicityClass, axisEPAngle}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; for (const auto& [collision1, tracks1, collision2, tracks2] : pair) { - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision1)) { - continue; - } - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision2)) { - continue; - } - - if (!collision1.sel8() || - !collision2.sel8() || - - !collision1.triggereventep() || - !collision2.triggereventep() || - - (additionalEvSel1 && - (!collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || - !collision2.selection_bit(aod::evsel::kNoTimeFrameBorder))) || - - (additionalEvSel2 && - (!collision1.selection_bit(aod::evsel::kNoITSROFrameBorder) || - !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder))) || - - (additionalEvSel3 && - (!collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || - !collision2.selection_bit(aod::evsel::kNoSameBunchPileup))) || - - (additionalEvSel4 && - (!collision1.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV) || - !collision2.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)))) { - continue; - } - if (collision1.bcId() == collision2.bcId()) { - continue; - } - int occupancy1 = collision1.trackOccupancyInTimeRange(); - int occupancy2 = collision2.trackOccupancyInTimeRange(); - if (fillOccupancy && occupancy1 >= cfgOccupancyCut && occupancy2 >= cfgOccupancyCut) // occupancy info is available for this collision (*) - { + if (!selectionEventPairME(collision1, collision2)) { continue; } auto centrality = collision1.centFT0C(); @@ -724,6 +989,7 @@ struct Kstarpbpb { auto qFT0C1 = collision1.qFT0C(); auto psiFT0C2 = collision2.psiFT0C(); auto qFT0C2 = collision2.qFT0C(); + auto psiSA1 = getSAEventAngle(psiFT0C1); for (const auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { @@ -743,8 +1009,8 @@ struct Kstarpbpb { continue; } - daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassPi); kstarMother = daughter1 + daughter2; if (std::abs(kstarMother.Rapidity()) > confRapidity) { @@ -775,9 +1041,8 @@ struct Kstarpbpb { fourVecDauCM = boost(daughter1); threeVecDauCM = fourVecDauCM.Vect(); threeVecDauCMXY = ROOT::Math::XYZVector(threeVecDauCM.X(), threeVecDauCM.Y(), 0.); - eventplaneVec = ROOT::Math::XYZVector(std::cos(2.0 * psiFT0C1), std::sin(2.0 * psiFT0C1), 0); - eventplaneVecNorm = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C1), -std::cos(2.0 * psiFT0C1), 0); - auto cosPhistarminuspsi = getPhiInRange(fourVecDauCM.Phi() - psiFT0C1); + eventplaneVecNorm = getSAAxis(kstarMother, psiSA1); + auto cosPhistarminuspsi = getPhiInRange(fourVecDauCM.Phi() - getSAPlaneAngle(kstarMother, psiSA1)); auto sa = std::cos(2.0 * cosPhistarminuspsi); auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); if (usepolar) { @@ -801,6 +1066,10 @@ struct Kstarpbpb { void processMC(CollisionMCTrueTable::iterator const& /*TrueCollision*/, CollisionMCRecTableCentFT0C const& RecCollisions, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { + // scratch vectors: local to this call, never carry state across particles + ROOT::Math::PxPyPzMVector kstarMother, kaonPlus, pionMinus; + double v2 = 0.; + histos.fill(HIST("hMC"), 0); if (RecCollisions.size() == 0) { histos.fill(HIST("hMC"), 1); @@ -817,24 +1086,7 @@ struct Kstarpbpb { histos.fill(HIST("hMC"), 4); continue; } - - if (additionalEvSel1 && - !RecCollision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - continue; - } - - if (additionalEvSel2 && - !RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { - continue; - } - - if (additionalEvSel3 && - !RecCollision.selection_bit(aod::evsel::kNoSameBunchPileup)) { - continue; - } - - if (additionalEvSel4 && - !RecCollision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (!selectionEventBits(RecCollision)) { continue; } histos.fill(HIST("hMC"), 5); @@ -845,6 +1097,7 @@ struct Kstarpbpb { histos.fill(HIST("hMC"), 7); auto centrality = RecCollision.centFT0C(); histos.fill(HIST("CentPercentileMCRecHist"), centrality); + auto psiSA = getSAEventAngle(psiFT0C); // same angle for rec and gen of this event auto oldindex = -999; auto rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); // loop over reconstructed particle @@ -906,7 +1159,7 @@ struct Kstarpbpb { if (std::abs(mothertrack1.y()) > confRapidity) { continue; } - if (pdgcheck && std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kK0Star892) { + if (pdgcheck && mothertrack1.pdgCode() != o2::constants::physics::kK0Star892) { continue; } if (!isTOFOnly && !(strategySelectionPID(track1, 0, strategyPID) || strategySelectionPID(track2, 1, strategyPID))) { @@ -919,14 +1172,10 @@ struct Kstarpbpb { continue; } oldindex = mothertrack1.globalIndex(); - if (track1.sign() > 0 && track2.sign() < 0) { - kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - pionMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - } - if (track1.sign() < 0 && track2.sign() > 0) { - pionMinus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - kaonPlus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - } + // track1 is always the kaon-PID candidate and track2 always the pion-PID candidate (enforced above); + // assign unconditionally so the boost below always uses the true kaon, regardless of its charge sign + kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + pionMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassPi); kstarMother = kaonPlus + pionMinus; if (std::abs(kstarMother.Rapidity()) > confRapidity) { continue; @@ -943,8 +1192,8 @@ struct Kstarpbpb { ROOT::Math::Boost boost{kstarMother.BoostToCM()}; auto fourVecDauCMRec = boost(kaonPlus); auto threeVecDauCMRec = fourVecDauCMRec.Vect(); - auto eventplaneVecNormRec = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); - auto cosPhistarminuspsiRec = getPhiInRange(fourVecDauCMRec.Phi() - psiFT0C); + auto eventplaneVecNormRec = getSAAxis(kstarMother, psiSA); + auto cosPhistarminuspsiRec = getPhiInRange(fourVecDauCMRec.Phi() - getSAPlaneAngle(kstarMother, psiSA)); auto saRec = std::cos(2.0 * cosPhistarminuspsiRec); auto cosThetaStarRec = eventplaneVecNormRec.Dot(threeVecDauCMRec) / std::sqrt(threeVecDauCMRec.Mag2()) / std::sqrt(eventplaneVecNormRec.Mag2()); @@ -982,7 +1231,7 @@ struct Kstarpbpb { if (!genacceptancecut) { daughtp = true; } - kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), MassKa); } else if (kCurrentDaughter.pdgCode() == -PDG_t::kPiPlus) { if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtm = true; @@ -990,7 +1239,7 @@ struct Kstarpbpb { if (!genacceptancecut) { daughtm = true; } - pionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); + pionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), MassPi); } } if (daughtp && daughtm) { @@ -1009,8 +1258,8 @@ struct Kstarpbpb { ROOT::Math::Boost boost{kstarMother.BoostToCM()}; auto fourVecDauCMGen = boost(kaonPlus); auto threeVecDauCMGen = fourVecDauCMGen.Vect(); - auto eventplaneVecNormGen = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); - auto cosPhistarminuspsiGen = getPhiInRange(fourVecDauCMGen.Phi() - psiFT0C); + auto eventplaneVecNormGen = getSAAxis(kstarMother, psiSA); + auto cosPhistarminuspsiGen = getPhiInRange(fourVecDauCMGen.Phi() - getSAPlaneAngle(kstarMother, psiSA)); auto saGen = std::cos(2.0 * cosPhistarminuspsiGen); auto cosThetaStarGen = eventplaneVecNormGen.Dot(threeVecDauCMGen) / std::sqrt(threeVecDauCMGen.Mag2()) / std::sqrt(eventplaneVecNormGen.Mag2()); @@ -1026,6 +1275,9 @@ struct Kstarpbpb { void processMCkstarWeight(CollisionMCTrueTable::iterator const& TrueCollision, CollisionMCRecTableCentFT0C const& RecCollisions, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { + // scratch vectors: local to this call, never carry state across particles + ROOT::Math::PxPyPzMVector kaonPlus, pionMinus; + float imp = TrueCollision.impactParameter(); float evPhi = TrueCollision.eventPlaneAngle() / 2.0; static constexpr std::array CentEdges = { @@ -1107,16 +1359,6 @@ struct Kstarpbpb { if (track1PDG != PDG_t::kKPlus || track2PDG != PDG_t::kPiPlus) { continue; } - if (!selectionTrack(track1) || !selectionTrack(track2) || track1.sign() * track2.sign() > 0) { - continue; - } - // PID check - if (!isTOFOnly && (!strategySelectionPID(track1, 0, strategyPID) || !strategySelectionPID(track2, 1, strategyPID))) { - continue; - } - if (isTOFOnly && (!selectionPID2(track1, 0) || !selectionPID2(track2, 1))) { - continue; - } for (const auto& mothertrack1 : mctrack1.mothers_as()) { for (const auto& mothertrack2 : mctrack2.mothers_as()) { if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { @@ -1178,12 +1420,12 @@ struct Kstarpbpb { if (kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtp = true; } - kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), MassKa); } else if (kCurrentDaughter.pdgCode() == -PDG_t::kPiPlus) { if (kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtm = true; } - pionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); + pionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), MassPi); } } if (daughtp && daughtm) { @@ -1195,6 +1437,272 @@ struct Kstarpbpb { } // process MC PROCESS_SWITCH(Kstarpbpb, processMCkstarWeight, "Process MC kstar Weight", false); + + // ================= phi(1020) spin alignment: port of the SA part of phipbpb.cxx ================= + struct SAValues { + double cosThetaStar; + double sa; + }; + + // K- in the phi rest frame (as in phipbpb.cxx) w.r.t. the chosen quantization axis + SAValues getSAValuesPhi(const ROOT::Math::PxPyPzMVector& mother, const ROOT::Math::PxPyPzMVector& kaonMinus, const ROOT::Math::XYZVector& axis, double psiSA) + { + ROOT::Math::Boost boost{mother.BoostToCM()}; + auto threeVecDau = boost(kaonMinus).Vect(); + auto cosThetaStar = axis.Dot(threeVecDau) / std::sqrt(threeVecDau.Mag2()) / std::sqrt(axis.Mag2()); + auto sa = std::cos(2.0 * getPhiInRange(threeVecDau.Phi() - getSAPlaneAngle(mother, psiSA))); + return {cosThetaStar, sa}; + } + + void processSEPhi(EventCandidates::iterator const& collision, TrackCandidates const& tracks) + { + if (!selectionEvent(collision) || !selectionOccupancy(collision)) { + return; + } + auto centrality = collision.centFT0C(); + auto psiSA = getSAEventAngle(collision.psiFT0C()); + if (cfgSAFrame.value == kRandomEventPlane) { + histos.fill(HIST("phi/hPsiRandom"), centrality, psiSA); + } + + ROOT::Math::PxPyPzMVector kaonPlusPhi, kaonMinusPhi, phiMother; + for (const auto& track1 : tracks) { + if (!(track1.signed1Pt() > cfgCutCharge.value)) { // positive kaon + continue; + } + if (!selectionTrackPhi(track1) || !selectionKaonPhi(track1) || !selectionITSPhi(track1)) { + continue; + } + for (const auto& track2 : tracks) { + if (!(track2.signed1Pt() < cfgCutCharge.value)) { // negative kaon + continue; + } + if (!selectionTrackPhi(track2) || !selectionKaonPhi(track2)) { + continue; + } + if (!selectionPairPhi(track1, track2)) { + continue; + } + if (phiSA.removeFakeTrack && (isFakeKaonPhi(track1) || isFakeKaonPhi(track2))) { + continue; + } + if (!selectionITSPhi(track2)) { + continue; + } + kaonPlusPhi = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + kaonMinusPhi = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassKa); + phiMother = kaonPlusPhi + kaonMinusPhi; + auto [cosThetaStar, sa] = getSAValuesPhi(phiMother, kaonMinusPhi, getSAAxis(phiMother, psiSA), psiSA); + auto absRapidity = std::abs(phiMother.Rapidity()); + histos.fill(HIST("phi/hSparseV2SameEventSA"), phiMother.M(), phiMother.Pt(), sa, absRapidity, centrality); + histos.fill(HIST("phi/hSparseV2SameEventCosThetaStar"), phiMother.M(), phiMother.Pt(), cosThetaStar, absRapidity, centrality); + } + } + } + PROCESS_SWITCH(Kstarpbpb, processSEPhi, "Process same event phi(1020) spin alignment", false); + + void processMEPhi(EventCandidates const& collisions, TrackCandidates const& tracks) + { + auto tracksTuple = std::make_tuple(tracks); + BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicityClass, axisEPAngle}, true}; + SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + ROOT::Math::PxPyPzMVector kaonPlusPhi, kaonMinusPhi, phiMother; + for (const auto& [collision1, tracks1, collision2, tracks2] : pair) { + if (!selectionEventPairME(collision1, collision2)) { + continue; + } + auto centrality = collision1.centFT0C(); + auto psiSA = getSAEventAngle(collision1.psiFT0C()); + for (const auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (track1.sign() * track2.sign() > 0) { + continue; + } + if (!selectionITSPhi(track1) || !selectionITSPhi(track2)) { + continue; + } + if (!selectionTrackPhi(track1) || !selectionTrackPhi(track2)) { + continue; + } + if (!selectionKaonPhi(track1) || !selectionKaonPhi(track2)) { + continue; + } + if (!selectionPairPhi(track1, track2)) { + continue; + } + if (phiSA.removeFakeTrack && (isFakeKaonPhi(track1) || isFakeKaonPhi(track2))) { + continue; + } + if (track1.sign() > 0) { + kaonPlusPhi = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + kaonMinusPhi = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassKa); + } else { + kaonMinusPhi = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + kaonPlusPhi = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassKa); + } + phiMother = kaonPlusPhi + kaonMinusPhi; + auto [cosThetaStar, sa] = getSAValuesPhi(phiMother, kaonMinusPhi, getSAAxis(phiMother, psiSA), psiSA); + auto absRapidity = std::abs(phiMother.Rapidity()); + histos.fill(HIST("phi/hSparseV2MixedEventSA"), phiMother.M(), phiMother.Pt(), sa, absRapidity, centrality); + histos.fill(HIST("phi/hSparseV2MixedEventCosThetaStar"), phiMother.M(), phiMother.Pt(), cosThetaStar, absRapidity, centrality); + } + } + } + PROCESS_SWITCH(Kstarpbpb, processMEPhi, "Process mixed event phi(1020) spin alignment", false); + + void processMCPhi(CollisionMCTrueTable::iterator const& /*TrueCollision*/, CollisionMCRecTableCentFT0C const& RecCollisions, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) + { + histos.fill(HIST("phi/hMC"), 0); + if (RecCollisions.size() == 0) { + histos.fill(HIST("phi/hMC"), 1); + return; + } + if (RecCollisions.size() > 1) { + histos.fill(HIST("phi/hMC"), 2); + return; + } + ROOT::Math::PxPyPzMVector kaonPlusPhi, kaonMinusPhi, phiMother; + for (const auto& RecCollision : RecCollisions) { + auto psiFT0C = 0.0; + histos.fill(HIST("phi/hMC"), 3); + if (!RecCollision.sel8()) { + histos.fill(HIST("phi/hMC"), 4); + continue; + } + if (!selectionEventBits(RecCollision)) { + continue; + } + histos.fill(HIST("phi/hMC"), 5); // same bin meaning as the K* hMC + if (std::abs(RecCollision.posZ()) > cfgCutVertex) { + histos.fill(HIST("phi/hMC"), 6); + continue; + } + histos.fill(HIST("phi/hMC"), 7); + auto centrality = RecCollision.centFT0C(); + histos.fill(HIST("phi/CentPercentileMCRecHist"), centrality); + auto psiSA = getSAEventAngle(psiFT0C); // same angle for rec and gen of this event + auto oldindex = -999; + auto rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); + // loop over reconstructed particle + for (const auto& track1 : rectrackspart) { + if (!selectionTrackPhi(track1)) { + continue; + } + if (phiSA.ispTdepPID && !selectionPIDpTdependentPhi(track1)) { + continue; + } + if (!phiSA.ispTdepPID && !selectionPIDPhi(track1)) { + continue; + } + if (!track1.has_mcParticle()) { + continue; + } + auto track1ID = track1.index(); + for (const auto& track2 : rectrackspart) { + auto track2ID = track2.index(); + if (track2ID <= track1ID) { + continue; + } + if (!selectionTrackPhi(track2)) { + continue; + } + if (phiSA.ispTdepPID && !selectionPIDpTdependentPhi(track2)) { + continue; + } + if (!phiSA.ispTdepPID && !selectionPIDPhi(track2)) { + continue; + } + if (!track2.has_mcParticle()) { + continue; + } + if (!selectionPairPhi(track1, track2)) { + continue; + } + if (track1.sign() * track2.sign() > 0) { + continue; + } + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + if (!mctrack1.isPhysicalPrimary() || !mctrack2.isPhysicalPrimary()) { + continue; + } + if (std::abs(mctrack1.pdgCode()) != PDG_t::kKPlus || std::abs(mctrack2.pdgCode()) != PDG_t::kKPlus) { + continue; + } + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { + if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { + continue; + } + if (mothertrack1 != mothertrack2) { + continue; + } + if (std::abs(mothertrack1.y()) > phiSA.confRapidity) { + continue; + } + if (std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kPhi) { + continue; + } + if (!selectionPIDPhi(track1) || !selectionPIDPhi(track2)) { + continue; + } + if (phiSA.avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { + histos.fill(HIST("phi/h1PhiRecsplit"), mothertrack1.pt()); + continue; + } + oldindex = mothertrack1.globalIndex(); + if (track1.sign() > 0) { + kaonPlusPhi = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + kaonMinusPhi = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassKa); + } else { + kaonMinusPhi = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), MassKa); + kaonPlusPhi = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), MassKa); + } + phiMother = kaonPlusPhi + kaonMinusPhi; + auto [cosThetaStar, sa] = getSAValuesPhi(phiMother, kaonMinusPhi, getSAAxisPhiMC(phiMother, psiSA), psiSA); + histos.fill(HIST("phi/hSparseV2MCRecCosThetaStar_effy"), phiMother.M(), phiMother.Pt(), cosThetaStar, std::abs(phiMother.Rapidity()), centrality); + histos.fill(HIST("phi/hSparseV2MCRecSA"), phiMother.M(), phiMother.Pt(), sa, std::abs(phiMother.Rapidity()), centrality); + } + } + } + } + // loop over generated particle + for (const auto& mcParticle : GenParticles) { + if (std::abs(mcParticle.y()) > phiSA.confRapidity) { + continue; + } + if (mcParticle.pdgCode() != o2::constants::physics::kPhi) { + continue; + } + auto kDaughters = mcParticle.daughters_as(); + static constexpr std::size_t NumberOfDaughters = 2; + if (kDaughters.size() != NumberOfDaughters) { + continue; + } + auto daughtp = false; + auto daughtm = false; + for (const auto& kCurrentDaughter : kDaughters) { + if (!kCurrentDaughter.isPhysicalPrimary()) { + continue; + } + bool inAcceptance = !phiSA.genacceptancecut || (kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta); + if (kCurrentDaughter.pdgCode() == +PDG_t::kKPlus) { + daughtp = daughtp || inAcceptance; + kaonPlusPhi = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), MassKa); + } else if (kCurrentDaughter.pdgCode() == -PDG_t::kKPlus) { + daughtm = daughtm || inAcceptance; + kaonMinusPhi = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), MassKa); + } + } + if (daughtp && daughtm) { + phiMother = kaonPlusPhi + kaonMinusPhi; + auto [cosThetaStar, sa] = getSAValuesPhi(phiMother, kaonMinusPhi, getSAAxisPhiMC(phiMother, psiSA), psiSA); + histos.fill(HIST("phi/hSparseV2MCGenCosThetaStar_effy"), phiMother.M(), phiMother.Pt(), cosThetaStar, std::abs(phiMother.Rapidity()), centrality); + histos.fill(HIST("phi/hSparseV2MCGenSA"), phiMother.M(), phiMother.Pt(), sa, std::abs(phiMother.Rapidity()), centrality); + } + } + } // rec collision loop + } + PROCESS_SWITCH(Kstarpbpb, processMCPhi, "Process MC phi(1020) spin alignment", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx b/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx index afbed255a6e..2a27e2541ac 100644 --- a/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx @@ -157,6 +157,11 @@ struct Phianalysisrun3pbpb { histos.add("h2PhiRapidity", "phi meson Rapidity", kTH2F, {ptAxisphi, {200, -4, 4}}); histos.add("hEta", "eta of kaon track candidates", HistType::kTH2F, {{200, -1.0f, 1.0f}, ptAxisphi}); histos.add("hPhi", "phi of kaon track candidates", HistType::kTH2F, {{65, 0, 6.5}, ptAxisphi}); + histos.add("QAbefore/TPC_Nsigma_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon}", {HistType::kTH3D, {{200, -12, 12}, centAxisphi, ptAxisphi}}); + histos.add("QAbefore/TOF_Nsigma_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon}", {HistType::kTH3D, {{200, -12, 12}, centAxisphi, ptAxisphi}}); + histos.add("QAbefore/trkDCAxy", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAz", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/TOF_TPC_Mapka_all", "TOF + TPC Combined PID for Kaon;#sigma_{TOF}^{Kaon};#sigma_{TPC}^{Kaon}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); // DCA QA // DCA histograms: separate for positive and negative kaons, range [-1.0, 1.0] @@ -200,46 +205,35 @@ struct Phianalysisrun3pbpb { histos.add("QAafter/TPC_Nsigma_all_neg", "TPC NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, centAxisphi, ptAxisphi}}); } else { histos.add("hMC", "MC Event statistics", kTH1F, {{15, 0.0f, 15.0f}}); - histos.add("EL1", "MC Event statistics", kTH1F, {impactParAxis}); - histos.add("EL2", "MC Event statistics", kTH1F, {centAxis}); - histos.add("ES1", "MC Event statistics", kTH1F, {impactParAxis}); - histos.add("ES3", "MC Event statistics", kTH1F, {impactParAxis}); - histos.add("ES2", "MC Event statistics", kTH1F, {centAxis}); - histos.add("ES4", "MC Event statistics", kTH1F, {centAxis}); histos.add("h1PhiGen", "Phi meson Gen", kTH1F, {ptAxisphi}); histos.add("h1PhiGen1", "Phi meson Gen", kTH1F, {ptAxisphi}); histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {ptAxisphi}); histos.add("Centrec", "MC Centrality", kTH1F, {centAxisphi}); histos.add("Centgen", "MC Centrality", kTH1F, {centAxisphi}); - histos.add("hVtxZgen", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); histos.add("hVtxZrec", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {ptAxisphi, centAxisphi}); histos.add("h3PhiRec3", "Phi meson Rec", kTH3F, {ptAxisphi, centAxisphi, massAxisphi}); - histos.add("h3Phi1Rec3", "Phi meson Rec", kTH3F, {ptAxisphi, centAxisphi, massAxisphi}); - histos.add("h3PhiGen3", "Phi meson Gen", kTH3F, {ptAxisphi, centAxisphi, massAxisphi}); histos.add("h3PhiInvMassMixedMC", "Invariant mass of Phi meson Mixed", kTH3F, {centAxisphi, ptAxisphi, massAxisphi}); histos.add("h3PhiInvMassSameMC", "Invariant mass of Phi meson same", kTH3F, {centAxisphi, ptAxisphi, massAxisphi}); histos.add("h3PhiInvMassSameMC1", "Invariant mass of Phi meson same", kTH3F, {centAxisphi, ptAxisphi, massAxisphi}); histos.add("h3PhiInvMassRotMC", "Invariant mass of Phi meson Rotation", kTH3F, {centAxisphi, ptAxisphi, massAxisphi}); histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {ptAxisphi, centAxisphi}); - histos.add("h2PhiGen1", "Phi meson gen", kTH2F, {ptAxis, impactParAxis}); histos.add("h1PhiRec1", "Phi meson Rec", kTH1F, {ptAxisphi}); histos.add("h1Phimassgen", "Phi meson gen", kTH1F, {massAxisphi}); histos.add("h1Phimassrec", "Phi meson Rec", kTH1F, {massAxisphi}); histos.add("h1Phimasssame", "Phi meson Rec", kTH1F, {massAxisphi}); histos.add("h1Phimassmix", "Phi meson Rec", kTH1F, {massAxisphi}); histos.add("h1Phimassrot", "Phi meson Rec", kTH1F, {massAxisphi}); - histos.add("h1Phi1massrec", "Phi meson Rec", kTH1F, {massAxisphi}); histos.add("h1Phipt", "Phi meson Rec", kTH1F, {ptAxisphi}); - histos.add("hOccupancy1", "Occupancy distribution", kTH1F, {{500, 0, 50000}}); histos.add("h1PhifinalRec", "Phi meson Rec", kTH1F, {ptAxisphi}); histos.add("h1Phifinalgenmass", "Phi meson gen mass", kTH1F, {massAxisphi}); histos.add("h3PhifinalRec", "Phi meson Rec", kTH3F, {ptAxisphi, centAxisphi, massAxisphi}); // Mass resolution: Rec-Gen invariant mass difference per truth-matched candidate, - // binned in (generated pT, centrality). Idea from h3PhiRec in - // https://github.com/sarjeetagami/O2Physics/blob/db08910960e93e188969354ae8925ca0c2a0a0a1/PWGLF/Tasks/Resonances/phianalysisrun3.cxx - // (there binned in genPt/recPt instead of genPt/centrality). Lets the - // resolution be obtained directly from mean/RMS or a Gaussian fit of the + // binned in (reconstructed pT, centrality) so it lines up with how real data + // (and every other Rec-level histogram in this file) is binned - resolution vs. + // pT is only comparable to the data-driven Voigtian-width proxy if both use the + // same, measurable (reconstructed) pT axis, not the MC-truth generated pT. + // Lets the resolution be obtained directly from mean/RMS or a Gaussian fit of the // projected deltaM distribution per pT bin, instead of only from the // Voigtian-sigma method (resv.cxx) that h3PhifinalRec alone supports. histos.add("h3PhiRecoResolution", "Phi meson Rec-Gen mass difference", kTH3F, {ptAxisphi, centAxisphi, deltaMassAxisphi}); @@ -252,12 +246,6 @@ struct Phianalysisrun3pbpb { histos.add("Centmix", "MC Centrality", kTH1F, {centAxisphi}); histos.add("Centgen1", "MC Centrality", kTH1F, {centAxisphi}); histos.add("h1PhiRecsplit1", "Phi meson Rec split", kTH1F, {ptAxisphi}); - histos.add("hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); - histos.add("hImpactParameterRec", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); - histos.add("hImpactParameterGenCen", "Impact parameter of generated MC events", kTH2F, {impactParAxis, centAxis}); - histos.add("hImpactParameterRecCen", "Impact parameter of generated MC events", kTH2F, {impactParAxis, centAxis}); - histos.add("TOF_Nsigma_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxisphi, ptAxisphi}}); - histos.add("TPC_Nsigma_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxisphi, ptAxisphi}}); histos.add("TOF_Nsigma1_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxisphi, ptAxisphi}}); histos.add("TPC_Nsigma1_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, centAxisphi, ptAxisphi}}); histos.add("trkDCAxy", "DCAxy distribution of positive kaon track candidates", HistType::kTH3F, {{150, -1.0f, 1.0f}, centAxisphi, ptAxisphi}); @@ -505,6 +493,32 @@ struct Phianalysisrun3pbpb { } } } + template + void fillMixedPairs(const T1& tracks1, const T2& tracks2, float multiplicity) + { + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + bool unlike = false; + bool likesign = false; + bool mix = true; + if (!selectionTrack(t1)) { + continue; + } + if (!selectionTrack(t2)) { + continue; + } + if (!selectionPair(t1, t2)) { + continue; + } + if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { + fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); + } + if (ispTdepPID && + (selectionPIDpTdependent(t1, 0) || selectionPIDpTdependent(t1, 1)) && + (selectionPIDpTdependent(t2, 0) || selectionPIDpTdependent(t2, 1))) { + fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); + } + } + } Filter collisionFilter = (!selectionConfig.cutvz) || (nabs(aod::collision::posZ) < selectionConfig.cfgCutVertex); @@ -699,340 +713,71 @@ struct Phianalysisrun3pbpb { } PROCESS_SWITCH(Phianalysisrun3pbpb, processSameEvent, "Process Same event", false); - void processMixedEvent1(EventCandidates const& collisions, TrackCandidates const& tracks) + void processMixedEvent(EventCandidates const& collisions, TrackCandidates const& tracks) { auto tracksTuple = std::make_tuple(tracks); - //////// currently mixing the event with similar TPC multiplicity //////// - BinningTypeVertexContributor1 binningOnPositions{{axisVertex, axisMultiplicity}, true}; - SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { - continue; - } - if (rctCut.requireRCTFlagChecker && !rctChecker(c2)) { - continue; - } - if (!c1.sel8()) { - continue; - } - if (!c2.sel8()) { - continue; - } - if (selectionConfig.selHasBC && (!c1.has_foundBC() || !c2.has_foundBC())) { - continue; - } - if (selectionConfig.selHasFT0 && (!c1.has_foundFT0() || !c2.has_foundFT0())) { - continue; - } - if (selectionConfig.additionalEvSel1 && (!c1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !c2.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel2 && (!c1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !c2.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel3 && (!c1.selection_bit(aod::evsel::kNoSameBunchPileup) || !c2.selection_bit(aod::evsel::kNoSameBunchPileup))) { - continue; - } - if (selectionConfig.additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { - continue; - } - if (selectionConfig.additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { - continue; - } - if (selectionConfig.additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - continue; - } - if (selectionConfig.isINELgt0 && - (!c1.isInelGt0() || !c2.isInelGt0())) { - continue; - } - - int occupancy1 = c1.trackOccupancyInTimeRange(); - int occupancy2 = c2.trackOccupancyInTimeRange(); - - if (selectionConfig.fillOccupancy && - ((occupancy1 < cfgMinOccupancy || occupancy1 > cfgMaxOccupancy) || - (occupancy2 < cfgMinOccupancy || occupancy2 > cfgMaxOccupancy))) { - continue; - } - float multiplicity = c1.centFT0C(); - for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - bool unlike = false; - bool likesign = false; - bool mix = true; - if (!selectionTrack(t1)) { - continue; - } - if (!selectionTrack(t2)) { + //////// currently mixing the event with similar multiplicity; estimator picked at runtime via centestimator //////// + const int kCentFT0C = 0; + const int kCentFT0A = 1; + const int kCentFT0M = 2; + const int kCentFV0A = 3; + if (centestimator == kCentFT0C) { + BinningTypeVertexContributor1 binningOnPositions{{axisVertex, axisMultiplicity}, true}; + SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + for (const auto& [c1, tracks1, c2, tracks2] : pair) { + if (rctCut.requireRCTFlagChecker && (!rctChecker(c1) || !rctChecker(c2))) { continue; } - if (!selectionPair(t1, t2)) { + if (!myEventSelections(c1) || !myEventSelections(c2)) { continue; } - if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } - if (ispTdepPID && - (selectionPIDpTdependent(t1, 0) || selectionPIDpTdependent(t1, 1)) && - (selectionPIDpTdependent(t2, 0) || selectionPIDpTdependent(t2, 1))) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } - } - } - } - PROCESS_SWITCH(Phianalysisrun3pbpb, processMixedEvent1, "Process Mixed event", false); - void processMixedEvent2(EventCandidates const& collisions, TrackCandidates const& tracks) - { - auto tracksTuple = std::make_tuple(tracks); - //////// currently mixing the event with similar TPC multiplicity //////// - BinningTypeVertexContributor2 binningOnPositions{{axisVertex, axisMultiplicity}, true}; - SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { - continue; - } - if (rctCut.requireRCTFlagChecker && !rctChecker(c2)) { - continue; - } - if (!c1.sel8()) { - continue; - } - if (!c2.sel8()) { - continue; + fillMixedPairs(tracks1, tracks2, c1.centFT0C()); } - if (selectionConfig.selHasBC && (!c1.has_foundBC() || !c2.has_foundBC())) { - continue; - } - if (selectionConfig.selHasFT0 && (!c1.has_foundFT0() || !c2.has_foundFT0())) { - continue; - } - if (selectionConfig.additionalEvSel1 && (!c1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !c2.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel2 && (!c1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !c2.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel3 && (!c1.selection_bit(aod::evsel::kNoSameBunchPileup) || !c2.selection_bit(aod::evsel::kNoSameBunchPileup))) { - continue; - } - if (selectionConfig.additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { - continue; - } - if (selectionConfig.additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { - continue; - } - if (selectionConfig.additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - continue; - } - if (selectionConfig.isINELgt0 && - (!c1.isInelGt0() || !c2.isInelGt0())) { - continue; - } - - int occupancy1 = c1.trackOccupancyInTimeRange(); - int occupancy2 = c2.trackOccupancyInTimeRange(); - - if (selectionConfig.fillOccupancy && - ((occupancy1 < cfgMinOccupancy || occupancy1 > cfgMaxOccupancy) || - (occupancy2 < cfgMinOccupancy || occupancy2 > cfgMaxOccupancy))) { - continue; - } - float multiplicity = c1.centFT0A(); - for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - bool unlike = false; - bool likesign = false; - bool mix = true; - if (!selectionTrack(t1)) { - continue; - } - if (!selectionTrack(t2)) { + } else if (centestimator == kCentFT0A) { + BinningTypeVertexContributor2 binningOnPositions{{axisVertex, axisMultiplicity}, true}; + SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + for (const auto& [c1, tracks1, c2, tracks2] : pair) { + if (rctCut.requireRCTFlagChecker && (!rctChecker(c1) || !rctChecker(c2))) { continue; } - if (!selectionPair(t1, t2)) { + if (!myEventSelections(c1) || !myEventSelections(c2)) { continue; } - if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } - if (ispTdepPID && - (selectionPIDpTdependent(t1, 0) || selectionPIDpTdependent(t1, 1)) && - (selectionPIDpTdependent(t2, 0) || selectionPIDpTdependent(t2, 1))) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } - } - } - } - - PROCESS_SWITCH(Phianalysisrun3pbpb, processMixedEvent2, "Process Mixed event", false); - void processMixedEvent3(EventCandidates const& collisions, TrackCandidates const& tracks) - { - auto tracksTuple = std::make_tuple(tracks); - //////// currently mixing the event with similar TPC multiplicity //////// - BinningTypeVertexContributor3 binningOnPositions{{axisVertex, axisMultiplicity}, true}; - SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { - continue; - } - if (rctCut.requireRCTFlagChecker && !rctChecker(c2)) { - continue; - } - if (!c1.sel8()) { - continue; - } - if (!c2.sel8()) { - continue; - } - if (selectionConfig.selHasBC && (!c1.has_foundBC() || !c2.has_foundBC())) { - continue; - } - if (selectionConfig.selHasFT0 && (!c1.has_foundFT0() || !c2.has_foundFT0())) { - continue; - } - if (selectionConfig.additionalEvSel1 && (!c1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !c2.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel2 && (!c1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !c2.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel3 && (!c1.selection_bit(aod::evsel::kNoSameBunchPileup) || !c2.selection_bit(aod::evsel::kNoSameBunchPileup))) { - continue; - } - if (selectionConfig.additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { - continue; - } - if (selectionConfig.additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { - continue; - } - if (selectionConfig.additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - continue; - } - if (selectionConfig.isINELgt0 && - (!c1.isInelGt0() || !c2.isInelGt0())) { - continue; - } - - int occupancy1 = c1.trackOccupancyInTimeRange(); - int occupancy2 = c2.trackOccupancyInTimeRange(); - - if (selectionConfig.fillOccupancy && - ((occupancy1 < cfgMinOccupancy || occupancy1 > cfgMaxOccupancy) || - (occupancy2 < cfgMinOccupancy || occupancy2 > cfgMaxOccupancy))) { - continue; + fillMixedPairs(tracks1, tracks2, c1.centFT0A()); } - float multiplicity = c1.centFT0M(); - for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - bool unlike = false; - bool likesign = false; - bool mix = true; - if (!selectionTrack(t1)) { - continue; - } - if (!selectionTrack(t2)) { + } else if (centestimator == kCentFT0M) { + BinningTypeVertexContributor3 binningOnPositions{{axisVertex, axisMultiplicity}, true}; + SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + for (const auto& [c1, tracks1, c2, tracks2] : pair) { + if (rctCut.requireRCTFlagChecker && (!rctChecker(c1) || !rctChecker(c2))) { continue; } - if (!selectionPair(t1, t2)) { + if (!myEventSelections(c1) || !myEventSelections(c2)) { continue; } - if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } - if (ispTdepPID && - (selectionPIDpTdependent(t1, 0) || selectionPIDpTdependent(t1, 1)) && - (selectionPIDpTdependent(t2, 0) || selectionPIDpTdependent(t2, 1))) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } - } - } - } - - PROCESS_SWITCH(Phianalysisrun3pbpb, processMixedEvent3, "Process Mixed event", false); - void processMixedEvent4(EventCandidates const& collisions, TrackCandidates const& tracks) - { - auto tracksTuple = std::make_tuple(tracks); - //////// currently mixing the event with similar TPC multiplicity //////// - BinningTypeVertexContributor4 binningOnPositions{{axisVertex, axisMultiplicity}, true}; - SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { - continue; - } - if (rctCut.requireRCTFlagChecker && !rctChecker(c2)) { - continue; + fillMixedPairs(tracks1, tracks2, c1.centFT0M()); } - if (!c1.sel8()) { - continue; - } - if (!c2.sel8()) { - continue; - } - if (selectionConfig.selHasBC && (!c1.has_foundBC() || !c2.has_foundBC())) { - continue; - } - if (selectionConfig.selHasFT0 && (!c1.has_foundFT0() || !c2.has_foundFT0())) { - continue; - } - if (selectionConfig.additionalEvSel1 && (!c1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !c2.selection_bit(aod::evsel::kNoTimeFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel2 && (!c1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !c2.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - continue; - } - if (selectionConfig.additionalEvSel3 && (!c1.selection_bit(aod::evsel::kNoSameBunchPileup) || !c2.selection_bit(aod::evsel::kNoSameBunchPileup))) { - continue; - } - if (selectionConfig.additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { - continue; - } - if (selectionConfig.additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { - continue; - } - if (selectionConfig.additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - continue; - } - if (selectionConfig.isINELgt0 && - (!c1.isInelGt0() || !c2.isInelGt0())) { - continue; - } - - int occupancy1 = c1.trackOccupancyInTimeRange(); - int occupancy2 = c2.trackOccupancyInTimeRange(); - - if (selectionConfig.fillOccupancy && - ((occupancy1 < cfgMinOccupancy || occupancy1 > cfgMaxOccupancy) || - (occupancy2 < cfgMinOccupancy || occupancy2 > cfgMaxOccupancy))) { - continue; - } - float multiplicity = c1.centFV0A(); - for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - bool unlike = false; - bool likesign = false; - bool mix = true; - if (!selectionTrack(t1)) { - continue; - } - if (!selectionTrack(t2)) { + } else if (centestimator == kCentFV0A) { + BinningTypeVertexContributor4 binningOnPositions{{axisVertex, axisMultiplicity}, true}; + SameKindPair pair{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + for (const auto& [c1, tracks1, c2, tracks2] : pair) { + if (rctCut.requireRCTFlagChecker && (!rctChecker(c1) || !rctChecker(c2))) { continue; } - if (!selectionPair(t1, t2)) { + if (!myEventSelections(c1) || !myEventSelections(c2)) { continue; } - if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } - if (ispTdepPID && - (selectionPIDpTdependent(t1, 0) || selectionPIDpTdependent(t1, 1)) && - (selectionPIDpTdependent(t2, 0) || selectionPIDpTdependent(t2, 1))) { - fillinvMass(t1, t2, multiplicity, unlike, mix, likesign, massKa, massKa); - } + fillMixedPairs(tracks1, tracks2, c1.centFV0A()); } } } - - PROCESS_SWITCH(Phianalysisrun3pbpb, processMixedEvent4, "Process Mixed event", false); + PROCESS_SWITCH(Phianalysisrun3pbpb, processMixedEvent, "Process Mixed event", false); void processRotEvent(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCs const&) { - if (!collision.sel8()) { + if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) { + return; + } + if (cfgDoSel8 && !collision.sel8()) { return; } if (selectionConfig.selHasBC && !collision.has_foundBC()) { @@ -1041,19 +786,44 @@ struct Phianalysisrun3pbpb { if (selectionConfig.selHasFT0 && !collision.has_foundFT0()) { return; } - if (selectionConfig.additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + if (selectionConfig.additionalEvSel1 && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return; + } + if (selectionConfig.additionalEvSel2 && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return; + } + if (selectionConfig.additionalEvSel3 && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { return; } - if (selectionConfig.additionalEvSel3 && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { + if (selectionConfig.additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return; + } + if (selectionConfig.additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + if (selectionConfig.additionalEvSel6 && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { return; } int occupancy = collision.trackOccupancyInTimeRange(); if (selectionConfig.fillOccupancy && (occupancy < cfgMinOccupancy || occupancy > cfgMaxOccupancy)) { return; } + if (selectionConfig.isINELgt0 && !collision.isInelGt0()) { + return; + } float multiplicity{-1}; - if (cfgMultFT0) { + const int kCentFT0C = 0; + const int kCentFT0A = 1; + const int kCentFT0M = 2; + const int kCentFV0A = 3; + if (centestimator == kCentFT0C) { multiplicity = collision.centFT0C(); + } else if (centestimator == kCentFT0A) { + multiplicity = collision.centFT0A(); + } else if (centestimator == kCentFT0M) { + multiplicity = collision.centFT0M(); + } else if (centestimator == kCentFV0A) { + multiplicity = collision.centFV0A(); } histos.fill(HIST("hCentrality"), multiplicity); histos.fill(HIST("hVtxZ"), collision.posZ()); @@ -1107,8 +877,7 @@ struct Phianalysisrun3pbpb { for (int nrotbkg = 0; nrotbkg < nBkgRotations; nrotbkg++) { auto anglestart = confMinRot; auto angleend = confMaxRot; - auto anglestep = (angleend - anglestart) / (1.0 * (nBkgRotations - 1)); - auto rotangle = anglestart + nrotbkg * anglestep; + auto rotangle = (nBkgRotations > 1) ? (anglestart + nrotbkg * (angleend - anglestart) / (1.0 * (nBkgRotations - 1))) : (0.5 * (anglestart + angleend)); if (track1.sign() * track2.sign() < 0) { auto rotkaonPx = track1.px() * std::cos(rotangle) - track1.py() * std::sin(rotangle); auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); @@ -1346,235 +1115,6 @@ struct Phianalysisrun3pbpb { } // process MC PROCESS_SWITCH(Phianalysisrun3pbpb, processMC, "Process Reconstructed", false); - void processGen(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& collisions) - { - - histos.fill(HIST("hMC"), 0.5); - if (std::abs(mcCollision.posZ()) < selectionConfig.cfgCutVertex) { - histos.fill(HIST("hMC"), 1.5); - } - float imp = mcCollision.impactParameter(); - histos.fill(HIST("hImpactParameterGen"), imp); - std::vector selectedEvents(collisions.size()); - int nevts = 0; - float multiplicity = 0.f; - for (const auto& collision : collisions) { - if (cfgDoSel8 && !collision.sel8()) { - continue; - } - if (selectionConfig.selHasBC && !collision.has_foundBC()) { - continue; - } - if (selectionConfig.selHasFT0 && !collision.has_foundFT0()) { - continue; - } - if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cfgCutVertex) { - continue; - } - - if (selectionConfig.additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - continue; - } - int occupancy = collision.trackOccupancyInTimeRange(); - if (selectionConfig.fillOccupancy && (occupancy < cfgMinOccupancy || occupancy > cfgMaxOccupancy)) { - continue; - } - histos.fill(HIST("hOccupancy1"), occupancy); - multiplicity = collision.centFT0C(); - histos.fill(HIST("Centgen"), multiplicity); - histos.fill(HIST("hVtxZgen"), collision.mcCollision().posZ()); - histos.fill(HIST("hImpactParameterGenCen"), imp, multiplicity); - - selectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); - histos.fill(HIST("hMC"), 2.5); - } - selectedEvents.resize(nevts); - - const auto evtReconstructedAndSelected = std::find(selectedEvents.begin(), selectedEvents.end(), mcCollision.globalIndex()) != selectedEvents.end(); - histos.fill(HIST("EL1"), imp); - histos.fill(HIST("EL2"), multiplicity); - if (reco && !evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection - return; - } - histos.fill(HIST("ES1"), imp); - histos.fill(HIST("ES2"), multiplicity); - for (const auto& mcParticle : mcParticles) { - const double kMaxAcceptedRapidity = 0.5; - - if (std::abs(mcParticle.y()) >= kMaxAcceptedRapidity) { - - continue; - } - if (pdgcheck && mcParticle.pdgCode() != o2::constants::physics::kPhi) { - continue; - } - auto kDaughters = mcParticle.daughters_as(); - const size_t kExpectedNumberOfDaughters = 2; - - if (kDaughters.size() != kExpectedNumberOfDaughters) { - - continue; - } - auto daughtp = false; - auto daughtm = false; - for (const auto& kCurrentDaughter : kDaughters) { - if (!kCurrentDaughter.isPhysicalPrimary()) { - continue; - } - if (kCurrentDaughter.pdgCode() == PDG_t::kKPlus) { - daughtp = true; - kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); - } else if (kCurrentDaughter.pdgCode() == PDG_t::kKMinus) { - daughtm = true; - kaonMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); - } - } - if (daughtp && daughtm) { - phiMesonMother = kaonPlus + kaonMinus; - histos.fill(HIST("h1PhiGen"), phiMesonMother.pt()); - histos.fill(HIST("h2PhiGen2"), phiMesonMother.pt(), multiplicity); - histos.fill(HIST("h2PhiGen1"), phiMesonMother.pt(), imp); - histos.fill(HIST("h1Phimassgen"), phiMesonMother.M()); - histos.fill(HIST("h3PhiGen3"), phiMesonMother.pt(), multiplicity, phiMesonMother.M()); - } - } - } - PROCESS_SWITCH(Phianalysisrun3pbpb, processGen, "Process Generated", false); - void processRec(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const& /*mcParticles*/, aod::McCollisions const& /*mcCollisions*/) - { - if (!collision.has_mcCollision()) { - return; - } - if (cfgDoSel8 && !collision.sel8()) { - return; - } - if (selectionConfig.selHasBC && !collision.has_foundBC()) { - return; - } - if (selectionConfig.selHasFT0 && !collision.has_foundFT0()) { - return; - } - if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cfgCutVertex) { - return; - } - - if (selectionConfig.additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - return; - } - int occupancy = collision.trackOccupancyInTimeRange(); - if (selectionConfig.fillOccupancy && (occupancy < cfgMinOccupancy || occupancy > cfgMaxOccupancy)) { - return; - } - auto multiplicity = collision.centFT0C(); - histos.fill(HIST("Centrec"), multiplicity); - histos.fill(HIST("hVtxZrec"), collision.posZ()); - float imp = collision.mcCollision().impactParameter(); - histos.fill(HIST("hImpactParameterRec"), imp); - histos.fill(HIST("hImpactParameterRecCen"), imp, multiplicity); - histos.fill(HIST("ES3"), imp); - histos.fill(HIST("ES4"), multiplicity); - auto oldindex = -999; - for (const auto& track1 : tracks) { - if (!selectionTrack(track1)) { - continue; - } - if (!track1.has_mcParticle()) { - continue; - } - auto track1ID = track1.index(); - for (const auto& track2 : tracks) { - if (!track2.has_mcParticle()) { - continue; - } - if (!selectionTrack(track2)) { - continue; - } - auto track2ID = track2.index(); - if (track2ID <= track1ID) { - continue; - } - if (!selectionPair(track1, track2)) { - continue; - } - if (track1.sign() * track2.sign() > 0) { - continue; - } - const auto mctrack1 = track1.mcParticle(); - const auto mctrack2 = track2.mcParticle(); - int track1PDG = std::abs(mctrack1.pdgCode()); - int track2PDG = std::abs(mctrack2.pdgCode()); - if (!mctrack1.isPhysicalPrimary()) { - continue; - } - if (!mctrack2.isPhysicalPrimary()) { - continue; - } - if (track1PDG != PDG_t::kKPlus || track2PDG != PDG_t::kKPlus) { - continue; - } - daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); - - phiMother = daughter1 + daughter2; - histos.fill(HIST("h1Phi1massrec"), phiMother.M()); - histos.fill(HIST("h3Phi1Rec3"), phiMother.pt(), multiplicity, phiMother.M()); - for (const auto& mothertrack1 : mctrack1.mothers_as()) { - for (const auto& mothertrack2 : mctrack2.mothers_as()) { - if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { - continue; - } - if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { - continue; - } - if (!mothertrack1.producedByGenerator()) { - continue; - } - const double kMaxRapidityCut = 0.5; - - if (std::abs(mothertrack1.y()) >= kMaxRapidityCut) { - continue; - } - - if (pdgcheck && std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kPhi) { - continue; - } - if (!ispTdepPID && (!selectionPID(track1) || !selectionPID(track2))) { - continue; - } - if (ispTdepPID && - (selectionPIDpTdependent(track1, 0) || selectionPIDpTdependent(track1, 1)) && - (selectionPIDpTdependent(track2, 0) || selectionPIDpTdependent(track2, 1))) { - - continue; - } - - histos.fill(HIST("TPC_Nsigma_MC"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("TOF_Nsigma_MC"), track1.tofNSigmaKa(), multiplicity, track1.pt()); - if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { - histos.fill(HIST("h1PhiRecsplit"), mothertrack1.pt()); - continue; - } - oldindex = mothertrack1.globalIndex(); - if (track1.sign() * track2.sign() < 0) { - kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); - } - phiMesonMother = kaonPlus + kaonMinus; - - if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { - continue; - } - histos.fill(HIST("h1PhiRec1"), phiMesonMother.pt()); - histos.fill(HIST("h2PhiRec2"), phiMesonMother.pt(), multiplicity); - histos.fill(HIST("h1Phimassrec"), phiMesonMother.M()); - histos.fill(HIST("h3PhiRec3"), phiMesonMother.pt(), multiplicity, phiMesonMother.M()); - } - } - } - } - } - - PROCESS_SWITCH(Phianalysisrun3pbpb, processRec, "Process Reconstructed", false); void processSameEventMC(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const& /*mcParticles*/, aod::McCollisions const& /*mcCollisions*/) { if (!collision.sel8()) { @@ -1672,8 +1212,7 @@ struct Phianalysisrun3pbpb { for (int nrotbkg = 0; nrotbkg < nBkgRotations; nrotbkg++) { auto anglestart = confMinRot; auto angleend = confMaxRot; - auto anglestep = (angleend - anglestart) / (1.0 * (nBkgRotations - 1)); - auto rotangle = anglestart + nrotbkg * anglestep; + auto rotangle = (nBkgRotations > 1) ? (anglestart + nrotbkg * (angleend - anglestart) / (1.0 * (nBkgRotations - 1))) : (0.5 * (anglestart + angleend)); if (track1.sign() * track2.sign() < 0) { auto rotkaonPx = track1.px() * std::cos(rotangle) - track1.py() * std::sin(rotangle); auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); @@ -2057,6 +1596,7 @@ struct Phianalysisrun3pbpb { std::array pvec1Rec = {track2.px(), track2.py(), track2.pz()}; std::array, 2> arrMomrec = {pvec0Rec, pvec1Rec}; recMass = RecoDecay::m(arrMomrec, std::array{massKa, massKa}); + auto recPt = RecoDecay::pt(std::array{track1.px() + track2.px(), track1.py() + track2.py()}); // reconstructed-pair rapidity, cut with the same rapiditycut1/rapiditycut2 that fillinvMass() applies to data auto recRapidity = RecoDecay::y(std::array{track1.px() + track2.px(), track1.py() + track2.py(), track1.pz() + track2.pz()}, recMass); @@ -2074,10 +1614,10 @@ struct Phianalysisrun3pbpb { auto motherE = mothertrack1.e(); genMass = std::sqrt(motherE * motherE - motherP * motherP); - histos.fill(HIST("h1PhifinalRec"), mothertrack1.pt()); - histos.fill(HIST("h3PhifinalRec"), mothertrack1.pt(), multiplicity, recMass); + histos.fill(HIST("h1PhifinalRec"), recPt); + histos.fill(HIST("h3PhifinalRec"), recPt, multiplicity, recMass); histos.fill(HIST("h1Phifinalgenmass"), genMass); - histos.fill(HIST("h3PhiRecoResolution"), mothertrack1.pt(), multiplicity, recMass - genMass); + histos.fill(HIST("h3PhiRecoResolution"), recPt, multiplicity, recMass - genMass); } } } From d68584aacacb646bf6e0a0b851e5efae07465b98 Mon Sep 17 00:00:00 2001 From: sarjeeta gami Date: Wed, 23 Sep 2026 17:51:53 +0530 Subject: [PATCH 2/3] [PWGLF] Fix code-check issues in kstarpbpb.cxx and phianalysisrun3pbpb.cxx Remove the unused TF1.h include, return braced initializer lists for XYZVector and SAValues, and simplify the negated boolean expressions flagged by clang-tidy. --- PWGLF/Tasks/Resonances/kstarpbpb.cxx | 9 ++++----- PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index 732a5a65717..86d997fbddd 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -49,7 +49,6 @@ #include #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include -#include #include #include #include @@ -531,7 +530,7 @@ struct Kstarpbpb { if (cfgSAFrame.value == kProductionPlane) { return ROOT::Math::XYZVector(0., 0., 1.).Cross(mother.Vect()).Unit(); // z x p } - return ROOT::Math::XYZVector(std::sin(cfgEPNormalHarmonic.value * psiSA), -std::cos(cfgEPNormalHarmonic.value * psiSA), 0.); + return {std::sin(cfgEPNormalHarmonic.value * psiSA), -std::cos(cfgEPNormalHarmonic.value * psiSA), 0.}; } // ---------------- event selection, common to all K* and phi(1020) process functions ---------------- @@ -686,7 +685,7 @@ struct Kstarpbpb { double pz1 = candidate1.pz(), pz2 = candidate2.pz(); double p1 = candidate1.p(), p2 = candidate2.p(); double angle = std::acos(std::clamp((pt1 * pt2 + pz1 * pz2) / (p1 * p2), -1.0, 1.0)); // clamp = TMath::ACos behaviour - return !(phiSA.isDeepAngle && angle < phiSA.cfgDeepAngle); + return !phiSA.isDeepAngle || angle >= phiSA.cfgDeepAngle; } template @@ -699,7 +698,7 @@ struct Kstarpbpb { ROOT::Math::XYZVector getSAAxisPhiMC(const ROOT::Math::PxPyPzMVector& mother, double psiSA) { if (cfgSAFrame.value == kEventPlane) { - return ROOT::Math::XYZVector(std::cos(2.0 * psiSA), std::sin(2.0 * psiSA), 0.); + return {std::cos(2.0 * psiSA), std::sin(2.0 * psiSA), 0.}; } return getSAAxis(mother, psiSA); } @@ -1451,7 +1450,7 @@ struct Kstarpbpb { auto threeVecDau = boost(kaonMinus).Vect(); auto cosThetaStar = axis.Dot(threeVecDau) / std::sqrt(threeVecDau.Mag2()) / std::sqrt(axis.Mag2()); auto sa = std::cos(2.0 * getPhiInRange(threeVecDau.Phi() - getSAPlaneAngle(mother, psiSA))); - return {cosThetaStar, sa}; + return {.cosThetaStar = cosThetaStar, .sa = sa}; } void processSEPhi(EventCandidates::iterator const& collision, TrackCandidates const& tracks) diff --git a/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx b/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx index 2a27e2541ac..26184b5f79f 100644 --- a/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisrun3pbpb.cxx @@ -410,7 +410,7 @@ struct Phianalysisrun3pbpb { return false; } int occupancy = collision.trackOccupancyInTimeRange(); - return !(selectionConfig.fillOccupancy && (occupancy < cfgMinOccupancy || occupancy > cfgMaxOccupancy)); + return !selectionConfig.fillOccupancy || (occupancy >= cfgMinOccupancy && occupancy <= cfgMaxOccupancy); } template float selColMultMC(CheckColCent const& col) @@ -448,7 +448,7 @@ struct Phianalysisrun3pbpb { double p1 = candidate1.p(); double p2 = candidate2.p(); double angle = std::acos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); - return !(isDeepAngle && angle < cfgDeepAngle); + return !isDeepAngle || angle >= cfgDeepAngle; } template void fillinvMass(const T1& candidate1, const T2& candidate2, float multiplicity, bool unlike, bool mix, bool likesign, float massd1, float massd2) From 00aabd1310e537dfef6047eefdc413456af0df7f Mon Sep 17 00:00:00 2001 From: sarjeeta gami Date: Wed, 23 Sep 2026 22:57:15 +0530 Subject: [PATCH 3/3] [PWGLF] Tidy the isTOFOnly configurable description --- PWGLF/Tasks/Resonances/kstarpbpb.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index 86d997fbddd..919065e8cd1 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -158,7 +158,7 @@ struct Kstarpbpb { Configurable isDeepAngle{"isDeepAngle", false, "Deep Angle cut"}; Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; Configurable ispTdepPID{"ispTdepPID", true, "pT dependent PID"}; - Configurable isTOFOnly{"isTOFOnly", false, "use TOF only PID"}; + Configurable isTOFOnly{"isTOFOnly", false, "TOF only PID"}; Configurable confRapidity{"confRapidity", 0.5, "Rapidity cut"}; Configurable genacceptancecut{"genacceptancecut", true, "use acceptance cut for generated"}; Configurable avoidsplitrackMC{"avoidsplitrackMC", false, "avoid split track in MC"};