58 updateTimeDependentParams(pc);
61 std::array<gsl::span<const o2::itsmft::Digit>,
NLayers>
digits{};
62 std::array<gsl::span<const o2::itsmft::ROFRecord>,
NLayers> rofs{};
63 std::array<gsl::span<const char>,
NLayers> labelsbuffer{};
65 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
70 rofs[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::ROFRecord>>(
ref);
73 labelsbuffer[dh->subSpecification] = pc.
inputs().
get<gsl::span<char>>(
ref);
85 for (uint32_t iLayer{0}; iLayer < (mDoStaggering ?
NLayers : 1); ++iLayer) {
86 int layer = (mDoStaggering) ? iLayer : -1;
88 LOG(info) <<
"Clusterer" << ((mDoStaggering) ? std::format(
" on layer {}",
layer) :
"") <<
" pulled " <<
digits[iLayer].
size() <<
" digits, in " << rofs[iLayer].size() <<
" RO frames";
89 mClusterer->setMaxROFDepthToSquash(mClusterer->getMaxROFDepthToSquash(
layer));
97 LOG(info) <<
"Clusterer" << ((mDoStaggering) ? std::format(
" on layer {}",
layer) :
"") <<
" pulled " <<
labels.getNElements() <<
" labels ";
101 std::vector<o2::itsmft::CompClusterExt> clusCompVec;
102 std::vector<o2::itsmft::ROFRecord> clusROFVec;
103 std::vector<unsigned char> clusPattVec;
105 std::unique_ptr<o2::dataformats::MCTruthContainer<o2::MCCompLabel>> clusterLabels;
107 clusterLabels = std::make_unique<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>();
109 mClusterer->process(mNThreads, reader, &clusCompVec, &clusPattVec, &clusROFVec, clusterLabels.get());
112 size_t nROFs = clusROFVec.size();
117 std::vector<o2::itsmft::ROFRecord> expClusRofVec(nROFsTF);
118 for (
int iROF{0}; iROF < nROFsTF; ++iROF) {
119 auto& rof = expClusRofVec[iROF];
124 rof.setROFrame(iROF);
126 rof.setFirstEntry(-1);
128 uint32_t prevEntry{0};
129 for (
const auto& rof : clusROFVec) {
130 const auto&
ir = rof.getBCData();
132 LOGP(warn,
"Discard ROF {} preceding TF 1st orbit {}{}",
ir.
asString(), firstTForbit, ((mDoStaggering) ? std::format(
" on layer {}",
layer) :
""));
135 auto irToFirst =
ir - firstIR;
136 if (irToFirst.toLong() - par.getROFDelayInBC(iLayer) < 0) {
137 LOGP(warn,
"Discard ROF {} preceding TF 1st orbit {} due to imposed ROF delay{}",
ir.
asString(), firstTForbit, ((mDoStaggering) ? std::format(
" on layer {}", iLayer) :
""));
140 irToFirst -= par.getROFDelayInBC(iLayer);
141 const long irROF = irToFirst.toLong() / par.getROFLengthInBC(iLayer);
142 if (irROF >= nROFsTF) {
143 LOGP(warn,
"Discard ROF {} exceeding TF orbit range{}",
ir.
asString(), ((mDoStaggering) ? std::format(
" on layer {}",
layer) :
""));
146 auto& expROF = expClusRofVec[irROF];
147 if (expROF.getNEntries() == 0) {
148 expROF.setFirstEntry(rof.getFirstEntry());
149 expROF.setNEntries(rof.getNEntries());
151 if (expROF.getNEntries() < rof.getNEntries()) {
152 LOGP(warn,
"Repeating {} with {} clusters, prefer to already processed instance with {} clusters{}", rof.asString(), rof.getNEntries(), expROF.getNEntries(), ((mDoStaggering) ? std::format(
" on layer {}",
layer) :
""));
153 expROF.setFirstEntry(rof.getFirstEntry());
154 expROF.setNEntries(rof.getNEntries());
156 LOGP(warn,
"Repeating {} with {} clusters, discard preferring already processed instance with {} clusters{}", rof.asString(), rof.getNEntries(), expROF.getNEntries(), ((mDoStaggering) ? std::format(
" on layer {}",
layer) :
""));
161 for (
auto& rof : expClusRofVec) {
162 if (rof.getFirstEntry() < 0) {
163 rof.setFirstEntry(prevLast);
165 prevLast = rof.getFirstEntry() + rof.getNEntries();
167 nROFs = expClusRofVec.size();
178 static std::vector<o2::itsmft::MC2ROFRecord> dummyMC2ROF;
184 LOG(info) <<
"IT3Clusterer on layer " << iLayer <<
" pushed " << clusCompVec.size() <<
" clusters, in " << nROFs <<
" RO frames in " <<
sw.RealTime() <<
" s";
187 LOG(info) <<
"IT3Clusterer produced " <<
nClusters <<
" clusters";
266 std::vector<InputSpec> inputs;
267 std::vector<OutputSpec> outputs;
269 inputs.emplace_back(
"digits",
"IT3",
"DIGITS", iLayer, Lifetime::Timeframe);
270 inputs.emplace_back(
"ROframes",
"IT3",
"DIGITSROF", iLayer, Lifetime::Timeframe);
271 outputs.emplace_back(
"ITS",
"COMPCLUSTERS", iLayer, Lifetime::Timeframe);
272 outputs.emplace_back(
"ITS",
"PATTERNS", iLayer, Lifetime::Timeframe);
273 outputs.emplace_back(
"ITS",
"CLUSTERSROF", iLayer, Lifetime::Timeframe);
275 inputs.emplace_back(
"labels",
"IT3",
"DIGITSMCTR", iLayer, Lifetime::Timeframe);
276 outputs.emplace_back(
"ITS",
"CLUSTERSMCTR", iLayer, Lifetime::Timeframe);
277 outputs.emplace_back(
"ITS",
"CLUSTERSMC2ROF", iLayer, Lifetime::Timeframe);
280 inputs.emplace_back(
"cldict",
"IT3",
"CLUSDICT", 0, Lifetime::Condition,
ccdbParamSpec(
"IT3/Calib/ClusterDictionary"));
281 inputs.emplace_back(
"cluspar",
"ITS",
"CLUSPARAM", 0, Lifetime::Condition,
ccdbParamSpec(
"ITS/Config/ClustererParam"));
282 inputs.emplace_back(
"alppar",
"ITS",
"ALPIDEPARAM", 0, Lifetime::Condition,
ccdbParamSpec(
"ITS/Config/AlpideParam"));
283 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
293 .
name =
"its3-clusterer",
296 .algorithm =
AlgorithmSpec{adaptFromTask<ClustererDPL>(ggRequest, useMC, doStag)},
298 {
"ignore-cluster-dictionary", VariantType::Bool,
false, {
"do not use cluster dictionary, always store explicit patterns"}},
299 {
"nthreads", VariantType::Int, 1, {
"Number of clustering threads"}}}};
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.