From 7ae013e9cb21b7d19602df9d1ce7efb93f4ad4c1 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Tue, 14 Apr 2026 13:28:51 +0530 Subject: [PATCH 1/5] [PWGLF] Update true event and MC filling logic --- .../Resonances/lambda1520analysisinpp.cxx | 1495 +++++++++++++++++ 1 file changed, 1495 insertions(+) diff --git a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx index 2418f442bf4..73dbf1ae02b 100644 --- a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx @@ -15,12 +15,1507 @@ #include "PWGLF/Utils/inelGt.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h"// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file lambda1520analysisinpp.cxx +/// \brief This standalone task reconstructs track-track decay of lambda(1520) resonance candidate +/// \author Hirak Kumar Koley + +#include "PWGLF/DataModel/mcCentrality.h" +#include "PWGLF/Utils/inelGt.h" + #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include "Math/Vector4D.h" +#include "TPDGCode.h" +#include "TRandom.h" + +#include +#include + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::aod::rctsel; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::physics; + +using LorentzVectorPtEtaPhiMass = ROOT::Math::PtEtaPhiMVector; + +enum { + Inel = 1, + Inel10, + Inelg0, + Inelg010, +}; + +enum TrackSelectionType { + AllTracks = 0, + GlobalTracks, + GlobalTracksWoPtEta, + GlobalTracksWoDCA, + QualityTracks, + InAcceptanceTracks, +}; + +enum PIDCutType { + SquareType = 1, + CircularType, +}; + +struct Lambda1520analysisinpp { + // Define slice per Resocollision + SliceCache cache; + Preslice perCollision = o2::aod::track::collisionId; + Preslice perMcCollision = o2::aod::mcparticle::mcCollisionId; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Service pdg; + RCTFlagsChecker rctChecker; + + struct : ConfigurableGroup { + Configurable cfgEvtZvtx{"cfgEvtZvtx", 10.0f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable cfgEvtTriggerTVXSel{"cfgEvtTriggerTVXSel", true, "Evt sel: triggerTVX selection (MB)"}; + Configurable cfgEvtNoTFBorderCut{"cfgEvtNoTFBorderCut", true, "Evt sel: apply TF border cut"}; + Configurable cfgEvtNoITSROFrameBorderCut{"cfgEvtNoITSROFrameBorderCut", false, "Evt sel: apply NoITSRO border cut"}; + Configurable cfgEvtIsRCTFlagpassed{"cfgEvtIsRCTFlagpassed", false, "Evt sel: apply RCT flag selection"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + Configurable cfgEvtSel8{"cfgEvtSel8", false, "Evt Sel 8 check for offline selection"}; + Configurable cfgEvtIsINELgt0{"cfgEvtIsINELgt0", false, "Evt sel: apply INEL>0 selection"}; + } configEvents; + + struct : ConfigurableGroup { + // Pre-selection Track cuts + Configurable trackSelection{"trackSelection", 0, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; + Configurable cMinPtcut{"cMinPtcut", 0.15f, "Minimal pT for tracks"}; + Configurable cMinTPCNClsFound{"cMinTPCNClsFound", 120, "minimum TPCNClsFound value for good track"}; + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Configurable cfgCutRapidity{"cfgCutRapidity", 0.5f, "rapidity range for particles"}; + Configurable cfgMinCrossedRows{"cfgMinCrossedRows", 70, "min crossed rows for good track"}; + + // DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1f, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 0.1f, "Track DCAz cut to PV Maximum"}; + + // Track selections + Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) + Configurable cfgGlobalTrack{"cfgGlobalTrack", false, "Global track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgPVContributor{"cfgPVContributor", false, "PV contributor track selection"}; // PV Contriuibutor + Configurable cfgHasTOF{"cfgHasTOF", false, "Require TOF"}; + Configurable cfgUseTPCRefit{"cfgUseTPCRefit", false, "Require TPC Refit"}; + Configurable cfgUseITSRefit{"cfgUseITSRefit", false, "Require ITS Refit"}; + Configurable cTPCNClsFound{"cTPCNClsFound", false, "Switch to turn on/off TPCNClsFound cut"}; + Configurable cDCAr7SigCut{"cDCAr7SigCut", false, "Track DCAr 7 Sigma cut to PV Maximum"}; + } configTracks; + + struct : ConfigurableGroup { + /// PID Selections + Configurable pidnSigmaPreSelectionCut{"pidnSigmaPreSelectionCut", 4.0f, "pidnSigma Cut for pre-selection of tracks"}; + Configurable cByPassTOF{"cByPassTOF", false, "By pass TOF PID selection"}; // By pass TOF PID selection + Configurable cPIDcutType{"cPIDcutType", 2, "cPIDcutType = 1 for square cut, 2 for circular cut"}; // By pass TOF PID selection + + // Kaon + Configurable> kaonTPCPIDpTintv{"kaonTPCPIDpTintv", {0.5f}, "pT intervals for Kaon TPC PID cuts"}; + Configurable> kaonTPCPIDcuts{"kaonTPCPIDcuts", {2}, "nSigma list for Kaon TPC PID cuts"}; + Configurable> kaonTOFPIDpTintv{"kaonTOFPIDpTintv", {999.0f}, "pT intervals for Kaon TOF PID cuts"}; + Configurable> kaonTOFPIDcuts{"kaonTOFPIDcuts", {2}, "nSigma list for Kaon TOF PID cuts"}; + Configurable> kaonTPCTOFCombinedpTintv{"kaonTPCTOFCombinedpTintv", {999.0f}, "pT intervals for Kaon TPC-TOF PID cuts"}; + Configurable> kaonTPCTOFCombinedPIDcuts{"kaonTPCTOFCombinedPIDcuts", {2}, "nSigma list for Kaon TPC-TOF PID cuts"}; + + // Proton + Configurable> protonTPCPIDpTintv{"protonTPCPIDpTintv", {0.9f}, "pT intervals for Kaon TPC PID cuts"}; + Configurable> protonTPCPIDcuts{"protonTPCPIDcuts", {2}, "nSigma list for Kaon TPC PID cuts"}; + Configurable> protonTOFPIDpTintv{"protonTOFPIDpTintv", {999.0f}, "pT intervals for Kaon TOF PID cuts"}; + Configurable> protonTOFPIDcuts{"protonTOFPIDcuts", {2}, "nSigma list for Kaon TOF PID cuts"}; + Configurable> protonTPCTOFCombinedpTintv{"protonTPCTOFCombinedpTintv", {999.0f}, "pT intervals for Proton TPC-TOF PID cuts"}; + Configurable> protonTPCTOFCombinedPIDcuts{"protonTPCTOFCombinedPIDcuts", {2}, "nSigma list for Proton TPC-TOF PID cuts"}; + } configPID; + + struct : ConfigurableGroup { + /// Event Mixing + Configurable nEvtMixing{"nEvtMixing", 10, "Number of events to mix"}; + ConfigurableAxis cfgVtxBins{"cfgVtxBins", {VARIABLE_WIDTH, -10.0f, -8.0f, -6.0f, -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f, 8.0f, 10.0f}, "Mixing bins - z-vertex"}; + ConfigurableAxis cfgMultPercentileBins{"cfgMultPercentileBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Mixing bins - multiplicity"}; + + // Rotational background + Configurable rotationalcut{"rotationalcut", 10, "Cut value (Rotation angle pi - pi/cut and pi + pi/cut)"}; + Configurable cNofRotations{"cNofRotations", 3, "Number of random rotations in the rotational background"}; + Configurable cfgRotPr{"cfgRotPr", true, "rotate Proton"}; + } configBkg; + + // Additional purity check + Configurable crejectPion{"crejectPion", false, "Switch to turn on/off pion contamination"}; + Configurable cUseOpeningAngleCut{"cUseOpeningAngleCut", false, "Kinematic Cuts for p-K pair opening angle"}; + Configurable cMinOpeningAngle{"cMinOpeningAngle", 1.4f, "Minimum opening angle between daughters"}; + Configurable cMaxOpeningAngle{"cMaxOpeningAngle", 2.4f, "Maximum opening angle between daughters"}; + Configurable cfgUseDeltaEtaPhiCuts{"cfgUseDeltaEtaPhiCuts", false, "Switch to turn on/off delta eta and delta phi cuts"}; + Configurable cfgUseDaughterEtaCutMC{"cfgUseDaughterEtaCutMC", false, "Switch to turn on/off eta cuts for daughters in MC"}; + + // MC selection cut + Configurable cEtacutMC{"cEtacutMC", 0.5f, "MC eta cut"}; + Configurable cUseRapcutMC{"cUseRapcutMC", true, "MC eta cut"}; + Configurable cUseEtacutMC{"cUseEtacutMC", true, "MC eta cut"}; + Configurable useWeight{"useWeight", false, "Use weight for signal loss calculation"}; + + // cuts on mother + Configurable cfgUseCutsOnMother{"cfgUseCutsOnMother", false, "Enable additional cuts on mother"}; + Configurable cMaxPtMotherCut{"cMaxPtMotherCut", 10.0f, "Maximum pt of mother cut"}; + Configurable cMaxMinvMotherCut{"cMaxMinvMotherCut", 3.0f, "Maximum Minv of mother cut"}; + Configurable cMaxDeltaEtaCut{"cMaxDeltaEtaCut", 0.7f, "Maximum deltaEta between daughters"}; + Configurable cMaxDeltaPhiCut{"cMaxDeltaPhiCut", 1.5f, "Maximum deltaPhi between daughters"}; + + // switches + Configurable cFillMultQA{"cFillMultQA", false, "Turn on/off additional QA plots"}; + Configurable cFillTrackQA{"cFillTrackQA", false, "Turn on/off additional QA plots"}; + Configurable cFilladditionalQAeventPlots{"cFilladditionalQAeventPlots", false, "Additional QA event plots"}; + Configurable cFilladditionalMEPlots{"cFilladditionalMEPlots", false, "Additional Mixed event plots"}; + Configurable cFilldeltaEtaPhiPlots{"cFilldeltaEtaPhiPlots", false, "Enable additional cuts on daughters"}; + Configurable cFill1DQAs{"cFill1DQAs", false, "Invariant mass 1D"}; + Configurable centEstimator{"centEstimator", 0, "Select centrality estimator: 0 - FT0M, 1 - FT0A, 2 - FT0C"}; + + TRandom* rn = new TRandom(); + + // Pre-filters for efficient process + Filter zVtxFilter = (nabs(o2::aod::collision::posZ) <= configEvents.cfgEvtZvtx); + Filter collisionFilterMC = nabs(aod::mccollision::posZ) <= configEvents.cfgEvtZvtx; + // Filter centralityFilter = nabs(aod::cent::centFT0C) <= cfg_Event_CentralityMax; + // Filter triggerFilter = (o2::aod::evsel::sel8 == true); + + Filter acceptanceFilter = (nabs(aod::track::eta) < configTracks.cfgCutEta && nabs(aod::track::pt) > configTracks.cMinPtcut) && + (nabs(aod::track::dcaXY) < configTracks.cMaxDCArToPVcut) && (nabs(aod::track::dcaZ) < configTracks.cMaxDCAzToPVcut); + + // Filter tofPIDFilter = aod::track::tofExpMom < 0.0f || ((aod::track::tofExpMom > 0.0f) && ( (nabs(aod::pidtof::tofNSigmaPi) < configPID.pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < configPID.pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < configPID.pidnSigmaPreSelectionCut))); // TOF + // Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < configPID.pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < configPID.pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < configPID.pidnSigmaPreSelectionCut; // TPC + /* Filter trackFilter = (configTracks.trackSelection == AllTracks) || + ((configTracks.trackSelection == GlobalTracks) && requireGlobalTrackInFilter()) || + ((configTracks.trackSelection == GlobalTracksWoPtEta) && requireGlobalTrackWoPtEtaInFilter()) || + ((configTracks.trackSelection == GlobalTracksWoDCA) && requireGlobalTrackWoDCAInFilter()) || + ((configTracks.trackSelection == QualityTracks) && requireQualityTracksInFilter()) || + ((configTracks.trackSelection == InAcceptanceTracks) && requireTrackCutInFilter(TrackSelectionFlags::kInAcceptanceTracks)); + */ + // Filter primarytrackFilter = requirePVContributor() && requirePrimaryTrack() && requireGlobalTrackWoDCA(); + + using EventCandidates = soa::Join; + using TrackCandidates = soa::Filtered>; + + // for MC reco + using MCEventCandidates = soa::Join; + using MCTrackCandidates = soa::Filtered>; + + // for MC truth + // using MCTrueEventCandidates = soa::Join; + // using MCTrueTrackCandidates = aod::McParticles; + + /// Figures + ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.12f, 0.14f, 0.16f, 0.18f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.5f, 0.55f, 0.6f, 0.65f, 0.7f, 0.75f, 0.8f, 0.85f, 0.9f, 0.95f, 1.0f, 1.1f, 1.2f, 1.25f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.75f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.6f, 3.7f, 3.8f, 3.9f, 4.0f, 4.1f, 4.2f, 4.5f, 4.6f, 4.8f, 4.9f, 5.0f, 5.5f, 5.6f, 6.0f, 6.4f, 6.5f, 7.0f, 7.2f, 8.0f, 9.0f, 9.5f, 9.6f, 10.0f, 11.0f, 11.5f, 12.0f, 13.0f, 14.0f, 14.4f, 15.0f, 16.0f, 18.0f, 19.2f, 20.0f}, "Binning of the pT axis"}; + ConfigurableAxis binsPtQA{"binsPtQA", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.4f, 1.6f, 1.8f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.2f, 4.4f, 4.6f, 4.8f, 5.0f, 5.2f, 5.4f, 5.6f, 5.8f, 6.0f, 6.2f, 6.4f, 6.6f, 6.8f, 7.0f, 7.2f, 7.4f, 7.6f, 7.8f, 8.0f, 8.2f, 8.4f, 8.6f, 8.8f, 9.0f, 9.2f, 9.4f, 9.6f, 9.8f, 10.0f, 10.2f, 10.4f, 10.6f, 10.8f, 11.0f, 11.2f, 11.4f, 11.6f, 11.8f, 12.0f, 12.2f, 12.4f, 12.6f, 12.8f, 13.0f, 13.2f, 13.4f, 13.6f, 13.8f, 14.0f, 14.2f, 14.4f, 14.6f, 14.8f, 15.0f, 15.2f, 15.4f, 15.6f, 15.8f, 16.0f, 16.2f, 16.4f, 16.6f, 16.8f, 17.0f, 17.2f, 17.4f, 17.6f, 17.8f, 18.0f, 18.2f, 18.4f, 18.6f, 18.8f, 19.0f, 19.2f, 19.4f, 19.6f, 19.8f, 20.0f}, "Binning of the pT axis"}; + ConfigurableAxis binsEta{"binsEta", {150, -1.5f, 1.5f}, ""}; + ConfigurableAxis binsMass{"binsMass", {70, 1.3f, 2.0f}, "Invariant Mass (GeV/#it{c}^2)"}; + ConfigurableAxis binsMult{"binsMult", {105, 0.0f, 105.0f}, "mult_{FT0M}"}; + ConfigurableAxis binsDCAz{"binsDCAz", {40, -0.2f, 0.2f}, ""}; + ConfigurableAxis binsDCAxy{"binsDCAxy", {40, -0.2f, 0.2f}, ""}; + ConfigurableAxis binsTPCXrows{"binsTPCXrows", {100, 60, 160}, ""}; + ConfigurableAxis binsnSigma{"binsnSigma", {130, -6.5f, 6.5f}, ""}; + ConfigurableAxis binsnTPCSignal{"binsnTPCSignal", {1000, 0, 1000}, ""}; + ConfigurableAxis binsEtaPhi{"binsEtaPhi", {350, -3.5f, 3.5f}, ""}; + + void init(framework::InitContext&) + { + rctChecker.init(configEvents.cfgEvtRCTFlagCheckerLabel, configEvents.cfgEvtRCTFlagCheckerZDCCheck, configEvents.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + + // axes + AxisSpec axisPt{binsPt, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisPtQA{binsPtQA, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisEta{binsEta, "#eta"}; + AxisSpec axisRap{binsEta, "#it{y}"}; + AxisSpec axisMassLambda1520{binsMass, "Invariant Mass (GeV/#it{c}^2)"}; + AxisSpec axisMult{binsMult, "mult_{FT0M}"}; + AxisSpec axisDCAz{binsDCAz, "DCA_{z}"}; + AxisSpec axisDCAxy{binsDCAxy, "DCA_{XY}"}; + AxisSpec axisTPCXrow{binsTPCXrows, "#Xrows_{TPC}"}; + AxisSpec axisPIDQA{binsnSigma, "#sigma"}; + AxisSpec axisTPCSignal{binsnTPCSignal, ""}; + AxisSpec axisMClabel{9, -1.f, 8.f, "MC Label"}; + AxisSpec axisEtaPhi{binsEtaPhi, ""}; + AxisSpec axisPhi{350, 0, 7, "#Phi"}; + AxisSpec axisMultMix{configBkg.cfgMultPercentileBins, "Multiplicity Percentile"}; + AxisSpec axisVtxMix{configBkg.cfgVtxBins, "Vertex Z (cm)"}; + AxisSpec idxMCAxis = {26, -0.5f, 25.5f, "Index"}; + + histos.add("CollCutCounts", "No. of event after cuts", kTH1I, {{10, 0, 10}}); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(1, "All Events"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(2, "|Vz| < cut"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(5, "kNoITSROFrameBorder"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(6, "rctChecker"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(7, "sel8"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(8, "IsINELgt0"); + histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(9, "All Passed Events"); + + histos.add("Event/posZ", "; vtx_{z} (cm); Entries", HistType::kTH1F, {{250, -12.5, 12.5}}); + histos.add("Event/centFT0M", "; FT0M Percentile; Entries", HistType::kTH1F, {{110, 0, 110}}); + + if (cFilladditionalQAeventPlots) { + // event histograms + if (doprocessData) { + histos.add("QAevent/hPairsCounterSameE", "total valid no. of pairs sameE", HistType::kTH1F, {{1, 0.5f, 1.5f}}); + histos.add("QAevent/hnTrksSameE", "n tracks per event SameE", HistType::kTH1F, {{1000, 0.0, 1000.0}}); + } + // Gen on Mixed event + if (doprocessME) { + + // Histograms for Mixed Event Pool characteristics + histos.add("QAevent/hMixPool_VtxZ", "Mixed Event Pool: Vertex Z;Vtx Z (cm);Counts", HistType::kTH1F, {axisVtxMix}); + histos.add("QAevent/hMixPool_Multiplicity", "Mixed Event Pool: Multiplicity;Multiplicity;Counts", HistType::kTH1F, {axisMultMix}); + histos.add("QAevent/hMixPool_VtxZ_vs_Multiplicity", "Mixed Event Pool: Vertex Z vs Multiplicity;Counts", HistType::kTH2F, {axisVtxMix, axisMultMix}); + + histos.add("QAevent/hPairsCounterMixedE", "total valid no. of pairs mixedE", HistType::kTH1F, {{1, 0.5f, 1.5f}}); + histos.add("QAevent/hVertexZMixedE", "Collision Vertex Z position", HistType::kTH1F, {{100, -15.0f, 15.0f}}); + histos.add("QAevent/hMultiplicityPercentMixedE", "Multiplicity percentile of collision", HistType::kTH1F, {{120, 0.0f, 120.0f}}); + histos.add("QAevent/hnTrksMixedE", "n tracks per event MixedE", HistType::kTH1F, {{1000, 0.0f, 1000.0f}}); + } + } + + if (doprocessData) { + // Track QA before cuts + // --- Track + if (cFillTrackQA) { + histos.add("QA/QAbefore/Track/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;{#sigma_{TOF}^{Kaon}};{#sigma_{TPC}^{Kaon}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPConly_Nsigma_ka", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;{#sigma_{TOF}^{Proton}};{#sigma_{TPC}^{Proton}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPConly_Nsigma_pr", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTH2F, {axisPt, axisDCAz}); + histos.add("QA/QAbefore/Track/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); + histos.add("QA/QAbefore/Track/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); + histos.add("QA/QAbefore/Track/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); + histos.add("QA/QAbefore/Track/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); + } + if (cFillMultQA) { + // Multiplicity correlation calibrations + histos.add("MultCalib/centGloPVpr", "Centrality vs Global-Tracks", kTHnSparseF, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}, {500, 0, 5000, "PV tracks"}}); + histos.add("MultCalib/centGloPVka", "Centrality vs Global-Tracks", kTHnSparseF, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}, {500, 0, 5000, "PV tracks"}}); + } + + // PID QA after cuts + // --- Kaon + histos.add("QA/QAafter/Kaon/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;{#sigma_{TOF}^{Kaon}};{#sigma_{TPC}^{Kaon}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/TPC_Nsigma_ka_TPConly", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTH2F, {axisPt, axisDCAz}); + histos.add("QA/QAafter/Kaon/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); + histos.add("QA/QAafter/Kaon/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); + histos.add("QA/QAafter/Kaon/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); + histos.add("QA/QAafter/Kaon/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); + histos.add("QA/QAafter/Kaon/TPC_Signal_ka_all", "TPC Signal for Kaon;#it{p} (GeV/#it{c});TPC Signal (A.U.)", {HistType::kTH2F, {axisPt, axisTPCSignal}}); + histos.add("QA/QAafter/Kaon/TPCnclusterPhika", "TPC ncluster vs phi", kTHnSparseF, {{160, 0, 160, "TPC nCluster"}, {63, 0.0f, 6.28f, "#phi"}}); + + // --- Proton + histos.add("QA/QAafter/Proton/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;{#sigma_{TOF}^{Proton}};{#sigma_{TPC}^{Proton}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAafter/Proton/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Proton/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Proton/TPC_Nsigma_pr_TPConly", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Proton/dcaZ", "DCA_{Z} distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm);", HistType::kTH2F, {axisPt, axisDCAz}); + histos.add("QA/QAafter/Proton/dcaXY", "DCA_{XY} momentum distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); + histos.add("QA/QAafter/Proton/TPC_CR", "# TPC Xrows distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); + histos.add("QA/QAafter/Proton/pT", "pT distribution of Protons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); + histos.add("QA/QAafter/Proton/eta", "#eta distribution of Protons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); + histos.add("QA/QAafter/Proton/TPC_Signal_pr_all", "TPC Signal for Proton;#it{p} (GeV/#it{c});TPC Signal (A.U.)", {HistType::kTH2F, {axisPt, axisTPCSignal}}); + histos.add("QA/QAafter/Proton/TPCnclusterPhipr", "TPC ncluster vs phi", kTHnSparseF, {{160, 0, 160, "TPC nCluster"}, {63, 0.0f, 6.28f, "#phi"}}); + + // Mass QA 1D for quick check + if (cFill1DQAs) { + histos.add("Result/Data/lambda1520invmass", "Invariant mass of #Lambda(1520) K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); + histos.add("Result/Data/antilambda1520invmass", "Invariant mass of #Lambda(1520) K^{#mp}p^{#pm}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); + histos.add("Result/Data/lambda1520invmassLSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr + histos.add("Result/Data/lambda1520invmassLSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr + } + // eta phi QA + if (cFilldeltaEtaPhiPlots) { + histos.add("QAbefore/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + histos.add("QAbefore/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + + histos.add("QAafter/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + histos.add("QAafter/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + + histos.add("QAafter/PhiPrafter", "Phi of proton candidates", HistType::kTH1F, {axisPhi}); + histos.add("QAafter/PhiKaafter", "Phi of kaon candidates", HistType::kTH1F, {axisPhi}); + } + + // 3d histogram + histos.add("Result/Data/h3lambda1520invmass", "Invariant mass of #Lambda(1520) K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/Data/h3antilambda1520invmass", "Invariant mass of #Lambda(1520) K^{#mp}p^{#pm}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/Data/h3lambda1520invmassLSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K+ + Pr + histos.add("Result/Data/h3lambda1520invmassLSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K- + anti-Pr + } + + if (doprocessRotational) { + if (cFill1DQAs) { + histos.add("Result/Data/lambda1520InvMassRotation", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr + histos.add("Result/Data/antilambda1520InvMassRotation", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr + } + histos.add("Result/Data/h3lambda1520InvMassRotation", "Invariant mass of #Lambda(1520) rotation", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/Data/h3antilambda1520InvMassRotation", "Invariant mass of #Lambda(1520) rotation", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + } + // Mixed event histograms + if (doprocessME) { + if (cFill1DQAs) { + histos.add("Result/Data/lambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); + histos.add("Result/Data/antilambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); + } + histos.add("Result/Data/h3lambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/Data/h3antilambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + + if (cFilladditionalMEPlots) { + if (cFill1DQAs) { + histos.add("Result/Data/lambda1520invmassME_LSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr + histos.add("Result/Data/lambda1520invmassME_LSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr + } + histos.add("Result/Data/h3lambda1520invmassME_LSPP", "Invariant mass of #Lambda(1520) mixed event Like Sign Method K^{#plus}p^{#plus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K+ + Pr + histos.add("Result/Data/h3lambda1520invmassME_LSMM", "Invariant mass of #Lambda(1520) mixed event Like Sign Method K^{#minus}p^{#minus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K- + anti-Pr + } + } + + // MC QA + histos.add("Event/hMCEventIndices", "hMCEventIndices", kTH2D, {axisMult, idxMCAxis}); + if (doprocessMCGen) { + histos.add("QA/Gen", "Gen histogram", kTH1D, {{10, 0, 10, "index"}}); + histos.add("QA/MC/h2GenEtaPt_beforeanycut", " #eta-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); + histos.add("QA/MC/h2GenPhiRapidity_beforeanycut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); + histos.add("QA/MC/h2GenEtaPt_afterEtaRapCut", " #eta-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); + histos.add("QA/MC/h2GenPhiRapidity_afterEtaRapCut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); + histos.add("QA/MC/h2GenEtaPt_afterRapcut", " #phi-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); + histos.add("QA/MC/h2GenPhiRapidity_afterRapcut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); + + histos.add("Result/MC/Genlambda1520pt", "pT distribution of True MC #Lambda(1520)0", kTH3F, {axisMClabel, axisPt, axisMult}); + histos.add("Result/MC/Genantilambda1520pt", "pT distribution of True MC Anti-#Lambda(1520)0", kTH3F, {axisMClabel, axisPt, axisMult}); + + histos.add("Result/SignalLoss/GenTrueprotonpt_num", "True proton (num)", kTH2F, {axisPt, axisMult}); + histos.add("Result/SignalLoss/Genprotonpt_num", "Proton (num)", kTH2F, {axisPt, axisMult}); + + histos.add("Result/SignalLoss/GenTruelambdapt_num", "True lambda (num)", kTH2F, {axisPt, axisMult}); + histos.add("Result/SignalLoss/Genlambdapt_num", "Lambda (num)", kTH2F, {axisPt, axisMult}); + + histos.add("Result/SignalLoss/GenTruexipt_num", "True xi (num)", kTH2F, {axisPt, axisMult}); + histos.add("Result/SignalLoss/Genxipt_num", "Xi (num)", kTH2F, {axisPt, axisMult}); + } + if (doprocessMCRec) { + histos.add("QA/MC/h2RecoEtaPt_after", " #eta-#it{p}_{T} distribution of Reconstructed #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPt}); + histos.add("QA/MC/h2RecoPhiRapidity_after", " #phi-y distribution of Reconstructed #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); + + histos.add("QA/MC/trkDCAxy_pr", "DCAxy distribution of proton track candidates", HistType::kTHnSparseF, {axisPt, axisDCAxy}); + histos.add("QA/MC/trkDCAxy_ka", "DCAxy distribution of kaon track candidates", HistType::kTHnSparseF, {axisPt, axisDCAxy}); + histos.add("QA/MC/trkDCAz_pr", "DCAz distribution of proton track candidates", HistType::kTHnSparseF, {axisPt, axisDCAz}); + histos.add("QA/MC/trkDCAz_ka", "DCAz distribution of kaon track candidates", HistType::kTHnSparseF, {axisPt, axisDCAz}); + histos.add("QA/MC/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/MC/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/MC/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/MC/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + + histos.add("Result/MC/h3lambda1520Recoinvmass", "Invariant mass of Reconstructed MC #Lambda(1520)0", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/MC/h3antilambda1520Recoinvmass", "Invariant mass of Reconstructed MC Anti-#Lambda(1520)0", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + } + if (doprocessSignalLoss) { + histos.add("Result/SignalLoss/GenTruelambda1520pt_den", "True lambda1520 (den)", kTH2F, {axisPt, axisMult}); + histos.add("Result/SignalLoss/GenTrueantilambda1520pt_den", "True anti-lambda1520 (den)", kTH2F, {axisPt, axisMult}); + + histos.add("Result/SignalLoss/GenTrueprotonpt_den", "True proton (den)", kTH2F, {axisPt, axisMult}); + histos.add("Result/SignalLoss/Genprotonpt_den", "Proton (den)", kTH2F, {axisPt, axisMult}); + + histos.add("Result/SignalLoss/GenTruelambdapt_den", "True lambda (den)", kTH2F, {axisPt, axisMult}); + histos.add("Result/SignalLoss/Genlambdapt_den", "Lambda (den)", kTH2F, {axisPt, axisMult}); + + histos.add("Result/SignalLoss/GenTruexipt_den", "True xi (den)", kTH2F, {axisPt, axisMult}); + histos.add("Result/SignalLoss/Genxipt_den", "Xi (den)", kTH2F, {axisPt, axisMult}); + } + + // Print output histograms statistics + LOG(info) << "Size of the histograms in Lambda1520analysisinpp:"; + histos.print(); + } + + float massKa = MassKaonCharged; + float massPr = MassProton; + + // Centralicity estimator selection + template + float centEst(Coll collisions) + { + float returnValue = -999.0f; + switch (centEstimator) { + case 0: + returnValue = collisions.centFT0M(); + break; + case 1: + returnValue = collisions.centFT0A(); + break; + case 2: + returnValue = collisions.centFT0C(); + break; + default: + returnValue = collisions.centFT0M(); + break; + } + return returnValue; + } + + template + bool isSelected(const Coll& collision, bool fillHist = true) + { + auto applyCut = [&](bool enabled, bool condition, int bin) { + if (!enabled) + return true; + if (!condition) + return false; + if (fillHist) + histos.fill(HIST("CollCutCounts"), bin); + return true; + }; + + if (fillHist) + histos.fill(HIST("CollCutCounts"), 0); + + if (!applyCut(true, std::abs(collision.posZ()) <= configEvents.cfgEvtZvtx, 1)) + return false; + + if (!applyCut(configEvents.cfgEvtTriggerTVXSel, + collision.selection_bit(aod::evsel::kIsTriggerTVX), 2)) + return false; + + if (!applyCut(configEvents.cfgEvtNoTFBorderCut, + collision.selection_bit(aod::evsel::kNoTimeFrameBorder), 3)) + return false; + + if (!applyCut(configEvents.cfgEvtNoITSROFrameBorderCut, + collision.selection_bit(aod::evsel::kNoITSROFrameBorder), 4)) + return false; + + if (!applyCut(configEvents.cfgEvtIsRCTFlagpassed, rctChecker(collision), 5)) + return false; + + if (!applyCut(configEvents.cfgEvtSel8, collision.sel8(), 6)) + return false; + + if (!applyCut(configEvents.cfgEvtIsINELgt0, collision.isInelGt0(), 7)) + return false; + + if (fillHist) + histos.fill(HIST("CollCutCounts"), 8); + + return true; + } + + template + bool trackCut(const TrackType track) + { + // basic track cuts + if (configTracks.cDCAr7SigCut && std::abs(track.dcaXY()) > (0.004f + 0.013f / (track.pt()))) // 7 - Sigma cut + return false; + if (configTracks.cTPCNClsFound && (track.tpcNClsFound() < configTracks.cMinTPCNClsFound)) + return false; + if (track.tpcNClsCrossedRows() < configTracks.cfgMinCrossedRows) + return false; + if (configTracks.cfgHasTOF && !track.hasTOF()) + return false; + if (configTracks.cfgPrimaryTrack && !track.isPrimaryTrack()) + return false; + if (configTracks.cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + return false; + if (configTracks.cfgPVContributor && !track.isPVContributor()) + return false; + if (configTracks.cfgGlobalTrack && !track.isGlobalTrack()) + return false; + + return true; + } + + // LOGF(info, "AFTER: pt: %f, hasTOF: %d, TPCSigma: %f, TOFSigma: %f, boolTPC: %d, boolTOF: %d, bool: %d", pt, candidate.hasTOF(), + // candidate.tpcNSigmaPr(), candidate.tofNSigmaPr(), tpcPIDPassed, tofPIDPassed, tpcPIDPassed || tofPIDPassed); + + template + bool ptDependentPidProton(const T& candidate) + { + auto vProtonTPCPIDpTintv = configPID.protonTPCPIDpTintv.value; + vProtonTPCPIDpTintv.insert(vProtonTPCPIDpTintv.begin(), configTracks.cMinPtcut); + auto vProtonTPCPIDcuts = configPID.protonTPCPIDcuts.value; + auto vProtonTOFPIDpTintv = configPID.protonTOFPIDpTintv.value; + auto vProtonTPCTOFCombinedpTintv = configPID.protonTPCTOFCombinedpTintv.value; + auto vProtonTPCTOFCombinedPIDcuts = configPID.protonTPCTOFCombinedPIDcuts.value; + auto vProtonTOFPIDcuts = configPID.protonTOFPIDcuts.value; + + float pt = candidate.pt(); + float ptSwitchToTOF = vProtonTPCPIDpTintv.back(); + float tpcNsigmaPr = candidate.tpcNSigmaPr(); + float tofNsigmaPr = candidate.tofNSigmaPr(); + + bool tpcPIDPassed = false; + + // TPC PID (interval check) + for (size_t i = 0; i < vProtonTPCPIDpTintv.size() - 1; ++i) { + if (pt > vProtonTPCPIDpTintv[i] && pt < vProtonTPCPIDpTintv[i + 1]) { + if (std::abs(tpcNsigmaPr) < vProtonTPCPIDcuts[i]) + tpcPIDPassed = true; + } + } + + // TOF bypass option (for QA or MC) + if (configPID.cByPassTOF) { + return std::abs(tpcNsigmaPr) < vProtonTPCPIDcuts.back(); + } + + // Case 1: No TOF and pt ≤ threshold → accept only via TPC PID + if (!candidate.hasTOF() && pt <= ptSwitchToTOF) { + return tpcPIDPassed; + } + + // Case 2: No TOF but pt > threshold → reject + if (!candidate.hasTOF() && pt > ptSwitchToTOF) { + return false; + } + + // Case 3: Has TOF → use TPC + TOF (square or circular) + if (candidate.hasTOF()) { + if (configPID.cPIDcutType == SquareType) { + // Rectangular cut + for (size_t i = 0; i < vProtonTOFPIDpTintv.size(); ++i) { + if (pt < vProtonTOFPIDpTintv[i]) { + if (std::abs(tofNsigmaPr) < vProtonTOFPIDcuts[i] && + std::abs(tpcNsigmaPr) < vProtonTPCPIDcuts.back()) + return true; + } + } + } else if (configPID.cPIDcutType == CircularType) { + // Circular cut + for (size_t i = 0; i < vProtonTPCTOFCombinedpTintv.size(); ++i) { + if (pt < vProtonTPCTOFCombinedpTintv[i]) { + float combinedSigma2 = + tpcNsigmaPr * tpcNsigmaPr + + tofNsigmaPr * tofNsigmaPr; + if (combinedSigma2 < vProtonTPCTOFCombinedPIDcuts[i] * vProtonTPCTOFCombinedPIDcuts[i]) + return true; + } + } + } + } + + return false; + } + + template + bool ptDependentPidKaon(const T& candidate) + { + auto vKaonTPCPIDpTintv = configPID.kaonTPCPIDpTintv.value; + vKaonTPCPIDpTintv.insert(vKaonTPCPIDpTintv.begin(), configTracks.cMinPtcut); + auto vKaonTPCPIDcuts = configPID.kaonTPCPIDcuts.value; + auto vKaonTOFPIDpTintv = configPID.kaonTOFPIDpTintv.value; + auto vKaonTPCTOFCombinedpTintv = configPID.kaonTPCTOFCombinedpTintv.value; + auto vKaonTPCTOFCombinedPIDcuts = configPID.kaonTPCTOFCombinedPIDcuts.value; + auto vKaonTOFPIDcuts = configPID.kaonTOFPIDcuts.value; + + float pt = candidate.pt(); + float ptSwitchToTOF = vKaonTPCPIDpTintv.back(); + float tpcNsigmaKa = candidate.tpcNSigmaKa(); + float tofNsigmaKa = candidate.tofNSigmaKa(); + + bool tpcPIDPassed = false; + + // TPC PID interval-based check + for (size_t i = 0; i < vKaonTPCPIDpTintv.size() - 1; ++i) { + if (pt > vKaonTPCPIDpTintv[i] && pt < vKaonTPCPIDpTintv[i + 1]) { + if (std::abs(tpcNsigmaKa) < vKaonTPCPIDcuts[i]) { + tpcPIDPassed = true; + break; + } + } + } + + // TOF bypass option + if (configPID.cByPassTOF) { + return std::abs(tpcNsigmaKa) < vKaonTPCPIDcuts.back(); + } + + // Case 1: No TOF and pt ≤ ptSwitch → use TPC-only + if (!candidate.hasTOF() && pt <= ptSwitchToTOF) { + return tpcPIDPassed; + } + + // Case 2: No TOF but pt > ptSwitch → reject + if (!candidate.hasTOF() && pt > ptSwitchToTOF) { + return false; + } + + // Case 3: TOF is available → apply TPC+TOF PID logic + if (candidate.hasTOF()) { + if (configPID.cPIDcutType == SquareType) { + // Rectangular cut + for (size_t i = 0; i < vKaonTOFPIDpTintv.size(); ++i) { + if (pt < vKaonTOFPIDpTintv[i]) { + if (std::abs(tofNsigmaKa) < vKaonTOFPIDcuts[i] && + std::abs(tpcNsigmaKa) < vKaonTPCPIDcuts.back()) { + return true; + } + } + } + } else if (configPID.cPIDcutType == CircularType) { + // Circular cut + for (size_t i = 0; i < vKaonTPCTOFCombinedpTintv.size(); ++i) { + if (pt < vKaonTPCTOFCombinedpTintv[i]) { + float combinedSigma2 = tpcNsigmaKa * tpcNsigmaKa + + tofNsigmaKa * tofNsigmaKa; + if (combinedSigma2 < vKaonTPCTOFCombinedPIDcuts[i] * vKaonTPCTOFCombinedPIDcuts[i]) { + return true; + } + } + } + } + } + + return false; + } + + auto static constexpr MinPtforPionRejection = 1.0f; + auto static constexpr MaxPtforPionRejection = 2.0f; + auto static constexpr MaxnSigmaforPionRejection = 2.0f; + + template + bool rejectPion(const T& candidate) + { + if (candidate.pt() > MinPtforPionRejection && candidate.pt() < MaxPtforPionRejection && !candidate.hasTOF() && candidate.tpcNSigmaPi() < MaxnSigmaforPionRejection) { + return false; + } + return true; + } + + auto static constexpr MaxNoLambda1520Daughters = 2; + + template + void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksType& dTracks2) + { + auto centrality = centEst(collision); + + // Multiplicity correlation calibration plots + if (cFillMultQA) { + if constexpr (IsData) { + histos.fill(HIST("MultCalib/centGloPVpr"), centrality, dTracks1.size(), collision.multNTracksPV()); + histos.fill(HIST("MultCalib/centGloPVka"), centrality, dTracks2.size(), collision.multNTracksPV()); + } + } + + if (cFilladditionalQAeventPlots) { + if constexpr (IsData) { + histos.fill(HIST("QAevent/hnTrksSameE"), dTracks1.size()); + } else if constexpr (IsMix) { + histos.fill(HIST("QAevent/hVertexZMixedE"), collision.posZ()); + histos.fill(HIST("QAevent/hMultiplicityPercentMixedE"), centrality); + histos.fill(HIST("QAevent/hnTrksMixedE"), dTracks1.size()); + } + } + // LOG(info) << "After pass, Collision index:" << collision.index() << "multiplicity: " << collision.centFT0M() << endl; + + LorentzVectorPtEtaPhiMass lDecayDaughter1, lDecayDaughter2, lResonance, ldaughterRot, lResonanceRot; + + for (const auto& [trk1, trk2] : combinations(CombinationsFullIndexPolicy(dTracks1, dTracks2))) { + // Full index policy is needed to consider all possible combinations + if (trk1.index() == trk2.index()) + continue; // We need to run (0,1), (1,0) pairs as well. but same id pairs are not needed. + + // apply the track cut + if (!trackCut(trk1) || !trackCut(trk2)) + continue; + + //// Initialize variables + // Trk1: Proton + auto isTrk1hasTOF = trk1.hasTOF(); + auto trk1ptPr = trk1.pt(); + auto trk1etaPr = trk1.eta(); + auto trk1phiPr = trk1.phi(); + auto trk1NSigmaPrTPC = trk1.tpcNSigmaPr(); + auto trk1NSigmaPrTOF = (isTrk1hasTOF) ? trk1.tofNSigmaPr() : -999.0f; + + // Trk2: Kaon + auto isTrk2hasTOF = trk2.hasTOF(); + auto trk2ptKa = trk2.pt(); + auto trk2etaKa = trk2.eta(); + auto trk2phiKa = trk2.phi(); + auto trk2NSigmaKaTPC = trk2.tpcNSigmaKa(); + auto trk2NSigmaKaTOF = (isTrk2hasTOF) ? trk2.tofNSigmaKa() : -999.0f; + + auto deltaEta = 0.0f; + auto deltaPhi = 0.0f; + + if (cfgUseDeltaEtaPhiCuts) { + deltaEta = std::abs(trk1etaPr - trk2etaKa); + deltaPhi = std::abs(trk1phiPr - trk2phiKa); + deltaPhi = (deltaPhi > o2::constants::math::PI) ? (o2::constants::math::TwoPI - deltaPhi) : deltaPhi; + if (deltaEta >= cMaxDeltaEtaCut) + continue; + if (deltaPhi >= cMaxDeltaPhiCut) + continue; + } + + //// QA plots before the selection + // --- Track QA all + if constexpr (IsData) { + if (cFillTrackQA) { + histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); + if (isTrk1hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); + histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); + } + if (!isTrk1hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_pr"), trk1ptPr, trk1NSigmaPrTPC); + } + histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); + if (isTrk2hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); + histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); + } + if (!isTrk2hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_ka"), trk2ptKa, trk2NSigmaKaTPC); + } + + histos.fill(HIST("QA/QAbefore/Track/dcaZ"), trk1ptPr, trk1.dcaZ()); + histos.fill(HIST("QA/QAbefore/Track/dcaXY"), trk1ptPr, trk1.dcaXY()); + histos.fill(HIST("QA/QAbefore/Track/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); + histos.fill(HIST("QA/QAbefore/Track/pT"), trk1ptPr); + histos.fill(HIST("QA/QAbefore/Track/eta"), trk1etaPr); + } + if (cFilldeltaEtaPhiPlots) { + histos.fill(HIST("QAbefore/deltaEta"), deltaEta); + histos.fill(HIST("QAbefore/deltaPhi"), deltaPhi); + } + } + + //// Apply the pid selection + if (crejectPion && rejectPion(trk2)) // to remove pion contamination from the kaon track + continue; + + if (!ptDependentPidProton(trk1) || !ptDependentPidKaon(trk2)) + continue; + + //// QA plots after the selection + if constexpr (IsData) { // --- PID QA Proton + histos.fill(HIST("QA/QAafter/Proton/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); + histos.fill(HIST("QA/QAafter/Proton/TPC_Signal_pr_all"), trk1.tpcInnerParam(), trk1.tpcSignal()); + if (isTrk1hasTOF) { + histos.fill(HIST("QA/QAafter/Proton/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); + histos.fill(HIST("QA/QAafter/Proton/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); + } + if (!isTrk1hasTOF) { + histos.fill(HIST("QA/QAafter/Proton/TPC_Nsigma_pr_TPConly"), trk1ptPr, trk1NSigmaPrTPC); + } + histos.fill(HIST("QA/QAafter/Proton/dcaZ"), trk1ptPr, trk1.dcaZ()); + histos.fill(HIST("QA/QAafter/Proton/dcaXY"), trk1ptPr, trk1.dcaXY()); + histos.fill(HIST("QA/QAafter/Proton/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); + histos.fill(HIST("QA/QAafter/Proton/pT"), trk1ptPr); + histos.fill(HIST("QA/QAafter/Proton/eta"), trk1etaPr); + histos.fill(HIST("QA/QAafter/Proton/TPCnclusterPhipr"), trk1.tpcNClsFound(), trk1phiPr); + + // --- PID QA Kaon + histos.fill(HIST("QA/QAafter/Kaon/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); + histos.fill(HIST("QA/QAafter/Kaon/TPC_Signal_ka_all"), trk2.tpcInnerParam(), trk2.tpcSignal()); + if (isTrk2hasTOF) { + histos.fill(HIST("QA/QAafter/Kaon/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); + histos.fill(HIST("QA/QAafter/Kaon/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); + } + if (!isTrk2hasTOF) { + histos.fill(HIST("QA/QAafter/Kaon/TPC_Nsigma_ka_TPConly"), trk2ptKa, trk2NSigmaKaTPC); + } + histos.fill(HIST("QA/QAafter/Kaon/dcaZ"), trk2ptKa, trk2.dcaZ()); + histos.fill(HIST("QA/QAafter/Kaon/dcaXY"), trk2ptKa, trk2.dcaXY()); + histos.fill(HIST("QA/QAafter/Kaon/TPC_CR"), trk2ptKa, trk2.tpcNClsCrossedRows()); + histos.fill(HIST("QA/QAafter/Kaon/pT"), trk2ptKa); + histos.fill(HIST("QA/QAafter/Kaon/eta"), trk2etaKa); + histos.fill(HIST("QA/QAafter/Kaon/TPCnclusterPhika"), trk2.tpcNClsFound(), trk2phiKa); + + if (cFilldeltaEtaPhiPlots) { + histos.fill(HIST("QAafter/PhiPrafter"), trk1phiPr); + histos.fill(HIST("QAafter/PhiKaafter"), trk2phiKa); + histos.fill(HIST("QAafter/deltaEta"), deltaEta); + histos.fill(HIST("QAafter/deltaPhi"), deltaPhi); + } + } + + //// Resonance reconstruction + lDecayDaughter1 = LorentzVectorPtEtaPhiMass(trk1ptPr, trk1etaPr, trk1phiPr, massPr); + lDecayDaughter2 = LorentzVectorPtEtaPhiMass(trk2ptKa, trk2etaKa, trk2phiKa, massKa); + + // Apply kinematic opening angle cut + if (cUseOpeningAngleCut) { + auto v1 = lDecayDaughter1.Vect(); + auto v2 = lDecayDaughter2.Vect(); + float alpha = std::acos(v1.Dot(v2) / (v1.R() * v2.R())); + if (alpha > cMinOpeningAngle && alpha < cMaxOpeningAngle) + continue; + } + + lResonance = lDecayDaughter1 + lDecayDaughter2; + + auto resonanceMass = lResonance.M(); + auto resonancePt = lResonance.Pt(); + auto resonanceRapidity = lResonance.Rapidity(); + + if constexpr (IsData || IsMix) { + // Rapidity cut + if (std::abs(resonanceRapidity) > configTracks.cfgCutRapidity) + continue; + } + + if (cfgUseCutsOnMother) { + if (resonancePt >= cMaxPtMotherCut) // excluding candidates in overflow + continue; + if (resonanceMass >= cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + + if (cFilladditionalQAeventPlots) { + if constexpr (IsData) { + histos.fill(HIST("QAevent/hPairsCounterSameE"), 1.0f); + } else if (IsMix) { + histos.fill(HIST("QAevent/hPairsCounterMixedE"), 1.0f); + } + } + + //// Un-like sign pair only + if (trk1.sign() * trk2.sign() < 0) { + if constexpr (IsRot) { + for (int i = 0; i < configBkg.cNofRotations; i++) { + float theta = rn->Uniform(o2::constants::math::PI - o2::constants::math::PI / configBkg.rotationalcut, o2::constants::math::PI + o2::constants::math::PI / configBkg.rotationalcut); + if (configBkg.cfgRotPr) { + ldaughterRot = LorentzVectorPtEtaPhiMass(trk1ptPr, trk1etaPr, trk1phiPr + theta, massPr); + lResonanceRot = ldaughterRot + lDecayDaughter2; + } else { + ldaughterRot = LorentzVectorPtEtaPhiMass(trk2ptKa, trk2etaKa, trk2phiKa + theta, massKa); + lResonanceRot = lDecayDaughter1 + ldaughterRot; + } + auto resonanceRotMass = lResonanceRot.M(); + auto resonanceRotPt = lResonanceRot.Pt(); + + // Rapidity cut + if (std::abs(lResonanceRot.Rapidity()) >= configTracks.cfgCutRapidity) + continue; + + if (cfgUseCutsOnMother) { + if (resonanceRotPt >= cMaxPtMotherCut) // excluding candidates in overflow + continue; + if (resonanceRotMass >= cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + if (trk1.sign() < 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/lambda1520InvMassRotation"), resonanceRotMass); + } + histos.fill(HIST("Result/Data/h3lambda1520InvMassRotation"), centrality, resonanceRotPt, resonanceRotMass); + } else if (trk1.sign() > 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/antilambda1520InvMassRotation"), resonanceRotMass); + } + histos.fill(HIST("Result/Data/h3antilambda1520InvMassRotation"), centrality, resonanceRotPt, resonanceRotMass); + } + } + } + if constexpr (IsData) { + if (trk1.sign() < 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/lambda1520invmass"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3lambda1520invmass"), centrality, resonancePt, resonanceMass); + } else if (trk1.sign() > 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/antilambda1520invmass"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3antilambda1520invmass"), centrality, resonancePt, resonanceMass); + } + } else if (IsMix) { + if (trk1.sign() < 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/lambda1520invmassME_UnlikeSign"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassME_UnlikeSign"), centrality, resonancePt, resonanceMass); + } else if (trk1.sign() > 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/antilambda1520invmassME_UnlikeSign"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3antilambda1520invmassME_UnlikeSign"), centrality, resonancePt, resonanceMass); + } + } + + // MC + if constexpr (IsMC) { + // now we do mc true + // ------ Temporal lambda function to prevent error in build + auto getMothersIndeces = [&](auto const& theMcParticle) { + std::vector lMothersIndeces{}; + for (auto const& lMother : theMcParticle.template mothers_as()) { + LOGF(debug, " mother index lMother: %d", lMother.globalIndex()); + lMothersIndeces.push_back(lMother.globalIndex()); + } + return lMothersIndeces; + }; + auto getMothersPDGCodes = [&](auto const& theMcParticle) { + std::vector lMothersPDGs{}; + for (auto const& lMother : theMcParticle.template mothers_as()) { + LOGF(debug, " mother pdgcode lMother: %d", lMother.pdgCode()); + lMothersPDGs.push_back(lMother.pdgCode()); + } + return lMothersPDGs; + }; + // ------ + std::vector motherstrk1 = {-1, -1}; + std::vector mothersPDGtrk1 = {-1, -1}; + + std::vector motherstrk2 = {-1, -1}; + std::vector mothersPDGtrk2 = {-1, -1}; + + // + // Get the MC particle + const auto& mctrk1 = trk1.mcParticle(); + if (mctrk1.has_mothers()) { + motherstrk1 = getMothersIndeces(mctrk1); + mothersPDGtrk1 = getMothersPDGCodes(mctrk1); + } + while (motherstrk1.size() > MaxNoLambda1520Daughters) { + motherstrk1.pop_back(); + mothersPDGtrk1.pop_back(); + } + + const auto& mctrk2 = trk2.mcParticle(); + if (mctrk2.has_mothers()) { + motherstrk2 = getMothersIndeces(mctrk2); + mothersPDGtrk2 = getMothersPDGCodes(mctrk2); + } + while (motherstrk2.size() > MaxNoLambda1520Daughters) { + motherstrk2.pop_back(); + mothersPDGtrk2.pop_back(); + } + + if (std::abs(mctrk1.pdgCode()) != kProton || std::abs(mctrk2.pdgCode()) != kKPlus) + continue; + + if (motherstrk1[0] != motherstrk2[0]) // Same mother + continue; + + if (std::abs(mothersPDGtrk1[0]) != Pdg::kLambda1520_Py) + continue; + + // LOGF(info, "mother trk1 id: %d, mother trk1: %d, trk1 id: %d, trk1 pdgcode: %d, mother trk2 id: %d, mother trk2: %d, trk2 id: %d, trk2 pdgcode: %d", motherstrk1[0], mothersPDGtrk1[0], trk1.globalIndex(), mctrk1.pdgCode(), motherstrk2[0], mothersPDGtrk2[0], trk2.globalIndex(), mctrk2.pdgCode()); + + if (cUseEtacutMC && std::abs(lResonance.Eta()) > cEtacutMC) // eta cut + continue; + + if (cUseRapcutMC && std::abs(resonanceRapidity) > configTracks.cfgCutRapidity) // rapidity cut + continue; + + histos.fill(HIST("QA/MC/h2RecoEtaPt_after"), lResonance.Eta(), resonancePt); + histos.fill(HIST("QA/MC/h2RecoPhiRapidity_after"), lResonance.Phi(), resonanceRapidity); + + // Track selection check. + histos.fill(HIST("QA/MC/trkDCAxy_pr"), trk1ptPr, trk1.dcaXY()); + histos.fill(HIST("QA/MC/trkDCAxy_ka"), trk2ptKa, trk2.dcaXY()); + histos.fill(HIST("QA/MC/trkDCAz_pr"), trk1ptPr, trk1.dcaZ()); + histos.fill(HIST("QA/MC/trkDCAz_ka"), trk2ptKa, trk2.dcaZ()); + + histos.fill(HIST("QA/MC/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); + if (isTrk1hasTOF) { + histos.fill(HIST("QA/MC/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); + } + histos.fill(HIST("QA/MC/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); + if (isTrk2hasTOF) { + histos.fill(HIST("QA/MC/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); + } + + // MC histograms + if (mothersPDGtrk1[0] > 0) { + histos.fill(HIST("Result/MC/h3lambda1520Recoinvmass"), centrality, resonancePt, resonanceMass); + } else { + histos.fill(HIST("Result/MC/h3antilambda1520Recoinvmass"), centrality, resonancePt, resonanceMass); + } + } + } else { + if constexpr (IsData) { + // Like sign pair ++ + if (trk1.sign() > 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/lambda1520invmassLSPP"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassLSPP"), centrality, resonancePt, resonanceMass); + } else { // Like sign pair -- + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/lambda1520invmassLSMM"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassLSMM"), centrality, resonancePt, resonanceMass); + } + } else if (IsMix) { + if (cFilladditionalMEPlots) { + // Like sign pair ++ + if (trk1.sign() > 0) { + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/lambda1520invmassME_LSPP"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassME_LSPP"), centrality, resonancePt, resonanceMass); + } else { // Like sign pair -- + if (cFill1DQAs) { + histos.fill(HIST("Result/Data/lambda1520invmassME_LSMM"), resonanceMass); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassME_LSMM"), centrality, resonancePt, resonanceMass); + } + } + } + } + } + } + + void processData(EventCandidates::iterator const& collision, + TrackCandidates const& tracks) + { + if (!isSelected(collision)) // Default event selection + return; + + auto centrality = centEst(collision); + + histos.fill(HIST("Event/posZ"), collision.posZ()); + histos.fill(HIST("Event/centFT0M"), centrality); + + fillHistograms(collision, tracks, tracks); + } + PROCESS_SWITCH(Lambda1520analysisinpp, processData, "Process Event for data without partition", false); + + void processRotational(EventCandidates::iterator const& collision, TrackCandidates const& tracks) + { + if (!isSelected(collision, false)) // Default event selection + return; + + if (!collision.isInelGt0()) // <-- + return; + + fillHistograms(collision, tracks, tracks); + } + PROCESS_SWITCH(Lambda1520analysisinpp, processRotational, "Process Rotational Background", false); + + // Processing Event Mixing + using BinningTypeVtxZT0M = ColumnBinningPolicy; + + void processME(EventCandidates const& collision, + TrackCandidates const& tracks) + { + auto tracksTuple = std::make_tuple(tracks); + + BinningTypeVtxZT0M colBinning{{configBkg.cfgVtxBins, configBkg.cfgMultPercentileBins}, true}; + SameKindPair pairs{colBinning, configBkg.nEvtMixing, -1, collision, tracksTuple, &cache}; // -1 is the number of the bin to skip + + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + // LOGF(info, "Mixed event collisions: (%d, %d)", collision1.globalIndex(), collision2.globalIndex()); + + // for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + // LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d)", t1.index(), t2.index(), collision1.index(), collision2.index()); + // } + + if (!isSelected(collision1, false)) // Default event selection + continue; + + if (!isSelected(collision2, false)) // Default event selection + continue; + + if (!collision1.isInelGt0()) // <-- + continue; + + if (!collision2.isInelGt0()) // <-- + continue; + + if (cFilladditionalQAeventPlots) { + // Fill histograms for the characteristics of the *mixed* events (collision1 and collision2) + // This will show the distribution of events that are actually being mixed. + if (cFill1DQAs) { + histos.fill(HIST("QAevent/hMixPool_VtxZ"), collision1.posZ()); + histos.fill(HIST("QAevent/hMixPool_Multiplicity"), collision1.centFT0M()); + } + histos.fill(HIST("QAevent/hMixPool_VtxZ_vs_Multiplicity"), collision1.posZ(), collision1.centFT0M()); + + // You might also want to fill for collision2 if you want to see both partners' distributions + // histos.fill(HIST("QAevent/hMixPool_VtxZ"), collision2.posZ()); + // histos.fill(HIST("QAevent/hMixPool_Multiplicity"), collision2.centFT0M()); + // histos.fill(HIST("QAevent/hMixPool_VtxZ_vs_Multiplicity"), collision2.posZ(), collision2.centFT0M()); + } + fillHistograms(collision1, tracks1, tracks2); + } + } + PROCESS_SWITCH(Lambda1520analysisinpp, processME, "Process EventMixing light without partition", false); + + void processMCRec(MCEventCandidates::iterator const& collision, + aod::McCollisions const&, + MCTrackCandidates const& tracks, aod::McParticles const&) + { + if (!isSelected(collision)) + return; + + auto centrality = centEst(collision); + + histos.fill(HIST("Event/posZ"), collision.posZ()); + histos.fill(HIST("Event/centFT0M"), centrality); + + fillHistograms(collision, tracks, tracks); + } + PROCESS_SWITCH(Lambda1520analysisinpp, processMCRec, "Process Event for MC Rec without partition", false); + + Partition selectedMCParticles = (nabs(aod::mcparticle::pdgCode) == static_cast(Pdg::kLambda1520_Py)); // Lambda(1520) + + void processMCGen(MCEventCandidates::iterator const& collision, aod::McCollisions const&, aod::McParticles const& mcParticles) + { + bool isInAfterAllCuts = isSelected(collision, false); + bool inVtx10 = (std::abs(collision.mcCollision().posZ()) > configEvents.cfgEvtZvtx) ? false : true; + bool isTriggerTVX = collision.selection_bit(aod::evsel::kIsTriggerTVX); + bool isSel8 = collision.sel8(); + + auto mcPartsAll = mcParticles.sliceBy(perMcCollision, collision.mcCollision().globalIndex()); + // bool isTrueINELgt0 = pwglf::isINELgt0mc(mcPartsAll, pdg); + bool isTrueINELgt0 = collision.isInelGt0(); // <-- + + auto centrality = centEst(collision); + + auto mcParts = selectedMCParticles->sliceBy(perMcCollision, collision.mcCollision().globalIndex()); + + // Not related to the real collisions + for (const auto& part : mcParts) { // loop over all Lambda(1520) particles + + std::vector daughterPDGs; + if (part.has_daughters()) { + auto daughter01 = mcParticles.rawIteratorAt(part.daughtersIds()[0] - mcParticles.offset()); + auto daughter02 = mcParticles.rawIteratorAt(part.daughtersIds()[1] - mcParticles.offset()); + daughterPDGs = {daughter01.pdgCode(), daughter02.pdgCode()}; + } else { + daughterPDGs = {-1, -1}; + } + + bool pass1 = std::abs(daughterPDGs[0]) == kKPlus || std::abs(daughterPDGs[1]) == kKPlus; // At least one decay to Kaon + bool pass2 = std::abs(daughterPDGs[0]) == kProton || std::abs(daughterPDGs[1]) == kProton; // At least one decay to Proton + + // Checking if we have both decay products + if (!pass1 || !pass2) + continue; + + // LOGF(info, "Part PDG: %d", part.pdgCode(), "DAU_ID1: %d", pass1, "DAU_ID2: %d", pass2); + + histos.fill(HIST("QA/MC/h2GenEtaPt_beforeanycut"), part.eta(), part.pt()); + histos.fill(HIST("QA/MC/h2GenPhiRapidity_beforeanycut"), part.phi(), part.y()); + + if (cUseRapcutMC && std::abs(part.y()) > configTracks.cfgCutRapidity) // rapidity cut + continue; + + if (cfgUseDaughterEtaCutMC) { + for (auto const& daughters : part.daughters_as()) { + if (std::fabs(daughters.eta()) > configTracks.cfgCutEta) + continue; // eta cut for daughters + } // loop over daughters + } + + histos.fill(HIST("QA/MC/h2GenEtaPt_afterRapcut"), part.eta(), part.pt()); + histos.fill(HIST("QA/MC/h2GenPhiRapidity_afterRapcut"), part.phi(), part.y()); + + if (cUseEtacutMC && std::abs(part.eta()) > cEtacutMC) // eta cut + continue; + + histos.fill(HIST("QA/MC/h2GenEtaPt_afterEtaRapCut"), part.eta(), part.pt()); + histos.fill(HIST("QA/MC/h2GenPhiRapidity_afterEtaRapCut"), part.phi(), part.y()); + + histos.fill(HIST("QA/Gen"), 1); + if (part.pdgCode() > 0) // without any event selection + histos.fill(HIST("Result/MC/Genlambda1520pt"), 0, part.pt(), centrality); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 0, part.pt(), centrality); + + if (inVtx10) // vtx10 + { + histos.fill(HIST("QA/Gen"), 2); + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 1, part.pt(), centrality); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 1, part.pt(), centrality); + } + if (inVtx10 && isSel8) // vtx10, sel8 + { + histos.fill(HIST("QA/Gen"), 3); + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 2, part.pt(), centrality); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 2, part.pt(), centrality); + } + if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX + { + histos.fill(HIST("QA/Gen"), 4); + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 3, part.pt(), centrality); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 3, part.pt(), centrality); + } + if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 + { + histos.fill(HIST("QA/Gen"), 5); + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 4, part.pt(), centrality); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 4, part.pt(), centrality); + } + if (isInAfterAllCuts) // after all event selection + { + histos.fill(HIST("QA/Gen"), 6); + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 5, part.pt(), centrality); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 5, part.pt(), centrality); + } + if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 + { + histos.fill(HIST("QA/Gen"), 7); + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 6, part.pt(), centrality); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 6, part.pt(), centrality); + } + } + + auto computePtL = [&](float pt, float m_ref) { + float ptL2 = pt * pt + m_ref * m_ref - MassLambda1520 * MassLambda1520; + return (ptL2 > 0) ? std::sqrt(ptL2) : -1.f; + }; + + // ===== NUM ===== + if (!(inVtx10 && isTrueINELgt0)) + return; + + if (!isInAfterAllCuts) + return; + + // if (!collision.has_mcCollision()) + // return; + + for (const auto& part : mcPartsAll) { + + if (!part.isPhysicalPrimary()) + continue; + + if (cUseRapcutMC && std::abs(part.y()) > configTracks.cfgCutRapidity) + continue; + + if (cUseEtacutMC && std::abs(part.eta()) > cEtacutMC) + continue; + + float pt = part.pt(); + + // proton + if (std::abs(part.pdgCode()) == kProton) { + histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt_num"), pt, centrality); + + float ptL = computePtL(pt, massPr); + if (ptL > 0) { + float w = useWeight ? ptL / pt : 1.f; + histos.fill(HIST("Result/SignalLoss/Genprotonpt_num"), ptL, centrality, w); + } + } + + // lambda + if (std::abs(part.pdgCode()) == kLambda0) { + histos.fill(HIST("Result/SignalLoss/GenTruelambdapt_num"), pt, centrality); + + float ptL = computePtL(pt, MassLambda0); + if (ptL > 0) { + float w = useWeight ? ptL / pt : 1.f; + histos.fill(HIST("Result/SignalLoss/Genlambdapt_num"), ptL, centrality, w); + } + } + + // xi + if (std::abs(part.pdgCode()) == PDG_t::kXiMinus) { + histos.fill(HIST("Result/SignalLoss/GenTruexipt_num"), pt, centrality); + + float ptL = computePtL(pt, MassXiMinus); + if (ptL > 0) { + float w = useWeight ? ptL / pt : 1.f; + histos.fill(HIST("Result/SignalLoss/Genxipt_num"), ptL, centrality, w); + } + } + } + } + PROCESS_SWITCH(Lambda1520analysisinpp, processMCGen, "Process Event for MC only", false); + + void processEventFactor(soa::Join const& mcCollisions, aod::McParticles const& mcParticles) + { + for (const auto& mccolls : mcCollisions) { + float centrality = mccolls.centFT0M(); + bool inVtx10 = std::abs(mccolls.posZ()) <= configEvents.cfgEvtZvtx; + + auto mcPartsThis = mcParticles.sliceBy(perMcCollision, mccolls.globalIndex()); + bool isTrueINELgt0 = pwglf::isINELgt0mc(mcPartsThis, pdg); // QA for Trigger efficiency + + histos.fill(HIST("Event/hMCEventIndices"), centrality, Inel); + if (inVtx10) + histos.fill(HIST("Event/hMCEventIndices"), centrality, Inel10); + if (isTrueINELgt0) + histos.fill(HIST("Event/hMCEventIndices"), centrality, Inelg0); + if (inVtx10 && isTrueINELgt0) + histos.fill(HIST("Event/hMCEventIndices"), centrality, Inelg010); + } + } + PROCESS_SWITCH(Lambda1520analysisinpp, processEventFactor, "Process Event factor", false); + + void processSignalLoss(soa::Join const& mcCollisions, aod::McParticles const& mcParticles) + { + for (const auto& mccolls : mcCollisions) { + float centrality = mccolls.centFT0M(); + + bool inVtx10 = std::abs(mccolls.posZ()) <= configEvents.cfgEvtZvtx; + + auto mcPartsThis = mcParticles.sliceBy(perMcCollision, mccolls.globalIndex()); + bool isTrueINELgt0 = pwglf::isINELgt0mc(mcPartsThis, pdg); + + if (!(inVtx10 && isTrueINELgt0)) + continue; + + auto computePtL = [&](float pt, float m_ref) { + float ptL2 = pt * pt + m_ref * m_ref - MassLambda1520 * MassLambda1520; + return (ptL2 > 0) ? std::sqrt(ptL2) : -1.f; + }; + + for (const auto& part : mcPartsThis) { + + // if (!part.has_mcCollision()) + // continue; + + if (cUseRapcutMC && std::abs(part.y()) > configTracks.cfgCutRapidity) + continue; + + if (cUseEtacutMC && std::abs(part.eta()) > cEtacutMC) + continue; + + // ========================= + // ===== LAMBDA(1520) ====== + // ========================= + if (std::abs(part.pdgCode()) == Pdg::kLambda1520_Py) { + + std::vector daughterPDGs; + if (part.has_daughters()) { + auto daughter01 = mcParticles.rawIteratorAt(part.daughtersIds()[0] - mcParticles.offset()); + auto daughter02 = mcParticles.rawIteratorAt(part.daughtersIds()[1] - mcParticles.offset()); + daughterPDGs = {daughter01.pdgCode(), daughter02.pdgCode()}; + } else { + daughterPDGs = {-1, -1}; + } + + bool pass1 = std::abs(daughterPDGs[0]) == kKPlus || std::abs(daughterPDGs[1]) == kKPlus; // At least one decay to Kaon + bool pass2 = std::abs(daughterPDGs[0]) == kProton || std::abs(daughterPDGs[1]) == kProton; // At least one decay to Proton + + // Checking if we have both decay products + if (!pass1 || !pass2) + continue; + + if (part.pdgCode() > 0) + histos.fill(HIST("Result/SignalLoss/GenTruelambda1520pt_den"), part.pt(), centrality); + else + histos.fill(HIST("Result/SignalLoss/GenTrueantilambda1520pt_den"), part.pt(), centrality); + } + + if (!part.isPhysicalPrimary()) + continue; + + float pt = part.pt(); + float weight = 1.f; + + // ========================= + // ===== PROTON ============ + // ========================= + if (std::abs(part.pdgCode()) == kProton) { + + // --- DENOMINATOR ONLY + histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt_den"), pt, centrality); + + float ptL = computePtL(pt, massPr); + if (ptL < 0) + continue; + + if (useWeight) + weight = ptL / pt; + + histos.fill(HIST("Result/SignalLoss/Genprotonpt_den"), ptL, centrality, weight); + } + + // ========================= + // ===== LAMBDA ============ + // ========================= + if (std::abs(part.pdgCode()) == kLambda0) { + + histos.fill(HIST("Result/SignalLoss/GenTruelambdapt_den"), pt, centrality); + + float ptL = computePtL(pt, MassLambda0); + if (ptL < 0) + continue; + + if (useWeight) + weight = ptL / pt; + + histos.fill(HIST("Result/SignalLoss/Genlambdapt_den"), ptL, centrality, weight); + } + + // ========================= + // ===== XI ================= + // ========================= + if (std::abs(part.pdgCode()) == PDG_t::kXiMinus) { + + histos.fill(HIST("Result/SignalLoss/GenTruexipt_den"), pt, centrality); + + float ptL = computePtL(pt, MassXiMinus); + if (ptL < 0) + continue; + + if (useWeight) + weight = ptL / pt; + + histos.fill(HIST("Result/SignalLoss/Genxipt_den"), ptL, centrality, weight); + } + } + } + } + PROCESS_SWITCH(Lambda1520analysisinpp, processSignalLoss, "Process SignalLoss", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} + + #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/O2DatabasePDGPlugin.h" From cff8beec08a28834af1a9ea476642552e442310a Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Tue, 14 Apr 2026 13:30:03 +0530 Subject: [PATCH 2/5] linter fix --- .../Resonances/lambda1520analysisinpp.cxx | 1520 ----------------- 1 file changed, 1520 deletions(-) diff --git a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx index 73dbf1ae02b..86675a501d0 100644 --- a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx @@ -13,27 +13,6 @@ /// \brief This standalone task reconstructs track-track decay of lambda(1520) resonance candidate /// \author Hirak Kumar Koley -#include "PWGLF/Utils/inelGt.h" - -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h"// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file lambda1520analysisinpp.cxx -/// \brief This standalone task reconstructs track-track decay of lambda(1520) resonance candidate -/// \author Hirak Kumar Koley - #include "PWGLF/DataModel/mcCentrality.h" #include "PWGLF/Utils/inelGt.h" @@ -1514,1502 +1493,3 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } - - -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" - -#include "Math/Vector4D.h" -#include "TPDGCode.h" -#include "TRandom.h" - -#include -#include - -using namespace o2; -using namespace o2::soa; -using namespace o2::aod; -using namespace o2::aod::rctsel; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::constants::physics; - -using LorentzVectorPtEtaPhiMass = ROOT::Math::PtEtaPhiMVector; - -enum { - Inel = 1, - Inel10, - Inelg0, - Inelg010, - Trig, - Trig10, - TrigINELg0, - TrigINELg010, - Sel8, - Sel810, - Sel8INELg0, - Sel8INELg010, - AllCuts, - AllCuts10, - AllCutsINELg0, - AllCutsINELg010, -}; - -enum TrackSelectionType { - AllTracks = 0, - GlobalTracks, - GlobalTracksWoPtEta, - GlobalTracksWoDCA, - QualityTracks, - InAcceptanceTracks, -}; - -enum PIDCutType { - SquareType = 1, - CircularType, -}; - -struct Lambda1520analysisinpp { - // Define slice per Resocollision - SliceCache cache; - Preslice perCollision = o2::aod::track::collisionId; - Preslice perMcCollision = o2::aod::mcparticle::mcCollisionId; - - HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - Service pdg; - RCTFlagsChecker rctChecker; - - struct : ConfigurableGroup { - Configurable cfgEvtZvtx{"cfgEvtZvtx", 10.0f, "Evt sel: Max. z-Vertex (cm)"}; - Configurable cfgEvtTriggerTVXSel{"cfgEvtTriggerTVXSel", true, "Evt sel: triggerTVX selection (MB)"}; - Configurable cfgEvtNoTFBorderCut{"cfgEvtNoTFBorderCut", true, "Evt sel: apply TF border cut"}; - Configurable cfgEvtNoITSROFrameBorderCut{"cfgEvtNoITSROFrameBorderCut", false, "Evt sel: apply NoITSRO border cut"}; - Configurable cfgEvtIsRCTFlagpassed{"cfgEvtIsRCTFlagpassed", false, "Evt sel: apply RCT flag selection"}; - Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; - Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; - Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; - Configurable cfgEvtSel8{"cfgEvtSel8", false, "Evt Sel 8 check for offline selection"}; - Configurable cfgEvtIsINELgt0{"cfgEvtIsINELgt0", false, "Evt sel: apply INEL>0 selection"}; - } configEvents; - - struct : ConfigurableGroup { - // Pre-selection Track cuts - Configurable trackSelection{"trackSelection", 0, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; - Configurable cMinPtcut{"cMinPtcut", 0.15f, "Minimal pT for tracks"}; - Configurable cMinTPCNClsFound{"cMinTPCNClsFound", 120, "minimum TPCNClsFound value for good track"}; - Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; - Configurable cfgCutRapidity{"cfgCutRapidity", 0.5f, "rapidity range for particles"}; - Configurable cfgMinCrossedRows{"cfgMinCrossedRows", 70, "min crossed rows for good track"}; - - // DCA Selections - // DCAr to PV - Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1f, "Track DCAr cut to PV Maximum"}; - // DCAz to PV - Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 0.1f, "Track DCAz cut to PV Maximum"}; - - // Track selections - Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz - Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) - Configurable cfgGlobalTrack{"cfgGlobalTrack", false, "Global track selection"}; // kGoldenChi2 | kDCAxy | kDCAz - Configurable cfgPVContributor{"cfgPVContributor", false, "PV contributor track selection"}; // PV Contriuibutor - Configurable cfgHasTOF{"cfgHasTOF", false, "Require TOF"}; - Configurable cfgUseTPCRefit{"cfgUseTPCRefit", false, "Require TPC Refit"}; - Configurable cfgUseITSRefit{"cfgUseITSRefit", false, "Require ITS Refit"}; - Configurable cTPCNClsFound{"cTPCNClsFound", false, "Switch to turn on/off TPCNClsFound cut"}; - Configurable cDCAr7SigCut{"cDCAr7SigCut", false, "Track DCAr 7 Sigma cut to PV Maximum"}; - } configTracks; - - struct : ConfigurableGroup { - /// PID Selections - Configurable pidnSigmaPreSelectionCut{"pidnSigmaPreSelectionCut", 4.0f, "pidnSigma Cut for pre-selection of tracks"}; - Configurable cByPassTOF{"cByPassTOF", false, "By pass TOF PID selection"}; // By pass TOF PID selection - Configurable cPIDcutType{"cPIDcutType", 2, "cPIDcutType = 1 for square cut, 2 for circular cut"}; // By pass TOF PID selection - - // Kaon - Configurable> kaonTPCPIDpTintv{"kaonTPCPIDpTintv", {0.5f}, "pT intervals for Kaon TPC PID cuts"}; - Configurable> kaonTPCPIDcuts{"kaonTPCPIDcuts", {2}, "nSigma list for Kaon TPC PID cuts"}; - Configurable> kaonTOFPIDpTintv{"kaonTOFPIDpTintv", {999.0f}, "pT intervals for Kaon TOF PID cuts"}; - Configurable> kaonTOFPIDcuts{"kaonTOFPIDcuts", {2}, "nSigma list for Kaon TOF PID cuts"}; - Configurable> kaonTPCTOFCombinedpTintv{"kaonTPCTOFCombinedpTintv", {999.0f}, "pT intervals for Kaon TPC-TOF PID cuts"}; - Configurable> kaonTPCTOFCombinedPIDcuts{"kaonTPCTOFCombinedPIDcuts", {2}, "nSigma list for Kaon TPC-TOF PID cuts"}; - - // Proton - Configurable> protonTPCPIDpTintv{"protonTPCPIDpTintv", {0.9f}, "pT intervals for Kaon TPC PID cuts"}; - Configurable> protonTPCPIDcuts{"protonTPCPIDcuts", {2}, "nSigma list for Kaon TPC PID cuts"}; - Configurable> protonTOFPIDpTintv{"protonTOFPIDpTintv", {999.0f}, "pT intervals for Kaon TOF PID cuts"}; - Configurable> protonTOFPIDcuts{"protonTOFPIDcuts", {2}, "nSigma list for Kaon TOF PID cuts"}; - Configurable> protonTPCTOFCombinedpTintv{"protonTPCTOFCombinedpTintv", {999.0f}, "pT intervals for Proton TPC-TOF PID cuts"}; - Configurable> protonTPCTOFCombinedPIDcuts{"protonTPCTOFCombinedPIDcuts", {2}, "nSigma list for Proton TPC-TOF PID cuts"}; - } configPID; - - struct : ConfigurableGroup { - /// Event Mixing - Configurable nEvtMixing{"nEvtMixing", 10, "Number of events to mix"}; - ConfigurableAxis cfgVtxBins{"cfgVtxBins", {VARIABLE_WIDTH, -10.0f, -8.0f, -6.0f, -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f, 8.0f, 10.0f}, "Mixing bins - z-vertex"}; - ConfigurableAxis cfgMultPercentileBins{"cfgMultPercentileBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Mixing bins - multiplicity"}; - - // Rotational background - Configurable rotationalcut{"rotationalcut", 10, "Cut value (Rotation angle pi - pi/cut and pi + pi/cut)"}; - Configurable cNofRotations{"cNofRotations", 3, "Number of random rotations in the rotational background"}; - Configurable cfgRotPr{"cfgRotPr", true, "rotate Proton"}; - } configBkg; - - // Additional purity check - Configurable crejectPion{"crejectPion", false, "Switch to turn on/off pion contamination"}; - Configurable cUseOpeningAngleCut{"cUseOpeningAngleCut", false, "Kinematic Cuts for p-K pair opening angle"}; - Configurable cMinOpeningAngle{"cMinOpeningAngle", 1.4f, "Minimum opening angle between daughters"}; - Configurable cMaxOpeningAngle{"cMaxOpeningAngle", 2.4f, "Maximum opening angle between daughters"}; - Configurable cfgUseDeltaEtaPhiCuts{"cfgUseDeltaEtaPhiCuts", false, "Switch to turn on/off delta eta and delta phi cuts"}; - Configurable cfgUseDaughterEtaCutMC{"cfgUseDaughterEtaCutMC", false, "Switch to turn on/off eta cuts for daughters in MC"}; - - // MC selection cut - Configurable cEtacutMC{"cEtacutMC", 0.5f, "MC eta cut"}; - Configurable cUseRapcutMC{"cUseRapcutMC", true, "MC eta cut"}; - Configurable cUseEtacutMC{"cUseEtacutMC", true, "MC eta cut"}; - Configurable useWeight{"useWeight", false, "Use weight for signal loss calculation"}; - - // cuts on mother - Configurable cfgUseCutsOnMother{"cfgUseCutsOnMother", false, "Enable additional cuts on mother"}; - Configurable cMaxPtMotherCut{"cMaxPtMotherCut", 10.0f, "Maximum pt of mother cut"}; - Configurable cMaxMinvMotherCut{"cMaxMinvMotherCut", 3.0f, "Maximum Minv of mother cut"}; - Configurable cMaxDeltaEtaCut{"cMaxDeltaEtaCut", 0.7f, "Maximum deltaEta between daughters"}; - Configurable cMaxDeltaPhiCut{"cMaxDeltaPhiCut", 1.5f, "Maximum deltaPhi between daughters"}; - - // switches - Configurable cFillMultQA{"cFillMultQA", false, "Turn on/off additional QA plots"}; - Configurable cFillTrackQA{"cFillTrackQA", false, "Turn on/off additional QA plots"}; - Configurable cFilladditionalQAeventPlots{"cFilladditionalQAeventPlots", false, "Additional QA event plots"}; - Configurable cFilladditionalMEPlots{"cFilladditionalMEPlots", false, "Additional Mixed event plots"}; - Configurable cFilldeltaEtaPhiPlots{"cFilldeltaEtaPhiPlots", false, "Enable additional cuts on daughters"}; - Configurable cFill1DQAs{"cFill1DQAs", false, "Invariant mass 1D"}; - Configurable centEstimator{"centEstimator", 0, "Select centrality estimator: 0 - FT0M, 1 - FT0A, 2 - FT0C"}; - - TRandom* rn = new TRandom(); - - // Pre-filters for efficient process - Filter zVtxFilter = (nabs(o2::aod::collision::posZ) <= configEvents.cfgEvtZvtx); - Filter collisionFilterMC = nabs(aod::mccollision::posZ) <= configEvents.cfgEvtZvtx; - // Filter centralityFilter = nabs(aod::cent::centFT0C) <= cfg_Event_CentralityMax; - // Filter triggerFilter = (o2::aod::evsel::sel8 == true); - - Filter acceptanceFilter = (nabs(aod::track::eta) < configTracks.cfgCutEta && nabs(aod::track::pt) > configTracks.cMinPtcut) && - (nabs(aod::track::dcaXY) < configTracks.cMaxDCArToPVcut) && (nabs(aod::track::dcaZ) < configTracks.cMaxDCAzToPVcut); - - // Filter tofPIDFilter = aod::track::tofExpMom < 0.0f || ((aod::track::tofExpMom > 0.0f) && ( (nabs(aod::pidtof::tofNSigmaPi) < configPID.pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaKa) < configPID.pidnSigmaPreSelectionCut) || (nabs(aod::pidtof::tofNSigmaPr) < configPID.pidnSigmaPreSelectionCut))); // TOF - // Filter tpcPIDFilter = nabs(aod::pidtpc::tpcNSigmaPi) < configPID.pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaKa) < configPID.pidnSigmaPreSelectionCut || nabs(aod::pidtpc::tpcNSigmaPr) < configPID.pidnSigmaPreSelectionCut; // TPC - /* Filter trackFilter = (configTracks.trackSelection == AllTracks) || - ((configTracks.trackSelection == GlobalTracks) && requireGlobalTrackInFilter()) || - ((configTracks.trackSelection == GlobalTracksWoPtEta) && requireGlobalTrackWoPtEtaInFilter()) || - ((configTracks.trackSelection == GlobalTracksWoDCA) && requireGlobalTrackWoDCAInFilter()) || - ((configTracks.trackSelection == QualityTracks) && requireQualityTracksInFilter()) || - ((configTracks.trackSelection == InAcceptanceTracks) && requireTrackCutInFilter(TrackSelectionFlags::kInAcceptanceTracks)); - */ - // Filter primarytrackFilter = requirePVContributor() && requirePrimaryTrack() && requireGlobalTrackWoDCA(); - - using EventCandidates = soa::Join; - using TrackCandidates = soa::Filtered>; - using MCEventCandidates = soa::Join; - using MCTrackCandidates = soa::Filtered>; - - /// Figures - ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.12f, 0.14f, 0.16f, 0.18f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.5f, 0.55f, 0.6f, 0.65f, 0.7f, 0.75f, 0.8f, 0.85f, 0.9f, 0.95f, 1.0f, 1.1f, 1.2f, 1.25f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.75f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.6f, 3.7f, 3.8f, 3.9f, 4.0f, 4.1f, 4.2f, 4.5f, 4.6f, 4.8f, 4.9f, 5.0f, 5.5f, 5.6f, 6.0f, 6.4f, 6.5f, 7.0f, 7.2f, 8.0f, 9.0f, 9.5f, 9.6f, 10.0f, 11.0f, 11.5f, 12.0f, 13.0f, 14.0f, 14.4f, 15.0f, 16.0f, 18.0f, 19.2f, 20.0f}, "Binning of the pT axis"}; - ConfigurableAxis binsPtQA{"binsPtQA", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.4f, 1.6f, 1.8f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.2f, 4.4f, 4.6f, 4.8f, 5.0f, 5.2f, 5.4f, 5.6f, 5.8f, 6.0f, 6.2f, 6.4f, 6.6f, 6.8f, 7.0f, 7.2f, 7.4f, 7.6f, 7.8f, 8.0f, 8.2f, 8.4f, 8.6f, 8.8f, 9.0f, 9.2f, 9.4f, 9.6f, 9.8f, 10.0f, 10.2f, 10.4f, 10.6f, 10.8f, 11.0f, 11.2f, 11.4f, 11.6f, 11.8f, 12.0f, 12.2f, 12.4f, 12.6f, 12.8f, 13.0f, 13.2f, 13.4f, 13.6f, 13.8f, 14.0f, 14.2f, 14.4f, 14.6f, 14.8f, 15.0f, 15.2f, 15.4f, 15.6f, 15.8f, 16.0f, 16.2f, 16.4f, 16.6f, 16.8f, 17.0f, 17.2f, 17.4f, 17.6f, 17.8f, 18.0f, 18.2f, 18.4f, 18.6f, 18.8f, 19.0f, 19.2f, 19.4f, 19.6f, 19.8f, 20.0f}, "Binning of the pT axis"}; - ConfigurableAxis binsEta{"binsEta", {150, -1.5f, 1.5f}, ""}; - ConfigurableAxis binsMass{"binsMass", {70, 1.3f, 2.0f}, "Invariant Mass (GeV/#it{c}^2)"}; - ConfigurableAxis binsMult{"binsMult", {105, 0.0f, 105.0f}, "mult_{FT0M}"}; - ConfigurableAxis binsDCAz{"binsDCAz", {40, -0.2f, 0.2f}, ""}; - ConfigurableAxis binsDCAxy{"binsDCAxy", {40, -0.2f, 0.2f}, ""}; - ConfigurableAxis binsTPCXrows{"binsTPCXrows", {100, 60, 160}, ""}; - ConfigurableAxis binsnSigma{"binsnSigma", {130, -6.5f, 6.5f}, ""}; - ConfigurableAxis binsnTPCSignal{"binsnTPCSignal", {1000, 0, 1000}, ""}; - ConfigurableAxis binsEtaPhi{"binsEtaPhi", {350, -3.5f, 3.5f}, ""}; - - void init(framework::InitContext&) - { - rctChecker.init(configEvents.cfgEvtRCTFlagCheckerLabel, configEvents.cfgEvtRCTFlagCheckerZDCCheck, configEvents.cfgEvtRCTFlagCheckerLimitAcceptAsBad); - - // axes - AxisSpec axisPt{binsPt, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec axisPtQA{binsPtQA, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec axisEta{binsEta, "#eta"}; - AxisSpec axisRap{binsEta, "#it{y}"}; - AxisSpec axisMassLambda1520{binsMass, "Invariant Mass (GeV/#it{c}^2)"}; - AxisSpec axisMult{binsMult, "mult_{FT0M}"}; - AxisSpec axisDCAz{binsDCAz, "DCA_{z}"}; - AxisSpec axisDCAxy{binsDCAxy, "DCA_{XY}"}; - AxisSpec axisTPCXrow{binsTPCXrows, "#Xrows_{TPC}"}; - AxisSpec axisPIDQA{binsnSigma, "#sigma"}; - AxisSpec axisTPCSignal{binsnTPCSignal, ""}; - AxisSpec axisMClabel{9, -1.f, 8.f, "MC Label"}; - AxisSpec axisEtaPhi{binsEtaPhi, ""}; - AxisSpec axisPhi{350, 0, 7, "#Phi"}; - AxisSpec axisMultMix{configBkg.cfgMultPercentileBins, "Multiplicity Percentile"}; - AxisSpec axisVtxMix{configBkg.cfgVtxBins, "Vertex Z (cm)"}; - AxisSpec idxMCAxis = {26, -0.5f, 25.5f, "Index"}; - - histos.add("CollCutCounts", "No. of event after cuts", kTH1I, {{10, 0, 10}}); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(1, "All Events"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(2, "|Vz| < cut"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(5, "kNoITSROFrameBorder"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(6, "rctChecker"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(7, "sel8"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(8, "IsINELgt0"); - histos.get(HIST("CollCutCounts"))->GetXaxis()->SetBinLabel(9, "All Passed Events"); - - histos.add("Event/posZ", "; vtx_{z} (cm); Entries", HistType::kTH1F, {{250, -12.5, 12.5}}); - histos.add("Event/centFT0M", "; FT0M Percentile; Entries", HistType::kTH1F, {{110, 0, 110}}); - - if (cFilladditionalQAeventPlots) { - // event histograms - if (doprocessData) { - histos.add("QAevent/hPairsCounterSameE", "total valid no. of pairs sameE", HistType::kTH1F, {{1, 0.5f, 1.5f}}); - histos.add("QAevent/hnTrksSameE", "n tracks per event SameE", HistType::kTH1F, {{1000, 0.0, 1000.0}}); - } - // Gen on Mixed event - if (doprocessME) { - - // Histograms for Mixed Event Pool characteristics - histos.add("QAevent/hMixPool_VtxZ", "Mixed Event Pool: Vertex Z;Vtx Z (cm);Counts", HistType::kTH1F, {axisVtxMix}); - histos.add("QAevent/hMixPool_Multiplicity", "Mixed Event Pool: Multiplicity;Multiplicity;Counts", HistType::kTH1F, {axisMultMix}); - histos.add("QAevent/hMixPool_VtxZ_vs_Multiplicity", "Mixed Event Pool: Vertex Z vs Multiplicity;Counts", HistType::kTH2F, {axisVtxMix, axisMultMix}); - - histos.add("QAevent/hPairsCounterMixedE", "total valid no. of pairs mixedE", HistType::kTH1F, {{1, 0.5f, 1.5f}}); - histos.add("QAevent/hVertexZMixedE", "Collision Vertex Z position", HistType::kTH1F, {{100, -15.0f, 15.0f}}); - histos.add("QAevent/hMultiplicityPercentMixedE", "Multiplicity percentile of collision", HistType::kTH1F, {{120, 0.0f, 120.0f}}); - histos.add("QAevent/hnTrksMixedE", "n tracks per event MixedE", HistType::kTH1F, {{1000, 0.0f, 1000.0f}}); - } - } - - if (doprocessData) { - // Track QA before cuts - // --- Track - if (cFillTrackQA) { - histos.add("QA/QAbefore/Track/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;{#sigma_{TOF}^{Kaon}};{#sigma_{TPC}^{Kaon}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPConly_Nsigma_ka", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;{#sigma_{TOF}^{Proton}};{#sigma_{TPC}^{Proton}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/TPConly_Nsigma_pr", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); - histos.add("QA/QAbefore/Track/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTH2F, {axisPt, axisDCAz}); - histos.add("QA/QAbefore/Track/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); - histos.add("QA/QAbefore/Track/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); - histos.add("QA/QAbefore/Track/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); - histos.add("QA/QAbefore/Track/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); - } - if (cFillMultQA) { - // Multiplicity correlation calibrations - histos.add("MultCalib/centGloPVpr", "Centrality vs Global-Tracks", kTHnSparseF, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}, {500, 0, 5000, "PV tracks"}}); - histos.add("MultCalib/centGloPVka", "Centrality vs Global-Tracks", kTHnSparseF, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}, {500, 0, 5000, "PV tracks"}}); - } - - // PID QA after cuts - // --- Kaon - histos.add("QA/QAafter/Kaon/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;{#sigma_{TOF}^{Kaon}};{#sigma_{TPC}^{Kaon}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); - histos.add("QA/QAafter/Kaon/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAafter/Kaon/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAafter/Kaon/TPC_Nsigma_ka_TPConly", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); - histos.add("QA/QAafter/Kaon/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTH2F, {axisPt, axisDCAz}); - histos.add("QA/QAafter/Kaon/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); - histos.add("QA/QAafter/Kaon/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); - histos.add("QA/QAafter/Kaon/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); - histos.add("QA/QAafter/Kaon/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); - histos.add("QA/QAafter/Kaon/TPC_Signal_ka_all", "TPC Signal for Kaon;#it{p} (GeV/#it{c});TPC Signal (A.U.)", {HistType::kTH2F, {axisPt, axisTPCSignal}}); - histos.add("QA/QAafter/Kaon/TPCnclusterPhika", "TPC ncluster vs phi", kTHnSparseF, {{160, 0, 160, "TPC nCluster"}, {63, 0.0f, 6.28f, "#phi"}}); - - // --- Proton - histos.add("QA/QAafter/Proton/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;{#sigma_{TOF}^{Proton}};{#sigma_{TPC}^{Proton}}", {HistType::kTH2F, {axisPIDQA, axisPIDQA}}); - histos.add("QA/QAafter/Proton/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAafter/Proton/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/QAafter/Proton/TPC_Nsigma_pr_TPConly", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTH2F, {axisPt, axisPIDQA}}); - histos.add("QA/QAafter/Proton/dcaZ", "DCA_{Z} distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm);", HistType::kTH2F, {axisPt, axisDCAz}); - histos.add("QA/QAafter/Proton/dcaXY", "DCA_{XY} momentum distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTH2F, {axisPt, axisDCAxy}); - histos.add("QA/QAafter/Proton/TPC_CR", "# TPC Xrows distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTH2F, {axisPt, axisTPCXrow}); - histos.add("QA/QAafter/Proton/pT", "pT distribution of Protons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); - histos.add("QA/QAafter/Proton/eta", "#eta distribution of Protons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); - histos.add("QA/QAafter/Proton/TPC_Signal_pr_all", "TPC Signal for Proton;#it{p} (GeV/#it{c});TPC Signal (A.U.)", {HistType::kTH2F, {axisPt, axisTPCSignal}}); - histos.add("QA/QAafter/Proton/TPCnclusterPhipr", "TPC ncluster vs phi", kTHnSparseF, {{160, 0, 160, "TPC nCluster"}, {63, 0.0f, 6.28f, "#phi"}}); - - // Mass QA 1D for quick check - if (cFill1DQAs) { - histos.add("Result/Data/lambda1520invmass", "Invariant mass of #Lambda(1520) K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); - histos.add("Result/Data/antilambda1520invmass", "Invariant mass of #Lambda(1520) K^{#mp}p^{#pm}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); - histos.add("Result/Data/lambda1520invmassLSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr - histos.add("Result/Data/lambda1520invmassLSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr - } - // eta phi QA - if (cFilldeltaEtaPhiPlots) { - histos.add("QAbefore/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); - histos.add("QAbefore/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); - - histos.add("QAafter/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); - histos.add("QAafter/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); - - histos.add("QAafter/PhiPrafter", "Phi of proton candidates", HistType::kTH1F, {axisPhi}); - histos.add("QAafter/PhiKaafter", "Phi of kaon candidates", HistType::kTH1F, {axisPhi}); - } - - // 3d histogram - histos.add("Result/Data/h3lambda1520invmass", "Invariant mass of #Lambda(1520) K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - histos.add("Result/Data/h3antilambda1520invmass", "Invariant mass of #Lambda(1520) K^{#mp}p^{#pm}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - histos.add("Result/Data/h3lambda1520invmassLSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K+ + Pr - histos.add("Result/Data/h3lambda1520invmassLSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K- + anti-Pr - } - - if (doprocessRotational) { - if (cFill1DQAs) { - histos.add("Result/Data/lambda1520InvMassRotation", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr - histos.add("Result/Data/antilambda1520InvMassRotation", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr - } - histos.add("Result/Data/h3lambda1520InvMassRotation", "Invariant mass of #Lambda(1520) rotation", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - histos.add("Result/Data/h3antilambda1520InvMassRotation", "Invariant mass of #Lambda(1520) rotation", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - } - // Mixed event histograms - if (doprocessME) { - if (cFill1DQAs) { - histos.add("Result/Data/lambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); - histos.add("Result/Data/antilambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); - } - histos.add("Result/Data/h3lambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - histos.add("Result/Data/h3antilambda1520invmassME_UnlikeSign", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - - if (cFilladditionalMEPlots) { - if (cFill1DQAs) { - histos.add("Result/Data/lambda1520invmassME_LSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr - histos.add("Result/Data/lambda1520invmassME_LSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr - } - histos.add("Result/Data/h3lambda1520invmassME_LSPP", "Invariant mass of #Lambda(1520) mixed event Like Sign Method K^{#plus}p^{#plus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K+ + Pr - histos.add("Result/Data/h3lambda1520invmassME_LSMM", "Invariant mass of #Lambda(1520) mixed event Like Sign Method K^{#minus}p^{#minus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K- + anti-Pr - } - } - - // MC QA - histos.add("Event/hMCEventIndices", "hMCEventIndices", kTH2D, {axisMult, idxMCAxis}); - if (doprocessMCGen) { - histos.add("QA/Gen", "Gen histogram", kTH1D, {{10, 0, 10, "index"}}); - histos.add("QA/MC/h2GenEtaPt_beforeanycut", " #eta-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); - histos.add("QA/MC/h2GenPhiRapidity_beforeanycut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); - histos.add("QA/MC/h2GenEtaPt_afterEtaRapCut", " #eta-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); - histos.add("QA/MC/h2GenPhiRapidity_afterEtaRapCut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); - histos.add("QA/MC/h2GenEtaPt_afterRapcut", " #phi-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); - histos.add("QA/MC/h2GenPhiRapidity_afterRapcut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); - - histos.add("Result/MC/Genlambda1520pt", "pT distribution of True MC #Lambda(1520)0", kTH3F, {axisMClabel, axisPt, axisMult}); - histos.add("Result/MC/Genantilambda1520pt", "pT distribution of True MC Anti-#Lambda(1520)0", kTH3F, {axisMClabel, axisPt, axisMult}); - } - if (doprocessMCRec) { - histos.add("QA/MC/h2RecoEtaPt_after", " #eta-#it{p}_{T} distribution of Reconstructed #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPt}); - histos.add("QA/MC/h2RecoPhiRapidity_after", " #phi-y distribution of Reconstructed #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisRap}); - - histos.add("QA/MC/trkDCAxy_pr", "DCAxy distribution of proton track candidates", HistType::kTHnSparseF, {axisPt, axisDCAxy}); - histos.add("QA/MC/trkDCAxy_ka", "DCAxy distribution of kaon track candidates", HistType::kTHnSparseF, {axisPt, axisDCAxy}); - histos.add("QA/MC/trkDCAz_pr", "DCAz distribution of proton track candidates", HistType::kTHnSparseF, {axisPt, axisDCAz}); - histos.add("QA/MC/trkDCAz_ka", "DCAz distribution of kaon track candidates", HistType::kTHnSparseF, {axisPt, axisDCAz}); - histos.add("QA/MC/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/MC/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Proton}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/MC/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TOF}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - histos.add("QA/MC/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});{#sigma_{TPC}^{Kaon}};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); - - histos.add("Result/MC/h3lambda1520Recoinvmass", "Invariant mass of Reconstructed MC #Lambda(1520)0", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - histos.add("Result/MC/h3antilambda1520Recoinvmass", "Invariant mass of Reconstructed MC Anti-#Lambda(1520)0", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); - } - if (doprocessSignalLoss) { - histos.add("Result/SignalLoss/Genprotonpt", "pT distribution of #Lambda(1520) from Proton", kTH3F, {axisMClabel, axisPt, axisMult}); - histos.add("Result/SignalLoss/Genlambdapt", "pT distribution of #Lambda(1520) from #Lambda", kTH3F, {axisMClabel, axisPt, axisMult}); - histos.add("Result/SignalLoss/Genxipt", "pT distribution of #Lambda(1520) from #Xi", kTH3F, {axisMClabel, axisPt, axisMult}); - - histos.add("Result/SignalLoss/GenTrueprotonpt", "pT distribution of True MC Proton", kTH3F, {axisMClabel, axisPt, axisMult}); - histos.add("Result/SignalLoss/GenTruelambdapt", "pT distribution of True MC #Lambda", kTH3F, {axisMClabel, axisPt, axisMult}); - histos.add("Result/SignalLoss/GenTruexipt", "pT distribution of True MC #Xi", kTH3F, {axisMClabel, axisPt, axisMult}); - } - - // Print output histograms statistics - LOG(info) << "Size of the histograms in Lambda1520analysisinpp:"; - histos.print(); - } - - float massKa = MassKaonCharged; - float massPr = MassProton; - - // Centralicity estimator selection - template - float centEst(Coll collisions) - { - float returnValue = -999.0f; - switch (centEstimator) { - case 0: - returnValue = collisions.centFT0M(); - break; - case 1: - returnValue = collisions.centFT0A(); - break; - case 2: - returnValue = collisions.centFT0C(); - break; - default: - returnValue = collisions.centFT0M(); - break; - } - return returnValue; - } - - template - bool isSelected(const Coll& collision, bool fillHist = true) - { - auto applyCut = [&](bool enabled, bool condition, int bin) { - if (!enabled) - return true; - if (!condition) - return false; - if (fillHist) - histos.fill(HIST("CollCutCounts"), bin); - return true; - }; - - if (fillHist) - histos.fill(HIST("CollCutCounts"), 0); - - if (!applyCut(true, std::abs(collision.posZ()) <= configEvents.cfgEvtZvtx, 1)) - return false; - - if (!applyCut(configEvents.cfgEvtTriggerTVXSel, - collision.selection_bit(aod::evsel::kIsTriggerTVX), 2)) - return false; - - if (!applyCut(configEvents.cfgEvtNoTFBorderCut, - collision.selection_bit(aod::evsel::kNoTimeFrameBorder), 3)) - return false; - - if (!applyCut(configEvents.cfgEvtNoITSROFrameBorderCut, - collision.selection_bit(aod::evsel::kNoITSROFrameBorder), 4)) - return false; - - if (!applyCut(configEvents.cfgEvtIsRCTFlagpassed, rctChecker(collision), 5)) - return false; - - if (!applyCut(configEvents.cfgEvtSel8, collision.sel8(), 6)) - return false; - - if (!applyCut(configEvents.cfgEvtIsINELgt0, collision.isInelGt0(), 7)) - return false; - - if (fillHist) - histos.fill(HIST("CollCutCounts"), 8); - - return true; - } - - template - bool trackCut(const TrackType track) - { - // basic track cuts - if (configTracks.cDCAr7SigCut && std::abs(track.dcaXY()) > (0.004f + 0.013f / (track.pt()))) // 7 - Sigma cut - return false; - if (configTracks.cTPCNClsFound && (track.tpcNClsFound() < configTracks.cMinTPCNClsFound)) - return false; - if (track.tpcNClsCrossedRows() < configTracks.cfgMinCrossedRows) - return false; - if (configTracks.cfgHasTOF && !track.hasTOF()) - return false; - if (configTracks.cfgPrimaryTrack && !track.isPrimaryTrack()) - return false; - if (configTracks.cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) - return false; - if (configTracks.cfgPVContributor && !track.isPVContributor()) - return false; - if (configTracks.cfgGlobalTrack && !track.isGlobalTrack()) - return false; - - return true; - } - - // LOGF(info, "AFTER: pt: %f, hasTOF: %d, TPCSigma: %f, TOFSigma: %f, boolTPC: %d, boolTOF: %d, bool: %d", pt, candidate.hasTOF(), - // candidate.tpcNSigmaPr(), candidate.tofNSigmaPr(), tpcPIDPassed, tofPIDPassed, tpcPIDPassed || tofPIDPassed); - - template - bool ptDependentPidProton(const T& candidate) - { - auto vProtonTPCPIDpTintv = configPID.protonTPCPIDpTintv.value; - vProtonTPCPIDpTintv.insert(vProtonTPCPIDpTintv.begin(), configTracks.cMinPtcut); - auto vProtonTPCPIDcuts = configPID.protonTPCPIDcuts.value; - auto vProtonTOFPIDpTintv = configPID.protonTOFPIDpTintv.value; - auto vProtonTPCTOFCombinedpTintv = configPID.protonTPCTOFCombinedpTintv.value; - auto vProtonTPCTOFCombinedPIDcuts = configPID.protonTPCTOFCombinedPIDcuts.value; - auto vProtonTOFPIDcuts = configPID.protonTOFPIDcuts.value; - - float pt = candidate.pt(); - float ptSwitchToTOF = vProtonTPCPIDpTintv.back(); - float tpcNsigmaPr = candidate.tpcNSigmaPr(); - float tofNsigmaPr = candidate.tofNSigmaPr(); - - bool tpcPIDPassed = false; - - // TPC PID (interval check) - for (size_t i = 0; i < vProtonTPCPIDpTintv.size() - 1; ++i) { - if (pt > vProtonTPCPIDpTintv[i] && pt < vProtonTPCPIDpTintv[i + 1]) { - if (std::abs(tpcNsigmaPr) < vProtonTPCPIDcuts[i]) - tpcPIDPassed = true; - } - } - - // TOF bypass option (for QA or MC) - if (configPID.cByPassTOF) { - return std::abs(tpcNsigmaPr) < vProtonTPCPIDcuts.back(); - } - - // Case 1: No TOF and pt ≤ threshold → accept only via TPC PID - if (!candidate.hasTOF() && pt <= ptSwitchToTOF) { - return tpcPIDPassed; - } - - // Case 2: No TOF but pt > threshold → reject - if (!candidate.hasTOF() && pt > ptSwitchToTOF) { - return false; - } - - // Case 3: Has TOF → use TPC + TOF (square or circular) - if (candidate.hasTOF()) { - if (configPID.cPIDcutType == SquareType) { - // Rectangular cut - for (size_t i = 0; i < vProtonTOFPIDpTintv.size(); ++i) { - if (pt < vProtonTOFPIDpTintv[i]) { - if (std::abs(tofNsigmaPr) < vProtonTOFPIDcuts[i] && - std::abs(tpcNsigmaPr) < vProtonTPCPIDcuts.back()) - return true; - } - } - } else if (configPID.cPIDcutType == CircularType) { - // Circular cut - for (size_t i = 0; i < vProtonTPCTOFCombinedpTintv.size(); ++i) { - if (pt < vProtonTPCTOFCombinedpTintv[i]) { - float combinedSigma2 = - tpcNsigmaPr * tpcNsigmaPr + - tofNsigmaPr * tofNsigmaPr; - if (combinedSigma2 < vProtonTPCTOFCombinedPIDcuts[i] * vProtonTPCTOFCombinedPIDcuts[i]) - return true; - } - } - } - } - - return false; - } - - template - bool ptDependentPidKaon(const T& candidate) - { - auto vKaonTPCPIDpTintv = configPID.kaonTPCPIDpTintv.value; - vKaonTPCPIDpTintv.insert(vKaonTPCPIDpTintv.begin(), configTracks.cMinPtcut); - auto vKaonTPCPIDcuts = configPID.kaonTPCPIDcuts.value; - auto vKaonTOFPIDpTintv = configPID.kaonTOFPIDpTintv.value; - auto vKaonTPCTOFCombinedpTintv = configPID.kaonTPCTOFCombinedpTintv.value; - auto vKaonTPCTOFCombinedPIDcuts = configPID.kaonTPCTOFCombinedPIDcuts.value; - auto vKaonTOFPIDcuts = configPID.kaonTOFPIDcuts.value; - - float pt = candidate.pt(); - float ptSwitchToTOF = vKaonTPCPIDpTintv.back(); - float tpcNsigmaKa = candidate.tpcNSigmaKa(); - float tofNsigmaKa = candidate.tofNSigmaKa(); - - bool tpcPIDPassed = false; - - // TPC PID interval-based check - for (size_t i = 0; i < vKaonTPCPIDpTintv.size() - 1; ++i) { - if (pt > vKaonTPCPIDpTintv[i] && pt < vKaonTPCPIDpTintv[i + 1]) { - if (std::abs(tpcNsigmaKa) < vKaonTPCPIDcuts[i]) { - tpcPIDPassed = true; - break; - } - } - } - - // TOF bypass option - if (configPID.cByPassTOF) { - return std::abs(tpcNsigmaKa) < vKaonTPCPIDcuts.back(); - } - - // Case 1: No TOF and pt ≤ ptSwitch → use TPC-only - if (!candidate.hasTOF() && pt <= ptSwitchToTOF) { - return tpcPIDPassed; - } - - // Case 2: No TOF but pt > ptSwitch → reject - if (!candidate.hasTOF() && pt > ptSwitchToTOF) { - return false; - } - - // Case 3: TOF is available → apply TPC+TOF PID logic - if (candidate.hasTOF()) { - if (configPID.cPIDcutType == SquareType) { - // Rectangular cut - for (size_t i = 0; i < vKaonTOFPIDpTintv.size(); ++i) { - if (pt < vKaonTOFPIDpTintv[i]) { - if (std::abs(tofNsigmaKa) < vKaonTOFPIDcuts[i] && - std::abs(tpcNsigmaKa) < vKaonTPCPIDcuts.back()) { - return true; - } - } - } - } else if (configPID.cPIDcutType == CircularType) { - // Circular cut - for (size_t i = 0; i < vKaonTPCTOFCombinedpTintv.size(); ++i) { - if (pt < vKaonTPCTOFCombinedpTintv[i]) { - float combinedSigma2 = tpcNsigmaKa * tpcNsigmaKa + - tofNsigmaKa * tofNsigmaKa; - if (combinedSigma2 < vKaonTPCTOFCombinedPIDcuts[i] * vKaonTPCTOFCombinedPIDcuts[i]) { - return true; - } - } - } - } - } - - return false; - } - - auto static constexpr MinPtforPionRejection = 1.0f; - auto static constexpr MaxPtforPionRejection = 2.0f; - auto static constexpr MaxnSigmaforPionRejection = 2.0f; - - template - bool rejectPion(const T& candidate) - { - if (candidate.pt() > MinPtforPionRejection && candidate.pt() < MaxPtforPionRejection && !candidate.hasTOF() && candidate.tpcNSigmaPi() < MaxnSigmaforPionRejection) { - return false; - } - return true; - } - - auto static constexpr MaxNoLambda1520Daughters = 2; - - template - void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksType& dTracks2) - { - auto centrality = centEst(collision); - - // Multiplicity correlation calibration plots - if (cFillMultQA) { - if constexpr (IsData) { - histos.fill(HIST("MultCalib/centGloPVpr"), centrality, dTracks1.size(), collision.multNTracksPV()); - histos.fill(HIST("MultCalib/centGloPVka"), centrality, dTracks2.size(), collision.multNTracksPV()); - } - } - - if (cFilladditionalQAeventPlots) { - if constexpr (IsData) { - histos.fill(HIST("QAevent/hnTrksSameE"), dTracks1.size()); - } else if constexpr (IsMix) { - histos.fill(HIST("QAevent/hVertexZMixedE"), collision.posZ()); - histos.fill(HIST("QAevent/hMultiplicityPercentMixedE"), centrality); - histos.fill(HIST("QAevent/hnTrksMixedE"), dTracks1.size()); - } - } - // LOG(info) << "After pass, Collision index:" << collision.index() << "multiplicity: " << collision.centFT0M() << endl; - - LorentzVectorPtEtaPhiMass lDecayDaughter1, lDecayDaughter2, lResonance, ldaughterRot, lResonanceRot; - - for (const auto& [trk1, trk2] : combinations(CombinationsFullIndexPolicy(dTracks1, dTracks2))) { - // Full index policy is needed to consider all possible combinations - if (trk1.index() == trk2.index()) - continue; // We need to run (0,1), (1,0) pairs as well. but same id pairs are not needed. - - // apply the track cut - if (!trackCut(trk1) || !trackCut(trk2)) - continue; - - //// Initialize variables - // Trk1: Proton - auto isTrk1hasTOF = trk1.hasTOF(); - auto trk1ptPr = trk1.pt(); - auto trk1etaPr = trk1.eta(); - auto trk1phiPr = trk1.phi(); - auto trk1NSigmaPrTPC = trk1.tpcNSigmaPr(); - auto trk1NSigmaPrTOF = (isTrk1hasTOF) ? trk1.tofNSigmaPr() : -999.0f; - - // Trk2: Kaon - auto isTrk2hasTOF = trk2.hasTOF(); - auto trk2ptKa = trk2.pt(); - auto trk2etaKa = trk2.eta(); - auto trk2phiKa = trk2.phi(); - auto trk2NSigmaKaTPC = trk2.tpcNSigmaKa(); - auto trk2NSigmaKaTOF = (isTrk2hasTOF) ? trk2.tofNSigmaKa() : -999.0f; - - auto deltaEta = 0.0f; - auto deltaPhi = 0.0f; - - if (cfgUseDeltaEtaPhiCuts) { - deltaEta = std::abs(trk1etaPr - trk2etaKa); - deltaPhi = std::abs(trk1phiPr - trk2phiKa); - deltaPhi = (deltaPhi > o2::constants::math::PI) ? (o2::constants::math::TwoPI - deltaPhi) : deltaPhi; - if (deltaEta >= cMaxDeltaEtaCut) - continue; - if (deltaPhi >= cMaxDeltaPhiCut) - continue; - } - - //// QA plots before the selection - // --- Track QA all - if constexpr (IsData) { - if (cFillTrackQA) { - histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); - if (isTrk1hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); - histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); - } - if (!isTrk1hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_pr"), trk1ptPr, trk1NSigmaPrTPC); - } - histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); - if (isTrk2hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); - histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); - } - if (!isTrk2hasTOF) { - histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_ka"), trk2ptKa, trk2NSigmaKaTPC); - } - - histos.fill(HIST("QA/QAbefore/Track/dcaZ"), trk1ptPr, trk1.dcaZ()); - histos.fill(HIST("QA/QAbefore/Track/dcaXY"), trk1ptPr, trk1.dcaXY()); - histos.fill(HIST("QA/QAbefore/Track/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); - histos.fill(HIST("QA/QAbefore/Track/pT"), trk1ptPr); - histos.fill(HIST("QA/QAbefore/Track/eta"), trk1etaPr); - } - if (cFilldeltaEtaPhiPlots) { - histos.fill(HIST("QAbefore/deltaEta"), deltaEta); - histos.fill(HIST("QAbefore/deltaPhi"), deltaPhi); - } - } - - //// Apply the pid selection - if (crejectPion && rejectPion(trk2)) // to remove pion contamination from the kaon track - continue; - - if (!ptDependentPidProton(trk1) || !ptDependentPidKaon(trk2)) - continue; - - //// QA plots after the selection - if constexpr (IsData) { // --- PID QA Proton - histos.fill(HIST("QA/QAafter/Proton/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); - histos.fill(HIST("QA/QAafter/Proton/TPC_Signal_pr_all"), trk1.tpcInnerParam(), trk1.tpcSignal()); - if (isTrk1hasTOF) { - histos.fill(HIST("QA/QAafter/Proton/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); - histos.fill(HIST("QA/QAafter/Proton/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); - } - if (!isTrk1hasTOF) { - histos.fill(HIST("QA/QAafter/Proton/TPC_Nsigma_pr_TPConly"), trk1ptPr, trk1NSigmaPrTPC); - } - histos.fill(HIST("QA/QAafter/Proton/dcaZ"), trk1ptPr, trk1.dcaZ()); - histos.fill(HIST("QA/QAafter/Proton/dcaXY"), trk1ptPr, trk1.dcaXY()); - histos.fill(HIST("QA/QAafter/Proton/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); - histos.fill(HIST("QA/QAafter/Proton/pT"), trk1ptPr); - histos.fill(HIST("QA/QAafter/Proton/eta"), trk1etaPr); - histos.fill(HIST("QA/QAafter/Proton/TPCnclusterPhipr"), trk1.tpcNClsFound(), trk1phiPr); - - // --- PID QA Kaon - histos.fill(HIST("QA/QAafter/Kaon/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); - histos.fill(HIST("QA/QAafter/Kaon/TPC_Signal_ka_all"), trk2.tpcInnerParam(), trk2.tpcSignal()); - if (isTrk2hasTOF) { - histos.fill(HIST("QA/QAafter/Kaon/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); - histos.fill(HIST("QA/QAafter/Kaon/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); - } - if (!isTrk2hasTOF) { - histos.fill(HIST("QA/QAafter/Kaon/TPC_Nsigma_ka_TPConly"), trk2ptKa, trk2NSigmaKaTPC); - } - histos.fill(HIST("QA/QAafter/Kaon/dcaZ"), trk2ptKa, trk2.dcaZ()); - histos.fill(HIST("QA/QAafter/Kaon/dcaXY"), trk2ptKa, trk2.dcaXY()); - histos.fill(HIST("QA/QAafter/Kaon/TPC_CR"), trk2ptKa, trk2.tpcNClsCrossedRows()); - histos.fill(HIST("QA/QAafter/Kaon/pT"), trk2ptKa); - histos.fill(HIST("QA/QAafter/Kaon/eta"), trk2etaKa); - histos.fill(HIST("QA/QAafter/Kaon/TPCnclusterPhika"), trk2.tpcNClsFound(), trk2phiKa); - - if (cFilldeltaEtaPhiPlots) { - histos.fill(HIST("QAafter/PhiPrafter"), trk1phiPr); - histos.fill(HIST("QAafter/PhiKaafter"), trk2phiKa); - histos.fill(HIST("QAafter/deltaEta"), deltaEta); - histos.fill(HIST("QAafter/deltaPhi"), deltaPhi); - } - } - - //// Resonance reconstruction - lDecayDaughter1 = LorentzVectorPtEtaPhiMass(trk1ptPr, trk1etaPr, trk1phiPr, massPr); - lDecayDaughter2 = LorentzVectorPtEtaPhiMass(trk2ptKa, trk2etaKa, trk2phiKa, massKa); - - // Apply kinematic opening angle cut - if (cUseOpeningAngleCut) { - auto v1 = lDecayDaughter1.Vect(); - auto v2 = lDecayDaughter2.Vect(); - float alpha = std::acos(v1.Dot(v2) / (v1.R() * v2.R())); - if (alpha > cMinOpeningAngle && alpha < cMaxOpeningAngle) - continue; - } - - lResonance = lDecayDaughter1 + lDecayDaughter2; - - auto resonanceMass = lResonance.M(); - auto resonancePt = lResonance.Pt(); - auto resonanceRapidity = lResonance.Rapidity(); - - if constexpr (IsData || IsMix) { - // Rapidity cut - if (std::abs(resonanceRapidity) > configTracks.cfgCutRapidity) - continue; - } - - if (cfgUseCutsOnMother) { - if (resonancePt >= cMaxPtMotherCut) // excluding candidates in overflow - continue; - if (resonanceMass >= cMaxMinvMotherCut) // excluding candidates in overflow - continue; - } - - if (cFilladditionalQAeventPlots) { - if constexpr (IsData) { - histos.fill(HIST("QAevent/hPairsCounterSameE"), 1.0f); - } else if (IsMix) { - histos.fill(HIST("QAevent/hPairsCounterMixedE"), 1.0f); - } - } - - //// Un-like sign pair only - if (trk1.sign() * trk2.sign() < 0) { - if constexpr (IsRot) { - for (int i = 0; i < configBkg.cNofRotations; i++) { - float theta = rn->Uniform(o2::constants::math::PI - o2::constants::math::PI / configBkg.rotationalcut, o2::constants::math::PI + o2::constants::math::PI / configBkg.rotationalcut); - if (configBkg.cfgRotPr) { - ldaughterRot = LorentzVectorPtEtaPhiMass(trk1ptPr, trk1etaPr, trk1phiPr + theta, massPr); - lResonanceRot = ldaughterRot + lDecayDaughter2; - } else { - ldaughterRot = LorentzVectorPtEtaPhiMass(trk2ptKa, trk2etaKa, trk2phiKa + theta, massKa); - lResonanceRot = lDecayDaughter1 + ldaughterRot; - } - auto resonanceRotMass = lResonanceRot.M(); - auto resonanceRotPt = lResonanceRot.Pt(); - - // Rapidity cut - if (std::abs(lResonanceRot.Rapidity()) >= configTracks.cfgCutRapidity) - continue; - - if (cfgUseCutsOnMother) { - if (resonanceRotPt >= cMaxPtMotherCut) // excluding candidates in overflow - continue; - if (resonanceRotMass >= cMaxMinvMotherCut) // excluding candidates in overflow - continue; - } - if (trk1.sign() < 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/lambda1520InvMassRotation"), resonanceRotMass); - } - histos.fill(HIST("Result/Data/h3lambda1520InvMassRotation"), centrality, resonanceRotPt, resonanceRotMass); - } else if (trk1.sign() > 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/antilambda1520InvMassRotation"), resonanceRotMass); - } - histos.fill(HIST("Result/Data/h3antilambda1520InvMassRotation"), centrality, resonanceRotPt, resonanceRotMass); - } - } - } - if constexpr (IsData) { - if (trk1.sign() < 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/lambda1520invmass"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3lambda1520invmass"), centrality, resonancePt, resonanceMass); - } else if (trk1.sign() > 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/antilambda1520invmass"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3antilambda1520invmass"), centrality, resonancePt, resonanceMass); - } - } else if (IsMix) { - if (trk1.sign() < 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/lambda1520invmassME_UnlikeSign"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3lambda1520invmassME_UnlikeSign"), centrality, resonancePt, resonanceMass); - } else if (trk1.sign() > 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/antilambda1520invmassME_UnlikeSign"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3antilambda1520invmassME_UnlikeSign"), centrality, resonancePt, resonanceMass); - } - } - - // MC - if constexpr (IsMC) { - // now we do mc true - // ------ Temporal lambda function to prevent error in build - auto getMothersIndeces = [&](auto const& theMcParticle) { - std::vector lMothersIndeces{}; - for (auto const& lMother : theMcParticle.template mothers_as()) { - LOGF(debug, " mother index lMother: %d", lMother.globalIndex()); - lMothersIndeces.push_back(lMother.globalIndex()); - } - return lMothersIndeces; - }; - auto getMothersPDGCodes = [&](auto const& theMcParticle) { - std::vector lMothersPDGs{}; - for (auto const& lMother : theMcParticle.template mothers_as()) { - LOGF(debug, " mother pdgcode lMother: %d", lMother.pdgCode()); - lMothersPDGs.push_back(lMother.pdgCode()); - } - return lMothersPDGs; - }; - // ------ - std::vector motherstrk1 = {-1, -1}; - std::vector mothersPDGtrk1 = {-1, -1}; - - std::vector motherstrk2 = {-1, -1}; - std::vector mothersPDGtrk2 = {-1, -1}; - - // - // Get the MC particle - const auto& mctrk1 = trk1.mcParticle(); - if (mctrk1.has_mothers()) { - motherstrk1 = getMothersIndeces(mctrk1); - mothersPDGtrk1 = getMothersPDGCodes(mctrk1); - } - while (motherstrk1.size() > MaxNoLambda1520Daughters) { - motherstrk1.pop_back(); - mothersPDGtrk1.pop_back(); - } - - const auto& mctrk2 = trk2.mcParticle(); - if (mctrk2.has_mothers()) { - motherstrk2 = getMothersIndeces(mctrk2); - mothersPDGtrk2 = getMothersPDGCodes(mctrk2); - } - while (motherstrk2.size() > MaxNoLambda1520Daughters) { - motherstrk2.pop_back(); - mothersPDGtrk2.pop_back(); - } - - if (std::abs(mctrk1.pdgCode()) != kProton || std::abs(mctrk2.pdgCode()) != kKPlus) - continue; - - if (motherstrk1[0] != motherstrk2[0]) // Same mother - continue; - - if (std::abs(mothersPDGtrk1[0]) != Pdg::kLambda1520_Py) - continue; - - // LOGF(info, "mother trk1 id: %d, mother trk1: %d, trk1 id: %d, trk1 pdgcode: %d, mother trk2 id: %d, mother trk2: %d, trk2 id: %d, trk2 pdgcode: %d", motherstrk1[0], mothersPDGtrk1[0], trk1.globalIndex(), mctrk1.pdgCode(), motherstrk2[0], mothersPDGtrk2[0], trk2.globalIndex(), mctrk2.pdgCode()); - - if (cUseEtacutMC && std::abs(lResonance.Eta()) > cEtacutMC) // eta cut - continue; - - if (cUseRapcutMC && std::abs(resonanceRapidity) > configTracks.cfgCutRapidity) // rapidity cut - continue; - - histos.fill(HIST("QA/MC/h2RecoEtaPt_after"), lResonance.Eta(), resonancePt); - histos.fill(HIST("QA/MC/h2RecoPhiRapidity_after"), lResonance.Phi(), resonanceRapidity); - - // Track selection check. - histos.fill(HIST("QA/MC/trkDCAxy_pr"), trk1ptPr, trk1.dcaXY()); - histos.fill(HIST("QA/MC/trkDCAxy_ka"), trk2ptKa, trk2.dcaXY()); - histos.fill(HIST("QA/MC/trkDCAz_pr"), trk1ptPr, trk1.dcaZ()); - histos.fill(HIST("QA/MC/trkDCAz_ka"), trk2ptKa, trk2.dcaZ()); - - histos.fill(HIST("QA/MC/TPC_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTPC); - if (isTrk1hasTOF) { - histos.fill(HIST("QA/MC/TOF_Nsigma_pr_all"), centrality, trk1ptPr, trk1NSigmaPrTOF); - } - histos.fill(HIST("QA/MC/TPC_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTPC); - if (isTrk2hasTOF) { - histos.fill(HIST("QA/MC/TOF_Nsigma_ka_all"), centrality, trk2ptKa, trk2NSigmaKaTOF); - } - - // MC histograms - if (mothersPDGtrk1[0] > 0) { - histos.fill(HIST("Result/MC/h3lambda1520Recoinvmass"), centrality, resonancePt, resonanceMass); - } else { - histos.fill(HIST("Result/MC/h3antilambda1520Recoinvmass"), centrality, resonancePt, resonanceMass); - } - } - } else { - if constexpr (IsData) { - // Like sign pair ++ - if (trk1.sign() > 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/lambda1520invmassLSPP"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3lambda1520invmassLSPP"), centrality, resonancePt, resonanceMass); - } else { // Like sign pair -- - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/lambda1520invmassLSMM"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3lambda1520invmassLSMM"), centrality, resonancePt, resonanceMass); - } - } else if (IsMix) { - if (cFilladditionalMEPlots) { - // Like sign pair ++ - if (trk1.sign() > 0) { - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/lambda1520invmassME_LSPP"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3lambda1520invmassME_LSPP"), centrality, resonancePt, resonanceMass); - } else { // Like sign pair -- - if (cFill1DQAs) { - histos.fill(HIST("Result/Data/lambda1520invmassME_LSMM"), resonanceMass); - } - histos.fill(HIST("Result/Data/h3lambda1520invmassME_LSMM"), centrality, resonancePt, resonanceMass); - } - } - } - } - } - } - - void processData(EventCandidates::iterator const& collision, - TrackCandidates const& tracks) - { - if (!isSelected(collision)) // Default event selection - return; - - auto centrality = centEst(collision); - - histos.fill(HIST("Event/posZ"), collision.posZ()); - histos.fill(HIST("Event/centFT0M"), centrality); - - fillHistograms(collision, tracks, tracks); - } - PROCESS_SWITCH(Lambda1520analysisinpp, processData, "Process Event for data without partition", false); - - void processRotational(EventCandidates::iterator const& collision, TrackCandidates const& tracks) - { - if (!isSelected(collision, false)) // Default event selection - return; - - if (!collision.isInelGt0()) // <-- - return; - - fillHistograms(collision, tracks, tracks); - } - PROCESS_SWITCH(Lambda1520analysisinpp, processRotational, "Process Rotational Background", false); - - void processMCRec(MCEventCandidates::iterator const& collision, - aod::McCollisions const&, - MCTrackCandidates const& tracks, aod::McParticles const&) - { - if (!isSelected(collision)) - return; - - auto centrality = centEst(collision); - - histos.fill(HIST("Event/posZ"), collision.posZ()); - histos.fill(HIST("Event/centFT0M"), centrality); - - fillHistograms(collision, tracks, tracks); - } - PROCESS_SWITCH(Lambda1520analysisinpp, processMCRec, "Process Event for MC Rec without partition", false); - - Partition selectedMCParticles = (nabs(aod::mcparticle::pdgCode) == static_cast(Pdg::kLambda1520_Py)); // Lambda(1520) - - void processMCGen(MCEventCandidates::iterator const& collision, aod::McCollisions const&, aod::McParticles const& mcParticles) - { - bool isInAfterAllCuts = isSelected(collision, false); - bool inVtx10 = (std::abs(collision.mcCollision().posZ()) > configEvents.cfgEvtZvtx) ? false : true; - bool isTriggerTVX = collision.selection_bit(aod::evsel::kIsTriggerTVX); - bool isSel8 = collision.sel8(); - - auto mcPartsAll = mcParticles.sliceBy(perMcCollision, collision.mcCollision().globalIndex()); - - bool isTrueINELgt0 = pwglf::isINELgt0mc(mcPartsAll, pdg); - // bool isTrueINELgt0 = collision.isInelGt0(); - - auto centrality = centEst(collision); - - auto mcParts = selectedMCParticles->sliceBy(perMcCollision, collision.mcCollision().globalIndex()); - - // Not related to the real collisions - for (const auto& part : mcParts) { // loop over all MC particles - - std::vector daughterPDGs; - if (part.has_daughters()) { - auto daughter01 = mcParticles.rawIteratorAt(part.daughtersIds()[0] - mcParticles.offset()); - auto daughter02 = mcParticles.rawIteratorAt(part.daughtersIds()[1] - mcParticles.offset()); - daughterPDGs = {daughter01.pdgCode(), daughter02.pdgCode()}; - } else { - daughterPDGs = {-1, -1}; - } - - bool pass1 = std::abs(daughterPDGs[0]) == kKPlus || std::abs(daughterPDGs[1]) == kKPlus; // At least one decay to Kaon - bool pass2 = std::abs(daughterPDGs[0]) == kProton || std::abs(daughterPDGs[1]) == kProton; // At least one decay to Proton - - // Checking if we have both decay products - if (!pass1 || !pass2) - continue; - - // LOGF(info, "Part PDG: %d", part.pdgCode(), "DAU_ID1: %d", pass1, "DAU_ID2: %d", pass2); - - histos.fill(HIST("QA/MC/h2GenEtaPt_beforeanycut"), part.eta(), part.pt()); - histos.fill(HIST("QA/MC/h2GenPhiRapidity_beforeanycut"), part.phi(), part.y()); - - if (cUseRapcutMC && std::abs(part.y()) > configTracks.cfgCutRapidity) // rapidity cut - continue; - - if (cfgUseDaughterEtaCutMC) { - for (auto const& daughters : part.daughters_as()) { - if (std::fabs(daughters.eta()) > configTracks.cfgCutEta) - continue; // eta cut for daughters - } // loop over daughters - } - - histos.fill(HIST("QA/MC/h2GenEtaPt_afterRapcut"), part.eta(), part.pt()); - histos.fill(HIST("QA/MC/h2GenPhiRapidity_afterRapcut"), part.phi(), part.y()); - - if (cUseEtacutMC && std::abs(part.eta()) > cEtacutMC) // eta cut - continue; - - histos.fill(HIST("QA/MC/h2GenEtaPt_afterEtaRapCut"), part.eta(), part.pt()); - histos.fill(HIST("QA/MC/h2GenPhiRapidity_afterEtaRapCut"), part.phi(), part.y()); - - histos.fill(HIST("QA/Gen"), 1); - if (part.pdgCode() > 0) // without any event selection - histos.fill(HIST("Result/MC/Genlambda1520pt"), 0, part.pt(), centrality); - else - histos.fill(HIST("Result/MC/Genantilambda1520pt"), 0, part.pt(), centrality); - - if (inVtx10) // vtx10 - { - histos.fill(HIST("QA/Gen"), 2); - if (part.pdgCode() > 0) - histos.fill(HIST("Result/MC/Genlambda1520pt"), 1, part.pt(), centrality); - else - histos.fill(HIST("Result/MC/Genantilambda1520pt"), 1, part.pt(), centrality); - } - if (inVtx10 && isSel8) // vtx10, sel8 - { - histos.fill(HIST("QA/Gen"), 3); - if (part.pdgCode() > 0) - histos.fill(HIST("Result/MC/Genlambda1520pt"), 2, part.pt(), centrality); - else - histos.fill(HIST("Result/MC/Genantilambda1520pt"), 2, part.pt(), centrality); - } - if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX - { - histos.fill(HIST("QA/Gen"), 4); - if (part.pdgCode() > 0) - histos.fill(HIST("Result/MC/Genlambda1520pt"), 3, part.pt(), centrality); - else - histos.fill(HIST("Result/MC/Genantilambda1520pt"), 3, part.pt(), centrality); - } - if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 - { - histos.fill(HIST("QA/Gen"), 5); - if (part.pdgCode() > 0) - histos.fill(HIST("Result/MC/Genlambda1520pt"), 4, part.pt(), centrality); - else - histos.fill(HIST("Result/MC/Genantilambda1520pt"), 4, part.pt(), centrality); - } - if (isInAfterAllCuts) // after all event selection - { - histos.fill(HIST("QA/Gen"), 6); - if (part.pdgCode() > 0) - histos.fill(HIST("Result/MC/Genlambda1520pt"), 5, part.pt(), centrality); - else - histos.fill(HIST("Result/MC/Genantilambda1520pt"), 5, part.pt(), centrality); - } - if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 - { - histos.fill(HIST("QA/Gen"), 7); - if (part.pdgCode() > 0) - histos.fill(HIST("Result/MC/Genlambda1520pt"), 6, part.pt(), centrality); - else - histos.fill(HIST("Result/MC/Genantilambda1520pt"), 6, part.pt(), centrality); - } - } - - // QA for Trigger efficiency - histos.fill(HIST("Event/hMCEventIndices"), centrality, Inel); - if (inVtx10) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Inel10); - if (isTrueINELgt0) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Inelg0); - if (inVtx10 && isTrueINELgt0) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Inelg010); - - // TVX MB trigger - if (isTriggerTVX) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Trig); - if (isTriggerTVX && inVtx10) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Trig10); - if (isTriggerTVX && isTrueINELgt0) - histos.fill(HIST("Event/hMCEventIndices"), centrality, TrigINELg0); - if (isTriggerTVX && isTrueINELgt0 && inVtx10) - histos.fill(HIST("Event/hMCEventIndices"), centrality, TrigINELg010); - - // Sel8 event selection - if (isSel8) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Sel8); - if (isSel8 && inVtx10) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Sel810); - if (isSel8 && isTrueINELgt0) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Sel8INELg0); - if (isSel8 && isTrueINELgt0 && inVtx10) - histos.fill(HIST("Event/hMCEventIndices"), centrality, Sel8INELg010); - - // CollisionCuts selection - if (isInAfterAllCuts) - histos.fill(HIST("Event/hMCEventIndices"), centrality, AllCuts); - if (isInAfterAllCuts && inVtx10) - histos.fill(HIST("Event/hMCEventIndices"), centrality, AllCuts10); - if (isInAfterAllCuts && isTrueINELgt0) - histos.fill(HIST("Event/hMCEventIndices"), centrality, AllCutsINELg0); - if (isInAfterAllCuts && isTrueINELgt0 && inVtx10) - histos.fill(HIST("Event/hMCEventIndices"), centrality, AllCutsINELg010); - } - PROCESS_SWITCH(Lambda1520analysisinpp, processMCGen, "Process Event for MC only", false); - - // Processing Event Mixing - using BinningTypeVtxZT0M = ColumnBinningPolicy; - - void processME(EventCandidates const& collision, - TrackCandidates const& tracks) - { - auto tracksTuple = std::make_tuple(tracks); - - BinningTypeVtxZT0M colBinning{{configBkg.cfgVtxBins, configBkg.cfgMultPercentileBins}, true}; - SameKindPair pairs{colBinning, configBkg.nEvtMixing, -1, collision, tracksTuple, &cache}; // -1 is the number of the bin to skip - - for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { - // LOGF(info, "Mixed event collisions: (%d, %d)", collision1.globalIndex(), collision2.globalIndex()); - - // for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { - // LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d)", t1.index(), t2.index(), collision1.index(), collision2.index()); - // } - - if (!isSelected(collision1, false)) // Default event selection - continue; - - if (!isSelected(collision2, false)) // Default event selection - continue; - - if (!collision1.isInelGt0()) // <-- - continue; - - if (!collision2.isInelGt0()) // <-- - continue; - - if (cFilladditionalQAeventPlots) { - // Fill histograms for the characteristics of the *mixed* events (collision1 and collision2) - // This will show the distribution of events that are actually being mixed. - if (cFill1DQAs) { - histos.fill(HIST("QAevent/hMixPool_VtxZ"), collision1.posZ()); - histos.fill(HIST("QAevent/hMixPool_Multiplicity"), collision1.centFT0M()); - } - histos.fill(HIST("QAevent/hMixPool_VtxZ_vs_Multiplicity"), collision1.posZ(), collision1.centFT0M()); - - // You might also want to fill for collision2 if you want to see both partners' distributions - // histos.fill(HIST("QAevent/hMixPool_VtxZ"), collision2.posZ()); - // histos.fill(HIST("QAevent/hMixPool_Multiplicity"), collision2.centFT0M()); - // histos.fill(HIST("QAevent/hMixPool_VtxZ_vs_Multiplicity"), collision2.posZ(), collision2.centFT0M()); - } - fillHistograms(collision1, tracks1, tracks2); - } - } - PROCESS_SWITCH(Lambda1520analysisinpp, processME, "Process EventMixing light without partition", false); - - void processSignalLoss(MCEventCandidates::iterator const& collision, aod::McCollisions const&, aod::McParticles const& mcParticles) - { - bool isInAfterAllCuts = isSelected(collision, false); - bool inVtx10 = (std::abs(collision.mcCollision().posZ()) > configEvents.cfgEvtZvtx) ? false : true; - bool isTriggerTVX = collision.selection_bit(aod::evsel::kIsTriggerTVX); - bool isSel8 = collision.sel8(); - - auto mcPartsAll = mcParticles.sliceBy(perMcCollision, collision.mcCollision().globalIndex()); - - bool isTrueINELgt0 = pwglf::isINELgt0mc(mcPartsAll, pdg); - // bool isTrueINELgt0 = collision.isInelGt0(); - - auto centrality = centEst(collision); - - auto computePtL = [&](float pt, float m_ref) { - float ptL2 = pt * pt + m_ref * m_ref - MassLambda1520 * MassLambda1520; - return (ptL2 > 0) ? std::sqrt(ptL2) : -1.f; - }; - - for (const auto& part : mcPartsAll) { - - if (!part.isPhysicalPrimary()) - continue; - - float pt = part.pt(); - - float weight; - - if (cUseRapcutMC && std::abs(part.y()) > configTracks.cfgCutRapidity) // rapidity cut - continue; - - if (std::abs(part.pdgCode()) == kProton) { - - // true proton - histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt"), 0, pt, centrality); - - if (inVtx10) // vtx10 - histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt"), 1, pt, centrality); - - if (inVtx10 && isSel8) // vtx10, sel8 - histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt"), 2, pt, centrality); - - if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX - histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt"), 3, pt, centrality); - - if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 - histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt"), 4, pt, centrality); - - if (isInAfterAllCuts) // after all event selection - histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt"), 5, pt, centrality); - - if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 - histos.fill(HIST("Result/SignalLoss/GenTrueprotonpt"), 6, pt, centrality); - - float ptL = computePtL(pt, massPr); - if (ptL < 0) - continue; - - if (useWeight) - weight = ptL / pt; - else - weight = 1.f; - - histos.fill(HIST("Result/SignalLoss/Genprotonpt"), 0, ptL, centrality, weight); - - if (inVtx10) // vtx10 - histos.fill(HIST("Result/SignalLoss/Genprotonpt"), 1, ptL, centrality, weight); - - if (inVtx10 && isSel8) // vtx10, sel8 - histos.fill(HIST("Result/SignalLoss/Genprotonpt"), 2, ptL, centrality, weight); - - if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX - histos.fill(HIST("Result/SignalLoss/Genprotonpt"), 3, ptL, centrality, weight); - - if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 - histos.fill(HIST("Result/SignalLoss/Genprotonpt"), 4, ptL, centrality, weight); - - if (isInAfterAllCuts) // after all event selection - histos.fill(HIST("Result/SignalLoss/Genprotonpt"), 5, ptL, centrality, weight); - - if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 - histos.fill(HIST("Result/SignalLoss/Genprotonpt"), 6, ptL, centrality, weight); - } - - if (std::abs(part.pdgCode()) == kLambda0) { - - // true lambda - histos.fill(HIST("Result/SignalLoss/GenTruelambdapt"), 0, pt, centrality); - - if (inVtx10) // vtx10 - histos.fill(HIST("Result/SignalLoss/GenTruelambdapt"), 1, pt, centrality); - - if (inVtx10 && isSel8) // vtx10, sel8 - histos.fill(HIST("Result/SignalLoss/GenTruelambdapt"), 2, pt, centrality); - - if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX - histos.fill(HIST("Result/SignalLoss/GenTruelambdapt"), 3, pt, centrality); - - if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 - histos.fill(HIST("Result/SignalLoss/GenTruelambdapt"), 4, pt, centrality); - - if (isInAfterAllCuts) // after all event selection - histos.fill(HIST("Result/SignalLoss/GenTruelambdapt"), 5, pt, centrality); - - if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 - histos.fill(HIST("Result/SignalLoss/GenTruelambdapt"), 6, pt, centrality); - - float ptL = computePtL(pt, MassLambda0); - if (ptL < 0) - continue; - - if (useWeight) - weight = ptL / pt; - else - weight = 1.f; - - histos.fill(HIST("Result/SignalLoss/Genlambdapt"), 0, ptL, centrality, weight); - - if (inVtx10) // vtx10 - histos.fill(HIST("Result/SignalLoss/Genlambdapt"), 1, ptL, centrality, weight); - - if (inVtx10 && isSel8) // vtx10, sel8 - histos.fill(HIST("Result/SignalLoss/Genlambdapt"), 2, ptL, centrality, weight); - - if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX - histos.fill(HIST("Result/SignalLoss/Genlambdapt"), 3, ptL, centrality, weight); - - if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 - histos.fill(HIST("Result/SignalLoss/Genlambdapt"), 4, ptL, centrality, weight); - - if (isInAfterAllCuts) // after all event selection - histos.fill(HIST("Result/SignalLoss/Genlambdapt"), 5, ptL, centrality, weight); - - if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 - histos.fill(HIST("Result/SignalLoss/Genlambdapt"), 6, ptL, centrality, weight); - } - - if (std::abs(part.pdgCode()) == PDG_t::kXiMinus) { - - // true Xi - histos.fill(HIST("Result/SignalLoss/GenTruexipt"), 0, pt, centrality); - - if (inVtx10) // vtx10 - histos.fill(HIST("Result/SignalLoss/GenTruexipt"), 1, pt, centrality); - - if (inVtx10 && isSel8) // vtx10, sel8 - histos.fill(HIST("Result/SignalLoss/GenTruexipt"), 2, pt, centrality); - - if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX - histos.fill(HIST("Result/SignalLoss/GenTruexipt"), 3, pt, centrality); - - if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 - histos.fill(HIST("Result/SignalLoss/GenTruexipt"), 4, pt, centrality); - - if (isInAfterAllCuts) // after all event selection - histos.fill(HIST("Result/SignalLoss/GenTruexipt"), 5, pt, centrality); - - if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 - histos.fill(HIST("Result/SignalLoss/GenTruexipt"), 6, pt, centrality); - - float ptL = computePtL(pt, MassXiMinus); - if (ptL < 0) - continue; - - if (useWeight) - weight = ptL / pt; - else - weight = 1.f; - - histos.fill(HIST("Result/SignalLoss/Genxipt"), 0, ptL, centrality, weight); - - if (inVtx10) // vtx10 - histos.fill(HIST("Result/SignalLoss/Genxipt"), 1, ptL, centrality, weight); - - if (inVtx10 && isSel8) // vtx10, sel8 - histos.fill(HIST("Result/SignalLoss/Genxipt"), 2, ptL, centrality, weight); - - if (inVtx10 && isTriggerTVX) // vtx10, TriggerTVX - histos.fill(HIST("Result/SignalLoss/Genxipt"), 3, ptL, centrality, weight); - - if (inVtx10 && isTrueINELgt0) // vtx10, INEL>0 - histos.fill(HIST("Result/SignalLoss/Genxipt"), 4, ptL, centrality, weight); - - if (isInAfterAllCuts) // after all event selection - histos.fill(HIST("Result/SignalLoss/Genxipt"), 5, ptL, centrality, weight); - - if (isInAfterAllCuts && isTrueINELgt0) // after all event selection && INEL>0 - histos.fill(HIST("Result/SignalLoss/Genxipt"), 6, ptL, centrality, weight); - } - } - } - PROCESS_SWITCH(Lambda1520analysisinpp, processSignalLoss, "Process SignalLoss", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} From 193a511d425944892bf282ad843d51aa0a83a2e0 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Tue, 14 Apr 2026 13:35:23 +0530 Subject: [PATCH 3/5] [PWGLF] Update true event and particles fills From a1e3316424ee2f53b8d0cb23f465f067f51ed717 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Tue, 14 Apr 2026 17:23:07 +0530 Subject: [PATCH 4/5] Refactor collision handling and cache usage --- .../Resonances/lambda1520analysisinpp.cxx | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx index 86675a501d0..0614be34ff3 100644 --- a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx @@ -66,10 +66,11 @@ enum PIDCutType { }; struct Lambda1520analysisinpp { - // Define slice per Resocollision - SliceCache cache; + // Define slice per collision Preslice perCollision = o2::aod::track::collisionId; + SliceCache cache; Preslice perMcCollision = o2::aod::mcparticle::mcCollisionId; + SliceCache cacheMC; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -391,6 +392,7 @@ struct Lambda1520analysisinpp { // MC QA histos.add("Event/hMCEventIndices", "hMCEventIndices", kTH2D, {axisMult, idxMCAxis}); + if (doprocessMCGen) { histos.add("QA/Gen", "Gen histogram", kTH1D, {{10, 0, 10, "index"}}); histos.add("QA/MC/h2GenEtaPt_beforeanycut", " #eta-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); @@ -1158,6 +1160,9 @@ struct Lambda1520analysisinpp { aod::McCollisions const&, MCTrackCandidates const& tracks, aod::McParticles const&) { + if (!collision.has_mcCollision()) + return; + if (!isSelected(collision)) return; @@ -1174,6 +1179,9 @@ struct Lambda1520analysisinpp { void processMCGen(MCEventCandidates::iterator const& collision, aod::McCollisions const&, aod::McParticles const& mcParticles) { + if (!collision.has_mcCollision()) + return; + bool isInAfterAllCuts = isSelected(collision, false); bool inVtx10 = (std::abs(collision.mcCollision().posZ()) > configEvents.cfgEvtZvtx) ? false : true; bool isTriggerTVX = collision.selection_bit(aod::evsel::kIsTriggerTVX); @@ -1298,9 +1306,6 @@ struct Lambda1520analysisinpp { if (!isInAfterAllCuts) return; - // if (!collision.has_mcCollision()) - // return; - for (const auto& part : mcPartsAll) { if (!part.isPhysicalPrimary()) @@ -1350,14 +1355,15 @@ struct Lambda1520analysisinpp { } PROCESS_SWITCH(Lambda1520analysisinpp, processMCGen, "Process Event for MC only", false); - void processEventFactor(soa::Join const& mcCollisions, aod::McParticles const& mcParticles) + void processEventFactor(MCEventCandidates const& collisions, soa::Join const& mcCollisions, aod::McParticles const& mcParticles) { + // Loop on generated collisions to fill the event factor for the INEL>0 correction for (const auto& mccolls : mcCollisions) { float centrality = mccolls.centFT0M(); bool inVtx10 = std::abs(mccolls.posZ()) <= configEvents.cfgEvtZvtx; - auto mcPartsThis = mcParticles.sliceBy(perMcCollision, mccolls.globalIndex()); - bool isTrueINELgt0 = pwglf::isINELgt0mc(mcPartsThis, pdg); // QA for Trigger efficiency + const auto& particlesInCollision = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolls.globalIndex(), cacheMC); + bool isTrueINELgt0 = pwglf::isINELgt0mc(particlesInCollision, pdg); // QA for Trigger efficiency histos.fill(HIST("Event/hMCEventIndices"), centrality, Inel); if (inVtx10) @@ -1377,8 +1383,8 @@ struct Lambda1520analysisinpp { bool inVtx10 = std::abs(mccolls.posZ()) <= configEvents.cfgEvtZvtx; - auto mcPartsThis = mcParticles.sliceBy(perMcCollision, mccolls.globalIndex()); - bool isTrueINELgt0 = pwglf::isINELgt0mc(mcPartsThis, pdg); + const auto& particlesInCollision = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolls.globalIndex(), cacheMC); + bool isTrueINELgt0 = pwglf::isINELgt0mc(particlesInCollision, pdg); if (!(inVtx10 && isTrueINELgt0)) continue; @@ -1388,10 +1394,7 @@ struct Lambda1520analysisinpp { return (ptL2 > 0) ? std::sqrt(ptL2) : -1.f; }; - for (const auto& part : mcPartsThis) { - - // if (!part.has_mcCollision()) - // continue; + for (const auto& part : particlesInCollision) { if (cUseRapcutMC && std::abs(part.y()) > configTracks.cfgCutRapidity) continue; From 51c6bd762708d42927ba89e5a0bf21d210040143 Mon Sep 17 00:00:00 2001 From: Hirak Koley Date: Tue, 14 Apr 2026 17:53:46 +0530 Subject: [PATCH 5/5] Remove unused parameter from processEventFactor --- PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx index 0614be34ff3..e9682bdde1a 100644 --- a/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520analysisinpp.cxx @@ -1355,7 +1355,7 @@ struct Lambda1520analysisinpp { } PROCESS_SWITCH(Lambda1520analysisinpp, processMCGen, "Process Event for MC only", false); - void processEventFactor(MCEventCandidates const& collisions, soa::Join const& mcCollisions, aod::McParticles const& mcParticles) + void processEventFactor(soa::Join const& mcCollisions, aod::McParticles const& mcParticles) { // Loop on generated collisions to fill the event factor for the INEL>0 correction for (const auto& mccolls : mcCollisions) {