From 090eed03101d9815f9f67ff2b7dabaee9c05700c Mon Sep 17 00:00:00 2001 From: Swati Saha Date: Wed, 29 Oct 2025 13:03:15 +0530 Subject: [PATCH 1/3] Added event selection cut of IsGoodZVtxFT0vsPV --- PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx index dd212faf22d..77706f1bfd6 100644 --- a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx @@ -85,6 +85,7 @@ struct MeanptFluctuationsQAQnTable { Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time interval with dead ITS zone"}; Configurable cfgEvSelkNoITSROFrameBorder{"cfgEvSelkNoITSROFrameBorder", true, "ITSROFrame border event selection cut"}; Configurable cfgEvSelkNoTimeFrameBorder{"cfgEvSelkNoTimeFrameBorder", true, "TimeFrame border event selection cut"}; + Configurable cfgEvSelUseGoodZvtxFT0vsPV{"cfgEvSelUseGoodZvtxFT0vsPV", true, "GoodZvertex and FT0 vs PV cut"}; Configurable cfgCentralityEstimator{"cfgCentralityEstimator", 1, "Centrlaity estimatore choice: 1-->FT0C, 2-->FT0A; 3-->FT0M, 4-->FV0A"}; O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") @@ -329,6 +330,9 @@ struct MeanptFluctuationsQAQnTable { if (cfgEvSelkNoTimeFrameBorder && !(coll.selection_bit(o2::aod::evsel::kNoTimeFrameBorder))) { return; } + if (cfgEvSelUseGoodZvtxFT0vsPV && !(coll.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV))) { + return; + } histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_PVTracks_beforeSel"), coll.multNTracksPV(), inputTracks.size()); histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_centFT0C_beforeSel"), coll.centFT0C(), inputTracks.size()); From 9947ac8459a7cb3c6e693b28da9cdc806007c00f Mon Sep 17 00:00:00 2001 From: Swati Saha Date: Wed, 29 Oct 2025 17:41:03 +0530 Subject: [PATCH 2/3] Added event selection cut of IsGoodZVtxFT0vsPV and ITS PID --- .../Tasks/v0ptHadPiKaProt.cxx | 138 +++++++++++++++++- 1 file changed, 130 insertions(+), 8 deletions(-) diff --git a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx index f0ec5f81685..4f31318569b 100644 --- a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx @@ -34,6 +34,7 @@ #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" #include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/Track.h" #include @@ -63,8 +64,36 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +static constexpr float LongArrayFloat[3][20] = {{1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {2.1, 2.2, 2.3, -2.1, -2.2, -2.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {3.1, 3.2, 3.3, -3.1, -3.2, -3.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}}; + struct V0ptHadPiKaProt { + // ITS response + o2::aod::ITSResponse itsResponse; + // Connect to ccdb + Service ccdb; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable ccdbUrl{"ccdbUrl", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; + + enum Particles { + PIONS = 0, + KAONS, + PROTONS + }; + enum ParticleNsigma { + kPionUpCut = 0, + kKaonUpCut, + kProtonUpCut, + kPionLowCut, + kKaonLowCut, + kProtonLowCut + }; + enum DetectorType { + kTPC = 0, + kTOF, + kITS + }; + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutTpcChi2NCl{"cfgCutTpcChi2NCl", 2.5f, "Maximum TPCchi2NCl"}; Configurable cfgCutItsChi2NCl{"cfgCutItsChi2NCl", 36.0f, "Maximum ITSchi2NCl"}; @@ -92,11 +121,11 @@ struct V0ptHadPiKaProt { Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time interval with dead ITS zone"}; Configurable cfgEvSelkNoITSROFrameBorder{"cfgEvSelkNoITSROFrameBorder", true, "ITSROFrame border event selection cut"}; Configurable cfgEvSelkNoTimeFrameBorder{"cfgEvSelkNoTimeFrameBorder", true, "TimeFrame border event selection cut"}; - - // Connect to ccdb - Service ccdb; - Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; - Configurable ccdbUrl{"ccdbUrl", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; + Configurable cfgEvSelUseGoodZvtxFT0vsPV{"cfgEvSelUseGoodZvtxFT0vsPV", true, "GoodZvertex and FT0 vs PV cut"}; + Configurable cfgUseItsPID{"cfgUseItsPID", false, "Use ITS PID for particle identification"}; + Configurable cfgPtCutTOF{"cfgPtCutTOF", 0.3f, "Minimum pt to use TOF N-sigma"}; + Configurable> nSigmas{"nSigmas", {LongArrayFloat[0], 3, 6, {"TPC", "TOF", "ITS"}, {"pos_pi", "pos_ka", "pos_pr", "neg_pi", "neg_ka", "neg_pr"}}, "Labeled array for n-sigma values for TPC, TOF, ITS for pions, kaons, protons (positive and negative)"}; + Configurable cfgUseRun3V2PID{"cfgUseRun3V2PID", true, "True if PID cuts to be used are similar to Run3 v2 PID analysis"}; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; std::vector>> subSample; @@ -110,9 +139,35 @@ struct V0ptHadPiKaProt { using AodCollisions = soa::Filtered>; using AodTracks = soa::Filtered>; + std::array tofNsigmaCut; + std::array itsNsigmaCut; + std::array tpcNsigmaCut; + // Equivalent of the AliRoot task UserCreateOutputObjects void init(o2::framework::InitContext&) { + // Get nSigma values of TPC, TOF, ITS for various particles from the matrix "nSigmas" + tpcNsigmaCut[kPionUpCut] = nSigmas->getData()[kTPC][kPionUpCut]; + tpcNsigmaCut[kKaonUpCut] = nSigmas->getData()[kTPC][kKaonUpCut]; + tpcNsigmaCut[kProtonUpCut] = nSigmas->getData()[kTPC][kProtonUpCut]; + tpcNsigmaCut[kPionLowCut] = nSigmas->getData()[kTPC][kPionLowCut]; + tpcNsigmaCut[kKaonLowCut] = nSigmas->getData()[kTPC][kKaonLowCut]; + tpcNsigmaCut[kProtonLowCut] = nSigmas->getData()[kTPC][kProtonLowCut]; + + tofNsigmaCut[kPionUpCut] = nSigmas->getData()[kTOF][kPionUpCut]; + tofNsigmaCut[kKaonUpCut] = nSigmas->getData()[kTOF][kKaonUpCut]; + tofNsigmaCut[kProtonUpCut] = nSigmas->getData()[kTOF][kProtonUpCut]; + tofNsigmaCut[kPionLowCut] = nSigmas->getData()[kTOF][kPionLowCut]; + tofNsigmaCut[kKaonLowCut] = nSigmas->getData()[kTOF][kKaonLowCut]; + tofNsigmaCut[kProtonLowCut] = nSigmas->getData()[kTOF][kProtonLowCut]; + + itsNsigmaCut[kPionUpCut] = nSigmas->getData()[kITS][kPionUpCut]; + itsNsigmaCut[kKaonUpCut] = nSigmas->getData()[kITS][kKaonUpCut]; + itsNsigmaCut[kProtonUpCut] = nSigmas->getData()[kITS][kProtonUpCut]; + itsNsigmaCut[kPionLowCut] = nSigmas->getData()[kITS][kPionLowCut]; + itsNsigmaCut[kKaonLowCut] = nSigmas->getData()[kITS][kKaonLowCut]; + itsNsigmaCut[kProtonLowCut] = nSigmas->getData()[kITS][kProtonLowCut]; + // Define axes std::vector ptBin = {0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.5, 4.0, 5.0, 6.0, 8.0, 10.0}; AxisSpec ptAxis = {ptBin, "#it{p}_{T} (GeV/#it{c})"}; @@ -332,6 +387,56 @@ struct V0ptHadPiKaProt { return false; } + template + int getNsigmaPID(TTrack track) + { + // Computing Nsigma arrays for pion, kaon, and protons + std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; + std::array nSigmaTOF = {track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()}; + std::array nSigmaITS = {itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track)}; + int pid = 0; // 0 = not identified, 1 = pion, 2 = kaon, 3 = proton + + std::array nSigmaToUse = cfgUseItsPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS + std::array detectorNsigmaCut = cfgUseItsPID ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS + + bool isPion, isKaon, isProton; + bool isDetectedPion = nSigmaToUse[PIONS] < detectorNsigmaCut[kPionUpCut] && nSigmaToUse[PIONS] > detectorNsigmaCut[kPionLowCut]; + bool isDetectedKaon = nSigmaToUse[KAONS] < detectorNsigmaCut[kKaonUpCut] && nSigmaToUse[KAONS] > detectorNsigmaCut[kKaonLowCut]; + bool isDetectedProton = nSigmaToUse[PROTONS] < detectorNsigmaCut[kProtonUpCut] && nSigmaToUse[PROTONS] > detectorNsigmaCut[kProtonLowCut]; + + bool isTofPion = nSigmaTOF[PIONS] < tofNsigmaCut[kPionUpCut] && nSigmaTOF[PIONS] > tofNsigmaCut[kPionLowCut]; + bool isTofKaon = nSigmaTOF[KAONS] < tofNsigmaCut[kKaonUpCut] && nSigmaTOF[KAONS] > tofNsigmaCut[kKaonLowCut]; + bool isTofProton = nSigmaTOF[PROTONS] < tofNsigmaCut[kProtonUpCut] && nSigmaTOF[PROTONS] > tofNsigmaCut[kProtonLowCut]; + + if (track.pt() > cfgPtCutTOF && !track.hasTOF()) { + return 0; + } else if (track.pt() > cfgPtCutTOF && track.hasTOF()) { + isPion = isTofPion && isDetectedPion; + isKaon = isTofKaon && isDetectedKaon; + isProton = isTofProton && isDetectedProton; + } else { + isPion = isDetectedPion; + isKaon = isDetectedKaon; + isProton = isDetectedProton; + } + + if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) { + return 0; // more than one particle satisfy the criteria + } + + if (isPion) { + pid = PIONS + 1; + } else if (isKaon) { + pid = KAONS + 1; + } else if (isProton) { + pid = PROTONS + 1; + } else { + return 0; // no particle satisfies the criteria + } + + return pid; // 0 = not identified, 1 = pion, 2 = kaon, 3 = proton + } + // process Data void process(AodCollisions::iterator const& coll, aod::BCsWithTimestamps const&, AodTracks const& inputTracks) { @@ -350,6 +455,9 @@ struct V0ptHadPiKaProt { if (cfgEvSelkNoTimeFrameBorder && !(coll.selection_bit(o2::aod::evsel::kNoTimeFrameBorder))) { return; } + if (cfgEvSelUseGoodZvtxFT0vsPV && !(coll.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV))) { + return; + } // Centrality double cent = 0.0; @@ -438,9 +546,23 @@ struct V0ptHadPiKaProt { histos.fill(HIST("h2DnsigmaProtonTpcVsTofBeforeCut"), nSigmaTpcProt, nSigmaTofProt); // identified particles selection - bool isPion = selectionPion(track); - bool isKaon = selectionKaon(track); - bool isProton = selectionProton(track); + bool isPion = false; + bool isKaon = false; + bool isProton = false; + + if (cfgUseRun3V2PID) { + int pidVal = getNsigmaPID(track); + if (pidVal == 1) + isPion = true; + if (pidVal == 2) + isKaon = true; + if (pidVal == 3) + isProton = true; + } else { + isPion = selectionPion(track); + isKaon = selectionKaon(track); + isProton = selectionProton(track); + } // PID QAs after selection if (isPion) { From bc1e18c4bcf2b1e817ae11bdee9d7c5c1de1796e Mon Sep 17 00:00:00 2001 From: Swati Saha Date: Wed, 29 Oct 2025 18:34:11 +0530 Subject: [PATCH 3/3] Fixed two O2_linter error --- .../Tasks/v0ptHadPiKaProt.cxx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx index 4f31318569b..f2f940ffad8 100644 --- a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx @@ -93,6 +93,12 @@ struct V0ptHadPiKaProt { kTOF, kITS }; + enum CentralityEstimator { + kFT0C = 0, + kFT0A, + kFT0M, + kFV0A + }; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutTpcChi2NCl{"cfgCutTpcChi2NCl", 2.5f, "Maximum TPCchi2NCl"}; @@ -116,7 +122,7 @@ struct V0ptHadPiKaProt { Configurable cfgCutEtaLeft{"cfgCutEtaLeft", 0.8f, "Left end of eta gap"}; Configurable cfgCutEtaRight{"cfgCutEtaRight", 0.8f, "Right end of eta gap"}; Configurable cfgNSubsample{"cfgNSubsample", 10, "Number of subsamples"}; - Configurable cfgCentralityChoice{"cfgCentralityChoice", 1, "Which centrality estimator? 1-->FT0C, 2-->FT0A, 3-->FT0M, 4-->FV0A"}; + Configurable cfgCentralityChoice{"cfgCentralityChoice", 0, "Which centrality estimator? 0-->FT0C, 1-->FT0A, 2-->FT0M, 3-->FV0A"}; Configurable cfgEvSelkNoSameBunchPileup{"cfgEvSelkNoSameBunchPileup", true, "Pileup removal"}; Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time interval with dead ITS zone"}; Configurable cfgEvSelkNoITSROFrameBorder{"cfgEvSelkNoITSROFrameBorder", true, "ITSROFrame border event selection cut"}; @@ -461,13 +467,13 @@ struct V0ptHadPiKaProt { // Centrality double cent = 0.0; - if (cfgCentralityChoice == 1) + if (cfgCentralityChoice == kFT0C) cent = coll.centFT0C(); - else if (cfgCentralityChoice == 2) + else if (cfgCentralityChoice == kFT0A) cent = coll.centFT0A(); - else if (cfgCentralityChoice == 3) + else if (cfgCentralityChoice == kFT0M) cent = coll.centFT0M(); - else if (cfgCentralityChoice == 4) + else if (cfgCentralityChoice == kFV0A) cent = coll.centFV0A(); histos.fill(HIST("hZvtx_after_sel"), coll.posZ()); @@ -552,11 +558,11 @@ struct V0ptHadPiKaProt { if (cfgUseRun3V2PID) { int pidVal = getNsigmaPID(track); - if (pidVal == 1) + if (pidVal == PIONS + 1) isPion = true; - if (pidVal == 2) + if (pidVal == KAONS + 1) isKaon = true; - if (pidVal == 3) + if (pidVal == PROTONS + 1) isProton = true; } else { isPion = selectionPion(track);