From 2e43b1cd65128e14e96c8ce18f3aeecf7b3026cf Mon Sep 17 00:00:00 2001 From: PaolaVT Date: Tue, 29 Jul 2025 13:29:02 -0600 Subject: [PATCH 01/24] Phi parametrizations were updated --- PWGMM/UE/Tasks/dedxAnalysis.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGMM/UE/Tasks/dedxAnalysis.cxx b/PWGMM/UE/Tasks/dedxAnalysis.cxx index b87e9c30478..11aea4031be 100644 --- a/PWGMM/UE/Tasks/dedxAnalysis.cxx +++ b/PWGMM/UE/Tasks/dedxAnalysis.cxx @@ -146,8 +146,8 @@ struct DedxAnalysis { AxisSpec ptAxis = {binP, "pT (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; - fphiCutLow = new TF1("StandardPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 50); - fphiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 50); + fphiCutLow = new TF1("StandardPhiCutLow", "0.119297/x/x+pi/18.0-0.000379693", 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", "0.16685/x+pi/18.0+0.00981942", 0, 50); if (calibrationMode) { // MIP for pions registryDeDx.add( From 49fe700df785d0753bb9b46c898f4174de8fb842 Mon Sep 17 00:00:00 2001 From: PaolaVT Date: Fri, 1 Aug 2025 13:14:30 -0600 Subject: [PATCH 02/24] The analysis task dedxPidAnalysis.cxx was added --- PWGLF/Tasks/Nuspex/CMakeLists.txt | 5 + PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 852 +++++++++++++++++++++++++ 2 files changed, 857 insertions(+) create mode 100644 PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index 05b1bc2ca8e..8e86feab651 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -150,4 +150,9 @@ o2physics_add_dpl_workflow(he3-lambda-derived-analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(dedx-pid-analysis + SOURCES dedxPidAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + endif() diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx new file mode 100644 index 00000000000..d688f0c8e72 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -0,0 +1,852 @@ +// 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. +/// +/// \author Paola Vargas Torres (paola.vargas.torres@cern.ch) +/// \since January 8, 2025 +/// \file dedxPidAnalysis.cxx +/// \brief Analysis to do PID + +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "TF1.h" + +using namespace o2; +using namespace o2::framework; +using namespace constants::physics; + +using PIDTracks = soa::Join< + aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, + aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta>; + +using SelectedCollisions = soa::Join; + +struct DedxPidAnalysis { + + // dE/dx for all charged particles + HistogramRegistry registryDeDx{ + "registryDeDx", + {}, + OutputObjHandlingPolicy::AnalysisObject, + true, + true}; + // Constant values + static constexpr int kEtaIntervals = 8; + static constexpr int kParticlesType = 4; + float tpcCut = 0.6; + float pionMin = 0.35; + float pionMax = 0.45; + float elTofCut = 0.1; + float pionTofCut = 1.0; + float invMassCut = 0.01; + float invMassCutGamma = 0.0015; + float magField = 1; + float pTcut = 2.0; + + // Configurable Parameters + // Tracks cuts + Configurable minTPCnClsFound{"minTPCnClsFound", 70.0f, + "min number of found TPC clusters"}; + Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.0f, "min number of found TPC crossed rows"}; + Configurable maxChi2TPC{"maxChi2TPC", 4.0f, + "max chi2 per cluster TPC"}; + Configurable maxChi2ITS{"maxChi2ITS", 36.0f, + "max chi2 per cluster ITS"}; + Configurable maxZDistanceToIP{"maxZDistanceToIP", 10.0f, + "max z distance to IP"}; + Configurable etaMin{"etaMin", -0.8f, "etaMin"}; + Configurable etaMax{"etaMax", +0.8f, "etaMax"}; + Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; + Configurable maxDCAz{"maxDCAz", 2.f, "maxDCAz"}; + // v0 cuts + Configurable v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"}; + Configurable minimumV0Radius{"minimumV0Radius", 0.5f, + "Minimum V0 Radius"}; + Configurable maximumV0Radius{"maximumV0Radius", 100.0f, + "Maximum V0 Radius"}; + Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, + "Maximum DCA Daughters"}; + Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; + Configurable minMassK0s{"minMassK0s", 0.4f, "Minimum Mass K0s"}; + Configurable maxMassK0s{"maxMassK0s", 0.6f, "Maximum Mass K0s"}; + Configurable minMassLambda{"minMassLambda", 1.1f, + "Minimum Mass Lambda"}; + Configurable maxMassLambda{"maxMassLambda", 1.2f, + "Maximum Mass Lambda"}; + Configurable minMassGamma{"minMassGamma", 0.000922f, + "Minimum Mass Gamma"}; + Configurable maxMassGamma{"maxMassGamma", 0.002022f, + "Maximum Mass Gamma"}; + Configurable nclCut{"nclCut", 135.0f, + "ncl Cut"}; + Configurable calibrationMode{"calibrationMode", false, "calibration mode"}; + Configurable additionalCuts{"additionalCuts", true, "additional cuts"}; + // Histograms names + static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; + static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + static constexpr std::string_view kNclDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_vs_dEdx_vs_Momentum_Pos_8_After"}; + static constexpr double EtaCut[kEtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; + Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; + ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; + + // phi cut fits + TF1* fphiCutHigh = nullptr; + TF1* fphiCutLow = nullptr; + + TrackSelection myTrackSelection() + { + TrackSelection selectedTracks; + selectedTracks.SetPtRange(0.1f, 1e10f); + selectedTracks.SetEtaRange(etaMin, etaMax); + selectedTracks.SetRequireITSRefit(true); + selectedTracks.SetRequireTPCRefit(true); + selectedTracks.SetMinNCrossedRowsTPC(minNCrossedRowsTPC); + selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC); + selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); + selectedTracks.SetRequireHitsInITSLayers(1, {0, 1}); + selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); + selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); + selectedTracks.SetMaxDcaZ(maxDCAz); + selectedTracks.SetRequireGoldenChi2(true); + + return selectedTracks; + } + + TrackSelection mySelectionPrim; + + void init(InitContext const&) + { + AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; + AxisSpec ptAxis = {binP, "pT (GeV/c)"}; + AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; + AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; + fphiCutLow = new TF1("StandardPhiCutLow", "0.119297/x/x+pi/18.0-0.000379693", 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", "0.16685/x+pi/18.0+0.00981942", 0, 50); + if (calibrationMode) { + // MIP for pions + registryDeDx.add( + "hdEdx_vs_eta_Neg_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + registryDeDx.add( + "hdEdx_vs_eta_Pos_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + // MIP for electrons + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + // Pions from TOF + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + } else { + // MIP for pions + registryDeDx.add( + "hdEdx_vs_eta_Neg_calibrated_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + + registryDeDx.add( + "hdEdx_vs_eta_Pos_calibrated_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + + // MIP for electrons + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_calibrated_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_calibrated_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + // Pions from TOF + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_calibrated_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_calibrated_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + // pt vs p + registryDeDx.add( + "hp_vs_pt_all_Neg", "p_vs_pT", HistType::kTH2F, + {{ptAxis}, {pAxis}}); + registryDeDx.add( + "hp_vs_pt_all_Pos", "p_vs_pT", HistType::kTH2F, + {{ptAxis}, {pAxis}}); + + // De/Dx for ch and v0 particles + for (int i = 0; i < kParticlesType; ++i) { + registryDeDx.add(kDedxvsMomentumPos[i].data(), "dE/dx", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + registryDeDx.add(kDedxvsMomentumNeg[i].data(), "dE/dx", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + } + } + + registryDeDx.add( + "hdEdx_vs_phi", "dE/dx", HistType::kTH2F, + {{100, 0.0, 6.4, "#phi"}, {dedxAxis}}); + + // phi cut + registryDeDx.add( + "hpt_vs_phi_Ncl_After", "phi cut", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + + registryDeDx.add( + "hpt_vs_phi_Ncl_Before", "phi cut", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + + // Ncl vs de/dx + + for (int i = 0; i < kEtaIntervals; ++i) { + registryDeDx.add(kNclDedxMomentumPosBefore[i].data(), "Ncl vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclDedxMomentumNegBefore[i].data(), "Ncl vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + + registryDeDx.add(kNclDedxMomentumPosAfter[i].data(), "Ncl vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclDedxMomentumNegAfter[i].data(), "Ncl vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + } + + // beta plot + registryDeDx.add( + "hbeta_vs_p_Neg", "beta", HistType::kTH2F, + {{pAxis}, {100, 0.0, 1.1, "#beta"}}); + + registryDeDx.add( + "hbeta_vs_p_Pos", "beta", HistType::kTH2F, + {{pAxis}, {100, 0.0, 1.1, "#beta"}}); + + // Event Counter + registryDeDx.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{100, -20.0, +20.0, "z_{vtx} (cm)"}}); + + mySelectionPrim = myTrackSelection(); + } + + // Single-Track Selection + template + bool passedSingleTrackSelection(const T1& track, const C& /*collision*/) + { + // Single-Track Selections + if (!track.hasTPC()) + return false; + if (track.tpcNClsFound() < minTPCnClsFound) + return false; + if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) + return false; + if (track.tpcChi2NCl() > maxChi2TPC) + return false; + if (track.eta() < etaMin || track.eta() > etaMax) + return false; + + return true; + } + + // General V0 Selections + template + bool passedV0Selection(const T1& v0, const C& /*collision*/) + { + if (v0.v0cosPA() < v0cospaMin) + return false; + if (v0.v0radius() < minimumV0Radius || v0.v0radius() > maximumV0Radius) + return false; + + return true; + } + + // K0s Selections + template + bool passedK0Selection(const T1& v0, const T2& ntrack, const T2& ptrack, + const C& collision) + { + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mK0Short() < minMassK0s || v0.mK0Short() > maxMassK0s) + return false; + + return true; + } + + // Lambda Selections + template + bool passedLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, + const C& collision) + { + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaPr()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mLambda() < minMassLambda || v0.mLambda() > maxMassLambda) + return false; + + return true; + } + + // AntiLambda Selections + template + bool passedAntiLambdaSelection(const T1& v0, const T2& ntrack, + const T2& ptrack, const C& collision) + { + + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaPr()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mAntiLambda() < minMassLambda || v0.mAntiLambda() > maxMassLambda) + return false; + + return true; + } + + // Gamma Selections + template + bool passedGammaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, + const C& collision) + { + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaEl()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaEl()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mGamma() < minMassGamma || v0.mGamma() > maxMassGamma) + return false; + + return true; + } + + // Phi cut + template + bool passedPhiCut(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + { + float pt = trk.pt(); + float phi = trk.phi(); + int charge = trk.sign(); + float eta = trk.eta(); + auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); + float sigP = trk.sign() * trk.tpcInnerParam(); + + if (pt < pTcut) + return true; + + if (magField < 0) // for negatve polarity field + phi = o2::constants::math::TwoPI - phi; + if (charge < 0) // for negatve charge + phi = o2::constants::math::TwoPI - phi; + + // to center gap in the middle + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_Before"), pt, phi, nTPCCl); + + // cut phi + if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) + return false; // reject track + + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + } + } + + // cut Ncl + if (nTPCCl < nclCut) + return false; + + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_After"), pt, phi, nTPCCl); + + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + } + } + + return true; + } + + // Phi cut Secondaries + template + bool passedPhiCutSecondaries(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + { + float pt = trk.pt(); + float phi = trk.phi(); + int charge = trk.sign(); + auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); + + if (pt < pTcut) + return true; + + if (magField < 0) // for negatve polarity field + phi = o2::constants::math::TwoPI - phi; + if (charge < 0) // for negatve charge + phi = o2::constants::math::TwoPI - phi; + + // to center gap in the middle + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + + // cut phi + if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) + return false; // reject track + + // cut Ncl + if (nTPCCl < nclCut) + return false; + + return true; + } + + // Process Data + void process(SelectedCollisions::iterator const& collision, + aod::V0Datas const& fullV0s, PIDTracks const& tracks) + { + // Event Selection + if (!collision.sel8()) + return; + + if (additionalCuts) { + if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + + if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + + if (std::abs(collision.posZ()) >= maxZDistanceToIP) + return; + + if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) + return; + } + + // Event Counter + registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); + + // Kaons + for (const auto& trk : tracks) { + + // track Selection + if (!passedSingleTrackSelection(trk, collision)) + continue; + + if (!mySelectionPrim.IsSelected(trk)) + continue; + + // phi and Ncl cut + if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + float signedP = trk.sign() * trk.tpcInnerParam(); + + // MIP calibration for pions + if (trk.tpcInnerParam() >= pionMin && trk.tpcInnerParam() <= pionMax) { + if (calibrationMode) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_Pi"), trk.eta(), trk.tpcSignal()); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_Pos_Pi"), trk.eta(), trk.tpcSignal()); + } + + } else { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_calibrated_Pi"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_Pos_calibrated_Pi"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorPos->at(i)); + } + } + } + } + } + // Beta from TOF + if (signedP < 0) { + registryDeDx.fill(HIST("hbeta_vs_p_Neg"), std::abs(signedP), trk.beta()); + } else { + registryDeDx.fill(HIST("hbeta_vs_p_Pos"), signedP, trk.beta()); + } + // Electrons from TOF + if (std::abs(trk.beta() - 1) < elTofCut) { // beta cut + if (calibrationMode) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_El"), trk.eta(), trk.tpcSignal(), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_El"), trk.eta(), trk.tpcSignal(), signedP); + } + } else { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_El"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_calibrated_El"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorPos->at(i), signedP); + } + } + } + } + } + // pions from TOF + if (trk.beta() > pionTofCut && trk.beta() < pionTofCut + 0.05) { // beta cut + if (calibrationMode) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_TOF"), trk.eta(), trk.tpcSignal(), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_TOF"), trk.eta(), trk.tpcSignal(), signedP); + } + } else { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_TOF"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_calibrated_TOF"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorPos->at(i), signedP); + } + } + } + } + } + + registryDeDx.fill(HIST("hdEdx_vs_phi"), trk.phi(), trk.tpcSignal()); + + if (!calibrationMode) { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP > 0) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + registryDeDx.fill(HIST("hp_vs_pt_all_Pos"), trk.pt(), signedP); + } else { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + registryDeDx.fill(HIST("hp_vs_pt_all_Neg"), trk.pt(), std::abs(signedP)); + } + } + } + } + } + + // Loop over Reconstructed V0s + if (!calibrationMode) { + for (const auto& v0 : fullV0s) { + + // Standard V0 Selections + if (!passedV0Selection(v0, collision)) { + continue; + } + + if (v0.dcaV0daughters() > dcaV0DaughtersMax) { + continue; + } + + // Positive and Negative Tracks + const auto& posTrack = v0.posTrack_as(); + const auto& negTrack = v0.negTrack_as(); + + if (!posTrack.passedTPCRefit()) + continue; + if (!negTrack.passedTPCRefit()) + continue; + // phi and Ncl cut + if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); + float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); + + float pxPos = posTrack.px(); + float pyPos = posTrack.py(); + float pzPos = posTrack.pz(); + + float pxNeg = negTrack.px(); + float pyNeg = negTrack.py(); + float pzNeg = negTrack.pz(); + + const float gammaMass = 2 * MassElectron; // GeV/c^2 + + // K0s Selection + if (passedK0Selection(v0, negTrack, posTrack, collision)) { + float ePosPi = posTrack.energy(MassPionCharged); + float eNegPi = negTrack.energy(MassPionCharged); + + float invMass = std::sqrt((eNegPi + ePosPi) * (eNegPi + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - MassK0Short) > invMassCut) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + + // Lambda Selection + if (passedLambdaSelection(v0, negTrack, posTrack, collision)) { + + float ePosPr = posTrack.energy(MassProton); + float eNegPi = negTrack.energy(MassPionCharged); + + float invMass = std::sqrt((eNegPi + ePosPr) * (eNegPi + ePosPr) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - MassLambda) > invMassCut) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[2]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + + // AntiLambda Selection + if (passedAntiLambdaSelection(v0, negTrack, posTrack, collision)) { + + float ePosPi = posTrack.energy(MassPionCharged); + float eNegPr = negTrack.energy(MassProton); + + float invMass = std::sqrt((eNegPr + ePosPi) * (eNegPr + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - MassLambda) > invMassCut) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + + // Gamma Selection + if (passedGammaSelection(v0, negTrack, posTrack, collision)) { + + float ePosEl = posTrack.energy(MassElectron); + float eNegEl = negTrack.energy(MassElectron); + + float invMass = std::sqrt((eNegEl + ePosEl) * (eNegEl + ePosEl) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - gammaMass) > invMassCutGamma) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[3]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From a5bcb83be84fb35873e4cd14835046e668f4b33a Mon Sep 17 00:00:00 2001 From: PaolaVT Date: Fri, 22 Aug 2025 12:46:33 -0600 Subject: [PATCH 03/24] Event selection was modified --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 47 +++++++++++--------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index d688f0c8e72..f6e38799dcf 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -79,7 +79,7 @@ struct DedxPidAnalysis { Configurable etaMin{"etaMin", -0.8f, "etaMin"}; Configurable etaMax{"etaMax", +0.8f, "etaMax"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; - Configurable maxDCAz{"maxDCAz", 2.f, "maxDCAz"}; + Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; // v0 cuts Configurable v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"}; Configurable minimumV0Radius{"minimumV0Radius", 0.5f, @@ -201,11 +201,11 @@ struct DedxPidAnalysis { // pt vs p registryDeDx.add( - "hp_vs_pt_all_Neg", "p_vs_pT", HistType::kTH2F, - {{ptAxis}, {pAxis}}); + "heta_vs_p_vs_pt_all_Neg", "eta_vs_p_vs_pT", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); registryDeDx.add( - "hp_vs_pt_all_Pos", "p_vs_pT", HistType::kTH2F, - {{ptAxis}, {pAxis}}); + "heta_vs_p_vs_pt_all_Pos", "eta_vs_p_vs_pT", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); // De/Dx for ch and v0 particles for (int i = 0; i < kParticlesType; ++i) { @@ -596,19 +596,8 @@ struct DedxPidAnalysis { if (!collision.sel8()) return; - if (additionalCuts) { - if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) - return; - - if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) - return; - - if (std::abs(collision.posZ()) >= maxZDistanceToIP) - return; - - if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) - return; - } + if (std::abs(collision.posZ()) > maxZDistanceToIP) + return; // Event Counter registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); @@ -624,8 +613,10 @@ struct DedxPidAnalysis { continue; // phi and Ncl cut - if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (additionalCuts) { + if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } float signedP = trk.sign() * trk.tpcInnerParam(); @@ -704,10 +695,10 @@ struct DedxPidAnalysis { if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP > 0) { registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - registryDeDx.fill(HIST("hp_vs_pt_all_Pos"), trk.pt(), signedP); + registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Pos"), trk.eta(), trk.pt(), signedP); } else { registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - registryDeDx.fill(HIST("hp_vs_pt_all_Neg"), trk.pt(), std::abs(signedP)); + registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Neg"), trk.eta(), trk.pt(), std::abs(signedP)); } } } @@ -736,11 +727,13 @@ struct DedxPidAnalysis { if (!negTrack.passedTPCRefit()) continue; // phi and Ncl cut - if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; - - if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (additionalCuts) { + if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); From 3ca59ecc4d7934e3e7728faf82ab80e731e700eb Mon Sep 17 00:00:00 2001 From: PaolaVT Date: Fri, 22 Aug 2025 13:01:22 -0600 Subject: [PATCH 04/24] Event selection was modified --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index f6e38799dcf..2d042bd5e96 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -613,10 +613,10 @@ struct DedxPidAnalysis { continue; // phi and Ncl cut - if (additionalCuts) { - if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) - continue; - } + if (additionalCuts) { + if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } float signedP = trk.sign() * trk.tpcInnerParam(); @@ -727,13 +727,13 @@ struct DedxPidAnalysis { if (!negTrack.passedTPCRefit()) continue; // phi and Ncl cut - if (additionalCuts) { - if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; - - if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; - } + if (additionalCuts) { + if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); From 55663dd91eb54c53d02c74f2ebde0d3088f425a4 Mon Sep 17 00:00:00 2001 From: PaolaVT Date: Thu, 4 Sep 2025 00:41:43 -0600 Subject: [PATCH 05/24] New cuts and some modifications on their names were implemented --- PWGMM/UE/Tasks/dedxAnalysis.cxx | 532 +++++++++++++++++++++++++------- 1 file changed, 427 insertions(+), 105 deletions(-) diff --git a/PWGMM/UE/Tasks/dedxAnalysis.cxx b/PWGMM/UE/Tasks/dedxAnalysis.cxx index 11aea4031be..faaf9cca459 100644 --- a/PWGMM/UE/Tasks/dedxAnalysis.cxx +++ b/PWGMM/UE/Tasks/dedxAnalysis.cxx @@ -25,11 +25,18 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "Framework/ASoA.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" +#include "Framework/Logger.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" +#include "ReconstructionDataFormats/V0.h" #include "TF1.h" @@ -42,6 +49,7 @@ using PIDTracks = soa::Join< aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta>; using SelectedCollisions = soa::Join; +using BCsRun3 = soa::Join; struct DedxAnalysis { @@ -62,13 +70,47 @@ struct DedxAnalysis { float pionTofCut = 1.0; float invMassCut = 0.01; float invMassCutGamma = 0.0015; - float magField = 1; float pTcut = 2.0; + // Event cut labels + enum EvCutLabel { + AllEv = 1, + SelEigth, + ZVtxCut + }; + + // Track primary label + enum TrkPriCutLabel { + AllPri = 1, + SelectionPrim, + PhiVarCutPri, + NTPCClCutPri, + NITSClCutPri + }; + + // Track secondary lebel + enum TrkSecCutLabel { + AllSec = 1, + V0CosPA, + V0DecayRadius, + V0Daughters, + TPCRefit, + PhiVarCutSec, + NTPCClCutSec, + NITSClCutSec, + V0RapidityK0s, + V0ProperLifetimeK0s, + V0RapidityLambda, + V0ProperLifetimeLambda, + V0RapidityAntiLambda, + V0ProperLifetimeAntiLambda + }; // Configurable Parameters // Tracks cuts Configurable minTPCnClsFound{"minTPCnClsFound", 70.0f, "min number of found TPC clusters"}; + Configurable minITSnCls{"minITSnCls", 70.0f, + "min number of ITS clusters"}; Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.0f, "min number of found TPC crossed rows"}; Configurable maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"}; @@ -79,7 +121,7 @@ struct DedxAnalysis { Configurable etaMin{"etaMin", -0.8f, "etaMin"}; Configurable etaMax{"etaMax", +0.8f, "etaMax"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; - Configurable maxDCAz{"maxDCAz", 2.f, "maxDCAz"}; + Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; // v0 cuts Configurable v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"}; Configurable minimumV0Radius{"minimumV0Radius", 0.5f, @@ -88,6 +130,9 @@ struct DedxAnalysis { "Maximum V0 Radius"}; Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, "Maximum DCA Daughters"}; + Configurable v0rapidityCut{"v0rapidityCut", 0.5f, "V0 rapidity cut"}; + Configurable v0ProperLifetimeCutK0s{"v0ProperLifetimeCutK0s", 20.f, "V0 proper lifetime cut for K0s"}; + Configurable v0ProperLifetimeCutLambda{"v0ProperLifetimeCutLambda", 30.f, "V0 proper lifetime cut for Lambda"}; Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; Configurable minMassK0s{"minMassK0s", 0.4f, "Minimum Mass K0s"}; Configurable maxMassK0s{"maxMassK0s", 0.6f, "Maximum Mass K0s"}; @@ -99,17 +144,23 @@ struct DedxAnalysis { "Minimum Mass Gamma"}; Configurable maxMassGamma{"maxMassGamma", 0.002022f, "Maximum Mass Gamma"}; - Configurable nclCut{"nclCut", 135.0f, - "ncl Cut"}; Configurable calibrationMode{"calibrationMode", false, "calibration mode"}; - Configurable additionalCuts{"additionalCuts", true, "additional cuts"}; + Configurable phiVarCut{"phiVarCut", true, "phi var cut"}; + Configurable nTPCClCut{"nTPCClCut", true, "number of clusters in TPC cut"}; + Configurable nITSClCut{"nITSClCut", true, "number of clusters in ITS cut"}; // Histograms names static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; - static constexpr std::string_view kNclDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view kNclDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view kNclDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view kNclDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_vs_dEdx_vs_Momentum_Pos_8_After"}; + // Ncl TPC + static constexpr std::string_view kNclTPCDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclTPCDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclTPCDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclTPCDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_8_After"}; + // Ncl TPC + static constexpr std::string_view kNclITSDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclITSDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclITSDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclITSDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_8_After"}; static constexpr double EtaCut[kEtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; @@ -118,6 +169,7 @@ struct DedxAnalysis { // phi cut fits TF1* fphiCutHigh = nullptr; TF1* fphiCutLow = nullptr; + Service ccdb; TrackSelection myTrackSelection() { @@ -129,7 +181,7 @@ struct DedxAnalysis { selectedTracks.SetMinNCrossedRowsTPC(minNCrossedRowsTPC); selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC); selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); - selectedTracks.SetRequireHitsInITSLayers(1, {0, 1}); + selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); selectedTracks.SetMaxDcaZ(maxDCAz); @@ -201,11 +253,11 @@ struct DedxAnalysis { // pt vs p registryDeDx.add( - "hp_vs_pt_all_Neg", "p_vs_pT", HistType::kTH2F, - {{ptAxis}, {pAxis}}); + "heta_vs_p_vs_pt_all_Neg", "eta_vs_p_vs_pT", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); registryDeDx.add( - "hp_vs_pt_all_Pos", "p_vs_pT", HistType::kTH2F, - {{ptAxis}, {pAxis}}); + "heta_vs_p_vs_pt_all_Pos", "eta_vs_p_vs_pT", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); // De/Dx for ch and v0 particles for (int i = 0; i < kParticlesType; ++i) { @@ -219,28 +271,45 @@ struct DedxAnalysis { registryDeDx.add( "hdEdx_vs_phi", "dE/dx", HistType::kTH2F, {{100, 0.0, 6.4, "#phi"}, {dedxAxis}}); - // phi cut - registryDeDx.add( - "hpt_vs_phi_Ncl_After", "phi cut", HistType::kTH3F, - {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); - - registryDeDx.add( - "hpt_vs_phi_Ncl_Before", "phi cut", HistType::kTH3F, - {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); - - // Ncl vs de/dx + if (phiVarCut) { + registryDeDx.add( + "hpt_vs_phi_Ncl_TPC_After", "phi cut", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); - for (int i = 0; i < kEtaIntervals; ++i) { - registryDeDx.add(kNclDedxMomentumPosBefore[i].data(), "Ncl vs dE/dx vs Momentum Positive before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclDedxMomentumNegBefore[i].data(), "Ncl vs dE/dx vs Momentum Negative before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add( + "hpt_vs_phi_Ncl_TPC_Before", "phi cut", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + + // Ncl vs de/dx TPC + + for (int i = 0; i < kEtaIntervals; ++i) { + registryDeDx.add(kNclTPCDedxMomentumPosBefore[i].data(), "Ncl TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclTPCDedxMomentumNegBefore[i].data(), "Ncl TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + if (nTPCClCut) { + registryDeDx.add(kNclTPCDedxMomentumPosAfter[i].data(), "Ncl TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclTPCDedxMomentumNegAfter[i].data(), "Ncl TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + } + } + } - registryDeDx.add(kNclDedxMomentumPosAfter[i].data(), "Ncl vs dE/dx vs Momentum Positive after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclDedxMomentumNegAfter[i].data(), "Ncl vs dE/dx vs Momentum Negative after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + // Ncl vs de/dx ITS + if (nITSClCut) { + for (int i = 0; i < kEtaIntervals; ++i) { + registryDeDx.add(kNclITSDedxMomentumPosBefore[i].data(), "Ncl ITS vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclITSDedxMomentumNegBefore[i].data(), "Ncl ITS vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + + registryDeDx.add(kNclITSDedxMomentumPosAfter[i].data(), "Ncl ITS vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclITSDedxMomentumNegAfter[i].data(), "Ncl ITS vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + } } // beta plot @@ -255,6 +324,42 @@ struct DedxAnalysis { // Event Counter registryDeDx.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{100, -20.0, +20.0, "z_{vtx} (cm)"}}); + // Event Counter + registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{3, 0.5, 3.5, ""}}); + auto hstat = registryDeDx.get(HIST("evsel")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "AllEv"); + x->SetBinLabel(2, "SelEigth"); + x->SetBinLabel(3, "ZVtxCut"); + + // Track Counter + registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); + auto htrackAll = registryDeDx.get(HIST("trackselAll")); + auto* xAll = htrackAll->GetXaxis(); + xAll->SetBinLabel(1, "AllPri"); + xAll->SetBinLabel(2, "SelectionPrim"); + xAll->SetBinLabel(3, "PhiVarCutPri"); + xAll->SetBinLabel(4, "NTPCClCutPri"); + xAll->SetBinLabel(5, "NITSClCutPri"); + + registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{13, 0.5, 13.5, ""}}); + auto htrackSec = registryDeDx.get(HIST("trackselSec")); + auto* xSec = htrackSec->GetXaxis(); + xSec->SetBinLabel(1, "AllSec"); + xSec->SetBinLabel(2, "V0CosPA"); + xSec->SetBinLabel(3, "V0DecayRadius"); + xSec->SetBinLabel(4, "V0Daughters"); + xSec->SetBinLabel(5, "TPCRefit"); + xSec->SetBinLabel(6, "PhiVarCutSec"); + xSec->SetBinLabel(7, "NTPCClCutSec"); + xSec->SetBinLabel(8, "NITSClCutSec"); + xSec->SetBinLabel(9, "V0RapidityK0s"); + xSec->SetBinLabel(10, "V0ProperLifetimeK0s"); + xSec->SetBinLabel(11, "V0RapidityLambda"); + xSec->SetBinLabel(12, "V0ProperLifetimeLambda"); + xSec->SetBinLabel(13, "V0RapidityAntiLambda"); + xSec->SetBinLabel(14, "V0ProperLifetimeAntiLambda"); + mySelectionPrim = myTrackSelection(); } @@ -265,8 +370,6 @@ struct DedxAnalysis { // Single-Track Selections if (!track.hasTPC()) return false; - if (track.tpcNClsFound() < minTPCnClsFound) - return false; if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) return false; if (track.tpcChi2NCl() > maxChi2TPC) @@ -283,8 +386,15 @@ struct DedxAnalysis { { if (v0.v0cosPA() < v0cospaMin) return false; + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0CosPA); + if (v0.v0radius() < minimumV0Radius || v0.v0radius() > maximumV0Radius) return false; + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0DecayRadius); + + if (v0.dcaV0daughters() > dcaV0DaughtersMax) + return false; + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0Daughters); return true; } @@ -417,17 +527,31 @@ struct DedxAnalysis { return true; } + // Magnetic field + int getMagneticField(uint64_t timestamp) + { + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } // Phi cut template - bool passedPhiCut(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + bool passedPhiVarCut(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) { float pt = trk.pt(); float phi = trk.phi(); int charge = trk.sign(); float eta = trk.eta(); - auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); float sigP = trk.sign() * trk.tpcInnerParam(); + auto nTPCCl = trk.tpcNClsFound(); if (pt < pTcut) return true; @@ -441,7 +565,7 @@ struct DedxAnalysis { phi += o2::constants::math::PI / 18.0f; phi = std::fmod(phi, o2::constants::math::PI / 9.0f); - registryDeDx.fill(HIST("hpt_vs_phi_Ncl_Before"), pt, phi, nTPCCl); + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_TPC_Before"), pt, phi, nTPCCl); // cut phi if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) @@ -449,107 +573,224 @@ struct DedxAnalysis { if (eta > EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); } } + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::PhiVarCutPri); - // cut Ncl - if (nTPCCl < nclCut) - return false; + if (nTPCClCut) { + // cut Ncl + if (nTPCCl < minTPCnClsFound) + return false; - registryDeDx.fill(HIST("hpt_vs_phi_Ncl_After"), pt, phi, nTPCCl); + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_TPC_After"), pt, phi, nTPCCl); + + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + } + } + } + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NTPCClCutPri); + return true; + } + + // NclCutITS + template + bool passedNITSClCut(const T& trk) + { + float eta = trk.eta(); + float sigP = trk.sign() * trk.tpcInnerParam(); + auto nITSCl = trk.itsNCls(); if (eta > EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[0]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[0]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[1]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[1]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[2]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[2]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[3]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[3]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[4]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[4]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[5]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[5]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[6]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[6]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[7]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[7]), nITSCl, trk.tpcSignal(), sigP); + } + } + + if (nITSCl < minITSnCls) + return false; + + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[0]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[0]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[1]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[1]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[2]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[2]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[3]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[3]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[4]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[4]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[5]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[5]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[6]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[6]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[7]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[7]), nITSCl, trk.tpcSignal(), sigP); } } @@ -563,7 +804,6 @@ struct DedxAnalysis { float pt = trk.pt(); float phi = trk.phi(); int charge = trk.sign(); - auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); if (pt < pTcut) return true; @@ -581,8 +821,28 @@ struct DedxAnalysis { if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) return false; // reject track - // cut Ncl - if (nTPCCl < nclCut) + return true; + } + + // NclCutTPC + template + bool passedNTPCClCutSecondaries(const T& trk) + { + auto nTPCCl = trk.tpcNClsFound(); + + if (nTPCCl < minTPCnClsFound) + return false; + + return true; + } + + // NclCutITS primary + template + bool passedNITSClCutSecondaries(const T& trk) + { + auto nITSCl = trk.itsNCls(); + + if (nITSCl < minITSnCls) return false; return true; @@ -592,40 +852,46 @@ struct DedxAnalysis { void process(SelectedCollisions::iterator const& collision, aod::V0Datas const& fullV0s, PIDTracks const& tracks) { + registryDeDx.fill(HIST("evsel"), EvCutLabel::AllEv); // Event Selection if (!collision.sel8()) return; - if (additionalCuts) { - if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) - return; + registryDeDx.fill(HIST("evsel"), EvCutLabel::SelEigth); - if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) - return; - - if (std::abs(collision.posZ()) >= maxZDistanceToIP) - return; + if (std::abs(collision.posZ()) > maxZDistanceToIP) + return; - if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) - return; - } + registryDeDx.fill(HIST("evsel"), EvCutLabel::ZVtxCut); // Event Counter registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); - // Kaons - for (const auto& trk : tracks) { + // For magnetic field + const auto& foundBC = collision.foundBC_as(); + const uint64_t timeStamp{foundBC.timestamp()}; + const int magField{getMagneticField(timeStamp)}; + for (const auto& trk : tracks) { + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::AllPri); // track Selection - if (!passedSingleTrackSelection(trk, collision)) - continue; - if (!mySelectionPrim.IsSelected(trk)) continue; + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); + // phi and Ncl cut - if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (phiVarCut) { + if (!passedPhiVarCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } + + // NCl cut ITS + if (nITSClCut) { + if (!passedNITSClCut(trk)) + continue; + } + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NITSClCutPri); float signedP = trk.sign() * trk.tpcInnerParam(); @@ -704,10 +970,10 @@ struct DedxAnalysis { if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP > 0) { registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - registryDeDx.fill(HIST("hp_vs_pt_all_Pos"), trk.pt(), signedP); + registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Pos"), trk.eta(), trk.pt(), signedP); } else { registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - registryDeDx.fill(HIST("hp_vs_pt_all_Neg"), trk.pt(), std::abs(signedP)); + registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Neg"), trk.eta(), trk.pt(), std::abs(signedP)); } } } @@ -719,14 +985,11 @@ struct DedxAnalysis { for (const auto& v0 : fullV0s) { // Standard V0 Selections + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllSec); if (!passedV0Selection(v0, collision)) { continue; } - if (v0.dcaV0daughters() > dcaV0DaughtersMax) { - continue; - } - // Positive and Negative Tracks const auto& posTrack = v0.posTrack_as(); const auto& negTrack = v0.negTrack_as(); @@ -735,12 +998,37 @@ struct DedxAnalysis { continue; if (!negTrack.passedTPCRefit()) continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::TPCRefit); // phi and Ncl cut - if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (phiVarCut) { + if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; - if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) - continue; + if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + } + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::PhiVarCutSec); + + if (nTPCClCut) { + if (!passedNTPCClCutSecondaries(posTrack)) + continue; + + if (!passedNTPCClCutSecondaries(negTrack)) + continue; + } + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NTPCClCutSec); + + if (nITSClCut) { + if (!passedNITSClCutSecondaries(posTrack)) + continue; + + if (!passedNITSClCutSecondaries(negTrack)) + continue; + } + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NITSClCutSec); float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); @@ -757,6 +1045,18 @@ struct DedxAnalysis { // K0s Selection if (passedK0Selection(v0, negTrack, posTrack, collision)) { + + if (std::abs(v0.rapidity(MassK0Short)) > v0rapidityCut) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityK0s); + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassK0Short; + + if (properLifetime > v0ProperLifetimeCutK0s) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeK0s); + float ePosPi = posTrack.energy(MassPionCharged); float eNegPi = negTrack.energy(MassPionCharged); @@ -779,6 +1079,17 @@ struct DedxAnalysis { // Lambda Selection if (passedLambdaSelection(v0, negTrack, posTrack, collision)) { + if (std::abs(v0.rapidity(MassLambda)) > v0rapidityCut) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityLambda); + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; + + if (properLifetime > v0ProperLifetimeCutLambda) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeLambda); + float ePosPr = posTrack.energy(MassProton); float eNegPi = negTrack.energy(MassPionCharged); @@ -801,6 +1112,17 @@ struct DedxAnalysis { // AntiLambda Selection if (passedAntiLambdaSelection(v0, negTrack, posTrack, collision)) { + if (std::abs(v0.rapidity(MassLambda)) > v0rapidityCut) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityAntiLambda); + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; + + if (properLifetime > v0ProperLifetimeCutLambda) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeAntiLambda); + float ePosPi = posTrack.energy(MassPionCharged); float eNegPr = negTrack.energy(MassProton); From d97f118583f907fd4a6a0f14b25c085738584220 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Thu, 11 Sep 2025 15:48:16 -0600 Subject: [PATCH 06/24] New histograms, event and track seleccions were implemented --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 639 +++++++++++++++++++++---- 1 file changed, 544 insertions(+), 95 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 2d042bd5e96..851d1634b68 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -25,9 +25,13 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "Framework/ASoA.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" +#include "Framework/Logger.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" @@ -35,13 +39,15 @@ using namespace o2; using namespace o2::framework; +using namespace o2::framework::expressions; using namespace constants::physics; using PIDTracks = soa::Join< aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, - aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta>; + aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta, aod::pidTPCPi, aod::pidTPCPr, aod::pidTPCEl>; using SelectedCollisions = soa::Join; +using BCsRun3 = soa::Join; struct DedxPidAnalysis { @@ -62,13 +68,54 @@ struct DedxPidAnalysis { float pionTofCut = 1.0; float invMassCut = 0.01; float invMassCutGamma = 0.0015; - float magField = 1; float pTcut = 2.0; + // Event cut labels + enum EvCutLabel { + AllEv = 1, + SelEigth, + ZVtxCut, + NoSameBunchPileup, + GoodZvtxFT0vsPV + + }; + + // Track primary label + enum TrkPriCutLabel { + AllPri = 1, + SelectionPrim, + PhiVarCutPri, + NTPCClCutPri, + NITSClCutPri + }; + + // Track secondary lebel + enum TrkSecCutLabel { + AllSec = 1, + V0CosPA, + V0DecayRadius, + V0Daughters, + TPCRefit, + PhiVarCutSec, + NTPCClCutSec, + NITSClCutSec, + AllK0s, + V0RapidityK0s, + V0ProperLifetimeK0s, + AllLambda, + V0RapidityLambda, + V0ProperLifetimeLambda, + AllAntiLambda, + V0RapidityAntiLambda, + V0ProperLifetimeAntiLambda, + AllGamma + }; // Configurable Parameters // Tracks cuts - Configurable minTPCnClsFound{"minTPCnClsFound", 70.0f, + Configurable minTPCnClsFound{"minTPCnClsFound", 135.0f, "min number of found TPC clusters"}; + Configurable minITSnCls{"minITSnCls", 0.0f, + "min number of ITS clusters"}; Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.0f, "min number of found TPC crossed rows"}; Configurable maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"}; @@ -88,6 +135,9 @@ struct DedxPidAnalysis { "Maximum V0 Radius"}; Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, "Maximum DCA Daughters"}; + Configurable v0rapidityCut{"v0rapidityCut", 0.5f, "V0 rapidity cut"}; + Configurable v0ProperLifetimeCutK0s{"v0ProperLifetimeCutK0s", 20.f, "V0 proper lifetime cut for K0s"}; + Configurable v0ProperLifetimeCutLambda{"v0ProperLifetimeCutLambda", 30.f, "V0 proper lifetime cut for Lambda"}; Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; Configurable minMassK0s{"minMassK0s", 0.4f, "Minimum Mass K0s"}; Configurable maxMassK0s{"maxMassK0s", 0.6f, "Maximum Mass K0s"}; @@ -99,17 +149,24 @@ struct DedxPidAnalysis { "Minimum Mass Gamma"}; Configurable maxMassGamma{"maxMassGamma", 0.002022f, "Maximum Mass Gamma"}; - Configurable nclCut{"nclCut", 135.0f, - "ncl Cut"}; Configurable calibrationMode{"calibrationMode", false, "calibration mode"}; - Configurable additionalCuts{"additionalCuts", true, "additional cuts"}; + Configurable phiVarCut{"phiVarCut", true, "phi var cut"}; + Configurable nTPCClCut{"nTPCClCut", true, "number of clusters in TPC cut"}; + Configurable nITSClCut{"nITSClCut", true, "number of clusters in ITS cut"}; + Configurable V0SelectionMode{"V0SelectionMode", 1, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; // Histograms names static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; - static constexpr std::string_view kNclDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view kNclDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view kNclDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view kNclDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_vs_dEdx_vs_Momentum_Pos_8_After"}; + // Ncl TPC + static constexpr std::string_view kNclTPCDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclTPCDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclTPCDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclTPCDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_8_After"}; + // Ncl TPC + static constexpr std::string_view kNclITSDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclITSDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclITSDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclITSDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_8_After"}; static constexpr double EtaCut[kEtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; @@ -118,6 +175,7 @@ struct DedxPidAnalysis { // phi cut fits TF1* fphiCutHigh = nullptr; TF1* fphiCutLow = nullptr; + Service ccdb; TrackSelection myTrackSelection() { @@ -129,7 +187,7 @@ struct DedxPidAnalysis { selectedTracks.SetMinNCrossedRowsTPC(minNCrossedRowsTPC); selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC); selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); - selectedTracks.SetRequireHitsInITSLayers(1, {0, 1}); + selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); selectedTracks.SetMaxDcaZ(maxDCAz); @@ -142,6 +200,14 @@ struct DedxPidAnalysis { void init(InitContext const&) { + if (V0SelectionMode == 1) { + LOGF(info, "V0 seleccion using TPC only"); + } else if (V0SelectionMode == 2) { + LOGF(info, "V0 seleccion using TOF only"); + } else if (V0SelectionMode == 3) { + LOGF(info, "V0 seleccion using TOF + TPC"); + } + AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; AxisSpec ptAxis = {binP, "pT (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; @@ -219,28 +285,61 @@ struct DedxPidAnalysis { registryDeDx.add( "hdEdx_vs_phi", "dE/dx", HistType::kTH2F, {{100, 0.0, 6.4, "#phi"}, {dedxAxis}}); - // phi cut - registryDeDx.add( - "hpt_vs_phi_Ncl_After", "phi cut", HistType::kTH3F, - {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + if (phiVarCut) { + // pt + registryDeDx.add( + "hpt_vs_phi_Ncl_TPC_After", "phi cut vs pt", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); - registryDeDx.add( - "hpt_vs_phi_Ncl_Before", "phi cut", HistType::kTH3F, - {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + registryDeDx.add( + "hpt_vs_phi_Ncl_TPC_Before", "phi cut vs pt", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + // p + registryDeDx.add( + "hp_vs_phi_Ncl_TPC_After", "phi cut vs p", HistType::kTH3F, + {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); - // Ncl vs de/dx + registryDeDx.add( + "hp_vs_phi_Ncl_TPC_Before", "phi cut vs p", HistType::kTH3F, + {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + // eta + registryDeDx.add( + "heta_vs_Ncl_TPC_Before", "eta and N_{cl}", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl}"}}); - for (int i = 0; i < kEtaIntervals; ++i) { - registryDeDx.add(kNclDedxMomentumPosBefore[i].data(), "Ncl vs dE/dx vs Momentum Positive before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclDedxMomentumNegBefore[i].data(), "Ncl vs dE/dx vs Momentum Negative before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add( + "heta_vs_Ncl_TPC_After", "eta and N_{cl} ", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl}"}}); + } + // Ncl vs de/dx TPC + if (nTPCClCut) { + for (int i = 0; i < kEtaIntervals; ++i) { + registryDeDx.add(kNclTPCDedxMomentumPosBefore[i].data(), "Ncl TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclTPCDedxMomentumNegBefore[i].data(), "Ncl TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + + registryDeDx.add(kNclTPCDedxMomentumPosAfter[i].data(), "Ncl TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclTPCDedxMomentumNegAfter[i].data(), "Ncl TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + } + } - registryDeDx.add(kNclDedxMomentumPosAfter[i].data(), "Ncl vs dE/dx vs Momentum Positive after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclDedxMomentumNegAfter[i].data(), "Ncl vs dE/dx vs Momentum Negative after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + // Ncl vs de/dx ITS + if (nITSClCut) { + for (int i = 0; i < kEtaIntervals; ++i) { + registryDeDx.add(kNclITSDedxMomentumPosBefore[i].data(), "Ncl ITS vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclITSDedxMomentumNegBefore[i].data(), "Ncl ITS vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + + registryDeDx.add(kNclITSDedxMomentumPosAfter[i].data(), "Ncl ITS vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclITSDedxMomentumNegAfter[i].data(), "Ncl ITS vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + } } // beta plot @@ -255,6 +354,48 @@ struct DedxPidAnalysis { // Event Counter registryDeDx.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{100, -20.0, +20.0, "z_{vtx} (cm)"}}); + // Event Counter + registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); + auto hstat = registryDeDx.get(HIST("evsel")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "AllEv"); + x->SetBinLabel(2, "SelEigth"); + x->SetBinLabel(3, "ZVtxCut"); + x->SetBinLabel(4, "NoSameBunchPileup"); + x->SetBinLabel(5, "GoodZvtxFT0vsPV"); + + // Track Counter + registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); + auto htrackAll = registryDeDx.get(HIST("trackselAll")); + auto* xAll = htrackAll->GetXaxis(); + xAll->SetBinLabel(1, "AllPri"); + xAll->SetBinLabel(2, "SelectionPrim"); + xAll->SetBinLabel(3, "PhiVarCutPri"); + xAll->SetBinLabel(4, "NTPCClCutPri"); + xAll->SetBinLabel(5, "NITSClCutPri"); + + registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{18, 0.5, 18.5, ""}}); + auto htrackSec = registryDeDx.get(HIST("trackselSec")); + auto* xSec = htrackSec->GetXaxis(); + xSec->SetBinLabel(1, "AllSec"); + xSec->SetBinLabel(2, "V0CosPA"); + xSec->SetBinLabel(3, "V0DecayRadius"); + xSec->SetBinLabel(4, "V0Daughters"); + xSec->SetBinLabel(5, "TPCRefit"); + xSec->SetBinLabel(6, "PhiVarCutSec"); + xSec->SetBinLabel(7, "NTPCClCutSec"); + xSec->SetBinLabel(8, "NITSClCutSec"); + xSec->SetBinLabel(9, "AllK0s"); + xSec->SetBinLabel(10, "V0RapidityK0s"); + xSec->SetBinLabel(11, "V0ProperLifetimeK0s"); + xSec->SetBinLabel(12, "AllLambda"); + xSec->SetBinLabel(13, "V0RapidityLambda"); + xSec->SetBinLabel(14, "V0ProperLifetimeLambda"); + xSec->SetBinLabel(15, "AllAntiLambda"); + xSec->SetBinLabel(16, "V0RapidityAntiLambda"); + xSec->SetBinLabel(17, "V0ProperLifetimeAntiLambda"); + xSec->SetBinLabel(18, "AllGamma"); + mySelectionPrim = myTrackSelection(); } @@ -265,8 +406,6 @@ struct DedxPidAnalysis { // Single-Track Selections if (!track.hasTPC()) return false; - if (track.tpcNClsFound() < minTPCnClsFound) - return false; if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) return false; if (track.tpcChi2NCl() > maxChi2TPC) @@ -283,8 +422,15 @@ struct DedxPidAnalysis { { if (v0.v0cosPA() < v0cospaMin) return false; + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0CosPA); + if (v0.v0radius() < minimumV0Radius || v0.v0radius() > maximumV0Radius) return false; + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0DecayRadius); + + if (v0.dcaV0daughters() > dcaV0DaughtersMax) + return false; + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0Daughters); return true; } @@ -299,18 +445,31 @@ struct DedxPidAnalysis { return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; + double sigmap = 0.0; + double sigman = 0.0; + + if (V0SelectionMode == 1) { + sigmap = ptrack.tpcNSigmaPi(); + sigman = ntrack.tpcNSigmaPi(); + } else if (V0SelectionMode == 2) { + sigmap = ptrack.tofNSigmaPi(); + sigman = ntrack.tofNSigmaPi(); + } else if (V0SelectionMode == 3) { + sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); + sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); + } if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaTOFmax) return false; } if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaTOFmax) return false; } @@ -332,17 +491,31 @@ struct DedxPidAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; + double sigmap = 0.0; + double sigman = 0.0; + + if (V0SelectionMode == 1) { + sigmap = ptrack.tpcNSigmaPr(); + sigman = ntrack.tpcNSigmaPi(); + } else if (V0SelectionMode == 2) { + sigmap = ptrack.tofNSigmaPr(); + sigman = ntrack.tofNSigmaPi(); + } else if (V0SelectionMode == 3) { + sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPr(), 2) + std::pow(ptrack.tofNSigmaPr(), 2)); + sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); + } + if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(ptrack.tofNSigmaPr()) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaTOFmax) return false; } if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaTOFmax) return false; } @@ -364,18 +537,30 @@ struct DedxPidAnalysis { return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; - + double sigmap = 0.0; + double sigman = 0.0; + + if (V0SelectionMode == 1) { + sigmap = ptrack.tpcNSigmaPi(); + sigman = ntrack.tpcNSigmaPr(); + } else if (V0SelectionMode == 2) { + sigmap = ptrack.tofNSigmaPi(); + sigman = ntrack.tofNSigmaPr(); + } else if (V0SelectionMode == 3) { + sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); + sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPr(), 2) + std::pow(ntrack.tofNSigmaPr(), 2)); + } if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaTOFmax) return false; } if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(ntrack.tofNSigmaPr()) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaTOFmax) return false; } @@ -397,17 +582,31 @@ struct DedxPidAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; + double sigmap = 0.0; + double sigman = 0.0; + + if (V0SelectionMode == 1) { + sigmap = ptrack.tpcNSigmaEl(); + sigman = ntrack.tpcNSigmaEl(); + } else if (V0SelectionMode == 2) { + sigmap = ptrack.tofNSigmaEl(); + sigman = ntrack.tofNSigmaEl(); + } else if (V0SelectionMode == 3) { + sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaEl(), 2) + std::pow(ptrack.tofNSigmaEl(), 2)); + sigman = std::sqrt(std::pow(ntrack.tpcNSigmaEl(), 2) + std::pow(ntrack.tofNSigmaEl(), 2)); + } + if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; - if (std::abs(ptrack.tofNSigmaEl()) > nsigmaTOFmax) + if (std::abs(sigmap) > nsigmaTOFmax) return false; } if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; - if (std::abs(ntrack.tofNSigmaEl()) > nsigmaTOFmax) + if (std::abs(sigman) > nsigmaTOFmax) return false; } @@ -417,17 +616,30 @@ struct DedxPidAnalysis { return true; } - + // Magnetic field + int getMagneticField(uint64_t timestamp) + { + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } // Phi cut template - bool passedPhiCut(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + bool passedPhiCutPri(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) { + float p = trk.pt(); float pt = trk.pt(); float phi = trk.phi(); int charge = trk.sign(); float eta = trk.eta(); - auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); - float sigP = trk.sign() * trk.tpcInnerParam(); + auto nTPCCl = trk.tpcNClsFound(); if (pt < pTcut) return true; @@ -441,115 +653,243 @@ struct DedxPidAnalysis { phi += o2::constants::math::PI / 18.0f; phi = std::fmod(phi, o2::constants::math::PI / 9.0f); - registryDeDx.fill(HIST("hpt_vs_phi_Ncl_Before"), pt, phi, nTPCCl); + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_TPC_Before"), pt, phi, nTPCCl); + registryDeDx.fill(HIST("hp_vs_phi_Ncl_TPC_Before"), p, phi, nTPCCl); + registryDeDx.fill(HIST("heta_vs_Ncl_TPC_Before"), eta, nTPCCl); // cut phi if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) return false; // reject track + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_TPC_After"), pt, phi, nTPCCl); + registryDeDx.fill(HIST("hp_vs_phi_Ncl_TPC_After"), p, phi, nTPCCl); + registryDeDx.fill(HIST("heta_vs_Ncl_TPC_After"), eta, nTPCCl); + + return true; + } + + // NclCutTPC + template + bool passedNTPCClCutPri(const T& trk) + { + float eta = trk.eta(); + float sigP = trk.sign() * trk.tpcInnerParam(); + auto nTPCCl = trk.tpcNClsFound(); + if (eta > EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); } } - // cut Ncl - if (nTPCCl < nclCut) + if (nTPCCl < minTPCnClsFound) return false; - registryDeDx.fill(HIST("hpt_vs_phi_Ncl_After"), pt, phi, nTPCCl); + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + } + } + + return true; + } + + // NclCutITS + template + bool passedNITSClCutPri(const T& trk) + { + float eta = trk.eta(); + float sigP = trk.sign() * trk.tpcInnerParam(); + auto nITSCl = trk.itsNCls(); if (eta > EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[0]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[0]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[1]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[1]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[2]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[2]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[3]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[3]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[4]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[4]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[5]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[5]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[6]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[6]), nITSCl, trk.tpcSignal(), sigP); } } else if (eta > EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[7]), nITSCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[7]), nITSCl, trk.tpcSignal(), sigP); + } + } + + if (nITSCl < minITSnCls) + return false; + + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[0]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[0]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[1]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[1]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[2]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[2]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[3]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[3]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[4]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[4]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[5]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[5]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[6]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[6]), nITSCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[7]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[7]), nITSCl, trk.tpcSignal(), sigP); } } @@ -563,7 +903,6 @@ struct DedxPidAnalysis { float pt = trk.pt(); float phi = trk.phi(); int charge = trk.sign(); - auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); if (pt < pTcut) return true; @@ -581,42 +920,94 @@ struct DedxPidAnalysis { if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) return false; // reject track - // cut Ncl - if (nTPCCl < nclCut) + return true; + } + + // NclCutTPC + template + bool passedNTPCClCutSecondaries(const T& trk) + { + auto nTPCCl = trk.tpcNClsFound(); + + if (nTPCCl < minTPCnClsFound) + return false; + + return true; + } + + // NclCutITS primary + template + bool passedNITSClCutSecondaries(const T& trk) + { + auto nITSCl = trk.itsNCls(); + + if (nITSCl < minITSnCls) return false; return true; } // Process Data - void process(SelectedCollisions::iterator const& collision, + void process(SelectedCollisions::iterator const& collision, BCsRun3 const& /**/, aod::V0Datas const& fullV0s, PIDTracks const& tracks) { + registryDeDx.fill(HIST("evsel"), EvCutLabel::AllEv); // Event Selection if (!collision.sel8()) return; + registryDeDx.fill(HIST("evsel"), EvCutLabel::SelEigth); + if (std::abs(collision.posZ()) > maxZDistanceToIP) return; + registryDeDx.fill(HIST("evsel"), EvCutLabel::ZVtxCut); + + if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + + registryDeDx.fill(HIST("evsel"), EvCutLabel::NoSameBunchPileup); + + if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + + registryDeDx.fill(HIST("evsel"), EvCutLabel::GoodZvtxFT0vsPV); + // Event Counter registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); - // Kaons - for (const auto& trk : tracks) { + // For magnetic field + const auto& foundBC = collision.foundBC_as(); + const uint64_t timeStamp{foundBC.timestamp()}; + const int magField{getMagneticField(timeStamp)}; + for (const auto& trk : tracks) { + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::AllPri); // track Selection - if (!passedSingleTrackSelection(trk, collision)) - continue; - if (!mySelectionPrim.IsSelected(trk)) continue; + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); + // phi and Ncl cut - if (additionalCuts) { - if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + if (phiVarCut) { + if (!passedPhiCutPri(trk, magField, *fphiCutLow, *fphiCutHigh)) continue; } + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::PhiVarCutPri); + // NCl cut ITS + if (nTPCClCut) { + if (!passedNTPCClCutPri(trk)) + continue; + } + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NTPCClCutPri); + + // NCl cut ITS + if (nITSClCut) { + if (!passedNITSClCutPri(trk)) + continue; + } + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NITSClCutPri); float signedP = trk.sign() * trk.tpcInnerParam(); @@ -710,14 +1101,11 @@ struct DedxPidAnalysis { for (const auto& v0 : fullV0s) { // Standard V0 Selections + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllSec); if (!passedV0Selection(v0, collision)) { continue; } - if (v0.dcaV0daughters() > dcaV0DaughtersMax) { - continue; - } - // Positive and Negative Tracks const auto& posTrack = v0.posTrack_as(); const auto& negTrack = v0.negTrack_as(); @@ -726,14 +1114,37 @@ struct DedxPidAnalysis { continue; if (!negTrack.passedTPCRefit()) continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::TPCRefit); // phi and Ncl cut - if (additionalCuts) { + if (phiVarCut) { if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) continue; if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) continue; } + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::PhiVarCutSec); + + if (nTPCClCut) { + if (!passedNTPCClCutSecondaries(posTrack)) + continue; + + if (!passedNTPCClCutSecondaries(negTrack)) + continue; + } + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NTPCClCutSec); + + if (nITSClCut) { + if (!passedNITSClCutSecondaries(posTrack)) + continue; + + if (!passedNITSClCutSecondaries(negTrack)) + continue; + } + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NITSClCutSec); float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); @@ -750,6 +1161,19 @@ struct DedxPidAnalysis { // K0s Selection if (passedK0Selection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllK0s); + + if (std::abs(v0.rapidity(MassK0Short)) > v0rapidityCut) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityK0s); + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassK0Short; + + if (properLifetime > v0ProperLifetimeCutK0s) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeK0s); + float ePosPi = posTrack.energy(MassPionCharged); float eNegPi = negTrack.energy(MassPionCharged); @@ -771,6 +1195,18 @@ struct DedxPidAnalysis { // Lambda Selection if (passedLambdaSelection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllLambda); + + if (std::abs(v0.rapidity(MassLambda)) > v0rapidityCut) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityLambda); + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; + + if (properLifetime > v0ProperLifetimeCutLambda) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeLambda); float ePosPr = posTrack.energy(MassProton); float eNegPi = negTrack.energy(MassPionCharged); @@ -793,6 +1229,18 @@ struct DedxPidAnalysis { // AntiLambda Selection if (passedAntiLambdaSelection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllAntiLambda); + + if (std::abs(v0.rapidity(MassLambda)) > v0rapidityCut) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityAntiLambda); + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; + + if (properLifetime > v0ProperLifetimeCutLambda) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeAntiLambda); float ePosPi = posTrack.energy(MassPionCharged); float eNegPr = negTrack.energy(MassProton); @@ -815,6 +1263,7 @@ struct DedxPidAnalysis { // Gamma Selection if (passedGammaSelection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllGamma); float ePosEl = posTrack.energy(MassElectron); float eNegEl = negTrack.energy(MassElectron); From 1e194135d7f208df876efbf3c0f2876c914a77a6 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Thu, 11 Sep 2025 16:04:30 -0600 Subject: [PATCH 07/24] New histograms, event and track seleccions were implemented --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 35 ++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 851d1634b68..97b518ce194 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -69,6 +69,9 @@ struct DedxPidAnalysis { float invMassCut = 0.01; float invMassCutGamma = 0.0015; float pTcut = 2.0; + int v0TPC = 1; + int v0TOF = 2; + int v0TPCTOF = 3; // Event cut labels enum EvCutLabel { @@ -153,7 +156,7 @@ struct DedxPidAnalysis { Configurable phiVarCut{"phiVarCut", true, "phi var cut"}; Configurable nTPCClCut{"nTPCClCut", true, "number of clusters in TPC cut"}; Configurable nITSClCut{"nITSClCut", true, "number of clusters in ITS cut"}; - Configurable V0SelectionMode{"V0SelectionMode", 1, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; + Configurable v0SelectionMode{"v0SelectionMode", 1, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; // Histograms names static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; @@ -200,11 +203,11 @@ struct DedxPidAnalysis { void init(InitContext const&) { - if (V0SelectionMode == 1) { + if (V0SelectionMode == v0TPC) { LOGF(info, "V0 seleccion using TPC only"); - } else if (V0SelectionMode == 2) { + } else if (V0SelectionMode == v0TOF) { LOGF(info, "V0 seleccion using TOF only"); - } else if (V0SelectionMode == 3) { + } else if (V0SelectionMode == v0TPCTOF) { LOGF(info, "V0 seleccion using TOF + TPC"); } @@ -448,13 +451,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (V0SelectionMode == 1) { + if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPi(); - } else if (V0SelectionMode == 2) { + } else if (V0SelectionMode == v0TOF) { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPi(); - } else if (V0SelectionMode == 3) { + } else if (V0SelectionMode == v0TPCTOF) { sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); } @@ -494,13 +497,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (V0SelectionMode == 1) { + if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPr(); sigman = ntrack.tpcNSigmaPi(); - } else if (V0SelectionMode == 2) { + } else if (V0SelectionMode == v0TOF) { sigmap = ptrack.tofNSigmaPr(); sigman = ntrack.tofNSigmaPi(); - } else if (V0SelectionMode == 3) { + } else if (V0SelectionMode == v0TPCTOF) { sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPr(), 2) + std::pow(ptrack.tofNSigmaPr(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); } @@ -540,13 +543,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (V0SelectionMode == 1) { + if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPr(); - } else if (V0SelectionMode == 2) { + } else if (V0SelectionMode == v0TOF) { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPr(); - } else if (V0SelectionMode == 3) { + } else if (V0SelectionMode == v0TPCTOF) { sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPr(), 2) + std::pow(ntrack.tofNSigmaPr(), 2)); } @@ -585,13 +588,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (V0SelectionMode == 1) { + if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaEl(); sigman = ntrack.tpcNSigmaEl(); - } else if (V0SelectionMode == 2) { + } else if (V0SelectionMode == v0TOF) { sigmap = ptrack.tofNSigmaEl(); sigman = ntrack.tofNSigmaEl(); - } else if (V0SelectionMode == 3) { + } else if (V0SelectionMode == v0TPCTOF) { sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaEl(), 2) + std::pow(ptrack.tofNSigmaEl(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaEl(), 2) + std::pow(ntrack.tofNSigmaEl(), 2)); } From bff87406637b9f5edbc0324d1561ce66a1180c6e Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Sun, 14 Sep 2025 13:55:11 -0600 Subject: [PATCH 08/24] The issue with the macOS-arm checks has been resolved --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 48 ++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 97b518ce194..1a0e918c32b 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -203,11 +203,19 @@ struct DedxPidAnalysis { void init(InitContext const&) { +<<<<<<< HEAD if (V0SelectionMode == v0TPC) { LOGF(info, "V0 seleccion using TPC only"); } else if (V0SelectionMode == v0TOF) { LOGF(info, "V0 seleccion using TOF only"); } else if (V0SelectionMode == v0TPCTOF) { +======= + if (v0SelectionMode == v0TPC) { + LOGF(info, "V0 seleccion using TPC only"); + } else if (v0SelectionMode == v0TOF) { + LOGF(info, "V0 seleccion using TOF only"); + } else if (v0SelectionMode == v0TPCTOF) { +>>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) LOGF(info, "V0 seleccion using TOF + TPC"); } @@ -451,6 +459,7 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; +<<<<<<< HEAD if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPi(); @@ -458,6 +467,15 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPi(); } else if (V0SelectionMode == v0TPCTOF) { +======= + if (v0SelectionMode == v0TPC) { + sigmap = ptrack.tpcNSigmaPi(); + sigman = ntrack.tpcNSigmaPi(); + } else if (v0SelectionMode == v0TOF) { + sigmap = ptrack.tofNSigmaPi(); + sigman = ntrack.tofNSigmaPi(); + } else if (v0SelectionMode == v0TPCTOF) { +>>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); } @@ -497,6 +515,7 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; +<<<<<<< HEAD if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPr(); sigman = ntrack.tpcNSigmaPi(); @@ -504,6 +523,15 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPr(); sigman = ntrack.tofNSigmaPi(); } else if (V0SelectionMode == v0TPCTOF) { +======= + if (v0SelectionMode == v0TPC) { + sigmap = ptrack.tpcNSigmaPr(); + sigman = ntrack.tpcNSigmaPi(); + } else if (v0SelectionMode == v0TOF) { + sigmap = ptrack.tofNSigmaPr(); + sigman = ntrack.tofNSigmaPi(); + } else if (v0SelectionMode == v0TPCTOF) { +>>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPr(), 2) + std::pow(ptrack.tofNSigmaPr(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); } @@ -543,6 +571,7 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; +<<<<<<< HEAD if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPr(); @@ -550,6 +579,15 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPr(); } else if (V0SelectionMode == v0TPCTOF) { +======= + if (v0SelectionMode == v0TPC) { + sigmap = ptrack.tpcNSigmaPi(); + sigman = ntrack.tpcNSigmaPr(); + } else if (v0SelectionMode == v0TOF) { + sigmap = ptrack.tofNSigmaPi(); + sigman = ntrack.tofNSigmaPr(); + } else if (v0SelectionMode == v0TPCTOF) { +>>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPr(), 2) + std::pow(ntrack.tofNSigmaPr(), 2)); } @@ -588,6 +626,7 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; +<<<<<<< HEAD if (V0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaEl(); sigman = ntrack.tpcNSigmaEl(); @@ -595,6 +634,15 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaEl(); sigman = ntrack.tofNSigmaEl(); } else if (V0SelectionMode == v0TPCTOF) { +======= + if (v0SelectionMode == v0TPC) { + sigmap = ptrack.tpcNSigmaEl(); + sigman = ntrack.tpcNSigmaEl(); + } else if (v0SelectionMode == v0TOF) { + sigmap = ptrack.tofNSigmaEl(); + sigman = ntrack.tofNSigmaEl(); + } else if (v0SelectionMode == v0TPCTOF) { +>>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaEl(), 2) + std::pow(ptrack.tofNSigmaEl(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaEl(), 2) + std::pow(ntrack.tofNSigmaEl(), 2)); } From 637b03a1a8a61245c448056dcdad4463d393f994 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Sun, 14 Sep 2025 14:00:53 -0600 Subject: [PATCH 09/24] The issue with the macOS-arm checks has been resolved --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 48 -------------------------- 1 file changed, 48 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 1a0e918c32b..ef114095c54 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -203,19 +203,11 @@ struct DedxPidAnalysis { void init(InitContext const&) { -<<<<<<< HEAD - if (V0SelectionMode == v0TPC) { - LOGF(info, "V0 seleccion using TPC only"); - } else if (V0SelectionMode == v0TOF) { - LOGF(info, "V0 seleccion using TOF only"); - } else if (V0SelectionMode == v0TPCTOF) { -======= if (v0SelectionMode == v0TPC) { LOGF(info, "V0 seleccion using TPC only"); } else if (v0SelectionMode == v0TOF) { LOGF(info, "V0 seleccion using TOF only"); } else if (v0SelectionMode == v0TPCTOF) { ->>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) LOGF(info, "V0 seleccion using TOF + TPC"); } @@ -459,15 +451,6 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; -<<<<<<< HEAD - if (V0SelectionMode == v0TPC) { - sigmap = ptrack.tpcNSigmaPi(); - sigman = ntrack.tpcNSigmaPi(); - } else if (V0SelectionMode == v0TOF) { - sigmap = ptrack.tofNSigmaPi(); - sigman = ntrack.tofNSigmaPi(); - } else if (V0SelectionMode == v0TPCTOF) { -======= if (v0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPi(); @@ -475,7 +458,6 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPi(); } else if (v0SelectionMode == v0TPCTOF) { ->>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); } @@ -515,15 +497,6 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; -<<<<<<< HEAD - if (V0SelectionMode == v0TPC) { - sigmap = ptrack.tpcNSigmaPr(); - sigman = ntrack.tpcNSigmaPi(); - } else if (V0SelectionMode == v0TOF) { - sigmap = ptrack.tofNSigmaPr(); - sigman = ntrack.tofNSigmaPi(); - } else if (V0SelectionMode == v0TPCTOF) { -======= if (v0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPr(); sigman = ntrack.tpcNSigmaPi(); @@ -531,7 +504,6 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPr(); sigman = ntrack.tofNSigmaPi(); } else if (v0SelectionMode == v0TPCTOF) { ->>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPr(), 2) + std::pow(ptrack.tofNSigmaPr(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); } @@ -571,15 +543,6 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; -<<<<<<< HEAD - if (V0SelectionMode == v0TPC) { - sigmap = ptrack.tpcNSigmaPi(); - sigman = ntrack.tpcNSigmaPr(); - } else if (V0SelectionMode == v0TOF) { - sigmap = ptrack.tofNSigmaPi(); - sigman = ntrack.tofNSigmaPr(); - } else if (V0SelectionMode == v0TPCTOF) { -======= if (v0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPr(); @@ -587,7 +550,6 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPr(); } else if (v0SelectionMode == v0TPCTOF) { ->>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPr(), 2) + std::pow(ntrack.tofNSigmaPr(), 2)); } @@ -626,15 +588,6 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; -<<<<<<< HEAD - if (V0SelectionMode == v0TPC) { - sigmap = ptrack.tpcNSigmaEl(); - sigman = ntrack.tpcNSigmaEl(); - } else if (V0SelectionMode == v0TOF) { - sigmap = ptrack.tofNSigmaEl(); - sigman = ntrack.tofNSigmaEl(); - } else if (V0SelectionMode == v0TPCTOF) { -======= if (v0SelectionMode == v0TPC) { sigmap = ptrack.tpcNSigmaEl(); sigman = ntrack.tpcNSigmaEl(); @@ -642,7 +595,6 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaEl(); sigman = ntrack.tofNSigmaEl(); } else if (v0SelectionMode == v0TPCTOF) { ->>>>>>> 0a9044196 (The issue with the macOS-arm checks has been resolved) sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaEl(), 2) + std::pow(ptrack.tofNSigmaEl(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaEl(), 2) + std::pow(ntrack.tofNSigmaEl(), 2)); } From b6ee179028558ebd4e6101ad99094aef844561ee Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Mon, 15 Sep 2025 13:19:06 -0600 Subject: [PATCH 10/24] Update code following review feedback --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index ef114095c54..cbe128996b2 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -361,25 +361,43 @@ struct DedxPidAnalysis { registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); auto hstat = registryDeDx.get(HIST("evsel")); auto* x = hstat->GetXaxis(); +<<<<<<< HEAD x->SetBinLabel(1, "AllEv"); x->SetBinLabel(2, "SelEigth"); x->SetBinLabel(3, "ZVtxCut"); x->SetBinLabel(4, "NoSameBunchPileup"); x->SetBinLabel(5, "GoodZvtxFT0vsPV"); +======= + x->SetBinLabel(AllEv, "AllEv"); + x->SetBinLabel(SelEigth, "SelEigth"); + x->SetBinLabel(ZVtxCut, "ZVtxCut"); + x->SetBinLabel(NoSameBunchPileup, "NoSameBunchPileup"); + x->SetBinLabel(GoodZvtxFT0vsPV, "GoodZvtxFT0vsPV"); + +>>>>>>> 2395f3f2a (Update code following review feedback) // Track Counter registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); auto htrackAll = registryDeDx.get(HIST("trackselAll")); auto* xAll = htrackAll->GetXaxis(); +<<<<<<< HEAD xAll->SetBinLabel(1, "AllPri"); xAll->SetBinLabel(2, "SelectionPrim"); xAll->SetBinLabel(3, "PhiVarCutPri"); xAll->SetBinLabel(4, "NTPCClCutPri"); xAll->SetBinLabel(5, "NITSClCutPri"); +======= + xAll->SetBinLabel(AllPri, "AllPri"); + xAll->SetBinLabel(SelectionPrim, "SelectionPrim"); + xAll->SetBinLabel(PhiVarCutPri, "PhiVarCutPri"); + xAll->SetBinLabel(NTPCClCutPri, "NTPCClCutPri"); + xAll->SetBinLabel(NITSClCutPri, "NITSClCutPri"); +>>>>>>> 2395f3f2a (Update code following review feedback) registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{18, 0.5, 18.5, ""}}); auto htrackSec = registryDeDx.get(HIST("trackselSec")); auto* xSec = htrackSec->GetXaxis(); +<<<<<<< HEAD xSec->SetBinLabel(1, "AllSec"); xSec->SetBinLabel(2, "V0CosPA"); xSec->SetBinLabel(3, "V0DecayRadius"); @@ -398,6 +416,26 @@ struct DedxPidAnalysis { xSec->SetBinLabel(16, "V0RapidityAntiLambda"); xSec->SetBinLabel(17, "V0ProperLifetimeAntiLambda"); xSec->SetBinLabel(18, "AllGamma"); +======= + xSec->SetBinLabel(AllSec, "AllSec"); + xSec->SetBinLabel(V0CosPA, "V0CosPA"); + xSec->SetBinLabel(V0DecayRadius, "V0DecayRadius"); + xSec->SetBinLabel(V0Daughters, "V0Daughters"); + xSec->SetBinLabel(TPCRefit, "TPCRefit"); + xSec->SetBinLabel(PhiVarCutSec, "PhiVarCutSec"); + xSec->SetBinLabel(NTPCClCutSec, "NTPCClCutSec"); + xSec->SetBinLabel(NITSClCutSec, "NITSClCutSec"); + xSec->SetBinLabel(AllK0s, "AllK0s"); + xSec->SetBinLabel(V0RapidityK0s, "V0RapidityK0s"); + xSec->SetBinLabel(V0ProperLifetimeK0s, "V0ProperLifetimeK0s"); + xSec->SetBinLabel(AllLambda, "AllLambda"); + xSec->SetBinLabel(V0RapidityLambda, "V0RapidityLambda"); + xSec->SetBinLabel(V0ProperLifetimeLambda, "V0ProperLifetimeLambda"); + xSec->SetBinLabel(AllAntiLambda, "AllAntiLambda"); + xSec->SetBinLabel(V0RapidityAntiLambda, "V0RapidityAntiLambda"); + xSec->SetBinLabel(V0ProperLifetimeAntiLambda, "V0ProperLifetimeAntiLambda"); + xSec->SetBinLabel(AllGamma, "AllGamma"); +>>>>>>> 2395f3f2a (Update code following review feedback) mySelectionPrim = myTrackSelection(); } @@ -458,8 +496,13 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPi(); } else if (v0SelectionMode == v0TPCTOF) { +<<<<<<< HEAD sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); +======= + sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); + sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); +>>>>>>> 2395f3f2a (Update code following review feedback) } if (ptrack.tpcInnerParam() > tpcCut) { @@ -504,8 +547,13 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPr(); sigman = ntrack.tofNSigmaPi(); } else if (v0SelectionMode == v0TPCTOF) { +<<<<<<< HEAD sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPr(), 2) + std::pow(ptrack.tofNSigmaPr(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); +======= + sigmap = std::hypot(ptrack.tpcNSigmaPr(), ptrack.tofNSigmaPr()); + sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); +>>>>>>> 2395f3f2a (Update code following review feedback) } if (ptrack.tpcInnerParam() > tpcCut) { @@ -550,8 +598,13 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPr(); } else if (v0SelectionMode == v0TPCTOF) { +<<<<<<< HEAD sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPr(), 2) + std::pow(ntrack.tofNSigmaPr(), 2)); +======= + sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); + sigman = std::hypot(ntrack.tpcNSigmaPr(), ntrack.tofNSigmaPr()); +>>>>>>> 2395f3f2a (Update code following review feedback) } if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) @@ -595,8 +648,13 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaEl(); sigman = ntrack.tofNSigmaEl(); } else if (v0SelectionMode == v0TPCTOF) { +<<<<<<< HEAD sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaEl(), 2) + std::pow(ptrack.tofNSigmaEl(), 2)); sigman = std::sqrt(std::pow(ntrack.tpcNSigmaEl(), 2) + std::pow(ntrack.tofNSigmaEl(), 2)); +======= + sigmap = std::hypot(ptrack.tpcNSigmaEl(), ptrack.tofNSigmaEl()); + sigman = std::hypot(ntrack.tpcNSigmaEl(), ntrack.tofNSigmaEl()); +>>>>>>> 2395f3f2a (Update code following review feedback) } if (ptrack.tpcInnerParam() > tpcCut) { From 406d558bd174793da6b4497910092d7007e3b6e6 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Mon, 15 Sep 2025 13:24:08 -0600 Subject: [PATCH 11/24] Update code following review feedback --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 72 +++----------------------- 1 file changed, 7 insertions(+), 65 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index cbe128996b2..86d9030e6ff 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -361,62 +361,25 @@ struct DedxPidAnalysis { registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); auto hstat = registryDeDx.get(HIST("evsel")); auto* x = hstat->GetXaxis(); -<<<<<<< HEAD - x->SetBinLabel(1, "AllEv"); - x->SetBinLabel(2, "SelEigth"); - x->SetBinLabel(3, "ZVtxCut"); - x->SetBinLabel(4, "NoSameBunchPileup"); - x->SetBinLabel(5, "GoodZvtxFT0vsPV"); - -======= x->SetBinLabel(AllEv, "AllEv"); x->SetBinLabel(SelEigth, "SelEigth"); x->SetBinLabel(ZVtxCut, "ZVtxCut"); x->SetBinLabel(NoSameBunchPileup, "NoSameBunchPileup"); x->SetBinLabel(GoodZvtxFT0vsPV, "GoodZvtxFT0vsPV"); - ->>>>>>> 2395f3f2a (Update code following review feedback) + // Track Counter registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); auto htrackAll = registryDeDx.get(HIST("trackselAll")); auto* xAll = htrackAll->GetXaxis(); -<<<<<<< HEAD - xAll->SetBinLabel(1, "AllPri"); - xAll->SetBinLabel(2, "SelectionPrim"); - xAll->SetBinLabel(3, "PhiVarCutPri"); - xAll->SetBinLabel(4, "NTPCClCutPri"); - xAll->SetBinLabel(5, "NITSClCutPri"); -======= xAll->SetBinLabel(AllPri, "AllPri"); xAll->SetBinLabel(SelectionPrim, "SelectionPrim"); xAll->SetBinLabel(PhiVarCutPri, "PhiVarCutPri"); xAll->SetBinLabel(NTPCClCutPri, "NTPCClCutPri"); xAll->SetBinLabel(NITSClCutPri, "NITSClCutPri"); ->>>>>>> 2395f3f2a (Update code following review feedback) registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{18, 0.5, 18.5, ""}}); auto htrackSec = registryDeDx.get(HIST("trackselSec")); auto* xSec = htrackSec->GetXaxis(); -<<<<<<< HEAD - xSec->SetBinLabel(1, "AllSec"); - xSec->SetBinLabel(2, "V0CosPA"); - xSec->SetBinLabel(3, "V0DecayRadius"); - xSec->SetBinLabel(4, "V0Daughters"); - xSec->SetBinLabel(5, "TPCRefit"); - xSec->SetBinLabel(6, "PhiVarCutSec"); - xSec->SetBinLabel(7, "NTPCClCutSec"); - xSec->SetBinLabel(8, "NITSClCutSec"); - xSec->SetBinLabel(9, "AllK0s"); - xSec->SetBinLabel(10, "V0RapidityK0s"); - xSec->SetBinLabel(11, "V0ProperLifetimeK0s"); - xSec->SetBinLabel(12, "AllLambda"); - xSec->SetBinLabel(13, "V0RapidityLambda"); - xSec->SetBinLabel(14, "V0ProperLifetimeLambda"); - xSec->SetBinLabel(15, "AllAntiLambda"); - xSec->SetBinLabel(16, "V0RapidityAntiLambda"); - xSec->SetBinLabel(17, "V0ProperLifetimeAntiLambda"); - xSec->SetBinLabel(18, "AllGamma"); -======= xSec->SetBinLabel(AllSec, "AllSec"); xSec->SetBinLabel(V0CosPA, "V0CosPA"); xSec->SetBinLabel(V0DecayRadius, "V0DecayRadius"); @@ -435,7 +398,6 @@ struct DedxPidAnalysis { xSec->SetBinLabel(V0RapidityAntiLambda, "V0RapidityAntiLambda"); xSec->SetBinLabel(V0ProperLifetimeAntiLambda, "V0ProperLifetimeAntiLambda"); xSec->SetBinLabel(AllGamma, "AllGamma"); ->>>>>>> 2395f3f2a (Update code following review feedback) mySelectionPrim = myTrackSelection(); } @@ -496,13 +458,8 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPi(); } else if (v0SelectionMode == v0TPCTOF) { -<<<<<<< HEAD - sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); - sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); -======= - sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); - sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); ->>>>>>> 2395f3f2a (Update code following review feedback) + sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); + sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } if (ptrack.tpcInnerParam() > tpcCut) { @@ -547,13 +504,8 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPr(); sigman = ntrack.tofNSigmaPi(); } else if (v0SelectionMode == v0TPCTOF) { -<<<<<<< HEAD - sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPr(), 2) + std::pow(ptrack.tofNSigmaPr(), 2)); - sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPi(), 2) + std::pow(ntrack.tofNSigmaPi(), 2)); -======= - sigmap = std::hypot(ptrack.tpcNSigmaPr(), ptrack.tofNSigmaPr()); - sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); ->>>>>>> 2395f3f2a (Update code following review feedback) + sigmap = std::hypot(ptrack.tpcNSigmaPr(), ptrack.tofNSigmaPr()); + sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } if (ptrack.tpcInnerParam() > tpcCut) { @@ -598,13 +550,8 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPr(); } else if (v0SelectionMode == v0TPCTOF) { -<<<<<<< HEAD - sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaPi(), 2) + std::pow(ptrack.tofNSigmaPi(), 2)); - sigman = std::sqrt(std::pow(ntrack.tpcNSigmaPr(), 2) + std::pow(ntrack.tofNSigmaPr(), 2)); -======= sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); sigman = std::hypot(ntrack.tpcNSigmaPr(), ntrack.tofNSigmaPr()); ->>>>>>> 2395f3f2a (Update code following review feedback) } if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) @@ -648,13 +595,8 @@ struct DedxPidAnalysis { sigmap = ptrack.tofNSigmaEl(); sigman = ntrack.tofNSigmaEl(); } else if (v0SelectionMode == v0TPCTOF) { -<<<<<<< HEAD - sigmap = std::sqrt(std::pow(ptrack.tpcNSigmaEl(), 2) + std::pow(ptrack.tofNSigmaEl(), 2)); - sigman = std::sqrt(std::pow(ntrack.tpcNSigmaEl(), 2) + std::pow(ntrack.tofNSigmaEl(), 2)); -======= - sigmap = std::hypot(ptrack.tpcNSigmaEl(), ptrack.tofNSigmaEl()); - sigman = std::hypot(ntrack.tpcNSigmaEl(), ntrack.tofNSigmaEl()); ->>>>>>> 2395f3f2a (Update code following review feedback) + sigmap = std::hypot(ptrack.tpcNSigmaEl(), ptrack.tofNSigmaEl()); + sigman = std::hypot(ntrack.tpcNSigmaEl(), ntrack.tofNSigmaEl()); } if (ptrack.tpcInnerParam() > tpcCut) { From 17cb3977c74ce2a79d6de7590fc3720bec9a271a Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 3 Oct 2025 18:27:28 -0600 Subject: [PATCH 12/24] Add centrality classes and update V0 selection cuts --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 840 ++++++++++++++++--------- 1 file changed, 537 insertions(+), 303 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 86d9030e6ff..de4be8cf34b 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -20,6 +20,7 @@ #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" #include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" @@ -31,6 +32,7 @@ #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" #include "Framework/Logger.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" @@ -46,9 +48,13 @@ using PIDTracks = soa::Join< aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta, aod::pidTPCPi, aod::pidTPCPr, aod::pidTPCEl>; -using SelectedCollisions = soa::Join; +using SelectedCollisions = soa::Join; using BCsRun3 = soa::Join; +static constexpr int kNCentHists{10}; +std::array, kNCentHists> hDedxVsMomentumVsCentPos{}; +std::array, kNCentHists> hDedxVsMomentumVsCentNeg{}; + struct DedxPidAnalysis { // dE/dx for all charged particles @@ -61,17 +67,27 @@ struct DedxPidAnalysis { // Constant values static constexpr int kEtaIntervals = 8; static constexpr int kParticlesType = 4; + static constexpr int kCentralityClasses = 10; float tpcCut = 0.6; float pionMin = 0.35; float pionMax = 0.45; float elTofCut = 0.1; float pionTofCut = 1.0; - float invMassCut = 0.01; - float invMassCutGamma = 0.0015; float pTcut = 2.0; - int v0TPC = 1; - int v0TOF = 2; - int v0TPCTOF = 3; + + bool fillHist = false; + + enum V0SelectionMode { + V0TPC = 1, + V0TOF = 2, + V0TPCTOF = 3 + + }; + + enum MomentumMode { + TpcInnerParam = 1, + TotalMomentum = 2 + }; // Event cut labels enum EvCutLabel { @@ -88,37 +104,43 @@ struct DedxPidAnalysis { AllPri = 1, SelectionPrim, PhiVarCutPri, - NTPCClCutPri, - NITSClCutPri + NClTPCFoundCutPri, + NClTPCPIDCutPri }; // Track secondary lebel enum TrkSecCutLabel { AllSec = 1, + V0Type, V0CosPA, V0DecayRadius, V0Daughters, TPCRefit, PhiVarCutSec, - NTPCClCutSec, - NITSClCutSec, + NClTPCFoundCutSec, + NClTPCPIDCutSec, AllK0s, V0RapidityK0s, V0ProperLifetimeK0s, + MassCutK0s, AllLambda, V0RapidityLambda, V0ProperLifetimeLambda, + MassCutLambda, AllAntiLambda, V0RapidityAntiLambda, V0ProperLifetimeAntiLambda, - AllGamma + MassCutAntiLambda, + AllGamma, + V0RapidityGamma, + MassCutGamma }; // Configurable Parameters // Tracks cuts - Configurable minTPCnClsFound{"minTPCnClsFound", 135.0f, + Configurable minTPCnClsFound{"minTPCnClsFound", 70.0f, "min number of found TPC clusters"}; - Configurable minITSnCls{"minITSnCls", 0.0f, - "min number of ITS clusters"}; + Configurable minTPCnClsPID{"minTPCnClsPID", 70.0f, + "min number of PID TPC clusters"}; Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.0f, "min number of found TPC crossed rows"}; Configurable maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"}; @@ -142,35 +164,37 @@ struct DedxPidAnalysis { Configurable v0ProperLifetimeCutK0s{"v0ProperLifetimeCutK0s", 20.f, "V0 proper lifetime cut for K0s"}; Configurable v0ProperLifetimeCutLambda{"v0ProperLifetimeCutLambda", 30.f, "V0 proper lifetime cut for Lambda"}; Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; - Configurable minMassK0s{"minMassK0s", 0.4f, "Minimum Mass K0s"}; - Configurable maxMassK0s{"maxMassK0s", 0.6f, "Maximum Mass K0s"}; - Configurable minMassLambda{"minMassLambda", 1.1f, - "Minimum Mass Lambda"}; - Configurable maxMassLambda{"maxMassLambda", 1.2f, - "Maximum Mass Lambda"}; - Configurable minMassGamma{"minMassGamma", 0.000922f, - "Minimum Mass Gamma"}; - Configurable maxMassGamma{"maxMassGamma", 0.002022f, - "Maximum Mass Gamma"}; + Configurable invMassCutK0s{"invMassCutK0s", 0.2f, "invariant Mass Cut for K0s"}; + Configurable invMassCutLambda{"invMassCutLambda", 0.1f, "invariant Mass Cut for Lambda"}; + Configurable invMassCutGamma{"invMassCutGamma", 0.1f, "invariant Mass Cut for Gamma"}; Configurable calibrationMode{"calibrationMode", false, "calibration mode"}; Configurable phiVarCut{"phiVarCut", true, "phi var cut"}; - Configurable nTPCClCut{"nTPCClCut", true, "number of clusters in TPC cut"}; - Configurable nITSClCut{"nITSClCut", true, "number of clusters in ITS cut"}; - Configurable v0SelectionMode{"v0SelectionMode", 1, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; + Configurable nClTPCFoundCut{"nClTPCFoundCut", false, "number of found clusters in TPC cut"}; + Configurable nClTPCPIDCut{"nClTPCPIDCut", true, "number of PID clusters in TPC cut"}; + Configurable v0SelectionMode{"v0SelectionMode", 3, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; + Configurable momentumMode{"momentumMode", 1, "1: TPC inner param, 2: Total momentum p"}; + Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable lowParam1{"lowParam1", 0.119297, "First parameter for low phi cut"}; + Configurable lowParam2{"lowParam2", 0.000379693, "Second parameter for low phi cut"}; + Configurable highParam1{"highParam1", 0.16685, "First parameter for high phi cut"}; + Configurable highParam2{"highParam2", 0.00981942, "Second parameter for high phi cut"}; // Histograms names static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + static constexpr std::string_view kDedxvsMomentumvsCentPos[kCentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; + static constexpr std::string_view kDedxvsMomentumvsCentNeg[kCentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; // Ncl TPC - static constexpr std::string_view kNclTPCDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view kNclTPCDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view kNclTPCDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view kNclTPCDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_TPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_TPC_vs_dEdx_vs_Momentum_Pos_8_After"}; - // Ncl TPC - static constexpr std::string_view kNclITSDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view kNclITSDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view kNclITSDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view kNclITSDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_ITS_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_ITS_vs_dEdx_vs_Momentum_Pos_8_After"}; + static constexpr std::string_view kNclTPCDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclTPCDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclTPCDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_TFoundPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclTPCDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; + // Ncl PID TPC + static constexpr std::string_view kNclPIDTPCDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclPIDTPCDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclPIDTPCDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclPIDTPCDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; static constexpr double EtaCut[kEtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + static constexpr double CentClasses[kCentralityClasses + 1] = {0.0, 0.1, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; @@ -203,20 +227,58 @@ struct DedxPidAnalysis { void init(InitContext const&) { - if (v0SelectionMode == v0TPC) { + if (v0SelectionMode == V0TPC) { LOGF(info, "V0 seleccion using TPC only"); - } else if (v0SelectionMode == v0TOF) { + } else if (v0SelectionMode == V0TOF) { LOGF(info, "V0 seleccion using TOF only"); - } else if (v0SelectionMode == v0TPCTOF) { + } else if (v0SelectionMode == V0TPCTOF) { LOGF(info, "V0 seleccion using TOF + TPC"); } + if (calibrationMode) { + LOGF(info, "Calibration mode activated"); + } else { + LOGF(info, "Running data applying calibration values"); + } + + if (phiVarCut) { + LOGF(info, "Applying phi prime cut"); + } else { + LOGF(info, "Phi prime cut disabled"); + } + + if (nClTPCFoundCut) { + LOGF(info, "Applying TPC found clusters cut"); + } else { + LOGF(info, "TPC found clusters cut disabled"); + } + + if (nClTPCPIDCut) { + LOGF(info, "Applying TPC clusters for PID cut"); + } else { + LOGF(info, "TPC clusters for PID cut disabled"); + } + if (momentumMode == TpcInnerParam) { + LOGF(info, "Using TPC inner parameter for momentum calculation"); + } else { + LOGF(info, "Using total momentum (p) for calculation"); + } + LOGF(info, "Centrality clases between %.1f - %.1f", CentClasses[0], CentClasses[10]); AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; AxisSpec ptAxis = {binP, "pT (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; - fphiCutLow = new TF1("StandardPhiCutLow", "0.119297/x/x+pi/18.0-0.000379693", 0, 50); - fphiCutHigh = new TF1("StandardPhiCutHigh", "0.16685/x+pi/18.0+0.00981942", 0, 50); + AxisSpec pAxisTrack = {binP, "#it{p} (GeV/c)"}; + fphiCutLow = new TF1("StandardPhiCutLow", + Form("%f/x/x+pi/18.0-%f", lowParam1.value, lowParam2.value), + 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", + Form("%f/x+pi/18.0+%f", highParam1.value, highParam2.value), + 0, 50); + LOGF(info, "=== Phi Cut Parameters ==="); + LOGF(info, "Low cut: %.6f/x² + pi/18 - %.6f", lowParam1.value, lowParam2.value); + LOGF(info, "High cut: %.6f/x + pi/18 + %.6f", highParam1.value, highParam2.value); + if (calibrationMode) { // MIP for pions registryDeDx.add( @@ -270,18 +332,23 @@ struct DedxPidAnalysis { // pt vs p registryDeDx.add( - "heta_vs_p_vs_pt_all_Neg", "eta_vs_p_vs_pT", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); + "heta_vs_pt_vs_p_all_Neg", "eta_vs_pT_vs_p", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxisTrack}}); registryDeDx.add( - "heta_vs_p_vs_pt_all_Pos", "eta_vs_p_vs_pT", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); + "heta_vs_pt_vs_p_all_Pos", "eta_vs_pT_vs_p", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxisTrack}}); // De/Dx for ch and v0 particles for (int i = 0; i < kParticlesType; ++i) { registryDeDx.add(kDedxvsMomentumPos[i].data(), "dE/dx", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); + {{pAxisTrack}, {dedxAxis}, {etaAxis}}); registryDeDx.add(kDedxvsMomentumNeg[i].data(), "dE/dx", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); + {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + } + + for (int i = 0; i < kCentralityClasses; ++i) { + hDedxVsMomentumVsCentPos[i] = registryDeDx.add(kDedxvsMomentumvsCentPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(kDedxvsMomentumvsCentNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } } @@ -290,60 +357,159 @@ struct DedxPidAnalysis { {{100, 0.0, 6.4, "#phi"}, {dedxAxis}}); // phi cut if (phiVarCut) { - // pt + // pt for found registryDeDx.add( - "hpt_vs_phi_Ncl_TPC_After", "phi cut vs pt", HistType::kTH3F, - {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + "hpt_vs_phi_NclFound_TPC_After", "phi cut vs pt", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, found}"}}); registryDeDx.add( - "hpt_vs_phi_Ncl_TPC_Before", "phi cut vs pt", HistType::kTH3F, - {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + "hpt_vs_phi_NclFound_TPC_Before", "phi cut vs pt", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, found}"}}); // p registryDeDx.add( - "hp_vs_phi_Ncl_TPC_After", "phi cut vs p", HistType::kTH3F, - {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + "hp_vs_phi_NclFound_TPC_After", "phi cut vs p", HistType::kTH3F, + {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, found}"}}); registryDeDx.add( - "hp_vs_phi_Ncl_TPC_Before", "phi cut vs p", HistType::kTH3F, - {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); - // eta + "hp_vs_phi_NclFound_TPC_Before", "phi cut vs p", HistType::kTH3F, + {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, found}"}}); + + // pt for PID registryDeDx.add( - "heta_vs_Ncl_TPC_Before", "eta and N_{cl}", HistType::kTH2F, - {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl}"}}); + "hpt_vs_phi_NclPID_TPC_After", "phi cut vs pt", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, PID}"}}); registryDeDx.add( - "heta_vs_Ncl_TPC_After", "eta and N_{cl} ", HistType::kTH2F, - {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl}"}}); + "hpt_vs_phi_NclPID_TPC_Before", "phi cut vs pt", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, PID}"}}); + // p + registryDeDx.add( + "hp_vs_phi_NclPID_TPC_After", "phi cut vs p", HistType::kTH3F, + {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_phi_NclPID_TPC_Before", "phi cut vs p", HistType::kTH3F, + {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, PID}"}}); } // Ncl vs de/dx TPC - if (nTPCClCut) { + if (nClTPCFoundCut) { for (int i = 0; i < kEtaIntervals; ++i) { - registryDeDx.add(kNclTPCDedxMomentumPosBefore[i].data(), "Ncl TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclTPCDedxMomentumNegBefore[i].data(), "Ncl TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); - - registryDeDx.add(kNclTPCDedxMomentumPosAfter[i].data(), "Ncl TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclTPCDedxMomentumNegAfter[i].data(), "Ncl TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclTPCDedxMomentumPosBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclTPCDedxMomentumNegBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); + + registryDeDx.add(kNclTPCDedxMomentumPosAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclTPCDedxMomentumNegAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); } } // Ncl vs de/dx ITS - if (nITSClCut) { + if (nClTPCPIDCut) { for (int i = 0; i < kEtaIntervals; ++i) { - registryDeDx.add(kNclITSDedxMomentumPosBefore[i].data(), "Ncl ITS vs dE/dx vs Momentum Positive before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclITSDedxMomentumNegBefore[i].data(), "Ncl ITS vs dE/dx vs Momentum Negative before", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); - - registryDeDx.add(kNclITSDedxMomentumPosAfter[i].data(), "Ncl ITS vs dE/dx vs Momentum Positive after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclITSDedxMomentumNegAfter[i].data(), "Ncl ITS vs dE/dx vs Momentum Negative after", HistType::kTH3F, - {{100, 0, 160, "N_{cl}^{ITS}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclPIDTPCDedxMomentumPosBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclPIDTPCDedxMomentumNegBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); + + registryDeDx.add(kNclPIDTPCDedxMomentumPosAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclPIDTPCDedxMomentumNegAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); } } + // eta + registryDeDx.add( + "heta_vs_NclFound_TPC_Before_Primary", "eta and N_{cl}", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, found}"}}); + + registryDeDx.add( + "heta_vs_NclFound_TPC_After_Primary", "eta and N_{cl} ", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, found}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_Before_Primary", "eta and N_{cl, PID}", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_After_Primary", "eta and N_{cl, PID} ", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + // momentum for primaries + registryDeDx.add( + "hp_vs_NclPID_TPC_Before_Primary", "p and N_{cl, PID}", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_After_Primary", "p and N_{cl, PID} ", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + // eta for secondaries + registryDeDx.add( + "heta_vs_NclPID_TPC_Before_PionsK0s", "eta and N_{cl, PID}", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_After_PionsK0s", "eta and N_{cl, PID} ", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_Before_PionsLambda", "eta and N_{cl, PID}", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_After_PionsLambda", "eta and N_{cl, PID} ", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_Before_ProtonsLambda", "eta and N_{cl, PID}", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_After_ProtonsLambda", "eta and N_{cl, PID} ", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_Before_ElectronsGamma", "eta and N_{cl, PID}", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "heta_vs_NclPID_TPC_After_ElectronsGamma", "eta and N_{cl, PID} ", HistType::kTH2F, + {{100, -0.8, 0.8, "#eta"}, {100, 0, 160, "N_{cl, PID}"}}); + + // momentum for secondaries + registryDeDx.add( + "hp_vs_NclPID_TPC_Before_PionsK0s", "p and N_{cl, PID}", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_After_PionsK0s", "p and N_{cl, PID} ", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_Before_PionsLambda", "p and N_{cl, PID}", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_After_PionsLambda", "p and N_{cl, PID} ", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_Before_ProtonsLambda", "p and N_{cl, PID}", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_After_ProtonsLambda", "p and N_{cl, PID} ", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_Before_ElectronsGamma", "p and N_{cl, PID}", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); + + registryDeDx.add( + "hp_vs_NclPID_TPC_After_ElectronsGamma", "p and N_{cl, PID} ", HistType::kTH2F, + {{pAxisTrack}, {100, 0, 160, "N_{cl, PID}"}}); // beta plot registryDeDx.add( @@ -368,36 +534,42 @@ struct DedxPidAnalysis { x->SetBinLabel(GoodZvtxFT0vsPV, "GoodZvtxFT0vsPV"); // Track Counter - registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); + registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 6.5, ""}}); auto htrackAll = registryDeDx.get(HIST("trackselAll")); auto* xAll = htrackAll->GetXaxis(); xAll->SetBinLabel(AllPri, "AllPri"); xAll->SetBinLabel(SelectionPrim, "SelectionPrim"); xAll->SetBinLabel(PhiVarCutPri, "PhiVarCutPri"); - xAll->SetBinLabel(NTPCClCutPri, "NTPCClCutPri"); - xAll->SetBinLabel(NITSClCutPri, "NITSClCutPri"); + xAll->SetBinLabel(NClTPCFoundCutPri, "NClTPCFoundCutPri"); + xAll->SetBinLabel(NClTPCPIDCutPri, "NClTPCPIDCutPri"); - registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{18, 0.5, 18.5, ""}}); + registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{24, 0.5, 24.5, ""}}); auto htrackSec = registryDeDx.get(HIST("trackselSec")); auto* xSec = htrackSec->GetXaxis(); xSec->SetBinLabel(AllSec, "AllSec"); + xSec->SetBinLabel(V0Type, "V0Type"); xSec->SetBinLabel(V0CosPA, "V0CosPA"); xSec->SetBinLabel(V0DecayRadius, "V0DecayRadius"); xSec->SetBinLabel(V0Daughters, "V0Daughters"); xSec->SetBinLabel(TPCRefit, "TPCRefit"); xSec->SetBinLabel(PhiVarCutSec, "PhiVarCutSec"); - xSec->SetBinLabel(NTPCClCutSec, "NTPCClCutSec"); - xSec->SetBinLabel(NITSClCutSec, "NITSClCutSec"); + xSec->SetBinLabel(NClTPCFoundCutSec, "NClTPCFoundCutSec"); + xSec->SetBinLabel(NClTPCPIDCutSec, "NClTPCPIDCutSec"); xSec->SetBinLabel(AllK0s, "AllK0s"); xSec->SetBinLabel(V0RapidityK0s, "V0RapidityK0s"); xSec->SetBinLabel(V0ProperLifetimeK0s, "V0ProperLifetimeK0s"); + xSec->SetBinLabel(MassCutK0s, "MassCutK0s"); xSec->SetBinLabel(AllLambda, "AllLambda"); xSec->SetBinLabel(V0RapidityLambda, "V0RapidityLambda"); xSec->SetBinLabel(V0ProperLifetimeLambda, "V0ProperLifetimeLambda"); + xSec->SetBinLabel(MassCutLambda, "MassCutLambda"); xSec->SetBinLabel(AllAntiLambda, "AllAntiLambda"); xSec->SetBinLabel(V0RapidityAntiLambda, "V0RapidityAntiLambda"); xSec->SetBinLabel(V0ProperLifetimeAntiLambda, "V0ProperLifetimeAntiLambda"); + xSec->SetBinLabel(MassCutAntiLambda, "MassCutAntiLambda"); xSec->SetBinLabel(AllGamma, "AllGamma"); + xSec->SetBinLabel(V0RapidityGamma, "V0RapidityGamma"); + xSec->SetBinLabel(MassCutGamma, "MassCutGamma"); mySelectionPrim = myTrackSelection(); } @@ -419,6 +591,13 @@ struct DedxPidAnalysis { return true; } + // Momentum + template + float getMomentum(const T1& track) + { + return (momentumMode == TpcInnerParam) ? track.tpcInnerParam() : track.p(); + }; + // General V0 Selections template bool passedV0Selection(const T1& v0, const C& /*collision*/) @@ -451,13 +630,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (v0SelectionMode == v0TPC) { + if (v0SelectionMode == V0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPi(); - } else if (v0SelectionMode == v0TOF) { + } else if (v0SelectionMode == V0TOF) { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPi(); - } else if (v0SelectionMode == v0TPCTOF) { + } else if (v0SelectionMode == V0TPCTOF) { sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } @@ -475,10 +654,25 @@ struct DedxPidAnalysis { if (std::abs(sigman) > nsigmaTOFmax) return false; } + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllK0s); - // Invariant-Mass Selection - if (v0.mK0Short() < minMassK0s || v0.mK0Short() > maxMassK0s) + if (std::abs(v0.yK0Short()) > v0rapidityCut) return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityK0s); + + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassK0Short; + + if (properLifetime > v0ProperLifetimeCutK0s) + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeK0s); + + if (std::abs(v0.mK0Short() - MassK0Short) > invMassCutK0s) + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutK0s); return true; } @@ -497,13 +691,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (v0SelectionMode == v0TPC) { + if (v0SelectionMode == V0TPC) { sigmap = ptrack.tpcNSigmaPr(); sigman = ntrack.tpcNSigmaPi(); - } else if (v0SelectionMode == v0TOF) { + } else if (v0SelectionMode == V0TOF) { sigmap = ptrack.tofNSigmaPr(); sigman = ntrack.tofNSigmaPi(); - } else if (v0SelectionMode == v0TPCTOF) { + } else if (v0SelectionMode == V0TPCTOF) { sigmap = std::hypot(ptrack.tpcNSigmaPr(), ptrack.tofNSigmaPr()); sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } @@ -521,10 +715,27 @@ struct DedxPidAnalysis { if (std::abs(sigman) > nsigmaTOFmax) return false; } + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllLambda); - // Invariant-Mass Selection - if (v0.mLambda() < minMassLambda || v0.mLambda() > maxMassLambda) + if (std::abs(v0.yLambda()) > v0rapidityCut) return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityLambda); + + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; + + if (properLifetime > v0ProperLifetimeCutLambda) + return false; + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeLambda); + + if (std::abs(v0.mLambda() - MassLambda) > invMassCutLambda) { + return false; + } + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutLambda); return true; } @@ -543,13 +754,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (v0SelectionMode == v0TPC) { + if (v0SelectionMode == V0TPC) { sigmap = ptrack.tpcNSigmaPi(); sigman = ntrack.tpcNSigmaPr(); - } else if (v0SelectionMode == v0TOF) { + } else if (v0SelectionMode == V0TOF) { sigmap = ptrack.tofNSigmaPi(); sigman = ntrack.tofNSigmaPr(); - } else if (v0SelectionMode == v0TPCTOF) { + } else if (v0SelectionMode == V0TPCTOF) { sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); sigman = std::hypot(ntrack.tpcNSigmaPr(), ntrack.tofNSigmaPr()); } @@ -566,11 +777,29 @@ struct DedxPidAnalysis { if (std::abs(sigman) > nsigmaTOFmax) return false; } + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllAntiLambda); + + if (std::abs(v0.yLambda()) > v0rapidityCut) + return false; + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityAntiLambda); + + float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; - // Invariant-Mass Selection - if (v0.mAntiLambda() < minMassLambda || v0.mAntiLambda() > maxMassLambda) + if (properLifetime > v0ProperLifetimeCutLambda) return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeAntiLambda); + + if (std::abs(v0.mAntiLambda() - MassLambda) > invMassCutLambda) + return false; + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutAntiLambda); + return true; } @@ -588,13 +817,13 @@ struct DedxPidAnalysis { double sigmap = 0.0; double sigman = 0.0; - if (v0SelectionMode == v0TPC) { + if (v0SelectionMode == V0TPC) { sigmap = ptrack.tpcNSigmaEl(); sigman = ntrack.tpcNSigmaEl(); - } else if (v0SelectionMode == v0TOF) { + } else if (v0SelectionMode == V0TOF) { sigmap = ptrack.tofNSigmaEl(); sigman = ntrack.tofNSigmaEl(); - } else if (v0SelectionMode == v0TPCTOF) { + } else if (v0SelectionMode == V0TPCTOF) { sigmap = std::hypot(ptrack.tpcNSigmaEl(), ptrack.tofNSigmaEl()); sigman = std::hypot(ntrack.tpcNSigmaEl(), ntrack.tofNSigmaEl()); } @@ -612,11 +841,25 @@ struct DedxPidAnalysis { if (std::abs(sigman) > nsigmaTOFmax) return false; } + const float gammaMass = 2 * MassElectron; // GeV/c^2 + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllGamma); - // Invariant-Mass Selection - if (v0.mGamma() < minMassGamma || v0.mGamma() > maxMassGamma) + const float yGamma = RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, MassGamma); + + if (std::abs(yGamma) > v0rapidityCut) + return false; + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityGamma); + + if (std::abs(v0.mGamma() - gammaMass) > invMassCutGamma) return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutGamma); + return true; } // Magnetic field @@ -637,12 +880,12 @@ struct DedxPidAnalysis { template bool passedPhiCutPri(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) { - float p = trk.pt(); + float p = trk.p(); float pt = trk.pt(); float phi = trk.phi(); int charge = trk.sign(); - float eta = trk.eta(); auto nTPCCl = trk.tpcNClsFound(); + auto nTPCPIDCl = trk.tpcNClsPID(); if (pt < pTcut) return true; @@ -656,72 +899,74 @@ struct DedxPidAnalysis { phi += o2::constants::math::PI / 18.0f; phi = std::fmod(phi, o2::constants::math::PI / 9.0f); - registryDeDx.fill(HIST("hpt_vs_phi_Ncl_TPC_Before"), pt, phi, nTPCCl); - registryDeDx.fill(HIST("hp_vs_phi_Ncl_TPC_Before"), p, phi, nTPCCl); - registryDeDx.fill(HIST("heta_vs_Ncl_TPC_Before"), eta, nTPCCl); + registryDeDx.fill(HIST("hpt_vs_phi_NclFound_TPC_Before"), pt, phi, nTPCCl); + registryDeDx.fill(HIST("hp_vs_phi_NclFound_TPC_Before"), p, phi, nTPCCl); + registryDeDx.fill(HIST("hpt_vs_phi_NclPID_TPC_Before"), pt, phi, nTPCPIDCl); + registryDeDx.fill(HIST("hp_vs_phi_NclPID_TPC_Before"), p, phi, nTPCPIDCl); // cut phi if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) return false; // reject track - registryDeDx.fill(HIST("hpt_vs_phi_Ncl_TPC_After"), pt, phi, nTPCCl); - registryDeDx.fill(HIST("hp_vs_phi_Ncl_TPC_After"), p, phi, nTPCCl); - registryDeDx.fill(HIST("heta_vs_Ncl_TPC_After"), eta, nTPCCl); + registryDeDx.fill(HIST("hpt_vs_phi_NclFound_TPC_After"), pt, phi, nTPCCl); + registryDeDx.fill(HIST("hp_vs_phi_NclFound_TPC_After"), p, phi, nTPCCl); + registryDeDx.fill(HIST("hpt_vs_phi_NclPID_TPC_After"), pt, phi, nTPCPIDCl); + registryDeDx.fill(HIST("hp_vs_phi_NclPID_TPC_After"), p, phi, nTPCPIDCl); return true; } // NclCutTPC template - bool passedNTPCClCutPri(const T& trk) + bool passedNClTPCFoundCutPri(const T& trk) { float eta = trk.eta(); - float sigP = trk.sign() * trk.tpcInnerParam(); + float sigP = trk.sign() * getMomentum(trk); auto nTPCCl = trk.tpcNClsFound(); - if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { @@ -732,49 +977,49 @@ struct DedxPidAnalysis { if (nTPCCl < minTPCnClsFound) return false; - if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { @@ -785,114 +1030,114 @@ struct DedxPidAnalysis { return true; } - // NclCutITS + // NclPIDCutTPC template - bool passedNITSClCutPri(const T& trk) + bool passedNClTPCPIDCutPri(const T& trk) { float eta = trk.eta(); - float sigP = trk.sign() * trk.tpcInnerParam(); - auto nITSCl = trk.itsNCls(); + float sigP = trk.sign() * getMomentum(trk); + auto nTPCCl = trk.tpcNClsPID(); - if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[0]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[0]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[1]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[1]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[2]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[2]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[3]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[3]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[4]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[4]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[5]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[5]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[6]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[6]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegBefore[7]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosBefore[7]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); } } - if (nITSCl < minITSnCls) + if (nTPCCl < minTPCnClsPID) return false; - if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[0]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[0]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[1]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[1]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[2]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[2]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[3]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[3]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[4]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[4]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[5]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[5]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[6]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[6]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); } - } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclITSDedxMomentumNegAfter[7]), nITSCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclITSDedxMomentumPosAfter[7]), nITSCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); } } @@ -928,7 +1173,7 @@ struct DedxPidAnalysis { // NclCutTPC template - bool passedNTPCClCutSecondaries(const T& trk) + bool passedNClTPCFoundCutSecondaries(const T& trk) { auto nTPCCl = trk.tpcNClsFound(); @@ -938,13 +1183,13 @@ struct DedxPidAnalysis { return true; } - // NclCutITS primary + // NclCutPIDTPC secondary template - bool passedNITSClCutSecondaries(const T& trk) + bool passedNClTPCPIDCutSecondaries(const T& trk) { - auto nITSCl = trk.itsNCls(); + auto nTPCCl = trk.tpcNClsPID(); - if (nITSCl < minITSnCls) + if (nTPCCl < minTPCnClsPID) return false; return true; @@ -984,6 +1229,10 @@ struct DedxPidAnalysis { const uint64_t timeStamp{foundBC.timestamp()}; const int magField{getMagneticField(timeStamp)}; + float centrality = collision.centFT0C(); + if (centrality < CentClasses[0] || centrality > CentClasses[10]) + return; + for (const auto& trk : tracks) { registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::AllPri); // track Selection @@ -998,24 +1247,29 @@ struct DedxPidAnalysis { continue; } registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::PhiVarCutPri); - // NCl cut ITS - if (nTPCClCut) { - if (!passedNTPCClCutPri(trk)) + + // NCl cut TPC + registryDeDx.fill(HIST("heta_vs_NclFound_TPC_Before_Primary"), trk.eta(), trk.tpcNClsFound()); + if (nClTPCFoundCut) { + if (!passedNClTPCFoundCutPri(trk)) continue; } - registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NTPCClCutPri); + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NClTPCFoundCutPri); + registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); - // NCl cut ITS - if (nITSClCut) { - if (!passedNITSClCutPri(trk)) + // NCl cut PID TPC + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_Primary"), trk.eta(), trk.tpcNClsPID()); + if (nClTPCPIDCut) { + if (!passedNClTPCPIDCutPri(trk)) continue; } - registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NITSClCutPri); + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NClTPCPIDCutPri); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_Primary"), trk.eta(), trk.tpcNClsPID()); - float signedP = trk.sign() * trk.tpcInnerParam(); + float signedP = trk.sign() * getMomentum(trk); // MIP calibration for pions - if (trk.tpcInnerParam() >= pionMin && trk.tpcInnerParam() <= pionMax) { + if (getMomentum(trk) >= pionMin && getMomentum(trk) <= pionMax) { if (calibrationMode) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_Pi"), trk.eta(), trk.tpcSignal()); @@ -1025,7 +1279,7 @@ struct DedxPidAnalysis { } else { for (int i = 0; i < kEtaIntervals; ++i) { - if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_calibrated_Pi"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i)); } else { @@ -1051,7 +1305,7 @@ struct DedxPidAnalysis { } } else { for (int i = 0; i < kEtaIntervals; ++i) { - if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_El"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); } else { @@ -1071,7 +1325,7 @@ struct DedxPidAnalysis { } } else { for (int i = 0; i < kEtaIntervals; ++i) { - if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_TOF"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); } else { @@ -1085,14 +1339,26 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hdEdx_vs_phi"), trk.phi(), trk.tpcSignal()); if (!calibrationMode) { + int centIndex = -1; + for (int j = 0; j < kCentralityClasses; ++j) { + if (centrality >= CentClasses[j] && centrality < CentClasses[j + 1]) { + centIndex = j; + break; + } + } + if (centIndex == -1) + continue; + for (int i = 0; i < kEtaIntervals; ++i) { - if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP > 0) { registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); - registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Pos"), trk.eta(), trk.pt(), signedP); + registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Pos"), trk.eta(), trk.pt(), trk.p()); + hDedxVsMomentumVsCentPos[centIndex]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); } else { registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); - registryDeDx.fill(HIST("heta_vs_p_vs_pt_all_Neg"), trk.eta(), trk.pt(), std::abs(signedP)); + registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Neg"), trk.eta(), trk.pt(), trk.p()); + hDedxVsMomentumVsCentNeg[centIndex]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); } } } @@ -1105,6 +1371,13 @@ struct DedxPidAnalysis { // Standard V0 Selections registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllSec); + + // Select V0 type + if (v0.v0Type() != v0TypeSelection) + continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0Type); + if (!passedV0Selection(v0, collision)) { continue; } @@ -1129,63 +1402,67 @@ struct DedxPidAnalysis { } registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::PhiVarCutSec); - if (nTPCClCut) { - if (!passedNTPCClCutSecondaries(posTrack)) + fillHist = false; + // K0s Selection + if (passedK0Selection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_PionsK0s"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_PionsK0s"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_PionsK0s"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_PionsK0s"), negTrack.p(), negTrack.tpcNClsPID()); + } + // Lambda Selection + if (passedLambdaSelection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_ProtonsLambda"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_PionsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_ProtonsLambda"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_PionsLambda"), negTrack.p(), negTrack.tpcNClsPID()); + } + // AntiLambda Selection + if (passedAntiLambdaSelection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_PionsLambda"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_ProtonsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_PionsLambda"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_ProtonsLambda"), negTrack.p(), negTrack.tpcNClsPID()); + } + // Gamma Selection + if (passedGammaSelection(v0, negTrack, posTrack, collision)) { + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_ElectronsGamma"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_ElectronsGamma"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_ElectronsGamma"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_Before_ElectronsGamma"), negTrack.p(), negTrack.tpcNClsPID()); + } + + if (nClTPCFoundCut) { + if (!passedNClTPCFoundCutSecondaries(posTrack)) continue; - if (!passedNTPCClCutSecondaries(negTrack)) + if (!passedNClTPCFoundCutSecondaries(negTrack)) continue; } - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NTPCClCutSec); + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NClTPCFoundCutSec); - if (nITSClCut) { - if (!passedNITSClCutSecondaries(posTrack)) + if (nClTPCPIDCut) { + if (!passedNClTPCPIDCutSecondaries(posTrack)) continue; - if (!passedNITSClCutSecondaries(negTrack)) + if (!passedNClTPCPIDCutSecondaries(negTrack)) continue; } - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NITSClCutSec); - - float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); - float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); - - float pxPos = posTrack.px(); - float pyPos = posTrack.py(); - float pzPos = posTrack.pz(); + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NClTPCPIDCutSec); - float pxNeg = negTrack.px(); - float pyNeg = negTrack.py(); - float pzNeg = negTrack.pz(); + float signedPpos = posTrack.sign() * getMomentum(posTrack); + float signedPneg = negTrack.sign() * getMomentum(negTrack); - const float gammaMass = 2 * MassElectron; // GeV/c^2 + fillHist = true; // K0s Selection if (passedK0Selection(v0, negTrack, posTrack, collision)) { - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllK0s); - - if (std::abs(v0.rapidity(MassK0Short)) > v0rapidityCut) - continue; - - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityK0s); - float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassK0Short; - - if (properLifetime > v0ProperLifetimeCutK0s) - continue; - - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeK0s); - - float ePosPi = posTrack.energy(MassPionCharged); - float eNegPi = negTrack.energy(MassPionCharged); - - float invMass = std::sqrt((eNegPi + ePosPi) * (eNegPi + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - - if (std::abs(invMass - MassK0Short) > invMassCut) { - continue; - } - + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsK0s"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsK0s"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), negTrack.p(), negTrack.tpcNClsPID()); for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1198,28 +1475,10 @@ struct DedxPidAnalysis { // Lambda Selection if (passedLambdaSelection(v0, negTrack, posTrack, collision)) { - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllLambda); - - if (std::abs(v0.rapidity(MassLambda)) > v0rapidityCut) - continue; - - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityLambda); - float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; - - if (properLifetime > v0ProperLifetimeCutLambda) - continue; - - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeLambda); - - float ePosPr = posTrack.energy(MassProton); - float eNegPi = negTrack.energy(MassPionCharged); - - float invMass = std::sqrt((eNegPi + ePosPr) * (eNegPi + ePosPr) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - - if (std::abs(invMass - MassLambda) > invMassCut) { - continue; - } - + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ProtonsLambda"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), negTrack.p(), negTrack.tpcNClsPID()); for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1232,28 +1491,10 @@ struct DedxPidAnalysis { // AntiLambda Selection if (passedAntiLambdaSelection(v0, negTrack, posTrack, collision)) { - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllAntiLambda); - - if (std::abs(v0.rapidity(MassLambda)) > v0rapidityCut) - continue; - - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityAntiLambda); - float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; - - if (properLifetime > v0ProperLifetimeCutLambda) - continue; - - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeAntiLambda); - - float ePosPi = posTrack.energy(MassPionCharged); - float eNegPr = negTrack.energy(MassProton); - - float invMass = std::sqrt((eNegPr + ePosPi) * (eNegPr + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - - if (std::abs(invMass - MassLambda) > invMassCut) { - continue; - } - + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsLambda"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.p(), negTrack.tpcNClsPID()); for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); @@ -1266,17 +1507,10 @@ struct DedxPidAnalysis { // Gamma Selection if (passedGammaSelection(v0, negTrack, posTrack, collision)) { - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllGamma); - - float ePosEl = posTrack.energy(MassElectron); - float eNegEl = negTrack.energy(MassElectron); - - float invMass = std::sqrt((eNegEl + ePosEl) * (eNegEl + ePosEl) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - - if (std::abs(invMass - gammaMass) > invMassCutGamma) { - continue; - } - + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ElectronsGamma"), posTrack.eta(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.eta(), negTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), posTrack.p(), posTrack.tpcNClsPID()); + registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.p(), negTrack.tpcNClsPID()); for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); From e8e39e7ec9a4d97342158a770d50e8b37af47edf Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Wed, 4 Feb 2026 15:55:59 -0600 Subject: [PATCH 13/24] A problem in the track counter was fixed --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 320 +++++++++++++------------ 1 file changed, 172 insertions(+), 148 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 441056dc30e..3f7cf60a2f3 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -52,9 +52,9 @@ using PIDTracks = soa::Join< using SelectedCollisions = soa::Join; using BCsRun3 = soa::Join; -static constexpr int kNCentHists{10}; -std::array, kNCentHists> hDedxVsMomentumVsCentPos{}; -std::array, kNCentHists> hDedxVsMomentumVsCentNeg{}; +static constexpr int NCentHists{10}; +std::array, NCentHists> hDedxVsMomentumVsCentPos{}; +std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; struct DedxPidAnalysis { @@ -66,9 +66,9 @@ struct DedxPidAnalysis { true, true}; // Constant values - static constexpr int kEtaIntervals = 8; - static constexpr int kParticlesType = 4; - static constexpr int kCentralityClasses = 10; + static constexpr int EtaIntervals = 8; + static constexpr int ParticlesType = 4; + static constexpr int CentralityClasses = 10; float tpcCut = 0.6; float pionMin = 0.35; float pionMax = 0.45; @@ -105,8 +105,8 @@ struct DedxPidAnalysis { AllPri = 1, SelectionPrim, PhiVarCutPri, - NClTPCFoundCutPri, - NClTPCPIDCutPri + NClTPCPIDCutPri, + NClTPCFoundCutPri }; // Track secondary lebel @@ -172,6 +172,8 @@ struct DedxPidAnalysis { Configurable phiVarCut{"phiVarCut", true, "phi var cut"}; Configurable nClTPCFoundCut{"nClTPCFoundCut", false, "number of found clusters in TPC cut"}; Configurable nClTPCPIDCut{"nClTPCPIDCut", true, "number of PID clusters in TPC cut"}; + Configurable nGoodZvtx{"nGoodZvtx", true, "Rejects events with no vertex match between FT0 and PV"}; // + Configurable nPileUp{"nPileUp", true, "Rejects events with pileup in the same bunch crossing"}; // Configurable v0SelectionMode{"v0SelectionMode", 3, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; Configurable momentumMode{"momentumMode", 1, "1: TPC inner param, 2: Total momentum p"}; Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; @@ -180,22 +182,22 @@ struct DedxPidAnalysis { Configurable highParam1{"highParam1", 0.16685, "First parameter for high phi cut"}; Configurable highParam2{"highParam2", 0.00981942, "Second parameter for high phi cut"}; // Histograms names - static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; - static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; - static constexpr std::string_view kDedxvsMomentumvsCentPos[kCentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; - static constexpr std::string_view kDedxvsMomentumvsCentNeg[kCentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; + static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; + static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + static constexpr std::string_view DedxvsMomentumvsCentPos[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; + static constexpr std::string_view DedxvsMomentumvsCentNeg[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; // Ncl TPC - static constexpr std::string_view kNclTPCDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view kNclTPCDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view kNclTPCDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_TFoundPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view kNclTPCDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; + static constexpr std::string_view NclTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view NclTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view NclTPCDedxMomentumNegAfter[EtaIntervals] = {"Ncl_TFoundPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view NclTPCDedxMomentumPosAfter[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; // Ncl PID TPC - static constexpr std::string_view kNclPIDTPCDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view kNclPIDTPCDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view kNclPIDTPCDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view kNclPIDTPCDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; - static constexpr double EtaCut[kEtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; - static constexpr double CentClasses[kCentralityClasses + 1] = {0.0, 0.1, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; + static constexpr std::string_view NclPIDTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view NclPIDTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view NclPIDTPCDedxMomentumNegAfter[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view NclPIDTPCDedxMomentumPosAfter[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; + static constexpr double EtaCut[EtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + static constexpr double CentClasses[CentralityClasses + 1] = {0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; @@ -228,6 +230,16 @@ struct DedxPidAnalysis { void init(InitContext const&) { + if (nPileUp) { + LOGF(info, "Applying NoSameBunchPileup cut"); + } else { + LOGF(info, "NoSameBunchPileup cut disabled"); + } + if (nGoodZvtx) { + LOGF(info, "Applying GoodZvtxFT0vsPV cut"); + } else { + LOGF(info, "GoodZvtxFT0vsPV cut disabled"); + } if (v0SelectionMode == V0TPC) { LOGF(info, "V0 seleccion using TPC only"); } else if (v0SelectionMode == V0TOF) { @@ -340,16 +352,16 @@ struct DedxPidAnalysis { {{etaAxis}, {ptAxis}, {pAxisTrack}}); // De/Dx for ch and v0 particles - for (int i = 0; i < kParticlesType; ++i) { - registryDeDx.add(kDedxvsMomentumPos[i].data(), "dE/dx", HistType::kTH3F, + for (int i = 0; i < ParticlesType; ++i) { + registryDeDx.add(DedxvsMomentumPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); - registryDeDx.add(kDedxvsMomentumNeg[i].data(), "dE/dx", HistType::kTH3F, + registryDeDx.add(DedxvsMomentumNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } - for (int i = 0; i < kCentralityClasses; ++i) { - hDedxVsMomentumVsCentPos[i] = registryDeDx.add(kDedxvsMomentumvsCentPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); - hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(kDedxvsMomentumvsCentNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + for (int i = 0; i < CentralityClasses; ++i) { + hDedxVsMomentumVsCentPos[i] = registryDeDx.add(DedxvsMomentumvsCentPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(DedxvsMomentumvsCentNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } } @@ -394,30 +406,30 @@ struct DedxPidAnalysis { } // Ncl vs de/dx TPC if (nClTPCFoundCut) { - for (int i = 0; i < kEtaIntervals; ++i) { - registryDeDx.add(kNclTPCDedxMomentumPosBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + for (int i = 0; i < EtaIntervals; ++i) { + registryDeDx.add(NclTPCDedxMomentumPosBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclTPCDedxMomentumNegBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + registryDeDx.add(NclTPCDedxMomentumNegBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclTPCDedxMomentumPosAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + registryDeDx.add(NclTPCDedxMomentumPosAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclTPCDedxMomentumNegAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + registryDeDx.add(NclTPCDedxMomentumNegAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); } } // Ncl vs de/dx ITS if (nClTPCPIDCut) { - for (int i = 0; i < kEtaIntervals; ++i) { - registryDeDx.add(kNclPIDTPCDedxMomentumPosBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + for (int i = 0; i < EtaIntervals; ++i) { + registryDeDx.add(NclPIDTPCDedxMomentumPosBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclPIDTPCDedxMomentumNegBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + registryDeDx.add(NclPIDTPCDedxMomentumNegBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclPIDTPCDedxMomentumPosAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + registryDeDx.add(NclPIDTPCDedxMomentumPosAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(kNclPIDTPCDedxMomentumNegAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + registryDeDx.add(NclPIDTPCDedxMomentumNegAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); } } @@ -524,6 +536,9 @@ struct DedxPidAnalysis { // Event Counter registryDeDx.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{100, -20.0, +20.0, "z_{vtx} (cm)"}}); + // Event Counter by centrality + registryDeDx.add("histCentrality", "collision centrality", HistType::kTH1F, {{100, 0.0, 100, "cent"}}); + // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); auto hstat = registryDeDx.get(HIST("evsel")); @@ -534,15 +549,15 @@ struct DedxPidAnalysis { x->SetBinLabel(NoSameBunchPileup, "NoSameBunchPileup"); x->SetBinLabel(GoodZvtxFT0vsPV, "GoodZvtxFT0vsPV"); - // Track Counter - registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 6.5, ""}}); + // Track Prim Counter + registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); auto htrackAll = registryDeDx.get(HIST("trackselAll")); auto* xAll = htrackAll->GetXaxis(); xAll->SetBinLabel(AllPri, "AllPri"); xAll->SetBinLabel(SelectionPrim, "SelectionPrim"); xAll->SetBinLabel(PhiVarCutPri, "PhiVarCutPri"); - xAll->SetBinLabel(NClTPCFoundCutPri, "NClTPCFoundCutPri"); xAll->SetBinLabel(NClTPCPIDCutPri, "NClTPCPIDCutPri"); + xAll->SetBinLabel(NClTPCFoundCutPri, "NClTPCFoundCutPri"); registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{24, 0.5, 24.5, ""}}); auto htrackSec = registryDeDx.get(HIST("trackselSec")); @@ -927,51 +942,51 @@ struct DedxPidAnalysis { if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); } } @@ -980,51 +995,51 @@ struct DedxPidAnalysis { if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); } } @@ -1041,51 +1056,51 @@ struct DedxPidAnalysis { if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); } } @@ -1094,51 +1109,51 @@ struct DedxPidAnalysis { if (eta >= EtaCut[0] && eta < EtaCut[1]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); } } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { if (sigP < 0) { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); } else { - registryDeDx.fill(HIST(kNclPIDTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); } } @@ -1212,15 +1227,17 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("evsel"), EvCutLabel::ZVtxCut); - if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) - return; - - registryDeDx.fill(HIST("evsel"), EvCutLabel::NoSameBunchPileup); - - if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) - return; + if (nPileUp) { + if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + registryDeDx.fill(HIST("evsel"), EvCutLabel::NoSameBunchPileup); + } - registryDeDx.fill(HIST("evsel"), EvCutLabel::GoodZvtxFT0vsPV); + if (nGoodZvtx) { + if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + registryDeDx.fill(HIST("evsel"), EvCutLabel::GoodZvtxFT0vsPV); + } // Event Counter registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); @@ -1234,8 +1251,12 @@ struct DedxPidAnalysis { if (centrality < CentClasses[0] || centrality > CentClasses[10]) return; + // Event Counter by cent + registryDeDx.fill(HIST("histCentrality"), centrality); + for (const auto& trk : tracks) { registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::AllPri); + // track Selection if (!mySelectionPrim.IsSelected(trk)) continue; @@ -1246,27 +1267,29 @@ struct DedxPidAnalysis { if (phiVarCut) { if (!passedPhiCutPri(trk, magField, *fphiCutLow, *fphiCutHigh)) continue; + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::PhiVarCutPri); } - registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::PhiVarCutPri); - - // NCl cut TPC - registryDeDx.fill(HIST("heta_vs_NclFound_TPC_Before_Primary"), trk.eta(), trk.tpcNClsFound()); - if (nClTPCFoundCut) { - if (!passedNClTPCFoundCutPri(trk)) - continue; - } - registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NClTPCFoundCutPri); - registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); // NCl cut PID TPC registryDeDx.fill(HIST("heta_vs_NclPID_TPC_Before_Primary"), trk.eta(), trk.tpcNClsPID()); if (nClTPCPIDCut) { if (!passedNClTPCPIDCutPri(trk)) continue; + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NClTPCPIDCutPri); } - registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NClTPCPIDCutPri); + registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_Primary"), trk.eta(), trk.tpcNClsPID()); + // NCl cut TPC + registryDeDx.fill(HIST("heta_vs_NclFound_TPC_Before_Primary"), trk.eta(), trk.tpcNClsFound()); + if (nClTPCFoundCut) { + if (!passedNClTPCFoundCutPri(trk)) + continue; + registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::NClTPCFoundCutPri); + } + + registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); + float signedP = trk.sign() * getMomentum(trk); // MIP calibration for pions @@ -1279,7 +1302,7 @@ struct DedxPidAnalysis { } } else { - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_calibrated_Pi"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i)); @@ -1305,7 +1328,7 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_El"), trk.eta(), trk.tpcSignal(), signedP); } } else { - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_El"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); @@ -1325,7 +1348,7 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_TOF"), trk.eta(), trk.tpcSignal(), signedP); } } else { - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_TOF"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); @@ -1341,7 +1364,7 @@ struct DedxPidAnalysis { if (!calibrationMode) { int centIndex = -1; - for (int j = 0; j < kCentralityClasses; ++j) { + for (int j = 0; j < CentralityClasses; ++j) { if (centrality >= CentClasses[j] && centrality < CentClasses[j + 1]) { centIndex = j; break; @@ -1350,14 +1373,14 @@ struct DedxPidAnalysis { if (centIndex == -1) continue; - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP > 0) { - registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + registryDeDx.fill(HIST(DedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Pos"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentPos[centIndex]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); } else { - registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + registryDeDx.fill(HIST(DedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Neg"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentNeg[centIndex]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); } @@ -1400,8 +1423,9 @@ struct DedxPidAnalysis { if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) continue; + + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::PhiVarCutSec); } - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::PhiVarCutSec); fillHist = false; // K0s Selection @@ -1439,9 +1463,9 @@ struct DedxPidAnalysis { if (!passedNClTPCFoundCutSecondaries(negTrack)) continue; - } - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NClTPCFoundCutSec); + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NClTPCFoundCutSec); + } if (nClTPCPIDCut) { if (!passedNClTPCPIDCutSecondaries(posTrack)) @@ -1449,9 +1473,9 @@ struct DedxPidAnalysis { if (!passedNClTPCPIDCutSecondaries(negTrack)) continue; - } - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NClTPCPIDCutSec); + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::NClTPCPIDCutSec); + } float signedPpos = posTrack.sign() * getMomentum(posTrack); float signedPneg = negTrack.sign() * getMomentum(negTrack); @@ -1464,12 +1488,12 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsK0s"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsK0s"), negTrack.p(), negTrack.tpcNClsPID()); - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } @@ -1480,12 +1504,12 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_PionsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), negTrack.p(), negTrack.tpcNClsPID()); - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumPos[2]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumPos[2]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } @@ -1496,12 +1520,12 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_PionsLambda"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ProtonsLambda"), negTrack.p(), negTrack.tpcNClsPID()); - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } @@ -1512,12 +1536,12 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("heta_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.eta(), negTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), posTrack.p(), posTrack.tpcNClsPID()); registryDeDx.fill(HIST("hp_vs_NclPID_TPC_After_ElectronsGamma"), negTrack.p(), negTrack.tpcNClsPID()); - for (int i = 0; i < kEtaIntervals; ++i) { + for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(kDedxvsMomentumPos[3]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + registryDeDx.fill(HIST(DedxvsMomentumPos[3]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } From 803e83477765323765a75ca1ca79b3b85f58e506 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 6 Feb 2026 00:43:23 -0600 Subject: [PATCH 14/24] INEL cut was added --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 42 ++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 3f7cf60a2f3..4c9fbb78d4b 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -49,7 +49,7 @@ using PIDTracks = soa::Join< aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta, aod::pidTPCPi, aod::pidTPCPr, aod::pidTPCEl>; -using SelectedCollisions = soa::Join; +using SelectedCollisions = soa::Join; using BCsRun3 = soa::Join; static constexpr int NCentHists{10}; @@ -85,6 +85,13 @@ struct DedxPidAnalysis { }; + enum NINELSelectionMode { + NoSelINEL = 1, + SelINELgt0 = 2, + SelINELgt1 = 3 + + }; + enum MomentumMode { TpcInnerParam = 1, TotalMomentum = 2 @@ -96,8 +103,8 @@ struct DedxPidAnalysis { SelEigth, ZVtxCut, NoSameBunchPileup, - GoodZvtxFT0vsPV - + GoodZvtxFT0vsPV, + INELgt }; // Track primary label @@ -173,9 +180,10 @@ struct DedxPidAnalysis { Configurable nClTPCFoundCut{"nClTPCFoundCut", false, "number of found clusters in TPC cut"}; Configurable nClTPCPIDCut{"nClTPCPIDCut", true, "number of PID clusters in TPC cut"}; Configurable nGoodZvtx{"nGoodZvtx", true, "Rejects events with no vertex match between FT0 and PV"}; // - Configurable nPileUp{"nPileUp", true, "Rejects events with pileup in the same bunch crossing"}; // + Configurable nPileUp{"nPileUp", true, "Rejects events with pileup in the same bunch crossing"}; + Configurable nINELSelectionMode{"nINELSelectionMode", 2, "INEL event selection: 1 no sel, 2 INEL>0, 3 INEL>1"}; Configurable v0SelectionMode{"v0SelectionMode", 3, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; - Configurable momentumMode{"momentumMode", 1, "1: TPC inner param, 2: Total momentum p"}; + Configurable momentumMode{"momentumMode", 2, "1: TPC inner param, 2: Total momentum p"}; Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; Configurable lowParam1{"lowParam1", 0.119297, "First parameter for low phi cut"}; Configurable lowParam2{"lowParam2", 0.000379693, "Second parameter for low phi cut"}; @@ -230,6 +238,7 @@ struct DedxPidAnalysis { void init(InitContext const&) { + const char* label = "No INEL selection"; if (nPileUp) { LOGF(info, "Applying NoSameBunchPileup cut"); } else { @@ -240,6 +249,15 @@ struct DedxPidAnalysis { } else { LOGF(info, "GoodZvtxFT0vsPV cut disabled"); } + if (nINELSelectionMode == NoSelINEL) { + LOGF(info, "INEL cut disabled"); + } else if (nINELSelectionMode == SelINELgt0) { + LOGF(info, "Applying INEL > 0 cut"); + label = "INEL > 0"; + } else if (nINELSelectionMode == SelINELgt1) { + LOGF(info, "Applying INEL > 1 cut"); + label = "INEL > 1"; + } if (v0SelectionMode == V0TPC) { LOGF(info, "V0 seleccion using TPC only"); } else if (v0SelectionMode == V0TOF) { @@ -540,7 +558,7 @@ struct DedxPidAnalysis { registryDeDx.add("histCentrality", "collision centrality", HistType::kTH1F, {{100, 0.0, 100, "cent"}}); // Event Counter - registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); + registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); auto hstat = registryDeDx.get(HIST("evsel")); auto* x = hstat->GetXaxis(); x->SetBinLabel(AllEv, "AllEv"); @@ -548,6 +566,7 @@ struct DedxPidAnalysis { x->SetBinLabel(ZVtxCut, "ZVtxCut"); x->SetBinLabel(NoSameBunchPileup, "NoSameBunchPileup"); x->SetBinLabel(GoodZvtxFT0vsPV, "GoodZvtxFT0vsPV"); + x->SetBinLabel(INELgt, label); // Track Prim Counter registryDeDx.add("trackselAll", "track selected all particles", HistType::kTH1F, {{5, 0.5, 5.5, ""}}); @@ -1239,6 +1258,17 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("evsel"), EvCutLabel::GoodZvtxFT0vsPV); } + if (nINELSelectionMode == NoSelINEL) { + } else if (nINELSelectionMode == SelINELgt0) { + if (!collision.isInelGt0()) + return; + registryDeDx.fill(HIST("evsel"), EvCutLabel::INELgt); + } else if (nINELSelectionMode == SelINELgt1) { + if (!collision.isInelGt1()) + return; + registryDeDx.fill(HIST("evsel"), EvCutLabel::INELgt); + } + // Event Counter registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); From 44c0caedbc040522f8a858b67933be0cd22c4d43 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 13 Feb 2026 16:45:03 -0600 Subject: [PATCH 15/24] Add ten different multiplicity selections --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 119 +++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 7 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 4c9fbb78d4b..5fbd8dc2682 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -49,7 +49,8 @@ using PIDTracks = soa::Join< aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta, aod::pidTPCPi, aod::pidTPCPr, aod::pidTPCEl>; -using SelectedCollisions = soa::Join; +using SelectedCollisions = soa::Join; using BCsRun3 = soa::Join; static constexpr int NCentHists{10}; @@ -78,21 +79,35 @@ struct DedxPidAnalysis { bool fillHist = false; - enum V0SelectionMode { + enum MultSelectionMode : int { + NoMultiplicity = 0, + MultFV0A = 1, + MultFT0M = 2, + MultFDDM = 3, + MultTracklets = 4, + MultTPC = 5, + MultNTracksPV = 6, + MultNTracksPVeta1 = 7, + CentralityFT0C = 8, + CentralityFT0M = 9, + CentralityFV0A = 10 + }; + + enum V0SelectionMode : int { V0TPC = 1, V0TOF = 2, V0TPCTOF = 3 }; - enum NINELSelectionMode { + enum NINELSelectionMode : int { NoSelINEL = 1, SelINELgt0 = 2, SelINELgt1 = 3 }; - enum MomentumMode { + enum MomentumMode : int { TpcInnerParam = 1, TotalMomentum = 2 }; @@ -185,6 +200,7 @@ struct DedxPidAnalysis { Configurable v0SelectionMode{"v0SelectionMode", 3, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; Configurable momentumMode{"momentumMode", 2, "1: TPC inner param, 2: Total momentum p"}; Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable multiplicityEstimator{"multiplicityEstimator", 9, "Flag to use a multiplicity estimator; No multiplicity: 0, MultFV0A: 1, MultFT0M: 2, MultFDDM: 3 ,MultTracklets: 4,MultTPC: 5,MultNTracksPV: 6 ,MultNTracksPVeta1: 7,CentralityFT0C: 8 ,CentralityFT0M: 9, CentralityFV0A: 10"}; Configurable lowParam1{"lowParam1", 0.119297, "First parameter for low phi cut"}; Configurable lowParam2{"lowParam2", 0.000379693, "Second parameter for low phi cut"}; Configurable highParam1{"highParam1", 0.16685, "First parameter for high phi cut"}; @@ -209,6 +225,7 @@ struct DedxPidAnalysis { Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; + ConfigurableAxis centBins{"centBins", {100, 0, 100}, "Binning for centralidad"}; // phi cut fits TF1* fphiCutHigh = nullptr; @@ -300,6 +317,55 @@ struct DedxPidAnalysis { AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; AxisSpec pAxisTrack = {binP, "#it{p} (GeV/c)"}; + AxisSpec centAxis{centBins, "Undefined multiplicity estimator"}; + switch (multiplicityEstimator) { + case MultSelectionMode::NoMultiplicity: // No multiplicity + LOGF(info, "No multiplicity estimator applied"); + break; + case MultSelectionMode::MultFV0A: // MultFV0A + centAxis.title = "MultFV0A"; + LOGF(info, "MultFV0A estimator applied"); + break; + case MultSelectionMode::MultFT0M: // MultFT0M + centAxis.title = "MultFT0M"; + LOGF(info, "MultFT0M estimator applied"); + break; + case MultSelectionMode::MultFDDM: // MultFDDM + centAxis.title = "MultFDDM"; + LOGF(info, " MultFDDM estimator applied"); + break; + case MultSelectionMode::MultTracklets: // MultTracklets + centAxis.title = "MultTracklets"; + LOGF(info, "MultTracklets estimator applied"); + break; + case MultSelectionMode::MultTPC: // MultTPC + centAxis.title = "MultTPC"; + LOGF(info, "MultTPC estimator applied"); + break; + case MultSelectionMode::MultNTracksPV: // MultNTracksPV + centAxis.title = "MultNTracksPV"; + LOGF(info, "MultNTracksPV estimator applied"); + break; + case MultSelectionMode::MultNTracksPVeta1: // MultNTracksPVeta1 + centAxis.title = "MultNTracksPVeta1"; + LOGF(info, "MultNTracksPVeta1 estimator applied"); + break; + case MultSelectionMode::CentralityFT0C: // Centrality FT0C + centAxis.title = "Centrality FT0C"; + LOGF(info, "Centrality FT0C estimator applied"); + break; + case MultSelectionMode::CentralityFT0M: // Centrality FT0M + centAxis.title = "Centrality FT0M"; + LOGF(info, "Centrality FT0M estimator applied"); + break; + case MultSelectionMode::CentralityFV0A: // Centrality FV0A + centAxis.title = "Centrality FV0A"; + LOGF(info, "Centrality FV0A estimator applied"); + break; + default: + LOG(fatal) << "Unrecognized option for multiplicity " << multiplicityEstimator; + } + fphiCutLow = new TF1("StandardPhiCutLow", Form("%f/x/x+pi/18.0-%f", lowParam1.value, lowParam2.value), 0, 50); @@ -555,7 +621,7 @@ struct DedxPidAnalysis { registryDeDx.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{100, -20.0, +20.0, "z_{vtx} (cm)"}}); // Event Counter by centrality - registryDeDx.add("histCentrality", "collision centrality", HistType::kTH1F, {{100, 0.0, 100, "cent"}}); + registryDeDx.add("histCentrality", "Centrality", HistType::kTH1F, {centAxis}); // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); @@ -1229,7 +1295,46 @@ struct DedxPidAnalysis { return true; } - + // Get Multiplicity + template + float getMultiplicity(const T& collision) + { + switch (multiplicityEstimator) { + case MultSelectionMode::NoMultiplicity: // No multiplicity + return 50.f; // to check if its filled + break; + case MultSelectionMode::MultFV0A: // MultFV0M + return collision.multZeqFV0A(); + break; + case MultSelectionMode::MultFT0M: + return collision.multZeqFT0A() + collision.multZeqFT0C(); + break; + case MultSelectionMode::MultFDDM: // MultFDDM + return collision.multZeqFDDA() + collision.multZeqFDDC(); + break; + case MultSelectionMode::MultTracklets: // MultTracklets + return 0.f; // Undefined in Run3 + break; + case MultSelectionMode::MultTPC: // MultTPC + return collision.multTPC(); + break; + case MultSelectionMode::MultNTracksPV: // MultNTracksPV + return collision.multZeqNTracksPV(); + break; + case MultSelectionMode::MultNTracksPVeta1: // MultNTracksPVeta1 + return collision.multNTracksPVeta1(); + break; + case MultSelectionMode::CentralityFT0C: // Centrality FT0C + return collision.centFT0C(); + break; + case MultSelectionMode::CentralityFT0M: // Centrality FT0M + return collision.centFT0M(); + break; + default: + LOG(fatal) << "Unknown multiplicity estimator: " << multiplicityEstimator; + return 0.f; + } + } // Process Data void process(SelectedCollisions::iterator const& collision, BCsRun3 const& /**/, aod::V0Datas const& fullV0s, PIDTracks const& tracks) @@ -1277,7 +1382,7 @@ struct DedxPidAnalysis { const uint64_t timeStamp{foundBC.timestamp()}; const int magField{getMagneticField(timeStamp)}; - float centrality = collision.centFT0C(); + float centrality = getMultiplicity(collision); if (centrality < CentClasses[0] || centrality > CentClasses[10]) return; From b27ab5ed1c7f60c46be3acaae1a41e9e5a6750ce Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 20 Feb 2026 17:21:05 -0600 Subject: [PATCH 16/24] Cross-check histograms for efficiency --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 5fbd8dc2682..5ff943f2348 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -623,6 +623,10 @@ struct DedxPidAnalysis { // Event Counter by centrality registryDeDx.add("histCentrality", "Centrality", HistType::kTH1F, {centAxis}); + // Tracks vs p + registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F, {{ptAxis}}); + registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F, {{ptAxis}}); + // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); auto hstat = registryDeDx.get(HIST("evsel")); @@ -1397,6 +1401,8 @@ struct DedxPidAnalysis { continue; registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); + // For pt + registryDeDx.fill(HIST("Tracks_vs_pT_all"), trk.pt()); // phi and Ncl cut if (phiVarCut) { @@ -1424,6 +1430,8 @@ struct DedxPidAnalysis { } registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); + // For pt + cuts + registryDeDx.fill(HIST("Tracks_vs_pT_all_cuts"), trk.pt()); float signedP = trk.sign() * getMomentum(trk); From 132549d40e9d0ae7cafe52b98312ad3163e17188 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 27 Feb 2026 17:48:03 -0600 Subject: [PATCH 17/24] Track cuts were modified --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 207 ++++++++++++++++--------- 1 file changed, 136 insertions(+), 71 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 5ff943f2348..2e56622c1a3 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -134,27 +134,37 @@ struct DedxPidAnalysis { // Track secondary lebel enum TrkSecCutLabel { AllSec = 1, - V0Type, V0CosPA, V0DecayRadius, V0Daughters, - TPCRefit, PhiVarCutSec, NClTPCFoundCutSec, NClTPCPIDCutSec, AllK0s, + SingleTrackSelectionK0s, + V0TypeK0s, + DCAtoVtxK0s, + Armenteros, V0RapidityK0s, V0ProperLifetimeK0s, MassCutK0s, AllLambda, + SingleTrackSelectionLambda, + V0TypeLambda, + DCAtoVtxLambda, V0RapidityLambda, V0ProperLifetimeLambda, MassCutLambda, AllAntiLambda, + SingleTrackSelectionAntiLambda, + V0TypeAntiLambda, + DCAtoVtxAntiLambda, V0RapidityAntiLambda, V0ProperLifetimeAntiLambda, MassCutAntiLambda, AllGamma, + SingleTrackSelectionGamma, + V0TypeGamma, V0RapidityGamma, MassCutGamma }; @@ -176,20 +186,26 @@ struct DedxPidAnalysis { Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; // v0 cuts - Configurable v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"}; - Configurable minimumV0Radius{"minimumV0Radius", 0.5f, + Configurable v0cospaMin{"v0cospaMin", 0.999f, "Minimum V0 CosPA"}; + Configurable minimumV0Radius{"minimumV0Radius", 1.2f, "Minimum V0 Radius"}; Configurable maximumV0Radius{"maximumV0Radius", 100.0f, "Maximum V0 Radius"}; Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, "Maximum DCA Daughters"}; + Configurable dcaProtonsFromLambda{"dcaProtonsFromLambda", 0.05f, + "Minimum DCA of protons to vtx for Lambda"}; + Configurable dcaPionsFromLambda{"dcaPionsFromLambda", 0.2f, + "Minimum DCA of pions to vtx for Lambda"}; + Configurable dcaPionsFromK0s{"dcaPionsFromK0s", 0.1f, + "Minimum DCA of pions to vtx for K0s"}; Configurable v0rapidityCut{"v0rapidityCut", 0.5f, "V0 rapidity cut"}; Configurable v0ProperLifetimeCutK0s{"v0ProperLifetimeCutK0s", 20.f, "V0 proper lifetime cut for K0s"}; Configurable v0ProperLifetimeCutLambda{"v0ProperLifetimeCutLambda", 30.f, "V0 proper lifetime cut for Lambda"}; Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; - Configurable invMassCutK0s{"invMassCutK0s", 0.2f, "invariant Mass Cut for K0s"}; - Configurable invMassCutLambda{"invMassCutLambda", 0.1f, "invariant Mass Cut for Lambda"}; - Configurable invMassCutGamma{"invMassCutGamma", 0.1f, "invariant Mass Cut for Gamma"}; + Configurable invMassCutK0s{"invMassCutK0s", 0.015f, "invariant Mass Cut for K0s"}; + Configurable invMassCutLambda{"invMassCutLambda", 0.015f, "invariant Mass Cut for Lambda"}; + Configurable invMassCutGamma{"invMassCutGamma", 0.015f, "invariant Mass Cut for Gamma"}; Configurable calibrationMode{"calibrationMode", false, "calibration mode"}; Configurable phiVarCut{"phiVarCut", true, "phi var cut"}; Configurable nClTPCFoundCut{"nClTPCFoundCut", false, "number of found clusters in TPC cut"}; @@ -200,11 +216,13 @@ struct DedxPidAnalysis { Configurable v0SelectionMode{"v0SelectionMode", 3, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; Configurable momentumMode{"momentumMode", 2, "1: TPC inner param, 2: Total momentum p"}; Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable v0TypeSelectionGamma{"v0TypeSelectionGamma", 7, "select on a certain V0 type (leave negative if no selection desired)"}; Configurable multiplicityEstimator{"multiplicityEstimator", 9, "Flag to use a multiplicity estimator; No multiplicity: 0, MultFV0A: 1, MultFT0M: 2, MultFDDM: 3 ,MultTracklets: 4,MultTPC: 5,MultNTracksPV: 6 ,MultNTracksPVeta1: 7,CentralityFT0C: 8 ,CentralityFT0M: 9, CentralityFV0A: 10"}; Configurable lowParam1{"lowParam1", 0.119297, "First parameter for low phi cut"}; Configurable lowParam2{"lowParam2", 0.000379693, "Second parameter for low phi cut"}; Configurable highParam1{"highParam1", 0.16685, "First parameter for high phi cut"}; Configurable highParam2{"highParam2", 0.00981942, "Second parameter for high phi cut"}; + Configurable armPodCut{"armPodCut", 5.0f, "pT * (cut) > |alpha|"}; // Histograms names static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; @@ -622,10 +640,10 @@ struct DedxPidAnalysis { // Event Counter by centrality registryDeDx.add("histCentrality", "Centrality", HistType::kTH1F, {centAxis}); - - // Tracks vs p - registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F, {{ptAxis}}); - registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F, {{ptAxis}}); + + // Tracks vs p + registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F,{{ ptAxis}}); + registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F,{{ ptAxis}}); // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); @@ -648,34 +666,43 @@ struct DedxPidAnalysis { xAll->SetBinLabel(NClTPCPIDCutPri, "NClTPCPIDCutPri"); xAll->SetBinLabel(NClTPCFoundCutPri, "NClTPCFoundCutPri"); - registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{24, 0.5, 24.5, ""}}); + registryDeDx.add("trackselSec", "track selected sec particles", HistType::kTH1F, {{34, 0.5, 34.5, ""}}); auto htrackSec = registryDeDx.get(HIST("trackselSec")); auto* xSec = htrackSec->GetXaxis(); xSec->SetBinLabel(AllSec, "AllSec"); - xSec->SetBinLabel(V0Type, "V0Type"); xSec->SetBinLabel(V0CosPA, "V0CosPA"); xSec->SetBinLabel(V0DecayRadius, "V0DecayRadius"); xSec->SetBinLabel(V0Daughters, "V0Daughters"); - xSec->SetBinLabel(TPCRefit, "TPCRefit"); xSec->SetBinLabel(PhiVarCutSec, "PhiVarCutSec"); xSec->SetBinLabel(NClTPCFoundCutSec, "NClTPCFoundCutSec"); xSec->SetBinLabel(NClTPCPIDCutSec, "NClTPCPIDCutSec"); xSec->SetBinLabel(AllK0s, "AllK0s"); + xSec->SetBinLabel(SingleTrackSelectionK0s, "SingleTrackSelectionK0s"); + xSec->SetBinLabel(V0TypeK0s, "V0TypeK0s"); + xSec->SetBinLabel( DCAtoVtxK0s, "DCAtoVtxK0s"); + xSec->SetBinLabel( Armenteros, "Armenteros"); xSec->SetBinLabel(V0RapidityK0s, "V0RapidityK0s"); xSec->SetBinLabel(V0ProperLifetimeK0s, "V0ProperLifetimeK0s"); xSec->SetBinLabel(MassCutK0s, "MassCutK0s"); xSec->SetBinLabel(AllLambda, "AllLambda"); + xSec->SetBinLabel(SingleTrackSelectionLambda, "SingleTrackSelectionLambda"); + xSec->SetBinLabel(V0TypeLambda, "V0TypeLambda"); + xSec->SetBinLabel( DCAtoVtxLambda, "DCAtoVtxLambda"); xSec->SetBinLabel(V0RapidityLambda, "V0RapidityLambda"); xSec->SetBinLabel(V0ProperLifetimeLambda, "V0ProperLifetimeLambda"); xSec->SetBinLabel(MassCutLambda, "MassCutLambda"); xSec->SetBinLabel(AllAntiLambda, "AllAntiLambda"); + xSec->SetBinLabel(SingleTrackSelectionAntiLambda, "SingleTrackSelectionAntiLambda"); + xSec->SetBinLabel(V0TypeAntiLambda, "V0TypeAntiLambda"); + xSec->SetBinLabel( DCAtoVtxAntiLambda, "DCAtoVtxAntiLambda"); xSec->SetBinLabel(V0RapidityAntiLambda, "V0RapidityAntiLambda"); xSec->SetBinLabel(V0ProperLifetimeAntiLambda, "V0ProperLifetimeAntiLambda"); xSec->SetBinLabel(MassCutAntiLambda, "MassCutAntiLambda"); xSec->SetBinLabel(AllGamma, "AllGamma"); + xSec->SetBinLabel(SingleTrackSelectionGamma, "SingleTrackSelectionGamma"); + xSec->SetBinLabel(V0TypeGamma, "V0TypeGamma"); xSec->SetBinLabel(V0RapidityGamma, "V0RapidityGamma"); xSec->SetBinLabel(MassCutGamma, "MassCutGamma"); - mySelectionPrim = myTrackSelection(); } @@ -684,12 +711,12 @@ struct DedxPidAnalysis { bool passedSingleTrackSelection(const T1& track, const C& /*collision*/) { // Single-Track Selections - if (!track.hasTPC()) - return false; + //if (!track.hasTPC()) + //return false; if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) return false; - if (track.tpcChi2NCl() > maxChi2TPC) - return false; + //if (track.tpcChi2NCl() > maxChi2TPC) + //return false; if (track.eta() < etaMin || track.eta() > etaMax) return false; @@ -727,12 +754,15 @@ struct DedxPidAnalysis { bool passedK0Selection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllK0s); // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; - double sigmap = 0.0; + /*double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -758,23 +788,37 @@ struct DedxPidAnalysis { return false; if (std::abs(sigman) > nsigmaTOFmax) return false; - } + }*/ if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllK0s); - - if (std::abs(v0.yK0Short()) > v0rapidityCut) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionK0s); + + if (v0.v0Type() != v0TypeSelection) //V0 type selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeK0s); + + if (std::fabs(v0.dcapostopv()) < dcaPionsFromK0s && std::fabs(v0.dcanegtopv()) < dcaPionsFromK0s ) //DCA selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxK0s); + + if (armPodCut * v0.qtarm() < std::abs(v0.alpha())) // Armenteros-Podolanski cut + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::Armenteros); + + if (std::abs(v0.yK0Short()) > v0rapidityCut) //Rapidity selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityK0s); float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassK0Short; - - if (properLifetime > v0ProperLifetimeCutK0s) + if (properLifetime > v0ProperLifetimeCutK0s) //Proper lifetime return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeK0s); - if (std::abs(v0.mK0Short() - MassK0Short) > invMassCutK0s) + if (std::abs(v0.mK0Short() - MassK0Short) > invMassCutK0s) //Invarian mass return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutK0s); @@ -787,13 +831,17 @@ struct DedxPidAnalysis { bool passedLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllLambda); // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; + - double sigmap = 0.0; + /*double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -819,26 +867,34 @@ struct DedxPidAnalysis { return false; if (std::abs(sigman) > nsigmaTOFmax) return false; - } + }*/ + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionLambda); + + if (v0.v0Type() != v0TypeSelection) //V0 type selection + return false; if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllLambda); - - if (std::abs(v0.yLambda()) > v0rapidityCut) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeLambda); + + if (std::fabs(v0.dcapostopv()) < dcaProtonsFromLambda && std::fabs(v0.dcanegtopv()) < dcaPionsFromLambda) //DCA selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxLambda); + + if (std::abs(v0.yLambda()) > v0rapidityCut) //Rapidity selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityLambda); float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; - - if (properLifetime > v0ProperLifetimeCutLambda) + if (properLifetime > v0ProperLifetimeCutLambda) //Proper lifetime return false; - if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeLambda); - if (std::abs(v0.mLambda() - MassLambda) > invMassCutLambda) { + if (std::abs(v0.mLambda() - MassLambda) > invMassCutLambda) //Invarian mass return false; - } if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutLambda); @@ -850,13 +906,15 @@ struct DedxPidAnalysis { bool passedAntiLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { - + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllAntiLambda); + // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; - double sigmap = 0.0; + /*double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -881,27 +939,35 @@ struct DedxPidAnalysis { return false; if (std::abs(sigman) > nsigmaTOFmax) return false; - } - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllAntiLambda); - - if (std::abs(v0.yLambda()) > v0rapidityCut) + }*/ + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionAntiLambda); + + // Select V0 type + if (v0.v0Type() != v0TypeSelection) //V0 type selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeAntiLambda); + + if (std::fabs(v0.dcapostopv()) < dcaPionsFromLambda && std::fabs(v0.dcanegtopv()) < dcaProtonsFromLambda) //DCA selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxAntiLambda); + + if (std::abs(v0.yLambda()) > v0rapidityCut) //Rapidity selection return false; - if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityAntiLambda); float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; - - if (properLifetime > v0ProperLifetimeCutLambda) + if (properLifetime > v0ProperLifetimeCutLambda) //Proper lifetime return false; - if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeAntiLambda); - if (std::abs(v0.mAntiLambda() - MassLambda) > invMassCutLambda) + if (std::abs(v0.mAntiLambda() - MassLambda) > invMassCutLambda) //Invarian mass return false; - if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutAntiLambda); @@ -913,13 +979,16 @@ struct DedxPidAnalysis { bool passedGammaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllGamma); + // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; - double sigmap = 0.0; + /*double sigmap = 0.0; double sigman = 0.0; if (v0SelectionMode == V0TPC) { @@ -945,23 +1014,25 @@ struct DedxPidAnalysis { return false; if (std::abs(sigman) > nsigmaTOFmax) return false; - } + }*/ const float gammaMass = 2 * MassElectron; // GeV/c^2 + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionGamma); - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllGamma); + if (v0.v0Type() != v0TypeSelectionGamma) //V0 type selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeGamma); const float yGamma = RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, MassGamma); - - if (std::abs(yGamma) > v0rapidityCut) + if (std::abs(yGamma) > v0rapidityCut) //Rapidity selection return false; - if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityGamma); - if (std::abs(v0.mGamma() - gammaMass) > invMassCutGamma) + if (std::abs(v0.mGamma() - gammaMass) > invMassCutGamma) //Invarian mass return false; - if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutGamma); @@ -1401,9 +1472,9 @@ struct DedxPidAnalysis { continue; registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); - // For pt + //For pt registryDeDx.fill(HIST("Tracks_vs_pT_all"), trk.pt()); - + // phi and Ncl cut if (phiVarCut) { if (!passedPhiCutPri(trk, magField, *fphiCutLow, *fphiCutHigh)) @@ -1430,7 +1501,7 @@ struct DedxPidAnalysis { } registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); - // For pt + cuts + //For pt + cuts registryDeDx.fill(HIST("Tracks_vs_pT_all_cuts"), trk.pt()); float signedP = trk.sign() * getMomentum(trk); @@ -1539,12 +1610,6 @@ struct DedxPidAnalysis { // Standard V0 Selections registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllSec); - // Select V0 type - if (v0.v0Type() != v0TypeSelection) - continue; - - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0Type); - if (!passedV0Selection(v0, collision)) { continue; } @@ -1553,12 +1618,12 @@ struct DedxPidAnalysis { const auto& posTrack = v0.posTrack_as(); const auto& negTrack = v0.negTrack_as(); - if (!posTrack.passedTPCRefit()) + /*if (!posTrack.passedTPCRefit()) continue; if (!negTrack.passedTPCRefit()) - continue; + continue;*/ - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::TPCRefit); + //registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::TPCRefit); // phi and Ncl cut if (phiVarCut) { if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) From 274189914be002bef1cc0cb0e6e6699b24d74e89 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 27 Feb 2026 17:53:21 -0600 Subject: [PATCH 18/24] Track cuts were modified --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 205 ++++++++++++------------- 1 file changed, 102 insertions(+), 103 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 2e56622c1a3..a8ff711af76 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -193,12 +193,12 @@ struct DedxPidAnalysis { "Maximum V0 Radius"}; Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, "Maximum DCA Daughters"}; - Configurable dcaProtonsFromLambda{"dcaProtonsFromLambda", 0.05f, - "Minimum DCA of protons to vtx for Lambda"}; - Configurable dcaPionsFromLambda{"dcaPionsFromLambda", 0.2f, - "Minimum DCA of pions to vtx for Lambda"}; - Configurable dcaPionsFromK0s{"dcaPionsFromK0s", 0.1f, - "Minimum DCA of pions to vtx for K0s"}; + Configurable dcaProtonsFromLambda{"dcaProtonsFromLambda", 0.05f, + "Minimum DCA of protons to vtx for Lambda"}; + Configurable dcaPionsFromLambda{"dcaPionsFromLambda", 0.2f, + "Minimum DCA of pions to vtx for Lambda"}; + Configurable dcaPionsFromK0s{"dcaPionsFromK0s", 0.1f, + "Minimum DCA of pions to vtx for K0s"}; Configurable v0rapidityCut{"v0rapidityCut", 0.5f, "V0 rapidity cut"}; Configurable v0ProperLifetimeCutK0s{"v0ProperLifetimeCutK0s", 20.f, "V0 proper lifetime cut for K0s"}; Configurable v0ProperLifetimeCutLambda{"v0ProperLifetimeCutLambda", 30.f, "V0 proper lifetime cut for Lambda"}; @@ -216,7 +216,7 @@ struct DedxPidAnalysis { Configurable v0SelectionMode{"v0SelectionMode", 3, "V0 Selection base on TPC: 1, TOF:2 ,Both:3"}; Configurable momentumMode{"momentumMode", 2, "1: TPC inner param, 2: Total momentum p"}; Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; - Configurable v0TypeSelectionGamma{"v0TypeSelectionGamma", 7, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable v0TypeSelectionGamma{"v0TypeSelectionGamma", 7, "select on a certain V0 type (leave negative if no selection desired)"}; Configurable multiplicityEstimator{"multiplicityEstimator", 9, "Flag to use a multiplicity estimator; No multiplicity: 0, MultFV0A: 1, MultFT0M: 2, MultFDDM: 3 ,MultTracklets: 4,MultTPC: 5,MultNTracksPV: 6 ,MultNTracksPVeta1: 7,CentralityFT0C: 8 ,CentralityFT0M: 9, CentralityFV0A: 10"}; Configurable lowParam1{"lowParam1", 0.119297, "First parameter for low phi cut"}; Configurable lowParam2{"lowParam2", 0.000379693, "Second parameter for low phi cut"}; @@ -640,10 +640,10 @@ struct DedxPidAnalysis { // Event Counter by centrality registryDeDx.add("histCentrality", "Centrality", HistType::kTH1F, {centAxis}); - - // Tracks vs p - registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F,{{ ptAxis}}); - registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F,{{ ptAxis}}); + + // Tracks vs p + registryDeDx.add("Tracks_vs_pT_all", "pT All", HistType::kTH1F, {{ptAxis}}); + registryDeDx.add("Tracks_vs_pT_all_cuts", "pT All + cuts", HistType::kTH1F, {{ptAxis}}); // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); @@ -677,24 +677,24 @@ struct DedxPidAnalysis { xSec->SetBinLabel(NClTPCFoundCutSec, "NClTPCFoundCutSec"); xSec->SetBinLabel(NClTPCPIDCutSec, "NClTPCPIDCutSec"); xSec->SetBinLabel(AllK0s, "AllK0s"); - xSec->SetBinLabel(SingleTrackSelectionK0s, "SingleTrackSelectionK0s"); - xSec->SetBinLabel(V0TypeK0s, "V0TypeK0s"); - xSec->SetBinLabel( DCAtoVtxK0s, "DCAtoVtxK0s"); - xSec->SetBinLabel( Armenteros, "Armenteros"); + xSec->SetBinLabel(SingleTrackSelectionK0s, "SingleTrackSelectionK0s"); + xSec->SetBinLabel(V0TypeK0s, "V0TypeK0s"); + xSec->SetBinLabel(DCAtoVtxK0s, "DCAtoVtxK0s"); + xSec->SetBinLabel(Armenteros, "Armenteros"); xSec->SetBinLabel(V0RapidityK0s, "V0RapidityK0s"); xSec->SetBinLabel(V0ProperLifetimeK0s, "V0ProperLifetimeK0s"); xSec->SetBinLabel(MassCutK0s, "MassCutK0s"); xSec->SetBinLabel(AllLambda, "AllLambda"); - xSec->SetBinLabel(SingleTrackSelectionLambda, "SingleTrackSelectionLambda"); - xSec->SetBinLabel(V0TypeLambda, "V0TypeLambda"); - xSec->SetBinLabel( DCAtoVtxLambda, "DCAtoVtxLambda"); + xSec->SetBinLabel(SingleTrackSelectionLambda, "SingleTrackSelectionLambda"); + xSec->SetBinLabel(V0TypeLambda, "V0TypeLambda"); + xSec->SetBinLabel(DCAtoVtxLambda, "DCAtoVtxLambda"); xSec->SetBinLabel(V0RapidityLambda, "V0RapidityLambda"); xSec->SetBinLabel(V0ProperLifetimeLambda, "V0ProperLifetimeLambda"); xSec->SetBinLabel(MassCutLambda, "MassCutLambda"); xSec->SetBinLabel(AllAntiLambda, "AllAntiLambda"); - xSec->SetBinLabel(SingleTrackSelectionAntiLambda, "SingleTrackSelectionAntiLambda"); - xSec->SetBinLabel(V0TypeAntiLambda, "V0TypeAntiLambda"); - xSec->SetBinLabel( DCAtoVtxAntiLambda, "DCAtoVtxAntiLambda"); + xSec->SetBinLabel(SingleTrackSelectionAntiLambda, "SingleTrackSelectionAntiLambda"); + xSec->SetBinLabel(V0TypeAntiLambda, "V0TypeAntiLambda"); + xSec->SetBinLabel(DCAtoVtxAntiLambda, "DCAtoVtxAntiLambda"); xSec->SetBinLabel(V0RapidityAntiLambda, "V0RapidityAntiLambda"); xSec->SetBinLabel(V0ProperLifetimeAntiLambda, "V0ProperLifetimeAntiLambda"); xSec->SetBinLabel(MassCutAntiLambda, "MassCutAntiLambda"); @@ -711,12 +711,12 @@ struct DedxPidAnalysis { bool passedSingleTrackSelection(const T1& track, const C& /*collision*/) { // Single-Track Selections - //if (!track.hasTPC()) - //return false; + // if (!track.hasTPC()) + // return false; if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) return false; - //if (track.tpcChi2NCl() > maxChi2TPC) - //return false; + // if (track.tpcChi2NCl() > maxChi2TPC) + // return false; if (track.eta() < etaMin || track.eta() > etaMax) return false; @@ -754,9 +754,9 @@ struct DedxPidAnalysis { bool passedK0Selection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { - + if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllK0s); + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllK0s); // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; @@ -792,33 +792,33 @@ struct DedxPidAnalysis { if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionK0s); - if (v0.v0Type() != v0TypeSelection) //V0 type selection - return false; - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeK0s); - - if (std::fabs(v0.dcapostopv()) < dcaPionsFromK0s && std::fabs(v0.dcanegtopv()) < dcaPionsFromK0s ) //DCA selection - return false; - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxK0s); - - if (armPodCut * v0.qtarm() < std::abs(v0.alpha())) // Armenteros-Podolanski cut - return false; - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::Armenteros); - - if (std::abs(v0.yK0Short()) > v0rapidityCut) //Rapidity selection + if (v0.v0Type() != v0TypeSelection) // V0 type selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeK0s); + + if (std::fabs(v0.dcapostopv()) < dcaPionsFromK0s && std::fabs(v0.dcanegtopv()) < dcaPionsFromK0s) // DCA selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxK0s); + + if (armPodCut * v0.qtarm() < std::abs(v0.alpha())) // Armenteros-Podolanski cut + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::Armenteros); + + if (std::abs(v0.yK0Short()) > v0rapidityCut) // Rapidity selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityK0s); float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassK0Short; - if (properLifetime > v0ProperLifetimeCutK0s) //Proper lifetime + if (properLifetime > v0ProperLifetimeCutK0s) // Proper lifetime return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeK0s); - if (std::abs(v0.mK0Short() - MassK0Short) > invMassCutK0s) //Invarian mass + if (std::abs(v0.mK0Short() - MassK0Short) > invMassCutK0s) // Invarian mass return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutK0s); @@ -831,15 +831,14 @@ struct DedxPidAnalysis { bool passedLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { - - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllLambda); + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllLambda); // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; if (!passedSingleTrackSelection(ntrack, collision)) return false; - /*double sigmap = 0.0; double sigman = 0.0; @@ -868,32 +867,32 @@ struct DedxPidAnalysis { if (std::abs(sigman) > nsigmaTOFmax) return false; }*/ - - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionLambda); - - if (v0.v0Type() != v0TypeSelection) //V0 type selection - return false; + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionLambda); + + if (v0.v0Type() != v0TypeSelection) // V0 type selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeLambda); + + if (std::fabs(v0.dcapostopv()) < dcaProtonsFromLambda && std::fabs(v0.dcanegtopv()) < dcaPionsFromLambda) // DCA selection + return false; if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeLambda); - - if (std::fabs(v0.dcapostopv()) < dcaProtonsFromLambda && std::fabs(v0.dcanegtopv()) < dcaPionsFromLambda) //DCA selection - return false; - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxLambda); - - if (std::abs(v0.yLambda()) > v0rapidityCut) //Rapidity selection + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxLambda); + + if (std::abs(v0.yLambda()) > v0rapidityCut) // Rapidity selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityLambda); float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; - if (properLifetime > v0ProperLifetimeCutLambda) //Proper lifetime + if (properLifetime > v0ProperLifetimeCutLambda) // Proper lifetime return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeLambda); - if (std::abs(v0.mLambda() - MassLambda) > invMassCutLambda) //Invarian mass + if (std::abs(v0.mLambda() - MassLambda) > invMassCutLambda) // Invarian mass return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutLambda); @@ -906,9 +905,9 @@ struct DedxPidAnalysis { bool passedAntiLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllAntiLambda); - + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllAntiLambda); + // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; @@ -940,33 +939,33 @@ struct DedxPidAnalysis { if (std::abs(sigman) > nsigmaTOFmax) return false; }*/ - - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionAntiLambda); - - // Select V0 type - if (v0.v0Type() != v0TypeSelection) //V0 type selection - return false; - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeAntiLambda); - - if (std::fabs(v0.dcapostopv()) < dcaPionsFromLambda && std::fabs(v0.dcanegtopv()) < dcaProtonsFromLambda) //DCA selection - return false; - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxAntiLambda); - - if (std::abs(v0.yLambda()) > v0rapidityCut) //Rapidity selection + + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionAntiLambda); + + // Select V0 type + if (v0.v0Type() != v0TypeSelection) // V0 type selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeAntiLambda); + + if (std::fabs(v0.dcapostopv()) < dcaPionsFromLambda && std::fabs(v0.dcanegtopv()) < dcaProtonsFromLambda) // DCA selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxAntiLambda); + + if (std::abs(v0.yLambda()) > v0rapidityCut) // Rapidity selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityAntiLambda); float properLifetime = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda; - if (properLifetime > v0ProperLifetimeCutLambda) //Proper lifetime + if (properLifetime > v0ProperLifetimeCutLambda) // Proper lifetime return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0ProperLifetimeAntiLambda); - if (std::abs(v0.mAntiLambda() - MassLambda) > invMassCutLambda) //Invarian mass + if (std::abs(v0.mAntiLambda() - MassLambda) > invMassCutLambda) // Invarian mass return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutAntiLambda); @@ -979,9 +978,9 @@ struct DedxPidAnalysis { bool passedGammaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllGamma); - + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::AllGamma); + // Single-Track Selections if (!passedSingleTrackSelection(ptrack, collision)) return false; @@ -1016,22 +1015,22 @@ struct DedxPidAnalysis { return false; }*/ const float gammaMass = 2 * MassElectron; // GeV/c^2 - - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionGamma); - if (v0.v0Type() != v0TypeSelectionGamma) //V0 type selection - return false; - if (fillHist) - registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeGamma); + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::SingleTrackSelectionGamma); + + if (v0.v0Type() != v0TypeSelectionGamma) // V0 type selection + return false; + if (fillHist) + registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeGamma); const float yGamma = RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, MassGamma); - if (std::abs(yGamma) > v0rapidityCut) //Rapidity selection + if (std::abs(yGamma) > v0rapidityCut) // Rapidity selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0RapidityGamma); - if (std::abs(v0.mGamma() - gammaMass) > invMassCutGamma) //Invarian mass + if (std::abs(v0.mGamma() - gammaMass) > invMassCutGamma) // Invarian mass return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::MassCutGamma); @@ -1472,9 +1471,9 @@ struct DedxPidAnalysis { continue; registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::SelectionPrim); - //For pt + // For pt registryDeDx.fill(HIST("Tracks_vs_pT_all"), trk.pt()); - + // phi and Ncl cut if (phiVarCut) { if (!passedPhiCutPri(trk, magField, *fphiCutLow, *fphiCutHigh)) @@ -1501,7 +1500,7 @@ struct DedxPidAnalysis { } registryDeDx.fill(HIST("heta_vs_NclFound_TPC_After_Primary"), trk.eta(), trk.tpcNClsFound()); - //For pt + cuts + // For pt + cuts registryDeDx.fill(HIST("Tracks_vs_pT_all_cuts"), trk.pt()); float signedP = trk.sign() * getMomentum(trk); @@ -1623,8 +1622,8 @@ struct DedxPidAnalysis { if (!negTrack.passedTPCRefit()) continue;*/ - //registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::TPCRefit); - // phi and Ncl cut + // registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::TPCRefit); + // phi and Ncl cut if (phiVarCut) { if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) continue; From aa4f230190522bd8a656b08ad82fce2356e2898d Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Tue, 3 Mar 2026 01:12:47 -0600 Subject: [PATCH 19/24] Correct logical condition in DCA to PV cuts --- PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index a8ff711af76..0966ad1a97d 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -797,7 +797,9 @@ struct DedxPidAnalysis { if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeK0s); - if (std::fabs(v0.dcapostopv()) < dcaPionsFromK0s && std::fabs(v0.dcanegtopv()) < dcaPionsFromK0s) // DCA selection + if (std::fabs(v0.dcapostopv()) < dcaPionsFromK0s) // DCA selection + return false; + if (std::fabs(v0.dcanegtopv()) < dcaPionsFromK0s) // DCA selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxK0s); @@ -876,7 +878,9 @@ struct DedxPidAnalysis { if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeLambda); - if (std::fabs(v0.dcapostopv()) < dcaProtonsFromLambda && std::fabs(v0.dcanegtopv()) < dcaPionsFromLambda) // DCA selection + if (std::fabs(v0.dcapostopv()) < dcaProtonsFromLambda) // DCA selection + return false; + if (std::fabs(v0.dcanegtopv()) < dcaPionsFromLambda) // DCA selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxLambda); @@ -949,7 +953,9 @@ struct DedxPidAnalysis { if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::V0TypeAntiLambda); - if (std::fabs(v0.dcapostopv()) < dcaPionsFromLambda && std::fabs(v0.dcanegtopv()) < dcaProtonsFromLambda) // DCA selection + if (std::fabs(v0.dcapostopv()) < dcaPionsFromLambda) // DCA selection + return false; + if (std::fabs(v0.dcanegtopv()) < dcaProtonsFromLambda) // DCA selection return false; if (fillHist) registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::DCAtoVtxAntiLambda); From 86276a3150d3987c5274d1c2cfbc680874fc2476 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Wed, 25 Mar 2026 14:00:00 -0600 Subject: [PATCH 20/24] Rename to multiplicityPt.cxx and update implementation --- PWGLF/Tasks/Nuspex/CMakeLists.txt | 2 +- PWGLF/Tasks/Nuspex/MultiplicityPt.cxx | 1481 ------------------------- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 1129 +++++++++++++++++++ 3 files changed, 1130 insertions(+), 1482 deletions(-) delete mode 100644 PWGLF/Tasks/Nuspex/MultiplicityPt.cxx create mode 100644 PWGLF/Tasks/Nuspex/multiplicityPt.cxx diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index 8cc49c394a4..ccf311b37c0 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -181,7 +181,7 @@ o2physics_add_dpl_workflow(chargedparticle-raa COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(multiplicity-pt - SOURCES MultiplicityPt.cxx + SOURCES multiplicityPt.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/Nuspex/MultiplicityPt.cxx b/PWGLF/Tasks/Nuspex/MultiplicityPt.cxx deleted file mode 100644 index 6d30693af1b..00000000000 --- a/PWGLF/Tasks/Nuspex/MultiplicityPt.cxx +++ /dev/null @@ -1,1481 +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. - -#include "PWGLF/DataModel/LFParticleIdentification.h" -#include "PWGLF/DataModel/spectraTOF.h" -#include "PWGLF/Utils/inelGt.h" - -#include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/McCollisionExtra.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/Logger.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/StaticFor.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "TPDGCode.h" -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using BCsRun3 = soa::Join; - -struct MultiplicityPt { - - // Service - Service pdg; - - // Add CCDB service for magnetic field - Service ccdb; - - Configurable isRun3{"isRun3", true, "is Run3 dataset"}; - Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; - Configurable cfgINELCut{"cfgINELCut", 0, "INEL event selection: 0 no sel, 1 INEL>0, 2 INEL>1"}; - Configurable askForCustomTVX{"askForCustomTVX", false, "Ask for custom TVX rather than sel8"}; - Configurable removeITSROFrameBorder{"removeITSROFrameBorder", false, "Remove ITS Read-Out Frame border"}; - Configurable removeNoSameBunchPileup{"removeNoSameBunchPileup", false, "Remove no same bunch pileup"}; - Configurable requireIsGoodZvtxFT0vsPV{"requireIsGoodZvtxFT0vsPV", false, "Require good Z vertex FT0 vs PV"}; - Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "Require vertex ITSTPC"}; - Configurable removeNoTimeFrameBorder{"removeNoTimeFrameBorder", false, "Remove no time frame border"}; - Configurable cfgCutEtaMax{"cfgCutEtaMax", 0.8f, "Max eta range for tracks"}; - Configurable cfgCutEtaMin{"cfgCutEtaMin", -0.8f, "Min eta range for tracks"}; - Configurable cfgCutY{"cfgCutY", 0.5f, "Y range for tracks"}; - Configurable cfgCutNsigma{"cfgCutNsigma", 3.0f, "nsigma cut range for tracks"}; - Configurable lastRequiredTrdCluster{"lastRequiredTrdCluster", -1, "Last cluster to require in TRD"}; - Configurable requireTrdOnly{"requireTrdOnly", false, "Require only tracks from TRD"}; - Configurable requireNoTrd{"requireNoTrd", false, "Require tracks without TRD"}; - Configurable multiplicityEstimator{"multiplicityEstimator", 6, - "Multiplicity estimator: 0=NoMult, 1=MultFV0M, 2=MultFT0M, 3=MultFDDM, 4=MultTracklets, 5=MultTPC, 6=MultNTracksPV, 7=MultNTracksPVeta1, 8=CentFT0C, 9=CentFT0M, 10=CentFV0A"}; - - // Analysis switches - Configurable enableDCAHistograms{"enableDCAHistograms", false, "Enable DCA histograms"}; - Configurable enablePIDHistograms{"enablePIDHistograms", true, "Enable PID histograms"}; - Configurable useCustomTrackCuts{"useCustomTrackCuts", true, "Flag to use custom track cuts"}; - Configurable itsPattern{"itsPattern", 0, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"}; - Configurable requireITS{"requireITS", true, "Additional cut on the ITS requirement"}; - Configurable requireTPC{"requireTPC", true, "Additional cut on the TPC requirement"}; - Configurable requireGoldenChi2{"requireGoldenChi2", true, "Additional cut on the GoldenChi2"}; - Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.f, "Additional cut on the minimum number of crossed rows in the TPC"}; - Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; - Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 4.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; - Configurable minChi2PerClusterTPC{"minChi2PerClusterTPC", 0.5f, "Additional cut on the minimum value of the chi2 per cluster in the TPC"}; - Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; - Configurable maxDcaXYFactor{"maxDcaXYFactor", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; - Configurable maxDcaZ{"maxDcaZ", 0.1f, "Additional cut on the maximum value of the DCA z"}; - Configurable minTPCNClsFound{"minTPCNClsFound", 70.f, "Additional cut on the minimum value of the number of found clusters in the TPC"}; - Configurable min_ITS_nClusters{"min_ITS_nClusters", 5, "minimum number of found ITS clusters"}; - - // Phi cut parameters - Configurable applyPhiCut{"applyPhiCut", true, "Apply phi sector cut to remove problematic TPC regions"}; - Configurable pTthresholdPhiCut{"pTthresholdPhiCut", 2.0f, "pT threshold above which to apply phi cut"}; - Configurable phiCutLowParam1{"phiCutLowParam1", 0.119297, "First parameter for low phi cut"}; - Configurable phiCutLowParam2{"phiCutLowParam2", 0.000379693, "Second parameter for low phi cut"}; - Configurable phiCutHighParam1{"phiCutHighParam1", 0.16685, "First parameter for high phi cut"}; - Configurable phiCutHighParam2{"phiCutHighParam2", 0.00981942, "Second parameter for high phi cut"}; - - // Basic track cuts - Configurable cfgTrkEtaCut{"cfgTrkEtaCut", 0.8f, "Eta range for tracks"}; - Configurable cfgTrkLowPtCut{"cfgTrkLowPtCut", 0.15f, "Minimum constituent pT"}; - - // Custom track cuts matching spectraTOF - TrackSelection customTrackCuts; - - // TF1 pointers for phi cuts - TF1* fphiCutLow = nullptr; - TF1* fphiCutHigh = nullptr; - - // Histogram Registry - HistogramRegistry ue; - - // ======================================================================== - // CENTRALITY/MULTIPLICITY CLASSES - Using same bins as before for consistency - // ======================================================================== - static constexpr int kCentralityClasses = 10; - static constexpr double CentClasses[kCentralityClasses + 1] = {0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; - - // Multiplicity percentile boundaries (computed on first pass) - std::vector multPercentileboundaries; - bool percentilesComputed = false; - - // Storage for multiplicity distribution (for percentile calculation) - std::vector multiplicityValues; - - // Table definitions - NO McCentFT0Ms dependency - using CollisionTableData = soa::Join; - using CollisionTableMC = soa::Join; - - // Track tables - TPC PID only - using TrackTableData = soa::Join; - using TrackTableMC = soa::Join; - - // MC tables - NO McCentFT0Ms - using CollisionTableMCTrue = aod::McCollisions; - using ParticleTableMC = aod::McParticles; - - // Preslice for MC particles - Preslice perMCCol = aod::mcparticle::mcCollisionId; - - // Multiplicity estimator enum - enum MultCodes : int { - kNoMultiplicity = 0, - kMultFV0M = 1, - kMultFT0M = 2, - kMultFDDM = 3, - kMultTracklets = 4, - kMultTPC = 5, - kMultNTracksPV = 6, - kMultNTracksPVeta1 = 7, - kCentralityFT0C = 8, - kCentralityFT0M = 9, - kCentralityFV0A = 10 - }; - - // Particle species enum - enum ParticleSpecies : int { - kPion = 0, - kKaon = 1, - kProton = 2, - kNSpecies = 3 - }; - - // PDG codes - static constexpr int PDGPion = 211; - static constexpr int PDGKaon = 321; - static constexpr int PDGProton = 2212; - - void processData(CollisionTableData::iterator const& collision, - TrackTableData const& tracks, - BCsRun3 const& bcs); - PROCESS_SWITCH(MultiplicityPt, processData, "process data", false); - - // MC processing - First pass to build percentiles - void processPercentileCalibration(CollisionTableMCTrue const& mcCollisions, - ParticleTableMC const& particles); - PROCESS_SWITCH(MultiplicityPt, processPercentileCalibration, "Build multiplicity percentile calibration (run first)", false); - - // MC processing - Main analysis - void processMC(TrackTableMC const& tracks, - aod::McParticles const& particles, - CollisionTableMCTrue const& mcCollisions, - CollisionTableMC const& collisions, - BCsRun3 const& bcs); - PROCESS_SWITCH(MultiplicityPt, processMC, "process MC", true); - - // True MC processing - void processTrue(CollisionTableMCTrue const& mcCollisions, - ParticleTableMC const& particles); - PROCESS_SWITCH(MultiplicityPt, processTrue, "process true MC", true); - - // ======================================================================== - // MULTIPLICITY GETTER FUNCTIONS - Using raw charged particle count - // ======================================================================== - - // Count charged primaries in |eta| < 1.0 - template - int countChargedPrimaries(const MCCollisionType& mcCollision, const ParticleTableMC& particles) const - { - int nCharged = 0; - auto particlesInColl = particles.sliceBy(perMCCol, mcCollision.globalIndex()); - for (const auto& p : particlesInColl) { - if (!p.isPhysicalPrimary()) - continue; - auto pdgParticle = pdg->GetParticle(p.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - continue; - if (std::abs(p.eta()) < 1.0) - nCharged++; - } - return nCharged; - } - - // For reconstructed collisions - template - float getMultiplicity(const CollisionType& collision) const - { - switch (multiplicityEstimator.value) { - case kNoMultiplicity: - return 50.f; - case kMultFV0M: - return collision.multZeqFV0A(); - case kMultFT0M: - return collision.multZeqFT0A() + collision.multZeqFT0C(); - case kMultFDDM: - return collision.multZeqFDDA() + collision.multZeqFDDC(); - case kMultTracklets: - return 0.f; - case kMultTPC: - return collision.multTPC(); - case kMultNTracksPV: - return collision.multZeqNTracksPV(); - case kMultNTracksPVeta1: - return collision.multNTracksPVeta1(); - case kCentralityFT0C: - case kCentralityFT0M: - case kCentralityFV0A: - return collision.multZeqNTracksPV(); - default: - return 0.f; - } - } - - // For MC collisions - returns RAW multiplicity - template - float getMultiplicityMC(const MCCollisionType& mcCollision, const ParticleTableMC& particles) const - { - return static_cast(countChargedPrimaries(mcCollision, particles)); - } - - // Convert raw multiplicity to percentile - float multiplicityToPercentile(float rawMult) const - { - if (!percentilesComputed || multPercentileboundaries.empty()) { - // If percentiles not computed, return raw multiplicity - return rawMult; - } - - // Find which percentile bin this multiplicity falls into - for (size_t i = 0; i < multPercentileboundaries.size() - 1; ++i) { - if (rawMult >= multPercentileboundaries[i] && rawMult < multPercentileboundaries[i + 1]) { - // Return the CENTER of the percentile bin - return CentClasses[i] + (CentClasses[i + 1] - CentClasses[i]) / 2.0; - } - } - - // Handle edge cases - if (rawMult < multPercentileboundaries[0]) { - return CentClasses[0]; - } - return CentClasses[kCentralityClasses]; - } - - // Get centrality class index from raw multiplicity - int getCentralityClass(float rawMult) const - { - if (!percentilesComputed || multPercentileboundaries.empty()) { - // Fallback: divide into equal bins - float maxMult = 150.0f; // Assumed maximum - int bin = static_cast((rawMult / maxMult) * kCentralityClasses); - return std::min(bin, kCentralityClasses - 1); - } - - // Use computed percentiles - for (int i = 0; i < kCentralityClasses; ++i) { - if (rawMult >= multPercentileboundaries[i] && rawMult < multPercentileboundaries[i + 1]) { - return i; - } - } - - // Outside range - if (rawMult < multPercentileboundaries[0]) - return 0; - return kCentralityClasses - 1; - } - - // ======================================================================== - // COMPUTE PERCENTILE BOUNDARIES - // ======================================================================== - void computePercentileBoundaries() - { - if (multiplicityValues.empty()) { - LOG(warning) << "No multiplicity values to compute percentiles from!"; - return; - } - - // Sort multiplicity values - std::sort(multiplicityValues.begin(), multiplicityValues.end()); - - LOG(info) << "Computing percentile boundaries from " << multiplicityValues.size() << " events"; - - // Compute percentile boundaries - multPercentileboundaries.clear(); - multPercentileboundaries.reserve(kCentralityClasses + 1); - - for (int i = 0; i <= kCentralityClasses; ++i) { - float percentile = CentClasses[i]; - size_t index = static_cast(percentile / 100.0 * multiplicityValues.size()); - if (index >= multiplicityValues.size()) { - index = multiplicityValues.size() - 1; - } - float boundary = multiplicityValues[index]; - multPercentileboundaries.push_back(boundary); - LOG(info) << "Percentile " << percentile << "% -> Multiplicity >= " << boundary; - } - - percentilesComputed = true; - - LOG(info) << "=== Percentile Boundaries Computed ==="; - for (int i = 0; i < kCentralityClasses; ++i) { - LOG(info) << "Class " << i << ": [" << CentClasses[i] << "%-" << CentClasses[i + 1] - << "%] = Mult [" << multPercentileboundaries[i] << "-" << multPercentileboundaries[i + 1] << ")"; - } - } - - // ======================================================================== - // MAGNETIC FIELD FUNCTION - // ======================================================================== - int getMagneticField(uint64_t timestamp) - { - static o2::parameters::GRPMagField* grpo = nullptr; - if (grpo == nullptr) { - grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); - if (grpo == nullptr) { - LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); - return 0; - } - LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); - } - return grpo->getNominalL3Field(); - } - - // ======================================================================== - // PHI CUT FUNCTION - // ======================================================================== - template - bool passedPhiCut(const TrackType& track, float magField) const - { - if (!applyPhiCut.value) { - return true; - } - - if (track.pt() < pTthresholdPhiCut.value) { - return true; - } - - float pt = track.pt(); - float phi = track.phi(); - int charge = track.sign(); - - if (magField < 0) { - phi = o2::constants::math::TwoPI - phi; - } - if (charge < 0) { - phi = o2::constants::math::TwoPI - phi; - } - - phi += o2::constants::math::PI / 18.0f; - phi = std::fmod(phi, o2::constants::math::PI / 9.0f); - - if (phi < fphiCutHigh->Eval(pt) && phi > fphiCutLow->Eval(pt)) { - return false; - } - - return true; - } - - float getTransformedPhi(const float phi, const int charge, const float magField) const - { - float transformedPhi = phi; - if (magField < 0) { - transformedPhi = o2::constants::math::TwoPI - transformedPhi; - } - if (charge < 0) { - transformedPhi = o2::constants::math::TwoPI - transformedPhi; - } - transformedPhi += o2::constants::math::PI / 18.0f; - transformedPhi = std::fmod(transformedPhi, o2::constants::math::PI / 9.0f); - return transformedPhi; - } - - // ======================================================================== - // TRACK SELECTION FUNCTIONS - // ======================================================================== - - template - bool passesCutWoDCA(TrackType const& track) const - { - if (useCustomTrackCuts.value) { - for (int i = 0; i < static_cast(TrackSelection::TrackCuts::kNCuts); i++) { - if (i == static_cast(TrackSelection::TrackCuts::kDCAxy) || - i == static_cast(TrackSelection::TrackCuts::kDCAz)) { - continue; - } - if (!customTrackCuts.IsSelected(track, static_cast(i))) { - return false; - } - } - return true; - } - return track.isGlobalTrackWoDCA(); - } - - template - bool passesDCAxyCut(TrackType const& track) const - { - if (useCustomTrackCuts.value) { - if (!passesCutWoDCA(track)) { - return false; - } - constexpr float dcaXYConst = 0.0105f; - constexpr float dcaXYPtScale = 0.0350f; - constexpr float dcaXYPtPower = 1.1f; - const float maxDcaXY = maxDcaXYFactor.value * (dcaXYConst + dcaXYPtScale / std::pow(track.pt(), dcaXYPtPower)); - if (std::abs(track.dcaXY()) > maxDcaXY) { - return false; - } - return true; - } - return track.isGlobalTrack(); - } - - template - bool passesTrackSelection(TrackType const& track, float magField = 0) const - { - if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) - return false; - - if (track.tpcChi2NCl() < minChi2PerClusterTPC.value || track.tpcChi2NCl() > maxChi2PerClusterTPC.value) - return false; - - if (!passesCutWoDCA(track)) - return false; - - if (applyPhiCut.value && !passedPhiCut(track, magField)) - return false; - - return passesDCAxyCut(track); - } - - // ======================================================================== - // PID SELECTION FUNCTIONS - // ======================================================================== - - template - bool passesPIDSelection(TrackType const& track) const - { - float nsigmaTPC = 0.f; - - if constexpr (species == kPion) { - nsigmaTPC = track.tpcNSigmaPi(); - } else if constexpr (species == kKaon) { - nsigmaTPC = track.tpcNSigmaKa(); - } else if constexpr (species == kProton) { - nsigmaTPC = track.tpcNSigmaPr(); - } - - return (std::abs(nsigmaTPC) < cfgCutNsigma.value); - } - - template - int getBestPIDHypothesis(TrackType const& track) const - { - float nsigmaPi = std::abs(track.tpcNSigmaPi()); - float nsigmaKa = std::abs(track.tpcNSigmaKa()); - float nsigmaPr = std::abs(track.tpcNSigmaPr()); - - constexpr float largeNSigmaValue = 999.0f; - float minNSigma = largeNSigmaValue; - int bestSpecies = -1; - - if (nsigmaPi < cfgCutNsigma.value && nsigmaPi < minNSigma) { - minNSigma = nsigmaPi; - bestSpecies = kPion; - } - if (nsigmaKa < cfgCutNsigma.value && nsigmaKa < minNSigma) { - minNSigma = nsigmaKa; - bestSpecies = kKaon; - } - if (nsigmaPr < cfgCutNsigma.value && nsigmaPr < minNSigma) { - minNSigma = nsigmaPr; - bestSpecies = kProton; - } - - return bestSpecies; - } - - // ======================================================================== - // EVENT SELECTION FUNCTION - // ======================================================================== - - template - bool isEventSelected(CollisionType const& collision) - { - if constexpr (fillHistograms) { - ue.fill(HIST("evsel"), 1.f); - if (collision.isInelGt0()) - ue.fill(HIST("evsel"), 2.f); - if (collision.isInelGt1()) - ue.fill(HIST("evsel"), 3.f); - } - - if (askForCustomTVX.value) { - if (!collision.selection_bit(aod::evsel::kIsTriggerTVX)) - return false; - } else { - if (!collision.sel8()) - return false; - } - - if constexpr (fillHistograms) - ue.fill(HIST("evsel"), 4.f); - - if (removeITSROFrameBorder.value && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) - return false; - if constexpr (fillHistograms) - ue.fill(HIST("evsel"), 5.f); - - if (removeNoSameBunchPileup.value && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) - return false; - if constexpr (fillHistograms) - ue.fill(HIST("evsel"), 6.f); - - if (requireIsGoodZvtxFT0vsPV.value && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) - return false; - if constexpr (fillHistograms) - ue.fill(HIST("evsel"), 7.f); - - if (requireIsVertexITSTPC.value && !collision.selection_bit(aod::evsel::kIsVertexITSTPC)) - return false; - if constexpr (fillHistograms) - ue.fill(HIST("evsel"), 8.f); - - if (removeNoTimeFrameBorder.value && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) - return false; - if constexpr (fillHistograms) - ue.fill(HIST("evsel"), 9.f); - - if (std::abs(collision.posZ()) > cfgCutVertex.value) - return false; - - if constexpr (fillHistograms) { - ue.fill(HIST("evsel"), 13.f); - if (collision.isInelGt0()) - ue.fill(HIST("evsel"), 14.f); - if (collision.isInelGt1()) - ue.fill(HIST("evsel"), 15.f); - } - - if (cfgINELCut.value == 1 && !collision.isInelGt0()) - return false; - if (cfgINELCut.value == 2 && !collision.isInelGt1()) - return false; - - return true; - } - - // ======================================================================== - // PRIMARY SELECTION - // ======================================================================== - - template - bool isGoodPrimary(ParticleType const& particle) const - { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - return false; - - if (!particle.isPhysicalPrimary()) - return false; - - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) - return false; - if (particle.pt() < cfgTrkLowPtCut.value) - return false; - - if (std::abs(particle.y()) > cfgCutY.value) - return false; - - return true; - } - - template - bool isGoodPrimarySpecies(ParticleType const& particle) const - { - int pdgCode = std::abs(particle.pdgCode()); - int expectedPDG = 0; - - if constexpr (species == kPion) - expectedPDG = PDGPion; - else if constexpr (species == kKaon) - expectedPDG = PDGKaon; - else if constexpr (species == kProton) - expectedPDG = PDGProton; - - if (pdgCode != expectedPDG) - return false; - - return isGoodPrimary(particle); - } - - void init(InitContext const&); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} - -void MultiplicityPt::init(InitContext const&) -{ - // ======================================================================== - // CUSTOM TRACK CUTS INITIALIZATION - // ======================================================================== - - if (useCustomTrackCuts.value) { - LOG(info) << "Using custom track cuts matching spectraTOF approach"; - customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); - - customTrackCuts.SetRequireITSRefit(requireITS.value); - customTrackCuts.SetRequireTPCRefit(requireTPC.value); - customTrackCuts.SetMinNClustersITS(min_ITS_nClusters.value); - customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); - customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); - customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); - customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); - customTrackCuts.SetMinNClustersTPC(minTPCNClsFound.value); - customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); - customTrackCuts.SetMaxDcaXYPtDep([](float /*pt*/) { return 10000.f; }); - customTrackCuts.SetMaxDcaZ(maxDcaZ.value); - - customTrackCuts.print(); - } - - // ======================================================================== - // PHI CUT INITIALIZATION - // ======================================================================== - - if (applyPhiCut.value) { - fphiCutLow = new TF1("StandardPhiCutLow", - Form("%f/x/x+pi/18.0-%f", - phiCutLowParam1.value, phiCutLowParam2.value), - 0, 50); - fphiCutHigh = new TF1("StandardPhiCutHigh", - Form("%f/x+pi/18.0+%f", - phiCutHighParam1.value, phiCutHighParam2.value), - 0, 50); - - LOGF(info, "=== Phi Cut Parameters ==="); - LOGF(info, "Low cut: %.6f/x² + pi/18 - %.6f", - phiCutLowParam1.value, phiCutLowParam2.value); - LOGF(info, "High cut: %.6f/x + pi/18 + %.6f", - phiCutHighParam1.value, phiCutHighParam2.value); - LOGF(info, "Applied for pT > %.1f GeV/c", pTthresholdPhiCut.value); - } - - // ======================================================================== - // AXIS DEFINITIONS - // ======================================================================== - - ConfigurableAxis ptBinning{ - "ptBinning", - {0.0, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, - 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, - 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.2, 2.4, 2.6, 2.8, - 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, - 12.0, 14.0, 16.0, 18.0, 20.0, 25.0, 30.0, 40.0, 50.0}, - "pT bin limits"}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - - // Multiplicity axis - initially raw multiplicity, will represent percentiles after calibration - std::vector centBins(CentClasses, CentClasses + kCentralityClasses + 1); - AxisSpec multAxis = {centBins, "Centrality/Multiplicity Class (%)"}; - - // Raw multiplicity axis for calibration - AxisSpec rawMultAxis = {150, 0, 150, "N_{ch} (|#eta| < 1.0)"}; - - // ======================================================================== - // HISTOGRAM REGISTRY - // ======================================================================== - - // Multiplicity distribution for percentile calibration - ue.add("Calibration/hRawMultiplicity", "Raw multiplicity distribution;N_{ch};Events", - HistType::kTH1D, {rawMultAxis}); - - // Event counting - ue.add("MC/GenRecoCollisions", "Generated and Reconstructed MC Collisions", HistType::kTH1D, {{10, 0.5, 10.5}}); - auto hColl = ue.get(HIST("MC/GenRecoCollisions")); - hColl->GetXaxis()->SetBinLabel(1, "Collisions generated"); - hColl->GetXaxis()->SetBinLabel(2, "Collisions reconstructed"); - - // Event loss histograms - ue.add("MC/EventLoss/MultGenerated", "Generated events vs multiplicity", - HistType::kTH1D, {multAxis}); - ue.add("MC/EventLoss/MultBadVertex", "Events with bad vertex vs multiplicity", - HistType::kTH1D, {multAxis}); - ue.add("MC/EventLoss/MultPhysicsSelected", "Physics-selected events vs multiplicity", - HistType::kTH1D, {multAxis}); - ue.add("MC/EventLoss/MultReconstructed", "Reconstructed events vs multiplicity", - HistType::kTH1D, {multAxis}); - ue.add("MC/EventLoss/MultRecoSelected", "Reconstructed+selected events vs multiplicity", - HistType::kTH1D, {multAxis}); - - ue.add("hEventLossBreakdown", "Event loss breakdown", HistType::kTH1D, {{4, 0.5, 4.5}}); - auto hLoss = ue.get(HIST("hEventLossBreakdown")); - hLoss->GetXaxis()->SetBinLabel(1, "Physics selected"); - hLoss->GetXaxis()->SetBinLabel(2, "Reconstructed"); - hLoss->GetXaxis()->SetBinLabel(3, "Selected"); - hLoss->GetXaxis()->SetBinLabel(4, "Final efficiency"); - - // ======================================================================== - // INCLUSIVE CHARGED PARTICLE HISTOGRAMS - // ======================================================================== - - ue.add("Inclusive/hPtPrimGenAll", "All generated primaries (no cuts);#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimGenAllVsMult", "All generated primaries vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtPrimBadVertex", "Generated primaries (bad vertex);#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimBadVertexVsMult", "Generated primaries (bad vertex) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtPrimGen", "Generated primaries (after physics selection);#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimGenVsMult", "Generated primaries (after phys sel) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtPrimRecoEv", "Generated primaries (reco events);#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimRecoEvVsMult", "Generated primaries (reco events) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtPrimGoodEv", "Generated primaries (good events);#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimGoodEvVsMult", "Generated primaries (good events) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtNumEff", "Tracking efficiency numerator;#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtNumEffVsMult", "Tracking efficiency numerator vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtDenEff", "Tracking efficiency denominator;#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtDenEffVsMult", "Tracking efficiency denominator vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtAllReco", "All reconstructed tracks;#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtAllRecoVsMult", "All reconstructed tracks vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtPrimReco", "Reconstructed primaries;#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimRecoVsMult", "Reconstructed primaries vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtSecReco", "Reconstructed secondaries;#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtSecRecoVsMult", "Reconstructed secondaries vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add("Inclusive/hPtMeasured", "All measured tracks;#it{p}_{T} (GeV/#it{c});Counts", - HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtMeasuredVsMult", "All measured tracks vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%)", - HistType::kTH2D, {ptAxis, multAxis}); - - // ======================================================================== - // PARTICLE-SPECIFIC HISTOGRAMS - // ======================================================================== - - const std::array particleNames = {"Pion", "Kaon", "Proton"}; - const std::array particleSymbols = {"#pi^{#pm}", "K^{#pm}", "p+#bar{p}"}; - - for (int iSpecies = 0; iSpecies < kNSpecies; ++iSpecies) { - const auto& name = particleNames[iSpecies]; - const auto& symbol = particleSymbols[iSpecies]; - - // 1D versions - ue.add(Form("%s/hPtPrimGenAll", name.c_str()), - Form("All generated %s (no cuts);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - - ue.add(Form("%s/hPtPrimBadVertex", name.c_str()), - Form("Generated %s (bad vertex);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - - ue.add(Form("%s/hPtPrimGen", name.c_str()), - Form("Generated %s (after physics selection);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - - ue.add(Form("%s/hPtPrimRecoEv", name.c_str()), - Form("Generated %s (reco events);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - - ue.add(Form("%s/hPtPrimGoodEv", name.c_str()), - Form("Generated %s (good events);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - - // 2D versions (vs multiplicity class) - ue.add(Form("%s/hPtPrimGenAllVsMult", name.c_str()), - Form("All generated %s vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add(Form("%s/hPtPrimBadVertexVsMult", name.c_str()), - Form("Generated %s (bad vertex) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add(Form("%s/hPtPrimGenVsMult", name.c_str()), - Form("Generated %s (after phys sel) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add(Form("%s/hPtPrimRecoEvVsMult", name.c_str()), - Form("Generated %s (reco events) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add(Form("%s/hPtPrimGoodEvVsMult", name.c_str()), - Form("Generated %s (good events) vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - // Tracking efficiency - ue.add(Form("%s/hPtNumEff", name.c_str()), - Form("%s tracking efficiency numerator;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - ue.add(Form("%s/hPtNumEffVsMult", name.c_str()), - Form("%s tracking eff numerator vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add(Form("%s/hPtDenEff", name.c_str()), - Form("%s tracking efficiency denominator;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - ue.add(Form("%s/hPtDenEffVsMult", name.c_str()), - Form("%s tracking eff denominator vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - // Primary fraction - ue.add(Form("%s/hPtAllReco", name.c_str()), - Form("All reconstructed %s;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - ue.add(Form("%s/hPtAllRecoVsMult", name.c_str()), - Form("All reconstructed %s vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add(Form("%s/hPtPrimReco", name.c_str()), - Form("Reconstructed primary %s;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - ue.add(Form("%s/hPtPrimRecoVsMult", name.c_str()), - Form("Reconstructed primary %s vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - ue.add(Form("%s/hPtSecReco", name.c_str()), - Form("Reconstructed secondary %s;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - ue.add(Form("%s/hPtSecRecoVsMult", name.c_str()), - Form("Reconstructed secondary %s vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - // Measured spectra - ue.add(Form("%s/hPtMeasured", name.c_str()), - Form("Measured %s;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), - HistType::kTH1D, {ptAxis}); - ue.add(Form("%s/hPtMeasuredVsMult", name.c_str()), - Form("Measured %s vs mult;#it{p}_{T} (GeV/#it{c});Mult Class (%%)", symbol.c_str()), - HistType::kTH2D, {ptAxis, multAxis}); - - // PID quality - if (enablePIDHistograms) { - ue.add(Form("%s/hNsigmaTPC", name.c_str()), - Form("TPC n#sigma %s;#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", symbol.c_str()), - HistType::kTH2D, {ptAxis, {200, -10, 10}}); - } - } - - // ======================================================================== - // PHI CUT MONITORING - // ======================================================================== - - if (applyPhiCut.value) { - ue.add("PhiCut/hPtVsPhiPrimeBefore", "pT vs φ' before cut;p_{T} (GeV/c);φ'", - HistType::kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); - ue.add("PhiCut/hPtVsPhiPrimeAfter", "pT vs φ' after cut;p_{T} (GeV/c);φ'", - HistType::kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); - ue.add("PhiCut/hRejectionRate", "Track rejection rate by phi cut;p_{T} (GeV/c);Rejection Rate", - HistType::kTProfile, {{100, 0, 10}}); - } - - // ======================================================================== - // EVENT SELECTION HISTOGRAM - // ======================================================================== - - constexpr int nEvSelBins = 20; - constexpr float evSelMin = 0.5f; - constexpr float evSelMax = 20.5f; - ue.add("evsel", "Event selection", HistType::kTH1D, {{nEvSelBins, evSelMin, evSelMax}}); - auto h = ue.get(HIST("evsel")); - h->GetXaxis()->SetBinLabel(1, "Events read"); - h->GetXaxis()->SetBinLabel(2, "INEL>0"); - h->GetXaxis()->SetBinLabel(3, "INEL>1"); - h->GetXaxis()->SetBinLabel(4, "Trigger passed"); - h->GetXaxis()->SetBinLabel(5, "NoITSROFrameBorder"); - h->GetXaxis()->SetBinLabel(6, "NoSameBunchPileup"); - h->GetXaxis()->SetBinLabel(7, "IsGoodZvtxFT0vsPV"); - h->GetXaxis()->SetBinLabel(8, "IsVertexITSTPC"); - h->GetXaxis()->SetBinLabel(9, "NoTimeFrameBorder"); - h->GetXaxis()->SetBinLabel(13, "posZ passed"); - h->GetXaxis()->SetBinLabel(14, "INEL>0 (final)"); - h->GetXaxis()->SetBinLabel(15, "INEL>1 (final)"); - - ue.add("hEta", "Track eta;#eta;Counts", HistType::kTH1D, {{20, -0.8, 0.8}}); - ue.add("hPhi", "Track phi;#varphi (rad);Counts", HistType::kTH1D, {{64, 0, 2.0 * M_PI}}); - ue.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); - ue.add("hvtxZmc", "MC vertex Z;Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); - - LOG(info) << "=== Initialized MultiplicityPt task with ON-THE-FLY PERCENTILE COMPUTATION ==="; - LOG(info) << "Centrality classes: " << kCentralityClasses; - LOG(info) << "Multiplicity estimator: " << multiplicityEstimator.value; - LOG(info) << "IMPORTANT: Run processPercentileCalibration FIRST to build percentile boundaries!"; - if (applyPhiCut.value) { - LOG(info) << "Phi cut ENABLED for pT > " << pTthresholdPhiCut.value << " GeV/c"; - } -} - -// ======================================================================== -// PERCENTILE CALIBRATION PASS -// ======================================================================== -void MultiplicityPt::processPercentileCalibration(CollisionTableMCTrue const& mcCollisions, - ParticleTableMC const& particles) -{ - LOG(info) << "=== PERCENTILE CALIBRATION PASS ==="; - LOG(info) << "Processing " << mcCollisions.size() << " MC collisions"; - - multiplicityValues.clear(); - multiplicityValues.reserve(mcCollisions.size()); - - for (const auto& mcCollision : mcCollisions) { - // Apply basic cuts - if (std::abs(mcCollision.posZ()) > cfgCutVertex.value) - continue; - - auto particlesInCollision = particles.sliceBy(perMCCol, mcCollision.globalIndex()); - - // Apply INEL cuts - if (cfgINELCut.value == 1 && !o2::pwglf::isINELgt0mc(particlesInCollision, pdg)) - continue; - if (cfgINELCut.value == 2 && !o2::pwglf::isINELgt1mc(particlesInCollision, pdg)) - continue; - - // Calculate multiplicity - float mcMult = getMultiplicityMC(mcCollision, particles); - multiplicityValues.push_back(mcMult); - - ue.fill(HIST("Calibration/hRawMultiplicity"), mcMult); - } - - // Compute percentile boundaries - computePercentileBoundaries(); - - LOG(info) << "=== PERCENTILE CALIBRATION COMPLETE ==="; - LOG(info) << "Processed " << multiplicityValues.size() << " events"; - LOG(info) << "Now run processMC and processTrue with these percentiles"; -} - -// ======================================================================== -// DATA PROCESSING -// ======================================================================== -void MultiplicityPt::processData(CollisionTableData::iterator const& collision, - TrackTableData const& tracks, - BCsRun3 const& /*bcs*/) -{ - if (!isEventSelected(collision)) { - return; - } - ue.fill(HIST("hvtxZ"), collision.posZ()); - - float magField = 0; - if (applyPhiCut.value) { - const auto& bc = collision.bc_as(); - magField = getMagneticField(bc.timestamp()); - } - - for (const auto& track : tracks) { - if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { - float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); - ue.fill(HIST("PhiCut/hPtVsPhiPrimeBefore"), track.pt(), phiPrime); - } - - if (!passesTrackSelection(track, magField)) { - continue; - } - - if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { - float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); - ue.fill(HIST("PhiCut/hPtVsPhiPrimeAfter"), track.pt(), phiPrime); - } - - ue.fill(HIST("Inclusive/hPtMeasured"), track.pt()); - ue.fill(HIST("hEta"), track.eta()); - ue.fill(HIST("hPhi"), track.phi()); - - int bestSpecies = getBestPIDHypothesis(track); - - if (bestSpecies == kPion) { - ue.fill(HIST("Pion/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); - } - } else if (bestSpecies == kKaon) { - ue.fill(HIST("Kaon/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); - } - } else if (bestSpecies == kProton) { - ue.fill(HIST("Proton/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); - } - } - } -} - -// ======================================================================== -// MC PROCESSING - Using computed percentiles -// ======================================================================== -void MultiplicityPt::processMC(TrackTableMC const& tracks, - aod::McParticles const& particles, - CollisionTableMCTrue const& mcCollisions, - CollisionTableMC const& collisions, - BCsRun3 const& /*bcs*/) -{ - if (!percentilesComputed) { - LOG(warning) << "Percentiles not computed yet! Run processPercentileCalibration first!"; - LOG(warning) << "Using fallback linear binning for now..."; - } - - LOG(info) << "=== DEBUG processMC START ==="; - LOG(info) << "MC collisions: " << mcCollisions.size(); - LOG(info) << "Reconstructed collisions: " << collisions.size(); - - ue.fill(HIST("MC/GenRecoCollisions"), 1.f, mcCollisions.size()); - ue.fill(HIST("MC/GenRecoCollisions"), 2.f, collisions.size()); - - std::set physicsSelectedMCCollisions; - std::set reconstructedMCCollisions; - std::set selectedMCCollisions; - - std::map mcCollisionMultiplicity; - std::map mcCollisionPercentile; - - // First pass: classify MC collisions - for (const auto& mcCollision : mcCollisions) { - int64_t mcCollId = mcCollision.globalIndex(); - - float mcMult = getMultiplicityMC(mcCollision, particles); - mcCollisionMultiplicity[mcCollId] = mcMult; - - // Convert to percentile - float percentile = multiplicityToPercentile(mcMult); - mcCollisionPercentile[mcCollId] = percentile; - - ue.fill(HIST("MC/EventLoss/MultGenerated"), percentile); - - auto particlesInCollision = particles.sliceBy(perMCCol, mcCollId); - - if (std::abs(mcCollision.posZ()) > cfgCutVertex.value) { - ue.fill(HIST("MC/EventLoss/MultBadVertex"), percentile); - continue; - } - - if (cfgINELCut.value == 1 && !o2::pwglf::isINELgt0mc(particlesInCollision, pdg)) { - continue; - } - if (cfgINELCut.value == 2 && !o2::pwglf::isINELgt1mc(particlesInCollision, pdg)) { - continue; - } - - physicsSelectedMCCollisions.insert(mcCollId); - ue.fill(HIST("MC/EventLoss/MultPhysicsSelected"), percentile); - } - - LOG(info) << "Physics-selected MC collisions: " << physicsSelectedMCCollisions.size(); - - // Second pass: track reconstructed events - std::set selectedCollisionIndices; - - for (const auto& collision : collisions) { - if (!collision.has_mcCollision()) { - continue; - } - - const auto& mcCollision = collision.mcCollision_as(); - int64_t mcCollId = mcCollision.globalIndex(); - - if (physicsSelectedMCCollisions.find(mcCollId) == physicsSelectedMCCollisions.end()) { - continue; - } - - float percentile = mcCollisionPercentile[mcCollId]; - - if (reconstructedMCCollisions.find(mcCollId) == reconstructedMCCollisions.end()) { - reconstructedMCCollisions.insert(mcCollId); - ue.fill(HIST("MC/EventLoss/MultReconstructed"), percentile); - } - - if (isEventSelected(collision)) { - if (selectedMCCollisions.find(mcCollId) == selectedMCCollisions.end()) { - selectedMCCollisions.insert(mcCollId); - ue.fill(HIST("MC/EventLoss/MultRecoSelected"), percentile); - } - selectedCollisionIndices.insert(collision.globalIndex()); - ue.fill(HIST("hvtxZ"), collision.posZ()); - } - } - - LOG(info) << "Reconstructed MC collisions: " << reconstructedMCCollisions.size(); - LOG(info) << "Selected MC collisions: " << selectedMCCollisions.size(); - - int nPhysicsSelected = physicsSelectedMCCollisions.size(); - int nReconstructed = reconstructedMCCollisions.size(); - int nSelected = selectedMCCollisions.size(); - - if (nPhysicsSelected > 0) { - ue.fill(HIST("hEventLossBreakdown"), 1, nPhysicsSelected); - ue.fill(HIST("hEventLossBreakdown"), 2, nReconstructed); - ue.fill(HIST("hEventLossBreakdown"), 3, nSelected); - ue.fill(HIST("hEventLossBreakdown"), 4, (nSelected * 100.0 / nPhysicsSelected)); - } - - // Process tracks - int totalTracksProcessed = 0; - int tracksFromSelectedEvents = 0; - int tracksPassingSelection = 0; - - std::array particleTracksIdentified = {0}; - std::array particleTracksPrimary = {0}; - std::array particleTracksSecondary = {0}; - - for (const auto& track : tracks) { - totalTracksProcessed++; - - if (!track.has_collision()) - continue; - - const auto& collision = track.collision_as(); - - if (selectedCollisionIndices.find(collision.globalIndex()) == selectedCollisionIndices.end()) { - continue; - } - tracksFromSelectedEvents++; - - if (!collision.has_mcCollision()) - continue; - - const auto& mcCollision = collision.mcCollision_as(); - float percentile = mcCollisionPercentile[mcCollision.globalIndex()]; - - float magField = 0; - if (applyPhiCut.value) { - const auto& bc = collision.bc_as(); - magField = getMagneticField(bc.timestamp()); - } - - if (!passesTrackSelection(track, magField)) { - continue; - } - tracksPassingSelection++; - - // Inclusive charged particle - ue.fill(HIST("Inclusive/hPtMeasured"), track.pt()); - ue.fill(HIST("Inclusive/hPtMeasuredVsMult"), track.pt(), percentile); - ue.fill(HIST("Inclusive/hPtAllReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtAllRecoVsMult"), track.pt(), percentile); - ue.fill(HIST("hEta"), track.eta()); - ue.fill(HIST("hPhi"), track.phi()); - - // Efficiency numerator - if (track.has_mcParticle()) { - const auto& particle = track.mcParticle(); - int pdgCode = std::abs(particle.pdgCode()); - - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Inclusive/hPtNumEff"), particle.pt()); - ue.fill(HIST("Inclusive/hPtNumEffVsMult"), particle.pt(), percentile); - ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtPrimRecoVsMult"), track.pt(), percentile); - - if (pdgCode == PDGPion) { - ue.fill(HIST("Pion/hPtNumEff"), particle.pt()); - ue.fill(HIST("Pion/hPtNumEffVsMult"), particle.pt(), percentile); - } - if (pdgCode == PDGKaon) { - ue.fill(HIST("Kaon/hPtNumEff"), particle.pt()); - ue.fill(HIST("Kaon/hPtNumEffVsMult"), particle.pt(), percentile); - } - if (pdgCode == PDGProton) { - ue.fill(HIST("Proton/hPtNumEff"), particle.pt()); - ue.fill(HIST("Proton/hPtNumEffVsMult"), particle.pt(), percentile); - } - } else { - ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtSecRecoVsMult"), track.pt(), percentile); - } - } - - // Identified particle analysis - int bestSpecies = getBestPIDHypothesis(track); - - if (bestSpecies == kPion) { - ue.fill(HIST("Pion/hPtMeasured"), track.pt()); - ue.fill(HIST("Pion/hPtMeasuredVsMult"), track.pt(), percentile); - ue.fill(HIST("Pion/hPtAllReco"), track.pt()); - ue.fill(HIST("Pion/hPtAllRecoVsMult"), track.pt(), percentile); - particleTracksIdentified[kPion]++; - - if (enablePIDHistograms) { - ue.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); - } - - if (track.has_mcParticle()) { - const auto& particle = track.mcParticle(); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Pion/hPtPrimReco"), track.pt()); - ue.fill(HIST("Pion/hPtPrimRecoVsMult"), track.pt(), percentile); - particleTracksPrimary[kPion]++; - } else { - ue.fill(HIST("Pion/hPtSecReco"), track.pt()); - ue.fill(HIST("Pion/hPtSecRecoVsMult"), track.pt(), percentile); - particleTracksSecondary[kPion]++; - } - } - - } else if (bestSpecies == kKaon) { - ue.fill(HIST("Kaon/hPtMeasured"), track.pt()); - ue.fill(HIST("Kaon/hPtMeasuredVsMult"), track.pt(), percentile); - ue.fill(HIST("Kaon/hPtAllReco"), track.pt()); - ue.fill(HIST("Kaon/hPtAllRecoVsMult"), track.pt(), percentile); - particleTracksIdentified[kKaon]++; - - if (enablePIDHistograms) { - ue.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); - } - - if (track.has_mcParticle()) { - const auto& particle = track.mcParticle(); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Kaon/hPtPrimReco"), track.pt()); - ue.fill(HIST("Kaon/hPtPrimRecoVsMult"), track.pt(), percentile); - particleTracksPrimary[kKaon]++; - } else { - ue.fill(HIST("Kaon/hPtSecReco"), track.pt()); - ue.fill(HIST("Kaon/hPtSecRecoVsMult"), track.pt(), percentile); - particleTracksSecondary[kKaon]++; - } - } - - } else if (bestSpecies == kProton) { - ue.fill(HIST("Proton/hPtMeasured"), track.pt()); - ue.fill(HIST("Proton/hPtMeasuredVsMult"), track.pt(), percentile); - ue.fill(HIST("Proton/hPtAllReco"), track.pt()); - ue.fill(HIST("Proton/hPtAllRecoVsMult"), track.pt(), percentile); - particleTracksIdentified[kProton]++; - - if (enablePIDHistograms) { - ue.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); - } - - if (track.has_mcParticle()) { - const auto& particle = track.mcParticle(); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Proton/hPtPrimReco"), track.pt()); - ue.fill(HIST("Proton/hPtPrimRecoVsMult"), track.pt(), percentile); - particleTracksPrimary[kProton]++; - } else { - ue.fill(HIST("Proton/hPtSecReco"), track.pt()); - ue.fill(HIST("Proton/hPtSecRecoVsMult"), track.pt(), percentile); - particleTracksSecondary[kProton]++; - } - } - } - } - - LOG(info) << "=== DEBUG TRACK COUNTING ==="; - LOG(info) << "Total tracks processed: " << totalTracksProcessed; - LOG(info) << "Tracks from selected events: " << tracksFromSelectedEvents; - LOG(info) << "Tracks passing selection: " << tracksPassingSelection; - - LOG(info) << "Pions identified: " << particleTracksIdentified[kPion] - << ", primary: " << particleTracksPrimary[kPion] - << ", secondary: " << particleTracksSecondary[kPion]; - LOG(info) << "Kaons identified: " << particleTracksIdentified[kKaon] - << ", primary: " << particleTracksPrimary[kKaon] - << ", secondary: " << particleTracksSecondary[kKaon]; - LOG(info) << "Protons identified: " << particleTracksIdentified[kProton] - << ", primary: " << particleTracksPrimary[kProton] - << ", secondary: " << particleTracksSecondary[kProton]; - - LOG(info) << "=== DEBUG processMC END ==="; -} - -// ======================================================================== -// TRUE MC PROCESSING - Using computed percentiles -// ======================================================================== -void MultiplicityPt::processTrue(CollisionTableMCTrue const& mcCollisions, - ParticleTableMC const& particles) -{ - if (!percentilesComputed) { - LOG(warning) << "Percentiles not computed yet! Run processPercentileCalibration first!"; - } - - LOG(info) << "=== DEBUG processTrue START ==="; - LOG(info) << "Number of MC collisions: " << mcCollisions.size(); - - int nAllGenerated = 0; - int nBadVertex = 0; - int nPhysicsSelected = 0; - - std::array particleCountAll = {0}; - std::array particleCountBadVertex = {0}; - std::array particleCountAfterPS = {0}; - - for (const auto& mcCollision : mcCollisions) { - nAllGenerated++; - - float mcMult = getMultiplicityMC(mcCollision, particles); - float percentile = multiplicityToPercentile(mcMult); - - ue.fill(HIST("hvtxZmc"), mcCollision.posZ()); - auto particlesInCollision = particles.sliceBy(perMCCol, mcCollision.globalIndex()); - - // Fill ALL generated primaries BEFORE any cuts - for (const auto& particle : particlesInCollision) { - if (isGoodPrimary(particle)) { - ue.fill(HIST("Inclusive/hPtPrimGenAll"), particle.pt()); - ue.fill(HIST("Inclusive/hPtPrimGenAllVsMult"), particle.pt(), percentile); - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Pion/hPtPrimGenAll"), particle.pt()); - ue.fill(HIST("Pion/hPtPrimGenAllVsMult"), particle.pt(), percentile); - particleCountAll[kPion]++; - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Kaon/hPtPrimGenAll"), particle.pt()); - ue.fill(HIST("Kaon/hPtPrimGenAllVsMult"), particle.pt(), percentile); - particleCountAll[kKaon]++; - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Proton/hPtPrimGenAll"), particle.pt()); - ue.fill(HIST("Proton/hPtPrimGenAllVsMult"), particle.pt(), percentile); - particleCountAll[kProton]++; - } - } - - // Apply vertex cut - if (std::abs(mcCollision.posZ()) > cfgCutVertex.value) { - nBadVertex++; - - for (const auto& particle : particlesInCollision) { - if (isGoodPrimary(particle)) { - ue.fill(HIST("Inclusive/hPtPrimBadVertex"), particle.pt()); - ue.fill(HIST("Inclusive/hPtPrimBadVertexVsMult"), particle.pt(), percentile); - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Pion/hPtPrimBadVertex"), particle.pt()); - ue.fill(HIST("Pion/hPtPrimBadVertexVsMult"), particle.pt(), percentile); - particleCountBadVertex[kPion]++; - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Kaon/hPtPrimBadVertex"), particle.pt()); - ue.fill(HIST("Kaon/hPtPrimBadVertexVsMult"), particle.pt(), percentile); - particleCountBadVertex[kKaon]++; - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Proton/hPtPrimBadVertex"), particle.pt()); - ue.fill(HIST("Proton/hPtPrimBadVertexVsMult"), particle.pt(), percentile); - particleCountBadVertex[kProton]++; - } - } - continue; - } - - // Apply INEL cuts - if (cfgINELCut.value == 1 && !o2::pwglf::isINELgt0mc(particlesInCollision, pdg)) - continue; - if (cfgINELCut.value == 2 && !o2::pwglf::isINELgt1mc(particlesInCollision, pdg)) - continue; - - nPhysicsSelected++; - - // Fill primaries AFTER physics selection (denominator for efficiency) - for (const auto& particle : particlesInCollision) { - if (isGoodPrimary(particle)) { - ue.fill(HIST("Inclusive/hPtDenEff"), particle.pt()); - ue.fill(HIST("Inclusive/hPtDenEffVsMult"), particle.pt(), percentile); - ue.fill(HIST("Inclusive/hPtPrimGen"), particle.pt()); - ue.fill(HIST("Inclusive/hPtPrimGenVsMult"), particle.pt(), percentile); - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Pion/hPtDenEff"), particle.pt()); - ue.fill(HIST("Pion/hPtDenEffVsMult"), particle.pt(), percentile); - ue.fill(HIST("Pion/hPtPrimGen"), particle.pt()); - ue.fill(HIST("Pion/hPtPrimGenVsMult"), particle.pt(), percentile); - particleCountAfterPS[kPion]++; - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Kaon/hPtDenEff"), particle.pt()); - ue.fill(HIST("Kaon/hPtDenEffVsMult"), particle.pt(), percentile); - ue.fill(HIST("Kaon/hPtPrimGen"), particle.pt()); - ue.fill(HIST("Kaon/hPtPrimGenVsMult"), particle.pt(), percentile); - particleCountAfterPS[kKaon]++; - } - - if (isGoodPrimarySpecies(particle)) { - ue.fill(HIST("Proton/hPtDenEff"), particle.pt()); - ue.fill(HIST("Proton/hPtDenEffVsMult"), particle.pt(), percentile); - ue.fill(HIST("Proton/hPtPrimGen"), particle.pt()); - ue.fill(HIST("Proton/hPtPrimGenVsMult"), particle.pt(), percentile); - particleCountAfterPS[kProton]++; - } - } - } - - LOG(info) << "=== DEBUG processTrue END ==="; - LOG(info) << "All generated events: " << nAllGenerated; - LOG(info) << "Events with bad vertex: " << nBadVertex; - LOG(info) << "Passing physics selection: " << nPhysicsSelected; - - LOG(info) << "=== PARTICLE-SPECIFIC STATISTICS ==="; - LOG(info) << "Pions - All: " << particleCountAll[kPion] - << ", Bad vertex: " << particleCountBadVertex[kPion] - << ", After PS: " << particleCountAfterPS[kPion]; - LOG(info) << "Kaons - All: " << particleCountAll[kKaon] - << ", Bad vertex: " << particleCountBadVertex[kKaon] - << ", After PS: " << particleCountAfterPS[kKaon]; - LOG(info) << "Protons - All: " << particleCountAll[kProton] - << ", Bad vertex: " << particleCountBadVertex[kProton] - << ", After PS: " << particleCountAfterPS[kProton]; -} diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx new file mode 100644 index 00000000000..8548be612c8 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -0,0 +1,1129 @@ +// 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. + +/// \author Dushmanta Sahu (dushmanta.sahu@cern.ch) +/// \file multiplicityPt.cxx +/// \brief Analysis to do PID with MC + +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/DataModel/mcCentrality.h" // For McCentFT0Ms +#include "PWGLF/DataModel/spectraTOF.h" +#include "PWGLF/Utils/inelGt.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/McCollisionExtra.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/Logger.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/StaticFor.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "TPDGCode.h" +#include +#include +#include +#include + +#include +#include +#include +#include // For std::accumulate +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::math; +using namespace constants::physics; + +using BCsRun3 = soa::Join; + +//============================================================================= +// Main Analysis Struct +//============================================================================= +struct MultiplicityPt { + + // Service + Service pdg; + static constexpr int CentBinMax = 100; + static constexpr int MultBinMax = 200; + static constexpr int RecMultBinMax = 100; + static constexpr int DebugCountMax = 20; + static constexpr int CentMultClasses = 10; + + enum INELCutSelection : int { + INEL = 0, + INELgt0 = 1, + INELgt1 = 2 + + }; + + //=========================================================================== + // Configurable Parameters + //=========================================================================== + Configurable isRun3{"isRun3", true, "is Run3 dataset"}; + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgINELCut{"cfgINELCut", 0, "INEL event selection: 0 no sel, 1 INEL>0, 2 INEL>1"}; + Configurable askForCustomTVX{"askForCustomTVX", false, "Ask for custom TVX rather than sel8"}; + Configurable removeITSROFrameBorder{"removeITSROFrameBorder", false, "Remove ITS Read-Out Frame border"}; + Configurable removeNoSameBunchPileup{"removeNoSameBunchPileup", false, "Remove no same bunch pileup"}; + Configurable requireIsGoodZvtxFT0vsPV{"requireIsGoodZvtxFT0vsPV", false, "Require good Z vertex FT0 vs PV"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "Require vertex ITSTPC"}; + Configurable removeNoTimeFrameBorder{"removeNoTimeFrameBorder", false, "Remove no time frame border"}; + Configurable cfgCutEtaMax{"cfgCutEtaMax", 0.8f, "Max eta range for tracks"}; + Configurable cfgCutEtaMin{"cfgCutEtaMin", -0.8f, "Min eta range for tracks"}; + Configurable cfgCutY{"cfgCutY", 0.5f, "Y range for tracks"}; + Configurable cfgCutNsigma{"cfgCutNsigma", 3.0f, "nsigma cut range for tracks"}; + Configurable lastRequiredTrdCluster{"lastRequiredTrdCluster", -1, "Last cluster to require in TRD"}; + Configurable requireTrdOnly{"requireTrdOnly", false, "Require only tracks from TRD"}; + Configurable requireNoTrd{"requireNoTrd", false, "Require tracks without TRD"}; + + // Analysis switches + Configurable enableDCAHistograms{"enableDCAHistograms", false, "Enable DCA histograms"}; + Configurable enablePIDHistograms{"enablePIDHistograms", true, "Enable PID histograms"}; + Configurable useCustomTrackCuts{"useCustomTrackCuts", true, "Flag to use custom track cuts"}; + Configurable itsPattern{"itsPattern", 0, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"}; + Configurable requireITS{"requireITS", true, "Additional cut on the ITS requirement"}; + Configurable requireTPC{"requireTPC", true, "Additional cut on the TPC requirement"}; + Configurable requireGoldenChi2{"requireGoldenChi2", true, "Additional cut on the GoldenChi2"}; + Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.f, "Additional cut on the minimum number of crossed rows in the TPC"}; + Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; + Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 4.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; + Configurable minChi2PerClusterTPC{"minChi2PerClusterTPC", 0.5f, "Additional cut on the minimum value of the chi2 per cluster in the TPC"}; + Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; + Configurable maxDcaXYFactor{"maxDcaXYFactor", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; + Configurable maxDcaZ{"maxDcaZ", 0.1f, "Additional cut on the maximum value of the DCA z"}; + Configurable minTPCNClsFound{"minTPCNClsFound", 70.0f, "min number of found TPC clusters"}; + Configurable minTPCNClsPID{"minTPCNClsPID", 130.0f, "min number of PID TPC clusters"}; + Configurable nClTPCFoundCut{"nClTPCFoundCut", false, "Apply TPC found clusters cut"}; + Configurable nClTPCPIDCut{"nClTPCPIDCut", true, "Apply TPC clusters for PID cut"}; + + // Phi cut parameters + Configurable applyPhiCut{"applyPhiCut", false, "Apply phi sector cut"}; + + // Basic track cuts + Configurable cfgTrkEtaCut{"cfgTrkEtaCut", 0.8f, "Eta range for tracks"}; + Configurable cfgTrkLowPtCut{"cfgTrkLowPtCut", 0.15f, "Minimum constituent pT"}; + + // PID selection - make them configurable per particle + Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; + Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; + Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; + + // Custom track cuts matching spectraTOF + TrackSelection customTrackCuts; + + // Histogram Registry + HistogramRegistry ue; + + //=========================================================================== + // Table Definitions - Using individual tables, not joined for MC + //=========================================================================== + + // Data collisions (not used but kept for completeness) + using CollisionTableData = soa::Join; + + // Track tables + using TrackTableData = soa::Join; + using TrackTableMC = soa::Join; + + // MC particles table + using ParticlesMC = aod::McParticles; + + // MC collisions table + using McCollisions = aod::McCollisions; + + // Reconstructed collisions (without joins that cause size mismatch) + using RecoCollisions = aod::Collisions; + + // Preslice for MC particles + Preslice perMCCol = aod::mcparticle::mcCollisionId; + + //=========================================================================== + // Constants + //=========================================================================== + enum ParticleSpecies : int { + kPion = 0, + kKaon = 1, + kProton = 2, + kNSpecies = 3 + }; + + + static constexpr int PDGPion = kPiPlus; + static constexpr int PDGKaon = kKPlus; + static constexpr int PDGProton = kProton; + + //=========================================================================== + // Helper Functions + //=========================================================================== + + template + int countGeneratedChargedPrimaries(const ParticleContainer& particles, float etaMax, float ptMin) const + { + int count = 0; + for (const auto& particle : particles) { + auto pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (!pdgParticle || pdgParticle->Charge() == 0.) + continue; + + if (!particle.isPhysicalPrimary()) + continue; + + if (std::abs(particle.eta()) > etaMax) + continue; + + if (particle.pt() < ptMin) + continue; + + count++; + } + return count; + } + + template + bool passedNClTPCFoundCut(const T& trk) const + { + if (!nClTPCFoundCut.value) + return true; + return trk.tpcNClsFound() >= minTPCNClsFound.value; + } + + template + bool passedNClTPCPIDCut(const T& trk) const + { + if (!nClTPCPIDCut.value) + return true; + return trk.tpcNClsPID() >= minTPCNClsPID.value; + } + + template + bool passesCutWoDCA(TrackType const& track) const + { + if (useCustomTrackCuts.value) { + for (int i = 0; i < static_cast(TrackSelection::TrackCuts::kNCuts); i++) { + if (i == static_cast(TrackSelection::TrackCuts::kDCAxy) || + i == static_cast(TrackSelection::TrackCuts::kDCAz)) { + continue; + } + if (!customTrackCuts.IsSelected(track, static_cast(i))) { + return false; + } + } + return true; + } + return track.isGlobalTrackWoDCA(); + } + + template + bool passesDCAxyCut(TrackType const& track) const + { + if (useCustomTrackCuts.value) { + if (!passesCutWoDCA(track)) { + return false; + } + constexpr float DcaXYConst = 0.0105f; + constexpr float DcaXYPtScale = 0.0350f; + constexpr float DcaXYPtPower = 1.1f; + const float maxDcaXY = maxDcaXYFactor.value * (DcaXYConst + DcaXYPtScale / std::pow(track.pt(), DcaXYPtPower)); + return std::abs(track.dcaXY()) <= maxDcaXY; + } + return track.isGlobalTrack(); + } + + template + bool passesTrackSelection(TrackType const& track) const + { + if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) + return false; + + if (track.tpcChi2NCl() < minChi2PerClusterTPC.value || track.tpcChi2NCl() > maxChi2PerClusterTPC.value) + return false; + + if (!passesCutWoDCA(track)) + return false; + + if (!passesDCAxyCut(track)) + return false; + + if (!passedNClTPCFoundCut(track)) + return false; + + if (!passedNClTPCPIDCut(track)) + return false; + + return true; + } + + template + bool passesPIDSelection(TrackType const& track) const + { + float nsigmaTPC = 0.f; + + if constexpr (species == kPion) { + nsigmaTPC = track.tpcNSigmaPi(); + } else if constexpr (species == kKaon) { + nsigmaTPC = track.tpcNSigmaKa(); + } else if constexpr (species == kProton) { + nsigmaTPC = track.tpcNSigmaPr(); + } + + float cutValue = cfgCutNsigma.value; + if constexpr (species == kPion) + cutValue = cfgCutNsigmaPi.value; + if constexpr (species == kKaon) + cutValue = cfgCutNsigmaKa.value; + if constexpr (species == kProton) + cutValue = cfgCutNsigmaPr.value; + + return (std::abs(nsigmaTPC) < cutValue); + } + + template + int getBestPIDHypothesis(TrackType const& track) const + { + float nsigmaPi = std::abs(track.tpcNSigmaPi()); + float nsigmaKa = std::abs(track.tpcNSigmaKa()); + float nsigmaPr = std::abs(track.tpcNSigmaPr()); + + float minNSigma = 999.0f; + int bestSpecies = -1; + + if (nsigmaPi < cfgCutNsigmaPi.value && nsigmaPi < minNSigma) { + minNSigma = nsigmaPi; + bestSpecies = kPion; + } + if (nsigmaKa < cfgCutNsigmaKa.value && nsigmaKa < minNSigma) { + minNSigma = nsigmaKa; + bestSpecies = kKaon; + } + if (nsigmaPr < cfgCutNsigmaPr.value && nsigmaPr < minNSigma) { + minNSigma = nsigmaPr; + bestSpecies = kProton; + } + + return bestSpecies; + } + + template + bool isGoodPrimary(ParticleType const& particle) const + { + auto pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (!pdgParticle || pdgParticle->Charge() == 0.) + return false; + + if (!particle.isPhysicalPrimary()) + return false; + + if (std::abs(particle.eta()) >= cfgCutEtaMax.value) + return false; + if (particle.pt() < cfgTrkLowPtCut.value) + return false; + + return true; + } + + //=========================================================================== + // Process Switches + //=========================================================================== + void processData(CollisionTableData::iterator const& collision, + TrackTableData const& tracks, + BCsRun3 const& bcs); + PROCESS_SWITCH(MultiplicityPt, processData, "process data", false); + + void processMC(TrackTableMC const& tracks, + aod::McParticles const& particles, + aod::McCollisions const& mcCollisions, + RecoCollisions const& collisions, + aod::McCollisionLabels const& labels, + aod::McCentFT0Ms const& centTable, + BCsRun3 const& bcs); + PROCESS_SWITCH(MultiplicityPt, processMC, "process MC", true); + + //=========================================================================== + // Standard Framework Functions + //=========================================================================== + void init(InitContext const&); + + void endOfStream(EndOfStreamContext& /*eos*/) + { + LOG(info) << "\n=== END OF STREAM: Writing histograms to output ==="; + auto hGenMult = ue.get(HIST("MC/EventLoss/GenMultVsCent")); + if (hGenMult) { + LOG(info) << "GenMultVsCent: Entries=" << hGenMult->GetEntries() + << ", Integral=" << hGenMult->Integral(); + } + LOG(info) << "=== END OF STREAM COMPLETE ==="; + } +}; + +//============================================================================= +// Workflow Definition +//============================================================================= +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} + +//============================================================================= +// Implementation of Member Functions +//============================================================================= + +void MultiplicityPt::init(InitContext const&) +{ + LOG(info) << "=================================================="; + LOG(info) << "Initializing MultiplicityPt task with full centrality diagnostics"; + LOG(info) << "=================================================="; + + if (useCustomTrackCuts.value) { + LOG(info) << "Using custom track cuts matching spectraTOF approach"; + customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); + + customTrackCuts.SetRequireITSRefit(requireITS.value); + customTrackCuts.SetRequireTPCRefit(requireTPC.value); + customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); + customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); + customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); + customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); + customTrackCuts.SetMinNClustersTPC(minTPCNClsFound.value); + customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); + customTrackCuts.SetMaxDcaXYPtDep([](float /*pt*/) { return 10000.f; }); + customTrackCuts.SetMaxDcaZ(maxDcaZ.value); + + customTrackCuts.print(); + } + + // Axis definitions + ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; + + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + + std::vector centBinningStd = {0., 1., 5., 10., 15., 20., 30., 40., 50., 60., 70., 80., 90., 100.}; + + // Fine centrality binning for diagnostics (100 bins, guaranteed increasing) + std::vector centBinningFine; + for (int i = 0; i <= CentBinMax; i++) { + centBinningFine.push_back(static_cast(i)); + } + + AxisSpec centAxis = {centBinningStd, "FT0M Centrality (%)"}; + AxisSpec centFineAxis = {centBinningFine, "FT0M Centrality (%)"}; + + // Multiplicity axes - properly defined + std::vector multBins; + for (int i = 0; i <= MultBinMax; i++) { + multBins.push_back(static_cast(i)); + } + AxisSpec multAxis = {multBins, "N_{ch}^{gen} (|#eta|<0.8)"}; + + // Reconstructed multiplicity axis - properly defined with explicit bin edges + std::vector recoMultBins; + for (int i = 0; i <= RecMultBinMax; i++) { + recoMultBins.push_back(static_cast(i)); + } + AxisSpec recoMultAxis = {recoMultBins, "N_{ch}^{reco}"}; + + //=========================================================================== + // Comprehensive Histogram Registration + //=========================================================================== + + // Centrality diagnostic histograms - USE FINE BINNING + ue.add("Centrality/hCentRaw", "Raw FT0M Centrality (no cuts);Centrality (%);Counts", + HistType::kTH1D, {centFineAxis}); + ue.add("Centrality/hCentAfterVtx", "Centrality after vertex cut;Centrality (%);Counts", + HistType::kTH1D, {centFineAxis}); + ue.add("Centrality/hCentAfterINEL", "Centrality after INEL cut;Centrality (%);Counts", + HistType::kTH1D, {centFineAxis}); + ue.add("Centrality/hCentAfterAll", "Centrality after all cuts;Centrality (%);Counts", + HistType::kTH1D, {centFineAxis}); + + // 2D correlations - USE FINE BINNING FOR DIAGNOSTICS + ue.add("Centrality/hCentVsMult", "Centrality vs Generated Multiplicity;Centrality (%);N_{ch}^{gen}", + HistType::kTH2D, {centFineAxis, multAxis}); + ue.add("Centrality/hMultVsCent", "Generated Multiplicity vs Centrality;N_{ch}^{gen};Centrality (%)", + HistType::kTH2D, {multAxis, centFineAxis}); + ue.add("Centrality/hCentVsVz", "Centrality vs Vertex Z;Centrality (%);V_{z} (cm)", + HistType::kTH2D, {centFineAxis, {40, -20, 20}}); + ue.add("Centrality/hRecoMultVsCent", "Reconstructed Track Multiplicity vs Centrality;Centrality (%);N_{tracks}^{reco}", + HistType::kTH2D, {centFineAxis, recoMultAxis}); + ue.add("Centrality/hGenMultPerCent", "Generated Multiplicity Distribution per Centrality Bin;Centrality (%);", + HistType::kTH2D, {centFineAxis, multAxis}); + + // Vertex resolution vs centrality + ue.add("Centrality/hVertexResVsCent", "Vertex Resolution vs Centrality;Centrality (%);V_{z} resolution (cm)", + HistType::kTH2D, {centFineAxis, {100, -1, 1}}); + + // INEL class distributions + ue.add("INEL/hINELClass", "INEL Class for MC Collisions;INEL Class;Counts", + HistType::kTH1D, {{3, 0.5, 3.5}}); + auto hINEL = ue.get(HIST("INEL/hINELClass")); + hINEL->GetXaxis()->SetBinLabel(1, "INEL0"); + hINEL->GetXaxis()->SetBinLabel(2, "INEL>0"); + hINEL->GetXaxis()->SetBinLabel(3, "INEL>1"); + + ue.add("INEL/hINELVsCent", "INEL Class vs Centrality;Centrality (%);INEL Class", + HistType::kTH2D, {centFineAxis, {3, 0.5, 3.5}}); + + // Cut flow + ue.add("CutFlow/hCutStats", "Cut Statistics;Cut Stage;Counts", + HistType::kTH1D, {{6, 0.5, 6.5}}); + auto hCut = ue.get(HIST("CutFlow/hCutStats")); + hCut->GetXaxis()->SetBinLabel(1, "All reco events"); + hCut->GetXaxis()->SetBinLabel(2, "Has MC match"); + hCut->GetXaxis()->SetBinLabel(3, "Has centrality"); + hCut->GetXaxis()->SetBinLabel(4, "Pass vertex"); + hCut->GetXaxis()->SetBinLabel(5, "Pass INEL"); + hCut->GetXaxis()->SetBinLabel(6, "Selected"); + + ue.add("CutFlow/hCentPerCut", "Centrality Distribution at Each Cut;Cut Stage;Centrality (%)", + HistType::kTH2D, {{6, 0.5, 6.5}, centFineAxis}); + + ue.add("MC/GenRecoCollisions", "Generated and Reconstructed MC Collisions", + HistType::kTH1D, {{10, 0.5, 10.5}}); + auto hColl = ue.get(HIST("MC/GenRecoCollisions")); + hColl->GetXaxis()->SetBinLabel(1, "Collisions generated"); + hColl->GetXaxis()->SetBinLabel(2, "Collisions reconstructed"); + hColl->GetXaxis()->SetBinLabel(3, "INEL>0"); + hColl->GetXaxis()->SetBinLabel(4, "INEL>1"); + + ue.add("hEventLossBreakdown", "Event loss breakdown", + HistType::kTH1D, {{4, 0.5, 4.5}}); + auto hLoss = ue.get(HIST("hEventLossBreakdown")); + hLoss->GetXaxis()->SetBinLabel(1, "Physics selected"); + hLoss->GetXaxis()->SetBinLabel(2, "Reconstructed"); + hLoss->GetXaxis()->SetBinLabel(3, "Selected"); + hLoss->GetXaxis()->SetBinLabel(4, "Final efficiency"); + + // Multiplicity histograms + ue.add("MC/EventLoss/NchGenerated", "Generated charged multiplicity;N_{ch}^{gen} (|#eta|<0.8);Counts", + HistType::kTH1D, {{200, 0, 200}}); + ue.add("MC/EventLoss/NchGenerated_PhysicsSelected", "Generated charged multiplicity (physics selected);N_{ch}^{gen} (|#eta|<0.8);Counts", + HistType::kTH1D, {{200, 0, 200}}); + ue.add("MC/EventLoss/NchGenerated_Reconstructed", "Generated charged multiplicity (reconstructed);N_{ch}^{gen} (|#eta|<0.8);Counts", + HistType::kTH1D, {{200, 0, 200}}); + + // pT vs Multiplicity + ue.add("MC/GenPtVsNch", "Generated pT vs Multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", + HistType::kTH2D, {ptAxis, {200, 0, 200}}); + ue.add("MC/GenPtVsNch_PhysicsSelected", "Generated pT vs Multiplicity (physics selected);#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", + HistType::kTH2D, {ptAxis, {200, 0, 200}}); + + // Centrality vs Multiplicity correlations - USE STANDARD BINNING FOR THESE + ue.add("MC/EventLoss/GenMultVsCent", "Generated charged particles vs FT0M centrality;FT0M Centrality (%);N_{ch}^{gen} (|#eta|<0.8)", + HistType::kTH2D, {centAxis, multAxis}); + ue.add("MC/EventLoss/GenMultVsCent_Selected", "Generated vs FT0M centrality (selected events);FT0M Centrality (%);N_{ch}^{gen}", + HistType::kTH2D, {centAxis, multAxis}); + ue.add("MC/EventLoss/GenMultVsCent_Rejected", "Generated vs FT0M centrality (rejected events);FT0M Centrality (%);N_{ch}^{gen}", + HistType::kTH2D, {centAxis, multAxis}); + + // TPC cluster histograms + ue.add("hNclFoundTPC", "Number of TPC found clusters", + HistType::kTH1D, {{200, 0, 200, "N_{cl, found}"}}); + ue.add("hNclPIDTPC", "Number of TPC PID clusters", + HistType::kTH1D, {{200, 0, 200, "N_{cl, PID}"}}); + ue.add("hNclFoundTPCvsPt", "TPC found clusters vs pT;#it{p}_{T} (GeV/#it{c});N_{cl,found}", + HistType::kTH2D, {ptAxis, {200, 0., 200.}}); + ue.add("hNclPIDTPCvsPt", "TPC PID clusters vs pT;#it{p}_{T} (GeV/#it{c});N_{cl,PID}", + HistType::kTH2D, {ptAxis, {200, 0., 200.}}); + + // Inclusive histograms + ue.add("Inclusive/hPtPrimGenAll", "All generated primaries (no cuts);#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + ue.add("Inclusive/hPtPrimBadVertex", "Generated primaries (bad vertex);#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + ue.add("Inclusive/hPtPrimGen", "Generated primaries (after physics selection);#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + ue.add("Inclusive/hPtPrimRecoEv", "Generated primaries (reco events);#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + ue.add("Inclusive/hPtPrimGoodEv", "Generated primaries (good events);#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + + ue.add("Inclusive/hPtNumEff", "Tracking efficiency numerator;#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + ue.add("Inclusive/hPtDenEff", "Tracking efficiency denominator;#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + + ue.add("Inclusive/hPtAllReco", "All reconstructed tracks;#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + ue.add("Inclusive/hPtPrimReco", "Reconstructed primaries;#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + ue.add("Inclusive/hPtSecReco", "Reconstructed secondaries;#it{p}_{T} (GeV/#it{c});Counts", + HistType::kTH1D, {ptAxis}); + + ue.add("Inclusive/hPtMeasuredVsCent", "All measured tracks (PID) vs centrality;#it{p}_{T} (GeV/#it{c});FT0M Centrality (%)", + HistType::kTH2D, {ptAxis, centAxis}); + + // Particle-specific histograms + const std::array particleNames = {"Pion", "Kaon", "Proton"}; + const std::array particleSymbols = {"#pi^{#pm}", "K^{#pm}", "p+#bar{p}"}; + + for (int iSpecies = 0; iSpecies < kNSpecies; ++iSpecies) { + const auto& name = particleNames[iSpecies]; + const auto& symbol = particleSymbols[iSpecies]; + + ue.add(Form("%s/hPtPrimGenAll", name.c_str()), + Form("All generated %s (no cuts);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + ue.add(Form("%s/hPtPrimBadVertex", name.c_str()), + Form("Generated %s (bad vertex);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + ue.add(Form("%s/hPtPrimGen", name.c_str()), + Form("Generated %s (after physics selection);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + ue.add(Form("%s/hPtPrimRecoEv", name.c_str()), + Form("Generated %s (reco events);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + ue.add(Form("%s/hPtPrimGoodEv", name.c_str()), + Form("Generated %s (good events);#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + + ue.add(Form("%s/hPtNumEff", name.c_str()), + Form("%s tracking efficiency numerator;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + ue.add(Form("%s/hPtDenEff", name.c_str()), + Form("%s tracking efficiency denominator;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + + ue.add(Form("%s/hPtAllReco", name.c_str()), + Form("All reconstructed %s;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + ue.add(Form("%s/hPtPrimReco", name.c_str()), + Form("Reconstructed primary %s;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + ue.add(Form("%s/hPtSecReco", name.c_str()), + Form("Reconstructed secondary %s;#it{p}_{T} (GeV/#it{c});Counts", symbol.c_str()), + HistType::kTH1D, {ptAxis}); + + ue.add(Form("%s/hPtMeasuredVsCent", name.c_str()), + Form("Measured %s (PID) vs centrality;#it{p}_{T} (GeV/#it{c});FT0M Centrality (%%)", symbol.c_str()), + HistType::kTH2D, {ptAxis, centAxis}); + + if (enablePIDHistograms) { + ue.add(Form("%s/hNsigmaTPC", name.c_str()), + Form("TPC n#sigma %s;#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", symbol.c_str()), + HistType::kTH2D, {ptAxis, {200, -10, 10}}); + } + } + + // Event selection histogram + constexpr int NEvSelBins = 20; + constexpr float EvSelMin = 0.5f; + constexpr float EvSelMax = 20.5f; + ue.add("evsel", "Event selection", HistType::kTH1D, {{NEvSelBins, EvSelMin, EvSelMax}}); + auto h = ue.get(HIST("evsel")); + h->GetXaxis()->SetBinLabel(1, "Events read"); + h->GetXaxis()->SetBinLabel(4, "Trigger passed"); + h->GetXaxis()->SetBinLabel(5, "NoITSROFrameBorder"); + h->GetXaxis()->SetBinLabel(6, "NoSameBunchPileup"); + h->GetXaxis()->SetBinLabel(7, "IsGoodZvtxFT0vsPV"); + h->GetXaxis()->SetBinLabel(8, "IsVertexITSTPC"); + h->GetXaxis()->SetBinLabel(9, "NoTimeFrameBorder"); + h->GetXaxis()->SetBinLabel(13, "posZ passed"); + + // Basic tracking histograms + ue.add("hEta", "Track eta;#eta;Counts", HistType::kTH1D, {{20, -0.8, 0.8}}); + ue.add("hPhi", "Track phi;#varphi (rad);Counts", HistType::kTH1D, {{64, 0, TwoPI}}); + ue.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); + ue.add("hvtxZmc", "MC vertex Z;Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); + + LOG(info) << "=== Initialized MultiplicityPt task with full centrality diagnostics ==="; + LOG(info) << "Standard centrality binning: " << centBinningStd.size() - 1 << " bins (0-100%)"; + LOG(info) << "Fine centrality binning: " << centBinningFine.size() - 1 << " bins (0-100%)"; +} + +//============================================================================= +// Process Functions +//============================================================================= + +void MultiplicityPt::processData(CollisionTableData::iterator const& /*collision*/, + TrackTableData const& /*tracks*/, + BCsRun3 const& /*bcs*/) +{ + // Intentionally empty - data processing disabled +} + +void MultiplicityPt::processMC(TrackTableMC const& tracks, + aod::McParticles const& particles, + aod::McCollisions const& mcCollisions, + RecoCollisions const& collisions, + aod::McCollisionLabels const& labels, + aod::McCentFT0Ms const& centTable, + BCsRun3 const& /*bcs*/) +{ + LOG(info) << "\n=== processMC START ==="; + LOG(info) << "Total MC collisions (generated): " << mcCollisions.size(); + LOG(info) << "Total reconstructed collisions: " << collisions.size(); + LOG(info) << "Total collision labels: " << labels.size(); + LOG(info) << "Total centrality entries: " << centTable.size(); + + //=========================================================================== + // DEBUG: Print raw centrality information first + //=========================================================================== + LOG(info) << "\n=== CENTRALITY DEBUG - RAW DATA ==="; + LOG(info) << "First 20 centrality values from centTable:"; + int debugCount = 0; + float minCent = 999.0f, maxCent = -999.0f; + std::map centDistribution; + + for (const auto& cent : centTable) { + float c = cent.centFT0M(); + if (debugCount < DebugCountMax) { + LOG(info) << " Cent entry " << debugCount << ": " << c; + } + minCent = std::min(minCent, c); + maxCent = std::max(maxCent, c); + + int bin10 = static_cast(c / 10) * 10; + centDistribution[bin10]++; + debugCount++; + } + + LOG(info) << "Centrality range: [" << minCent << ", " << maxCent << "]"; + LOG(info) << "Distribution by 10% bins:"; + for (int i = 0; i < CentBinMax; i += 10) { + LOG(info) << " " << i << "-" << i + 10 << "%: " << centDistribution[i]; + } + + // Check if centrality is inverted (0 = peripheral, 100 = central) + // If minCent is near 0 and maxCent near 100, check correlation with multiplicity + LOG(info) << "Checking if centrality might be inverted..."; + LOG(info) << "Will check correlation with multiplicity in the next step."; + + //=========================================================================== + // FIRST PASS: Build maps of MC collision ID to generated particle counts + //=========================================================================== + std::map mcCollisionToNch; + std::map mcCollisionVz; + std::set physicsSelectedMCCollisions; + std::map mcCollisionToINELClass; // 0=INEL0, 1=INEL>0, 2=INEL>1 + + ue.fill(HIST("MC/GenRecoCollisions"), 1.f, mcCollisions.size()); + ue.fill(HIST("MC/GenRecoCollisions"), 2.f, collisions.size()); + + LOG(info) << "\n--- FIRST PASS: Building MC collision maps ---"; + + int mcWithParticles = 0; + int mcINELgt0 = 0, mcINELgt1 = 0; + + for (const auto& mcCollision : mcCollisions) { + int64_t mcCollId = mcCollision.globalIndex(); + auto particlesInCollision = particles.sliceBy(perMCCol, mcCollId); + + int nGenCharged = countGeneratedChargedPrimaries(particlesInCollision, cfgCutEtaMax.value, cfgTrkLowPtCut.value); + + mcCollisionToNch[mcCollId] = nGenCharged; + mcCollisionVz[mcCollId] = mcCollision.posZ(); + + // Determine INEL class + bool inel0 = o2::pwglf::isINELgt0mc(particlesInCollision, pdg); + bool inel1 = o2::pwglf::isINELgt1mc(particlesInCollision, pdg); + + int inelClass = 0; + if (inel1) + inelClass = 2; + else if (inel0) + inelClass = 1; + mcCollisionToINELClass[mcCollId] = inelClass; + + ue.fill(HIST("INEL/hINELClass"), inelClass); + + if (inel0) + mcINELgt0++; + if (inel1) + mcINELgt1++; + if (nGenCharged > 0) + mcWithParticles++; + + ue.fill(HIST("MC/EventLoss/NchGenerated"), nGenCharged); + + // Physics selection based on vertex and INEL cuts + bool physicsSelected = true; + + if (std::abs(mcCollision.posZ()) > cfgCutVertex.value) { + physicsSelected = false; + } + + // Apply INEL cut based on configuration + if (cfgINELCut.value == INELgt0 && !inel0) { + physicsSelected = false; + } + if (cfgINELCut.value == INELgt1 && !inel1) { + physicsSelected = false; + } + + if (physicsSelected) { + physicsSelectedMCCollisions.insert(mcCollId); + ue.fill(HIST("MC/EventLoss/NchGenerated_PhysicsSelected"), nGenCharged); + + if (inel0) { + ue.fill(HIST("MC/GenRecoCollisions"), 3.f); + } + if (inel1) { + ue.fill(HIST("MC/GenRecoCollisions"), 4.f); + } + } + } + + LOG(info) << "\n--- FIRST PASS SUMMARY ---"; + LOG(info) << "Total MC collisions processed: " << mcCollisions.size(); + LOG(info) << "MC collisions with particles: " << mcWithParticles; + LOG(info) << "INEL0: " << (mcCollisions.size() - mcINELgt0); + LOG(info) << "INEL>0: " << mcINELgt0; + LOG(info) << "INEL>1: " << mcINELgt1; + LOG(info) << "Physics-selected MC collisions: " << physicsSelectedMCCollisions.size(); + + //=========================================================================== + // Build maps for labels and centrality + //=========================================================================== + std::map recoToMcMap; + std::map recoToCentMap; + + size_t nCollisions = collisions.size(); + + // Associate labels with collisions by index + size_t iLabel = 0; + for (const auto& label : labels) { + if (iLabel < nCollisions) { + const auto& collision = collisions.iteratorAt(iLabel); + int64_t recoCollId = collision.globalIndex(); + int64_t mcCollId = label.mcCollisionId(); + recoToMcMap[recoCollId] = mcCollId; + } + iLabel++; + } + + // Associate centrality with collisions by index + size_t iCent = 0; + for (const auto& cent : centTable) { + if (iCent < nCollisions) { + const auto& collision = collisions.iteratorAt(iCent); + int64_t recoCollId = collision.globalIndex(); + float centValue = cent.centFT0M(); + + // Fill raw centrality histogram + ue.fill(HIST("Centrality/hCentRaw"), centValue); + + recoToCentMap[recoCollId] = centValue; + } + iCent++; + } + + LOG(info) << "\n--- MAP SIZES ---"; + LOG(info) << "recoToMcMap size: " << recoToMcMap.size(); + LOG(info) << "recoToCentMap size: " << recoToCentMap.size(); + + //=========================================================================== + // DEBUG: Check correlation between centrality and multiplicity + //=========================================================================== + LOG(info) << "\n=== CENTRALITY VS MULTIPLICITY DEBUG ==="; + + // Create temporary vectors to check correlation + std::vector> centMultPairs; + for (const auto& collision : collisions) { + int64_t collId = collision.globalIndex(); + + auto mcIt = recoToMcMap.find(collId); + if (mcIt == recoToMcMap.end()) + continue; + + auto centIt = recoToCentMap.find(collId); + if (centIt == recoToCentMap.end()) + continue; + + auto nchIt = mcCollisionToNch.find(mcIt->second); + if (nchIt == mcCollisionToNch.end()) + continue; + + centMultPairs.push_back({centIt->second, nchIt->second}); + } + + // Sort by centrality + std::sort(centMultPairs.begin(), centMultPairs.end()); + + LOG(info) << "Correlation between centrality and multiplicity:"; + LOG(info) << " If centrality is normal (0=central, 100=peripheral), multiplicity should decrease with centrality"; + LOG(info) << " If inverted (0=peripheral, 100=central), multiplicity should increase with centrality"; + + // Print a few samples across the range + if (centMultPairs.size() > CentMultClasses) { + for (size_t i = 0; i < centMultPairs.size(); i += centMultPairs.size() / 10) { + LOG(info) << " Cent: " << centMultPairs[i].first + << "%, Mult: " << centMultPairs[i].second; + } + } + + //=========================================================================== + // SECOND PASS: Process reconstructed collisions with detailed cut accounting + //=========================================================================== + + LOG(info) << "\n--- SECOND PASS: Processing reconstructed collisions ---"; + + std::set reconstructedMCCollisions; + std::set selectedMCCollisions; + + int nRecoCollisions = 0; + int nSelectedEvents = 0; + int nRejectedEvents = 0; + int nNoMCMatch = 0; + int nNoCent = 0; + int nInvalidCent = 0; + + // Cut counters + int nPassVertex = 0; + int nPassINEL = 0; + int nPassAll = 0; + + // For mean calculations + std::vector centAll, centVertex, centINEL, centSelected; + + for (const auto& collision : collisions) { + nRecoCollisions++; + + int64_t collId = collision.globalIndex(); + + // Fill cut flow + ue.fill(HIST("CutFlow/hCutStats"), 1); + + // Get MC collision ID from labels map + auto mcIt = recoToMcMap.find(collId); + if (mcIt == recoToMcMap.end()) { + nNoMCMatch++; + continue; + } + ue.fill(HIST("CutFlow/hCutStats"), 2); + + int64_t mcCollId = mcIt->second; + + // Get generated multiplicity for this MC collision + auto nchIt = mcCollisionToNch.find(mcCollId); + if (nchIt == mcCollisionToNch.end()) { + continue; + } + + int nGenCharged = nchIt->second; + + // Get INEL class + auto inelIt = mcCollisionToINELClass.find(mcCollId); + int inelClass = (inelIt != mcCollisionToINELClass.end()) ? inelIt->second : 0; + + // Get centrality from cent map + auto centIt = recoToCentMap.find(collId); + if (centIt == recoToCentMap.end()) { + nNoCent++; + continue; + } + ue.fill(HIST("CutFlow/hCutStats"), 3); + + float cent = centIt->second; + if (cent < 0 || cent > CentBinMax) { + nInvalidCent++; + continue; + } + + // Store all events with valid info + centAll.push_back(cent); + ue.fill(HIST("Centrality/hCentVsMult"), cent, nGenCharged); + ue.fill(HIST("Centrality/hMultVsCent"), nGenCharged, cent); + ue.fill(HIST("Centrality/hCentVsVz"), cent, collision.posZ()); + ue.fill(HIST("INEL/hINELVsCent"), cent, inelClass); + + // Track cuts progressively + bool passVertex = std::abs(collision.posZ()) <= cfgCutVertex.value; + if (passVertex) { + centVertex.push_back(cent); + ue.fill(HIST("Centrality/hCentAfterVtx"), cent); + ue.fill(HIST("CutFlow/hCutStats"), 4); + ue.fill(HIST("CutFlow/hCentPerCut"), 4, cent); + nPassVertex++; + } + + // Check INEL selection at generator level + bool passINEL = true; + if (cfgINELCut.value == INELgt0 && inelClass < INELgt0) + passINEL = false; + if (cfgINELCut.value == INELgt1 && inelClass < INELgt1) + passINEL = false; + + if (passINEL) { + centINEL.push_back(cent); + ue.fill(HIST("Centrality/hCentAfterINEL"), cent); + ue.fill(HIST("CutFlow/hCutStats"), 5); + ue.fill(HIST("CutFlow/hCentPerCut"), 5, cent); + nPassINEL++; + } + + // Fill GenMultVsCent for all reconstructed events + ue.fill(HIST("MC/EventLoss/GenMultVsCent"), cent, nGenCharged); + ue.fill(HIST("MC/EventLoss/NchGenerated_Reconstructed"), nGenCharged); + + reconstructedMCCollisions.insert(mcCollId); + + // Apply all cuts + bool passedAll = passVertex && passINEL; + + if (!passedAll) { + ue.fill(HIST("MC/EventLoss/GenMultVsCent_Rejected"), cent, nGenCharged); + nRejectedEvents++; + continue; + } + + // Event passed all selections + centSelected.push_back(cent); + ue.fill(HIST("Centrality/hCentAfterAll"), cent); + ue.fill(HIST("CutFlow/hCutStats"), 6); + ue.fill(HIST("CutFlow/hCentPerCut"), 6, cent); + ue.fill(HIST("MC/EventLoss/GenMultVsCent_Selected"), cent, nGenCharged); + ue.fill(HIST("hvtxZ"), collision.posZ()); + selectedMCCollisions.insert(mcCollId); + nSelectedEvents++; + nPassAll++; + + // Process tracks in selected events + int nTracksInEvent = 0; + for (const auto& track : tracks) { + if (!track.has_collision()) + continue; + if (track.collisionId() != collId) + continue; + + if (!passesTrackSelection(track)) { + continue; + } + nTracksInEvent++; + + // Fill TPC cluster histograms + ue.fill(HIST("hNclFoundTPC"), track.tpcNClsFound()); + ue.fill(HIST("hNclPIDTPC"), track.tpcNClsPID()); + ue.fill(HIST("hNclFoundTPCvsPt"), track.pt(), track.tpcNClsFound()); + ue.fill(HIST("hNclPIDTPCvsPt"), track.pt(), track.tpcNClsPID()); + + ue.fill(HIST("Inclusive/hPtAllReco"), track.pt()); + ue.fill(HIST("Inclusive/hPtMeasuredVsCent"), track.pt(), cent); + ue.fill(HIST("hEta"), track.eta()); + ue.fill(HIST("hPhi"), track.phi()); + + if (track.has_mcParticle()) { + const auto& particle = track.mcParticle(); + int pdgCode = std::abs(particle.pdgCode()); + + if (particle.isPhysicalPrimary()) { + ue.fill(HIST("Inclusive/hPtNumEff"), particle.pt()); + ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + + if (pdgCode == PDGPion) { + ue.fill(HIST("Pion/hPtNumEff"), particle.pt()); + ue.fill(HIST("Pion/hPtPrimReco"), track.pt()); + } else if (pdgCode == PDGKaon) { + ue.fill(HIST("Kaon/hPtNumEff"), particle.pt()); + ue.fill(HIST("Kaon/hPtPrimReco"), track.pt()); + } else if (pdgCode == PDGProton) { + ue.fill(HIST("Proton/hPtNumEff"), particle.pt()); + ue.fill(HIST("Proton/hPtPrimReco"), track.pt()); + } + } else { + ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); + + if (pdgCode == PDGPion) { + ue.fill(HIST("Pion/hPtSecReco"), track.pt()); + } else if (pdgCode == PDGKaon) { + ue.fill(HIST("Kaon/hPtSecReco"), track.pt()); + } else if (pdgCode == PDGProton) { + ue.fill(HIST("Proton/hPtSecReco"), track.pt()); + } + } + } + + int bestSpecies = getBestPIDHypothesis(track); + + if (bestSpecies == kPion) { + ue.fill(HIST("Pion/hPtMeasuredVsCent"), track.pt(), cent); + ue.fill(HIST("Pion/hPtAllReco"), track.pt()); + + if (enablePIDHistograms) { + ue.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); + } + } else if (bestSpecies == kKaon) { + ue.fill(HIST("Kaon/hPtMeasuredVsCent"), track.pt(), cent); + ue.fill(HIST("Kaon/hPtAllReco"), track.pt()); + + if (enablePIDHistograms) { + ue.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); + } + } else if (bestSpecies == kProton) { + ue.fill(HIST("Proton/hPtMeasuredVsCent"), track.pt(), cent); + ue.fill(HIST("Proton/hPtAllReco"), track.pt()); + + if (enablePIDHistograms) { + ue.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); + } + } + } + + // Fill event-level track multiplicity + ue.fill(HIST("Centrality/hRecoMultVsCent"), cent, nTracksInEvent); + } + + // Calculate and display cut statistics + LOG(info) << "\n=== CUT STATISTICS ==="; + LOG(info) << "Total collisions with valid info: " << centAll.size(); + LOG(info) << "Pass vertex cut: " << nPassVertex << " (" + << (centAll.size() > 0 ? 100.0 * nPassVertex / centAll.size() : 0.0) << "%)"; + LOG(info) << "Pass INEL cut: " << nPassINEL << " (" + << (centAll.size() > 0 ? 100.0 * nPassINEL / centAll.size() : 0.0) << "%)"; + LOG(info) << "Pass all cuts: " << nPassAll << " (" + << (centAll.size() > 0 ? 100.0 * nPassAll / centAll.size() : 0.0) << "%)"; + + // Calculate mean centrality at each stage + if (!centAll.empty()) { + float meanAll = std::accumulate(centAll.begin(), centAll.end(), 0.0) / centAll.size(); + float meanVertex = centVertex.empty() ? 0 : std::accumulate(centVertex.begin(), centVertex.end(), 0.0) / centVertex.size(); + float meanINEL = centINEL.empty() ? 0 : std::accumulate(centINEL.begin(), centINEL.end(), 0.0) / centINEL.size(); + float meanSelected = centSelected.empty() ? 0 : std::accumulate(centSelected.begin(), centSelected.end(), 0.0) / centSelected.size(); + + LOG(info) << "\n=== CENTRALITY MEANS ==="; + LOG(info) << "Mean centrality (all): " << meanAll; + LOG(info) << "Mean centrality (after vertex): " << meanVertex; + LOG(info) << "Mean centrality (after INEL): " << meanINEL; + LOG(info) << "Mean centrality (selected): " << meanSelected; + } + + ue.fill(HIST("hEventLossBreakdown"), 1.f, physicsSelectedMCCollisions.size()); + ue.fill(HIST("hEventLossBreakdown"), 2.f, reconstructedMCCollisions.size()); + ue.fill(HIST("hEventLossBreakdown"), 3.f, selectedMCCollisions.size()); + + float efficiency = physicsSelectedMCCollisions.size() > 0 ? 100.f * selectedMCCollisions.size() / physicsSelectedMCCollisions.size() : 0; + ue.fill(HIST("hEventLossBreakdown"), 4.f, efficiency); + + LOG(info) << "\n=== FINAL EFFICIENCY ==="; + LOG(info) << "Physics selected: " << physicsSelectedMCCollisions.size(); + LOG(info) << "Reconstructed: " << reconstructedMCCollisions.size(); + LOG(info) << "Selected: " << selectedMCCollisions.size(); + LOG(info) << "Efficiency: " << efficiency << "%"; + LOG(info) << "=== processMC END ==="; +} From a9d00bfa09043021171bc690d103c0754dfc14ff Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Wed, 25 Mar 2026 14:14:26 -0600 Subject: [PATCH 21/24] Fix whitespace and clang-format --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 31 +++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index 8548be612c8..58a9f6c03e2 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -70,17 +70,17 @@ struct MultiplicityPt { // Service Service pdg; static constexpr int CentBinMax = 100; - static constexpr int MultBinMax = 200; - static constexpr int RecMultBinMax = 100; - static constexpr int DebugCountMax = 20; - static constexpr int CentMultClasses = 10; - - enum INELCutSelection : int { - INEL = 0, - INELgt0 = 1, - INELgt1 = 2 - - }; + static constexpr int MultBinMax = 200; + static constexpr int RecMultBinMax = 100; + static constexpr int DebugCountMax = 20; + static constexpr int CentMultClasses = 10; + + enum INELCutSelection : int { + INEL = 0, + INELgt0 = 1, + INELgt1 = 2 + + }; //=========================================================================== // Configurable Parameters @@ -175,10 +175,9 @@ struct MultiplicityPt { kNSpecies = 3 }; - - static constexpr int PDGPion = kPiPlus; - static constexpr int PDGKaon = kKPlus; - static constexpr int PDGProton = kProton; + static constexpr int PDGPion = kPiPlus; + static constexpr int PDGKaon = kKPlus; + static constexpr int PDGProton = kProton; //=========================================================================== // Helper Functions @@ -420,7 +419,7 @@ void MultiplicityPt::init(InitContext const&) } // Axis definitions - ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; + ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; From 22bf64a87078d9c645e0e69b65673bd499fb3749 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Wed, 25 Mar 2026 14:57:34 -0600 Subject: [PATCH 22/24] Fix format --- PWGLF/Tasks/Nuspex/CMakeLists.txt | 12 ++++++------ PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index ccf311b37c0..0609b38835e 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -166,9 +166,9 @@ o2physics_add_dpl_workflow(he3-lambda-derived-analysis COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(dedx-pid-analysis - SOURCES dedxPidAnalysis.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES dedxPidAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(pikp-raa-analysis SOURCES piKpRAA.cxx @@ -181,9 +181,9 @@ o2physics_add_dpl_workflow(chargedparticle-raa COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(multiplicity-pt - SOURCES multiplicityPt.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES multiplicityPt.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(deuteron-in-jets-trg-pt SOURCES DeuteronInJetsTrgPt.cxx diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index 58a9f6c03e2..59e06791e8f 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -1097,6 +1097,12 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, << (centAll.size() > 0 ? 100.0 * nPassINEL / centAll.size() : 0.0) << "%)"; LOG(info) << "Pass all cuts: " << nPassAll << " (" << (centAll.size() > 0 ? 100.0 * nPassAll / centAll.size() : 0.0) << "%)"; + LOG(info) << "Reco collisions: " << nRecoCollisions; + LOG(info) << "Selected Events: " << nSelectedEvents; + LOG(info) << "Rejected Events: " << nRejectedEvents; + LOG(info) << "No Match: " << nNoMCMatch; + LOG(info) << "No Cent: " << nNoCent; + LOG(info) << "Invalid Cent: " << nInvalidCent; // Calculate mean centrality at each stage if (!centAll.empty()) { From 7459b46dde56eaaf9d612cf9800d022f4c957c71 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 27 Mar 2026 18:08:14 -0600 Subject: [PATCH 23/24] Phi prime cut was added --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 191 +++++++++++++++++++------- 1 file changed, 140 insertions(+), 51 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index 59e06791e8f..3991b923a25 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -29,6 +29,8 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" @@ -62,13 +64,11 @@ using namespace constants::physics; using BCsRun3 = soa::Join; -//============================================================================= -// Main Analysis Struct -//============================================================================= struct MultiplicityPt { // Service Service pdg; + Service ccdb; static constexpr int CentBinMax = 100; static constexpr int MultBinMax = 200; static constexpr int RecMultBinMax = 100; @@ -82,9 +82,6 @@ struct MultiplicityPt { }; - //=========================================================================== - // Configurable Parameters - //=========================================================================== Configurable isRun3{"isRun3", true, "is Run3 dataset"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgINELCut{"cfgINELCut", 0, "INEL event selection: 0 no sel, 1 INEL>0, 2 INEL>1"}; @@ -123,7 +120,12 @@ struct MultiplicityPt { Configurable nClTPCPIDCut{"nClTPCPIDCut", true, "Apply TPC clusters for PID cut"}; // Phi cut parameters - Configurable applyPhiCut{"applyPhiCut", false, "Apply phi sector cut"}; + Configurable applyPhiCut{"applyPhiCut", false, "Apply phi sector cut to remove problematic TPC regions"}; + Configurable pTthresholdPhiCut{"pTthresholdPhiCut", 2.0f, "pT threshold above which to apply phi cut"}; + Configurable phiCutLowParam1{"phiCutLowParam1", 0.119297, "First parameter for low phi cut"}; + Configurable phiCutLowParam2{"phiCutLowParam2", 0.000379693, "Second parameter for low phi cut"}; + Configurable phiCutHighParam1{"phiCutHighParam1", 0.16685, "First parameter for high phi cut"}; + Configurable phiCutHighParam2{"phiCutHighParam2", 0.00981942, "Second parameter for high phi cut"}; // Basic track cuts Configurable cfgTrkEtaCut{"cfgTrkEtaCut", 0.8f, "Eta range for tracks"}; @@ -136,14 +138,14 @@ struct MultiplicityPt { // Custom track cuts matching spectraTOF TrackSelection customTrackCuts; + + // TF1 pointers for phi cuts + TF1* fphiCutLow = nullptr; + TF1* fphiCutHigh = nullptr; // Histogram Registry HistogramRegistry ue; - //=========================================================================== - // Table Definitions - Using individual tables, not joined for MC - //=========================================================================== - // Data collisions (not used but kept for completeness) using CollisionTableData = soa::Join; @@ -165,9 +167,6 @@ struct MultiplicityPt { // Preslice for MC particles Preslice perMCCol = aod::mcparticle::mcCollisionId; - //=========================================================================== - // Constants - //=========================================================================== enum ParticleSpecies : int { kPion = 0, kKaon = 1, @@ -179,9 +178,69 @@ struct MultiplicityPt { static constexpr int PDGKaon = kKPlus; static constexpr int PDGProton = kProton; - //=========================================================================== - // Helper Functions - //=========================================================================== + + // Get magnetic field from CCDB + int getMagneticField(uint64_t timestamp) + { + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + + // Get transformed phi for phi cut (with magnetic field) + float getTransformedPhi(const float phi, const int charge, const float magField) const + { + float transformedPhi = phi; + if (magField < 0) { + transformedPhi = o2::constants::math::TwoPI - transformedPhi; + } + if (charge < 0) { + transformedPhi = o2::constants::math::TwoPI - transformedPhi; + } + transformedPhi += o2::constants::math::PI / 18.0f; + transformedPhi = std::fmod(transformedPhi, o2::constants::math::PI / 9.0f); + return transformedPhi; + } + + // Phi cut function (with magnetic field) + template + bool passedPhiCut(const TrackType& track, float magField) const + { + if (!applyPhiCut.value) { + return true; + } + + if (track.pt() < pTthresholdPhiCut.value) { + return true; + } + + float pt = track.pt(); + float phi = track.phi(); + int charge = track.sign(); + + if (magField < 0) { + phi = o2::constants::math::TwoPI - phi; + } + if (charge < 0) { + phi = o2::constants::math::TwoPI - phi; + } + + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + + if (phi < fphiCutHigh->Eval(pt) && phi > fphiCutLow->Eval(pt)) { + return false; + } + + return true; + } template int countGeneratedChargedPrimaries(const ParticleContainer& particles, float etaMax, float ptMin) const @@ -257,7 +316,7 @@ struct MultiplicityPt { } template - bool passesTrackSelection(TrackType const& track) const + bool passesTrackSelection(TrackType const& track, float magField = 0) const { if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) return false; @@ -276,6 +335,10 @@ struct MultiplicityPt { if (!passedNClTPCPIDCut(track)) return false; + + // Add phi cut with magnetic field + if (!passedPhiCut(track, magField)) + return false; return true; } @@ -348,9 +411,7 @@ struct MultiplicityPt { return true; } - //=========================================================================== - // Process Switches - //=========================================================================== + void processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks, BCsRun3 const& bcs); @@ -365,9 +426,7 @@ struct MultiplicityPt { BCsRun3 const& bcs); PROCESS_SWITCH(MultiplicityPt, processMC, "process MC", true); - //=========================================================================== - // Standard Framework Functions - //=========================================================================== + void init(InitContext const&); void endOfStream(EndOfStreamContext& /*eos*/) @@ -382,17 +441,12 @@ struct MultiplicityPt { } }; -//============================================================================= -// Workflow Definition -//============================================================================= + WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } -//============================================================================= -// Implementation of Member Functions -//============================================================================= void MultiplicityPt::init(InitContext const&) { @@ -400,6 +454,25 @@ void MultiplicityPt::init(InitContext const&) LOG(info) << "Initializing MultiplicityPt task with full centrality diagnostics"; LOG(info) << "=================================================="; + // Initialize phi cut functions + if (applyPhiCut.value) { + fphiCutLow = new TF1("StandardPhiCutLow", + Form("%f/x/x+pi/18.0-%f", + phiCutLowParam1.value, phiCutLowParam2.value), + 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", + Form("%f/x+pi/18.0+%f", + phiCutHighParam1.value, phiCutHighParam2.value), + 0, 50); + + LOGF(info, "=== Phi Cut Parameters ==="); + LOGF(info, "Low cut: %.6f/x² + pi/18 - %.6f", + phiCutLowParam1.value, phiCutLowParam2.value); + LOGF(info, "High cut: %.6f/x + pi/18 + %.6f", + phiCutHighParam1.value, phiCutHighParam2.value); + LOGF(info, "Applied for pT > %.1f GeV/c", pTthresholdPhiCut.value); + } + if (useCustomTrackCuts.value) { LOG(info) << "Using custom track cuts matching spectraTOF approach"; customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); @@ -448,10 +521,6 @@ void MultiplicityPt::init(InitContext const&) } AxisSpec recoMultAxis = {recoMultBins, "N_{ch}^{reco}"}; - //=========================================================================== - // Comprehensive Histogram Registration - //=========================================================================== - // Centrality diagnostic histograms - USE FINE BINNING ue.add("Centrality/hCentRaw", "Raw FT0M Centrality (no cuts);Centrality (%);Counts", HistType::kTH1D, {centFineAxis}); @@ -578,6 +647,16 @@ void MultiplicityPt::init(InitContext const&) ue.add("Inclusive/hPtMeasuredVsCent", "All measured tracks (PID) vs centrality;#it{p}_{T} (GeV/#it{c});FT0M Centrality (%)", HistType::kTH2D, {ptAxis, centAxis}); + // Phi cut monitoring histograms + if (applyPhiCut.value) { + ue.add("PhiCut/hPtVsPhiPrimeBefore", "pT vs φ' before cut;p_{T} (GeV/c);φ'", + HistType::kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); + ue.add("PhiCut/hPtVsPhiPrimeAfter", "pT vs φ' after cut;p_{T} (GeV/c);φ'", + HistType::kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); + ue.add("PhiCut/hRejectionRate", "Track rejection rate by phi cut;p_{T} (GeV/c);Rejection Rate", + HistType::kTProfile, {{100, 0, 10}}); + } + // Particle-specific histograms const std::array particleNames = {"Pion", "Kaon", "Proton"}; const std::array particleSymbols = {"#pi^{#pm}", "K^{#pm}", "p+#bar{p}"}; @@ -654,12 +733,11 @@ void MultiplicityPt::init(InitContext const&) LOG(info) << "=== Initialized MultiplicityPt task with full centrality diagnostics ==="; LOG(info) << "Standard centrality binning: " << centBinningStd.size() - 1 << " bins (0-100%)"; LOG(info) << "Fine centrality binning: " << centBinningFine.size() - 1 << " bins (0-100%)"; + if (applyPhiCut.value) { + LOG(info) << "Phi cut ENABLED for pT > " << pTthresholdPhiCut.value << " GeV/c"; + } } -//============================================================================= -// Process Functions -//============================================================================= - void MultiplicityPt::processData(CollisionTableData::iterator const& /*collision*/, TrackTableData const& /*tracks*/, BCsRun3 const& /*bcs*/) @@ -681,9 +759,7 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, LOG(info) << "Total collision labels: " << labels.size(); LOG(info) << "Total centrality entries: " << centTable.size(); - //=========================================================================== - // DEBUG: Print raw centrality information first - //=========================================================================== + LOG(info) << "\n=== CENTRALITY DEBUG - RAW DATA ==="; LOG(info) << "First 20 centrality values from centTable:"; int debugCount = 0; @@ -714,9 +790,7 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, LOG(info) << "Checking if centrality might be inverted..."; LOG(info) << "Will check correlation with multiplicity in the next step."; - //=========================================================================== - // FIRST PASS: Build maps of MC collision ID to generated particle counts - //=========================================================================== + std::map mcCollisionToNch; std::map mcCollisionVz; std::set physicsSelectedMCCollisions; @@ -797,9 +871,6 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, LOG(info) << "INEL>1: " << mcINELgt1; LOG(info) << "Physics-selected MC collisions: " << physicsSelectedMCCollisions.size(); - //=========================================================================== - // Build maps for labels and centrality - //=========================================================================== std::map recoToMcMap; std::map recoToCentMap; @@ -837,9 +908,7 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, LOG(info) << "recoToMcMap size: " << recoToMcMap.size(); LOG(info) << "recoToCentMap size: " << recoToCentMap.size(); - //=========================================================================== - // DEBUG: Check correlation between centrality and multiplicity - //=========================================================================== + LOG(info) << "\n=== CENTRALITY VS MULTIPLICITY DEBUG ==="; // Create temporary vectors to check correlation @@ -1003,6 +1072,13 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, nSelectedEvents++; nPassAll++; + // Get magnetic field for phi cut + float magField = 0; + if (applyPhiCut.value) { + const auto& bc = collision.bc_as(); + magField = getMagneticField(bc.timestamp()); + } + // Process tracks in selected events int nTracksInEvent = 0; for (const auto& track : tracks) { @@ -1011,9 +1087,22 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, if (track.collisionId() != collId) continue; - if (!passesTrackSelection(track)) { + // Fill phi cut monitoring before cut + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + ue.fill(HIST("PhiCut/hPtVsPhiPrimeBefore"), track.pt(), phiPrime); + } + + if (!passesTrackSelection(track, magField)) { continue; } + + // Fill phi cut monitoring after cut + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + ue.fill(HIST("PhiCut/hPtVsPhiPrimeAfter"), track.pt(), phiPrime); + } + nTracksInEvent++; // Fill TPC cluster histograms From 01a01d7f6ec7313f416b9d3dc06b29aaf2838693 Mon Sep 17 00:00:00 2001 From: Paola Vargas Torres Date: Fri, 27 Mar 2026 18:15:20 -0600 Subject: [PATCH 24/24] Phi prime cut was added --- PWGLF/Tasks/Nuspex/multiplicityPt.cxx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index 3991b923a25..1a71c04db8b 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -138,7 +138,7 @@ struct MultiplicityPt { // Custom track cuts matching spectraTOF TrackSelection customTrackCuts; - + // TF1 pointers for phi cuts TF1* fphiCutLow = nullptr; TF1* fphiCutHigh = nullptr; @@ -178,7 +178,6 @@ struct MultiplicityPt { static constexpr int PDGKaon = kKPlus; static constexpr int PDGProton = kProton; - // Get magnetic field from CCDB int getMagneticField(uint64_t timestamp) { @@ -335,7 +334,7 @@ struct MultiplicityPt { if (!passedNClTPCPIDCut(track)) return false; - + // Add phi cut with magnetic field if (!passedPhiCut(track, magField)) return false; @@ -411,7 +410,6 @@ struct MultiplicityPt { return true; } - void processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks, BCsRun3 const& bcs); @@ -426,7 +424,6 @@ struct MultiplicityPt { BCsRun3 const& bcs); PROCESS_SWITCH(MultiplicityPt, processMC, "process MC", true); - void init(InitContext const&); void endOfStream(EndOfStreamContext& /*eos*/) @@ -441,13 +438,11 @@ struct MultiplicityPt { } }; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } - void MultiplicityPt::init(InitContext const&) { LOG(info) << "=================================================="; @@ -759,7 +754,6 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, LOG(info) << "Total collision labels: " << labels.size(); LOG(info) << "Total centrality entries: " << centTable.size(); - LOG(info) << "\n=== CENTRALITY DEBUG - RAW DATA ==="; LOG(info) << "First 20 centrality values from centTable:"; int debugCount = 0; @@ -790,7 +784,6 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, LOG(info) << "Checking if centrality might be inverted..."; LOG(info) << "Will check correlation with multiplicity in the next step."; - std::map mcCollisionToNch; std::map mcCollisionVz; std::set physicsSelectedMCCollisions; @@ -908,7 +901,6 @@ void MultiplicityPt::processMC(TrackTableMC const& tracks, LOG(info) << "recoToMcMap size: " << recoToMcMap.size(); LOG(info) << "recoToCentMap size: " << recoToCentMap.size(); - LOG(info) << "\n=== CENTRALITY VS MULTIPLICITY DEBUG ==="; // Create temporary vectors to check correlation