28 float yPlaneMLOT)
noexcept
30 const uint8_t rowSpan = *patt++;
31 const uint8_t colSpan = *patt++;
32 const int nBytes = (rowSpan * colSpan + 7) / 8;
34 float cogDr{0.f}, cogDc{0.f};
35 int nPix{0}, pixIdx{0};
36 for (
int ib = 0; ib < nBytes; ib++) {
37 const uint8_t
byte = *patt++;
38 for (
int bit = 7; bit >= 0 && pixIdx < rowSpan * colSpan; bit--, pixIdx++) {
39 if (
byte & (1 << bit)) {
40 cogDr += pixIdx / colSpan;
41 cogDc += pixIdx % colSpan;
51 float x{0.f},
y{0.f},
z{0.f};
53 cluster.subDetID, cluster.layer, cluster.layer);
57 x -= cogDr * pitchRow;
58 z += cogDc * pitchCol;
60 if (cluster.subDetID == 0) {
74 gsl::span<const DigROFRecord> digitROFs,
76 std::vector<unsigned char>& patterns,
77 std::vector<o2::trkft3::ROFRecord>& clusterROFs,
82 mThread = std::make_unique<ClustererThread>(
this);
87 for (
size_t iROF = 0; iROF < digitROFs.size(); ++iROF) {
88 const auto& inROF = digitROFs[iROF];
89 const auto outFirst =
static_cast<int>(
clusters.size());
90 const int first = inROF.getFirstEntry();
91 const int nEntries = inROF.getNEntries();
94 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(), outFirst, 0);
100 mSortIdx.resize(nEntries);
101 std::iota(mSortIdx.begin(), mSortIdx.end(),
first);
102 std::sort(mSortIdx.begin(), mSortIdx.end(), [&
digits](
int a,
int b) {
103 const auto& da = digits[a];
104 const auto& db = digits[b];
105 if (da.getChipIndex() != db.getChipIndex()) {
106 return da.getChipIndex() < db.getChipIndex();
108 if (da.getColumn() != db.getColumn()) {
109 return da.getColumn() < db.getColumn();
111 return da.getRow() < db.getRow();
116 while (sliceStart < nEntries) {
117 const int chipFirst = sliceStart;
118 const uint16_t chipID =
digits[mSortIdx[sliceStart]].getChipIndex();
119 while (sliceStart < nEntries &&
digits[mSortIdx[sliceStart]].getChipIndex() == chipID) {
122 const int chipN = sliceStart - chipFirst;
124 mThread->processChip(
digits, chipFirst, chipN, &
clusters, &patterns, digitLabels, clusterLabels, geom);
127 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(),
128 outFirst,
static_cast<int>(
clusters.size()) - outFirst);
135 int chipFirst,
int chipN,
136 std::vector<ClusterType>* clustersOut,
137 std::vector<unsigned char>* patternsOut,
145 const auto& sortIdx = parent->
mSortIdx;
148 finishChipSingleHitFast(
digits, sortIdx[chipFirst], labelsDigPtr, labelsClusPtr, geom);
150 initChip(
digits, sortIdx[chipFirst], geom);
151 for (
int i = chipFirst + 1;
i < chipFirst + chipN; ++
i) {
152 updateChip(
digits, sortIdx[
i]);
154 finishChip(
digits, labelsDigPtr, labelsClusPtr, geom);
162 if (!patterns.empty()) {
163 patternsOut->insert(patternsOut->end(), patterns.begin(), patterns.end());
166 if (labelsClusPtr &&
labels.getNElements()) {
179 size = constants::moduleMLOT::chip::nRows + 2;
183 size = constants::VD::petal::layer::nRows[
layer] + 2;
189 column1 =
new int[
size];
190 column2 =
new int[
size];
191 column1[0] = column1[
size - 1] = -1;
192 column2[0] = column2[
size - 1] = -1;
198 preClusterHeads.clear();
199 preClusterIndices.clear();
202 currCol = pix.getColumn();
203 curr[pix.getRow()] = 0;
204 preClusterHeads.push_back(0);
205 preClusterIndices.push_back(0);
214 const auto& pix =
digits[ip];
215 uint16_t
row = pix.getRow();
217 if (currCol != pix.getColumn()) {
221 if (pix.getColumn() > currCol + 1) {
223 currCol = pix.getColumn();
224 addNewPreCluster(ip,
row);
228 currCol = pix.getColumn();
234 if (curr[
row - 1] >= 0) {
235 expandPreCluster(ip,
row, curr[
row - 1]);
239#ifdef _ALLOW_DIAGONAL_TRK_CLUSTERS_
240 int neighbours[]{curr[
row - 1], prev[
row], prev[
row + 1], prev[
row - 1]};
242 int neighbours[]{curr[
row - 1], prev[
row]};
244 for (
auto pci : neighbours) {
249 expandPreCluster(ip,
row, pci);
254 if (preClusterIndices[pci] < preClusterIndices[curr[
row]]) {
255 preClusterIndices[curr[
row]] = preClusterIndices[pci];
257 preClusterIndices[pci] = preClusterIndices[curr[
row]];
262 addNewPreCluster(ip,
row);
273 const uint16_t chipID =
digits[
pixels[0].second].getChipIndex();
275 for (
size_t i1 = 0; i1 < preClusterHeads.size(); ++i1) {
276 auto ci = preClusterIndices[i1];
282 uint32_t totalCharge = 0;
289 const auto& pixEntry =
pixels[next];
290 const auto& d =
digits[pixEntry.second];
291 uint16_t
r = d.getRow(),
c = d.getColumn();
292 pixArrBuff.emplace_back(
r,
c);
294 totalCharge += d.getCharge();
296 fetchMCLabels(pixEntry.second, labelsDigPtr, nlab);
298 next = pixEntry.first;
303 preClusterIndices[i1] = -1;
305 for (
size_t i2 = i1 + 1; i2 < preClusterHeads.size(); ++i2) {
306 if (preClusterIndices[i2] != ci) {
310 preClusterIndices[i2] = -1;
314 int subDetID = -1,
layer = -1;
320 const bool doLabels = (labelsClusPtr !=
nullptr);
321 if (
bbox.isAcceptableSize()) {
322 streamCluster(
bbox, pixArrBuff, totalCharge, doLabels, nlab, chipID, subDetID,
layer);
325 auto warnLeft = MaxHugeClusWarn - parent->mNHugeClus;
327 LOGP(warn,
"Splitting huge TRK cluster: chipID {}, rows {}:{} cols {}:{}{}",
329 warnLeft == 1 ?
" (further warnings muted)" :
"");
330 parent->mNHugeClus++;
339 std::vector<std::pair<uint16_t, uint16_t>> subPix;
340 uint32_t subCharge = 0;
341 for (
const auto& [
r,
c] : pixArrBuff) {
343 subPix.emplace_back(
r,
c);
347 if (!subPix.empty()) {
348 streamCluster(bboxT, subPix, subCharge, doLabels, nlab, chipID, subDetID,
layer);
366 const auto& d =
digits[hit];
367 const uint16_t chipID = d.getChipIndex();
368 const uint16_t
row = d.getRow();
369 const uint16_t
col = d.getColumn();
373 fetchMCLabels(hit, labelsDigPtr, nlab);
374 const auto cnt =
static_cast<uint32_t
>(
clusters.size());
375 for (
int i = nlab;
i--;) {
376 labels.addElement(cnt, labelsBuff[
i]);
381 patterns.emplace_back(1);
382 patterns.emplace_back(1);
383 patterns.emplace_back(0x80);
400 const std::vector<std::pair<uint16_t, uint16_t>>& pixbuf,
401 uint32_t totalCharge,
402 bool doLabels,
int nlab,
403 uint16_t chipID,
int subDetID,
int layer)
406 const auto cnt =
static_cast<uint32_t
>(
clusters.size());
407 for (
int i = nlab;
i--;) {
408 labels.addElement(cnt, labelsBuff[
i]);
412 const uint16_t rowSpanW =
bbox.rowSpan();
413 const uint16_t colSpanW =
bbox.colSpan();
416 std::array<unsigned char, o2::itsmft::ClusterPattern::MaxPatternBytes> patt{};
417 for (
const auto& [
r,
c] : pixbuf) {
419 int nbit =
ir * colSpanW + ic;
420 patt[nbit >> 3] |= (0x1 << (7 - (nbit % 8)));
422 patterns.emplace_back(
static_cast<unsigned char>(rowSpanW));
423 patterns.emplace_back(
static_cast<unsigned char>(colSpanW));
424 int nBytes = (rowSpanW * colSpanW + 7) / 8;
425 patterns.insert(patterns.end(), patt.begin(), patt.begin() + nBytes);
431 cluster.
size =
static_cast<uint16_t
>(pixbuf.size());
432 cluster.
subDetID =
static_cast<int16_t
>(subDetID);
441 if (nfilled >= MaxLabels) {
447 const auto& lbls = labelsDig->
getLabels(digID);
448 for (
int i = lbls.size();
i--;) {
451 if (labelsBuff[ic] == lbls[
i]) {
455 labelsBuff[nfilled++] = lbls[
i];
456 if (nfilled >= MaxLabels) {
std::vector< std::string > labels
int collectPixels(int which, int N, double *xyDxy, double *q)
Definition of the SegmentationChipclass.
Definition of the TRK cluster finder.
static constexpr uint8_t MaxRowSpan
static constexpr uint8_t MaxColSpan
std::vector< int > mSortIdx
reusable per-ROF sort buffer
static o2::math_utils::Point3D< float > getClusterLocalCoordinates(const ClusterType &cluster, const uint8_t *patt, float yPlaneMLOT=0.f) noexcept
virtual void process(gsl::span< const Digit > digits, gsl::span< const DigROFRecord > digitROFs, std::vector< ClusterType > &clusters, std::vector< unsigned char > &patterns, std::vector< o2::trkft3::ROFRecord > &clusterROFs, const ConstDigitTruth *digitLabels=nullptr, ClusterTruth *clusterLabels=nullptr)
int getSubDetID(int index) const
int getLayer(int index) const
local layer index within the sub-detector (0-based per VD/MLOT)
static GeometryTGeo * Instance()
static constexpr math_utils::Vector2D< float > flatToCurved(int layer, float xFlat, float yFlat) noexcept
static void detectorToLocalUnchecked(int row, int col, float &xRow, float &zCol, int subDetID, int layer, int disk) noexcept
static constexpr float PitchColVD
static constexpr float PitchColMLOT
static constexpr float PitchRowMLOT
static constexpr float PitchRowVD
GLboolean GLboolean GLboolean b
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
GLenum GLuint GLint GLint layer
GLboolean GLboolean GLboolean GLboolean a
GLdouble GLdouble GLdouble z
bool isInside(uint16_t r, uint16_t c) const
o2::InteractionRecord ir(0, 0)
std::vector< Cluster > clusters
std::vector< Digit > digits