diff --git a/Analysis/Tasks/CMakeLists.txt b/Analysis/Tasks/CMakeLists.txt index 3381c8457c3ef..eb42e55c516ff 100644 --- a/Analysis/Tasks/CMakeLists.txt +++ b/Analysis/Tasks/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory(PWGJE) add_subdirectory(PWGLF) add_subdirectory(PWGUD) add_subdirectory(ALICE3) +add_subdirectory(SkimmingTutorials) o2_add_dpl_workflow(trackextension diff --git a/Analysis/Tasks/SkimmingTutorials/CMakeLists.txt b/Analysis/Tasks/SkimmingTutorials/CMakeLists.txt new file mode 100644 index 0000000000000..fc409b4efb12c --- /dev/null +++ b/Analysis/Tasks/SkimmingTutorials/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright CERN and copyright holders of ALICE O2. This software is distributed +# under the terms of the GNU General Public License v3 (GPL Version 3), copied +# verbatim in the file "COPYING". +# +# See http://alice-o2.web.cern.ch/license for full licensing information. +# +# 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. + + +o2_add_dpl_workflow(tpcspectra-task-skim-reference + SOURCES spectraTPCReference.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::AnalysisDataModel + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(tpcspectra-task-skim-provider + SOURCES spectraTPCProvider.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::AnalysisDataModel + COMPONENT_NAME Analysis) + +o2_add_dpl_workflow(tpcspectra-task-skim-analyser + SOURCES spectraTPCAnalyser.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::AnalysisDataModel + COMPONENT_NAME Analysis) diff --git a/Analysis/Tasks/SkimmingTutorials/DataModel/LFDerived.h b/Analysis/Tasks/SkimmingTutorials/DataModel/LFDerived.h new file mode 100644 index 0000000000000..27c19e854a3e0 --- /dev/null +++ b/Analysis/Tasks/SkimmingTutorials/DataModel/LFDerived.h @@ -0,0 +1,37 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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. +#ifndef O2_ANALYSIS_LFDERIVED_H +#define O2_ANALYSIS_LFDERIVED_H + +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +//DECLARE_SOA_TABLE(LFCollisions, "AOD", "LFCOLLISION", o2::soa::Index<>, +// o2::aod::bc::RunNumber, o2::aod::collision::PosZ); +//using LFCollision = LFCollisions::iterator; + +namespace lftrack +{ +//DECLARE_SOA_INDEX_COLUMN(LFCollision, lfCollision); +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(P, p, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(TPCNSigma, tpcNSigma, float[9]); +} // namespace lftrack +DECLARE_SOA_TABLE(LFTracks, "AOD", "LFTRACK", o2::soa::Index<>, + //lftrack::LFCollisionId, + lftrack::Pt, lftrack::P, lftrack::Eta, + lftrack::TPCNSigma); +using LFTrack = LFTracks::iterator; +} // namespace o2::aod + +#endif // O2_ANALYSIS_LFDERIVED_H diff --git a/Analysis/Tasks/SkimmingTutorials/LFDerived.h b/Analysis/Tasks/SkimmingTutorials/LFDerived.h new file mode 100644 index 0000000000000..b122888acd74b --- /dev/null +++ b/Analysis/Tasks/SkimmingTutorials/LFDerived.h @@ -0,0 +1,38 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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. +/// \author Nima Zardoshti , CERN +#ifndef O2_ANALYSIS_LFDERIVED_H +#define O2_ANALYSIS_LFDERIVED_H + +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +//DECLARE_SOA_TABLE(LFCollisions, "AOD", "LFCOLLISION", o2::soa::Index<>, +// o2::aod::bc::RunNumber, o2::aod::collision::PosZ); +//using LFCollision = LFCollisions::iterator; + +namespace lftrack +{ +//DECLARE_SOA_INDEX_COLUMN(LFCollision, lfCollision); +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(P, p, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(TPCNSigma, tpcNSigma, float[9]); +} // namespace lftrack +DECLARE_SOA_TABLE(LFTracks, "AOD", "LFTRACK", o2::soa::Index<>, + //lftrack::LFCollisionId, + lftrack::Pt, lftrack::P, lftrack::Eta, + lftrack::TPCNSigma); +using LFTrack = LFTracks::iterator; +} // namespace o2::aod + +#endif // O2_ANALYSIS_LFDERIVED_H diff --git a/Analysis/Tasks/SkimmingTutorials/spectraTPCAnalyser.cxx b/Analysis/Tasks/SkimmingTutorials/spectraTPCAnalyser.cxx new file mode 100644 index 0000000000000..58ea028b15150 --- /dev/null +++ b/Analysis/Tasks/SkimmingTutorials/spectraTPCAnalyser.cxx @@ -0,0 +1,110 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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. + +// O2 includes +#include "ReconstructionDataFormats/Track.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "AnalysisDataModel/PID/PIDResponse.h" +#include "AnalysisDataModel/TrackSelectionTables.h" +#include "DataModel/LFDerived.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +void customize(std::vector& workflowOptions) +{ + std::vector options{ + {"add-tof-histos", VariantType::Int, 0, {"Generate TPC with TOF histograms"}}}; + std::swap(workflowOptions, options); +} + +#include "Framework/runDataProcessing.h" + +// FIXME: we should put this function in some common header so it has to be defined only once +template +void makelogaxis(T h) +{ + const int nbins = h->GetNbinsX(); + double binp[nbins + 1]; + double max = h->GetXaxis()->GetBinUpEdge(nbins); + double min = h->GetXaxis()->GetBinLowEdge(1); + if (min <= 0) { + min = 0.00001; + } + double lmin = TMath::Log10(min); + double ldelta = (TMath::Log10(max) - lmin) / ((double)nbins); + for (int i = 0; i < nbins; i++) { + binp[i] = TMath::Exp(TMath::Log(10) * (lmin + i * ldelta)); + } + binp[nbins] = max + 1; + h->GetXaxis()->Set(nbins, binp); +} + +constexpr int Np = 9; +struct TPCSpectraAnalyserTask { + + static constexpr const char* pT[Np] = {"e", "#mu", "#pi", "K", "p", "d", "t", "^{3}He", "#alpha"}; + static constexpr std::string_view hp[Np] = {"p/El", "p/Mu", "p/Pi", "p/Ka", "p/Pr", "p/De", "p/Tr", "p/He", "p/Al"}; + static constexpr std::string_view hpt[Np] = {"pt/El", "pt/Mu", "pt/Pi", "pt/Ka", "pt/Pr", "pt/De", "pt/Tr", "pt/He", "pt/Al"}; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + histos.add("p/Unselected", "Unselected;#it{p} (GeV/#it{c})", kTH1F, {{100, 0, 20}}); + histos.add("pt/Unselected", "Unselected;#it{p}_{T} (GeV/#it{c})", kTH1F, {{100, 0, 20}}); + for (int i = 0; i < Np; i++) { + histos.add(hp[i].data(), Form("%s;#it{p} (GeV/#it{c})", pT[i]), kTH1F, {{100, 0, 20}}); + histos.add(hpt[i].data(), Form("%s;#it{p}_{T} (GeV/#it{c})", pT[i]), kTH1F, {{100, 0, 20}}); + } + } + + Configurable nsigmacut{"nsigmacut", 3, "Value of the Nsigma cut"}; + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + + template + void fillParticleHistos(const T& track, const float nsigma[]) + { + if (abs(nsigma[i]) > nsigmacut.value) { + return; + } + histos.fill(HIST(hp[i]), track.p()); + histos.fill(HIST(hpt[i]), track.pt()); + } + + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; //collision filters not doing anything now? + Filter trackFilter = nabs(aod::lftrack::eta) < cfgCutEta; + + void process(soa::Filtered::iterator const& track) + { + auto nsigma = track.tpcNSigma(); + histos.fill(HIST("p/Unselected"), track.p()); + histos.fill(HIST("pt/Unselected"), track.pt()); + + fillParticleHistos<0>(track, nsigma); + fillParticleHistos<1>(track, nsigma); + fillParticleHistos<2>(track, nsigma); + fillParticleHistos<3>(track, nsigma); + fillParticleHistos<4>(track, nsigma); + fillParticleHistos<5>(track, nsigma); + fillParticleHistos<6>(track, nsigma); + fillParticleHistos<7>(track, nsigma); + fillParticleHistos<8>(track, nsigma); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask("tpcspectra-task-skim-analyser")}; + return workflow; +} diff --git a/Analysis/Tasks/SkimmingTutorials/spectraTPCProvider.cxx b/Analysis/Tasks/SkimmingTutorials/spectraTPCProvider.cxx new file mode 100644 index 0000000000000..4c4b8ca7914de --- /dev/null +++ b/Analysis/Tasks/SkimmingTutorials/spectraTPCProvider.cxx @@ -0,0 +1,61 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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. +/// \author Nima Zardoshti , CERN + +// O2 includes +#include "ReconstructionDataFormats/Track.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "AnalysisDataModel/PID/PIDResponse.h" +#include "AnalysisDataModel/TrackSelectionTables.h" +#include "MathUtils/Utils.h" +#include "DataModel/LFDerived.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::math_utils::detail; + +#include "Framework/runDataProcessing.h" + +struct TPCSpectraProviderTask { + + //Produces outputCollisions; //currently it seems in the spectraTPC task no loop over the collision is made. Leave this here in case it will be added + Produces outputTracks; + + //Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable trackEtaCut{"trackEtaCut", 0.9f, "Eta range for tracks"}; + + //Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + Filter trackFilter = (nabs(aod::track::eta) < trackEtaCut) && (aod::track::isGlobalTrack == (uint8_t) true); + + Configurable nsigmacut{"nsigmacut", 3, "Value of the Nsigma cut"}; //can we add an upper limit? + + using TrackCandidates = soa::Filtered>; + void process(TrackCandidates::iterator const& track) + { + uint32_t pNsigma = 0xFFFFFF00; //15 bit precision for Nsigma + float nsigma[9] = {truncateFloatFraction(track.tpcNSigmaEl(), pNsigma), truncateFloatFraction(track.tpcNSigmaMu(), pNsigma), + truncateFloatFraction(track.tpcNSigmaPi(), pNsigma), truncateFloatFraction(track.tpcNSigmaKa(), pNsigma), + truncateFloatFraction(track.tpcNSigmaPr(), pNsigma), truncateFloatFraction(track.tpcNSigmaDe(), pNsigma), + truncateFloatFraction(track.tpcNSigmaTr(), pNsigma), truncateFloatFraction(track.tpcNSigmaHe(), pNsigma), + truncateFloatFraction(track.tpcNSigmaAl(), pNsigma)}; //the significance needs to be discussed + + //outputTracks(outputCollisions.lastIndex(), track.pt(), track.p(), track.eta(), nsigma); + outputTracks(track.pt(), track.p(), track.eta(), nsigma); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const&) +{ + WorkflowSpec workflow{adaptAnalysisTask("tpcspectra-task-skim-provider")}; + return workflow; +} diff --git a/Analysis/Tasks/SkimmingTutorials/spectraTPCReference.cxx b/Analysis/Tasks/SkimmingTutorials/spectraTPCReference.cxx new file mode 100644 index 0000000000000..f9d6305756734 --- /dev/null +++ b/Analysis/Tasks/SkimmingTutorials/spectraTPCReference.cxx @@ -0,0 +1,112 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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. + +// O2 includes +#include "ReconstructionDataFormats/Track.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "AnalysisDataModel/PID/PIDResponse.h" +#include "AnalysisDataModel/TrackSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +void customize(std::vector& workflowOptions) +{ + std::vector options{ + {"add-tof-histos", VariantType::Int, 0, {"Generate TPC with TOF histograms"}}}; + std::swap(workflowOptions, options); +} + +#include "Framework/runDataProcessing.h" + +// FIXME: we should put this function in some common header so it has to be defined only once +template +void makelogaxis(T h) +{ + const int nbins = h->GetNbinsX(); + double binp[nbins + 1]; + double max = h->GetXaxis()->GetBinUpEdge(nbins); + double min = h->GetXaxis()->GetBinLowEdge(1); + if (min <= 0) { + min = 0.00001; + } + double lmin = TMath::Log10(min); + double ldelta = (TMath::Log10(max) - lmin) / ((double)nbins); + for (int i = 0; i < nbins; i++) { + binp[i] = TMath::Exp(TMath::Log(10) * (lmin + i * ldelta)); + } + binp[nbins] = max + 1; + h->GetXaxis()->Set(nbins, binp); +} + +constexpr int Np = 9; +struct TPCSpectraReferenceTask { + static constexpr const char* pT[Np] = {"e", "#mu", "#pi", "K", "p", "d", "t", "^{3}He", "#alpha"}; + static constexpr std::string_view hp[Np] = {"p/El", "p/Mu", "p/Pi", "p/Ka", "p/Pr", "p/De", "p/Tr", "p/He", "p/Al"}; + static constexpr std::string_view hpt[Np] = {"pt/El", "pt/Mu", "pt/Pi", "pt/Ka", "pt/Pr", "pt/De", "pt/Tr", "pt/He", "pt/Al"}; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + histos.add("p/Unselected", "Unselected;#it{p} (GeV/#it{c})", kTH1F, {{100, 0, 20}}); + histos.add("pt/Unselected", "Unselected;#it{p}_{T} (GeV/#it{c})", kTH1F, {{100, 0, 20}}); + for (int i = 0; i < Np; i++) { + histos.add(hp[i].data(), Form("%s;#it{p} (GeV/#it{c})", pT[i]), kTH1F, {{100, 0, 20}}); + histos.add(hpt[i].data(), Form("%s;#it{p}_{T} (GeV/#it{c})", pT[i]), kTH1F, {{100, 0, 20}}); + } + } + + //Defining filters and input + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::isGlobalTrack == (uint8_t) true); + + Configurable nsigmacut{"nsigmacut", 3, "Value of the Nsigma cut"}; + + template + void fillParticleHistos(const T& track, const float nsigma[]) + { + if (abs(nsigma[i]) > nsigmacut.value) { + return; + } + histos.fill(HIST(hp[i]), track.p()); + histos.fill(HIST(hpt[i]), track.pt()); + } + + using TrackCandidates = soa::Filtered>; + void process(TrackCandidates::iterator const& track) + { + const float nsigma[Np] = {track.tpcNSigmaEl(), track.tpcNSigmaMu(), track.tpcNSigmaPi(), + track.tpcNSigmaKa(), track.tpcNSigmaPr(), track.tpcNSigmaDe(), + track.tpcNSigmaTr(), track.tpcNSigmaHe(), track.tpcNSigmaAl()}; + histos.fill(HIST("p/Unselected"), track.p()); + histos.fill(HIST("pt/Unselected"), track.pt()); + + fillParticleHistos<0>(track, nsigma); + fillParticleHistos<1>(track, nsigma); + fillParticleHistos<2>(track, nsigma); + fillParticleHistos<3>(track, nsigma); + fillParticleHistos<4>(track, nsigma); + fillParticleHistos<5>(track, nsigma); + fillParticleHistos<6>(track, nsigma); + fillParticleHistos<7>(track, nsigma); + fillParticleHistos<8>(track, nsigma); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask("tpcspectra-task-skim-reference")}; + return workflow; +} diff --git a/Common/MathUtils/include/MathUtils/Utils.h b/Common/MathUtils/include/MathUtils/Utils.h index e621226a6614f..d23933cc5ba0f 100644 --- a/Common/MathUtils/include/MathUtils/Utils.h +++ b/Common/MathUtils/include/MathUtils/Utils.h @@ -18,6 +18,7 @@ #include "MathUtils/detail/bitOps.h" #include "MathUtils/detail/StatAccumulator.h" #include "MathUtils/detail/trigonometric.h" +#include "MathUtils/detail/TypeTruncation.h" namespace o2 { @@ -221,6 +222,7 @@ using detail::StatAccumulator; using detail::bit2Mask; using detail::numberOfBitsSet; +using detail::truncateFloatFraction; } // namespace math_utils } // namespace o2 diff --git a/Common/MathUtils/include/MathUtils/detail/TypeTruncation.h b/Common/MathUtils/include/MathUtils/detail/TypeTruncation.h new file mode 100644 index 0000000000000..96cfb94bde876 --- /dev/null +++ b/Common/MathUtils/include/MathUtils/detail/TypeTruncation.h @@ -0,0 +1,47 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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 TypeTruncation.h +/// \brief +/// \author Nima Zardoshti , CERN (copied from AliPhysics implementation by Peter Hristov) + +#ifndef MATHUTILS_INCLUDE_MATHUTILS_DETAIL_TYPETRUNCATION_H_ +#define MATHUTILS_INCLUDE_MATHUTILS_DETAIL_TYPETRUNCATION_H_ + +#ifndef GPUCA_GPUCODE_DEVICE +#include +#endif + +namespace o2 +{ +namespace math_utils +{ +namespace detail +{ + +static float truncateFloatFraction(float x, uint32_t mask = 0xFFFFFF00) +{ + // Mask the less significant bits in the float fraction (1 bit sign, 8 bits exponent, 23 bits fraction), see + // https://en.wikipedia.org/wiki/Single-precision_floating-point_format + // mask 0xFFFFFF00 means 23 - 8 = 15 bits in the fraction + union { + float y; + uint32_t iy; + } myu; + myu.y = x; + myu.iy &= mask; + return myu.y; +} + +} // namespace detail +} // namespace math_utils +} // namespace o2 + +#endif /* MATHUTILS_INCLUDE_MATHUTILS_DETAIL_TYPETRUNCATION_H_ */