29 float yPlaneMLOT)
noexcept
31 const uint8_t rowSpan = *patt++;
32 const uint8_t colSpan = *patt++;
33 const int nBytes = (rowSpan * colSpan + 7) / 8;
35 float cogDr{0.f}, cogDc{0.f};
36 int nPix{0}, pixIdx{0};
37 for (
int ib = 0; ib < nBytes; ib++) {
38 const uint8_t
byte = *patt++;
39 for (
int bit = 7; bit >= 0 && pixIdx < rowSpan * colSpan; bit--, pixIdx++) {
40 if (
byte & (1 << bit)) {
41 cogDr += pixIdx / colSpan;
42 cogDc += pixIdx % colSpan;
52 float x{0.f},
y{0.f},
z{0.f};
54 cluster.subDetID, cluster.layer, cluster.layer);
58 x -= cogDr * pitchRow;
59 z += cogDc * pitchCol;
61 if (cluster.subDetID == 0) {
75 gsl::span<const DigROFRecord> digitROFs,
77 std::vector<unsigned char>& patterns,
78 std::vector<o2::trkft3::ROFRecord>& clusterROFs,
83 mThread = std::make_unique<ClustererThread>(
this);
88 for (
size_t iROF = 0; iROF < digitROFs.size(); ++iROF) {
89 const auto& inROF = digitROFs[iROF];
90 const auto outFirst =
static_cast<int>(
clusters.size());
91 const int first = inROF.getFirstEntry();
92 const int nEntries = inROF.getNEntries();
95 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(), outFirst, 0);
101 mSortIdx.resize(nEntries);
102 std::iota(mSortIdx.begin(), mSortIdx.end(),
first);
103 std::sort(mSortIdx.begin(), mSortIdx.end(), [&
digits](
int a,
int b) {
104 const auto& da = digits[a];
105 const auto& db = digits[b];
106 if (da.getChipIndex() != db.getChipIndex()) {
107 return da.getChipIndex() < db.getChipIndex();
109 if (da.getColumn() != db.getColumn()) {
110 return da.getColumn() < db.getColumn();
112 return da.getRow() < db.getRow();
117 while (sliceStart < nEntries) {
118 const int chipFirst = sliceStart;
119 const uint16_t chipID =
digits[mSortIdx[sliceStart]].getChipIndex();
120 while (sliceStart < nEntries &&
digits[mSortIdx[sliceStart]].getChipIndex() == chipID) {
123 const int chipN = sliceStart - chipFirst;
125 mThread->processChip(
digits, chipFirst, chipN, &
clusters, &patterns, digitLabels, clusterLabels, geom);
128 clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(),
129 outFirst,
static_cast<int>(
clusters.size()) - outFirst);
136 int chipFirst,
int chipN,
137 std::vector<ClusterType>* clustersOut,
138 std::vector<unsigned char>* patternsOut,
146 const auto& sortIdx = parent->
mSortIdx;
149 finishChipSingleHitFast(
digits, sortIdx[chipFirst], labelsDigPtr, labelsClusPtr, geom);
151 initChip(
digits, sortIdx[chipFirst], geom);
152 for (
int i = chipFirst + 1;
i < chipFirst + chipN; ++
i) {
153 updateChip(
digits, sortIdx[
i]);
155 finishChip(
digits, labelsDigPtr, labelsClusPtr, geom);
163 if (!patterns.empty()) {
164 patternsOut->insert(patternsOut->end(), patterns.begin(), patterns.end());
167 if (labelsClusPtr &&
labels.getNElements()) {
177 const uint16_t chipID =
digits[
first].getChipIndex();
180 size = constants::moduleMLOT::chip::nRows + 2;
182 if (geom->getSubDetID(chipID) == 0) {
183 const int layer = geom->getLayer(chipID);
190 column1 =
new int[
size];
191 column2 =
new int[
size];
192 column1[0] = column1[
size - 1] = -1;
193 column2[0] = column2[
size - 1] = -1;
199 preClusterHeads.clear();
200 preClusterIndices.clear();
203 currCol = pix.getColumn();
204 curr[pix.getRow()] = 0;
205 preClusterHeads.push_back(0);
206 preClusterIndices.push_back(0);
215 const auto& pix =
digits[ip];
216 uint16_t
row = pix.getRow();
218 if (currCol != pix.getColumn()) {
222 if (pix.getColumn() > currCol + 1) {
224 currCol = pix.getColumn();
225 addNewPreCluster(ip,
row);
229 currCol = pix.getColumn();
235 if (curr[
row - 1] >= 0) {
236 expandPreCluster(ip,
row, curr[
row - 1]);
240#ifdef _ALLOW_DIAGONAL_TRK_CLUSTERS_
241 int neighbours[]{curr[
row - 1], prev[
row], prev[
row + 1], prev[
row - 1]};
243 int neighbours[]{curr[
row - 1], prev[
row]};
245 for (
auto pci : neighbours) {
250 expandPreCluster(ip,
row, pci);
255 if (preClusterIndices[pci] < preClusterIndices[curr[
row]]) {
256 preClusterIndices[curr[
row]] = preClusterIndices[pci];
258 preClusterIndices[pci] = preClusterIndices[curr[
row]];
263 addNewPreCluster(ip,
row);
274 const uint16_t chipID =
digits[
pixels[0].second].getChipIndex();
276 for (
size_t i1 = 0; i1 < preClusterHeads.size(); ++i1) {
277 auto ci = preClusterIndices[i1];
283 uint32_t totalCharge = 0;
290 const auto& pixEntry =
pixels[next];
291 const auto& d =
digits[pixEntry.second];
292 uint16_t
r = d.getRow(),
c = d.getColumn();
293 pixArrBuff.emplace_back(
r,
c);
295 totalCharge += d.getCharge();
297 fetchMCLabels(pixEntry.second, labelsDigPtr, nlab);
299 next = pixEntry.first;
304 preClusterIndices[i1] = -1;
306 for (
size_t i2 = i1 + 1; i2 < preClusterHeads.size(); ++i2) {
307 if (preClusterIndices[i2] != ci) {
311 preClusterIndices[i2] = -1;
315 int subDetID = -1,
layer = -1;
317 subDetID = geom->getSubDetID(chipID);
318 layer = geom->getLayer(chipID);
321 const bool doLabels = (labelsClusPtr !=
nullptr);
322 if (
bbox.isAcceptableSize()) {
323 streamCluster(
bbox, pixArrBuff, totalCharge, doLabels, nlab, chipID, subDetID,
layer);
326 auto warnLeft = MaxHugeClusWarn - parent->mNHugeClus;
328 LOGP(warn,
"Splitting huge TRK cluster: chipID {}, rows {}:{} cols {}:{}{}",
330 warnLeft == 1 ?
" (further warnings muted)" :
"");
331 parent->mNHugeClus++;
340 std::vector<std::pair<uint16_t, uint16_t>> subPix;
341 uint32_t subCharge = 0;
342 for (
const auto& [
r,
c] : pixArrBuff) {
344 subPix.emplace_back(
r,
c);
348 if (!subPix.empty()) {
349 streamCluster(bboxT, subPix, subCharge, doLabels, nlab, chipID, subDetID,
layer);
367 const auto& d =
digits[hit];
368 const uint16_t chipID = d.getChipIndex();
369 const uint16_t
row = d.getRow();
370 const uint16_t
col = d.getColumn();
374 fetchMCLabels(hit, labelsDigPtr, nlab);
375 const auto cnt =
static_cast<uint32_t
>(
clusters.size());
376 for (
int i = 0;
i < nlab;
i++) {
377 labels.addElement(cnt, labelsBuff[
i]);
382 patterns.emplace_back(1);
383 patterns.emplace_back(1);
384 patterns.emplace_back(0x80);
392 cluster.
subDetID = geom->getSubDetID(chipID);
393 cluster.
layer = geom->getLayer(chipID);
401 const std::vector<std::pair<uint16_t, uint16_t>>& pixbuf,
402 uint32_t totalCharge,
403 bool doLabels,
int nlab,
404 uint16_t chipID,
int subDetID,
int layer)
407 const auto cnt =
static_cast<uint32_t
>(
clusters.size());
408 for (
int i = 0;
i < nlab;
i++) {
409 labels.addElement(cnt, labelsBuff[
i]);
413 const uint16_t rowSpanW =
bbox.rowSpan();
414 const uint16_t colSpanW =
bbox.colSpan();
417 std::array<unsigned char, o2::itsmft::ClusterPattern::MaxPatternBytes> patt{};
418 for (
const auto& [
r,
c] : pixbuf) {
420 int nbit =
ir * colSpanW + ic;
421 patt[nbit >> 3] |= (0x1 << (7 - (nbit % 8)));
423 patterns.emplace_back(
static_cast<unsigned char>(rowSpanW));
424 patterns.emplace_back(
static_cast<unsigned char>(colSpanW));
425 int nBytes = (rowSpanW * colSpanW + 7) / 8;
426 patterns.insert(patterns.end(), patt.begin(), patt.begin() + nBytes);
432 cluster.
size =
static_cast<uint16_t
>(pixbuf.size());
433 cluster.
subDetID =
static_cast<int16_t
>(subDetID);
445 auto sortBuffer = [
this]() { std::sort(this->labelsBuff.begin(), this->labelsBuff.end(), [](
Label const&
a,
Label const&
b) { return a.getTrackID() < b.getTrackID(); }); };
448 for (
int ic = 0; ic < nfilled; ic++) {
449 if (labelsBuff[ic] ==
label) {
455 if (nfilled < MaxLabels) {
456 labelsBuff[nfilled++] =
label;
457 if (nfilled == MaxLabels) {
460 }
else if (labelsBuff.back().getTrackID() >
label.getTrackID()) {
461 labelsBuff.back() =
label;
std::vector< o2::MCCompLabel > labels
int collectPixels(int which, int N, double *xyDxy, double *q)
Definition of the SegmentationChipclass.
Definition of the GeometryTGeo class.
Definition of the TRK cluster finder.
static constexpr uint8_t MaxRowSpan
static constexpr uint8_t MaxColSpan
std::conditional_t< DetID==o2::detectors::DetID::TRK, o2::trk::GeometryTGeo, o2::ft3::GeometryTGeo > GeometryTGeo
The geometry that gives a chip's sub-detector and layer.
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)
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
GLuint GLsizei const GLchar * label
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