From b4fc601b2c8f6b13414acfcd78e85e19b2d2f1c0 Mon Sep 17 00:00:00 2001 From: mkruger Date: Fri, 7 Nov 2025 11:14:46 +0100 Subject: [PATCH 1/2] add QA task for PCC --- PWGLF/Tasks/Nuspex/CMakeLists.txt | 5 ++ PWGLF/Tasks/Nuspex/pccQa.cxx | 137 ++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 PWGLF/Tasks/Nuspex/pccQa.cxx diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index 3242c18130c..2b492bb38d0 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -84,6 +84,11 @@ o2physics_add_dpl_workflow(charged-particles PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(pcc-qa + SOURCES pccQa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(id-raa SOURCES identifiedraa.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/Tasks/Nuspex/pccQa.cxx b/PWGLF/Tasks/Nuspex/pccQa.cxx new file mode 100644 index 00000000000..5b182c1a573 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/pccQa.cxx @@ -0,0 +1,137 @@ +// 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 pccQa.cxx +/// \brief Task producing DCA distributions with and without particle-composition correction. +/// \author Mario Krüger + +#include "PWGLF/DataModel/particleCompositionCorrectionTable.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include + +#include + +#include + +using namespace o2; +using namespace o2::framework; +using aod::track::TrackSelectionFlags; + +struct PccQa { + HistogramRegistry histos; + Service pdg; + + static constexpr float MaxVtxZ = 10.f; + + void init(InitContext const&); + + template + void processMeas(const C& collision, const T& tracks); + + using CollisionTableData = soa::Join; + using TrackTableData = soa::Join; + void processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks); + PROCESS_SWITCH(PccQa, processData, "process data", false); + + using CollisionTableMCTrue = aod::McCollisions; + using CollisionTableMC = soa::SmallGroups>; + using TrackTableMC = soa::Join; + using ParticleTableMC = soa::Join; + Preslice perCollision = aod::track::collisionId; + void processMC(CollisionTableMCTrue::iterator const& mcCollision, TrackTableMC const& tracks, CollisionTableMC const& collisions, ParticleTableMC const&); + PROCESS_SWITCH(PccQa, processMC, "process mc", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} + +void PccQa::init(InitContext const&) +{ + histos.add("eventCounter", "", kTH1D, {{1, 0.5, 1.5}}); + const AxisSpec dcaAxis = {1000, -1., 1., "#it{DCA}_{xy}", "dca"}; + std::vector ptBinEdges = {0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0}; + const AxisSpec ptAxis{ptBinEdges, "#it{p}_{T} (GeV/#it{c})", "pt"}; + + histos.add("DCAxyVsPt", "", kTH2D, {ptAxis, dcaAxis}); + + if (doprocessMC) { + histos.add("DCAxyVsPt_weighted", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("prim/DCAxyVsPt", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("prim/DCAxyVsPt_weighted", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("sec/DCAxyVsPt", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("sec/DCAxyVsPt_weighted", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("sec/dec/DCAxyVsPt", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("sec/dec/DCAxyVsPt_weighted", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("sec/mat/DCAxyVsPt", "", kTH2D, {ptAxis, dcaAxis}); + histos.add("sec/mat/DCAxyVsPt_weighted", "", kTH2D, {ptAxis, dcaAxis}); + } +} + +void PccQa::processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks) +{ + processMeas(collision, tracks); +} +void PccQa::processMC(CollisionTableMCTrue::iterator const&, TrackTableMC const& tracks, CollisionTableMC const& collisions, ParticleTableMC const&) +{ + for (const auto& collision : collisions) { + auto curTracks = tracks.sliceBy(perCollision, collision.globalIndex()); + processMeas(collision, curTracks); + break; + } +} + +template +void PccQa::processMeas(const C& collision, const T& tracks) +{ + if ((std::abs(collision.posZ()) > MaxVtxZ) || !collision.sel8()) return; + histos.fill(HIST("eventCounter"), 1); + + for (const auto& track : tracks) { + if (!TrackSelectionFlags::checkFlag(track.trackCutFlag(), TrackSelectionFlags::kGlobalTrackWoDCA)) { + continue; + } + histos.fill(HIST("DCAxyVsPt"), track.pt(), track.dcaXY()); + + if constexpr (IS_MC) { + if (!track.has_mcParticle()) { + continue; + } + const auto& particle = track.template mcParticle_as(); + + histos.fill(HIST("DCAxyVsPt_weighted"), track.pt(), track.dcaXY(), particle.pccWeight()); + + if (particle.isPhysicalPrimary()) { + histos.fill(HIST("prim/DCAxyVsPt"), track.pt(), track.dcaXY()); + histos.fill(HIST("prim/DCAxyVsPt_weighted"), track.pt(), track.dcaXY(), particle.pccWeight()); + } else { + histos.fill(HIST("sec/DCAxyVsPt"), track.pt(), track.dcaXY()); + histos.fill(HIST("sec/DCAxyVsPt_weighted"), track.pt(), track.dcaXY(), particle.pccWeight()); + if (particle.getProcess() == TMCProcess::kPDecay) { + histos.fill(HIST("sec/dec/DCAxyVsPt"), track.pt(), track.dcaXY()); + histos.fill(HIST("sec/dec/DCAxyVsPt_weighted"), track.pt(), track.dcaXY(), particle.pccWeight()); + } else if (particle.getProcess() == TMCProcess::kPHInhelastic || particle.getProcess() == TMCProcess::kPHadronic || particle.getProcess() == TMCProcess::kPHElastic) { + histos.fill(HIST("sec/mat/DCAxyVsPt"), track.pt(), track.dcaXY()); + histos.fill(HIST("sec/mat/DCAxyVsPt_weighted"), track.pt(), track.dcaXY(), particle.pccWeight()); + } + } + } + } +} From bddc2dd687c19a8700fe4932ecbbd18945d905c7 Mon Sep 17 00:00:00 2001 From: mkruger Date: Fri, 7 Nov 2025 11:20:32 +0100 Subject: [PATCH 2/2] fix for clang-format --- PWGLF/Tasks/Nuspex/pccQa.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PWGLF/Tasks/Nuspex/pccQa.cxx b/PWGLF/Tasks/Nuspex/pccQa.cxx index 5b182c1a573..fbef346fa64 100644 --- a/PWGLF/Tasks/Nuspex/pccQa.cxx +++ b/PWGLF/Tasks/Nuspex/pccQa.cxx @@ -101,7 +101,9 @@ void PccQa::processMC(CollisionTableMCTrue::iterator const&, TrackTableMC const& template void PccQa::processMeas(const C& collision, const T& tracks) { - if ((std::abs(collision.posZ()) > MaxVtxZ) || !collision.sel8()) return; + if ((std::abs(collision.posZ()) > MaxVtxZ) || !collision.sel8()) { + return; + } histos.fill(HIST("eventCounter"), 1); for (const auto& track : tracks) {