Project
Loading...
Searching...
No Matches
ClustererSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13#include "TRKBase/AlmiraParam.h"
18#include "Framework/Logger.h"
20
21#include <algorithm>
22#include <cctype>
23#include <format>
24#include <string>
25
26namespace o2::trk
27{
28
29template <int DetID>
31{
32 mNThreads = std::max(1, ic.options().get<int>("nthreads"));
33#ifdef O2_WITH_ACTS
34 if constexpr (DetID == o2::detectors::DetID::TRK) {
35 mUseACTS = ic.options().get<bool>("useACTS");
36 }
37#endif
38}
39
40template <int DetID>
42{
43 o2::base::GeometryManager::loadGeometry(); // default prefix -> o2sim_geometry[-aligned].root
44
45 constexpr auto Origin = DetID == o2::detectors::DetID::TRK ? o2::header::gDataOriginTRK : o2::header::gDataOriginFT3;
46 const auto detName = Origin.template as<std::string>();
47 uint64_t totalClusters = 0;
48 constexpr int NLayers = DetID == o2::detectors::DetID::TRK ? static_cast<int>(o2::trk::AlmiraParam::kNLayers) : o2::trk::constants::MLOTDisks::nLayers;
49 for (int iLayer = 0; iLayer < NLayers; ++iLayer) {
50 auto digits = pc.inputs().get<gsl::span<o2::trkft3::Digit>>(std::format("digits_{}", iLayer));
51 auto rofs = pc.inputs().get<gsl::span<o2::trkft3::ROFRecord>>(std::format("ROframes_{}", iLayer));
52
53 gsl::span<const char> labelbuffer;
54 if (mUseMC) {
55 labelbuffer = pc.inputs().get<gsl::span<char>>(std::format("labels_{}", iLayer));
56 }
58
59 std::vector<o2::trkft3::Cluster<DetID>> clusters;
60 std::vector<unsigned char> patterns;
61 std::vector<o2::trkft3::ROFRecord> clusterROFs;
62 std::unique_ptr<o2::dataformats::MCTruthContainer<o2::MCCompLabel>> clusterLabels;
63 if (mUseMC) {
64 clusterLabels = std::make_unique<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>();
65 }
66
67 bool clustered = false;
68#ifdef O2_WITH_ACTS
69 if constexpr (DetID == o2::detectors::DetID::TRK) {
70 if (mUseACTS) {
71 LOG(info) << "Running TRKClusterer with ACTS on layer " << iLayer;
72 mClustererACTS.process(digits,
73 rofs,
75 patterns,
76 clusterROFs,
77 mUseMC ? &labels : nullptr,
78 clusterLabels.get());
79 clustered = true;
80 }
81 }
82#endif
83 if (!clustered) {
84 LOG(info) << "Running " << detName << "Clusterer on layer " << iLayer;
85 mClusterer.process(digits,
86 rofs,
88 patterns,
89 clusterROFs,
90 mUseMC ? &labels : nullptr,
91 clusterLabels.get());
92 }
93
94 const auto subspec = static_cast<o2::framework::DataAllocator::SubSpecificationType>(iLayer);
95 pc.outputs().snapshot(o2::framework::Output{Origin, "COMPCLUSTERS", subspec}, clusters);
96 pc.outputs().snapshot(o2::framework::Output{Origin, "PATTERNS", subspec}, patterns);
97 pc.outputs().snapshot(o2::framework::Output{Origin, "CLUSTERSROF", subspec}, clusterROFs);
98 if (mUseMC) {
99 pc.outputs().snapshot(o2::framework::Output{Origin, "CLUSTERSMCTR", subspec}, *clusterLabels);
100 }
101 totalClusters += clusters.size();
102 LOGP(info, "{}Clusterer layer {} pushed {} clusters in {} ROFs", detName, iLayer, clusters.size(), clusterROFs.size());
103 }
104
105 LOGP(info, "{}Clusterer produced {} clusters", detName, totalClusters);
106}
107
108namespace
109{
110template <int DetID>
111o2::framework::DataProcessorSpec getClustererSpecT(bool useMC)
112{
113 constexpr auto origin = DetID == o2::detectors::DetID::TRK ? o2::header::gDataOriginTRK : o2::header::gDataOriginFT3;
114 std::vector<o2::framework::InputSpec> inputs;
115 constexpr int NLayers = DetID == o2::detectors::DetID::TRK ? static_cast<int>(o2::trk::AlmiraParam::kNLayers) : o2::trk::constants::MLOTDisks::nLayers;
116 for (int iLayer = 0; iLayer < NLayers; ++iLayer) {
117 inputs.emplace_back(std::format("digits_{}", iLayer), origin, "DIGITS", iLayer, o2::framework::Lifetime::Timeframe);
118 inputs.emplace_back(std::format("ROframes_{}", iLayer), origin, "DIGITSROF", iLayer, o2::framework::Lifetime::Timeframe);
119 if (useMC) {
120 inputs.emplace_back(std::format("labels_{}", iLayer), origin, "DIGITSMCTR", iLayer, o2::framework::Lifetime::Timeframe);
121 }
122 }
123
124 std::vector<o2::framework::OutputSpec> outputs;
125 for (int iLayer = 0; iLayer < NLayers; ++iLayer) {
126 outputs.emplace_back(origin, "COMPCLUSTERS", iLayer, o2::framework::Lifetime::Timeframe);
127 outputs.emplace_back(origin, "PATTERNS", iLayer, o2::framework::Lifetime::Timeframe);
128 outputs.emplace_back(origin, "CLUSTERSROF", iLayer, o2::framework::Lifetime::Timeframe);
129 if (useMC) {
130 outputs.emplace_back(origin, "CLUSTERSMCTR", iLayer, o2::framework::Lifetime::Timeframe);
131 }
132 }
133
134 o2::framework::Options options{{"nthreads", o2::framework::VariantType::Int, 1, {"Number of clustering threads"}}};
135#ifdef O2_WITH_ACTS
136 if constexpr (DetID == o2::detectors::DetID::TRK) {
137 options.push_back({"useACTS", o2::framework::VariantType::Bool, false, {"Use ACTS for clustering"}});
138 }
139#endif
140 auto name = origin.template as<std::string>() + "-clusterer";
141 std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c) { return std::tolower(c); });
143 name,
144 inputs,
145 outputs,
146 o2::framework::AlgorithmSpec{o2::framework::adaptFromTask<o2::trk::ClustererDPL<DetID>>(useMC)},
147 options};
148}
149} // namespace
150
152{
153 return getClustererSpecT<o2::detectors::DetID::TRK>(useMC);
154}
155
157{
158 return getClustererSpecT<o2::detectors::DetID::FT3>(useMC);
159}
160
161template class ClustererDPL<o2::detectors::DetID::TRK>;
162template class ClustererDPL<o2::detectors::DetID::FT3>;
163
164} // namespace o2::trk
header::DataOrigin origin
A const (ready only) version of MCTruthContainer.
Definition of the GeometryManager class.
std::vector< o2::MCCompLabel > labels
uint32_t c
Definition RawData.h:2
static void loadGeometry(std::string_view geomFilePath="", bool applyMisalignment=false, bool preferAlignedFile=true)
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:60
void snapshot(const Output &spec, T const &object)
o2::header::DataHeader::SubSpecificationType SubSpecificationType
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
void init(o2::framework::InitContext &ic) final
void run(o2::framework::ProcessingContext &pc) final
GLuint const GLchar * name
Definition glcorearb.h:781
constexpr o2::header::DataOrigin gDataOriginTRK
Definition DataHeader.h:587
constexpr o2::header::DataOrigin gDataOriginFT3
Definition DataHeader.h:588
std::vector< ConfigParamSpec > Options
o2::framework::DataProcessorSpec getFT3ClustererSpec(bool useMC)
The clusterer of FT3's digits.
o2::framework::DataProcessorSpec getClustererSpec(bool useMC)
The clusterer of TRK's digits.
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static constexpr size_t kNLayers
Definition AlmiraParam.h:29
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters
std::vector< Digit > digits