160 gsl::span<const DigROFRecord> digitROFs,
161 std::vector<o2::trk::Cluster>&
clusters,
162 std::vector<unsigned char>& patterns,
163 std::vector<o2::trk::ROFRecord>& clusterROFs,
166 gsl::span<const DigMC2ROFRecord> digMC2ROFs,
167 std::vector<o2::trk::MC2ROFRecord>* clusterMC2ROFs)
170 mThread = std::make_unique<ClustererThread>(
this);
175 for (
size_t iROF = 0; iROF < digitROFs.size(); ++iROF) {
176 const auto& inROF = digitROFs[iROF];
177 const auto outFirst =
static_cast<int>(
clusters.size());
178 const int first = inROF.getFirstEntry();
179 const int nEntries = inROF.getNEntries();
182 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(), outFirst, 0);
191 const auto& da = digits[a];
192 const auto& db = digits[b];
193 if (da.getChipIndex() != db.getChipIndex()) {
194 return da.getChipIndex() < db.getChipIndex();
196 if (da.getColumn() != db.getColumn()) {
197 return da.getColumn() < db.getColumn();
199 return da.getRow() < db.getRow();
204 using CellCollection = std::vector<Cell>;
206 using ClusterCollection = std::vector<Cluster>;
207 static constexpr int GridDim = 2;
209 CellCollection
cells;
210 Acts::Ccl::ClusteringData
data;
211 ClusterCollection clsCollection;
215 while (sliceStart < nEntries) {
216 const int chipFirst = sliceStart;
217 const uint16_t chipID =
digits[
mSortIdx[sliceStart]].getChipIndex();
218 while (sliceStart < nEntries &&
digits[
mSortIdx[sliceStart]].getChipIndex() == chipID) {
221 const int chipN = sliceStart - chipFirst;
226 clsCollection.clear();
227 cells.reserve(chipN);
228 for (
int i = chipFirst;
i < chipFirst + chipN; ++
i) {
230 cells.emplace_back(digit.getRow(), digit.getColumn(),
mSortIdx[
i]);
233 LOG(
debug) <<
"Clustering with ACTS on chip " << chipID <<
" " <<
cells.size() <<
" digits";
234 Acts::Ccl::createClusters<CellCollection, ClusterCollection, GridDim>(
data,
237 Acts::Ccl::DefaultConnect<Cell, GridDim>(
false));
239 LOG(
debug) <<
" found " << clsCollection.size() <<
" clusters";
242 for (
const auto& actsCluster : clsCollection) {
243 if (actsCluster.cells.empty()) {
248 uint16_t rowMin =
static_cast<uint16_t
>(actsCluster.cells[0].row);
249 uint16_t rowMax = rowMin;
250 uint16_t colMin =
static_cast<uint16_t
>(actsCluster.cells[0].col);
251 uint16_t colMax = colMin;
253 for (
const auto& cell : actsCluster.cells) {
254 rowMin = std::min(rowMin,
static_cast<uint16_t
>(cell.row));
255 rowMax = std::max(rowMax,
static_cast<uint16_t
>(cell.row));
256 colMin = std::min(colMin,
static_cast<uint16_t
>(cell.col));
257 colMax = std::max(colMax,
static_cast<uint16_t
>(cell.col));
260 const uint16_t rowSpan = rowMax - rowMin + 1;
261 const uint16_t colSpan = colMax - colMin + 1;
269 LOG(warning) <<
"Splitting huge TRK cluster: chipID " << chipID
270 <<
", rows " << rowMin <<
":" << rowMax
271 <<
" cols " << colMin <<
":" << colMax;
273 for (uint16_t tileColMin = colMin; tileColMin <= colMax;
277 for (uint16_t tileRowMin = rowMin; tileRowMin <= rowMax;
282 std::vector<std::pair<uint16_t, uint16_t>> tileCells;
283 for (
const auto& cell : actsCluster.cells) {
284 uint16_t
r =
static_cast<uint16_t
>(cell.row);
285 uint16_t
c =
static_cast<uint16_t
>(cell.col);
286 if (
r >= tileRowMin && r <= tileRowMax && c >= tileColMin &&
c <= tileColMax) {
287 tileCells.emplace_back(
r,
c);
291 if (tileCells.empty()) {
295 uint16_t tileRowSpan = tileRowMax - tileRowMin + 1;
296 uint16_t tileColSpan = tileColMax - tileColMin + 1;
299 std::array<unsigned char, o2::itsmft::ClusterPattern::MaxPatternBytes> patt{};
300 for (
const auto& [
r,
c] : tileCells) {
301 uint32_t
ir =
r - tileRowMin;
302 uint32_t ic =
c - tileColMin;
303 int nbit =
ir * tileColSpan + ic;
304 patt[nbit >> 3] |= (0x1 << (7 - (nbit % 8)));
306 patterns.emplace_back(
static_cast<unsigned char>(tileRowSpan));
307 patterns.emplace_back(
static_cast<unsigned char>(tileColSpan));
308 const int nBytes = (tileRowSpan * tileColSpan + 7) / 8;
309 patterns.insert(patterns.end(), patt.begin(), patt.begin() + nBytes);
312 if (clusterLabels && digitLabels) {
313 const auto clsIdx =
static_cast<uint32_t
>(
clusters.size());
314 for (
const auto& cell : actsCluster.cells) {
315 uint16_t
r =
static_cast<uint16_t
>(cell.row);
316 uint16_t
c =
static_cast<uint16_t
>(cell.col);
317 if (
r >= tileRowMin && r <= tileRowMax && c >= tileColMin &&
c <= tileColMax) {
319 const auto& lbls = digitLabels->
getLabels(cell.digitIdx);
320 for (
const auto& lbl : lbls) {
331 cluster.
row = tileRowMin;
332 cluster.
col = tileColMin;
333 cluster.
size =
static_cast<uint16_t
>(tileCells.size());
335 cluster.
subDetID =
static_cast<int16_t
>(geom->getSubDetID(chipID));
336 cluster.
layer =
static_cast<int16_t
>(geom->getLayer(chipID));
337 cluster.
disk =
static_cast<int16_t
>(geom->getDisk(chipID));
344 std::array<unsigned char, o2::itsmft::ClusterPattern::MaxPatternBytes> patt{};
345 for (
const auto& cell : actsCluster.cells) {
346 uint32_t
ir =
static_cast<uint32_t
>(cell.row - rowMin);
347 uint32_t ic =
static_cast<uint32_t
>(cell.col - colMin);
348 int nbit =
ir * colSpan + ic;
349 patt[nbit >> 3] |= (0x1 << (7 - (nbit % 8)));
351 patterns.emplace_back(
static_cast<unsigned char>(rowSpan));
352 patterns.emplace_back(
static_cast<unsigned char>(colSpan));
353 const int nBytes = (rowSpan * colSpan + 7) / 8;
354 patterns.insert(patterns.end(), patt.begin(), patt.begin() + nBytes);
357 if (clusterLabels && digitLabels) {
358 const auto clsIdx =
static_cast<uint32_t
>(
clusters.size());
359 for (
const auto& cell : actsCluster.cells) {
361 const auto& lbls = digitLabels->
getLabels(cell.digitIdx);
362 for (
const auto& lbl : lbls) {
372 cluster.
row = rowMin;
373 cluster.
col = colMin;
374 cluster.
size =
static_cast<uint16_t
>(actsCluster.cells.size());
376 cluster.
subDetID =
static_cast<int16_t
>(geom->getSubDetID(chipID));
377 cluster.
layer =
static_cast<int16_t
>(geom->getLayer(chipID));
378 cluster.
disk =
static_cast<int16_t
>(geom->getDisk(chipID));
384 LOG(
debug) <<
" clusterization of chip " << chipID <<
" completed!";
386 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(),
387 outFirst,
static_cast<int>(
clusters.size()) - outFirst);
390 if (clusterMC2ROFs && !digMC2ROFs.empty()) {
391 clusterMC2ROFs->reserve(clusterMC2ROFs->size() + digMC2ROFs.size());
392 for (
const auto& in : digMC2ROFs) {
393 clusterMC2ROFs->emplace_back(in.eventRecordID, in.rofRecordID, in.minROF, in.maxROF);