156 gsl::span<const DigROFRecord> digitROFs,
157 std::vector<o2::trk::Cluster>&
clusters,
158 std::vector<unsigned char>& patterns,
159 std::vector<o2::trk::ROFRecord>& clusterROFs,
162 gsl::span<const DigMC2ROFRecord> digMC2ROFs,
163 std::vector<o2::trk::MC2ROFRecord>* clusterMC2ROFs)
166 mThread = std::make_unique<ClustererThread>(
this);
171 for (
size_t iROF = 0; iROF < digitROFs.size(); ++iROF) {
172 const auto& inROF = digitROFs[iROF];
173 const auto outFirst =
static_cast<int>(
clusters.size());
174 const int first = inROF.getFirstEntry();
175 const int nEntries = inROF.getNEntries();
178 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(), outFirst, 0);
187 const auto& da = digits[a];
188 const auto& db = digits[b];
189 if (da.getChipIndex() != db.getChipIndex()) {
190 return da.getChipIndex() < db.getChipIndex();
192 if (da.getColumn() != db.getColumn()) {
193 return da.getColumn() < db.getColumn();
195 return da.getRow() < db.getRow();
200 using CellCollection = std::vector<Cell>;
202 using ClusterCollection = std::vector<Cluster>;
203 static constexpr int GridDim = 2;
205 CellCollection
cells;
206 Acts::Ccl::ClusteringData
data;
207 ClusterCollection clsCollection;
211 while (sliceStart < nEntries) {
212 const int chipFirst = sliceStart;
213 const uint16_t chipID =
digits[
mSortIdx[sliceStart]].getChipIndex();
214 while (sliceStart < nEntries &&
digits[
mSortIdx[sliceStart]].getChipIndex() == chipID) {
217 const int chipN = sliceStart - chipFirst;
222 clsCollection.clear();
223 cells.reserve(chipN);
224 for (
int i = chipFirst;
i < chipFirst + chipN; ++
i) {
226 cells.emplace_back(digit.getRow(), digit.getColumn(),
mSortIdx[
i]);
229 LOG(
debug) <<
"Clustering with ACTS on chip " << chipID <<
" " <<
cells.size() <<
" digits";
230 Acts::Ccl::createClusters<CellCollection, ClusterCollection, GridDim>(
data,
233 Acts::Ccl::DefaultConnect<Cell, GridDim>(
false));
235 LOG(
debug) <<
" found " << clsCollection.size() <<
" clusters";
238 for (
const auto& actsCluster : clsCollection) {
239 if (actsCluster.cells.empty()) {
244 uint16_t rowMin =
static_cast<uint16_t
>(actsCluster.cells[0].row);
245 uint16_t rowMax = rowMin;
246 uint16_t colMin =
static_cast<uint16_t
>(actsCluster.cells[0].col);
247 uint16_t colMax = colMin;
249 for (
const auto& cell : actsCluster.cells) {
250 rowMin = std::min(rowMin,
static_cast<uint16_t
>(cell.row));
251 rowMax = std::max(rowMax,
static_cast<uint16_t
>(cell.row));
252 colMin = std::min(colMin,
static_cast<uint16_t
>(cell.col));
253 colMax = std::max(colMax,
static_cast<uint16_t
>(cell.col));
256 const uint16_t rowSpan = rowMax - rowMin + 1;
257 const uint16_t colSpan = colMax - colMin + 1;
265 LOG(warning) <<
"Splitting huge TRK cluster: chipID " << chipID
266 <<
", rows " << rowMin <<
":" << rowMax
267 <<
" cols " << colMin <<
":" << colMax;
269 for (uint16_t tileColMin = colMin; tileColMin <= colMax;
273 for (uint16_t tileRowMin = rowMin; tileRowMin <= rowMax;
278 std::vector<std::pair<uint16_t, uint16_t>> tileCells;
279 for (
const auto& cell : actsCluster.cells) {
280 uint16_t
r =
static_cast<uint16_t
>(cell.row);
281 uint16_t
c =
static_cast<uint16_t
>(cell.col);
282 if (
r >= tileRowMin && r <= tileRowMax && c >= tileColMin &&
c <= tileColMax) {
283 tileCells.emplace_back(
r,
c);
287 if (tileCells.empty()) {
291 uint16_t tileRowSpan = tileRowMax - tileRowMin + 1;
292 uint16_t tileColSpan = tileColMax - tileColMin + 1;
295 std::array<unsigned char, o2::itsmft::ClusterPattern::MaxPatternBytes> patt{};
296 for (
const auto& [
r,
c] : tileCells) {
297 uint32_t
ir =
r - tileRowMin;
298 uint32_t ic =
c - tileColMin;
299 int nbit =
ir * tileColSpan + ic;
300 patt[nbit >> 3] |= (0x1 << (7 - (nbit % 8)));
302 patterns.emplace_back(
static_cast<unsigned char>(tileRowSpan));
303 patterns.emplace_back(
static_cast<unsigned char>(tileColSpan));
304 const int nBytes = (tileRowSpan * tileColSpan + 7) / 8;
305 patterns.insert(patterns.end(), patt.begin(), patt.begin() + nBytes);
308 if (clusterLabels && digitLabels) {
309 const auto clsIdx =
static_cast<uint32_t
>(
clusters.size());
310 for (
const auto& cell : actsCluster.cells) {
311 uint16_t
r =
static_cast<uint16_t
>(cell.row);
312 uint16_t
c =
static_cast<uint16_t
>(cell.col);
313 if (
r >= tileRowMin && r <= tileRowMax && c >= tileColMin &&
c <= tileColMax) {
315 const auto& lbls = digitLabels->
getLabels(cell.digitIdx);
316 for (
const auto& lbl : lbls) {
327 cluster.
row = tileRowMin;
328 cluster.
col = tileColMin;
329 cluster.
size =
static_cast<uint16_t
>(tileCells.size());
331 cluster.
subDetID =
static_cast<int16_t
>(geom->getSubDetID(chipID));
332 cluster.
layer =
static_cast<int16_t
>(geom->getLayer(chipID));
333 cluster.
disk =
static_cast<int16_t
>(geom->getDisk(chipID));
340 std::array<unsigned char, o2::itsmft::ClusterPattern::MaxPatternBytes> patt{};
341 for (
const auto& cell : actsCluster.cells) {
342 uint32_t
ir =
static_cast<uint32_t
>(cell.row - rowMin);
343 uint32_t ic =
static_cast<uint32_t
>(cell.col - colMin);
344 int nbit =
ir * colSpan + ic;
345 patt[nbit >> 3] |= (0x1 << (7 - (nbit % 8)));
347 patterns.emplace_back(
static_cast<unsigned char>(rowSpan));
348 patterns.emplace_back(
static_cast<unsigned char>(colSpan));
349 const int nBytes = (rowSpan * colSpan + 7) / 8;
350 patterns.insert(patterns.end(), patt.begin(), patt.begin() + nBytes);
353 if (clusterLabels && digitLabels) {
354 const auto clsIdx =
static_cast<uint32_t
>(
clusters.size());
355 for (
const auto& cell : actsCluster.cells) {
357 const auto& lbls = digitLabels->
getLabels(cell.digitIdx);
358 for (
const auto& lbl : lbls) {
368 cluster.
row = rowMin;
369 cluster.
col = colMin;
370 cluster.
size =
static_cast<uint16_t
>(actsCluster.cells.size());
372 cluster.
subDetID =
static_cast<int16_t
>(geom->getSubDetID(chipID));
373 cluster.
layer =
static_cast<int16_t
>(geom->getLayer(chipID));
374 cluster.
disk =
static_cast<int16_t
>(geom->getDisk(chipID));
380 LOG(
debug) <<
" clusterization of chip " << chipID <<
" completed!";
382 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(),
383 outFirst,
static_cast<int>(
clusters.size()) - outFirst);
386 if (clusterMC2ROFs && !digMC2ROFs.empty()) {
387 clusterMC2ROFs->reserve(clusterMC2ROFs->size() + digMC2ROFs.size());
388 for (
const auto& in : digMC2ROFs) {
389 clusterMC2ROFs->emplace_back(in.eventRecordID, in.rofRecordID, in.minROF, in.maxROF);