From d4f6f80e65d586d8a68bee878c931ee6c747f1df Mon Sep 17 00:00:00 2001 From: ddobrigk Date: Tue, 16 Jan 2024 07:16:06 +0100 Subject: [PATCH] PWGLF: Extra dev of derived V0 analysis (#4324) * PWGLF: extra dev of derived V0 analysis * Add task * Please consider the following formatting changes (#218) --------- Co-authored-by: ALICE Builder --- PWGLF/Tasks/CMakeLists.txt | 6 +- PWGLF/Tasks/derivedlambdakzeroanalysis.cxx | 234 +++++++++++++++++++++ PWGLF/Tasks/lambdakzeroanalysis.cxx | 141 ------------- 3 files changed, 236 insertions(+), 145 deletions(-) create mode 100644 PWGLF/Tasks/derivedlambdakzeroanalysis.cxx delete mode 100644 PWGLF/Tasks/lambdakzeroanalysis.cxx diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 88931ba6097..74dafa9618b 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -110,8 +110,8 @@ o2physics_add_dpl_workflow(id-raa COMPONENT_NAME Analysis) # Strangeness -o2physics_add_dpl_workflow(lambdakzeroanalysis - SOURCES lambdakzeroanalysis.cxx +o2physics_add_dpl_workflow(derivedlambdakzeroanalysis + SOURCES derivedlambdakzeroanalysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) @@ -181,7 +181,6 @@ o2physics_add_dpl_workflow(k892pmanalysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(lambda1520analysis SOURCES lambda1520analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -242,7 +241,6 @@ o2physics_add_dpl_workflow(f1protoncorrelation PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(chargedkstaranalysis SOURCES chargedkstaranalysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/Tasks/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/derivedlambdakzeroanalysis.cxx new file mode 100644 index 00000000000..e743ec1397d --- /dev/null +++ b/PWGLF/Tasks/derivedlambdakzeroanalysis.cxx @@ -0,0 +1,234 @@ +// 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. +// +// Example V0 analysis task +// ======================== +// +// This code loops over a V0Data table and produces some +// standard analysis output. It is meant to be run over +// derived data. +// +// Comments, questions, complaints, suggestions? +// Please write to: +// david.dobrigkeit.chinellato@cern.ch +// +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "ReconstructionDataFormats/Track.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Common/Core/trackUtilities.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/PIDResponse.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Framework/ASoAHelpers.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +using dauTracks = soa::Join; + +struct derivedlambdakzeroanalysis { + + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Selection criteria: acceptance + Configurable rapidityCut{"rapidityCut", 0.5, "rapidity"}; + Configurable daughterEtaCut{"daughterEtaCut", 0.8, "max eta for daughters"}; + + // Standard 5 topological criteria + Configurable v0cospa{"v0cospa", 0.995, "min V0 CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable dcav0dau{"dcav0dau", 1.0, "max DCA V0 Daughters (cm)"}; + Configurable dcanegtopv{"dcanegtopv", .1, "min DCA Neg To PV (cm)"}; + Configurable dcapostopv{"dcapostopv", .1, "min DCA Pos To PV (cm)"}; + Configurable v0radius{"v0radius", 5.0, "minimum V0 radius (cm)"}; + + // PID (TPC) + Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; + + Configurable doQA{"doQA", true, "do topological variable QA histograms"}; + Configurable massWindowQA{"massWindowQA", 0.005f, "mass window for QA plots"}; + + static constexpr float defaultLifetimeCuts[1][2] = {{30., 20.}}; + Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; + + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; + ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, ""}; + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; + ConfigurableAxis axisCentrality{"axisCentrality", {100, 0.0f, 100.0f}, ""}; + + // topological variable QA axes + ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {100, -0.5f, 0.5f}, "DCA (cm)"}; + ConfigurableAxis axisDCAdau{"axisDCAdau", {200, 0.0f, 2.0f}, "DCA (cm)"}; + ConfigurableAxis axisPointingAngle{"axisPointingAngle", {200, 0.0f, 2.0f}, "pointing angle (rad)"}; + ConfigurableAxis axisV0Radius{"axisV0Radius", {200, 0.0f, 60.0f}, "V0 2D radius (cm)"}; + + enum species { spK0Short = 0, + spLambda, + spAntiLambda }; + + void init(InitContext const&) + { + // Event Counters + histos.add("hEventSelection", "hEventSelection", kTH1F, {{2, -0.5f, +2.5f}}); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "posZ cut"); + + histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); + + // histograms versus mass + histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass}); + histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + + // QA histograms if requested + if (doQA) { + // initialize for K0short... + histos.add("K0Short/h3dPosDCAxy", "h3dPosDCAxy", kTH3F, {axisCentrality, axisPt, axisDCAtoPV}); + histos.add("K0Short/h3dNegDCAxy", "h3dNegDCAxy", kTH3F, {axisCentrality, axisPt, axisDCAtoPV}); + histos.add("K0Short/h3dDCADaughters", "h3dDCADaughters", kTH3F, {axisCentrality, axisPt, axisDCAdau}); + histos.add("K0Short/h3dPointingAngle", "h3dPointingAngle", kTH3F, {axisCentrality, axisPt, axisPointingAngle}); + histos.add("K0Short/h3dV0Radius", "h3dV0Radius", kTH3F, {axisCentrality, axisPt, axisV0Radius}); + + // ...clone for Lambda and AntiLambda + histos.addClone("K0Short/", "Lambda/"); + histos.addClone("K0Short/", "AntiLambda/"); + } + } + + template + bool compatibleTPC(TV0 v0, int sp) + { + float pidPos = TMath::Abs(v0.template posTrackExtra_as().tpcNSigmaPi()); + float pidNeg = TMath::Abs(v0.template negTrackExtra_as().tpcNSigmaPi()); + + if (sp == spLambda) + pidPos = TMath::Abs(v0.template posTrackExtra_as().tpcNSigmaPr()); + if (sp == spAntiLambda) + pidNeg = TMath::Abs(v0.template negTrackExtra_as().tpcNSigmaPr()); + + if (pidPos < TpcPidNsigmaCut && pidNeg < TpcPidNsigmaCut) + return true; + + // if not, then not + return false; + } + + template + void fillQAHistograms(TV0 v0, int sp, float centrality) + { + float massRef = o2::constants::physics::MassKaonNeutral; + + if (sp != spK0Short) + massRef = o2::constants::physics::MassLambda; + + if (std::abs(v0.mK0Short() - massRef) < massWindowQA && sp == spK0Short) { + histos.fill(HIST("K0Short/h3dPosDCAxy"), centrality, v0.pt(), v0.dcapostopv()); + histos.fill(HIST("K0Short/h3dNegDCAxy"), centrality, v0.pt(), v0.dcanegtopv()); + histos.fill(HIST("K0Short/h3dDCADaughters"), centrality, v0.pt(), v0.dcaV0daughters()); + histos.fill(HIST("K0Short/h3dPointingAngle"), centrality, v0.pt(), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("K0Short/h3dV0Radius"), centrality, v0.pt(), v0.v0radius()); + } + if (std::abs(v0.mLambda() - massRef) < massWindowQA && sp == spLambda) { + histos.fill(HIST("Lambda/h3dPosDCAxy"), centrality, v0.pt(), v0.dcapostopv()); + histos.fill(HIST("Lambda/h3dNegDCAxy"), centrality, v0.pt(), v0.dcanegtopv()); + histos.fill(HIST("Lambda/h3dDCADaughters"), centrality, v0.pt(), v0.dcaV0daughters()); + histos.fill(HIST("Lambda/h3dPointingAngle"), centrality, v0.pt(), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("Lambda/h3dV0Radius"), centrality, v0.pt(), v0.v0radius()); + } + if (std::abs(v0.mAntiLambda() - massRef) < massWindowQA && sp == spAntiLambda) { + histos.fill(HIST("AntiLambda/h3dPosDCAxy"), centrality, v0.pt(), v0.dcapostopv()); + histos.fill(HIST("AntiLambda/h3dNegDCAxy"), centrality, v0.pt(), v0.dcanegtopv()); + histos.fill(HIST("AntiLambda/h3dDCADaughters"), centrality, v0.pt(), v0.dcaV0daughters()); + histos.fill(HIST("AntiLambda/h3dPointingAngle"), centrality, v0.pt(), TMath::ACos(v0.v0cosPA())); + histos.fill(HIST("AntiLambda/h3dV0Radius"), centrality, v0.pt(), v0.v0radius()); + } + } + + Filter preFilterV0 = nabs(aod::v0data::dcapostopv) > dcapostopv&& nabs(aod::v0data::dcanegtopv) > dcanegtopv&& aod::v0data::dcaV0daughters v0cospa; + + void process(soa::Join::iterator const& collision, soa::Filtered> const& fullV0s, dauTracks const&) + { + histos.fill(HIST("hEventSelection"), 0.5 /* all collisions */); + if (!collision.sel8()) { + return; + } + histos.fill(HIST("hEventSelection"), 1.5 /* sel8 collisions */); + + if (std::abs(collision.posZ()) > 10.f) { + return; + } + histos.fill(HIST("hEventSelection"), 2.5 /* vertex-Z selected */); + histos.fill(HIST("hEventCentrality"), collision.centFT0C()); + + for (auto& v0 : fullV0s) { + if (std::abs(v0.negativeeta()) > daughterEtaCut || std::abs(v0.positiveeta()) > daughterEtaCut) + continue; // remove acceptance that's badly reproduced by MC + + if (v0.v0radius() > v0radius) { + // ___________________________________ + // Analysis 1: Lambda + if (TMath::Abs(v0.yLambda()) < rapidityCut) { + if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda")) { + // Lambda daughter PID + if (compatibleTPC(v0, spLambda)) { + histos.fill(HIST("h3dMassLambda"), collision.centFT0C(), v0.pt(), v0.mLambda()); + if (doQA) + fillQAHistograms(v0, spLambda, collision.centFT0C()); + } + // AntiLambda daughter PID + if (compatibleTPC(v0, spAntiLambda)) { + histos.fill(HIST("h3dMassAntiLambda"), collision.centFT0C(), v0.pt(), v0.mAntiLambda()); + if (doQA) + fillQAHistograms(v0, spAntiLambda, collision.centFT0C()); + } + } + } + // ___________________________________ + // Analysis 2: K0Short + if (TMath::Abs(v0.yK0Short()) < rapidityCut) { + if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S")) { + if (compatibleTPC(v0, spK0Short)) { + histos.fill(HIST("h3dMassK0Short"), collision.centFT0C(), v0.pt(), v0.mK0Short()); + if (doQA) + fillQAHistograms(v0, spK0Short, collision.centFT0C()); + } + } + } + } // end radius check + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/lambdakzeroanalysis.cxx b/PWGLF/Tasks/lambdakzeroanalysis.cxx deleted file mode 100644 index c427b051579..00000000000 --- a/PWGLF/Tasks/lambdakzeroanalysis.cxx +++ /dev/null @@ -1,141 +0,0 @@ -// 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. -// -// Example V0 analysis task -// ======================== -// -// This code loops over a V0Data table and produces some -// standard analysis output. It is meant to be run over -// derived data. -// -// Comments, questions, complaints, suggestions? -// Please write to: -// david.dobrigkeit.chinellato@cern.ch -// -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Framework/ASoAHelpers.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -using dauTracks = soa::Join; - -struct lambdakzeroAnalysis { - - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; - ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, ""}; - ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; - ConfigurableAxis axisCentrality{"axisCentrality", {100, 0.0f, 100.0f}, ""}; - - void init(InitContext const&) - { - // Event Counters - histos.add("hEventSelection", "hEventSelection", kTH1F, {{2, -0.5f, +1.5f}}); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "posZ cut"); - - histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); - - histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass}); - histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - - // Extra QA histograms to be added - } - - // Selection criteria - Configurable v0cospa{"v0cospa", 0.995, "V0 CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable dcav0dau{"dcav0dau", 1.0, "DCA V0 Daughters"}; - Configurable dcanegtopv{"dcanegtopv", .1, "DCA Neg To PV"}; - Configurable dcapostopv{"dcapostopv", .1, "DCA Pos To PV"}; - Configurable v0radius{"v0radius", 5.0, "v0radius"}; - Configurable rapidity{"rapidity", 0.5, "rapidity"}; - Configurable saveDcaHist{"saveDcaHist", 0, "saveDcaHist"}; - Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable boolArmenterosCut{"boolArmenterosCut", true, "cut on Armenteros-Podolanski graph"}; - Configurable paramArmenterosCut{"paramArmenterosCut", 0.2, "parameter Armenteros Cut"}; - - static constexpr float defaultLifetimeCuts[1][2] = {{25., 20.}}; - Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; - - Filter preFilterV0 = nabs(aod::v0data::dcapostopv) > dcapostopv&& nabs(aod::v0data::dcanegtopv) > dcanegtopv&& aod::v0data::dcaV0daughters < dcav0dau; - - void process(soa::Join::iterator const& collision, soa::Filtered> const& fullV0s, dauTracks const&) - { - histos.fill(HIST("hEventSelection"), 0.5); - if (abs(collision.posZ()) > 10.f) { // 10cm - return; - } - histos.fill(HIST("hEventSelection"), 1.5); - histos.fill(HIST("hEventCentrality"), collision.centFT0C()); - - for (auto& v0 : fullV0s) { - // FIXME: could not find out how to filter cosPA and radius variables (dynamic columns) - if (v0.v0radius() > v0radius && v0.v0cosPA() > v0cospa) { - if (TMath::Abs(v0.yLambda()) < rapidity) { - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda")) { - // Lambda - if (TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { - histos.fill(HIST("h3dMassLambda"), collision.centFT0C(), v0.pt(), v0.mLambda()); - } - // AntiLambda - if (TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { - histos.fill(HIST("h3dMassAntiLambda"), collision.centFT0C(), v0.pt(), v0.mAntiLambda()); - } - } - } - - // K0Short - if (TMath::Abs(v0.yK0Short()) < rapidity) { - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S")) { - if (TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut && TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { - histos.fill(HIST("h3dMassK0Short"), collision.centFT0C(), v0.pt(), v0.mK0Short()); - } - } - } - } - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -}