From 2df3a005bb33fde89e11a29939368f917a6925ab Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi Date: Thu, 12 Mar 2026 11:57:16 +0100 Subject: [PATCH 1/2] Adapt task to study sigma-pion correlations --- ...SigmaProtonTables.h => LFSigmaHadTables.h} | 46 +- .../TableProducer/Strangeness/CMakeLists.txt | 4 +- .../Strangeness/sigmaHadCorr.cxx | 740 ++++++++++++++++++ .../Strangeness/sigmaProtonCorr.cxx | 547 ------------- 4 files changed, 765 insertions(+), 572 deletions(-) rename PWGLF/DataModel/{LFSigmaProtonTables.h => LFSigmaHadTables.h} (52%) create mode 100644 PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx delete mode 100644 PWGLF/TableProducer/Strangeness/sigmaProtonCorr.cxx diff --git a/PWGLF/DataModel/LFSigmaProtonTables.h b/PWGLF/DataModel/LFSigmaHadTables.h similarity index 52% rename from PWGLF/DataModel/LFSigmaProtonTables.h rename to PWGLF/DataModel/LFSigmaHadTables.h index d9eafbedda5..a70af6317fd 100644 --- a/PWGLF/DataModel/LFSigmaProtonTables.h +++ b/PWGLF/DataModel/LFSigmaHadTables.h @@ -10,8 +10,8 @@ // or submit itself to any jurisdiction. /// -/// \file LFKinkDecayTables.h -/// \brief Slim tables for kinks +/// \file LFSigmaHadTables.h +/// \brief Slim tables for Sigma-hadron pairs /// \author Francesco Mazzaschi /// @@ -22,31 +22,31 @@ #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" -#ifndef PWGLF_DATAMODEL_LFSIGMAPROTONTABLES_H_ -#define PWGLF_DATAMODEL_LFSIGMAPROTONTABLES_H_ +#ifndef PWGLF_DATAMODEL_LFSIGMAHADTABLES_H_ +#define PWGLF_DATAMODEL_LFSIGMAHADTABLES_H_ namespace o2::aod { namespace sigmaproton { -DECLARE_SOA_COLUMN(ChargeSigma, chargeSigma, int); //! Charge of the sigma candidate -DECLARE_SOA_COLUMN(SigmaDecRad, sigmaDecRad, float); //! Decay radius of the Sigma candidate -DECLARE_SOA_COLUMN(SigmaCosPA, sigmaCosPA, float); //! Cosine of pointing angle of the Sigma candidate -DECLARE_SOA_COLUMN(ChargePr, chargePr, int); //! Charge of the proton candidate -DECLARE_SOA_COLUMN(PxPr, pxPr, float); //! Px of the proton candidate -DECLARE_SOA_COLUMN(PyPr, pyPr, float); //! Py of the proton candidate -DECLARE_SOA_COLUMN(PzPr, pzPr, float); //! Pz of the proton candidate -DECLARE_SOA_COLUMN(NSigmaTPCPr, nSigmaTPCPr, float); //! Number of sigmas for the proton candidate from Sigma kink in TPC -DECLARE_SOA_COLUMN(NSigmaTOFPr, nSigmaTOFPr, float); //! Number of sigmas for the proton candidate from Sigma kink in TOF +DECLARE_SOA_COLUMN(ChargeSigma, chargeSigma, int); //! Charge of the sigma candidate +DECLARE_SOA_COLUMN(SigmaDecRad, sigmaDecRad, float); //! Decay radius of the Sigma candidate +DECLARE_SOA_COLUMN(SigmaCosPA, sigmaCosPA, float); //! Cosine of pointing angle of the Sigma candidate +DECLARE_SOA_COLUMN(ChargeHad, chargeHad, int); //! Charge of the hadron candidate +DECLARE_SOA_COLUMN(PxHad, pxHad, float); //! Px of the hadron candidate +DECLARE_SOA_COLUMN(PyHad, pyHad, float); //! Py of the hadron candidate +DECLARE_SOA_COLUMN(PzHad, pzHad, float); //! Pz of the hadron candidate +DECLARE_SOA_COLUMN(NSigmaTPCHad, nSigmaTPCHad, float); //! Number of sigmas for the hadron candidate from Sigma kink in TPC +DECLARE_SOA_COLUMN(NSigmaTOFHad, nSigmaTOFHad, float); //! Number of sigmas for the hadron candidate from Sigma kink in TOF // MC Columns DECLARE_SOA_COLUMN(SigmaPDG, sigmaPDG, int); //! PDG code of the Sigma daughter DECLARE_SOA_COLUMN(DaughterPDG, daughterPDG, int); //! PDG code of the kink daughter -DECLARE_SOA_COLUMN(PrPDG, prPDG, int); //! PDG code of the proton candidate +DECLARE_SOA_COLUMN(HadPDG, hadPDG, int); //! PDG code of the hadron candidate DECLARE_SOA_COLUMN(SigmaGenPt, sigmaGenPt, float); //! Generated pT of the Sigma candidate -DECLARE_SOA_COLUMN(PrGenPt, prGenPt, float); //! Generated pT of the proton candidate -DECLARE_SOA_COLUMN(GenKStar, genKStar, float); //! Generated k* of the Sigma-Proton pair +DECLARE_SOA_COLUMN(HadGenPt, hadGenPt, float); //! Generated pT of the hadron candidate +DECLARE_SOA_COLUMN(GenKStar, genKStar, float); //! Generated k* of the Sigma-hadron pair } // namespace sigmaproton @@ -54,18 +54,18 @@ DECLARE_SOA_TABLE(SigmaProtonCands, "AOD", "SIGMAPROTONCANDS", o2::soa::Index<>, sigmaproton::ChargeSigma, kinkcand::PxMoth, kinkcand::PyMoth, kinkcand::PzMoth, kinkcand::PxDaug, kinkcand::PyDaug, kinkcand::PzDaug, sigmaproton::SigmaDecRad, sigmaproton::SigmaCosPA, - sigmaproton::ChargePr, sigmaproton::PxPr, sigmaproton::PyPr, sigmaproton::PzPr, - sigmaproton::NSigmaTPCPr, sigmaproton::NSigmaTOFPr); + sigmaproton::ChargeHad, sigmaproton::PxHad, sigmaproton::PyHad, sigmaproton::PzHad, + sigmaproton::NSigmaTPCHad, sigmaproton::NSigmaTOFHad); DECLARE_SOA_TABLE(SigmaProtonMCCands, "AOD", "SIGMAPROTONMCCANDS", o2::soa::Index<>, sigmaproton::ChargeSigma, kinkcand::PxMoth, kinkcand::PyMoth, kinkcand::PzMoth, kinkcand::PxDaug, kinkcand::PyDaug, kinkcand::PzDaug, sigmaproton::SigmaDecRad, sigmaproton::SigmaCosPA, - sigmaproton::ChargePr, sigmaproton::PxPr, sigmaproton::PyPr, sigmaproton::PzPr, - sigmaproton::NSigmaTPCPr, sigmaproton::NSigmaTOFPr, - sigmaproton::SigmaPDG, sigmaproton::DaughterPDG, sigmaproton::PrPDG, - sigmaproton::SigmaGenPt, sigmaproton::PrGenPt, sigmaproton::GenKStar); + sigmaproton::ChargeHad, sigmaproton::PxHad, sigmaproton::PyHad, sigmaproton::PzHad, + sigmaproton::NSigmaTPCHad, sigmaproton::NSigmaTOFHad, + sigmaproton::SigmaPDG, sigmaproton::DaughterPDG, sigmaproton::HadPDG, + sigmaproton::SigmaGenPt, sigmaproton::HadGenPt, sigmaproton::GenKStar); } // namespace o2::aod -#endif // PWGLF_DATAMODEL_LFSIGMAPROTONTABLES_H_ +#endif // PWGLF_DATAMODEL_LFSIGMAHADTABLES_H_ diff --git a/PWGLF/TableProducer/Strangeness/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/CMakeLists.txt index 9a6e18ac944..3f1d8565951 100644 --- a/PWGLF/TableProducer/Strangeness/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/CMakeLists.txt @@ -162,8 +162,8 @@ o2physics_add_dpl_workflow(lambdaspincorrelation PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(sigmaprotoncorr - SOURCES sigmaProtonCorr.cxx +o2physics_add_dpl_workflow(sigmahadcorr + SOURCES sigmaHadCorr.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) diff --git a/PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx b/PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx new file mode 100644 index 00000000000..5e8bf462b05 --- /dev/null +++ b/PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx @@ -0,0 +1,740 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file sigmaHadCorr.cxx +/// \brief Analysis task for sigma-hadron correlations +/// \author Francesco Mazzaschi + +#include "PWGLF/DataModel/LFKinkDecayTables.h" +#include "PWGLF/DataModel/LFSigmaHadTables.h" + +#include "Common/Core/PID/PIDTOF.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using TracksFull = soa::Join; +using TracksFullMC = soa::Join; +using CollisionsFull = soa::Join; +using CollisionsFullMC = soa::Join; + +struct sigmaHadCand { + + float ptHad() const + { + return std::hypot(pxHad, pyHad); + } + float sigmaPt() const + { + return std::hypot(sigmaPx, sigmaPy); + } + + int sigmaCharge = 0; // Charge of the sigma candidate + float sigmaMass = -1.f; // Mass of the Sigma candidate + float sigmaPx = -1; // Px of the Sigma candidate + float sigmaPy = -1; // Py of the Sigma candidate + float sigmaPz = -1; // Pz of the Sigma candidate + float sigmaDauPx = -1; // Px of the daughter track from Sigma decay + float sigmaDauPy = -1; // Py of the daughter track from Sigma decay + float sigmaDauPz = -1; // Pz of the daughter track from Sigma decay + float sigmaDecRadius = -1; // Decay radius of the Sigma candidate + float sigmaCosPA = -1; // Cosine of pointing angle of the Sigma candidate + + int chargeHad = 0; // Charge of the hadron candidate + float pxHad = -1; // Px of the hadron candidate + float pyHad = -1; // Py of the hadron candidate + float pzHad = -1; // Pz of the hadron candidate + + float nSigmaTPCHad = -1; // Number of sigmas for the hadron candidate + float nSigmaTOFHad = -1; // Number of sigmas for the hadron candidate using TOF + + int kinkDauID = -1; // ID of the pion from Sigma decay in MC + int sigmaID = -1; // ID of the Sigma candidate in MC + int hadID = -1; // ID of the hadron candidate in MC +}; + +struct sigmaHadCorrTask { + + std::vector sigmaHadCandidates; // Vector to store Sigma-hadron candidates + Produces outputDataTable; // Output table for Sigma-hadron candidates + Produces outputDataTableMC; // Output table for Sigma-hadron candidates in MC + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rSigmaHad{"sigmaHad", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + // Configurable for event selection + Configurable cutzvertex{"cutZVertex", 10.0f, "Accepted z-vertex range (cm)"}; + + Configurable minPtSigma{"minPtSigma", 1.f, "Minimum pT for Sigma candidates (GeV/c)"}; + Configurable cutEtaDaught{"cutEtaDaughter", 0.8f, "Eta cut for daughter tracks"}; + Configurable cutDCAtoPVSigma{"cutDCAtoPVSigma", 0.1f, "Max DCA to primary vertex for Sigma candidates (cm)"}; + Configurable doSigmaMinus{"doSigmaMinus", true, "If true, pair Sigma- candidates, else Sigma+"}; + Configurable cutSigmaRadius{"cutSigmaRadius", 20.f, "Minimum radius for Sigma candidates (cm)"}; + Configurable cutSigmaMass{"cutSigmaMass", 0.3, "Sigma mass window (GeV/c^2)"}; + Configurable alphaAPCut{"alphaAPCut", 0., "Alpha AP cut for Sigma candidates"}; + Configurable qtAPCutLow{"qtAPCutLow", 0.15, "Lower qT AP cut for Sigma candidates (GeV/c)"}; + Configurable qtAPCutHigh{"qtAPCutHigh", 0.2, "Upper qT AP cut for Sigma candidates (GeV/c)"}; + + Configurable cutNITSClusPr{"cutNITSClusPr", 5, "Minimum number of ITS clusters for hadron track"}; + Configurable cutNTPCClusPr{"cutNTPCClusPr", 90, "Minimum number of TPC clusters for hadron track"}; + Configurable cutNSigmaTPC{"cutNSigmaTPC", 3, "TPC nSigma cut for hadron track"}; + Configurable cutNSigmaTOF{"cutNSigmaTOF", 3, "TOF nSigma cut for hadron track"}; + Configurable applyTOFPIDKinkDaughter{"applyTOFPIDKinkDaughter", false, "If true, apply TOF PID cut to the kink daughter track"}; + Configurable matchSigmaToPions{"matchSigmaToPions", false, "If true, pair Sigma with pions instead of hadrons"}; + + Configurable cutMaxKStar{"cutMaxKStar", 1.5, "Maximum k* for Sigma-hadron pairs (GeV/c)"}; + Configurable useRecalculatedSigmaMomentum{"useRecalculatedSigmaMomentum", false, "If true, compute k* using Sigma momentum recalculated from daughter kinematics"}; + + Configurable fillOutputTree{"fillOutputTree", true, "If true, fill the output tree with Sigma-hadron candidates"}; + Configurable fillSparseInvMassKstar{"fillSparseInvMassKstar", false, "If true, fill THnSparse with invmass, k*, sigma charge, proton charge, sigma decay radius, cosPA, sigma pt"}; + + ConfigurableAxis CfgVtxBins{"CfgVtxBins", {10, -10, 10}, "Mixing bins - z-vertex"}; + ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0, 40.0, 80.0, 500.0}, "Mixing bins - number of contributor"}; + Configurable nEvtMixingBkg{"nEvtMixingBkg", 5, "Number of events to mix for background reconstruction"}; + + Preslice kinkCandsPerCollisionPreslice = aod::kinkcand::collisionId; + Preslice tracksPerCollisionPreslice = aod::track::collisionId; + Preslice tracksMCPerCollisionPreslice = aod::track::collisionId; + + void init(InitContext const&) + { + // Axes + const AxisSpec ptAxis{100, -10, 10, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec massResolutionAxis{100, -0.1, 0.1, "m_{rec} - m_{gen} (GeV/#it{c}^{2})"}; + const AxisSpec nSigmaHadAxis{100, -5, 5, "n#sigma_{had}"}; + const AxisSpec sigmaMassAxis{100, 1.1, 1.3, "m (GeV/#it{c}^{2})"}; + const AxisSpec kStarAxis{200, 0.0, 2., "k* (GeV/#it{c})"}; + const AxisSpec ptHadAxis{100, 0.0, 10.0, "#it{p}_{T,had} (GeV/#it{c})"}; + const AxisSpec sigmaPtAxis{100, 0.0, 10.0, "#it{p}_{T,#Sigma} (GeV/#it{c})"}; + const AxisSpec sigmaChargeAxis{2, -1.5, 1.5, "#Sigma charge"}; + const AxisSpec hadronChargeAxis{2, -1.5, 1.5, "Hadron charge"}; + const AxisSpec sigmaDecRadiusAxis{25, 14.5, 40.5, "#Sigma decay radius (cm)"}; + const AxisSpec cosPAAxis{50, 0.9, 1.0, "cos(PA)"}; + const AxisSpec alphaAPAxis{100, -1.0, 1.0, "#alpha_{AP}"}; + const AxisSpec qtAPAxis{100, 0.0, 0.5, "q_{T,AP} (GeV/#it{c})"}; + const AxisSpec vertexZAxis{100, -15., 15., "vrtx_{Z} [cm]"}; + + // qa histograms + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + // Dedicated QA folder + rSigmaHad.add("QA/h2TPCNSigmaHadVsPtHad", "TPC n#sigma_{had} vs #it{p}_{T,had}", {HistType::kTH2F, {ptHadAxis, nSigmaHadAxis}}); + rSigmaHad.add("QA/h2TOFNSigmaHadVsPtHad", "TOF n#sigma_{had} vs #it{p}_{T,had}", {HistType::kTH2F, {ptHadAxis, nSigmaHadAxis}}); + rSigmaHad.add("QA/hSigmaPt", "#Sigma #it{p}_{T}", {HistType::kTH1F, {sigmaPtAxis}}); + rSigmaHad.add("QA/hSigmaPtRecal", "#Sigma #it{p}_{T} recalculated", {HistType::kTH1F, {sigmaPtAxis}}); + rSigmaHad.add("QA/h2InvMassVsPtSigma", "m_{#Sigma} vs #it{p}_{T,#Sigma}", {HistType::kTH2F, {sigmaPtAxis, sigmaMassAxis}}); + rSigmaHad.add("QA/h2QtAPvsAlphaAP", "q_{T,AP} vs #alpha_{AP}", {HistType::kTH2F, {alphaAPAxis, qtAPAxis}}); + + if (fillSparseInvMassKstar) { + rSigmaHad.add("hSparseSigmaHad", + "7D sparse: invmass, k*, sigma charge, hadron charge, sigma decay radius, cosPA, sigma pt", + {HistType::kTHnSparseF, {sigmaMassAxis, kStarAxis, sigmaChargeAxis, hadronChargeAxis, sigmaDecRadiusAxis, cosPAAxis, sigmaPtAxis}}); + rSigmaHad.add("hSparseSigmaHadMC", + "8D sparse (MC): invmass, k*, sigma charge, hadron charge, sigma decay radius, cosPA, sigma pt, k* gen", + {HistType::kTHnSparseF, {sigmaMassAxis, kStarAxis, sigmaChargeAxis, hadronChargeAxis, sigmaDecRadiusAxis, cosPAAxis, sigmaPtAxis, kStarAxis}}); + } + + LOG(info) << "Sigma-hadron correlation task initialized"; + LOG(info) << "Process SE enabled: " << doprocessSameEvent; + LOG(info) << "Process ME enabled: " << doprocessMixedEvent; + LOG(info) << "Process SE MC enabled: " << doprocessSameEventMC; + LOG(info) << "Process ME MC enabled: " << doprocessMixedEventMC; + LOG(info) << "Pairing mode: " << (matchSigmaToPions ? "Sigma-pion" : "Sigma-hadron"); + } + + float getAlphaAP(const std::array& momMother, const std::array& momKink) + { + std::array momMissing = {momMother[0] - momKink[0], momMother[1] - momKink[1], momMother[2] - momKink[2]}; + float lQlP = std::inner_product(momMother.begin(), momMother.end(), momKink.begin(), 0.f); + float lQlN = std::inner_product(momMother.begin(), momMother.end(), momMissing.begin(), 0.f); + return (lQlP - lQlN) / (lQlP + lQlN); + } + + float getQtAP(const std::array& momMother, const std::array& momKink) + { + float dp = std::inner_product(momMother.begin(), momMother.end(), momKink.begin(), 0.f); + float p2V0 = std::inner_product(momMother.begin(), momMother.end(), momMother.begin(), 0.f); + float p2A = std::inner_product(momKink.begin(), momKink.end(), momKink.begin(), 0.f); + return std::sqrt(p2A - dp * dp / p2V0); + } + + float getCosPA(const std::array& momMother, const std::array& decayVertex, const std::array& primaryVertex) + { + std::array decayVec = {decayVertex[0] - primaryVertex[0], decayVertex[1] - primaryVertex[1], decayVertex[2] - primaryVertex[2]}; + float dotProduct = std::inner_product(momMother.begin(), momMother.end(), decayVec.begin(), 0.f); + float momMotherMag = std::sqrt(std::inner_product(momMother.begin(), momMother.end(), momMother.begin(), 0.f)); + float decayVecMag = std::sqrt(std::inner_product(decayVec.begin(), decayVec.end(), decayVec.begin(), 0.f)); + return dotProduct / (momMotherMag * decayVecMag); + } + + float getRecalculatedSigmaMomentum(const sigmaHadCand& candidate) + { + constexpr float massPion = o2::constants::physics::MassPionCharged; + constexpr float massNeutron = o2::constants::physics::MassNeutron; + float massSigma = doSigmaMinus ? o2::constants::physics::MassSigmaMinus : o2::constants::physics::MassSigmaPlus; + + float pMother = std::sqrt(candidate.sigmaPx * candidate.sigmaPx + candidate.sigmaPy * candidate.sigmaPy + candidate.sigmaPz * candidate.sigmaPz); + if (pMother < 1e-6f) { + return -999.f; + } + float versorX = candidate.sigmaPx / pMother; + float versorY = candidate.sigmaPy / pMother; + float versorZ = candidate.sigmaPz / pMother; + float ePi = std::sqrt(massPion * massPion + candidate.sigmaDauPx * candidate.sigmaDauPx + candidate.sigmaDauPy * candidate.sigmaDauPy + candidate.sigmaDauPz * candidate.sigmaDauPz); + float a = versorX * candidate.sigmaDauPx + versorY * candidate.sigmaDauPy + versorZ * candidate.sigmaDauPz; + float K = massSigma * massSigma + massPion * massPion - massNeutron * massNeutron; + float A = 4.f * (ePi * ePi - a * a); + float B = -4.f * a * K; + float C = 4.f * ePi * ePi * massSigma * massSigma - K * K; + if (std::abs(A) < 1e-6f) { + return -999.f; + } + float D = B * B - 4.f * A * C; + if (D < 0.f) { + return -999.f; + } + float sqrtD = std::sqrt(D); + float P1 = (-B + sqrtD) / (2.f * A); + float P2 = (-B - sqrtD) / (2.f * A); + if (P2 < 0.f && P1 < 0.f) { + return -999.f; + } + if (P2 < 0.f) { + return P1; + } + float p1Diff = std::abs(P1 - pMother); + float p2Diff = std::abs(P2 - pMother); + return (p1Diff < p2Diff) ? P1 : P2; + } + + std::array getSigmaMomentumForKstar(const sigmaHadCand& candidate) + { + std::array sigmaMomentum = {candidate.sigmaPx, candidate.sigmaPy, candidate.sigmaPz}; + if (!useRecalculatedSigmaMomentum) { + return sigmaMomentum; + } + + float pNew = getRecalculatedSigmaMomentum(candidate); + if (pNew <= 0.f) { + return sigmaMomentum; + } + + float pOld = std::sqrt(candidate.sigmaPx * candidate.sigmaPx + candidate.sigmaPy * candidate.sigmaPy + candidate.sigmaPz * candidate.sigmaPz); + if (pOld <= 0.f) { + return sigmaMomentum; + } + + float scale = pNew / pOld; + sigmaMomentum[0] *= scale; + sigmaMomentum[1] *= scale; + sigmaMomentum[2] *= scale; + return sigmaMomentum; + } + + float getHadTrackMass() + { + return matchSigmaToPions ? o2::constants::physics::MassPionCharged : o2::constants::physics::MassProton; + } + + float getSigmaMassForKstar() + { + return doSigmaMinus ? o2::constants::physics::MassSigmaMinus : o2::constants::physics::MassSigmaPlus; + } + + template + float getTPCNSigmaHad(const Ttrack& track) + { + return matchSigmaToPions ? track.tpcNSigmaPi() : track.tpcNSigmaPr(); + } + + template + float getTOFNSigmaHad(const Ttrack& track) + { + return matchSigmaToPions ? track.tofNSigmaPi() : track.tofNSigmaPr(); + } + + TLorentzVector trackSum, PartOneCMS, PartTwoCMS, trackRelK; + float getKStar(const sigmaHadCand& candidate) + { + TLorentzVector part1; // Sigma + TLorentzVector part2; // Hadron track (proton/pion) + part1.SetXYZM(candidate.sigmaPx, candidate.sigmaPy, candidate.sigmaPz, getSigmaMassForKstar()); + part2.SetXYZM(candidate.pxHad, candidate.pyHad, candidate.pzHad, getHadTrackMass()); + trackSum = part1 + part2; + const float beta = trackSum.Beta(); + const float betax = beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betay = beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betaz = beta * std::cos(trackSum.Theta()); + PartOneCMS.SetXYZM(part1.Px(), part1.Py(), part1.Pz(), part1.M()); + PartTwoCMS.SetXYZM(part2.Px(), part2.Py(), part2.Pz(), part2.M()); + const ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-betax, -betay, -betaz); + PartOneCMS = boostPRF(PartOneCMS); + PartTwoCMS = boostPRF(PartTwoCMS); + trackRelK = PartOneCMS - PartTwoCMS; + return 0.5 * trackRelK.P(); + } + + float getKStar(float sigmaPx, float sigmaPy, float sigmaPz, float pxHad, float pyHad, float pzHad) + { + TLorentzVector part1; // Sigma + TLorentzVector part2; // Hadron track (proton/pion) + part1.SetXYZM(sigmaPx, sigmaPy, sigmaPz, getSigmaMassForKstar()); + part2.SetXYZM(pxHad, pyHad, pzHad, getHadTrackMass()); + trackSum = part1 + part2; + const float beta = trackSum.Beta(); + const float betax = beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betay = beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betaz = beta * std::cos(trackSum.Theta()); + PartOneCMS.SetXYZM(part1.Px(), part1.Py(), part1.Pz(), part1.M()); + PartTwoCMS.SetXYZM(part2.Px(), part2.Py(), part2.Pz(), part2.M()); + const ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-betax, -betay, -betaz); + PartOneCMS = boostPRF(PartOneCMS); + PartTwoCMS = boostPRF(PartTwoCMS); + trackRelK = PartOneCMS - PartTwoCMS; + return 0.5 * trackRelK.P(); + } + + template + bool selectHadTrack(const Ttrack& candidate) + { + if (std::abs(getTPCNSigmaHad(candidate)) > cutNSigmaTPC || candidate.tpcNClsFound() < cutNTPCClusPr || std::abs(candidate.eta()) > cutEtaDaught) { + return false; + } + + if (candidate.itsNCls() < cutNITSClusPr) { + return false; + } + + float ptMinTOF = 0.75f; // Minimum pT to use TOF for hadron-track PID + if (candidate.pt() < ptMinTOF) { + return true; // No TOF cut for low pT + } + + if (!candidate.hasTOF()) { + return false; + } + if (std::abs(getTOFNSigmaHad(candidate)) > cutNSigmaTOF) { + return false; + } + return true; // Track is selected + } + + template + bool selectSigma(aod::KinkCands::iterator const& sigmaCand, Ttrack const& kinkDauTrack) + { + float mass = doSigmaMinus ? sigmaCand.mSigmaMinus() : sigmaCand.mSigmaPlus(); + std::array momMoth = {sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth()}; + std::array momDaug = {sigmaCand.pxDaug(), sigmaCand.pyDaug(), sigmaCand.pzDaug()}; + float alphaAP = getAlphaAP(momMoth, momDaug); + float qtAP = getQtAP(momMoth, momDaug); + + if (sigmaCand.ptMoth() < minPtSigma) { + return false; + } + + if (alphaAP > alphaAPCut || (qtAP < qtAPCutLow || qtAP > qtAPCutHigh)) { + return false; + } + float decRad = std::hypot(sigmaCand.xDecVtx(), sigmaCand.yDecVtx()); + if (decRad < cutSigmaRadius) { + return false; + } + + if (doSigmaMinus) { + if (mass < o2::constants::physics::MassSigmaMinus - cutSigmaMass || mass > o2::constants::physics::MassSigmaMinus + cutSigmaMass) { + return false; + } + if (std::abs(kinkDauTrack.tpcNSigmaPi()) > cutNSigmaTPC) { + return false; + } + } else { + if (mass < o2::constants::physics::MassSigmaPlus - cutSigmaMass || mass > o2::constants::physics::MassSigmaPlus + cutSigmaMass) { + return false; + } + if (std::abs(kinkDauTrack.tpcNSigmaPr()) > cutNSigmaTPC) { + return false; + } + } + + if (applyTOFPIDKinkDaughter) { + constexpr float ptMinTOF = 0.75f; + if (kinkDauTrack.pt() >= ptMinTOF) { + if (!kinkDauTrack.hasTOF()) { + return false; + } + float kinkDauTOFNSigma = doSigmaMinus ? kinkDauTrack.tofNSigmaPi() : kinkDauTrack.tofNSigmaPr(); + if (std::abs(kinkDauTOFNSigma) > cutNSigmaTOF) { + return false; + } + } + } + + if (std::abs(sigmaCand.dcaMothPv()) > cutDCAtoPVSigma) { + return false; + } + return true; + } + + template + void fillTreeAndHistograms(aod::KinkCands const& kinkCands, Ttrack const& tracksDauSigma, Ttrack const& tracks, Tcollision const& collision, bool isMC) + { + for (const auto& sigmaCand : kinkCands) { + auto kinkDauTrack = tracksDauSigma.rawIteratorAt(sigmaCand.trackDaugId()); + if (!selectSigma(sigmaCand, kinkDauTrack)) { + continue; + } + + std::array momMothAll = {sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth()}; + std::array momDaugAll = {sigmaCand.pxDaug(), sigmaCand.pyDaug(), sigmaCand.pzDaug()}; + float alphaAP = getAlphaAP(momMothAll, momDaugAll); + float qtAP = getQtAP(momMothAll, momDaugAll); + rSigmaHad.fill(HIST("QA/h2QtAPvsAlphaAP"), alphaAP, qtAP); + + sigmaHadCand sigmaForPt; + sigmaForPt.sigmaPx = sigmaCand.pxMoth(); + sigmaForPt.sigmaPy = sigmaCand.pyMoth(); + sigmaForPt.sigmaPz = sigmaCand.pzMoth(); + sigmaForPt.sigmaDauPx = sigmaCand.pxDaug(); + sigmaForPt.sigmaDauPy = sigmaCand.pyDaug(); + sigmaForPt.sigmaDauPz = sigmaCand.pzDaug(); + auto sigmaMomForPt = getSigmaMomentumForKstar(sigmaForPt); + float sigmaPtRecal = std::hypot(sigmaMomForPt[0], sigmaMomForPt[1]); + float sigmaPtForSparse = useRecalculatedSigmaMomentum ? sigmaPtRecal : sigmaCand.ptMoth(); + float sigmaMassForQa = doSigmaMinus ? sigmaCand.mSigmaMinus() : sigmaCand.mSigmaPlus(); + + rSigmaHad.fill(HIST("QA/hSigmaPt"), sigmaCand.ptMoth()); + rSigmaHad.fill(HIST("QA/hSigmaPtRecal"), sigmaPtRecal); + rSigmaHad.fill(HIST("QA/h2InvMassVsPtSigma"), sigmaPtForSparse, sigmaMassForQa); + + for (const auto& hadTrack : tracks) { + if (hadTrack.globalIndex() == sigmaCand.trackDaugId()) { + continue; + } + + if (!selectHadTrack(hadTrack)) { + continue; + } + + sigmaHadCand candidate; + candidate.sigmaCharge = sigmaCand.mothSign(); + candidate.sigmaPx = sigmaCand.pxMoth(); + candidate.sigmaPy = sigmaCand.pyMoth(); + candidate.sigmaPz = sigmaCand.pzMoth(); + candidate.sigmaDauPx = sigmaCand.pxDaug(); + candidate.sigmaDauPy = sigmaCand.pyDaug(); + candidate.sigmaDauPz = sigmaCand.pzDaug(); + candidate.sigmaDecRadius = std::hypot(sigmaCand.xDecVtx(), sigmaCand.yDecVtx()); + + std::array momMoth = {sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth()}; + std::array decayVtx = {sigmaCand.xDecVtx(), sigmaCand.yDecVtx(), sigmaCand.zDecVtx()}; + std::array primaryVtx = {collision.posX(), collision.posY(), collision.posZ()}; + candidate.sigmaCosPA = getCosPA(momMoth, decayVtx, primaryVtx); + + candidate.chargeHad = hadTrack.sign(); + candidate.pxHad = hadTrack.px(); + candidate.pyHad = hadTrack.py(); + candidate.pzHad = hadTrack.pz(); + candidate.nSigmaTPCHad = getTPCNSigmaHad(hadTrack); + candidate.nSigmaTOFHad = getTOFNSigmaHad(hadTrack); + candidate.sigmaMass = doSigmaMinus ? sigmaCand.mSigmaMinus() : sigmaCand.mSigmaPlus(); + + candidate.sigmaID = sigmaCand.trackMothId(); + candidate.kinkDauID = sigmaCand.trackDaugId(); + candidate.hadID = hadTrack.globalIndex(); + + auto sigmaMomForKstar = getSigmaMomentumForKstar(candidate); + float kStar = getKStar(sigmaMomForKstar[0], sigmaMomForKstar[1], sigmaMomForKstar[2], candidate.pxHad, candidate.pyHad, candidate.pzHad); + if (kStar > cutMaxKStar) { + continue; + } + + float sigmaPtUsed = std::hypot(sigmaMomForKstar[0], sigmaMomForKstar[1]); + + rSigmaHad.fill(HIST("h2PtHadNSigmaTPC"), candidate.ptHad(), candidate.nSigmaTPCHad); + rSigmaHad.fill(HIST("QA/h2TPCNSigmaHadVsPtHad"), candidate.ptHad(), candidate.nSigmaTPCHad); + if (hadTrack.hasTOF()) { + rSigmaHad.fill(HIST("h2PtHadNSigmaTOF"), candidate.ptHad(), candidate.nSigmaTOFHad); + rSigmaHad.fill(HIST("QA/h2TOFNSigmaHadVsPtHad"), candidate.ptHad(), candidate.nSigmaTOFHad); + } + if (fillSparseInvMassKstar && !isMC) { + rSigmaHad.fill(HIST("hSparseSigmaHad"), + candidate.sigmaMass, + kStar, + candidate.sigmaCharge, + candidate.chargeHad, + candidate.sigmaDecRadius, + candidate.sigmaCosPA, + sigmaPtUsed); + } + sigmaHadCandidates.push_back(candidate); + } + } + } + + void processSameEvent(CollisionsFull const& collisions, aod::KinkCands const& kinkCands, TracksFull const& tracks) + { + for (auto const& collision : collisions) { + + sigmaHadCandidates.clear(); + auto kinkCands_c = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision.globalIndex()); + auto tracks_c = tracks.sliceBy(tracksPerCollisionPreslice, collision.globalIndex()); + if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { + continue; + } + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + fillTreeAndHistograms(kinkCands_c, tracks_c, tracks_c, collision, false); + if (fillOutputTree) { + // Fill output table + for (const auto& candidate : sigmaHadCandidates) { + outputDataTable(candidate.sigmaCharge, + candidate.sigmaPx, + candidate.sigmaPy, + candidate.sigmaPz, + candidate.sigmaDauPx, + candidate.sigmaDauPy, + candidate.sigmaDauPz, + candidate.sigmaDecRadius, + candidate.sigmaCosPA, + candidate.chargeHad, + candidate.pxHad, + candidate.pyHad, + candidate.pzHad, + candidate.nSigmaTPCHad, + candidate.nSigmaTOFHad); + } + } + } + } + PROCESS_SWITCH(sigmaHadCorrTask, processSameEvent, "Process Same event", true); + + // Processing Event Mixing + SliceCache cache; + using BinningType = ColumnBinningPolicy; + BinningType colBinning{{CfgVtxBins, CfgMultBins}, true}; + + void processMixedEvent(const CollisionsFull& collisions, const aod::KinkCands& kinkCands, const TracksFull& tracks) + { + for (auto const& [collision1, collision2] : + selfCombinations(colBinning, nEvtMixingBkg, -1, collisions, collisions)) { + if (collision1.index() == collision2.index()) + continue; + + sigmaHadCandidates.clear(); + if (std::abs(collision1.posZ()) > cutzvertex || !collision1.sel8()) { + continue; + } + if (std::abs(collision2.posZ()) > cutzvertex || !collision2.sel8()) { + continue; + } + auto kinkCands_c1 = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision1.globalIndex()); + auto tracks_c1 = tracks.sliceBy(tracksPerCollisionPreslice, collision1.globalIndex()); + auto tracks_c2 = tracks.sliceBy(tracksPerCollisionPreslice, collision2.globalIndex()); + fillTreeAndHistograms(kinkCands_c1, tracks_c1, tracks_c2, collision1, false); + + if (fillOutputTree) { + // Fill output table + for (const auto& candidate : sigmaHadCandidates) { + outputDataTable(candidate.sigmaCharge, + candidate.sigmaPx, + candidate.sigmaPy, + candidate.sigmaPz, + candidate.sigmaDauPx, + candidate.sigmaDauPy, + candidate.sigmaDauPz, + candidate.sigmaDecRadius, + candidate.sigmaCosPA, + candidate.chargeHad, + candidate.pxHad, + candidate.pyHad, + candidate.pzHad, + candidate.nSigmaTPCHad, + candidate.nSigmaTOFHad); + } + } + } + LOG(debug) << "Processing mixed event"; + } + PROCESS_SWITCH(sigmaHadCorrTask, processMixedEvent, "Process Mixed event", false); + + void processSameEventMC(CollisionsFullMC const& collisions, aod::KinkCands const& kinkCands, TracksFullMC const& tracks, aod::McParticles const&) + { + for (auto const& collision : collisions) { + + sigmaHadCandidates.clear(); + auto kinkCands_c = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision.globalIndex()); + auto tracks_c = tracks.sliceBy(tracksMCPerCollisionPreslice, collision.globalIndex()); + + if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { + continue; + } + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + fillTreeAndHistograms(kinkCands_c, tracks_c, tracks_c, collision, true); + for (const auto& candidate : sigmaHadCandidates) { + auto mcLabelSigma = tracks.rawIteratorAt(candidate.sigmaID); + auto mcLabelSigmaDau = tracks.rawIteratorAt(candidate.kinkDauID); + auto mcLabelHad = tracks.rawIteratorAt(candidate.hadID); + + if (!mcLabelSigma.has_mcParticle() || !mcLabelSigmaDau.has_mcParticle() || !mcLabelHad.has_mcParticle()) { + continue; // Skip candidates where MC truth is not available + } + + auto mcPartSigma = mcLabelSigma.mcParticle_as(); + auto mcPartSigmaDau = mcLabelSigmaDau.mcParticle_as(); + auto mcPartHad = mcLabelHad.mcParticle_as(); + auto pdgSigma = mcPartSigma.pdgCode(); + auto pdgSigmaDau = mcLabelSigmaDau.has_mcParticle() ? mcPartSigmaDau.pdgCode() : -999; + auto pdgHad = mcLabelHad.has_mcParticle() ? mcPartHad.pdgCode() : -999; + + float sigmaPtGen = std::hypot(mcPartSigma.px(), mcPartSigma.py()); + float hadPtGen = std::hypot(mcPartHad.px(), mcPartHad.py()); + float kStarGen = getKStar(mcPartSigma.px(), mcPartSigma.py(), mcPartSigma.pz(), mcPartHad.px(), mcPartHad.py(), mcPartHad.pz()); + + if (fillSparseInvMassKstar) { + auto sigmaMomForKstar = getSigmaMomentumForKstar(candidate); + float kStarRec = getKStar(sigmaMomForKstar[0], sigmaMomForKstar[1], sigmaMomForKstar[2], candidate.pxHad, candidate.pyHad, candidate.pzHad); + float sigmaPtUsed = std::hypot(sigmaMomForKstar[0], sigmaMomForKstar[1]); + rSigmaHad.fill(HIST("hSparseSigmaHadMC"), + candidate.sigmaMass, + kStarRec, + candidate.sigmaCharge, + candidate.chargeHad, + candidate.sigmaDecRadius, + candidate.sigmaCosPA, + sigmaPtUsed, + kStarGen); + } + + if (fillOutputTree) { + outputDataTableMC(candidate.sigmaCharge, + candidate.sigmaPx, + candidate.sigmaPy, + candidate.sigmaPz, + candidate.sigmaDauPx, + candidate.sigmaDauPy, + candidate.sigmaDauPz, + candidate.sigmaDecRadius, + candidate.sigmaCosPA, + candidate.chargeHad, + candidate.pxHad, + candidate.pyHad, + candidate.pzHad, + candidate.nSigmaTPCHad, + candidate.nSigmaTOFHad, + pdgSigma, + pdgSigmaDau, + pdgHad, + sigmaPtGen, + hadPtGen, + kStarGen); + } + } + } + } + PROCESS_SWITCH(sigmaHadCorrTask, processSameEventMC, "Process Same event MC", false); + + void processMixedEventMC(const CollisionsFullMC& collisions, const aod::KinkCands& kinkCands, const TracksFullMC& tracks, const aod::McParticles&) + { + for (auto const& [collision1, collision2] : + selfCombinations(colBinning, nEvtMixingBkg, -1, collisions, collisions)) { + if (collision1.index() == collision2.index()) + continue; + + sigmaHadCandidates.clear(); + if (std::abs(collision1.posZ()) > cutzvertex || !collision1.sel8()) { + continue; + } + if (std::abs(collision2.posZ()) > cutzvertex || !collision2.sel8()) { + continue; + } + auto kinkCands_c1 = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision1.globalIndex()); + auto tracks_c1 = tracks.sliceBy(tracksPerCollisionPreslice, collision1.globalIndex()); + auto tracks_c2 = tracks.sliceBy(tracksPerCollisionPreslice, collision2.globalIndex()); + fillTreeAndHistograms(kinkCands_c1, tracks_c1, tracks_c2, collision1, true); + + for (const auto& candidate : sigmaHadCandidates) { + auto mcLabelSigma = tracks.rawIteratorAt(candidate.sigmaID); + auto mcLabelSigmaDau = tracks.rawIteratorAt(candidate.kinkDauID); + auto mcLabelHad = tracks.rawIteratorAt(candidate.hadID); + + if (!mcLabelSigma.has_mcParticle() || !mcLabelSigmaDau.has_mcParticle() || !mcLabelHad.has_mcParticle()) { + continue; // Skip candidates where MC truth is not available + } + + auto mcPartSigma = mcLabelSigma.mcParticle_as(); + auto mcPartSigmaDau = mcLabelSigmaDau.mcParticle_as(); + auto mcPartHad = mcLabelHad.mcParticle_as(); + auto pdgSigma = mcPartSigma.pdgCode(); + auto pdgSigmaDau = mcLabelSigmaDau.has_mcParticle() ? mcPartSigmaDau.pdgCode() : -999; + auto pdgHad = mcLabelHad.has_mcParticle() ? mcPartHad.pdgCode() : -999; + float sigmaPtGen = std::hypot(mcPartSigma.px(), mcPartSigma.py()); + float hadPtGen = std::hypot(mcPartHad.px(), mcPartHad.py()); + float kStarGen = getKStar(mcPartSigma.px(), mcPartSigma.py(), mcPartSigma.pz(), mcPartHad.px(), mcPartHad.py(), mcPartHad.pz()); + + if (fillSparseInvMassKstar) { + auto sigmaMomForKstar = getSigmaMomentumForKstar(candidate); + float kStarRec = getKStar(sigmaMomForKstar[0], sigmaMomForKstar[1], sigmaMomForKstar[2], candidate.pxHad, candidate.pyHad, candidate.pzHad); + float sigmaPtUsed = std::hypot(sigmaMomForKstar[0], sigmaMomForKstar[1]); + rSigmaHad.fill(HIST("hSparseSigmaHadMC"), + candidate.sigmaMass, + kStarRec, + candidate.sigmaCharge, + candidate.chargeHad, + candidate.sigmaDecRadius, + candidate.sigmaCosPA, + sigmaPtUsed, + kStarGen); + } + + if (fillOutputTree) { + outputDataTableMC(candidate.sigmaCharge, + candidate.sigmaPx, + candidate.sigmaPy, + candidate.sigmaPz, + candidate.sigmaDauPx, + candidate.sigmaDauPy, + candidate.sigmaDauPz, + candidate.sigmaDecRadius, + candidate.sigmaCosPA, + candidate.chargeHad, + candidate.pxHad, + candidate.pyHad, + candidate.pzHad, + candidate.nSigmaTPCHad, + candidate.nSigmaTOFHad, + pdgSigma, + pdgSigmaDau, + pdgHad, + sigmaPtGen, + hadPtGen, + kStarGen); + } + } + } + LOG(debug) << "Processing mixed event MC"; + } + PROCESS_SWITCH(sigmaHadCorrTask, processMixedEventMC, "Process Mixed event MC", false); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/Strangeness/sigmaProtonCorr.cxx b/PWGLF/TableProducer/Strangeness/sigmaProtonCorr.cxx deleted file mode 100644 index 26c4eee67d7..00000000000 --- a/PWGLF/TableProducer/Strangeness/sigmaProtonCorr.cxx +++ /dev/null @@ -1,547 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file sigmaProtonCorr.cxx -/// \brief Analysis task for sigma-proton correlations -/// \author Francesco Mazzaschi - -#include "PWGLF/DataModel/LFKinkDecayTables.h" -#include "PWGLF/DataModel/LFSigmaProtonTables.h" - -#include "Common/Core/PID/PIDTOF.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" - -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - -#include -#include -#include -#include - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using TracksFull = soa::Join; -using TracksFullMC = soa::Join; -using CollisionsFull = soa::Join; -using CollisionsFullMC = soa::Join; - -struct sigmaProtonCand { - - float ptPr() const - { - return std::hypot(pxPr, pyPr); - } - float sigmaPt() const - { - return std::hypot(sigmaPx, sigmaPy); - } - - int sigmaCharge = 0; // Charge of the sigma candidate - int sigmaMass = -1; // Mass of the Sigma candidate - float sigmaPx = -1; // Px of the Sigma candidate - float sigmaPy = -1; // Py of the Sigma candidate - float sigmaPz = -1; // Pz of the Sigma candidate - float sigmaDauPx = -1; // Px of the daughter track from Sigma decay - float sigmaDauPy = -1; // Py of the daughter track from Sigma decay - float sigmaDauPz = -1; // Pz of the daughter track from Sigma decay - float sigmaDecRadius = -1; // Decay radius of the Sigma candidate - float sigmaCosPA = -1; // Cosine of pointing angle of the Sigma candidate - - int chargePr = 0; // Charge of the proton candidate - float pxPr = -1; // Px of the proton candidate - float pyPr = -1; // Py of the proton candidate - float pzPr = -1; // Pz of the proton candidate - - float nSigmaTPCPr = -1; // Number of sigmas for the proton candidate - float nSigmaTOFPr = -1; // Number of sigmas for the proton candidate using TOF - - int kinkDauID = -1; // ID of the pion from Sigma decay in MC - int sigmaID = -1; // ID of the Sigma candidate in MC - int prID = -1; // ID of the proton candidate in MC -}; - -struct sigmaProtonCorrTask { - - std::vector sigmaProtonCandidates; // Vector to store Sigma-Proton candidates - Produces outputDataTable; // Output table for Sigma-Proton candidates - Produces outputDataTableMC; // Output table for Sigma-Proton candidates in MC - // Histograms are defined with HistogramRegistry - HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry rSigmaProton{"sigmaProton", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - // Configurable for event selection - Configurable cutzvertex{"cutZVertex", 10.0f, "Accepted z-vertex range (cm)"}; - - Configurable minPtSigma{"minPtSigma", 1.f, "Minimum pT for Sigma candidates (GeV/c)"}; - Configurable cutEtaDaught{"cutEtaDaughter", 0.8f, "Eta cut for daughter tracks"}; - Configurable cutDCAtoPVSigma{"cutDCAtoPVSigma", 0.1f, "Max DCA to primary vertex for Sigma candidates (cm)"}; - Configurable doSigmaMinus{"doSigmaMinus", true, "If true, pair Sigma- candidates, else Sigma+"}; - Configurable cutSigmaRadius{"cutSigmaRadius", 20.f, "Minimum radius for Sigma candidates (cm)"}; - Configurable cutSigmaMass{"cutSigmaMass", 0.3, "Sigma mass window (GeV/c^2)"}; - Configurable alphaAPCut{"alphaAPCut", 0., "Alpha AP cut for Sigma candidates"}; - Configurable qtAPCutLow{"qtAPCutLow", 0.15, "Lower qT AP cut for Sigma candidates (GeV/c)"}; - Configurable qtAPCutHigh{"qtAPCutHigh", 0.2, "Upper qT AP cut for Sigma candidates (GeV/c)"}; - - Configurable cutNITSClusPr{"cutNITSClusPr", 5, "Minimum number of ITS clusters for proton candidate"}; - Configurable cutNTPCClusPr{"cutNTPCClusPr", 90, "Minimum number of TPC clusters for proton candidate"}; - Configurable cutNSigmaTPC{"cutNSigmaTPC", 3, "NSigmaTPCPr"}; - Configurable cutNSigmaTOF{"cutNSigmaTOF", 3, "NSigmaTOFPr"}; - - Configurable cutMaxKStar{"cutMaxKStar", 1.5, "Maximum k* for Sigma-Proton pairs (GeV/c)"}; - - Configurable fillOutputTree{"fillOutputTree", true, "If true, fill the output tree with Sigma-Proton candidates"}; - - ConfigurableAxis CfgVtxBins{"CfgVtxBins", {10, -10, 10}, "Mixing bins - z-vertex"}; - ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0, 40.0, 80.0, 500.0}, "Mixing bins - number of contributor"}; - Configurable nEvtMixingBkg{"nEvtMixingBkg", 5, "Number of events to mix for background reconstruction"}; - - Preslice kinkCandsPerCollisionPreslice = aod::kinkcand::collisionId; - Preslice tracksPerCollisionPreslice = aod::track::collisionId; - Preslice tracksMCPerCollisionPreslice = aod::track::collisionId; - - void init(InitContext const&) - { - // Axes - const AxisSpec ptAxis{100, -10, 10, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec massResolutionAxis{100, -0.1, 0.1, "m_{rec} - m_{gen} (GeV/#it{c}^{2})"}; - const AxisSpec nSigmaPrAxis{100, -5, 5, "n#sigma_{#pr}"}; - const AxisSpec sigmaMassAxis{100, 1.1, 1.4, "m (GeV/#it{c}^{2})"}; - const AxisSpec vertexZAxis{100, -15., 15., "vrtx_{Z} [cm]"}; - - // qa histograms - rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); - rSigmaProton.add("h2PtMassSigma", "h2PtMassSigma", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); - rSigmaProton.add("h2PtPrNSigma", "h2PtPrNSigma", {HistType::kTH2F, {ptAxis, nSigmaPrAxis}}); - rSigmaProton.add("h2PtPrNSigmaTOF", "h2PtPrNSigmaTOF", {HistType::kTH2F, {ptAxis, nSigmaPrAxis}}); - - LOG(info) << "Sigma-Proton correlation task initialized"; - LOG(info) << "Process SE enabled: " << doprocessSameEvent; - LOG(info) << "Process ME enabled: " << doprocessMixedEvent; - LOG(info) << "Process SE MC enabled: " << doprocessSameEventMC; - LOG(info) << "Process ME MC enabled: " << doprocessMixedEventMC; - } - - float getAlphaAP(const std::array& momMother, const std::array& momKink) - { - std::array momMissing = {momMother[0] - momKink[0], momMother[1] - momKink[1], momMother[2] - momKink[2]}; - float lQlP = std::inner_product(momMother.begin(), momMother.end(), momKink.begin(), 0.f); - float lQlN = std::inner_product(momMother.begin(), momMother.end(), momMissing.begin(), 0.f); - return (lQlP - lQlN) / (lQlP + lQlN); - } - - float getQtAP(const std::array& momMother, const std::array& momKink) - { - float dp = std::inner_product(momMother.begin(), momMother.end(), momKink.begin(), 0.f); - float p2V0 = std::inner_product(momMother.begin(), momMother.end(), momMother.begin(), 0.f); - float p2A = std::inner_product(momKink.begin(), momKink.end(), momKink.begin(), 0.f); - return std::sqrt(p2A - dp * dp / p2V0); - } - - float getCosPA(const std::array& momMother, const std::array& decayVertex, const std::array& primaryVertex) - { - std::array decayVec = {decayVertex[0] - primaryVertex[0], decayVertex[1] - primaryVertex[1], decayVertex[2] - primaryVertex[2]}; - float dotProduct = std::inner_product(momMother.begin(), momMother.end(), decayVec.begin(), 0.f); - float momMotherMag = std::sqrt(std::inner_product(momMother.begin(), momMother.end(), momMother.begin(), 0.f)); - float decayVecMag = std::sqrt(std::inner_product(decayVec.begin(), decayVec.end(), decayVec.begin(), 0.f)); - return dotProduct / (momMotherMag * decayVecMag); - } - - TLorentzVector trackSum, PartOneCMS, PartTwoCMS, trackRelK; - float getKStar(const sigmaProtonCand& candidate) - { - TLorentzVector part1; // Sigma - TLorentzVector part2; // Proton - part1.SetXYZM(candidate.sigmaPx, candidate.sigmaPy, candidate.sigmaPz, o2::constants::physics::MassSigmaMinus); - part2.SetXYZM(candidate.pxPr, candidate.pyPr, candidate.pzPr, o2::constants::physics::MassProton); - trackSum = part1 + part2; - const float beta = trackSum.Beta(); - const float betax = beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); - const float betay = beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); - const float betaz = beta * std::cos(trackSum.Theta()); - PartOneCMS.SetXYZM(part1.Px(), part1.Py(), part1.Pz(), part1.M()); - PartTwoCMS.SetXYZM(part2.Px(), part2.Py(), part2.Pz(), part2.M()); - const ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-betax, -betay, -betaz); - PartOneCMS = boostPRF(PartOneCMS); - PartTwoCMS = boostPRF(PartTwoCMS); - trackRelK = PartOneCMS - PartTwoCMS; - return 0.5 * trackRelK.P(); - } - - float getKStar(float sigmaPx, float sigmaPy, float sigmaPz, float pxPr, float pyPr, float pzPr) - { - TLorentzVector part1; // Sigma - TLorentzVector part2; // Proton - part1.SetXYZM(sigmaPx, sigmaPy, sigmaPz, o2::constants::physics::MassSigmaMinus); - part2.SetXYZM(pxPr, pyPr, pzPr, o2::constants::physics::MassProton); - trackSum = part1 + part2; - const float beta = trackSum.Beta(); - const float betax = beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); - const float betay = beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); - const float betaz = beta * std::cos(trackSum.Theta()); - PartOneCMS.SetXYZM(part1.Px(), part1.Py(), part1.Pz(), part1.M()); - PartTwoCMS.SetXYZM(part2.Px(), part2.Py(), part2.Pz(), part2.M()); - const ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-betax, -betay, -betaz); - PartOneCMS = boostPRF(PartOneCMS); - PartTwoCMS = boostPRF(PartTwoCMS); - trackRelK = PartOneCMS - PartTwoCMS; - return 0.5 * trackRelK.P(); - } - - template - bool selectPrTrack(const Ttrack& candidate) - { - if (std::abs(candidate.tpcNSigmaPr()) > cutNSigmaTPC || candidate.tpcNClsFound() < cutNTPCClusPr || std::abs(candidate.eta()) > cutEtaDaught) { - return false; - } - - if (candidate.itsNCls() < cutNITSClusPr) { - return false; - } - - float ptMinTOF = 0.75f; // Minimum pT to use TOF for proton PID - if (candidate.pt() < ptMinTOF) { - return true; // No TOF cut for low pT - } - - if (!candidate.hasTOF()) { - return false; - } - if (std::abs(candidate.tofNSigmaPr()) > cutNSigmaTOF) { - return false; - } - return true; // Track is selected - } - - template - bool selectSigma(aod::KinkCands::iterator const& sigmaCand, Ttrack const&) - { - - auto kinkDauTrack = sigmaCand.trackDaug_as(); - float mass = doSigmaMinus ? sigmaCand.mSigmaMinus() : sigmaCand.mSigmaPlus(); - std::array momMoth = {sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth()}; - std::array momDaug = {sigmaCand.pxDaug(), sigmaCand.pyDaug(), sigmaCand.pzDaug()}; - float alphaAP = getAlphaAP(momMoth, momDaug); - float qtAP = getQtAP(momMoth, momDaug); - - if (sigmaCand.ptMoth() < minPtSigma) { - return false; - } - - if (alphaAP > alphaAPCut || (qtAP < qtAPCutLow || qtAP > qtAPCutHigh)) { - return false; - } - float decRad = std::hypot(sigmaCand.xDecVtx(), sigmaCand.yDecVtx()); - if (decRad < cutSigmaRadius) { - return false; - } - - if (doSigmaMinus) { - if (mass < o2::constants::physics::MassSigmaMinus - cutSigmaMass || mass > o2::constants::physics::MassSigmaMinus + cutSigmaMass) { - return false; - } - if (std::abs(kinkDauTrack.tpcNSigmaPi()) > cutNSigmaTPC) { - return false; - } - } else { - if (mass < o2::constants::physics::MassSigmaPlus - cutSigmaMass || mass > o2::constants::physics::MassSigmaPlus + cutSigmaMass) { - return false; - } - if (std::abs(kinkDauTrack.tpcNSigmaPr()) > cutNSigmaTPC) { - return false; - } - } - if (std::abs(sigmaCand.dcaMothPv()) > cutDCAtoPVSigma) { - return false; - } - return true; - } - - template - void fillTreeAndHistograms(aod::KinkCands const& kinkCands, Ttrack const& tracksDauSigma, Ttrack const& tracks, Tcollision const& collision) - { - for (const auto& sigmaCand : kinkCands) { - if (selectSigma(sigmaCand, tracksDauSigma)) { - if (doSigmaMinus) { - rSigmaProton.fill(HIST("h2PtMassSigma"), sigmaCand.mothSign() * sigmaCand.ptMoth(), sigmaCand.mSigmaMinus()); - } else { - rSigmaProton.fill(HIST("h2PtMassSigma"), sigmaCand.mothSign() * sigmaCand.ptMoth(), sigmaCand.mSigmaPlus()); - } - - for (const auto& prTrack : tracks) { - if (!selectPrTrack(prTrack)) { - continue; - } - - sigmaProtonCand candidate; - candidate.sigmaCharge = sigmaCand.mothSign(); - candidate.sigmaPx = sigmaCand.pxMoth(); - candidate.sigmaPy = sigmaCand.pyMoth(); - candidate.sigmaPz = sigmaCand.pzMoth(); - candidate.sigmaDauPx = sigmaCand.pxDaug(); - candidate.sigmaDauPy = sigmaCand.pyDaug(); - candidate.sigmaDauPz = sigmaCand.pzDaug(); - candidate.sigmaDecRadius = std::hypot(sigmaCand.xDecVtx(), sigmaCand.yDecVtx()); - - std::array momMoth = {sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth()}; - std::array decayVtx = {sigmaCand.xDecVtx(), sigmaCand.yDecVtx(), sigmaCand.zDecVtx()}; - std::array primaryVtx = {collision.posX(), collision.posY(), collision.posZ()}; - candidate.sigmaCosPA = getCosPA(momMoth, decayVtx, primaryVtx); - - candidate.chargePr = prTrack.sign(); - candidate.pxPr = prTrack.px(); - candidate.pyPr = prTrack.py(); - candidate.pzPr = prTrack.pz(); - candidate.nSigmaTPCPr = prTrack.tpcNSigmaPr(); - candidate.nSigmaTOFPr = prTrack.tofNSigmaPr(); - candidate.sigmaMass = doSigmaMinus ? sigmaCand.mSigmaMinus() : sigmaCand.mSigmaPlus(); - - candidate.sigmaID = sigmaCand.trackMothId(); - candidate.kinkDauID = sigmaCand.trackDaugId(); - candidate.prID = prTrack.globalIndex(); - - if (getKStar(candidate) > cutMaxKStar) { - continue; - } - - rSigmaProton.fill(HIST("h2PtPrNSigma"), candidate.ptPr(), candidate.nSigmaTPCPr); - if (prTrack.hasTOF()) { - rSigmaProton.fill(HIST("h2PtPrNSigmaTOF"), candidate.ptPr(), candidate.nSigmaTOFPr); - } - sigmaProtonCandidates.push_back(candidate); - } - } - } - } - - void processSameEvent(CollisionsFull const& collisions, aod::KinkCands const& kinkCands, TracksFull const& tracks) - { - for (auto const& collision : collisions) { - - sigmaProtonCandidates.clear(); - auto kinkCands_c = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision.globalIndex()); - auto tracks_c = tracks.sliceBy(tracksPerCollisionPreslice, collision.globalIndex()); - if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { - continue; - } - rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); - fillTreeAndHistograms(kinkCands_c, tracks_c, tracks_c, collision); - if (fillOutputTree) { - // Fill output table - for (const auto& candidate : sigmaProtonCandidates) { - outputDataTable(candidate.sigmaCharge, - candidate.sigmaPx, - candidate.sigmaPy, - candidate.sigmaPz, - candidate.sigmaDauPx, - candidate.sigmaDauPy, - candidate.sigmaDauPz, - candidate.sigmaDecRadius, - candidate.sigmaCosPA, - candidate.chargePr, - candidate.pxPr, - candidate.pyPr, - candidate.pzPr, - candidate.nSigmaTPCPr, - candidate.nSigmaTOFPr); - } - } - } - } - PROCESS_SWITCH(sigmaProtonCorrTask, processSameEvent, "Process Same event", true); - - // Processing Event Mixing - SliceCache cache; - using BinningType = ColumnBinningPolicy; - BinningType colBinning{{CfgVtxBins, CfgMultBins}, true}; - - void processMixedEvent(const CollisionsFull& collisions, const aod::KinkCands& kinkCands, const TracksFull& tracks) - { - for (auto const& [collision1, collision2] : - selfCombinations(colBinning, nEvtMixingBkg, -1, collisions, collisions)) { - if (collision1.index() == collision2.index()) - continue; - - sigmaProtonCandidates.clear(); - if (std::abs(collision1.posZ()) > cutzvertex || !collision1.sel8()) { - continue; - } - if (std::abs(collision2.posZ()) > cutzvertex || !collision2.sel8()) { - continue; - } - auto kinkCands_c1 = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision1.globalIndex()); - auto tracks_c1 = tracks.sliceBy(tracksPerCollisionPreslice, collision1.globalIndex()); - auto tracks_c2 = tracks.sliceBy(tracksPerCollisionPreslice, collision2.globalIndex()); - fillTreeAndHistograms(kinkCands_c1, tracks_c1, tracks_c2, collision1); - - if (fillOutputTree) { - // Fill output table - for (const auto& candidate : sigmaProtonCandidates) { - outputDataTable(candidate.sigmaCharge, - candidate.sigmaPx, - candidate.sigmaPy, - candidate.sigmaPz, - candidate.sigmaDauPx, - candidate.sigmaDauPy, - candidate.sigmaDauPz, - candidate.sigmaDecRadius, - candidate.sigmaCosPA, - candidate.chargePr, - candidate.pxPr, - candidate.pyPr, - candidate.pzPr, - candidate.nSigmaTPCPr, - candidate.nSigmaTOFPr); - } - } - } - LOG(debug) << "Processing mixed event"; - } - PROCESS_SWITCH(sigmaProtonCorrTask, processMixedEvent, "Process Mixed event", false); - - void processSameEventMC(CollisionsFullMC const& collisions, aod::KinkCands const& kinkCands, TracksFullMC const& tracks, aod::McParticles const&) - { - for (auto const& collision : collisions) { - - sigmaProtonCandidates.clear(); - auto kinkCands_c = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision.globalIndex()); - auto tracks_c = tracks.sliceBy(tracksMCPerCollisionPreslice, collision.globalIndex()); - - if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { - continue; - } - rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); - fillTreeAndHistograms(kinkCands_c, tracks_c, tracks_c, collision); - if (fillOutputTree) { - // Fill output table - for (const auto& candidate : sigmaProtonCandidates) { - auto mcLabelSigma = tracks.rawIteratorAt(candidate.sigmaID); - auto mcLabelSigmaDau = tracks.rawIteratorAt(candidate.kinkDauID); - auto mcLabelPr = tracks.rawIteratorAt(candidate.prID); - - if (!mcLabelSigma.has_mcParticle() || !mcLabelSigmaDau.has_mcParticle() || !mcLabelPr.has_mcParticle()) { - continue; // Skip candidates where MC truth is not available - } - - auto mcPartSigma = mcLabelSigma.mcParticle_as(); - auto mcPartSigmaDau = mcLabelSigmaDau.mcParticle_as(); - auto mcPartPr = mcLabelPr.mcParticle_as(); - auto pdgSigma = mcPartSigma.pdgCode(); - auto pdgSigmaDau = mcLabelSigmaDau.has_mcParticle() ? mcPartSigmaDau.pdgCode() : -999; - auto pdgPr = mcLabelPr.has_mcParticle() ? mcPartPr.pdgCode() : -999; - - float sigmaPtGen = std::hypot(mcPartSigma.px(), mcPartSigma.py()); - float prPtGen = std::hypot(mcPartPr.px(), mcPartPr.py()); - float kStarGen = getKStar(mcPartSigma.px(), mcPartSigma.py(), mcPartSigma.pz(), mcPartPr.px(), mcPartPr.py(), mcPartPr.pz()); - - outputDataTableMC(candidate.sigmaCharge, - candidate.sigmaPx, - candidate.sigmaPy, - candidate.sigmaPz, - candidate.sigmaDauPx, - candidate.sigmaDauPy, - candidate.sigmaDauPz, - candidate.sigmaDecRadius, - candidate.sigmaCosPA, - candidate.chargePr, - candidate.pxPr, - candidate.pyPr, - candidate.pzPr, - candidate.nSigmaTPCPr, - candidate.nSigmaTOFPr, - pdgSigma, - pdgSigmaDau, - pdgPr, - sigmaPtGen, - prPtGen, - kStarGen); - } - } - } - } - PROCESS_SWITCH(sigmaProtonCorrTask, processSameEventMC, "Process Same event MC", false); - - void processMixedEventMC(const CollisionsFullMC& collisions, const aod::KinkCands& kinkCands, const TracksFullMC& tracks, const aod::McParticles&) - { - for (auto const& [collision1, collision2] : - selfCombinations(colBinning, nEvtMixingBkg, -1, collisions, collisions)) { - if (collision1.index() == collision2.index()) - continue; - - sigmaProtonCandidates.clear(); - if (std::abs(collision1.posZ()) > cutzvertex || !collision1.sel8()) { - continue; - } - if (std::abs(collision2.posZ()) > cutzvertex || !collision2.sel8()) { - continue; - } - auto kinkCands_c1 = kinkCands.sliceBy(kinkCandsPerCollisionPreslice, collision1.globalIndex()); - auto tracks_c1 = tracks.sliceBy(tracksPerCollisionPreslice, collision1.globalIndex()); - auto tracks_c2 = tracks.sliceBy(tracksPerCollisionPreslice, collision2.globalIndex()); - fillTreeAndHistograms(kinkCands_c1, tracks_c1, tracks_c2, collision1); - - if (fillOutputTree) { - // Fill output table - for (const auto& candidate : sigmaProtonCandidates) { - auto mcLabelSigma = tracks.rawIteratorAt(candidate.sigmaID); - auto mcLabelSigmaDau = tracks.rawIteratorAt(candidate.kinkDauID); - auto mcLabelPr = tracks.rawIteratorAt(candidate.prID); - - if (!mcLabelSigma.has_mcParticle() || !mcLabelSigmaDau.has_mcParticle() || !mcLabelPr.has_mcParticle()) { - continue; // Skip candidates where MC truth is not available - } - - auto mcPartSigma = mcLabelSigma.mcParticle_as(); - auto mcPartSigmaDau = mcLabelSigmaDau.mcParticle_as(); - auto mcPartPr = mcLabelPr.mcParticle_as(); - auto pdgSigma = mcPartSigma.pdgCode(); - auto pdgSigmaDau = mcLabelSigmaDau.has_mcParticle() ? mcPartSigmaDau.pdgCode() : -999; - auto pdgPr = mcLabelPr.has_mcParticle() ? mcPartPr.pdgCode() : -999; - float sigmaPtGen = std::hypot(mcPartSigma.px(), mcPartSigma.py()); - float prPtGen = std::hypot(mcPartPr.px(), mcPartPr.py()); - float kStarGen = getKStar(mcPartSigma.px(), mcPartSigma.py(), mcPartSigma.pz(), mcPartPr.px(), mcPartPr.py(), mcPartPr.pz()); - outputDataTableMC(candidate.sigmaCharge, - candidate.sigmaPx, - candidate.sigmaPy, - candidate.sigmaPz, - candidate.sigmaDauPx, - candidate.sigmaDauPy, - candidate.sigmaDauPz, - candidate.sigmaDecRadius, - candidate.sigmaCosPA, - candidate.chargePr, - candidate.pxPr, - candidate.pyPr, - candidate.pzPr, - candidate.nSigmaTPCPr, - candidate.nSigmaTOFPr, - pdgSigma, - pdgSigmaDau, - pdgPr, - sigmaPtGen, - prPtGen, - kStarGen); - } - } - } - LOG(debug) << "Processing mixed event MC"; - } - PROCESS_SWITCH(sigmaProtonCorrTask, processMixedEventMC, "Process Mixed event MC", false); -}; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} From ab9361c2c2026ed7a231fd3230f4a90779ef6c42 Mon Sep 17 00:00:00 2001 From: Francesco Mazzaschi <43742195+fmazzasc@users.noreply.github.com> Date: Thu, 12 Mar 2026 16:38:08 +0100 Subject: [PATCH 2/2] Add include --- PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx b/PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx index 5e8bf462b05..50b2c8851dc 100644 --- a/PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx +++ b/PWGLF/TableProducer/Strangeness/sigmaHadCorr.cxx @@ -25,6 +25,7 @@ #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/PID.h" +#include #include #include #include