From 278fc87c1781317d69f911645bd7bba08a896bf8 Mon Sep 17 00:00:00 2001 From: m-rasa Date: Thu, 1 Oct 2026 17:27:16 +0200 Subject: [PATCH 1/2] Add deuteron in UPC task --- PWGUD/Tasks/CMakeLists.txt | 5 + PWGUD/Tasks/sgDeuteronSpectra.cxx | 167 ++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 PWGUD/Tasks/sgDeuteronSpectra.cxx diff --git a/PWGUD/Tasks/CMakeLists.txt b/PWGUD/Tasks/CMakeLists.txt index 7244f33fb0e..d2b22f579d6 100644 --- a/PWGUD/Tasks/CMakeLists.txt +++ b/PWGUD/Tasks/CMakeLists.txt @@ -303,3 +303,8 @@ o2physics_add_dpl_workflow(pt-spectra-inclusive-upc SOURCES ptSpectraInclusiveUpc.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(sg-deuteron-spectra + SOURCES sgDeuteronSpectra.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGUD/Tasks/sgDeuteronSpectra.cxx b/PWGUD/Tasks/sgDeuteronSpectra.cxx new file mode 100644 index 00000000000..a771281c04a --- /dev/null +++ b/PWGUD/Tasks/sgDeuteronSpectra.cxx @@ -0,0 +1,167 @@ +// 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. +// +// \Single Gap Event Analyzer for (anti)deuteron production +// \author Marika Rasa, marika.rasa@cern.ch +// \since September 2026 + +#include "PWGUD/Core/SGSelector.h" +#include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct SGDeuteronSpectra { + //UPC cuts + SGSelector sgSelector; + Configurable FV0_cut{"FV0", 50., "FV0A threshold"}; + Configurable ZDC_cut{"ZDC", 10., "ZDC threshold"}; + Configurable FT0A_cut{"FT0A", 150., "FT0A threshold"}; + Configurable FT0C_cut{"FT0C", 50., "FT0C threshold"}; + Configurable FDDA_cut{"FDDA", 10000., "FDDA threshold"}; + Configurable FDDC_cut{"FDDC", 10000., "FDDC threshold"}; + + //Track cuts + Configurable PV_cut{"PV_cut", 1.0, "Use Only PV tracks"}; + Configurable dcaZ_cut{"dcaZ_cut", 2.0, "dcaZ cut"}; + Configurable dcaXY_cut{"dcaXY_cut", 0.0, "dcaXY cut (0 for Pt-function)"}; + Configurable tpcChi2_cut{"tpcChi2_cut", 4, "Max tpcChi2NCl"}; + Configurable tpcNClsFindable_cut{"tpcNClsFindable_cut", 70, "Min tpcNClsFindable"}; + Configurable itsChi2_cut{"itsChi2_cut", 36, "Max itsChi2NCl"}; + Configurable eta_cut{"eta_cut", 0.9, "Track Pseudorapidity"}; + Configurable pt_cut{"pt_cut", 0.1, "Track Pt"}; + + //configurable axis for histograms + ConfigurableAxis ptAxis{"ptAxis", {200, 0.0, 10.0}, "p_{T}"}; + ConfigurableAxis nsigmaAxis{"nSigmaAxis", {800,-20.0,20.0}, "nSigma axis for TPC and TOF"}; + + // initialize histogram registry + HistogramRegistry registry{"registry",{}}; + + void init(InitContext&) + { + const AxisSpec axispt{ptAxis, "p_{T}"}; + const AxisSpec axistpc{nsigmaAxis, "n#sigma_{TPC}"}; + const AxisSpec axistof{nsigmaAxis, "n#sigma_{TOF}"}; + + // Collision histograms + registry.add("collisions/GapSide", "Gap Side: A, C, A+C", {HistType::kTH1F, {{3, -0.5, 2.5}}}); + registry.add("collisions/TrueGapSide", "Gap Side: A, C, A+C", {HistType::kTH1F, {{4, -1.5, 2.5}}}); + registry.add("tracks/Deut_Pt_TPC_GapA", "", {HistType::kTH2F, {axispt, axistpc}}); + registry.add("tracks/Deut_Pt_TOF_GapA", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Deut_Pt_TOF_GapA_TPCpresel", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Antideut_Pt_TPC_GapA", "", {HistType::kTH2F, {axispt, axistpc}}); + registry.add("tracks/Antideut_Pt_TOF_GapA", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Antideut_Pt_TOF_GapA_TPCpresel", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Deut_Pt_TPC_GapC", "", {HistType::kTH2F, {axispt, axistpc}}); + registry.add("tracks/Deut_Pt_TOF_GapC", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Deut_Pt_TOF_GapC_TPCpresel", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Antideut_Pt_TPC_GapC", "", {HistType::kTH2F, {axispt, axistpc}}); + registry.add("tracks/Antideut_Pt_TOF_GapC", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Antideut_Pt_TOF_GapC_TPCpresel", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Deut_Pt_TPC_DoubleGap", "", {HistType::kTH2F, {axispt, axistpc}}); + registry.add("tracks/Deut_Pt_TOF_DoubleGap", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Deut_Pt_TOF_DoubleGap_TPCpresel", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Antideut_Pt_TPC_DoubleGap", "", {HistType::kTH2F, {axispt, axistpc}}); + registry.add("tracks/Antideut_Pt_TOF_DoubleGap", "", {HistType::kTH2F, {axispt, axistof}}); + registry.add("tracks/Antideut_Pt_TOF_DoubleGap_TPCpresel", "", {HistType::kTH2F, {axispt, axistof}}); + + } + + + // define data types + using UDCollisionsFull = soa::Join; // UDCollisions + using UDCollisionFull = UDCollisionsFull::iterator; + using UDTracksFull = soa::Join; + + void process(UDCollisionFull const& coll, UDTracksFull const& tracks) + { + + registry.fill(HIST("collisions/GapSide"), coll.gapSide(), 1.); + float FIT_cut[5] = {FV0_cut, FT0A_cut, FT0C_cut, FDDA_cut, FDDC_cut}; + int truegapSide = sgSelector.trueGap(coll, FIT_cut[0], FIT_cut[1], FIT_cut[2], ZDC_cut); + registry.fill(HIST("collisions/TrueGapSide"), truegapSide, 1.); + + + std::vector parameters = {PV_cut, dcaZ_cut, dcaXY_cut, tpcChi2_cut, tpcNClsFindable_cut, itsChi2_cut, eta_cut, pt_cut}; + + for (const auto& t : tracks) { + if (trackselector(t, parameters)) { + if (truegapSide == 0) { + if (t.sign() > 0) { + registry.fill(HIST("tracks/Deut_Pt_TPC_GapA"), t.pt(), t.tpcNSigmaDe()); + registry.fill(HIST("tracks/Deut_Pt_TOF_GapA"), t.pt(), t.tofNSigmaDe()); + if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { + registry.fill(HIST("tracks/Deut_Pt_TOF_GapA_TPCpresel"), t.pt(), t.tofNSigmaDe()); + } + } + else { + registry.fill(HIST("tracks/Antideut_Pt_TPC_GapA"), t.pt(), t.tpcNSigmaDe()); + registry.fill(HIST("tracks/Antideut_Pt_TOF_GapA"), t.pt(), t.tofNSigmaDe()); + if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { + registry.fill(HIST("tracks/Antideut_Pt_TOF_GapA_TPCpresel"), t.pt(), t.tofNSigmaDe()); + } + } + } + + if (truegapSide == 1) { + if (t.sign() > 0) { + registry.fill(HIST("tracks/Deut_Pt_TPC_GapC"), t.pt(), t.tpcNSigmaDe()); + registry.fill(HIST("tracks/Deut_Pt_TOF_GapC"), t.pt(), t.tofNSigmaDe()); + if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { + registry.fill(HIST("tracks/Deut_Pt_TOF_GapC_TPCpresel"), t.pt(), t.tofNSigmaDe()); + } + } + else { + registry.fill(HIST("tracks/Antideut_Pt_TPC_GapC"), t.pt(), t.tpcNSigmaDe()); + registry.fill(HIST("tracks/Antideut_Pt_TOF_GapC"), t.pt(), t.tofNSigmaDe()); + if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { + registry.fill(HIST("tracks/Antideut_Pt_TOF_GapC_TPCpresel"), t.pt(), t.tofNSigmaDe()); + } + } + } + + if (truegapSide == 2) { + if (t.sign() > 0) { + registry.fill(HIST("tracks/Deut_Pt_TPC_DoubleGap"), t.pt(), t.tpcNSigmaDe()); + registry.fill(HIST("tracks/Deut_Pt_TOF_DoubleGap"), t.pt(), t.tofNSigmaDe()); + if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { registry.fill(HIST("tracks/Deut_Pt_TOF_DoubleGap_TPCpresel"), t.pt(), t.tofNSigmaDe()); + } + } + else { + registry.fill(HIST("tracks/Antideut_Pt_TPC_DoubleGap"),t.pt(), t.tpcNSigmaDe()); + registry.fill(HIST("tracks/Antideut_Pt_TOF_DoubleGap"), t.pt(), t.tofNSigmaDe()); + if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { + registry.fill(HIST("tracks/Antideut_Pt_TOF_DoubleGap_TPCpresel"), t.pt(), t.tofNSigmaDe()); + } + } + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"sgdeuteronspectra"}), + }; +} From b1e234b4d97f7272396e6b84180cb4aa81ed33c3 Mon Sep 17 00:00:00 2001 From: m-rasa Date: Fri, 2 Oct 2026 17:28:59 +0200 Subject: [PATCH 2/2] Fix PR formatting issues --- PWGUD/Tasks/CMakeLists.txt | 2 +- PWGUD/Tasks/sgDeuteronSpectra.cxx | 40 +++++++++++++------------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/PWGUD/Tasks/CMakeLists.txt b/PWGUD/Tasks/CMakeLists.txt index bd034bc15bf..85b021b606d 100644 --- a/PWGUD/Tasks/CMakeLists.txt +++ b/PWGUD/Tasks/CMakeLists.txt @@ -307,4 +307,4 @@ o2physics_add_dpl_workflow(pt-spectra-inclusive-upc o2physics_add_dpl_workflow(sg-deuteron-spectra SOURCES sgDeuteronSpectra.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGUD/Tasks/sgDeuteronSpectra.cxx b/PWGUD/Tasks/sgDeuteronSpectra.cxx index a771281c04a..824048822f7 100644 --- a/PWGUD/Tasks/sgDeuteronSpectra.cxx +++ b/PWGUD/Tasks/sgDeuteronSpectra.cxx @@ -30,7 +30,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; struct SGDeuteronSpectra { - //UPC cuts + // UPC cuts SGSelector sgSelector; Configurable FV0_cut{"FV0", 50., "FV0A threshold"}; Configurable ZDC_cut{"ZDC", 10., "ZDC threshold"}; @@ -39,7 +39,7 @@ struct SGDeuteronSpectra { Configurable FDDA_cut{"FDDA", 10000., "FDDA threshold"}; Configurable FDDC_cut{"FDDC", 10000., "FDDC threshold"}; - //Track cuts + // Track cuts Configurable PV_cut{"PV_cut", 1.0, "Use Only PV tracks"}; Configurable dcaZ_cut{"dcaZ_cut", 2.0, "dcaZ cut"}; Configurable dcaXY_cut{"dcaXY_cut", 0.0, "dcaXY cut (0 for Pt-function)"}; @@ -49,19 +49,19 @@ struct SGDeuteronSpectra { Configurable eta_cut{"eta_cut", 0.9, "Track Pseudorapidity"}; Configurable pt_cut{"pt_cut", 0.1, "Track Pt"}; - //configurable axis for histograms + // Configurable axis for histograms ConfigurableAxis ptAxis{"ptAxis", {200, 0.0, 10.0}, "p_{T}"}; - ConfigurableAxis nsigmaAxis{"nSigmaAxis", {800,-20.0,20.0}, "nSigma axis for TPC and TOF"}; + ConfigurableAxis nsigmaAxis{"nSigmaAxis", {800, -20.0, 20.0}, "nSigma axis for TPC and TOF"}; - // initialize histogram registry - HistogramRegistry registry{"registry",{}}; + // Initialize histogram registry + HistogramRegistry registry{"registry", {}}; void init(InitContext&) { const AxisSpec axispt{ptAxis, "p_{T}"}; const AxisSpec axistpc{nsigmaAxis, "n#sigma_{TPC}"}; const AxisSpec axistof{nsigmaAxis, "n#sigma_{TOF}"}; - + // Collision histograms registry.add("collisions/GapSide", "Gap Side: A, C, A+C", {HistType::kTH1F, {{3, -0.5, 2.5}}}); registry.add("collisions/TrueGapSide", "Gap Side: A, C, A+C", {HistType::kTH1F, {{4, -1.5, 2.5}}}); @@ -83,18 +83,15 @@ struct SGDeuteronSpectra { registry.add("tracks/Antideut_Pt_TPC_DoubleGap", "", {HistType::kTH2F, {axispt, axistpc}}); registry.add("tracks/Antideut_Pt_TOF_DoubleGap", "", {HistType::kTH2F, {axispt, axistof}}); registry.add("tracks/Antideut_Pt_TOF_DoubleGap_TPCpresel", "", {HistType::kTH2F, {axispt, axistof}}); - - } - + } - // define data types + // Define data types using UDCollisionsFull = soa::Join; // UDCollisions using UDCollisionFull = UDCollisionsFull::iterator; using UDTracksFull = soa::Join; void process(UDCollisionFull const& coll, UDTracksFull const& tracks) { - registry.fill(HIST("collisions/GapSide"), coll.gapSide(), 1.); float FIT_cut[5] = {FV0_cut, FT0A_cut, FT0C_cut, FDDA_cut, FDDC_cut}; int truegapSide = sgSelector.trueGap(coll, FIT_cut[0], FIT_cut[1], FIT_cut[2], ZDC_cut); @@ -112,14 +109,13 @@ struct SGDeuteronSpectra { if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { registry.fill(HIST("tracks/Deut_Pt_TOF_GapA_TPCpresel"), t.pt(), t.tofNSigmaDe()); } - } - else { + } else { registry.fill(HIST("tracks/Antideut_Pt_TPC_GapA"), t.pt(), t.tpcNSigmaDe()); registry.fill(HIST("tracks/Antideut_Pt_TOF_GapA"), t.pt(), t.tofNSigmaDe()); if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { registry.fill(HIST("tracks/Antideut_Pt_TOF_GapA_TPCpresel"), t.pt(), t.tofNSigmaDe()); } - } + } } if (truegapSide == 1) { @@ -129,30 +125,28 @@ struct SGDeuteronSpectra { if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { registry.fill(HIST("tracks/Deut_Pt_TOF_GapC_TPCpresel"), t.pt(), t.tofNSigmaDe()); } - } - else { + } else { registry.fill(HIST("tracks/Antideut_Pt_TPC_GapC"), t.pt(), t.tpcNSigmaDe()); registry.fill(HIST("tracks/Antideut_Pt_TOF_GapC"), t.pt(), t.tofNSigmaDe()); if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { registry.fill(HIST("tracks/Antideut_Pt_TOF_GapC_TPCpresel"), t.pt(), t.tofNSigmaDe()); } - } + } } - + if (truegapSide == 2) { if (t.sign() > 0) { registry.fill(HIST("tracks/Deut_Pt_TPC_DoubleGap"), t.pt(), t.tpcNSigmaDe()); registry.fill(HIST("tracks/Deut_Pt_TOF_DoubleGap"), t.pt(), t.tofNSigmaDe()); if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { registry.fill(HIST("tracks/Deut_Pt_TOF_DoubleGap_TPCpresel"), t.pt(), t.tofNSigmaDe()); } - } - else { - registry.fill(HIST("tracks/Antideut_Pt_TPC_DoubleGap"),t.pt(), t.tpcNSigmaDe()); + } else { + registry.fill(HIST("tracks/Antideut_Pt_TPC_DoubleGap"), t.pt(), t.tpcNSigmaDe()); registry.fill(HIST("tracks/Antideut_Pt_TOF_DoubleGap"), t.pt(), t.tofNSigmaDe()); if (TMath::Abs(t.tpcNSigmaDe()) < 3.0) { registry.fill(HIST("tracks/Antideut_Pt_TOF_DoubleGap_TPCpresel"), t.pt(), t.tofNSigmaDe()); } - } + } } } }