From 57664e228422e0927454d6ec288dde11d1db40fa Mon Sep 17 00:00:00 2001 From: Yakiv <5348341@upjs.sk> Date: Thu, 9 Oct 2025 18:03:27 +0200 Subject: [PATCH 01/17] Task to study primary multistrange production in Run 3 --- PWGLF/Tasks/Strangeness/CMakeLists.txt | 5 + PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 171 +++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 PWGLF/Tasks/Strangeness/strangecasctrack.cxx diff --git a/PWGLF/Tasks/Strangeness/CMakeLists.txt b/PWGLF/Tasks/Strangeness/CMakeLists.txt index 3198993318b..fc8d93c36b4 100644 --- a/PWGLF/Tasks/Strangeness/CMakeLists.txt +++ b/PWGLF/Tasks/Strangeness/CMakeLists.txt @@ -170,3 +170,8 @@ o2physics_add_dpl_workflow(cascadeanalysislightions SOURCES cascadeAnalysisLightIonsDerivedData.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(strangecasctrack + SOURCES strangecasctrack.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::EventFilteringUtils + COMPONENT_NAME myo2) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx new file mode 100644 index 00000000000..1a0872ee824 --- /dev/null +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -0,0 +1,171 @@ +// 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 strangecasctrack.cxx +/// \brief Analysis of strangeness tracking efficiency via primary production of Omega and Xi in Run 3 +/// \author Yakiv Paroviak (yakiv.paroviak@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelection.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct StrangeCascTrack { + + using TraCascDatas = soa::Join; + using CascDatas = soa::Join; + + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable doProcessPP{"doprocesspp", true, "true for pp, false for PbPb and OO"}; + Configurable doProcessPbPb{"doprocesspbpb", false, "true for PbPb, false for pp and OO"}; + Configurable doProcessOO{"doprocessoo", false, "true for OO, false for pp and PbPb"}; + + Configurable doProcessMC{"domc", false, "true for MC, false for data"}; + + Configurable doRequireFT0{"doft0", false, "true for offline trigger for Run 3"}; + Configurable doApplyPID{"dopid", false, "true for offline trigger for Run 3"}; + Configurable doApplyCuts{"docuts", true, "true for offline trigger for Run 3"}; + + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisMult{"axisMult", {VARIABLE_WIDTH, 0.0f, 0.01f, 1.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}, "Multiplicity"}; + ConfigurableAxis axisOmegaMass{"axisOmegaMass", {2000, 1.6, 1.8}, "#Omega M_{inv} (GeV/c^{2})"}; + ConfigurableAxis axisXiMass{"axisXiMass", {2000, 1.2, 1.4}, "#Xi M_{inv} (GeV/c^{2})"}; + + Configurable CutDCAtoPVxy{"cutpvdcaxy", 0.02f, "max cascade dca to PV in xy"}; + Configurable CutDCAtoPVz{"cutpvdcaz", 0.02f, "max cascade dca to PV in z"}; + + + void init(InitContext const&) + { + histos.add("Events/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); + histos.add("Events/PVx", "PV x position", kTH1F, {{200, -0.1, 0.1}}); + histos.add("Events/PVy", "PV y position", kTH1F, {{200, -0.1, 0.1}}); + histos.add("Events/PVz", "PV z position", kTH1F, {{100, -20, 20}}); + histos.add("Events/Mult", "Multiplicity", kTH1F, {axisMult}); + + histos.add("Tracked/Phi", "Phi", kTH1F, {{100, 0., 2*M_PI}}); + histos.add("Tracked/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); + histos.add("Tracked/DCAxy", "DCA to xy", kTH1F, {{500, 0., 0.5}}); + histos.add("Tracked/DCAz", "DCA to z", kTH1F, {{500, 0., 0.5}}); + histos.add("Tracked/EvMult", "Multiplicity of events with >=1 cascade", kTH1F, {axisMult}); + histos.add("Tracked/MassOmega", "Invariant mass hypothesis",kTH1F, {axisOmegaMass}); + histos.add("Tracked/MassXi", "Invariant mass hypothesis", kTH1F, {axisXiMass}); + histos.add("Tracked/Omega", "",kTHnD, {axisOmegaMass, axisPt, axisMult}); + histos.add("Tracked/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); + + histos.add("All/Phi", "Phi", kTH1F, {{100, 0., 2*M_PI}}); + histos.add("All/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); + histos.add("All/DCAxy", "DCA to xy", kTH1F, {{1000, 0, 1.}}); + histos.add("All/DCAz", "DCA to z", kTH1F, {{1000, 0, 1.}}); + histos.add("All/EvMult", "Multiplicity of events with >=1 cascade", kTH1F, {axisMult}); + histos.add("All/MassOmega", "Invariant mass hypothesis",kTH1F, {axisOmegaMass}); + histos.add("All/MassXi", "Invariant mass hypothesis", kTH1F, {axisXiMass}); + histos.add("All/Omega", "", kTHnD, {axisOmegaMass, axisPt, axisMult}); + histos.add("All/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); + } + + +void processTracked(soa::Join::iterator const& collision, + aod::TraCascDatas const& tracascades) +{ + double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); + int64_t casccollid = 0; + for (auto const& cascade : tracascades) { + + double dcaxy = cascade.dcaXYCascToPV(); + double dcaz = cascade.dcaZCascToPV(); + if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) continue; // DCA check + + if (collision.index() != casccollid) { + histos.fill(HIST("Tracked/EvMult"), mult); // count and list mult of events with at least one cascade + casccollid = collision.index(); + } + + double pt = cascade.pt(); + double phi = cascade.phi(); + double eta = cascade.eta(); + double massXi = cascade.mXi(); + double massOmega = cascade.mOmega(); + + histos.fill(HIST("Tracked/DCAxy"), dcaxy); + histos.fill(HIST("Tracked/DCAz"), dcaz); + histos.fill(HIST("Tracked/Phi"), phi); + histos.fill(HIST("Tracked/Eta"), eta); + histos.fill(HIST("Tracked/MassXi"), massXi); + histos.fill(HIST("Tracked/MassOmega"), massOmega); + histos.fill(HIST("Tracked/Xi"), massXi, pt, mult); + histos.fill(HIST("Tracked/Omega"), massOmega, pt, mult); + + } +} + +void processAll(soa::Join::iterator const& collision, + aod::CascDatas const& cascades) +{ + histos.fill(HIST("Events/EvCounter"), 0.5); + double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); + histos.fill(HIST("Events/Mult"), mult); + double pvx = collision.posX(); + double pvy = collision.posY(); + double pvz = collision.posZ(); + histos.fill(HIST("Events/PVx"), pvx); + histos.fill(HIST("Events/PVy"), pvy); + histos.fill(HIST("Events/PVz"), pvz); + + int64_t casccollid = 0; + for (auto const& cascade : cascades) { + + double dcaxy = cascade.dcaXYCascToPV(); + double dcaz = cascade.dcaZCascToPV(); + if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) continue; // DCA check + + if (collision.index() != casccollid) { + histos.fill(HIST("All/EvMult"), mult); // count and list mult of events with at least one cascade + casccollid = collision.index(); + } + + double pt = cascade.pt(); + double phi = cascade.phi(); + double eta = cascade.eta(); + double massXi = cascade.mXi(); + double massOmega = cascade.mOmega(); + + histos.fill(HIST("All/DCAxy"), dcaxy); + histos.fill(HIST("All/DCAz"), dcaz); + histos.fill(HIST("All/Phi"), phi); + histos.fill(HIST("All/Eta"), eta); + histos.fill(HIST("All/MassXi"), massXi); + histos.fill(HIST("All/MassOmega"), massOmega); + histos.fill(HIST("All/Xi"), massXi, pt, mult); + histos.fill(HIST("All/Omega"), massOmega, pt, mult); + + } +} +PROCESS_SWITCH(StrangeCascTrack, processTracked, "process tracked cascades", true); +PROCESS_SWITCH(StrangeCascTrack, processAll, "process all cascades", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} From 027dfd5f7093878e90918636b403d2b589eb90f2 Mon Sep 17 00:00:00 2001 From: Yakiv <5348341@upjs.sk> Date: Thu, 9 Oct 2025 18:05:30 +0200 Subject: [PATCH 02/17] Task to study primary multistrange production in Run 3 --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 1a0872ee824..d17dc95cfda 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -18,7 +18,6 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelection.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "PWGLF/DataModel/LFStrangenessTables.h" From ffdda2c4c4818bd26b1cbf8d87f8e2ac46863841 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Thu, 9 Oct 2025 20:59:17 +0200 Subject: [PATCH 03/17] Formatting update --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 188 +++++++++---------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index d17dc95cfda..29234f4918d 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -13,14 +13,16 @@ /// \brief Analysis of strangeness tracking efficiency via primary production of Omega and Xi in Run 3 /// \author Yakiv Paroviak (yakiv.paroviak@cern.ch) -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" + #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" using namespace o2; using namespace o2::framework; @@ -33,24 +35,23 @@ struct StrangeCascTrack { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Configurable doProcessPP{"doprocesspp", true, "true for pp, false for PbPb and OO"}; - Configurable doProcessPbPb{"doprocesspbpb", false, "true for PbPb, false for pp and OO"}; - Configurable doProcessOO{"doprocessoo", false, "true for OO, false for pp and PbPb"}; + Configurable doProcessPP{"doProcessPP", true, "true for pp, false for PbPb and OO"}; + Configurable doProcessPbPb{"doProcessPbPb", false, "true for PbPb, false for pp and OO"}; + Configurable doProcessOO{"doProcessOO", false, "true for OO, false for pp and PbPb"}; - Configurable doProcessMC{"domc", false, "true for MC, false for data"}; + Configurable doProcessMC{"doProcessMC", false, "true for MC, false for data"}; - Configurable doRequireFT0{"doft0", false, "true for offline trigger for Run 3"}; - Configurable doApplyPID{"dopid", false, "true for offline trigger for Run 3"}; - Configurable doApplyCuts{"docuts", true, "true for offline trigger for Run 3"}; + Configurable doRequireFT0{"doRequireFT0", false, "true for offline trigger for Run 3"}; + Configurable doApplyPID{"doApplyPID", false, "true for offline trigger for Run 3"}; + Configurable doApplyCuts{"doApplyCuts", true, "true for offline trigger for Run 3"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "p_{T} (GeV/c)"}; ConfigurableAxis axisMult{"axisMult", {VARIABLE_WIDTH, 0.0f, 0.01f, 1.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}, "Multiplicity"}; ConfigurableAxis axisOmegaMass{"axisOmegaMass", {2000, 1.6, 1.8}, "#Omega M_{inv} (GeV/c^{2})"}; ConfigurableAxis axisXiMass{"axisXiMass", {2000, 1.2, 1.4}, "#Xi M_{inv} (GeV/c^{2})"}; - Configurable CutDCAtoPVxy{"cutpvdcaxy", 0.02f, "max cascade dca to PV in xy"}; - Configurable CutDCAtoPVz{"cutpvdcaz", 0.02f, "max cascade dca to PV in z"}; - + Configurable CutDCAtoPVxy{"CutDCAtoPVxy", 0.02f, "max cascade dca to PV in xy"}; + Configurable CutDCAtoPVz{"CutDCAtoPVz", 0.02f, "max cascade dca to PV in z"}; void init(InitContext const&) { @@ -60,106 +61,105 @@ struct StrangeCascTrack { histos.add("Events/PVz", "PV z position", kTH1F, {{100, -20, 20}}); histos.add("Events/Mult", "Multiplicity", kTH1F, {axisMult}); - histos.add("Tracked/Phi", "Phi", kTH1F, {{100, 0., 2*M_PI}}); + histos.add("Tracked/Phi", "Phi", kTH1F, {{100, 0., 2 * o2::constants::math::M_PI}}); histos.add("Tracked/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); histos.add("Tracked/DCAxy", "DCA to xy", kTH1F, {{500, 0., 0.5}}); histos.add("Tracked/DCAz", "DCA to z", kTH1F, {{500, 0., 0.5}}); histos.add("Tracked/EvMult", "Multiplicity of events with >=1 cascade", kTH1F, {axisMult}); - histos.add("Tracked/MassOmega", "Invariant mass hypothesis",kTH1F, {axisOmegaMass}); + histos.add("Tracked/MassOmega", "Invariant mass hypothesis", kTH1F, {axisOmegaMass}); histos.add("Tracked/MassXi", "Invariant mass hypothesis", kTH1F, {axisXiMass}); - histos.add("Tracked/Omega", "",kTHnD, {axisOmegaMass, axisPt, axisMult}); + histos.add("Tracked/Omega", "", kTHnD, {axisOmegaMass, axisPt, axisMult}); histos.add("Tracked/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); - histos.add("All/Phi", "Phi", kTH1F, {{100, 0., 2*M_PI}}); + histos.add("All/Phi", "Phi", kTH1F, {{100, 0., 2 * o2::constants::math::M_PI}}); histos.add("All/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); histos.add("All/DCAxy", "DCA to xy", kTH1F, {{1000, 0, 1.}}); histos.add("All/DCAz", "DCA to z", kTH1F, {{1000, 0, 1.}}); histos.add("All/EvMult", "Multiplicity of events with >=1 cascade", kTH1F, {axisMult}); - histos.add("All/MassOmega", "Invariant mass hypothesis",kTH1F, {axisOmegaMass}); + histos.add("All/MassOmega", "Invariant mass hypothesis", kTH1F, {axisOmegaMass}); histos.add("All/MassXi", "Invariant mass hypothesis", kTH1F, {axisXiMass}); histos.add("All/Omega", "", kTHnD, {axisOmegaMass, axisPt, axisMult}); - histos.add("All/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); + histos.add("All/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); } - -void processTracked(soa::Join::iterator const& collision, - aod::TraCascDatas const& tracascades) -{ - double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); - int64_t casccollid = 0; - for (auto const& cascade : tracascades) { - - double dcaxy = cascade.dcaXYCascToPV(); - double dcaz = cascade.dcaZCascToPV(); - if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) continue; // DCA check - - if (collision.index() != casccollid) { - histos.fill(HIST("Tracked/EvMult"), mult); // count and list mult of events with at least one cascade - casccollid = collision.index(); + void processTracked(soa::Join::iterator const& collision, + aod::TraCascDatas const& tracascades) + { + double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); + int64_t casccollid = 0; + for (auto const& cascade : tracascades) { + + double dcaxy = cascade.dcaXYCascToPV(); + double dcaz = cascade.dcaZCascToPV(); + if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) + continue; // DCA check + + if (collision.index() != casccollid) { + histos.fill(HIST("Tracked/EvMult"), mult); // count and list mult of events with at least one cascade + casccollid = collision.index(); + } + + double pt = cascade.pt(); + double phi = cascade.phi(); + double eta = cascade.eta(); + double massXi = cascade.mXi(); + double massOmega = cascade.mOmega(); + + histos.fill(HIST("Tracked/DCAxy"), dcaxy); + histos.fill(HIST("Tracked/DCAz"), dcaz); + histos.fill(HIST("Tracked/Phi"), phi); + histos.fill(HIST("Tracked/Eta"), eta); + histos.fill(HIST("Tracked/MassXi"), massXi); + histos.fill(HIST("Tracked/MassOmega"), massOmega); + histos.fill(HIST("Tracked/Xi"), massXi, pt, mult); + histos.fill(HIST("Tracked/Omega"), massOmega, pt, mult); } - - double pt = cascade.pt(); - double phi = cascade.phi(); - double eta = cascade.eta(); - double massXi = cascade.mXi(); - double massOmega = cascade.mOmega(); - - histos.fill(HIST("Tracked/DCAxy"), dcaxy); - histos.fill(HIST("Tracked/DCAz"), dcaz); - histos.fill(HIST("Tracked/Phi"), phi); - histos.fill(HIST("Tracked/Eta"), eta); - histos.fill(HIST("Tracked/MassXi"), massXi); - histos.fill(HIST("Tracked/MassOmega"), massOmega); - histos.fill(HIST("Tracked/Xi"), massXi, pt, mult); - histos.fill(HIST("Tracked/Omega"), massOmega, pt, mult); - } -} -void processAll(soa::Join::iterator const& collision, - aod::CascDatas const& cascades) -{ - histos.fill(HIST("Events/EvCounter"), 0.5); - double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); - histos.fill(HIST("Events/Mult"), mult); - double pvx = collision.posX(); - double pvy = collision.posY(); - double pvz = collision.posZ(); - histos.fill(HIST("Events/PVx"), pvx); - histos.fill(HIST("Events/PVy"), pvy); - histos.fill(HIST("Events/PVz"), pvz); - - int64_t casccollid = 0; - for (auto const& cascade : cascades) { - - double dcaxy = cascade.dcaXYCascToPV(); - double dcaz = cascade.dcaZCascToPV(); - if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) continue; // DCA check - - if (collision.index() != casccollid) { - histos.fill(HIST("All/EvMult"), mult); // count and list mult of events with at least one cascade - casccollid = collision.index(); + void processAll(soa::Join::iterator const& collision, + aod::CascDatas const& cascades) + { + histos.fill(HIST("Events/EvCounter"), 0.5); + double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); + histos.fill(HIST("Events/Mult"), mult); + double pvx = collision.posX(); + double pvy = collision.posY(); + double pvz = collision.posZ(); + histos.fill(HIST("Events/PVx"), pvx); + histos.fill(HIST("Events/PVy"), pvy); + histos.fill(HIST("Events/PVz"), pvz); + + int64_t casccollid = 0; + for (auto const& cascade : cascades) { + + double dcaxy = cascade.dcaXYCascToPV(); + double dcaz = cascade.dcaZCascToPV(); + if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) + continue; // DCA check + + if (collision.index() != casccollid) { + histos.fill(HIST("All/EvMult"), mult); // count and list mult of events with at least one cascade + casccollid = collision.index(); + } + + double pt = cascade.pt(); + double phi = cascade.phi(); + double eta = cascade.eta(); + double massXi = cascade.mXi(); + double massOmega = cascade.mOmega(); + + histos.fill(HIST("All/DCAxy"), dcaxy); + histos.fill(HIST("All/DCAz"), dcaz); + histos.fill(HIST("All/Phi"), phi); + histos.fill(HIST("All/Eta"), eta); + histos.fill(HIST("All/MassXi"), massXi); + histos.fill(HIST("All/MassOmega"), massOmega); + histos.fill(HIST("All/Xi"), massXi, pt, mult); + histos.fill(HIST("All/Omega"), massOmega, pt, mult); } - - double pt = cascade.pt(); - double phi = cascade.phi(); - double eta = cascade.eta(); - double massXi = cascade.mXi(); - double massOmega = cascade.mOmega(); - - histos.fill(HIST("All/DCAxy"), dcaxy); - histos.fill(HIST("All/DCAz"), dcaz); - histos.fill(HIST("All/Phi"), phi); - histos.fill(HIST("All/Eta"), eta); - histos.fill(HIST("All/MassXi"), massXi); - histos.fill(HIST("All/MassOmega"), massOmega); - histos.fill(HIST("All/Xi"), massXi, pt, mult); - histos.fill(HIST("All/Omega"), massOmega, pt, mult); - } -} -PROCESS_SWITCH(StrangeCascTrack, processTracked, "process tracked cascades", true); -PROCESS_SWITCH(StrangeCascTrack, processAll, "process all cascades", true); + PROCESS_SWITCH(StrangeCascTrack, processTracked, "process tracked cascades", true); + PROCESS_SWITCH(StrangeCascTrack, processAll, "process all cascades", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 437e7eaeeef8de0fdeed4742550d6fa6a82674f9 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Thu, 9 Oct 2025 21:13:27 +0200 Subject: [PATCH 04/17] Formatting update --- PWGLF/Tasks/Strangeness/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Strangeness/CMakeLists.txt b/PWGLF/Tasks/Strangeness/CMakeLists.txt index fc8d93c36b4..31a0087b3fa 100644 --- a/PWGLF/Tasks/Strangeness/CMakeLists.txt +++ b/PWGLF/Tasks/Strangeness/CMakeLists.txt @@ -170,7 +170,7 @@ o2physics_add_dpl_workflow(cascadeanalysislightions SOURCES cascadeAnalysisLightIonsDerivedData.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) - + o2physics_add_dpl_workflow(strangecasctrack SOURCES strangecasctrack.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::EventFilteringUtils From 49c07809297cabe6de86f83810e5f1c389b896b6 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Thu, 9 Oct 2025 21:21:10 +0200 Subject: [PATCH 05/17] Formatting update --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 29234f4918d..acce86c5847 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -27,6 +27,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::math; struct StrangeCascTrack { @@ -61,7 +62,7 @@ struct StrangeCascTrack { histos.add("Events/PVz", "PV z position", kTH1F, {{100, -20, 20}}); histos.add("Events/Mult", "Multiplicity", kTH1F, {axisMult}); - histos.add("Tracked/Phi", "Phi", kTH1F, {{100, 0., 2 * o2::constants::math::M_PI}}); + histos.add("Tracked/Phi", "Phi", kTH1F, {{100, 0., 2 * M_PI}}); histos.add("Tracked/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); histos.add("Tracked/DCAxy", "DCA to xy", kTH1F, {{500, 0., 0.5}}); histos.add("Tracked/DCAz", "DCA to z", kTH1F, {{500, 0., 0.5}}); @@ -71,7 +72,7 @@ struct StrangeCascTrack { histos.add("Tracked/Omega", "", kTHnD, {axisOmegaMass, axisPt, axisMult}); histos.add("Tracked/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); - histos.add("All/Phi", "Phi", kTH1F, {{100, 0., 2 * o2::constants::math::M_PI}}); + histos.add("All/Phi", "Phi", kTH1F, {{100, 0., 2 * M_PI}}); histos.add("All/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); histos.add("All/DCAxy", "DCA to xy", kTH1F, {{1000, 0, 1.}}); histos.add("All/DCAz", "DCA to z", kTH1F, {{1000, 0, 1.}}); From dd4153dbc0151efb12526e8c6dbeb68e007409ab Mon Sep 17 00:00:00 2001 From: Yakiv Date: Fri, 24 Oct 2025 00:28:03 +0200 Subject: [PATCH 06/17] task update --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 556 ++++++++++++++++--- 1 file changed, 464 insertions(+), 92 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index acce86c5847..d7a832bcb42 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -14,111 +14,145 @@ /// \author Yakiv Paroviak (yakiv.paroviak@cern.ch) #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Multiplicity.h" +#include "CCDB/BasicCCDBManager.h" +#include #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" +#include "Framework/StaticFor.h" +#include "Framework/AnalysisDataModel.h" + +#include +#include "TF1.h" +#include "TF2.h" +#include +#include using namespace o2; +using namespace o2::constants::math; using namespace o2::framework; using namespace o2::framework::expressions; -using namespace o2::constants::math; + +// tables for derived data +using DerCollisionWMult = soa::Join::iterator; +using DerCascDatas = soa::Join; +using DerTraCascDatas = soa::Join; + +// tables for derived MC +using DerMCGenCascades = soa::Join; +using DerMCRecCollision = soa::Join::iterator; +using DerMCRecCascDatas = soa::Join; +using DerMCRecTraCascDatas = soa::Join; + +// tables for PID selection +using DauTracks = soa::Join; struct StrangeCascTrack { - using TraCascDatas = soa::Join; - using CascDatas = soa::Join; + Service ccdb; + Service pdgDB; + + PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + // subprocess switches: Configurable doProcessPP{"doProcessPP", true, "true for pp, false for PbPb and OO"}; - Configurable doProcessPbPb{"doProcessPbPb", false, "true for PbPb, false for pp and OO"}; - Configurable doProcessOO{"doProcessOO", false, "true for OO, false for pp and PbPb"}; + // selections + Configurable doApplyCuts{"doApplyCuts", true, "apply cuts"}; // dca for filtering data primaries + Configurable doApplyTPCPID{"doApplyTPCPID", true, "apply tpc pid to dau tracks"}; + Configurable doApplyTOFPID{"doApplyTOFPID", true, "apply tof pid to dau tracks"}; + Configurable doCompetingMassRej{"doCompetingMassRej", true, "competing mass rejection for omegas"}; + // corrections + Configurable doApplyEfficiency{"doApplyEfficiency", false, "apply efficiency correction"}; + Configurable doPropagateEfficiency{"doPropagateEfficiency", false, "apply efficiency propagation"}; + Configurable doApplyPurity{"doApplyPurity", false, "apply purity correction"}; + Configurable doPropagatePurity{"doPropagatePurity", false, "apply purity propagation"}; + Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository to use"}; + Configurable efficiencyCCDBPath{"efficiencyCCDBPath", "GLO/Config/GeometryAligned", "Path of the efficiency corrections"}; + // mc settings + Configurable doFillTruth{"doFillTruth", false, "require MC truth for reco"}; - Configurable doProcessMC{"doProcessMC", false, "true for MC, false for data"}; - Configurable doRequireFT0{"doRequireFT0", false, "true for offline trigger for Run 3"}; - Configurable doApplyPID{"doApplyPID", false, "true for offline trigger for Run 3"}; - Configurable doApplyCuts{"doApplyCuts", true, "true for offline trigger for Run 3"}; + // event and dau track selection + struct : ConfigurableGroup { + Configurable cutDCAtoPVxy{"cutDCAtoPVxy", 0.02f, "max cascade dca to PV in xy"}; + Configurable cutDCAtoPVz{"cutDCAtoPVz", 0.02f, "max cascade dca to PV in z"}; + Configurable compMassRej{"compMassRej", 0.008, "Competing mass rejection"}; + // TPC PID selection + Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; + Configurable NSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; + Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + // TOF PID selection + Configurable NSigmaTOFPion{"NSigmaTOFPion", 3, "NSigmaTOFPion"}; + Configurable NSigmaTOFKaon{"NSigmaTOFKaon", 3, "NSigmaTOFKaon"}; + Configurable NSigmaTOFProton{"NSigmaTOFProton", 3, "NSigmaTOFProton"}; + } selCuts; - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "p_{T} (GeV/c)"}; - ConfigurableAxis axisMult{"axisMult", {VARIABLE_WIDTH, 0.0f, 0.01f, 1.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}, "Multiplicity"}; - ConfigurableAxis axisOmegaMass{"axisOmegaMass", {2000, 1.6, 1.8}, "#Omega M_{inv} (GeV/c^{2})"}; - ConfigurableAxis axisXiMass{"axisXiMass", {2000, 1.2, 1.4}, "#Xi M_{inv} (GeV/c^{2})"}; + // axes + struct : ConfigurableGroup { + ConfigurableAxis axisPhi{"Phi", {72, 0, TwoPI}, "#phi"}; + ConfigurableAxis axisEta{"Eta", {102, -2.01, 2.01}, "#eta"}; + ConfigurableAxis axisDCAxy{"DCA to xy plane", {500, 0., 0.5}, "cm"}; + ConfigurableAxis axisDCAz{"DCA to z plane", {500, 0., 0.5}, "cm"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisMult{"axisMult", {VARIABLE_WIDTH, 0.0f, 0.01f, 1.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}, "FT0 mult %"}; + ConfigurableAxis axisOmegaMass{"axisOmegaMass", {2000, 1.6, 1.8}, "#Omega M_{inv} (GeV/c^{2})"}; + ConfigurableAxis axisXiMass{"axisXiMass", {2000, 1.2, 1.4}, "#Xi M_{inv} (GeV/c^{2})"}; + } axesConfig; - Configurable CutDCAtoPVxy{"CutDCAtoPVxy", 0.02f, "max cascade dca to PV in xy"}; - Configurable CutDCAtoPVz{"CutDCAtoPVz", 0.02f, "max cascade dca to PV in z"}; + // // Filters events + // if (doFilterEvents) { + // Filter eventFilter = (o2::aod::evsel::sel8 == true); + // Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < cutzvertex); + // } - void init(InitContext const&) - { - histos.add("Events/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); - histos.add("Events/PVx", "PV x position", kTH1F, {{200, -0.1, 0.1}}); - histos.add("Events/PVy", "PV y position", kTH1F, {{200, -0.1, 0.1}}); - histos.add("Events/PVz", "PV z position", kTH1F, {{100, -20, 20}}); - histos.add("Events/Mult", "Multiplicity", kTH1F, {axisMult}); - - histos.add("Tracked/Phi", "Phi", kTH1F, {{100, 0., 2 * M_PI}}); - histos.add("Tracked/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); - histos.add("Tracked/DCAxy", "DCA to xy", kTH1F, {{500, 0., 0.5}}); - histos.add("Tracked/DCAz", "DCA to z", kTH1F, {{500, 0., 0.5}}); - histos.add("Tracked/EvMult", "Multiplicity of events with >=1 cascade", kTH1F, {axisMult}); - histos.add("Tracked/MassOmega", "Invariant mass hypothesis", kTH1F, {axisOmegaMass}); - histos.add("Tracked/MassXi", "Invariant mass hypothesis", kTH1F, {axisXiMass}); - histos.add("Tracked/Omega", "", kTHnD, {axisOmegaMass, axisPt, axisMult}); - histos.add("Tracked/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); - - histos.add("All/Phi", "Phi", kTH1F, {{100, 0., 2 * M_PI}}); - histos.add("All/Eta", "Eta", kTH1F, {{102, -2.01, 2.01}}); - histos.add("All/DCAxy", "DCA to xy", kTH1F, {{1000, 0, 1.}}); - histos.add("All/DCAz", "DCA to z", kTH1F, {{1000, 0, 1.}}); - histos.add("All/EvMult", "Multiplicity of events with >=1 cascade", kTH1F, {axisMult}); - histos.add("All/MassOmega", "Invariant mass hypothesis", kTH1F, {axisOmegaMass}); - histos.add("All/MassXi", "Invariant mass hypothesis", kTH1F, {axisXiMass}); - histos.add("All/Omega", "", kTHnD, {axisOmegaMass, axisPt, axisMult}); - histos.add("All/Xi", "", kTHnD, {axisXiMass, axisPt, axisMult}); - } + // cascade reconstruction types + static constexpr std::string_view kTypeNames[] = {"Standard", "Tracked"}; - void processTracked(soa::Join::iterator const& collision, - aod::TraCascDatas const& tracascades) + // for efficiency and purity corrections + TH2F* hEfficiency; + TH2F* hEfficiencyUncertainty; + TH2F* hPurity; + TH2F* hPurityUncertainty; + int mRunNumber; + // loads efficiencies and purities + void initEfficiencyFromCCDB(int64_t runNumber, int64_t timestamp) { - double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); - int64_t casccollid = 0; - for (auto const& cascade : tracascades) { - - double dcaxy = cascade.dcaXYCascToPV(); - double dcaz = cascade.dcaZCascToPV(); - if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) - continue; // DCA check - - if (collision.index() != casccollid) { - histos.fill(HIST("Tracked/EvMult"), mult); // count and list mult of events with at least one cascade - casccollid = collision.index(); - } + if (mRunNumber == runNumber) { + return; + } + mRunNumber = runNumber; + LOG(info) << "Loading efficiencies and purities from CCDB for run " << mRunNumber << " now..."; + auto timeStamp = timestamp; - double pt = cascade.pt(); - double phi = cascade.phi(); - double eta = cascade.eta(); - double massXi = cascade.mXi(); - double massOmega = cascade.mOmega(); + TList* listEfficiencies = ccdb->getForTimeStamp(efficiencyCCDBPath, timeStamp); - histos.fill(HIST("Tracked/DCAxy"), dcaxy); - histos.fill(HIST("Tracked/DCAz"), dcaz); - histos.fill(HIST("Tracked/Phi"), phi); - histos.fill(HIST("Tracked/Eta"), eta); - histos.fill(HIST("Tracked/MassXi"), massXi); - histos.fill(HIST("Tracked/MassOmega"), massOmega); - histos.fill(HIST("Tracked/Xi"), massXi, pt, mult); - histos.fill(HIST("Tracked/Omega"), massOmega, pt, mult); + if (!listEfficiencies) { + LOG(fatal) << "Problem getting TList object with efficiencies and purities!"; } - } - void processAll(soa::Join::iterator const& collision, - aod::CascDatas const& cascades) + hEfficiency = static_cast(listEfficiencies->FindObject("hEfficiency")); + hPurity = static_cast(listEfficiencies->FindObject("hPurity")); + hEfficiencyUncertainty = static_cast(listEfficiencies->FindObject("hEfficiencyUncertainty")); + hPurityUncertainty = static_cast(listEfficiencies->FindObject("hPurityUncertainty")); + if (doPropagateEfficiency && !hEfficiencyUncertainty) LOG(fatal) << "Problem getting hEfficiencyUncertainty!"; + if (doPropagatePurity && !hPurityUncertainty) LOG(fatal) << "Problem getting hPurityUncertainty!"; + LOG(info) << "Efficiencies and purities now loaded for " << mRunNumber; + } + // general info about processed events + template + void fillEvents(TEvent const& collision) { histos.fill(HIST("Events/EvCounter"), 0.5); double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); @@ -129,38 +163,376 @@ struct StrangeCascTrack { histos.fill(HIST("Events/PVx"), pvx); histos.fill(HIST("Events/PVy"), pvy); histos.fill(HIST("Events/PVz"), pvz); + } + // checks general selection criteria + template + bool isValidCasc(TCascade cascade) + { + if (cascade.dcaXYCascToPV() > selCuts.cutDCAtoPVxy) return false; + if (cascade.dcaZCascToPV() > selCuts.cutDCAtoPVz) return false; + return true; + } + // checks TPC PID of dau tracks + template + bool passesTPC(TCascade cascade) + { + const auto& posDaughterTrackCasc = cascade.template posTrackExtra_as(); + const auto& negDaughterTrackCasc = cascade.template negTrackExtra_as(); + if (cascade.sign() < 0) { + if (std::abs(posDaughterTrackCasc.tpcNSigmaPr()) > selCuts.NSigmaTPCProton) { + return false; + } + if (std::abs(negDaughterTrackCasc.tpcNSigmaPi()) > selCuts.NSigmaTPCPion) { + return false; + } + } else { + if (std::abs(negDaughterTrackCasc.tpcNSigmaPr()) > selCuts.NSigmaTPCProton) { + return false; + } + if (std::abs(posDaughterTrackCasc.tpcNSigmaPi()) > selCuts.NSigmaTPCPion) { + return false; + } + } + return true; + } + // checks TOF PID of dau tracks + template + bool passesTOF(TCascade cascade, TString particle) + { + return true; + // const auto& bachDaughterTrackCasc = cascade.bachTrackExtra_as(); + // const auto& posDaughterTrackCasc = cascade.posTrackExtra_as(); + // const auto& negDaughterTrackCasc = cascade.negTrackExtra_as(); + // bool xiPassTOFSelection = true; + // bool omegaPassTOFSelection = true; + // if (cascade.sign() < 0) { + // if (posDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { + // omegaPassTOFSelection &= false; + // } + // } + // if (negDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { + // omegaPassTOFSelection &= false; + // } + // } + // } else { + // if (posDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { + // omegaPassTOFSelection &= false; + // } + // } + // if (negDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { + // omegaPassTOFSelection &= false; + // } + // } + // } + + // if (bachDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { + // omegaPassTOFSelection &= false; + // } + // } + // if (bachDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { + // omegaPassTOFSelection &= false; + // } + // } + + // if (particle == "xi") {return xiPassTOFSelection;} else {return omegaPassTOFSelection;} + } + // checks whether gen cascade corresponds to PDG code + template + bool isValidPDG(TCascade cascade, TString particle) + { + static constexpr int kPdgCodes[] = {3312, 3334}; // "XiMinus", "OmegaMinus" + if (particle == "xi" && std::abs(cascade.pdgCode())==kPdgCodes[0]) return true; + if (particle == "omega" && std::abs(cascade.pdgCode())==kPdgCodes[1]) return true; + return false; + } + // checks whether rec cascade is a truth primary xi or omega + template + bool isMCTruth(const TCascade& cascade, TString particle) + { + if constexpr (requires { cascade.has_cascMCCore(); }) { // safety check: discard rec cascade without gen reference + auto cascmccore = cascade.template cascMCCore_as(); + if (!cascmccore.isPhysicalPrimary()) + return false; + int pdg = std::abs(cascmccore.pdgCode()); + if (particle == "xi") return (pdg == 3312); + if (particle == "omega") return (pdg == 3334); + + } + return false; + } + // applies purities and efficiencies + void fillHist(std::shared_ptr hist, double binFillThn[], float efficiency, float effUncert, float purity, float purityUncert) + { + float previousContent, previousError2, currentContent, currentError2; + int bin = hist->GetBin(binFillThn); + previousContent = hist->GetBinContent(bin); + previousError2 = hist->GetBinError2(bin); + currentContent = previousContent + purity / (efficiency); + currentError2 = previousError2 + std::pow( purity / (efficiency), 2) + std::pow(purityUncert / (efficiency), 2) + std::pow(effUncert * purity, 2) / std::pow(efficiency, 4); + hist->SetBinContent(bin, currentContent); + hist->SetBinError2(bin, currentError2); + } + // applies selections and fills histograms + template + void analyseCascs(TEvent collision, TCascs cascades) + { int64_t casccollid = 0; for (auto const& cascade : cascades) { - double dcaxy = cascade.dcaXYCascToPV(); - double dcaz = cascade.dcaZCascToPV(); - if (doApplyCuts && ((dcaxy > CutDCAtoPVxy) || (dcaz > CutDCAtoPVz))) - continue; // DCA check + if constexpr (requires { cascade.topologyChi2(); }) { + if (!cascade.has_standardCascade()) continue; // safety check: dismisses tracked cascades without proper reference + } + + // for tracked cascades, make a reference to standard table + auto stdCasc = [&]() { + if constexpr (requires { cascade.topologyChi2(); }) { + if constexpr (requires { collision.straMCCollisionId(); }) { + return cascade.template standardCascade_as(); + } else { + return cascade.template standardCascade_as(); + } + } else { + return cascade; + } + }(); + + // fill cascade statistics without any selections + static constexpr int type = [&]() { + if constexpr (requires { cascade.topologyChi2(); }) { + return 1; + } else { + return 0; + } + }(); + + double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); // ion collisions use FT0C for multiplicity, pp uses both + + float efficiency = 1.0f; + float efficiencyError = 0.0f; + float purity = 1.0f; + float purityError = 0.0f; + if (doApplyEfficiency) { + efficiency = hEfficiency->Interpolate(cascade.pt(), mult); + if (doPropagateEfficiency) { + efficiencyError = hEfficiencyUncertainty->Interpolate(cascade.pt(), mult); + } + if (efficiency == 0) { // check for zero efficiency, do not apply if the case + efficiency = 1.; + efficiencyError = 0.; + } + } + if (doApplyPurity) { + purity = hPurity->Interpolate(cascade.pt(), mult); + if (doPropagatePurity) { + purityError = hPurityUncertainty->Interpolate(cascade.pt(), mult); + } + if (purity == 0) { // check for zero purity, do not apply if the case + purity = 1.; + purityError = 0.; + } + } if (collision.index() != casccollid) { - histos.fill(HIST("All/EvMult"), mult); // count and list mult of events with at least one cascade + histos.fill(HIST(kTypeNames[type]) + HIST("/EvMult"), mult); casccollid = collision.index(); } - double pt = cascade.pt(); - double phi = cascade.phi(); - double eta = cascade.eta(); double massXi = cascade.mXi(); double massOmega = cascade.mOmega(); + double pt = cascade.pt(); + + histos.fill(HIST(kTypeNames[type]) + HIST("/DCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/DCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Phi"), cascade.phi()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Eta"), cascade.eta()); + histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiNoSel"), massXi); + histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaNoSel"), massOmega); - histos.fill(HIST("All/DCAxy"), dcaxy); - histos.fill(HIST("All/DCAz"), dcaz); - histos.fill(HIST("All/Phi"), phi); - histos.fill(HIST("All/Eta"), eta); - histos.fill(HIST("All/MassXi"), massXi); - histos.fill(HIST("All/MassOmega"), massOmega); - histos.fill(HIST("All/Xi"), massXi, pt, mult); - histos.fill(HIST("All/Omega"), massOmega, pt, mult); + // start checking selections + bool passedAllSels = true; + // apply general selection criteria + if (doApplyCuts) + { if (isValidCasc(cascade)) + { + histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiGenSel"), massXi); + histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaGenSel"), massOmega); + } else { + passedAllSels = false; + }} + // apply tpc pid + if (doApplyTPCPID) + { if (passesTPC(stdCasc)) + { + histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTPCPID"), massXi); + histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTPCPID"), massOmega); + } else { + passedAllSels = false; + }} + // apply tof pid + bool passedAllSelsXi = passedAllSels; + bool passedAllSelsOmega = passedAllSels; + if (doApplyTOFPID) + { if (passesTOF(cascade, "xi")) + { + histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTOFPID"), massXi); + } else { + passedAllSelsXi = false; + } + if (passesTOF(cascade, "omega")) + { + histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTOFPID"), massOmega); + } else { + passedAllSelsOmega = false; + } + } + // apply competing mass rej + if (doCompetingMassRej) + { if (std::abs(massXi - pdgDB->Mass(3312)) > selCuts.compMassRej) + { + histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaMassSel"), massOmega); + } else { + passedAllSelsOmega = false; + } + } + + // fill w/ cascs that passed all applied sels + double binFillXi[3] = {massXi, pt, mult}; + if (passedAllSelsXi) + { + histos.fill(HIST(kTypeNames[type]) + HIST("/MassXi"), massXi); + fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Xi")), binFillXi, efficiency, efficiencyError, purity, purityError); + if constexpr (requires { collision.straMCCollisionId(); }) { + if (doFillTruth && isMCTruth(stdCasc, "xi")) histos.fill(HIST("MC/RecTruth/")+HIST(kTypeNames[type])+HIST("/Xi"), massXi, pt, mult); + } + } + double binFillOmega[3] = {massOmega, pt, mult}; + if (passedAllSelsOmega) + { + histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmega"), massOmega); + fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Omega")), binFillOmega, efficiency, efficiencyError, purity, purityError); + if constexpr (requires { collision.straMCCollisionId(); }) { + if (doFillTruth && isMCTruth(stdCasc, "omega")) histos.fill(HIST("MC/RecTruth/")+HIST(kTypeNames[type])+HIST("/Omega"), massOmega, pt, mult); + } + } } } - PROCESS_SWITCH(StrangeCascTrack, processTracked, "process tracked cascades", true); - PROCESS_SWITCH(StrangeCascTrack, processAll, "process all cascades", true); + + void init(InitContext const&) + { + // for all events processing + histos.add("Events/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); + histos.add("Events/PVx", "PV x position", kTH1F, {{200, -0.1, 0.1}}); + histos.add("Events/PVy", "PV y position", kTH1F, {{200, -0.1, 0.1}}); + histos.add("Events/PVz", "PV z position", kTH1F, {{100, -20, 20}}); + histos.add("Events/Mult", "Multiplicity", kTH1F, {axesConfig.axisMult}); + // for cascade processing + static_for<0, 1>([&](auto type) { + histos.add(Form("%s/Phi", kTypeNames[type].data()), "Phi", kTH1F, {axesConfig.axisPhi}); + histos.add(Form("%s/Eta", kTypeNames[type].data()), "Eta", kTH1F, {axesConfig.axisEta}); + histos.add(Form("%s/DCAxy", kTypeNames[type].data()), "DCA to xy", kTH1F, {axesConfig.axisDCAxy}); + histos.add(Form("%s/DCAz", kTypeNames[type].data()), "DCA to z", kTH1F, {axesConfig.axisDCAz}); + histos.add(Form("%s/EvMult", kTypeNames[type].data()), "Multiplicity of events with >=1 cascade", kTH1F, {axesConfig.axisMult}); + // no selection applied + histos.add(Form("%s/MassOmegaNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only gen selection applied + histos.add(Form("%s/MassOmegaGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only tpc pid selection applied + histos.add(Form("%s/MassOmegaTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only tof pid selection applied + histos.add(Form("%s/MassOmegaTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only competing mass rejection selection applied + histos.add(Form("%s/MassOmegaMassSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + // passed all applied sels + histos.add(Form("%s/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + histos.add(Form("%s/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + }); + // for MC-specific processing + histos.add("MC/Gen/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); + histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis + histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Omegas + histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); + histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); + histos.add("MC/RecTruth/Standard/Omega", "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add("MC/RecTruth/Standard/Xi", "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add("MC/RecTruth/Tracked/Omega", "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add("MC/RecTruth/Tracked/Xi", "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + } + + void processDerivedData(DerCollisionWMult const& collision, DerCascDatas const& allCascs, DerTraCascDatas const& traCascs, DauTracks const&) + { + fillEvents(collision); // save info about all processed events + if (doApplyEfficiency) { + initEfficiencyFromCCDB(collision.runNumber(), collision.timestamp()); + } + analyseCascs(collision, allCascs); // process all cascades + analyseCascs(collision, traCascs); // process tracked cascades + } + + void processDerivedMCGen(aod::StraMCCollisions const& genColls, DerMCGenCascades const& genCascs, soa::Join const& recColls) + { + for (auto const& genColl : genColls) { + histos.fill(HIST("MC/Gen/EvCounter"), 0.5); // generated events statistics + // (for efficiency calculation) only take reconstructed events + auto slicedRecColls = recColls.sliceBy(perMcCollision, genColl.globalIndex()); + for (auto const& recColl : slicedRecColls) { + histos.fill(HIST("MC/Rec/EvCounter"), 0.5); + double casc_mult = doProcessPP ? recColl.centFT0M() : recColl.centFT0C(); + histos.fill(HIST("MC/Rec/EvMult"), casc_mult); + int64_t genCollId = recColl.straMCCollisionId(); + for (auto const& casc : genCascs) { + if (casc.straMCCollisionId() != genCollId) continue; // safety check + if (!casc.isPhysicalPrimary()) continue; // skip non-primary particles + double casc_pt = std::sqrt(std::pow(casc.pxMC(), 2) + std::pow(casc.pyMC(), 2)); + if (isValidPDG(casc, "xi")) histos.fill(HIST("MC/Gen/Xi"), casc_pt, casc_mult); + if (isValidPDG(casc, "omega")) histos.fill(HIST("MC/Gen/Omega"), casc_pt, casc_mult); + } + }} + } + + void processDerivedMCRec(DerMCRecCollision const& collision, DerMCRecCascDatas const& allCascs, DerMCRecTraCascDatas const& traCascs, DauTracks const&, DerMCGenCascades const&) + { + fillEvents(collision); // save info about all processed events + if (doApplyEfficiency) { + initEfficiencyFromCCDB(collision.runNumber(), collision.timestamp()); + } + analyseCascs(collision, allCascs); // process all cascades + analyseCascs(collision, traCascs); // process tracked cascades + } + + PROCESS_SWITCH(StrangeCascTrack, processDerivedData, "process derived data", true); + PROCESS_SWITCH(StrangeCascTrack, processDerivedMCGen, "process derived generated mc data", false); + PROCESS_SWITCH(StrangeCascTrack, processDerivedMCRec, "process derived reconstructed mc data", false); // mc and data are mutually exclusive! }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From be928ae28ed1255856c0f675e4232ae09c9f9042 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Fri, 24 Oct 2025 00:41:53 +0200 Subject: [PATCH 07/17] Formatting check --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 347 ++++++++++--------- 1 file changed, 178 insertions(+), 169 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index d7a832bcb42..15db32c5c5d 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -13,27 +13,27 @@ /// \brief Analysis of strangeness tracking efficiency via primary production of Omega and Xi in Run 3 /// \author Yakiv Paroviak (yakiv.paroviak@cern.ch) -#include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CCDB/BasicCCDBManager.h" -#include #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" #include "Framework/StaticFor.h" -#include "Framework/AnalysisDataModel.h" +#include "Framework/runDataProcessing.h" +#include -#include #include "TF1.h" #include "TF2.h" +#include + #include #include @@ -82,20 +82,19 @@ struct StrangeCascTrack { // mc settings Configurable doFillTruth{"doFillTruth", false, "require MC truth for reco"}; - // event and dau track selection struct : ConfigurableGroup { - Configurable cutDCAtoPVxy{"cutDCAtoPVxy", 0.02f, "max cascade dca to PV in xy"}; - Configurable cutDCAtoPVz{"cutDCAtoPVz", 0.02f, "max cascade dca to PV in z"}; - Configurable compMassRej{"compMassRej", 0.008, "Competing mass rejection"}; - // TPC PID selection - Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; - Configurable NSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; - Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; - // TOF PID selection - Configurable NSigmaTOFPion{"NSigmaTOFPion", 3, "NSigmaTOFPion"}; - Configurable NSigmaTOFKaon{"NSigmaTOFKaon", 3, "NSigmaTOFKaon"}; - Configurable NSigmaTOFProton{"NSigmaTOFProton", 3, "NSigmaTOFProton"}; + Configurable cutDCAtoPVxy{"cutDCAtoPVxy", 0.02f, "max cascade dca to PV in xy"}; + Configurable cutDCAtoPVz{"cutDCAtoPVz", 0.02f, "max cascade dca to PV in z"}; + Configurable compMassRej{"compMassRej", 0.008, "Competing mass rejection"}; + // TPC PID selection + Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; + Configurable NSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; + Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + // TOF PID selection + Configurable NSigmaTOFPion{"NSigmaTOFPion", 3, "NSigmaTOFPion"}; + Configurable NSigmaTOFKaon{"NSigmaTOFKaon", 3, "NSigmaTOFKaon"}; + Configurable NSigmaTOFProton{"NSigmaTOFProton", 3, "NSigmaTOFProton"}; } selCuts; // axes @@ -146,8 +145,10 @@ struct StrangeCascTrack { hPurity = static_cast(listEfficiencies->FindObject("hPurity")); hEfficiencyUncertainty = static_cast(listEfficiencies->FindObject("hEfficiencyUncertainty")); hPurityUncertainty = static_cast(listEfficiencies->FindObject("hPurityUncertainty")); - if (doPropagateEfficiency && !hEfficiencyUncertainty) LOG(fatal) << "Problem getting hEfficiencyUncertainty!"; - if (doPropagatePurity && !hPurityUncertainty) LOG(fatal) << "Problem getting hPurityUncertainty!"; + if (doPropagateEfficiency && !hEfficiencyUncertainty) + LOG(fatal) << "Problem getting hEfficiencyUncertainty!"; + if (doPropagatePurity && !hPurityUncertainty) + LOG(fatal) << "Problem getting hPurityUncertainty!"; LOG(info) << "Efficiencies and purities now loaded for " << mRunNumber; } // general info about processed events @@ -168,8 +169,10 @@ struct StrangeCascTrack { template bool isValidCasc(TCascade cascade) { - if (cascade.dcaXYCascToPV() > selCuts.cutDCAtoPVxy) return false; - if (cascade.dcaZCascToPV() > selCuts.cutDCAtoPVz) return false; + if (cascade.dcaXYCascToPV() > selCuts.cutDCAtoPVxy) + return false; + if (cascade.dcaZCascToPV() > selCuts.cutDCAtoPVz) + return false; return true; } // checks TPC PID of dau tracks @@ -185,12 +188,12 @@ struct StrangeCascTrack { if (std::abs(negDaughterTrackCasc.tpcNSigmaPi()) > selCuts.NSigmaTPCPion) { return false; } - } else { + } else { if (std::abs(negDaughterTrackCasc.tpcNSigmaPr()) > selCuts.NSigmaTPCProton) { return false; } if (std::abs(posDaughterTrackCasc.tpcNSigmaPi()) > selCuts.NSigmaTPCPion) { - return false; + return false; } } return true; @@ -200,90 +203,93 @@ struct StrangeCascTrack { bool passesTOF(TCascade cascade, TString particle) { return true; - // const auto& bachDaughterTrackCasc = cascade.bachTrackExtra_as(); - // const auto& posDaughterTrackCasc = cascade.posTrackExtra_as(); - // const auto& negDaughterTrackCasc = cascade.negTrackExtra_as(); - // bool xiPassTOFSelection = true; - // bool omegaPassTOFSelection = true; - // if (cascade.sign() < 0) { - // if (posDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { - // omegaPassTOFSelection &= false; - // } - // } - // if (negDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { - // omegaPassTOFSelection &= false; - // } - // } - // } else { - // if (posDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { - // omegaPassTOFSelection &= false; - // } - // } - // if (negDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { - // omegaPassTOFSelection &= false; - // } - // } - // } - - // if (bachDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { - // omegaPassTOFSelection &= false; - // } - // } - - // if (bachDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { - // omegaPassTOFSelection &= false; - // } - // } - - // if (particle == "xi") {return xiPassTOFSelection;} else {return omegaPassTOFSelection;} - } + // const auto& bachDaughterTrackCasc = cascade.bachTrackExtra_as(); + // const auto& posDaughterTrackCasc = cascade.posTrackExtra_as(); + // const auto& negDaughterTrackCasc = cascade.negTrackExtra_as(); + // bool xiPassTOFSelection = true; + // bool omegaPassTOFSelection = true; + // if (cascade.sign() < 0) { + // if (posDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { + // omegaPassTOFSelection &= false; + // } + // } + // if (negDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { + // omegaPassTOFSelection &= false; + // } + // } + // } else { + // if (posDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { + // omegaPassTOFSelection &= false; + // } + // } + // if (negDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { + // omegaPassTOFSelection &= false; + // } + // } + // } + + // if (bachDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { + // omegaPassTOFSelection &= false; + // } + // } + + // if (bachDaughterTrackCasc.hasTOF()) { + // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { + // xiPassTOFSelection &= false; + // } + // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { + // omegaPassTOFSelection &= false; + // } + // } + + // if (particle == "xi") {return xiPassTOFSelection;} else {return omegaPassTOFSelection;} + } // checks whether gen cascade corresponds to PDG code template bool isValidPDG(TCascade cascade, TString particle) { static constexpr int kPdgCodes[] = {3312, 3334}; // "XiMinus", "OmegaMinus" - if (particle == "xi" && std::abs(cascade.pdgCode())==kPdgCodes[0]) return true; - if (particle == "omega" && std::abs(cascade.pdgCode())==kPdgCodes[1]) return true; + if (particle == "xi" && std::abs(cascade.pdgCode()) == kPdgCodes[0]) + return true; + if (particle == "omega" && std::abs(cascade.pdgCode()) == kPdgCodes[1]) + return true; return false; } // checks whether rec cascade is a truth primary xi or omega template bool isMCTruth(const TCascade& cascade, TString particle) { - if constexpr (requires { cascade.has_cascMCCore(); }) { // safety check: discard rec cascade without gen reference - auto cascmccore = cascade.template cascMCCore_as(); - if (!cascmccore.isPhysicalPrimary()) - return false; - int pdg = std::abs(cascmccore.pdgCode()); - if (particle == "xi") return (pdg == 3312); - if (particle == "omega") return (pdg == 3334); - - } - return false; + if constexpr (requires { cascade.has_cascMCCore(); }) { // safety check: discard rec cascade without gen reference + auto cascmccore = cascade.template cascMCCore_as(); + if (!cascmccore.isPhysicalPrimary()) + return false; + int pdg = std::abs(cascmccore.pdgCode()); + if (particle == "xi") + return (pdg == 3312); + if (particle == "omega") + return (pdg == 3334); + } + return false; } // applies purities and efficiencies void fillHist(std::shared_ptr hist, double binFillThn[], float efficiency, float effUncert, float purity, float purityUncert) @@ -293,7 +299,7 @@ struct StrangeCascTrack { previousContent = hist->GetBinContent(bin); previousError2 = hist->GetBinError2(bin); currentContent = previousContent + purity / (efficiency); - currentError2 = previousError2 + std::pow( purity / (efficiency), 2) + std::pow(purityUncert / (efficiency), 2) + std::pow(effUncert * purity, 2) / std::pow(efficiency, 4); + currentError2 = previousError2 + std::pow(purity / (efficiency), 2) + std::pow(purityUncert / (efficiency), 2) + std::pow(effUncert * purity, 2) / std::pow(efficiency, 4); hist->SetBinContent(bin, currentContent); hist->SetBinError2(bin, currentError2); } @@ -305,20 +311,21 @@ struct StrangeCascTrack { for (auto const& cascade : cascades) { if constexpr (requires { cascade.topologyChi2(); }) { - if (!cascade.has_standardCascade()) continue; // safety check: dismisses tracked cascades without proper reference + if (!cascade.has_standardCascade()) + continue; // safety check: dismisses tracked cascades without proper reference } // for tracked cascades, make a reference to standard table auto stdCasc = [&]() { - if constexpr (requires { cascade.topologyChi2(); }) { - if constexpr (requires { collision.straMCCollisionId(); }) { - return cascade.template standardCascade_as(); - } else { - return cascade.template standardCascade_as(); - } + if constexpr (requires { cascade.topologyChi2(); }) { + if constexpr (requires { collision.straMCCollisionId(); }) { + return cascade.template standardCascade_as(); } else { - return cascade; + return cascade.template standardCascade_as(); } + } else { + return cascade; + } }(); // fill cascade statistics without any selections @@ -340,22 +347,22 @@ struct StrangeCascTrack { efficiency = hEfficiency->Interpolate(cascade.pt(), mult); if (doPropagateEfficiency) { efficiencyError = hEfficiencyUncertainty->Interpolate(cascade.pt(), mult); - } - if (efficiency == 0) { // check for zero efficiency, do not apply if the case - efficiency = 1.; - efficiencyError = 0.; - } } + if (efficiency == 0) { // check for zero efficiency, do not apply if the case + efficiency = 1.; + efficiencyError = 0.; + } + } if (doApplyPurity) { purity = hPurity->Interpolate(cascade.pt(), mult); if (doPropagatePurity) { purityError = hPurityUncertainty->Interpolate(cascade.pt(), mult); - } - if (purity == 0) { // check for zero purity, do not apply if the case - purity = 1.; - purityError = 0.; - } } + if (purity == 0) { // check for zero purity, do not apply if the case + purity = 1.; + purityError = 0.; + } + } if (collision.index() != casccollid) { histos.fill(HIST(kTypeNames[type]) + HIST("/EvMult"), mult); @@ -376,44 +383,41 @@ struct StrangeCascTrack { // start checking selections bool passedAllSels = true; // apply general selection criteria - if (doApplyCuts) - { if (isValidCasc(cascade)) - { + if (doApplyCuts) { + if (isValidCasc(cascade)) { histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiGenSel"), massXi); histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaGenSel"), massOmega); } else { passedAllSels = false; - }} + } + } // apply tpc pid - if (doApplyTPCPID) - { if (passesTPC(stdCasc)) - { + if (doApplyTPCPID) { + if (passesTPC(stdCasc)) { histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTPCPID"), massXi); histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTPCPID"), massOmega); } else { passedAllSels = false; - }} + } + } // apply tof pid bool passedAllSelsXi = passedAllSels; bool passedAllSelsOmega = passedAllSels; - if (doApplyTOFPID) - { if (passesTOF(cascade, "xi")) - { + if (doApplyTOFPID) { + if (passesTOF(cascade, "xi")) { histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTOFPID"), massXi); } else { passedAllSelsXi = false; } - if (passesTOF(cascade, "omega")) - { + if (passesTOF(cascade, "omega")) { histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTOFPID"), massOmega); } else { passedAllSelsOmega = false; } } // apply competing mass rej - if (doCompetingMassRej) - { if (std::abs(massXi - pdgDB->Mass(3312)) > selCuts.compMassRej) - { + if (doCompetingMassRej) { + if (std::abs(massXi - pdgDB->Mass(3312)) > selCuts.compMassRej) { histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaMassSel"), massOmega); } else { passedAllSelsOmega = false; @@ -422,21 +426,21 @@ struct StrangeCascTrack { // fill w/ cascs that passed all applied sels double binFillXi[3] = {massXi, pt, mult}; - if (passedAllSelsXi) - { + if (passedAllSelsXi) { histos.fill(HIST(kTypeNames[type]) + HIST("/MassXi"), massXi); fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Xi")), binFillXi, efficiency, efficiencyError, purity, purityError); if constexpr (requires { collision.straMCCollisionId(); }) { - if (doFillTruth && isMCTruth(stdCasc, "xi")) histos.fill(HIST("MC/RecTruth/")+HIST(kTypeNames[type])+HIST("/Xi"), massXi, pt, mult); + if (doFillTruth && isMCTruth(stdCasc, "xi")) + histos.fill(HIST("MC/RecTruth/") + HIST(kTypeNames[type]) + HIST("/Xi"), massXi, pt, mult); } } double binFillOmega[3] = {massOmega, pt, mult}; - if (passedAllSelsOmega) - { + if (passedAllSelsOmega) { histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmega"), massOmega); fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Omega")), binFillOmega, efficiency, efficiencyError, purity, purityError); if constexpr (requires { collision.straMCCollisionId(); }) { - if (doFillTruth && isMCTruth(stdCasc, "omega")) histos.fill(HIST("MC/RecTruth/")+HIST(kTypeNames[type])+HIST("/Omega"), massOmega, pt, mult); + if (doFillTruth && isMCTruth(stdCasc, "omega")) + histos.fill(HIST("MC/RecTruth/") + HIST(kTypeNames[type]) + HIST("/Omega"), massOmega, pt, mult); } } } @@ -452,34 +456,34 @@ struct StrangeCascTrack { histos.add("Events/Mult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // for cascade processing static_for<0, 1>([&](auto type) { - histos.add(Form("%s/Phi", kTypeNames[type].data()), "Phi", kTH1F, {axesConfig.axisPhi}); - histos.add(Form("%s/Eta", kTypeNames[type].data()), "Eta", kTH1F, {axesConfig.axisEta}); - histos.add(Form("%s/DCAxy", kTypeNames[type].data()), "DCA to xy", kTH1F, {axesConfig.axisDCAxy}); - histos.add(Form("%s/DCAz", kTypeNames[type].data()), "DCA to z", kTH1F, {axesConfig.axisDCAz}); - histos.add(Form("%s/EvMult", kTypeNames[type].data()), "Multiplicity of events with >=1 cascade", kTH1F, {axesConfig.axisMult}); - // no selection applied - histos.add(Form("%s/MassOmegaNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only gen selection applied - histos.add(Form("%s/MassOmegaGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only tpc pid selection applied - histos.add(Form("%s/MassOmegaTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only tof pid selection applied - histos.add(Form("%s/MassOmegaTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only competing mass rejection selection applied - histos.add(Form("%s/MassOmegaMassSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - // passed all applied sels - histos.add(Form("%s/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - histos.add(Form("%s/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); - histos.add(Form("%s/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Phi", kTypeNames[type].data()), "Phi", kTH1F, {axesConfig.axisPhi}); + histos.add(Form("%s/Eta", kTypeNames[type].data()), "Eta", kTH1F, {axesConfig.axisEta}); + histos.add(Form("%s/DCAxy", kTypeNames[type].data()), "DCA to xy", kTH1F, {axesConfig.axisDCAxy}); + histos.add(Form("%s/DCAz", kTypeNames[type].data()), "DCA to z", kTH1F, {axesConfig.axisDCAz}); + histos.add(Form("%s/EvMult", kTypeNames[type].data()), "Multiplicity of events with >=1 cascade", kTH1F, {axesConfig.axisMult}); + // no selection applied + histos.add(Form("%s/MassOmegaNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only gen selection applied + histos.add(Form("%s/MassOmegaGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only tpc pid selection applied + histos.add(Form("%s/MassOmegaTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only tof pid selection applied + histos.add(Form("%s/MassOmegaTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXiTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + // only competing mass rejection selection applied + histos.add(Form("%s/MassOmegaMassSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + // passed all applied sels + histos.add(Form("%s/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + histos.add(Form("%s/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); }); // for MC-specific processing histos.add("MC/Gen/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); - histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis + histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Omegas histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); @@ -511,13 +515,18 @@ struct StrangeCascTrack { histos.fill(HIST("MC/Rec/EvMult"), casc_mult); int64_t genCollId = recColl.straMCCollisionId(); for (auto const& casc : genCascs) { - if (casc.straMCCollisionId() != genCollId) continue; // safety check - if (!casc.isPhysicalPrimary()) continue; // skip non-primary particles + if (casc.straMCCollisionId() != genCollId) + continue; // safety check + if (!casc.isPhysicalPrimary()) + continue; // skip non-primary particles double casc_pt = std::sqrt(std::pow(casc.pxMC(), 2) + std::pow(casc.pyMC(), 2)); - if (isValidPDG(casc, "xi")) histos.fill(HIST("MC/Gen/Xi"), casc_pt, casc_mult); - if (isValidPDG(casc, "omega")) histos.fill(HIST("MC/Gen/Omega"), casc_pt, casc_mult); + if (isValidPDG(casc, "xi")) + histos.fill(HIST("MC/Gen/Xi"), casc_pt, casc_mult); + if (isValidPDG(casc, "omega")) + histos.fill(HIST("MC/Gen/Omega"), casc_pt, casc_mult); } - }} + } + } } void processDerivedMCRec(DerMCRecCollision const& collision, DerMCRecCascDatas const& allCascs, DerMCRecTraCascDatas const& traCascs, DauTracks const&, DerMCGenCascades const&) @@ -531,7 +540,7 @@ struct StrangeCascTrack { } PROCESS_SWITCH(StrangeCascTrack, processDerivedData, "process derived data", true); - PROCESS_SWITCH(StrangeCascTrack, processDerivedMCGen, "process derived generated mc data", false); + PROCESS_SWITCH(StrangeCascTrack, processDerivedMCGen, "process derived generated mc data", false); PROCESS_SWITCH(StrangeCascTrack, processDerivedMCRec, "process derived reconstructed mc data", false); // mc and data are mutually exclusive! }; From 93b2367168dc3479a38ccdcac457c56baaaa7035 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Fri, 24 Oct 2025 02:07:17 +0200 Subject: [PATCH 08/17] Fix unused variable error --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 154 +++++++++---------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 15db32c5c5d..609537fcf36 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -199,71 +199,71 @@ struct StrangeCascTrack { return true; } // checks TOF PID of dau tracks - template - bool passesTOF(TCascade cascade, TString particle) - { - return true; - // const auto& bachDaughterTrackCasc = cascade.bachTrackExtra_as(); - // const auto& posDaughterTrackCasc = cascade.posTrackExtra_as(); - // const auto& negDaughterTrackCasc = cascade.negTrackExtra_as(); - // bool xiPassTOFSelection = true; - // bool omegaPassTOFSelection = true; - // if (cascade.sign() < 0) { - // if (posDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { - // omegaPassTOFSelection &= false; - // } - // } - // if (negDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { - // omegaPassTOFSelection &= false; - // } - // } - // } else { - // if (posDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { - // omegaPassTOFSelection &= false; - // } - // } - // if (negDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { - // omegaPassTOFSelection &= false; - // } - // } - // } - - // if (bachDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { - // omegaPassTOFSelection &= false; - // } - // } - - // if (bachDaughterTrackCasc.hasTOF()) { - // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { - // xiPassTOFSelection &= false; - // } - // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { - // omegaPassTOFSelection &= false; - // } - // } - - // if (particle == "xi") {return xiPassTOFSelection;} else {return omegaPassTOFSelection;} - } + // template + // bool passesTOF(TCascade cascade, TString particle) + // { + // return true; + // // const auto& bachDaughterTrackCasc = cascade.bachTrackExtra_as(); + // // const auto& posDaughterTrackCasc = cascade.posTrackExtra_as(); + // // const auto& negDaughterTrackCasc = cascade.negTrackExtra_as(); + // // bool xiPassTOFSelection = true; + // // bool omegaPassTOFSelection = true; + // // if (cascade.sign() < 0) { + // // if (posDaughterTrackCasc.hasTOF()) { + // // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { + // // xiPassTOFSelection &= false; + // // } + // // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { + // // omegaPassTOFSelection &= false; + // // } + // // } + // // if (negDaughterTrackCasc.hasTOF()) { + // // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { + // // xiPassTOFSelection &= false; + // // } + // // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { + // // omegaPassTOFSelection &= false; + // // } + // // } + // // } else { + // // if (posDaughterTrackCasc.hasTOF()) { + // // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { + // // xiPassTOFSelection &= false; + // // } + // // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { + // // omegaPassTOFSelection &= false; + // // } + // // } + // // if (negDaughterTrackCasc.hasTOF()) { + // // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { + // // xiPassTOFSelection &= false; + // // } + // // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { + // // omegaPassTOFSelection &= false; + // // } + // // } + // // } + // + // // if (bachDaughterTrackCasc.hasTOF()) { + // // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { + // // xiPassTOFSelection &= false; + // // } + // // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { + // // omegaPassTOFSelection &= false; + // // } + // // } + // + // // if (bachDaughterTrackCasc.hasTOF()) { + // // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { + // // xiPassTOFSelection &= false; + // // } + // // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { + // // omegaPassTOFSelection &= false; + // // } + // // } + // + // // if (particle == "xi") {return xiPassTOFSelection;} else {return omegaPassTOFSelection;} + // } // checks whether gen cascade corresponds to PDG code template bool isValidPDG(TCascade cascade, TString particle) @@ -403,18 +403,18 @@ struct StrangeCascTrack { // apply tof pid bool passedAllSelsXi = passedAllSels; bool passedAllSelsOmega = passedAllSels; - if (doApplyTOFPID) { - if (passesTOF(cascade, "xi")) { - histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTOFPID"), massXi); - } else { - passedAllSelsXi = false; - } - if (passesTOF(cascade, "omega")) { - histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTOFPID"), massOmega); - } else { - passedAllSelsOmega = false; - } - } + // if (doApplyTOFPID) { + // if (passesTOF(cascade, "xi")) { + // histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTOFPID"), massXi); + // } else { + // passedAllSelsXi = false; + // } + // if (passesTOF(cascade, "omega")) { + // histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTOFPID"), massOmega); + // } else { + // passedAllSelsOmega = false; + // } + // } // apply competing mass rej if (doCompetingMassRej) { if (std::abs(massXi - pdgDB->Mass(3312)) > selCuts.compMassRej) { From d3e5da436bac8defc3fd47d475203152065cc1f4 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 05:48:24 +0100 Subject: [PATCH 09/17] Add TOF PID and rework histograms in strangecasctrack --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 487 +++++++++++-------- 1 file changed, 279 insertions(+), 208 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 609537fcf36..2b9cb88262d 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -43,14 +43,14 @@ using namespace o2::framework; using namespace o2::framework::expressions; // tables for derived data -using DerCollisionWMult = soa::Join::iterator; -using DerCascDatas = soa::Join; +using DerCollisionWMults = soa::Join; +using DerCascDatas = soa::Join; using DerTraCascDatas = soa::Join; // tables for derived MC using DerMCGenCascades = soa::Join; -using DerMCRecCollision = soa::Join::iterator; -using DerMCRecCascDatas = soa::Join; +using DerMCRecCollisions = soa::Join; +using DerMCRecCascDatas = soa::Join; using DerMCRecTraCascDatas = soa::Join; // tables for PID selection @@ -66,9 +66,12 @@ struct StrangeCascTrack { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // subprocess switches: - Configurable doProcessPP{"doProcessPP", true, "true for pp, false for PbPb and OO"}; + Configurable doProcesspp{"doProcesspp", true, "true for pp"}; + Configurable doProcessPbPb{"doProcessPbPb", false, "true for PbPb"}; + Configurable doProcessOO{"doProcessOO", false, "true for OO"}; + Configurable doProcesspO{"doProcesspO", false, "true for pO"}; // selections - Configurable doApplyCuts{"doApplyCuts", true, "apply cuts"}; // dca for filtering data primaries + Configurable doApplyCuts{"doApplyCuts", true, "apply cuts"}; // general cascade cuts - dca, cosPA etc. Configurable doApplyTPCPID{"doApplyTPCPID", true, "apply tpc pid to dau tracks"}; Configurable doApplyTOFPID{"doApplyTOFPID", true, "apply tof pid to dau tracks"}; Configurable doCompetingMassRej{"doCompetingMassRej", true, "competing mass rejection for omegas"}; @@ -78,23 +81,26 @@ struct StrangeCascTrack { Configurable doApplyPurity{"doApplyPurity", false, "apply purity correction"}; Configurable doPropagatePurity{"doPropagatePurity", false, "apply purity propagation"}; Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository to use"}; - Configurable efficiencyCCDBPath{"efficiencyCCDBPath", "GLO/Config/GeometryAligned", "Path of the efficiency corrections"}; - // mc settings - Configurable doFillTruth{"doFillTruth", false, "require MC truth for reco"}; + Configurable efficiencyCCDBPath_pp{"efficiencyCCDBPath_pp", "Users/y/yparovia/LHC24f4d/Efficiency", "Path of the efficiency corrections"}; + Configurable efficiencyCCDBPath_PbPb{"efficiencyCCDBPath_PbPb", "Users/y/yparovia/LHC25f3/Efficiency", "Path of the efficiency corrections"}; + Configurable efficiencyCCDBPath_OO{"efficiencyCCDBPath_OO", "Users/y/yparovia/LHC25h3/Efficiency", "Path of the efficiency corrections"}; + Configurable efficiencyCCDBPath_pO{"efficiencyCCDBPath_pO", "Users/y/yparovia/LHC25h2/Efficiency", "Path of the efficiency corrections"}; // event and dau track selection struct : ConfigurableGroup { + Configurable cutZVertex{"cutZVertex", 10.0f, "max Z-vertex position"}; Configurable cutDCAtoPVxy{"cutDCAtoPVxy", 0.02f, "max cascade dca to PV in xy"}; Configurable cutDCAtoPVz{"cutDCAtoPVz", 0.02f, "max cascade dca to PV in z"}; - Configurable compMassRej{"compMassRej", 0.008, "Competing mass rejection"}; + Configurable compMassRej{"compMassRej", 0.008f, "Competing mass rejection"}; + Configurable cutV0CosPA{"cutV0CosPA", 0.97f, "max V0 cosPA"}; + Configurable cutBachCosPA{"cutBachCosPA", 0.97f, "max Bachelor cosPA"}; // TPC PID selection - Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; - Configurable NSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; - Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + Configurable nSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; + Configurable nSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; + Configurable nSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; // TOF PID selection - Configurable NSigmaTOFPion{"NSigmaTOFPion", 3, "NSigmaTOFPion"}; - Configurable NSigmaTOFKaon{"NSigmaTOFKaon", 3, "NSigmaTOFKaon"}; - Configurable NSigmaTOFProton{"NSigmaTOFProton", 3, "NSigmaTOFProton"}; + Configurable nSigmaTOFXi{"nSigmaTOFXi", 3, "nSigmaTOFXi"}; + Configurable nSigmaTOFOmega{"nSigmaTOFOmega", 3, "nSigmaTOFOmega"}; } selCuts; // axes @@ -104,26 +110,40 @@ struct StrangeCascTrack { ConfigurableAxis axisDCAxy{"DCA to xy plane", {500, 0., 0.5}, "cm"}; ConfigurableAxis axisDCAz{"DCA to z plane", {500, 0., 0.5}, "cm"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "p_{T} (GeV/c)"}; - ConfigurableAxis axisMult{"axisMult", {VARIABLE_WIDTH, 0.0f, 0.01f, 1.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}, "FT0 mult %"}; + ConfigurableAxis axisMult{"axisMult", {VARIABLE_WIDTH, 0.0f, 5.0, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}, "FT0 mult %"}; ConfigurableAxis axisOmegaMass{"axisOmegaMass", {2000, 1.6, 1.8}, "#Omega M_{inv} (GeV/c^{2})"}; ConfigurableAxis axisXiMass{"axisXiMass", {2000, 1.2, 1.4}, "#Xi M_{inv} (GeV/c^{2})"}; } axesConfig; - // // Filters events - // if (doFilterEvents) { - // Filter eventFilter = (o2::aod::evsel::sel8 == true); - // Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); - // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < cutzvertex); - // } + // Filters events + // Filter eventFilter = (o2::aod::evsel::sel8 == true); + // Filter posZFilter = (nabs(o2::aod::collision::posZ) < selCuts.cutZVertex); + // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < selCuts.cutZVertex); // cascade reconstruction types static constexpr std::string_view kTypeNames[] = {"Standard", "Tracked"}; // for efficiency and purity corrections - TH2F* hEfficiency; - TH2F* hEfficiencyUncertainty; - TH2F* hPurity; - TH2F* hPurityUncertainty; + TH2F* hEfficiencyOmegaStd; + TH2F* hEfficiencyOmegaTra; + TH2F* hEfficiencyXiStd; + TH2F* hEfficiencyXiTra; + + TH2F* hEfficiencyErrOmegaStd; + TH2F* hEfficiencyErrOmegaTra; + TH2F* hEfficiencyErrXiStd; + TH2F* hEfficiencyErrXiTra; + + TH2F* hPurityOmegaStd; + TH2F* hPurityOmegaTra; + TH2F* hPurityXiStd; + TH2F* hPurityXiTra; + + TH2F* hPurityErrOmegaStd; + TH2F* hPurityErrOmegaTra; + TH2F* hPurityErrXiStd; + TH2F* hPurityErrXiTra; + int mRunNumber; // loads efficiencies and purities void initEfficiencyFromCCDB(int64_t runNumber, int64_t timestamp) @@ -135,19 +155,42 @@ struct StrangeCascTrack { LOG(info) << "Loading efficiencies and purities from CCDB for run " << mRunNumber << " now..."; auto timeStamp = timestamp; + std::string efficiencyCCDBPath = [&]() { + if (doProcesspp) return efficiencyCCDBPath_pp; + if (doProcesspO) return efficiencyCCDBPath_pO; + if (doProcessPbPb) return efficiencyCCDBPath_PbPb; + if (doProcessOO) return efficiencyCCDBPath_OO; + }(); + TList* listEfficiencies = ccdb->getForTimeStamp(efficiencyCCDBPath, timeStamp); if (!listEfficiencies) { LOG(fatal) << "Problem getting TList object with efficiencies and purities!"; } - hEfficiency = static_cast(listEfficiencies->FindObject("hEfficiency")); - hPurity = static_cast(listEfficiencies->FindObject("hPurity")); - hEfficiencyUncertainty = static_cast(listEfficiencies->FindObject("hEfficiencyUncertainty")); - hPurityUncertainty = static_cast(listEfficiencies->FindObject("hPurityUncertainty")); - if (doPropagateEfficiency && !hEfficiencyUncertainty) + hEfficiencyOmegaStd = static_cast(listEfficiencies->FindObject("Eff_Omega_Standard")); + hEfficiencyOmegaTra = static_cast(listEfficiencies->FindObject("Eff_Omega_Tracked")); + hEfficiencyXiStd = static_cast(listEfficiencies->FindObject("Eff_Xi_Standard")); + hEfficiencyXiTra = static_cast(listEfficiencies->FindObject("Eff_Xi_Tracked")); + + hEfficiencyErrOmegaStd = static_cast(listEfficiencies->FindObject("EffErr_Omega_Standard")); + hEfficiencyErrOmegaTra = static_cast(listEfficiencies->FindObject("EffErr_Omega_Tracked")); + hEfficiencyErrXiStd = static_cast(listEfficiencies->FindObject("EffErr_Xi_Standard")); + hEfficiencyErrXiTra = static_cast(listEfficiencies->FindObject("EffErr_Xi_Tracked")); + + hPurityOmegaStd = static_cast(listEfficiencies->FindObject("Pur_Omega_Standard")); + hPurityOmegaTra = static_cast(listEfficiencies->FindObject("Pur_Omega_Tracked")); + hPurityXiStd = static_cast(listEfficiencies->FindObject("Pur_Xi_Standard")); + hPurityXiTra = static_cast(listEfficiencies->FindObject("Pur_Xi_Tracked")); + + hPurityErrOmegaStd = static_cast(listEfficiencies->FindObject("PurErr_Omega_Standard")); + hPurityErrOmegaTra = static_cast(listEfficiencies->FindObject("PurErr_Omega_Tracked")); + hPurityErrXiStd = static_cast(listEfficiencies->FindObject("PurErr_Xi_Standard")); + hPurityErrXiTra = static_cast(listEfficiencies->FindObject("PurErr_Xi_Tracked")); + + if (doPropagateEfficiency && (!hEfficiencyErrOmegaStd || !hEfficiencyErrOmegaTra || !hEfficiencyErrXiStd || !hEfficiencyErrXiTra)) LOG(fatal) << "Problem getting hEfficiencyUncertainty!"; - if (doPropagatePurity && !hPurityUncertainty) + if (doPropagatePurity && (!hPurityErrOmegaStd || !hPurityErrOmegaTra || !hPurityErrXiStd || !hPurityErrXiTra)) LOG(fatal) << "Problem getting hPurityUncertainty!"; LOG(info) << "Efficiencies and purities now loaded for " << mRunNumber; } @@ -156,7 +199,7 @@ struct StrangeCascTrack { void fillEvents(TEvent const& collision) { histos.fill(HIST("Events/EvCounter"), 0.5); - double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); + double mult = (doProcesspp || doProcesspO) ? collision.centFT0M() : collision.centFT0C(); histos.fill(HIST("Events/Mult"), mult); double pvx = collision.posX(); double pvy = collision.posY(); @@ -166,13 +209,17 @@ struct StrangeCascTrack { histos.fill(HIST("Events/PVz"), pvz); } // checks general selection criteria - template - bool isValidCasc(TCascade cascade) + template + bool isValidCasc(TEvent collision, TCascade cascade) { if (cascade.dcaXYCascToPV() > selCuts.cutDCAtoPVxy) return false; if (cascade.dcaZCascToPV() > selCuts.cutDCAtoPVz) return false; + if (cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < selCuts.cutV0CosPA) + return false; + if (cascade.bachBaryonCosPA() < selCuts.cutBachCosPA) + return false; return true; } // checks TPC PID of dau tracks @@ -182,88 +229,29 @@ struct StrangeCascTrack { const auto& posDaughterTrackCasc = cascade.template posTrackExtra_as(); const auto& negDaughterTrackCasc = cascade.template negTrackExtra_as(); if (cascade.sign() < 0) { - if (std::abs(posDaughterTrackCasc.tpcNSigmaPr()) > selCuts.NSigmaTPCProton) { + if (std::abs(posDaughterTrackCasc.tpcNSigmaPr()) > selCuts.nSigmaTPCProton) { return false; } - if (std::abs(negDaughterTrackCasc.tpcNSigmaPi()) > selCuts.NSigmaTPCPion) { + if (std::abs(negDaughterTrackCasc.tpcNSigmaPi()) > selCuts.nSigmaTPCPion) { return false; } } else { - if (std::abs(negDaughterTrackCasc.tpcNSigmaPr()) > selCuts.NSigmaTPCProton) { + if (std::abs(negDaughterTrackCasc.tpcNSigmaPr()) > selCuts.nSigmaTPCProton) { return false; } - if (std::abs(posDaughterTrackCasc.tpcNSigmaPi()) > selCuts.NSigmaTPCPion) { + if (std::abs(posDaughterTrackCasc.tpcNSigmaPi()) > selCuts.nSigmaTPCPion) { return false; } } return true; } // checks TOF PID of dau tracks - // template - // bool passesTOF(TCascade cascade, TString particle) - // { - // return true; - // // const auto& bachDaughterTrackCasc = cascade.bachTrackExtra_as(); - // // const auto& posDaughterTrackCasc = cascade.posTrackExtra_as(); - // // const auto& negDaughterTrackCasc = cascade.negTrackExtra_as(); - // // bool xiPassTOFSelection = true; - // // bool omegaPassTOFSelection = true; - // // if (cascade.sign() < 0) { - // // if (posDaughterTrackCasc.hasTOF()) { - // // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { - // // xiPassTOFSelection &= false; - // // } - // // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { - // // omegaPassTOFSelection &= false; - // // } - // // } - // // if (negDaughterTrackCasc.hasTOF()) { - // // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { - // // xiPassTOFSelection &= false; - // // } - // // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { - // // omegaPassTOFSelection &= false; - // // } - // // } - // // } else { - // // if (posDaughterTrackCasc.hasTOF()) { - // // if (std::abs(cascade.tofNSigmaXiLaPi()) > selCuts.NSigmaTOFPion) { - // // xiPassTOFSelection &= false; - // // } - // // if (std::abs(cascade.tofNSigmaOmLaPi()) > selCuts.NSigmaTOFPion) { - // // omegaPassTOFSelection &= false; - // // } - // // } - // // if (negDaughterTrackCasc.hasTOF()) { - // // if (std::abs(cascade.tofNSigmaXiLaPr()) > selCuts.NSigmaTOFProton) { - // // xiPassTOFSelection &= false; - // // } - // // if (std::abs(cascade.tofNSigmaOmLaPr()) > selCuts.NSigmaTOFProton) { - // // omegaPassTOFSelection &= false; - // // } - // // } - // // } - // - // // if (bachDaughterTrackCasc.hasTOF()) { - // // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { - // // xiPassTOFSelection &= false; - // // } - // // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { - // // omegaPassTOFSelection &= false; - // // } - // // } - // - // // if (bachDaughterTrackCasc.hasTOF()) { - // // if (std::abs(cascade.tofNSigmaXiPi()) > selCuts.NSigmaTOFPion) { - // // xiPassTOFSelection &= false; - // // } - // // if (std::abs(cascade.tofNSigmaOmKa()) > selCuts.NSigmaTOFKaon) { - // // omegaPassTOFSelection &= false; - // // } - // // } - // - // // if (particle == "xi") {return xiPassTOFSelection;} else {return omegaPassTOFSelection;} - // } + template + bool passesTOF(TCascade cascade, TString particle) + { + if (particle == "xi") return cascade.tofXiCompatibility(selCuts.nSigmaTOFXi); + if (particle == "omega") return cascade.tofOmegaCompatibility(selCuts.nSigmaTOFOmega); + } // checks whether gen cascade corresponds to PDG code template bool isValidPDG(TCascade cascade, TString particle) @@ -337,111 +325,176 @@ struct StrangeCascTrack { } }(); - double mult = doProcessPP ? collision.centFT0M() : collision.centFT0C(); // ion collisions use FT0C for multiplicity, pp uses both + double mult = (doProcesspp || doProcesspO) ? collision.centFT0M() : collision.centFT0C(); // ion collisions use FT0C for multiplicity, pp uses both + + float efficiencyOmega = 1.0f; + float efficiencyXi = 1.0f; + float efficiencyOmegaErr = 0.0f; + float efficiencyXiErr = 0.0f; + float purityOmega = 1.0f; + float purityXi = 1.0f; + float purityOmegaErr = 0.0f; + float purityXiErr = 0.0f; - float efficiency = 1.0f; - float efficiencyError = 0.0f; - float purity = 1.0f; - float purityError = 0.0f; if (doApplyEfficiency) { - efficiency = hEfficiency->Interpolate(cascade.pt(), mult); - if (doPropagateEfficiency) { - efficiencyError = hEfficiencyUncertainty->Interpolate(cascade.pt(), mult); - } - if (efficiency == 0) { // check for zero efficiency, do not apply if the case - efficiency = 1.; - efficiencyError = 0.; + if constexpr (requires { cascade.topologyChi2(); }) { + efficiencyOmega = hEfficiencyOmegaTra->Interpolate(cascade.pt(), mult); + efficiencyXi = hEfficiencyXiTra->Interpolate(cascade.pt(), mult); + if (doPropagateEfficiency) { + efficiencyOmegaErr = hEfficiencyErrOmegaTra->Interpolate(cascade.pt(), mult); + efficiencyXiErr = hEfficiencyErrXiTra->Interpolate(cascade.pt(), mult); + } + if (efficiencyOmega == 0) { // check for zero efficiency, do not apply if the case + efficiencyOmega = 1.; + efficiencyOmegaErr = 0.; + } + if (efficiencyXi == 0) { // check for zero efficiency, do not apply if the case + efficiencyXi = 1.; + efficiencyXiErr = 0.; + } + } else { + efficiencyOmega = hEfficiencyOmegaStd->Interpolate(cascade.pt(), mult); + efficiencyXi = hEfficiencyXiStd->Interpolate(cascade.pt(), mult); + if (doPropagateEfficiency) { + efficiencyOmegaErr = hEfficiencyErrOmegaStd->Interpolate(cascade.pt(), mult); + efficiencyXiErr = hEfficiencyErrXiStd->Interpolate(cascade.pt(), mult); + } + if (efficiencyOmega == 0) { // check for zero efficiency, do not apply if the case + efficiencyOmega = 1.; + efficiencyOmegaErr = 0.; + } + if (efficiencyXi == 0) { // check for zero efficiency, do not apply if the case + efficiencyXi = 1.; + efficiencyXiErr = 0.; + } + } } + if (doApplyPurity) { - purity = hPurity->Interpolate(cascade.pt(), mult); - if (doPropagatePurity) { - purityError = hPurityUncertainty->Interpolate(cascade.pt(), mult); - } - if (purity == 0) { // check for zero purity, do not apply if the case - purity = 1.; - purityError = 0.; + if constexpr (requires { cascade.topologyChi2(); }) { + purityOmega = hPurityOmegaTra->Interpolate(cascade.pt(), mult); + purityXi = hPurityXiTra->Interpolate(cascade.pt(), mult); + if (doPropagatePurity) { + purityOmegaErr = hPurityErrOmegaTra->Interpolate(cascade.pt(), mult); + purityXiErr = hPurityErrXiTra->Interpolate(cascade.pt(), mult); + } + if (purityOmega == 0) { // check for zero purity, do not apply if the case + purityOmega = 1.; + purityOmegaErr = 0.; + } + if (purityXi == 0) { // check for zero purity, do not apply if the case + purityXi = 1.; + purityXiErr = 0.; + } + } else { + purityOmega = hPurityOmegaStd->Interpolate(cascade.pt(), mult); + purityXi = hPurityXiStd->Interpolate(cascade.pt(), mult); + if (doPropagatePurity) { + purityOmegaErr = hPurityErrOmegaStd->Interpolate(cascade.pt(), mult); + purityXiErr = hPurityErrXiStd->Interpolate(cascade.pt(), mult); + } + if (purityOmega == 0) { // check for zero purity, do not apply if the case + purityOmega = 1.; + purityOmegaErr = 0.; + } + if (purityXi == 0) { // check for zero purity, do not apply if the case + purityXi = 1.; + purityXiErr = 0.; + } } } if (collision.index() != casccollid) { - histos.fill(HIST(kTypeNames[type]) + HIST("/EvMult"), mult); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/EvMult"), mult); casccollid = collision.index(); } double massXi = cascade.mXi(); double massOmega = cascade.mOmega(); double pt = cascade.pt(); - - histos.fill(HIST(kTypeNames[type]) + HIST("/DCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/DCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/Phi"), cascade.phi()); - histos.fill(HIST(kTypeNames[type]) + HIST("/Eta"), cascade.eta()); - histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiNoSel"), massXi); - histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaNoSel"), massOmega); + double v0cosPA = stdCasc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()); + + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/DCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/DCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/Phi"), cascade.phi()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/Eta"), cascade.eta()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/V0CosPA"), v0cosPA); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/MassXi"), massXi); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/MassOmega"), massOmega); + + if constexpr (requires { collision.straMCCollisionId(); }) { + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Phi"), cascade.phi()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Eta"), cascade.eta()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/EvMult"), mult); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/V0CosPA"), v0cosPA); + if (isMCTruth(stdCasc, "xi")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassXi"), massXi); + if (isMCTruth(stdCasc, "omega")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); + }} // start checking selections bool passedAllSels = true; // apply general selection criteria if (doApplyCuts) { - if (isValidCasc(cascade)) { - histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiGenSel"), massXi); - histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaGenSel"), massOmega); - } else { - passedAllSels = false; - } + if (!isValidCasc(collision, stdCasc)) passedAllSels = false; } // apply tpc pid if (doApplyTPCPID) { - if (passesTPC(stdCasc)) { - histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTPCPID"), massXi); - histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTPCPID"), massOmega); - } else { - passedAllSels = false; - } + if (!passesTPC(stdCasc)) passedAllSels = false; } // apply tof pid bool passedAllSelsXi = passedAllSels; bool passedAllSelsOmega = passedAllSels; - // if (doApplyTOFPID) { - // if (passesTOF(cascade, "xi")) { - // histos.fill(HIST(kTypeNames[type]) + HIST("/MassXiTOFPID"), massXi); - // } else { - // passedAllSelsXi = false; - // } - // if (passesTOF(cascade, "omega")) { - // histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaTOFPID"), massOmega); - // } else { - // passedAllSelsOmega = false; - // } - // } + if (doApplyTOFPID) { + if (!passesTOF(stdCasc, "xi")) passedAllSelsXi = false; + if (!passesTOF(stdCasc, "omega")) passedAllSelsOmega = false; + } // apply competing mass rej if (doCompetingMassRej) { - if (std::abs(massXi - pdgDB->Mass(3312)) > selCuts.compMassRej) { - histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmegaMassSel"), massOmega); - } else { - passedAllSelsOmega = false; - } + if (!(std::abs(massXi - pdgDB->Mass(3312)) > selCuts.compMassRej)) passedAllSelsOmega = false; } - // fill w/ cascs that passed all applied sels + // fill truth w/ cascs that passed all applied sels double binFillXi[3] = {massXi, pt, mult}; + + if constexpr (requires { collision.straMCCollisionId(); }) { + if (passedAllSels && (passedAllSelsXi || passedAllSelsOmega)) { // fill once for every desired cascade + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Phi"), cascade.phi()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Eta"), cascade.eta()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/EvMult"), mult); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/V0CosPA"), v0cosPA); + }}} + + // fill rec if (passedAllSelsXi) { - histos.fill(HIST(kTypeNames[type]) + HIST("/MassXi"), massXi); - fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Xi")), binFillXi, efficiency, efficiencyError, purity, purityError); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec/MassXi"), massXi); + fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Rec/Xi")), binFillXi, efficiencyXi, efficiencyXiErr, purityXi, purityXiErr); if constexpr (requires { collision.straMCCollisionId(); }) { - if (doFillTruth && isMCTruth(stdCasc, "xi")) - histos.fill(HIST("MC/RecTruth/") + HIST(kTypeNames[type]) + HIST("/Xi"), massXi, pt, mult); - } + if (isMCTruth(stdCasc, "xi")) { + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassXi"), massXi); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Xi"), massXi, pt, mult); + }} } double binFillOmega[3] = {massOmega, pt, mult}; if (passedAllSelsOmega) { - histos.fill(HIST(kTypeNames[type]) + HIST("/MassOmega"), massOmega); - fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Omega")), binFillOmega, efficiency, efficiencyError, purity, purityError); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec/MassOmega"), massOmega); + fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Rec/Omega")), binFillOmega, efficiencyOmega, efficiencyOmegaErr, purityOmega, purityOmegaErr); if constexpr (requires { collision.straMCCollisionId(); }) { - if (doFillTruth && isMCTruth(stdCasc, "omega")) - histos.fill(HIST("MC/RecTruth/") + HIST(kTypeNames[type]) + HIST("/Omega"), massOmega, pt, mult); - } + if (isMCTruth(stdCasc, "omega")) { + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassOmega"), massOmega); + histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Omega"), massOmega, pt, mult); + }} } } } @@ -456,44 +509,58 @@ struct StrangeCascTrack { histos.add("Events/Mult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // for cascade processing static_for<0, 1>([&](auto type) { - histos.add(Form("%s/Phi", kTypeNames[type].data()), "Phi", kTH1F, {axesConfig.axisPhi}); - histos.add(Form("%s/Eta", kTypeNames[type].data()), "Eta", kTH1F, {axesConfig.axisEta}); - histos.add(Form("%s/DCAxy", kTypeNames[type].data()), "DCA to xy", kTH1F, {axesConfig.axisDCAxy}); - histos.add(Form("%s/DCAz", kTypeNames[type].data()), "DCA to z", kTH1F, {axesConfig.axisDCAz}); - histos.add(Form("%s/EvMult", kTypeNames[type].data()), "Multiplicity of events with >=1 cascade", kTH1F, {axesConfig.axisMult}); - // no selection applied - histos.add(Form("%s/MassOmegaNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiNoSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only gen selection applied - histos.add(Form("%s/MassOmegaGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiGenSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only tpc pid selection applied - histos.add(Form("%s/MassOmegaTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiTPCPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only tof pid selection applied - histos.add(Form("%s/MassOmegaTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXiTOFPID", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - // only competing mass rejection selection applied - histos.add(Form("%s/MassOmegaMassSel", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + // no selections applied + histos.add(Form("%s/NoSel/Phi", kTypeNames[type].data()), "Phi", kTH1F, {axesConfig.axisPhi}); + histos.add(Form("%s/NoSel/Eta", kTypeNames[type].data()), "Eta", kTH1F, {axesConfig.axisEta}); + histos.add(Form("%s/NoSel/DCAxy", kTypeNames[type].data()), "DCA to xy", kTH1F, {axesConfig.axisDCAxy}); + histos.add(Form("%s/NoSel/DCAz", kTypeNames[type].data()), "DCA to z", kTH1F, {axesConfig.axisDCAz}); + histos.add(Form("%s/NoSel/BachCosPA", kTypeNames[type].data()), "Bachelor cosPA", kTH1F, {{202, -1.1, 1.1}}); + histos.add(Form("%s/NoSel/V0CosPA", kTypeNames[type].data()), "V0 cosPA", kTH1F, {{202, -1.1, 1.1}}); + histos.add(Form("%s/NoSel/EvMult", kTypeNames[type].data()), "Multiplicity of events with >=1 cascade", kTH1F, {axesConfig.axisMult}); + histos.add(Form("%s/NoSel/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + histos.add(Form("%s/NoSel/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + // mc truth for no selectrion + histos.add(Form("%s/NoSel-Truth/Phi", kTypeNames[type].data()), "Phi", kTH1F, {axesConfig.axisPhi}); + histos.add(Form("%s/NoSel-Truth/Eta", kTypeNames[type].data()), "Eta", kTH1F, {axesConfig.axisEta}); + histos.add(Form("%s/NoSel-Truth/DCAxy", kTypeNames[type].data()), "DCA to xy", kTH1F, {axesConfig.axisDCAxy}); + histos.add(Form("%s/NoSel-Truth/DCAz", kTypeNames[type].data()), "DCA to z", kTH1F, {axesConfig.axisDCAz}); + histos.add(Form("%s/NoSel-Truth/DCAzVSpt", kTypeNames[type].data()), "DCA to z vs pT", kTH2F, {axesConfig.axisPt, axesConfig.axisDCAz}); + histos.add(Form("%s/NoSel-Truth/BachCosPA", kTypeNames[type].data()), "Bachelor cosPA", kTH1F, {{202, -1.1, 1.1}}); + histos.add(Form("%s/NoSel-Truth/V0CosPA", kTypeNames[type].data()), "V0 cosPA", kTH1F, {{202, -1.1, 1.1}}); + histos.add(Form("%s/NoSel-Truth/EvMult", kTypeNames[type].data()), "Multiplicity of events with >=1 cascade", kTH1F, {axesConfig.axisMult}); + histos.add(Form("%s/NoSel-Truth/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + histos.add(Form("%s/NoSel-Truth/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); // passed all applied sels - histos.add(Form("%s/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); - histos.add(Form("%s/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); - histos.add(Form("%s/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); - histos.add(Form("%s/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/Rec/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + histos.add(Form("%s/Rec/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + // mc truth for all passed selections + histos.add(Form("%s/Rec-Truth/Phi", kTypeNames[type].data()), "Phi", kTH1F, {axesConfig.axisPhi}); + histos.add(Form("%s/Rec-Truth/Eta", kTypeNames[type].data()), "Eta", kTH1F, {axesConfig.axisEta}); + histos.add(Form("%s/Rec-Truth/DCAxy", kTypeNames[type].data()), "DCA to xy", kTH1F, {axesConfig.axisDCAxy}); + histos.add(Form("%s/Rec-Truth/DCAz", kTypeNames[type].data()), "DCA to z", kTH1F, {axesConfig.axisDCAz}); + histos.add(Form("%s/Rec-Truth/DCAzVSpt", kTypeNames[type].data()), "DCA to z vs pT", kTH2F, {axesConfig.axisPt, axesConfig.axisDCAz}); + histos.add(Form("%s/Rec-Truth/BachCosPA", kTypeNames[type].data()), "Bachelor cosPA", kTH1F, {{202, -1.1, 1.1}}); + histos.add(Form("%s/Rec-Truth/V0CosPA", kTypeNames[type].data()), "V0 cosPA", kTH1F, {{202, -1.1, 1.1}}); + histos.add(Form("%s/Rec-Truth/EvMult", kTypeNames[type].data()), "Multiplicity of events with >=1 cascade", kTH1F, {axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/MassXi", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisXiMass}); + histos.add(Form("%s/Rec-Truth/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); + histos.add(Form("%s/Rec-Truth/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add(Form("%s/Rec-Truth/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + }); // for MC-specific processing histos.add("MC/Gen/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); - histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis - histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Omegas - histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); - histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); - histos.add("MC/RecTruth/Standard/Omega", "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); - histos.add("MC/RecTruth/Standard/Xi", "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); - histos.add("MC/RecTruth/Tracked/Omega", "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); - histos.add("MC/RecTruth/Tracked/Xi", "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Xis + histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Omegas + histos.add("MC/Gen/PrimaryXi", "Xi primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis + histos.add("MC/Gen/PrimaryOmega", "Omega primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Omegas + histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); // counter of all recreated events + histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // multiplicity of all recreated events } - void processDerivedData(DerCollisionWMult const& collision, DerCascDatas const& allCascs, DerTraCascDatas const& traCascs, DauTracks const&) + void processDerivedData(DerCollisionWMults::iterator const& collision, DerCascDatas const& allCascs, DerTraCascDatas const& traCascs, DauTracks const&) { fillEvents(collision); // save info about all processed events if (doApplyEfficiency) { @@ -511,25 +578,29 @@ struct StrangeCascTrack { auto slicedRecColls = recColls.sliceBy(perMcCollision, genColl.globalIndex()); for (auto const& recColl : slicedRecColls) { histos.fill(HIST("MC/Rec/EvCounter"), 0.5); - double casc_mult = doProcessPP ? recColl.centFT0M() : recColl.centFT0C(); + double casc_mult = (doProcesspp || doProcesspO) ? recColl.centFT0M() : recColl.centFT0C(); histos.fill(HIST("MC/Rec/EvMult"), casc_mult); int64_t genCollId = recColl.straMCCollisionId(); for (auto const& casc : genCascs) { if (casc.straMCCollisionId() != genCollId) continue; // safety check - if (!casc.isPhysicalPrimary()) - continue; // skip non-primary particles double casc_pt = std::sqrt(std::pow(casc.pxMC(), 2) + std::pow(casc.pyMC(), 2)); if (isValidPDG(casc, "xi")) histos.fill(HIST("MC/Gen/Xi"), casc_pt, casc_mult); if (isValidPDG(casc, "omega")) histos.fill(HIST("MC/Gen/Omega"), casc_pt, casc_mult); + if (casc.isPhysicalPrimary()) { + if (isValidPDG(casc, "xi")) + histos.fill(HIST("MC/Gen/PrimaryXi"), casc_pt, casc_mult); + if (isValidPDG(casc, "omega")) + histos.fill(HIST("MC/Gen/PrimaryOmega"), casc_pt, casc_mult); + } } } } } - void processDerivedMCRec(DerMCRecCollision const& collision, DerMCRecCascDatas const& allCascs, DerMCRecTraCascDatas const& traCascs, DauTracks const&, DerMCGenCascades const&) + void processDerivedMCRec(DerMCRecCollisions::iterator const& collision, DerMCRecCascDatas const& allCascs, DerMCRecTraCascDatas const& traCascs, DauTracks const&, DerMCGenCascades const&) { fillEvents(collision); // save info about all processed events if (doApplyEfficiency) { From 9604409d9ac139554544b03473fc0f0769b213a3 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 06:16:47 +0100 Subject: [PATCH 10/17] Formatting check --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 2b9cb88262d..940243aa412 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -256,10 +256,9 @@ struct StrangeCascTrack { template bool isValidPDG(TCascade cascade, TString particle) { - static constexpr int kPdgCodes[] = {3312, 3334}; // "XiMinus", "OmegaMinus" - if (particle == "xi" && std::abs(cascade.pdgCode()) == kPdgCodes[0]) + if (particle == "xi" && std::abs(cascade.pdgCode()) == PDG_t::kXiMinus) return true; - if (particle == "omega" && std::abs(cascade.pdgCode()) == kPdgCodes[1]) + if (particle == "omega" && std::abs(cascade.pdgCode()) == PDG_t::kOmegaMinus) return true; return false; } @@ -273,9 +272,9 @@ struct StrangeCascTrack { return false; int pdg = std::abs(cascmccore.pdgCode()); if (particle == "xi") - return (pdg == 3312); + return (pdg == PDG_t::kXiMinus); if (particle == "omega") - return (pdg == 3334); + return (pdg == PDG_t::kOmegaMinus); } return false; } @@ -457,7 +456,7 @@ struct StrangeCascTrack { } // apply competing mass rej if (doCompetingMassRej) { - if (!(std::abs(massXi - pdgDB->Mass(3312)) > selCuts.compMassRej)) passedAllSelsOmega = false; + if (!(std::abs(massXi - o2::constants::physics::MassXiMinus) > selCuts.compMassRej)) passedAllSelsOmega = false; } // fill truth w/ cascs that passed all applied sels From 6817b80117b69ad4e4eac66513c9bc50ed259607 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 06:19:12 +0100 Subject: [PATCH 11/17] Formatting check --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 92 ++++++++++++-------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 940243aa412..a795f3d3e5d 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -116,9 +116,9 @@ struct StrangeCascTrack { } axesConfig; // Filters events - // Filter eventFilter = (o2::aod::evsel::sel8 == true); - // Filter posZFilter = (nabs(o2::aod::collision::posZ) < selCuts.cutZVertex); - // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < selCuts.cutZVertex); + // Filter eventFilter = (o2::aod::evsel::sel8 == true); + // Filter posZFilter = (nabs(o2::aod::collision::posZ) < selCuts.cutZVertex); + // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < selCuts.cutZVertex); // cascade reconstruction types static constexpr std::string_view kTypeNames[] = {"Standard", "Tracked"}; @@ -156,10 +156,14 @@ struct StrangeCascTrack { auto timeStamp = timestamp; std::string efficiencyCCDBPath = [&]() { - if (doProcesspp) return efficiencyCCDBPath_pp; - if (doProcesspO) return efficiencyCCDBPath_pO; - if (doProcessPbPb) return efficiencyCCDBPath_PbPb; - if (doProcessOO) return efficiencyCCDBPath_OO; + if (doProcesspp) + return efficiencyCCDBPath_pp; + if (doProcesspO) + return efficiencyCCDBPath_pO; + if (doProcessPbPb) + return efficiencyCCDBPath_PbPb; + if (doProcessOO) + return efficiencyCCDBPath_OO; }(); TList* listEfficiencies = ccdb->getForTimeStamp(efficiencyCCDBPath, timeStamp); @@ -249,8 +253,10 @@ struct StrangeCascTrack { template bool passesTOF(TCascade cascade, TString particle) { - if (particle == "xi") return cascade.tofXiCompatibility(selCuts.nSigmaTOFXi); - if (particle == "omega") return cascade.tofOmegaCompatibility(selCuts.nSigmaTOFOmega); + if (particle == "xi") + return cascade.tofXiCompatibility(selCuts.nSigmaTOFXi); + if (particle == "omega") + return cascade.tofOmegaCompatibility(selCuts.nSigmaTOFOmega); } // checks whether gen cascade corresponds to PDG code template @@ -366,10 +372,9 @@ struct StrangeCascTrack { efficiencyXi = 1.; efficiencyXiErr = 0.; } - } } - + if (doApplyPurity) { if constexpr (requires { cascade.topologyChi2(); }) { purityOmega = hPurityOmegaTra->Interpolate(cascade.pt(), mult); @@ -424,39 +429,47 @@ struct StrangeCascTrack { histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/MassOmega"), massOmega); if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Phi"), cascade.phi()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Eta"), cascade.eta()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/EvMult"), mult); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/V0CosPA"), v0cosPA); - if (isMCTruth(stdCasc, "xi")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassXi"), massXi); - if (isMCTruth(stdCasc, "omega")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); - }} + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Phi"), cascade.phi()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Eta"), cascade.eta()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/EvMult"), mult); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/V0CosPA"), v0cosPA); + if (isMCTruth(stdCasc, "xi")) + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassXi"), massXi); + if (isMCTruth(stdCasc, "omega")) + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); + } + } // start checking selections bool passedAllSels = true; // apply general selection criteria if (doApplyCuts) { - if (!isValidCasc(collision, stdCasc)) passedAllSels = false; + if (!isValidCasc(collision, stdCasc)) + passedAllSels = false; } // apply tpc pid if (doApplyTPCPID) { - if (!passesTPC(stdCasc)) passedAllSels = false; + if (!passesTPC(stdCasc)) + passedAllSels = false; } // apply tof pid bool passedAllSelsXi = passedAllSels; bool passedAllSelsOmega = passedAllSels; if (doApplyTOFPID) { - if (!passesTOF(stdCasc, "xi")) passedAllSelsXi = false; - if (!passesTOF(stdCasc, "omega")) passedAllSelsOmega = false; + if (!passesTOF(stdCasc, "xi")) + passedAllSelsXi = false; + if (!passesTOF(stdCasc, "omega")) + passedAllSelsOmega = false; } // apply competing mass rej if (doCompetingMassRej) { - if (!(std::abs(massXi - o2::constants::physics::MassXiMinus) > selCuts.compMassRej)) passedAllSelsOmega = false; + if (!(std::abs(massXi - o2::constants::physics::MassXiMinus) > selCuts.compMassRej)) + passedAllSelsOmega = false; } // fill truth w/ cascs that passed all applied sels @@ -464,7 +477,7 @@ struct StrangeCascTrack { if constexpr (requires { collision.straMCCollisionId(); }) { if (passedAllSels && (passedAllSelsXi || passedAllSelsOmega)) { // fill once for every desired cascade - if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAxy"), cascade.dcaXYCascToPV()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAz"), cascade.dcaZCascToPV()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); @@ -473,17 +486,20 @@ struct StrangeCascTrack { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/EvMult"), mult); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/V0CosPA"), v0cosPA); - }}} + } + } + } // fill rec if (passedAllSelsXi) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec/MassXi"), massXi); fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Rec/Xi")), binFillXi, efficiencyXi, efficiencyXiErr, purityXi, purityXiErr); if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "xi")) { + if (isMCTruth(stdCasc, "xi")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassXi"), massXi); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Xi"), massXi, pt, mult); - }} + } + } } double binFillOmega[3] = {massOmega, pt, mult}; if (passedAllSelsOmega) { @@ -493,7 +509,8 @@ struct StrangeCascTrack { if (isMCTruth(stdCasc, "omega")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassOmega"), massOmega); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Omega"), massOmega, pt, mult); - }} + } + } } } } @@ -547,16 +564,15 @@ struct StrangeCascTrack { histos.add(Form("%s/Rec-Truth/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); histos.add(Form("%s/Rec-Truth/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); histos.add(Form("%s/Rec-Truth/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); - }); // for MC-specific processing histos.add("MC/Gen/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); - histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Xis - histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Omegas + histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Xis + histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Omegas histos.add("MC/Gen/PrimaryXi", "Xi primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis histos.add("MC/Gen/PrimaryOmega", "Omega primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Omegas - histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); // counter of all recreated events - histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // multiplicity of all recreated events + histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); // counter of all recreated events + histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // multiplicity of all recreated events } void processDerivedData(DerCollisionWMults::iterator const& collision, DerCascDatas const& allCascs, DerTraCascDatas const& traCascs, DauTracks const&) From 2979f7067b25fff32e3390c111e2fd5fef4ebd4f Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 06:48:32 +0100 Subject: [PATCH 12/17] Event filter --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 95 +++++++++----------- 1 file changed, 41 insertions(+), 54 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index a795f3d3e5d..4017da0a138 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -116,9 +116,9 @@ struct StrangeCascTrack { } axesConfig; // Filters events - // Filter eventFilter = (o2::aod::evsel::sel8 == true); - // Filter posZFilter = (nabs(o2::aod::collision::posZ) < selCuts.cutZVertex); - // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < selCuts.cutZVertex); + // Filter eventFilter = (o2::aod::evsel::sel8 == true); + // Filter posZFilter = (nabs(o2::aod::collision::posZ) < selCuts.cutZVertex); + // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < selCuts.cutZVertex); // cascade reconstruction types static constexpr std::string_view kTypeNames[] = {"Standard", "Tracked"}; @@ -156,14 +156,10 @@ struct StrangeCascTrack { auto timeStamp = timestamp; std::string efficiencyCCDBPath = [&]() { - if (doProcesspp) - return efficiencyCCDBPath_pp; - if (doProcesspO) - return efficiencyCCDBPath_pO; - if (doProcessPbPb) - return efficiencyCCDBPath_PbPb; - if (doProcessOO) - return efficiencyCCDBPath_OO; + if (doProcesspp) return efficiencyCCDBPath_pp; + if (doProcesspO) return efficiencyCCDBPath_pO; + if (doProcessPbPb) return efficiencyCCDBPath_PbPb; + if (doProcessOO) return efficiencyCCDBPath_OO; }(); TList* listEfficiencies = ccdb->getForTimeStamp(efficiencyCCDBPath, timeStamp); @@ -216,6 +212,8 @@ struct StrangeCascTrack { template bool isValidCasc(TEvent collision, TCascade cascade) { + if (std::abs(collision.posZ()) > selCuts.cutZVertex) + return false; if (cascade.dcaXYCascToPV() > selCuts.cutDCAtoPVxy) return false; if (cascade.dcaZCascToPV() > selCuts.cutDCAtoPVz) @@ -253,10 +251,9 @@ struct StrangeCascTrack { template bool passesTOF(TCascade cascade, TString particle) { - if (particle == "xi") - return cascade.tofXiCompatibility(selCuts.nSigmaTOFXi); - if (particle == "omega") - return cascade.tofOmegaCompatibility(selCuts.nSigmaTOFOmega); + if (particle == "xi") return cascade.tofXiCompatibility(selCuts.nSigmaTOFXi); + if (particle == "omega") return cascade.tofOmegaCompatibility(selCuts.nSigmaTOFOmega); + return true; } // checks whether gen cascade corresponds to PDG code template @@ -372,9 +369,10 @@ struct StrangeCascTrack { efficiencyXi = 1.; efficiencyXiErr = 0.; } + } } - + if (doApplyPurity) { if constexpr (requires { cascade.topologyChi2(); }) { purityOmega = hPurityOmegaTra->Interpolate(cascade.pt(), mult); @@ -429,47 +427,39 @@ struct StrangeCascTrack { histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/MassOmega"), massOmega); if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Phi"), cascade.phi()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Eta"), cascade.eta()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/EvMult"), mult); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/V0CosPA"), v0cosPA); - if (isMCTruth(stdCasc, "xi")) - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassXi"), massXi); - if (isMCTruth(stdCasc, "omega")) - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); - } - } + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Phi"), cascade.phi()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Eta"), cascade.eta()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/EvMult"), mult); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/V0CosPA"), v0cosPA); + if (isMCTruth(stdCasc, "xi")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassXi"), massXi); + if (isMCTruth(stdCasc, "omega")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); + }} // start checking selections bool passedAllSels = true; // apply general selection criteria if (doApplyCuts) { - if (!isValidCasc(collision, stdCasc)) - passedAllSels = false; + if (!isValidCasc(collision, stdCasc)) passedAllSels = false; } // apply tpc pid if (doApplyTPCPID) { - if (!passesTPC(stdCasc)) - passedAllSels = false; + if (!passesTPC(stdCasc)) passedAllSels = false; } // apply tof pid bool passedAllSelsXi = passedAllSels; bool passedAllSelsOmega = passedAllSels; if (doApplyTOFPID) { - if (!passesTOF(stdCasc, "xi")) - passedAllSelsXi = false; - if (!passesTOF(stdCasc, "omega")) - passedAllSelsOmega = false; + if (!passesTOF(stdCasc, "xi")) passedAllSelsXi = false; + if (!passesTOF(stdCasc, "omega")) passedAllSelsOmega = false; } // apply competing mass rej if (doCompetingMassRej) { - if (!(std::abs(massXi - o2::constants::physics::MassXiMinus) > selCuts.compMassRej)) - passedAllSelsOmega = false; + if (!(std::abs(massXi - o2::constants::physics::MassXiMinus) > selCuts.compMassRej)) passedAllSelsOmega = false; } // fill truth w/ cascs that passed all applied sels @@ -477,7 +467,7 @@ struct StrangeCascTrack { if constexpr (requires { collision.straMCCollisionId(); }) { if (passedAllSels && (passedAllSelsXi || passedAllSelsOmega)) { // fill once for every desired cascade - if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAxy"), cascade.dcaXYCascToPV()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAz"), cascade.dcaZCascToPV()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); @@ -486,20 +476,17 @@ struct StrangeCascTrack { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/EvMult"), mult); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/V0CosPA"), v0cosPA); - } - } - } + }}} // fill rec if (passedAllSelsXi) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec/MassXi"), massXi); fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Rec/Xi")), binFillXi, efficiencyXi, efficiencyXiErr, purityXi, purityXiErr); if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "xi")) { + if (isMCTruth(stdCasc, "xi")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassXi"), massXi); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Xi"), massXi, pt, mult); - } - } + }} } double binFillOmega[3] = {massOmega, pt, mult}; if (passedAllSelsOmega) { @@ -509,8 +496,7 @@ struct StrangeCascTrack { if (isMCTruth(stdCasc, "omega")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassOmega"), massOmega); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Omega"), massOmega, pt, mult); - } - } + }} } } } @@ -564,15 +550,16 @@ struct StrangeCascTrack { histos.add(Form("%s/Rec-Truth/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); histos.add(Form("%s/Rec-Truth/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); histos.add(Form("%s/Rec-Truth/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); + }); // for MC-specific processing histos.add("MC/Gen/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); - histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Xis - histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Omegas + histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Xis + histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Omegas histos.add("MC/Gen/PrimaryXi", "Xi primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis histos.add("MC/Gen/PrimaryOmega", "Omega primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Omegas - histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); // counter of all recreated events - histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // multiplicity of all recreated events + histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); // counter of all recreated events + histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // multiplicity of all recreated events } void processDerivedData(DerCollisionWMults::iterator const& collision, DerCascDatas const& allCascs, DerTraCascDatas const& traCascs, DauTracks const&) From 5c1d44abb08bd0869829e8acd65837bbb666c691 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 06:48:54 +0100 Subject: [PATCH 13/17] Event filter - formatting --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 91 ++++++++++++-------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 4017da0a138..05c5de3c707 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -116,9 +116,9 @@ struct StrangeCascTrack { } axesConfig; // Filters events - // Filter eventFilter = (o2::aod::evsel::sel8 == true); - // Filter posZFilter = (nabs(o2::aod::collision::posZ) < selCuts.cutZVertex); - // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < selCuts.cutZVertex); + // Filter eventFilter = (o2::aod::evsel::sel8 == true); + // Filter posZFilter = (nabs(o2::aod::collision::posZ) < selCuts.cutZVertex); + // Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < selCuts.cutZVertex); // cascade reconstruction types static constexpr std::string_view kTypeNames[] = {"Standard", "Tracked"}; @@ -156,10 +156,14 @@ struct StrangeCascTrack { auto timeStamp = timestamp; std::string efficiencyCCDBPath = [&]() { - if (doProcesspp) return efficiencyCCDBPath_pp; - if (doProcesspO) return efficiencyCCDBPath_pO; - if (doProcessPbPb) return efficiencyCCDBPath_PbPb; - if (doProcessOO) return efficiencyCCDBPath_OO; + if (doProcesspp) + return efficiencyCCDBPath_pp; + if (doProcesspO) + return efficiencyCCDBPath_pO; + if (doProcessPbPb) + return efficiencyCCDBPath_PbPb; + if (doProcessOO) + return efficiencyCCDBPath_OO; }(); TList* listEfficiencies = ccdb->getForTimeStamp(efficiencyCCDBPath, timeStamp); @@ -251,8 +255,10 @@ struct StrangeCascTrack { template bool passesTOF(TCascade cascade, TString particle) { - if (particle == "xi") return cascade.tofXiCompatibility(selCuts.nSigmaTOFXi); - if (particle == "omega") return cascade.tofOmegaCompatibility(selCuts.nSigmaTOFOmega); + if (particle == "xi") + return cascade.tofXiCompatibility(selCuts.nSigmaTOFXi); + if (particle == "omega") + return cascade.tofOmegaCompatibility(selCuts.nSigmaTOFOmega); return true; } // checks whether gen cascade corresponds to PDG code @@ -369,10 +375,9 @@ struct StrangeCascTrack { efficiencyXi = 1.; efficiencyXiErr = 0.; } - } } - + if (doApplyPurity) { if constexpr (requires { cascade.topologyChi2(); }) { purityOmega = hPurityOmegaTra->Interpolate(cascade.pt(), mult); @@ -427,39 +432,47 @@ struct StrangeCascTrack { histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel/MassOmega"), massOmega); if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAxy"), cascade.dcaXYCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAz"), cascade.dcaZCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Phi"), cascade.phi()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Eta"), cascade.eta()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/EvMult"), mult); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); - histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/V0CosPA"), v0cosPA); - if (isMCTruth(stdCasc, "xi")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassXi"), massXi); - if (isMCTruth(stdCasc, "omega")) histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); - }} + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAxy"), cascade.dcaXYCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAz"), cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Phi"), cascade.phi()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/Eta"), cascade.eta()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/EvMult"), mult); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/V0CosPA"), v0cosPA); + if (isMCTruth(stdCasc, "xi")) + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassXi"), massXi); + if (isMCTruth(stdCasc, "omega")) + histos.fill(HIST(kTypeNames[type]) + HIST("/NoSel-Truth/MassOmega"), massOmega); + } + } // start checking selections bool passedAllSels = true; // apply general selection criteria if (doApplyCuts) { - if (!isValidCasc(collision, stdCasc)) passedAllSels = false; + if (!isValidCasc(collision, stdCasc)) + passedAllSels = false; } // apply tpc pid if (doApplyTPCPID) { - if (!passesTPC(stdCasc)) passedAllSels = false; + if (!passesTPC(stdCasc)) + passedAllSels = false; } // apply tof pid bool passedAllSelsXi = passedAllSels; bool passedAllSelsOmega = passedAllSels; if (doApplyTOFPID) { - if (!passesTOF(stdCasc, "xi")) passedAllSelsXi = false; - if (!passesTOF(stdCasc, "omega")) passedAllSelsOmega = false; + if (!passesTOF(stdCasc, "xi")) + passedAllSelsXi = false; + if (!passesTOF(stdCasc, "omega")) + passedAllSelsOmega = false; } // apply competing mass rej if (doCompetingMassRej) { - if (!(std::abs(massXi - o2::constants::physics::MassXiMinus) > selCuts.compMassRej)) passedAllSelsOmega = false; + if (!(std::abs(massXi - o2::constants::physics::MassXiMinus) > selCuts.compMassRej)) + passedAllSelsOmega = false; } // fill truth w/ cascs that passed all applied sels @@ -467,7 +480,7 @@ struct StrangeCascTrack { if constexpr (requires { collision.straMCCollisionId(); }) { if (passedAllSels && (passedAllSelsXi || passedAllSelsOmega)) { // fill once for every desired cascade - if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { + if (isMCTruth(stdCasc, "xi") || isMCTruth(stdCasc, "omega")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAxy"), cascade.dcaXYCascToPV()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAz"), cascade.dcaZCascToPV()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/DCAzVSpt"), pt, cascade.dcaZCascToPV()); @@ -476,17 +489,20 @@ struct StrangeCascTrack { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/EvMult"), mult); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/BachCosPA"), stdCasc.bachBaryonCosPA()); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/V0CosPA"), v0cosPA); - }}} + } + } + } // fill rec if (passedAllSelsXi) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec/MassXi"), massXi); fillHist(histos.get(HIST(kTypeNames[type]) + HIST("/Rec/Xi")), binFillXi, efficiencyXi, efficiencyXiErr, purityXi, purityXiErr); if constexpr (requires { collision.straMCCollisionId(); }) { - if (isMCTruth(stdCasc, "xi")) { + if (isMCTruth(stdCasc, "xi")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassXi"), massXi); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Xi"), massXi, pt, mult); - }} + } + } } double binFillOmega[3] = {massOmega, pt, mult}; if (passedAllSelsOmega) { @@ -496,7 +512,8 @@ struct StrangeCascTrack { if (isMCTruth(stdCasc, "omega")) { histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/MassOmega"), massOmega); histos.fill(HIST(kTypeNames[type]) + HIST("/Rec-Truth/Omega"), massOmega, pt, mult); - }} + } + } } } } @@ -554,12 +571,12 @@ struct StrangeCascTrack { }); // for MC-specific processing histos.add("MC/Gen/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); - histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Xis - histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Omegas + histos.add("MC/Gen/Xi", "Xi", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Xis + histos.add("MC/Gen/Omega", "Omega", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated Omegas histos.add("MC/Gen/PrimaryXi", "Xi primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Xis histos.add("MC/Gen/PrimaryOmega", "Omega primaries", kTH2F, {axesConfig.axisPt, axesConfig.axisMult}); // generated primary Omegas - histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); // counter of all recreated events - histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // multiplicity of all recreated events + histos.add("MC/Rec/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); // counter of all recreated events + histos.add("MC/Rec/EvMult", "Multiplicity", kTH1F, {axesConfig.axisMult}); // multiplicity of all recreated events } void processDerivedData(DerCollisionWMults::iterator const& collision, DerCascDatas const& allCascs, DerTraCascDatas const& traCascs, DauTracks const&) From a86792c70a33c548796ba7783d14a2678bb22850 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 06:59:10 +0100 Subject: [PATCH 14/17] Event filter - formatting --- PWGLF/Tasks/Strangeness/CMakeLists.txt | 2 +- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 24 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/CMakeLists.txt b/PWGLF/Tasks/Strangeness/CMakeLists.txt index 31a0087b3fa..5c0fecbfeb8 100644 --- a/PWGLF/Tasks/Strangeness/CMakeLists.txt +++ b/PWGLF/Tasks/Strangeness/CMakeLists.txt @@ -174,4 +174,4 @@ o2physics_add_dpl_workflow(cascadeanalysislightions o2physics_add_dpl_workflow(strangecasctrack SOURCES strangecasctrack.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::EventFilteringUtils - COMPONENT_NAME myo2) + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 05c5de3c707..55e30268956 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -56,7 +56,7 @@ using DerMCRecTraCascDatas = soa::Join; -struct StrangeCascTrack { +struct strangecasctrack { Service ccdb; Service pdgDB; @@ -95,9 +95,9 @@ struct StrangeCascTrack { Configurable cutV0CosPA{"cutV0CosPA", 0.97f, "max V0 cosPA"}; Configurable cutBachCosPA{"cutBachCosPA", 0.97f, "max Bachelor cosPA"}; // TPC PID selection - Configurable nSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; - Configurable nSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; - Configurable nSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + Configurable nSigmaTPCPion{"nSigmaTPCPion", 4, "NSigmaTPCPion"}; + Configurable nSigmaTPCKaon{"nSigmaTPCKaon", 4, "NSigmaTPCKaon"}; + Configurable nSigmaTPCProton{"nSigmaTPCProton", 4, "NSigmaTPCProton"}; // TOF PID selection Configurable nSigmaTOFXi{"nSigmaTOFXi", 3, "nSigmaTOFXi"}; Configurable nSigmaTOFOmega{"nSigmaTOFOmega", 3, "nSigmaTOFOmega"}; @@ -105,10 +105,10 @@ struct StrangeCascTrack { // axes struct : ConfigurableGroup { - ConfigurableAxis axisPhi{"Phi", {72, 0, TwoPI}, "#phi"}; - ConfigurableAxis axisEta{"Eta", {102, -2.01, 2.01}, "#eta"}; - ConfigurableAxis axisDCAxy{"DCA to xy plane", {500, 0., 0.5}, "cm"}; - ConfigurableAxis axisDCAz{"DCA to z plane", {500, 0., 0.5}, "cm"}; + ConfigurableAxis axisPhi{"axisPhi", {72, 0, TwoPI}, "#phi"}; + ConfigurableAxis axisEta{"axisEta", {102, -2.01, 2.01}, "#eta"}; + ConfigurableAxis axisDCAxy{"axisDCAxy", {500, 0., 0.5}, "cm"}; + ConfigurableAxis axisDCAz{"axisDCAz", {500, 0., 0.5}, "cm"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "p_{T} (GeV/c)"}; ConfigurableAxis axisMult{"axisMult", {VARIABLE_WIDTH, 0.0f, 5.0, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}, "FT0 mult %"}; ConfigurableAxis axisOmegaMass{"axisOmegaMass", {2000, 1.6, 1.8}, "#Omega M_{inv} (GeV/c^{2})"}; @@ -629,14 +629,14 @@ struct StrangeCascTrack { analyseCascs(collision, traCascs); // process tracked cascades } - PROCESS_SWITCH(StrangeCascTrack, processDerivedData, "process derived data", true); - PROCESS_SWITCH(StrangeCascTrack, processDerivedMCGen, "process derived generated mc data", false); - PROCESS_SWITCH(StrangeCascTrack, processDerivedMCRec, "process derived reconstructed mc data", false); // mc and data are mutually exclusive! + PROCESS_SWITCH(strangecasctrack, processDerivedData, "process derived data", true); + PROCESS_SWITCH(strangecasctrack, processDerivedMCGen, "process derived generated mc data", false); + PROCESS_SWITCH(strangecasctrack, processDerivedMCRec, "process derived reconstructed mc data", false); // mc and data are mutually exclusive! }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; } From cee3aaa50b7e8377e1862157f1438e1ac781fc6f Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 07:00:22 +0100 Subject: [PATCH 15/17] Final --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 55e30268956..a8b7d8e60ad 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -567,7 +567,6 @@ struct strangecasctrack { histos.add(Form("%s/Rec-Truth/MassOmega", kTypeNames[type].data()), "Invariant mass hypothesis", kTH1F, {axesConfig.axisOmegaMass}); histos.add(Form("%s/Rec-Truth/Omega", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisOmegaMass, axesConfig.axisPt, axesConfig.axisMult}); histos.add(Form("%s/Rec-Truth/Xi", kTypeNames[type].data()), "", kTHnD, {axesConfig.axisXiMass, axesConfig.axisPt, axesConfig.axisMult}); - }); // for MC-specific processing histos.add("MC/Gen/EvCounter", "Event Counter", kTH1F, {{1, 0, 1}}); From d9b672a521c0250ba84419a238d5989d27fd9956 Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 09:40:59 +0100 Subject: [PATCH 16/17] Fix --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index a8b7d8e60ad..420f7e167a1 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -156,14 +156,15 @@ struct strangecasctrack { auto timeStamp = timestamp; std::string efficiencyCCDBPath = [&]() { - if (doProcesspp) + if (doProcesspp) { return efficiencyCCDBPath_pp; - if (doProcesspO) + } else if (doProcesspO) { return efficiencyCCDBPath_pO; - if (doProcessPbPb) + } else if (doProcessPbPb) { return efficiencyCCDBPath_PbPb; - if (doProcessOO) + } else { return efficiencyCCDBPath_OO; + } }(); TList* listEfficiencies = ccdb->getForTimeStamp(efficiencyCCDBPath, timeStamp); From 03990a1d9b4875eadaebb834c574cc11b0c26e3d Mon Sep 17 00:00:00 2001 From: Yakiv Date: Sun, 2 Nov 2025 10:02:13 +0100 Subject: [PATCH 17/17] Fix --- PWGLF/Tasks/Strangeness/strangecasctrack.cxx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx index 420f7e167a1..f4f2369cee5 100644 --- a/PWGLF/Tasks/Strangeness/strangecasctrack.cxx +++ b/PWGLF/Tasks/Strangeness/strangecasctrack.cxx @@ -162,9 +162,8 @@ struct strangecasctrack { return efficiencyCCDBPath_pO; } else if (doProcessPbPb) { return efficiencyCCDBPath_PbPb; - } else { - return efficiencyCCDBPath_OO; } + return efficiencyCCDBPath_OO; }(); TList* listEfficiencies = ccdb->getForTimeStamp(efficiencyCCDBPath, timeStamp);