diff --git a/Tutorials/PWGLF/Strangeness/CMakeLists.txt b/Tutorials/PWGLF/Strangeness/CMakeLists.txt index ede23b4c734..39734cb836a 100644 --- a/Tutorials/PWGLF/Strangeness/CMakeLists.txt +++ b/Tutorials/PWGLF/Strangeness/CMakeLists.txt @@ -9,28 +9,6 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -# Strangeness analysis tutorial -o2physics_add_dpl_workflow(strangeness-step0 - SOURCES strangeness_step0.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME AnalysisTutorial) +add_subdirectory(pp) +add_subdirectory(PbPb) -o2physics_add_dpl_workflow(strangeness-step1 - SOURCES strangeness_step1.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME AnalysisTutorial) - -o2physics_add_dpl_workflow(strangeness-step2 - SOURCES strangeness_step2.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME AnalysisTutorial) - -o2physics_add_dpl_workflow(strangeness-step3 - SOURCES strangeness_step3.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME AnalysisTutorial) - -o2physics_add_dpl_workflow(strangeness-step4 - SOURCES strangeness_step4.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME AnalysisTutorial) diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/CMakeLists.txt b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/CMakeLists.txt new file mode 100644 index 00000000000..d050dc59b47 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/CMakeLists.txt @@ -0,0 +1,41 @@ +# 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. + +o2physics_add_dpl_workflow(strangeness-pbpb-skeleton + SOURCES strangeness_pbpb_skeleton.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-pbpb-step0 + SOURCES strangeness_pbpb_step0.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-pbpb-step1 + SOURCES strangeness_pbpb_step1.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-pbpb-step2 + SOURCES strangeness_pbpb_step2.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-pbpb-step3 + SOURCES strangeness_pbpb_step3.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-pbpb-step4 + SOURCES strangeness_pbpb_step4.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_skeleton.sh b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_skeleton.sh new file mode 100644 index 00000000000..9327402771f --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_skeleton.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="skeleton" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configuration_skeleton.json" + +o2-analysistutorial-lf-strangeness-pbpb-skeleton "${OPTION}" --aod-file @input_data.txt > "$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/${STEP}/AnalysisResults.root" + mv dpl-config.json "${DIR_THIS}/results/${STEP}/${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step0.sh b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step0.sh new file mode 100644 index 00000000000..bcfeb9ab890 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step0.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="0" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configuration_step0.json" + +o2-analysis-lf-cascadespawner "${OPTION}" | o2-analysistutorial-lf-strangeness-pbpb-step0 "${OPTION}" --aod-file @input_data.txt > "$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/step${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/step${STEP}/AnalysisResults.root" + mv dpl-config.json "${DIR_THIS}/results/step${STEP}/step${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step1.sh b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step1.sh new file mode 100644 index 00000000000..826f0ea1421 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step1.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="1" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configuration_step1.json" + +o2-analysis-lf-cascadespawner "${OPTION}" | o2-analysistutorial-lf-strangeness-pbpb-step1 "${OPTION}" --aod-file @input_data.txt > "$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/step${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/step${STEP}/AnalysisResults.root" + mv dpl-config.json "${DIR_THIS}/results/step${STEP}/step${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step2.sh b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step2.sh new file mode 100644 index 00000000000..aca62bad45e --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step2.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="2" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configuration_step2.json" + +o2-analysis-lf-cascadespawner "${OPTION}" | o2-analysistutorial-lf-strangeness-pbpb-step2 "${OPTION}" --aod-file @input_data.txt > "$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/step${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/step${STEP}/AnalysisResults.root" + mv dpl-config.json "${DIR_THIS}/results/step${STEP}/step${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step3.sh b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step3.sh new file mode 100644 index 00000000000..580b3c0c17f --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step3.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="3" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configuration_step3.json" + +o2-analysis-lf-cascadepid "${OPTION}" | o2-analysis-lf-cascadespawner "${OPTION}" | o2-analysistutorial-lf-strangeness-pbpb-step3 "${OPTION}" --aod-file @input_data.txt > "$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/step${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/step${STEP}/AnalysisResults.root" + mv dpl-config.json "${DIR_THIS}/results/step${STEP}/step${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step4.sh b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step4.sh new file mode 100644 index 00000000000..08f929b3fa8 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/run_step4.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="4" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configuration_step4.json" + +o2-analysis-lf-cascadepid "${OPTION}" | o2-analysis-lf-cascadespawner "${OPTION}" | o2-analysistutorial-lf-strangeness-pbpb-step4 "${OPTION}" --aod-file @input_data.txt > "$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/step${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/step${STEP}/AnalysisResults.root" + mv dpl-config.json "${DIR_THIS}/results/step${STEP}/step${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_skeleton.cxx b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_skeleton.cxx new file mode 100644 index 00000000000..788aaead7ae --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_skeleton.cxx @@ -0,0 +1,67 @@ +// 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. +/// +/// \brief Step4 of the Strangeness tutorial +/// \author Romain Schotter +/// based on the original codes from: +/// \author Nepeivoda Roman (roman.nepeivoda@cern.ch) +/// \author Chiara De Martin (chiara.de.martin@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/O2DatabasePDGPlugin.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct strangeness_pbpb_tutorial { + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // Axes + AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm]"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection requirements + Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + + void process(soa::Filtered>::iterator const& collision) + { + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step0.cxx b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step0.cxx new file mode 100644 index 00000000000..b0e595246d7 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step0.cxx @@ -0,0 +1,86 @@ +// 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. +/// +/// \brief Step4 of the Strangeness tutorial +/// \author Romain Schotter +/// based on the original codes from: +/// \author Nepeivoda Roman (roman.nepeivoda@cern.ch) +/// \author Chiara De Martin (chiara.de.martin@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/O2DatabasePDGPlugin.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// STEP 0 +// Starting point: loop over all cascades and fill invariant mass histogram + +struct strangeness_pbpb_tutorial { + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rXi{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rOmega{"omega", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // Axes + AxisSpec XiMassAxis = {100, 1.28f, 1.36f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec OmegaMassAxis = {100, 1.63f, 1.7f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm]"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + + // Xi/Omega reconstruction + rXi.add("hMassXi", "hMassXi", {HistType::kTH1F, {XiMassAxis}}); + + rOmega.add("hMassOmega", "hMassOmega", {HistType::kTH1F, {OmegaMassAxis}}); + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection requirements + Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + + void process(soa::Filtered>::iterator const& collision, + aod::CascCores const& Cascades) + { + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + + // Cascades + for (const auto& casc : Cascades) { + rXi.fill(HIST("hMassXi"), casc.mXi()); + rOmega.fill(HIST("hMassOmega"), casc.mOmega()); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step1.cxx b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step1.cxx new file mode 100644 index 00000000000..836be98b240 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step1.cxx @@ -0,0 +1,146 @@ +// 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. +/// +/// \brief Step4 of the Strangeness tutorial +/// \author Romain Schotter +/// based on the original codes from: +/// \author Nepeivoda Roman (roman.nepeivoda@cern.ch) +/// \author Chiara De Martin (chiara.de.martin@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/O2DatabasePDGPlugin.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// STEP 0 +// Starting point: loop over all cascades and fill invariant mass histogram +// STEP 1 +// Apply selections on topological variables of Cascades + +struct strangeness_pbpb_tutorial { + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rXi{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rOmega{"omega", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + + // Configurable parameters for cascade selection + Configurable cascadesetting_cospa{"cascadesetting_cospa", 0.98, "Casc CosPA"}; + Configurable cascadesetting_v0cospa{"cascadesetting_v0cospa", 0.97, "V0 CosPA"}; + Configurable cascadesetting_dcacascdau{"cascadesetting_dcacascdau", 1.0, "DCA cascade daughters"}; + Configurable cascadesetting_dcav0dau{"cascadesetting_dcav0dau", 1.0, "DCA v0 daughters"}; + Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.06, "DCA bachelor to PV"}; + Configurable cascadesetting_dcapostopv{"cascadesetting_dcapostopv", 0.06, "DCA positive to PV"}; + Configurable cascadesetting_dcanegtopv{"cascadesetting_dcanegtopv", 0.06, "DCA negative to PV"}; + Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "minimum V0 DCA to PV"}; + Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 0.5, "cascradius"}; + Configurable cascadesetting_v0radius{"cascadesetting_v0radius", 1.2, "v0radius"}; + Configurable cascadesetting_v0masswindow{"cascadesetting_v0masswindow", 0.01, "v0 mass window"}; + Configurable cascadesetting_competingmassrej{"cascadesetting_competingmassrej", 0.008, "Competing mass rejection"}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // Axes + AxisSpec XiMassAxis = {100, 1.28f, 1.36f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec OmegaMassAxis = {100, 1.63f, 1.7f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm]"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + + // Xi/Omega reconstruction + rXi.add("hMassXi", "hMassXi", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hMassXiSelected", "hMassXiSelected", {HistType::kTH1F, {XiMassAxis}}); + + rOmega.add("hMassOmega", "hMassOmega", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hMassOmegaSelected", "hMassOmegaSelected", {HistType::kTH1F, {OmegaMassAxis}}); + + // Xi/Omega topological cuts + rXi.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rXi.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + + rOmega.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rOmega.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection requirements + Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + + // Filters on Cascades + // Cannot filter on dynamic columns + Filter preFilterCascades = (aod::cascdata::dcaV0daughters < cascadesetting_dcav0dau && + nabs(aod::cascdata::dcapostopv) > cascadesetting_dcapostopv && + nabs(aod::cascdata::dcanegtopv) > cascadesetting_dcanegtopv && + nabs(aod::cascdata::dcabachtopv) > cascadesetting_dcabachtopv && + aod::cascdata::dcacascdaughters < cascadesetting_dcacascdau); + + void process(soa::Filtered>::iterator const& collision, + soa::Filtered> const& Cascades) + { + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + + // Cascades + for (const auto& casc : Cascades) { + rXi.fill(HIST("hMassXi"), casc.mXi()); + rOmega.fill(HIST("hMassOmega"), casc.mOmega()); + + // Cut on dynamic columns + if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_cospa) + continue; + if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_v0cospa) + continue; + if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascadesetting_v0masswindow) + continue; + if (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_mindcav0topv) + continue; + if (casc.cascradius() < cascadesetting_cascradius) + continue; + if (casc.v0radius() < cascadesetting_v0radius) + continue; + + // Fill histograms! (if possible) + rXi.fill(HIST("hMassXiSelected"), casc.mXi()); + + rXi.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rXi.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + + if (TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > cascadesetting_competingmassrej) { // competing mass rejection, only in case of Omega + rOmega.fill(HIST("hMassOmegaSelected"), casc.mOmega()); + + rOmega.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rOmega.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step2.cxx b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step2.cxx new file mode 100644 index 00000000000..1558bb78052 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step2.cxx @@ -0,0 +1,182 @@ +// 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. +/// +/// \brief Step4 of the Strangeness tutorial +/// \author Romain Schotter +/// based on the original codes from: +/// \author Nepeivoda Roman (roman.nepeivoda@cern.ch) +/// \author Chiara De Martin (chiara.de.martin@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/O2DatabasePDGPlugin.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// STEP 0 +// Starting point: loop over all cascades and fill invariant mass histogram +// STEP 1 +// Apply selections on topological variables of Cascades +// STEP 2 +// Apply TPC PID selections on cascade daughter tracks + +struct strangeness_pbpb_tutorial { + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rXi{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rOmega{"omega", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + + // Configurable parameters for cascade selection + Configurable cascadesetting_cospa{"cascadesetting_cospa", 0.98, "Casc CosPA"}; + Configurable cascadesetting_v0cospa{"cascadesetting_v0cospa", 0.97, "V0 CosPA"}; + Configurable cascadesetting_dcacascdau{"cascadesetting_dcacascdau", 1.0, "DCA cascade daughters"}; + Configurable cascadesetting_dcav0dau{"cascadesetting_dcav0dau", 1.0, "DCA v0 daughters"}; + Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.06, "DCA bachelor to PV"}; + Configurable cascadesetting_dcapostopv{"cascadesetting_dcapostopv", 0.06, "DCA positive to PV"}; + Configurable cascadesetting_dcanegtopv{"cascadesetting_dcanegtopv", 0.06, "DCA negative to PV"}; + Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "minimum V0 DCA to PV"}; + Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 0.5, "cascradius"}; + Configurable cascadesetting_v0radius{"cascadesetting_v0radius", 1.2, "v0radius"}; + Configurable cascadesetting_v0masswindow{"cascadesetting_v0masswindow", 0.01, "v0 mass window"}; + Configurable cascadesetting_competingmassrej{"cascadesetting_competingmassrej", 0.008, "Competing mass rejection"}; + + // Configurable parameters for PID selection + Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; + Configurable NSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; + Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // Axes + AxisSpec XiMassAxis = {100, 1.28f, 1.36f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec OmegaMassAxis = {100, 1.63f, 1.7f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm]"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + + // Xi/Omega reconstruction + rXi.add("hMassXi", "hMassXi", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hMassXiSelected", "hMassXiSelected", {HistType::kTH1F, {XiMassAxis}}); + + rOmega.add("hMassOmega", "hMassOmega", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hMassOmegaSelected", "hMassOmegaSelected", {HistType::kTH1F, {OmegaMassAxis}}); + + // Xi/Omega topological cuts + rXi.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rXi.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + + rOmega.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rOmega.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection requirements + Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + + // Filters on Cascades + // Cannot filter on dynamic columns + Filter preFilterCascades = (aod::cascdata::dcaV0daughters < cascadesetting_dcav0dau && + nabs(aod::cascdata::dcapostopv) > cascadesetting_dcapostopv && + nabs(aod::cascdata::dcanegtopv) > cascadesetting_dcanegtopv && + nabs(aod::cascdata::dcabachtopv) > cascadesetting_dcabachtopv && + aod::cascdata::dcacascdaughters < cascadesetting_dcacascdau); + + // Defining the type of the daughter tracks + using dauTracks = soa::Join; + + void process(soa::Filtered>::iterator const& collision, + soa::Filtered> const& Cascades, + dauTracks const&) + { + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + + // Cascades + for (const auto& casc : Cascades) { + const auto& bachDaughterTrackCasc = casc.bachTrackExtra_as(); + const auto& posDaughterTrackCasc = casc.posTrackExtra_as(); + const auto& negDaughterTrackCasc = casc.negTrackExtra_as(); + + rXi.fill(HIST("hMassXi"), casc.mXi()); + rOmega.fill(HIST("hMassOmega"), casc.mOmega()); + + // Cut on dynamic columns + if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_cospa) + continue; + if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_v0cospa) + continue; + if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascadesetting_v0masswindow) + continue; + if (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_mindcav0topv) + continue; + if (casc.cascradius() < cascadesetting_cascradius) + continue; + if (casc.v0radius() < cascadesetting_v0radius) + continue; + + // PID selection + if (casc.sign() < 0) { + if (TMath::Abs(posDaughterTrackCasc.tpcNSigmaPr()) > NSigmaTPCProton) { + continue; + } + if (TMath::Abs(negDaughterTrackCasc.tpcNSigmaPi()) > NSigmaTPCPion) { + continue; + } + } else { + if (TMath::Abs(negDaughterTrackCasc.tpcNSigmaPr()) > NSigmaTPCProton) { + continue; + } + if (TMath::Abs(posDaughterTrackCasc.tpcNSigmaPi()) > NSigmaTPCPion) { + continue; + } + } + + // Fill histograms! (if possible) + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaPi()) < NSigmaTPCPion) { // Xi case + rXi.fill(HIST("hMassXiSelected"), casc.mXi()); + + rXi.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rXi.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + } + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaKa()) < NSigmaTPCKaon) { // Omega case + if (TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > cascadesetting_competingmassrej) { // competing mass rejection, only in case of Omega + rOmega.fill(HIST("hMassOmegaSelected"), casc.mOmega()); + + rOmega.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rOmega.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step3.cxx b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step3.cxx new file mode 100644 index 00000000000..f12a4f02560 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step3.cxx @@ -0,0 +1,243 @@ +// 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. +/// +/// \brief Step4 of the Strangeness tutorial +/// \author Romain Schotter +/// based on the original codes from: +/// \author Nepeivoda Roman (roman.nepeivoda@cern.ch) +/// \author Chiara De Martin (chiara.de.martin@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/O2DatabasePDGPlugin.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// STEP 0 +// Starting point: loop over all cascades and fill invariant mass histogram +// STEP 1 +// Apply selections on topological variables of Cascades +// STEP 2 +// Apply TPC PID selections on cascade daughter tracks +// STEP 3 +// Apply TOF PID selections on cascade daugther tracks (if info is available) + +struct strangeness_pbpb_tutorial { + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rXi{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rOmega{"omega", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + + // Configurable parameters for cascade selection + Configurable cascadesetting_cospa{"cascadesetting_cospa", 0.98, "Casc CosPA"}; + Configurable cascadesetting_v0cospa{"cascadesetting_v0cospa", 0.97, "V0 CosPA"}; + Configurable cascadesetting_dcacascdau{"cascadesetting_dcacascdau", 1.0, "DCA cascade daughters"}; + Configurable cascadesetting_dcav0dau{"cascadesetting_dcav0dau", 1.0, "DCA v0 daughters"}; + Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.06, "DCA bachelor to PV"}; + Configurable cascadesetting_dcapostopv{"cascadesetting_dcapostopv", 0.06, "DCA positive to PV"}; + Configurable cascadesetting_dcanegtopv{"cascadesetting_dcanegtopv", 0.06, "DCA negative to PV"}; + Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "minimum V0 DCA to PV"}; + Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 0.5, "cascradius"}; + Configurable cascadesetting_v0radius{"cascadesetting_v0radius", 1.2, "v0radius"}; + Configurable cascadesetting_v0masswindow{"cascadesetting_v0masswindow", 0.01, "v0 mass window"}; + Configurable cascadesetting_competingmassrej{"cascadesetting_competingmassrej", 0.008, "Competing mass rejection"}; + + // Configurable parameters for PID selection + Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; + Configurable NSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; + Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + + // Configurable parameters for TOF PID selection + Configurable NSigmaTOFPion{"NSigmaTOFPion", 3, "NSigmaTOFPion"}; + Configurable NSigmaTOFKaon{"NSigmaTOFKaon", 3, "NSigmaTOFKaon"}; + Configurable NSigmaTOFProton{"NSigmaTOFProton", 3, "NSigmaTOFProton"}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // Axes + AxisSpec XiMassAxis = {100, 1.28f, 1.36f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec OmegaMassAxis = {100, 1.63f, 1.7f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm]"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + + // Xi/Omega reconstruction + rXi.add("hMassXi", "hMassXi", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hMassXiSelected", "hMassXiSelected", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hMassXiSelectedWithTOF", "hMassXiSelectedWithTOF", {HistType::kTH1F, {XiMassAxis}}); + + rOmega.add("hMassOmega", "hMassOmega", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hMassOmegaSelected", "hMassOmegaSelected", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hMassOmegaSelectedWithTOF", "hMassOmegaSelectedWithTOF", {HistType::kTH1F, {OmegaMassAxis}}); + + // Xi/Omega topological cuts + rXi.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rXi.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + + rOmega.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rOmega.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection requirements + Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + + // Filters on Cascades + // Cannot filter on dynamic columns + Filter preFilterCascades = (aod::cascdata::dcaV0daughters < cascadesetting_dcav0dau && + nabs(aod::cascdata::dcapostopv) > cascadesetting_dcapostopv && + nabs(aod::cascdata::dcanegtopv) > cascadesetting_dcanegtopv && + nabs(aod::cascdata::dcabachtopv) > cascadesetting_dcabachtopv && + aod::cascdata::dcacascdaughters < cascadesetting_dcacascdau); + + // Defining the type of the daughter tracks + using dauTracks = soa::Join; + + void process(soa::Filtered>::iterator const& collision, + soa::Filtered> const& Cascades, + dauTracks const&) + { + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + + // Cascades + for (const auto& casc : Cascades) { + const auto& bachDaughterTrackCasc = casc.bachTrackExtra_as(); + const auto& posDaughterTrackCasc = casc.posTrackExtra_as(); + const auto& negDaughterTrackCasc = casc.negTrackExtra_as(); + + rXi.fill(HIST("hMassXi"), casc.mXi()); + rOmega.fill(HIST("hMassOmega"), casc.mOmega()); + + // Cut on dynamic columns + if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_cospa) + continue; + if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_v0cospa) + continue; + if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascadesetting_v0masswindow) + continue; + if (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_mindcav0topv) + continue; + if (casc.cascradius() < cascadesetting_cascradius) + continue; + if (casc.v0radius() < cascadesetting_v0radius) + continue; + + // PID selection + if (casc.sign() < 0) { + if (TMath::Abs(posDaughterTrackCasc.tpcNSigmaPr()) > NSigmaTPCProton) { + continue; + } + if (TMath::Abs(negDaughterTrackCasc.tpcNSigmaPi()) > NSigmaTPCPion) { + continue; + } + } else { + if (TMath::Abs(negDaughterTrackCasc.tpcNSigmaPr()) > NSigmaTPCProton) { + continue; + } + if (TMath::Abs(posDaughterTrackCasc.tpcNSigmaPi()) > NSigmaTPCPion) { + continue; + } + } + + // TOF PID check + bool xiPassTOFSelection = true; + bool omegaPassTOFSelection = true; + if (casc.sign() < 0) { + if (posDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPr()) > NSigmaTOFProton) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPr()) > NSigmaTOFProton) { + omegaPassTOFSelection &= false; + } + } + if (negDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPi()) > NSigmaTOFPion) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPi()) > NSigmaTOFPion) { + omegaPassTOFSelection &= false; + } + } + } else { + if (posDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPi()) > NSigmaTOFPion) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPi()) > NSigmaTOFPion) { + omegaPassTOFSelection &= false; + } + } + if (negDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPr()) > NSigmaTOFProton) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPr()) > NSigmaTOFProton) { + omegaPassTOFSelection &= false; + } + } + } + + if (bachDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiPi()) > NSigmaTOFPion) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmKa()) > NSigmaTOFKaon) { + omegaPassTOFSelection &= false; + } + } + + // Fill histograms! (if possible) + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaPi()) < NSigmaTPCPion) { // Xi case + rXi.fill(HIST("hMassXiSelected"), casc.mXi()); + if (xiPassTOFSelection) + rXi.fill(HIST("hMassXiSelectedWithTOF"), casc.mXi()); + + rXi.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rXi.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + } + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaKa()) < NSigmaTPCKaon) { // Omega case + if (TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > cascadesetting_competingmassrej) { // competing mass rejection, only in case of Omega + rOmega.fill(HIST("hMassOmegaSelected"), casc.mOmega()); + if (omegaPassTOFSelection) + rOmega.fill(HIST("hMassOmegaSelectedWithTOF"), casc.mOmega()); + + rOmega.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rOmega.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step4.cxx b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step4.cxx new file mode 100644 index 00000000000..d45ef3c26a1 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/Analysis/strangeness_pbpb_step4.cxx @@ -0,0 +1,324 @@ +// 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. +/// +/// \brief Step4 of the Strangeness tutorial +/// \author Romain Schotter +/// based on the original codes from: +/// \author Nepeivoda Roman (roman.nepeivoda@cern.ch) +/// \author Chiara De Martin (chiara.de.martin@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/O2DatabasePDGPlugin.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// STEP 0 +// Starting point: loop over all cascades and fill invariant mass histogram +// STEP 1 +// Apply selections on topological variables of Cascades +// STEP 2 +// Apply TPC PID selections on cascade daughter tracks +// STEP 3 +// Apply TOF PID selections on cascade daugther tracks (if info is available) +// STEP 4 +// Check the MC information of the cascades + +struct strangeness_pbpb_tutorial { + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rXi{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rOmega{"omega", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rGenParticles{"genParticles", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + + // Configurable parameters for cascade selection + Configurable cascadesetting_cospa{"cascadesetting_cospa", 0.98, "Casc CosPA"}; + Configurable cascadesetting_v0cospa{"cascadesetting_v0cospa", 0.97, "V0 CosPA"}; + Configurable cascadesetting_dcacascdau{"cascadesetting_dcacascdau", 1.0, "DCA cascade daughters"}; + Configurable cascadesetting_dcav0dau{"cascadesetting_dcav0dau", 1.0, "DCA v0 daughters"}; + Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.06, "DCA bachelor to PV"}; + Configurable cascadesetting_dcapostopv{"cascadesetting_dcapostopv", 0.06, "DCA positive to PV"}; + Configurable cascadesetting_dcanegtopv{"cascadesetting_dcanegtopv", 0.06, "DCA negative to PV"}; + Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "minimum V0 DCA to PV"}; + Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 0.5, "cascradius"}; + Configurable cascadesetting_v0radius{"cascadesetting_v0radius", 1.2, "v0radius"}; + Configurable cascadesetting_v0masswindow{"cascadesetting_v0masswindow", 0.01, "v0 mass window"}; + Configurable cascadesetting_competingmassrej{"cascadesetting_competingmassrej", 0.008, "Competing mass rejection"}; + + // Configurable parameters for PID selection + Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; + Configurable NSigmaTPCKaon{"NSigmaTPCKaon", 4, "NSigmaTPCKaon"}; + Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + + // Configurable parameters for TOF PID selection + Configurable NSigmaTOFPion{"NSigmaTOFPion", 3, "NSigmaTOFPion"}; + Configurable NSigmaTOFKaon{"NSigmaTOFKaon", 3, "NSigmaTOFKaon"}; + Configurable NSigmaTOFProton{"NSigmaTOFProton", 3, "NSigmaTOFProton"}; + + // PDG data base + Service pdgDB; + + void init(InitContext const&) + { + // Axes + AxisSpec XiMassAxis = {100, 1.28f, 1.36f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec OmegaMassAxis = {100, 1.63f, 1.7f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm]"}; + AxisSpec ptAxis = {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + + // Xi/Omega reconstruction + rXi.add("hMassXi", "hMassXi", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hMassXiSelected", "hMassXiSelected", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hMassXiSelectedWithTOF", "hMassXiSelectedWithTOF", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hMassXiTrueRec", "hMassXiTrueRec", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hPtXiTrueRec", "hPtXiTrueRec", {HistType::kTH1F, {ptAxis}}); + rXi.add("hMassXiTrueRecWithTOF", "hMassXiTrueRecWithTOF", {HistType::kTH1F, {XiMassAxis}}); + rXi.add("hPtXiTrueRecWithTOF", "hPtXiTrueRecWithTOF", {HistType::kTH1F, {ptAxis}}); + + rOmega.add("hMassOmega", "hMassOmega", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hMassOmegaSelected", "hMassOmegaSelected", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hMassOmegaSelectedWithTOF", "hMassOmegaSelectedWithTOF", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hMassOmegaTrueRec", "hMassOmegaTrueRec", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hPtOmegaTrueRec", "hPtOmegaTrueRec", {HistType::kTH1F, {ptAxis}}); + rOmega.add("hMassOmegaTrueRecWithTOF", "hMassOmegaTrueRecWithTOF", {HistType::kTH1F, {OmegaMassAxis}}); + rOmega.add("hPtOmegaTrueRecWithTOF", "hPtOmegaTrueRecWithTOF", {HistType::kTH1F, {ptAxis}}); + + // Xi/Omega topological cuts + rXi.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rXi.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + + rOmega.add("hCascDCAV0Daughters", "hCascDCAV0Daughters", {HistType::kTH1F, {{55, 0.0f, 2.2f}}}); + rOmega.add("hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.f}}}); + + // Generated level histograms + rEventSelection.add("hVertexZGen", "hVertexZGen", {HistType::kTH1F, {vertexZAxis}}); + rGenParticles.add("hPtXiGen", "hPtXiGen", {HistType::kTH1F, {{ptAxis}}}); + rGenParticles.add("hPtOmegaGen", "hPtOmegaGen", {HistType::kTH1F, {{ptAxis}}}); + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection requirements + Filter eventFilter = (o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + Filter posZFilterMC = (nabs(o2::aod::mccollision::posZ) < cutzvertex); + + // Filters on Cascades + // Cannot filter on dynamic columns + Filter preFilterCascades = (aod::cascdata::dcaV0daughters < cascadesetting_dcav0dau && + nabs(aod::cascdata::dcapostopv) > cascadesetting_dcapostopv && + nabs(aod::cascdata::dcanegtopv) > cascadesetting_dcanegtopv && + nabs(aod::cascdata::dcabachtopv) > cascadesetting_dcabachtopv && + aod::cascdata::dcacascdaughters < cascadesetting_dcacascdau); + + // Defining the type of the daughter tracks + using dauTracks = soa::Join; + + void processRecMC(soa::Filtered>::iterator const& collision, + soa::Filtered> const& Cascades, + dauTracks const&, + aod::CascMCCores const& /*cascmccores*/) + { + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + + // Cascades + for (const auto& casc : Cascades) { + const auto& bachDaughterTrackCasc = casc.bachTrackExtra_as(); + const auto& posDaughterTrackCasc = casc.posTrackExtra_as(); + const auto& negDaughterTrackCasc = casc.negTrackExtra_as(); + + rXi.fill(HIST("hMassXi"), casc.mXi()); + rOmega.fill(HIST("hMassOmega"), casc.mOmega()); + + // Cut on dynamic columns + if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_cospa) + continue; + if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_v0cospa) + continue; + if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascadesetting_v0masswindow) + continue; + if (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < cascadesetting_mindcav0topv) + continue; + if (casc.cascradius() < cascadesetting_cascradius) + continue; + if (casc.v0radius() < cascadesetting_v0radius) + continue; + + // PID selection + if (casc.sign() < 0) { + if (TMath::Abs(posDaughterTrackCasc.tpcNSigmaPr()) > NSigmaTPCProton) { + continue; + } + if (TMath::Abs(negDaughterTrackCasc.tpcNSigmaPi()) > NSigmaTPCPion) { + continue; + } + } else { + if (TMath::Abs(negDaughterTrackCasc.tpcNSigmaPr()) > NSigmaTPCProton) { + continue; + } + if (TMath::Abs(posDaughterTrackCasc.tpcNSigmaPi()) > NSigmaTPCPion) { + continue; + } + } + + // TOF PID check + bool xiPassTOFSelection = true; + bool omegaPassTOFSelection = true; + if (casc.sign() < 0) { + if (posDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPr()) > NSigmaTOFProton) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPr()) > NSigmaTOFProton) { + omegaPassTOFSelection &= false; + } + } + if (negDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPi()) > NSigmaTOFPion) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPi()) > NSigmaTOFPion) { + omegaPassTOFSelection &= false; + } + } + } else { + if (posDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPi()) > NSigmaTOFPion) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPi()) > NSigmaTOFPion) { + omegaPassTOFSelection &= false; + } + } + if (negDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiLaPr()) > NSigmaTOFProton) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmLaPr()) > NSigmaTOFProton) { + omegaPassTOFSelection &= false; + } + } + } + + if (bachDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiPi()) > NSigmaTOFPion) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmKa()) > NSigmaTOFKaon) { + omegaPassTOFSelection &= false; + } + } + + if (bachDaughterTrackCasc.hasTOF()) { + if (TMath::Abs(casc.tofNSigmaXiPi()) > NSigmaTOFPion) { + xiPassTOFSelection &= false; + } + if (TMath::Abs(casc.tofNSigmaOmKa()) > NSigmaTOFKaon) { + omegaPassTOFSelection &= false; + } + } + + // Fill histograms! (if possible) + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaPi()) < NSigmaTPCPion) { // Xi case + rXi.fill(HIST("hMassXiSelected"), casc.mXi()); + if (xiPassTOFSelection) { + rXi.fill(HIST("hMassXiSelectedWithTOF"), casc.mXi()); + } + + rXi.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rXi.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + } + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaKa()) < NSigmaTPCKaon) { // Omega case + if (TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > cascadesetting_competingmassrej) { // competing mass rejection, only in case of Omega + rOmega.fill(HIST("hMassOmegaSelected"), casc.mOmega()); + if (omegaPassTOFSelection) { + rOmega.fill(HIST("hMassOmegaSelectedWithTOF"), casc.mOmega()); + } + + rOmega.fill(HIST("hCascDCAV0Daughters"), casc.dcaV0daughters()); + rOmega.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + } + } + + // MC truth info + if (!casc.has_cascMCCore()) { + continue; + } + auto cascmccore = casc.cascMCCore_as(); + + // Checking that the cascade is a true Xi + if (TMath::Abs(cascmccore.pdgCode()) == 3312) { + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaPi()) < NSigmaTPCPion) { // Xi case + rXi.fill(HIST("hMassXiTrueRec"), casc.mXi()); + rXi.fill(HIST("hPtXiTrueRec"), casc.pt()); + if (xiPassTOFSelection) { + rXi.fill(HIST("hMassXiTrueRecWithTOF"), casc.mXi()); + rXi.fill(HIST("hPtXiTrueRecWithTOF"), casc.pt()); + } + } + } + if (TMath::Abs(cascmccore.pdgCode()) == 3334) { + if (TMath::Abs(bachDaughterTrackCasc.tpcNSigmaKa()) < NSigmaTPCKaon) { // Omega case + if (TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > cascadesetting_competingmassrej) { // competing mass rejection, only in case of Omega + rOmega.fill(HIST("hMassOmegaTrueRec"), casc.mOmega()); + rOmega.fill(HIST("hPtOmegaTrueRec"), casc.pt()); + if (omegaPassTOFSelection) { + rOmega.fill(HIST("hMassOmegaTrueRecWithTOF"), casc.mOmega()); + rOmega.fill(HIST("hPtOmegaTrueRecWithTOF"), casc.pt()); + } + } + } + } + } + } + + void processGenMC(soa::Filtered::iterator const& mcCollision, + const soa::SmallGroups>& collisions, + const soa::SmallGroups>& cascMC) + { + if (collisions.size() < 1) // to process generated collisions that've been reconstructed at least once + return; + rEventSelection.fill(HIST("hVertexZGen"), mcCollision.posZ()); + + for (const auto& cascmc : cascMC) { + if (TMath::Abs(cascmc.pdgCode()) == 3312) { + rGenParticles.fill(HIST("hPtXiGen"), cascmc.ptMC()); + } + if (TMath::Abs(cascmc.pdgCode()) == 3334) { + rGenParticles.fill(HIST("hPtOmegaGen"), cascmc.ptMC()); + } + } + } + + PROCESS_SWITCH(strangeness_pbpb_tutorial, processRecMC, "Process Run 3 mc, reconstructed", true); + PROCESS_SWITCH(strangeness_pbpb_tutorial, processGenMC, "Process Run 3 mc, generated", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Tutorials/PWGLF/Strangeness/PbPb/CMakeLists.txt b/Tutorials/PWGLF/Strangeness/PbPb/CMakeLists.txt new file mode 100644 index 00000000000..f593f821726 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/CMakeLists.txt @@ -0,0 +1,13 @@ +# 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. + +add_subdirectory(Analysis) +# add_subdirectory(DerivedDataProduction) \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/PbPb/DerivedDataProduction/Data/run.sh b/Tutorials/PWGLF/Strangeness/PbPb/DerivedDataProduction/Data/run.sh new file mode 100644 index 00000000000..632f8375470 --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/DerivedDataProduction/Data/run.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="deriveddata" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configuration.json" + +o2-analysis-pid-tof-base "${OPTION}" | + o2-analysis-event-selection "${OPTION}" | + o2-analysis-lf-lambdakzerobuilder "${OPTION}" | + o2-analysis-lf-cascadebuilder "${OPTION}" | + o2-analysis-multiplicity-table "${OPTION}" | + o2-analysis-centrality-table "${OPTION}" | + o2-analysis-lf-epvector "${OPTION}" | + o2-analysis-centrality-qa "${OPTION}" | + o2-analysis-ud-sgcand-producer "${OPTION}" | + o2-analysis-timestamp "${OPTION}" | + o2-analysis-ft0-corrected-table "${OPTION}" | + o2-analysis-track-propagation "${OPTION}" | + o2-analysis-pid-tpc-base "${OPTION}" | + o2-analysis-pid-tpc "${OPTION}" | + o2-analysis-trackselection "${OPTION}" | + o2-analysis-pid-tof-full "${OPTION}" | + o2-analysis-pid-tof-beta "${OPTION}" | + o2-analysis-lf-strangederivedbuilder "${OPTION}" --aod-file @input_data.txt --aod-writer-json OutputDirector.json >"$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/${STEP}/AnalysisResults.root" + mv AO2D.root "${DIR_THIS}/results/${STEP}/AO2D.root" + mv dpl-config.json "${DIR_THIS}/results/${STEP}/${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi diff --git a/Tutorials/PWGLF/Strangeness/PbPb/DerivedDataProduction/MC/runMC.sh b/Tutorials/PWGLF/Strangeness/PbPb/DerivedDataProduction/MC/runMC.sh new file mode 100644 index 00000000000..e9e086e4f4e --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/PbPb/DerivedDataProduction/MC/runMC.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# log file where the terminal output will be saved +STEP="deriveddata" +LOGFILE="log-${STEP}.txt" + +#directory of this script +DIR_THIS=$PWD + +OPTION="-b --configuration json://configurationMC.json" + +o2-analysis-pid-tof-base "${OPTION}" | + o2-analysis-mccollisionextra "${OPTION}" | + o2-analysis-lf-lambdakzerobuilder "${OPTION}" | + o2-analysis-lf-cascadebuilder "${OPTION}" | + o2-analysis-lf-cascademcbuilder "${OPTION}" | + o2-analysis-centrality-table "${OPTION}" | + o2-analysis-lf-lambdakzeromcbuilder "${OPTION}" | + o2-analysis-mccollision-converter "${OPTION}" | + o2-analysis-ud-sgcand-producer "${OPTION}" | + o2-analysis-timestamp "${OPTION}" | + o2-analysis-ft0-corrected-table "${OPTION}" | + o2-analysis-track-propagation "${OPTION}" | + o2-analysis-pid-tpc-base "${OPTION}" | + o2-analysis-pid-tpc "${OPTION}" | + o2-analysis-multiplicity-table "${OPTION}" | + o2-analysis-trackselection "${OPTION}" | + o2-analysis-pid-tof-full "${OPTION}" | + o2-analysis-pid-tof-beta "${OPTION}" | + o2-analysis-event-selection "${OPTION}" | + o2-analysis-lf-strangederivedbuilder "${OPTION}" --aod-file @input_dataMC.txt --aod-writer-json OutputDirectorMC.json >"$LOGFILE" 2>&1 + +# report status +rc=$? +if [ $rc -eq 0 ]; then + echo "No problems!" + mkdir -p "${DIR_THIS}/results/${STEP}" + mv AnalysisResults.root "${DIR_THIS}/results/${STEP}/AnalysisResults.root" + mv AO2D.root "${DIR_THIS}/results/${STEP}/AO2D.root" + mv dpl-config.json "${DIR_THIS}/results/${STEP}/${STEP}.json" +else + echo "Error: Exit code ${rc}" + echo "Check the log file ${LOGFILE}" + exit ${rc} +fi diff --git a/Tutorials/PWGLF/Strangeness/README.md b/Tutorials/PWGLF/Strangeness/README.md index ee28059d0f8..1976051fe3b 100644 --- a/Tutorials/PWGLF/Strangeness/README.md +++ b/Tutorials/PWGLF/Strangeness/README.md @@ -1,13 +1,29 @@ # This is the base for the PWGLF tutorials for the O2AT -The tutorial (17-28 Apr 2023) can be still used and is a reference for the LF analyses. +The tutorial (14-18 Oct 2024) can be used as a reference for the LF analysis. It is built as a set of steps. Each step adds a level of complexity and is built in a separate executable. -The executables are defined in the `CMakeLists.txt`. -## Files -* `README.md` this readme +The tutorial is divided into two directories depending on the collision system: +## pp +This repository contains the codes to analyse V0 and cascade particles in proton-proton collisions: * `CMakeLists.txt` here are defined the source files to compile * `strangeness_step0.cxx` Starting point: loop over all V0s and fill invariant mass histogram * `strangeness_step1.cxx` Apply selections on topological variables of V0s * `strangeness_step2.cxx` Apply PID selections on V0 daughter tracks * `strangeness_step3.cxx` Check the MC information of the V0s and verify with the PID information of daughter tracks + +The introduction and hands-on sessions can be found here: https://indico.cern.ch/event/1326201/ + +## PbPb +This repository contains the code to analyse cascade particles in Pb-Pb collisions. +The tutorial revolves around two aspects: +i) the derived data production in the directory DerivedDataProduction, +ii) the analysis of the derived data in the directory Analysis, containing: +* `CMakeLists.txt` here are defined the source files to compile +* `strangeness_pbpb_step0.cxx` Starting point: loop over all cascades and fill invariant mass histogram +* `strangeness_pbpb_step1.cxx` Apply selections on topological variables of cascades +* `strangeness_pbpb_step2.cxx` Apply TPC PID selections on cascade daughter tracks +* `strangeness_pbpb_step3.cxx` Apply TOF PID selections on cascade daughter tracks (if available) +* `strangeness_pbpb_step4.cxx` Check the MC information of the cascade + +The introduction and hands-on sessions can be found here: https://indico.cern.ch/event/1425820/ \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/pp/CMakeLists.txt b/Tutorials/PWGLF/Strangeness/pp/CMakeLists.txt new file mode 100644 index 00000000000..f46ac1f9e0b --- /dev/null +++ b/Tutorials/PWGLF/Strangeness/pp/CMakeLists.txt @@ -0,0 +1,36 @@ +# 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. + +# Strangeness analysis tutorial +o2physics_add_dpl_workflow(strangeness-step0 + SOURCES strangeness_step0.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-step1 + SOURCES strangeness_step1.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-step2 + SOURCES strangeness_step2.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-step3 + SOURCES strangeness_step3.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + +o2physics_add_dpl_workflow(strangeness-step4 + SOURCES strangeness_step4.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) \ No newline at end of file diff --git a/Tutorials/PWGLF/Strangeness/strangeness_step0.cxx b/Tutorials/PWGLF/Strangeness/pp/strangeness_step0.cxx similarity index 100% rename from Tutorials/PWGLF/Strangeness/strangeness_step0.cxx rename to Tutorials/PWGLF/Strangeness/pp/strangeness_step0.cxx diff --git a/Tutorials/PWGLF/Strangeness/strangeness_step1.cxx b/Tutorials/PWGLF/Strangeness/pp/strangeness_step1.cxx similarity index 100% rename from Tutorials/PWGLF/Strangeness/strangeness_step1.cxx rename to Tutorials/PWGLF/Strangeness/pp/strangeness_step1.cxx diff --git a/Tutorials/PWGLF/Strangeness/strangeness_step2.cxx b/Tutorials/PWGLF/Strangeness/pp/strangeness_step2.cxx similarity index 100% rename from Tutorials/PWGLF/Strangeness/strangeness_step2.cxx rename to Tutorials/PWGLF/Strangeness/pp/strangeness_step2.cxx diff --git a/Tutorials/PWGLF/Strangeness/strangeness_step3.cxx b/Tutorials/PWGLF/Strangeness/pp/strangeness_step3.cxx similarity index 100% rename from Tutorials/PWGLF/Strangeness/strangeness_step3.cxx rename to Tutorials/PWGLF/Strangeness/pp/strangeness_step3.cxx diff --git a/Tutorials/PWGLF/Strangeness/strangeness_step4.cxx b/Tutorials/PWGLF/Strangeness/pp/strangeness_step4.cxx similarity index 100% rename from Tutorials/PWGLF/Strangeness/strangeness_step4.cxx rename to Tutorials/PWGLF/Strangeness/pp/strangeness_step4.cxx