Project
Loading...
Searching...
No Matches
Clusterer.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14#ifndef ALICEO2_ITS_CLUSTERER_H
15#define ALICEO2_ITS_CLUSTERER_H
16
17#define _PERFORM_TIMING_
18
19// uncomment this to not allow diagonal clusters, e.g. like |* |
20// | *|
21#define _ALLOW_DIAGONAL_ALPIDE_CLUSTERS_
22
23#include <utility>
24#include <vector>
25#include <cstring>
26#include <memory>
27#include <gsl/span>
36#include "Rtypes.h"
37
38#ifdef _PERFORM_TIMING_
39#include <TStopwatch.h>
40#endif
41
42class TTree;
43
44namespace o2
45{
46class MCCompLabel;
47namespace dataformats
48{
49template <typename T>
50class ConstMCTruthContainerView;
51template <typename T>
53} // namespace dataformats
54
55namespace itsmft
56{
57
58using CompClusCont = std::vector<CompClusterExt>;
59using PatternCont = std::vector<unsigned char>;
60using ROFRecCont = std::vector<ROFRecord>;
61
62// template <class CompClusCont, class PatternCont, class ROFRecCont> // container types (PMR or std::vectors)
63
65{
71 using Label = o2::MCCompLabel;
74
75 public:
76 static constexpr int MaxLabels = 10;
77 static constexpr int MaxHugeClusWarn = 5; // max number of warnings for HugeCluster
78
79 struct BBox {
80 uint16_t chipID = 0xffff;
81 uint16_t rowMin = 0xffff;
82 uint16_t colMin = 0xffff;
83 uint16_t rowMax = 0;
84 uint16_t colMax = 0;
85 BBox(uint16_t c) : chipID(c) {}
86 bool isInside(uint16_t row, uint16_t col) const { return row >= rowMin && row <= rowMax && col >= colMin && col <= colMax; }
87 auto rowSpan() const { return rowMax - rowMin + 1; }
88 auto colSpan() const { return colMax - colMin + 1; }
90 void clear()
91 {
92 rowMin = colMin = 0xffff;
93 rowMax = colMax = 0;
94 }
95 void adjust(uint16_t row, uint16_t col)
96 {
97 if (row < rowMin) {
98 rowMin = row;
99 }
100 if (row > rowMax) {
101 rowMax = row;
102 }
103 if (col < colMin) {
104 colMin = col;
105 }
106 if (col > colMax) {
107 colMax = col;
108 }
109 }
110 };
111
112 //=========================================================
114 struct ThreadStat {
115 uint16_t firstChip = 0;
116 uint16_t nChips = 0;
117 uint32_t firstClus = 0;
118 uint32_t firstPatt = 0;
119 uint32_t nClus = 0;
120 uint32_t nPatt = 0;
121 };
122
124 struct PreCluster {
125 int head = 0; // index of precluster head in the pixels
126 int index = 0;
127 };
128 int id = -1;
129 Clusterer* parent = nullptr; // parent clusterer
130 // buffers for entries in preClusterIndices in 2 columns, to avoid boundary checks, we reserve
131 // extra elements in the beginning and the end
134 int* curr = nullptr; // pointer on the 1st row of currently processed columnsX
135 int* prev = nullptr; // pointer on the 1st row of previously processed columnsX
136 // pixels[].first is the index of the next pixel of the same precluster in the pixels
137 // pixels[].second is the index of the referred pixel in the ChipPixelData (element of mChips)
138 std::vector<std::pair<int, uint32_t>> pixels;
139 uint16_t currCol = 0xffff;
140 bool noLeftCol = true;
141 std::array<Label, MaxLabels> labelsBuff;
142 std::vector<PixelData> pixArrBuff;
143 std::vector<PreCluster> preClusters;
144 //
149 std::vector<ThreadStat> stats; // statistics for each thread results, used at merging
152 void resetColumn(int* buff) { std::memset(buff, -1, sizeof(int) * SegmentationAlpide::NRows); }
153
155 void swapColumnBuffers() { std::swap(prev, curr); }
156
158 void expandPreCluster(uint32_t ip, uint16_t row, int preClusIndex)
159 {
160 auto& firstIndex = preClusters[preClusters[preClusIndex].index].head;
161 pixels.emplace_back(firstIndex, ip);
162 firstIndex = pixels.size() - 1;
163 curr[row] = preClusIndex;
164 }
165
167 void addNewPrecluster(uint32_t ip, uint16_t row)
168 {
169 int lastIndex = preClusters.size();
170 preClusters.emplace_back(pixels.size(), lastIndex);
171 // new head does not point yet (-1) on other pixels, store just the entry of the pixel in the ChipPixelData
172 pixels.emplace_back(-1, ip);
173 curr[row] = lastIndex; // store index of the new precluster in the current column buffer
174 }
175
176 void fetchMCLabels(int digID, const ConstMCTruth* labelsDig, int& nfilled);
177 void initChip(const ChipPixelData* curChipData, uint32_t first);
178 void updateChip(const ChipPixelData* curChipData, uint32_t ip);
179 void finishChip(ChipPixelData* curChipData, CompClusCont* compClus, PatternCont* patterns,
180 const ConstMCTruth* labelsDig, MCTruth* labelsClus);
181 void finishChipSingleHitFast(uint32_t hit, ChipPixelData* curChipData, CompClusCont* compClusPtr,
182 PatternCont* patternsPtr, const ConstMCTruth* labelsDigPtr, MCTruth* labelsClusPTr);
183 void process(uint16_t chip, uint16_t nChips, CompClusCont* compClusPtr, PatternCont* patternsPtr,
184 const ConstMCTruth* labelsDigPtr, MCTruth* labelsClPtr, const ROFRecord& rofPtr);
185
186 ClustererThread(Clusterer* par = nullptr, int _id = -1) : parent(par), id(_id), curr(column2 + 1), prev(column1 + 1)
187 {
188 std::fill(std::begin(column1), std::end(column1), -1);
189 std::fill(std::begin(column2), std::end(column2), -1);
190 }
191 };
192 //=========================================================
193
194 Clusterer();
195 ~Clusterer() = default;
196
197 Clusterer(const Clusterer&) = delete;
198 Clusterer& operator=(const Clusterer&) = delete;
199
200 void process(int nThreads, PixelReader& r, CompClusCont* compClus, PatternCont* patterns, ROFRecCont* vecROFRec, MCTruth* labelsCl = nullptr);
201
202 template <typename VCLUS, typename VPAT>
203 static void streamCluster(const std::vector<PixelData>& pixbuf, const std::array<Label, MaxLabels>* lblBuff, const BBox& bbox, const LookUp& pattIdConverter,
204 VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isHuge = false);
205
206 bool isContinuousReadOut() const { return mContinuousReadout; }
207 void setContinuousReadOut(bool v) { mContinuousReadout = v; }
208
209 bool isDropHugeClusters() const { return mDropHugeClusters; }
210 void setDropHugeClusters(bool v) { mDropHugeClusters = v; }
211
212 int getMaxBCSeparationToMask() const { return mMaxBCSeparationToMask; }
213 void setMaxBCSeparationToMask(int n) { mMaxBCSeparationToMask = n; }
214
215 int getMaxRowColDiffToMask() const { return mMaxRowColDiffToMask; }
216 void setMaxRowColDiffToMask(int v) { mMaxRowColDiffToMask = v; }
217
218 int getMaxROFDepthToSquash() const { return mSquashingDepth; }
219 void setMaxROFDepthToSquash(int v) { mSquashingDepth = v; }
220
221 int getMaxBCSeparationToSquash() const { return mMaxBCSeparationToSquash; }
222 void setMaxBCSeparationToSquash(int n) { mMaxBCSeparationToSquash = n; }
223
224 void print() const;
225 void clear();
226 void reset();
227
228 void setNChips(int n)
229 {
230 mChips.resize(n);
231 mChipsOld.resize(n);
232 }
233
235 void loadDictionary(const std::string& fileName) { mPattIdConverter.loadDictionary(fileName); }
236 void setDictionary(const TopologyDictionary* dict) { mPattIdConverter.setDictionary(dict); }
237
238 TStopwatch& getTimer() { return mTimer; } // cannot be const
239 TStopwatch& getTimerMerge() { return mTimerMerge; } // cannot be const
240
241 private:
242 void flushClusters(CompClusCont* compClus, MCTruth* labels);
243
244 // clusterization options
245 bool mContinuousReadout = true;
246 bool mDropHugeClusters = false;
247
249 int mMaxBCSeparationToMask = 6000. / o2::constants::lhc::LHCBunchSpacingNS + 10;
250 int mMaxRowColDiffToMask = 0;
251 int mNHugeClus = 0;
252
254 int mSquashingDepth = 0;
255 int mMaxBCSeparationToSquash = 6000. / o2::constants::lhc::LHCBunchSpacingNS + 10;
256
257 std::vector<std::unique_ptr<ClustererThread>> mThreads; // buffers for threads
258 std::vector<ChipPixelData> mChips; // currently processed ROF's chips data
259 std::vector<ChipPixelData> mChipsOld; // previously processed ROF's chips data (for masking)
260 std::vector<ChipPixelData*> mFiredChipsPtr; // pointers on the fired chips data in the decoder cache
261
262 LookUp mPattIdConverter;
263
264 TStopwatch mTimer;
265 TStopwatch mTimerMerge;
266};
267
268template <typename VCLUS, typename VPAT>
269void Clusterer::streamCluster(const std::vector<PixelData>& pixbuf, const std::array<Label, MaxLabels>* lblBuff, const Clusterer::BBox& bbox, const LookUp& pattIdConverter,
270 VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isHuge)
271{
272 if (labelsClusPtr && lblBuff) { // MC labels were requested
273 auto cnt = compClusPtr->size();
274 for (int i = nlab; i--;) {
275 labelsClusPtr->addElement(cnt, (*lblBuff)[i]);
276 }
277 }
278 auto colSpanW = bbox.colSpan();
279 auto rowSpanW = bbox.rowSpan();
280 // add to compact clusters, which must be always filled
281 std::array<unsigned char, ClusterPattern::MaxPatternBytes> patt{};
282 for (const auto& pix : pixbuf) {
283 uint32_t ir = pix.getRowDirect() - bbox.rowMin, ic = pix.getCol() - bbox.colMin;
284 int nbits = ir * colSpanW + ic;
285 patt[nbits >> 3] |= (0x1 << (7 - (nbits % 8)));
286 }
287 uint16_t pattID = (isHuge || pattIdConverter.size() == 0) ? CompCluster::InvalidPatternID : pattIdConverter.findGroupID(rowSpanW, colSpanW, patt.data());
288 uint16_t row = bbox.rowMin, col = bbox.colMin;
289 if (pattID == CompCluster::InvalidPatternID || pattIdConverter.isGroup(pattID)) {
290 if (pattID != CompCluster::InvalidPatternID) {
291 // For groupped topologies, the reference pixel is the COG pixel
292 float xCOG = 0., zCOG = 0.;
293 ClusterPattern::getCOG(rowSpanW, colSpanW, patt.data(), xCOG, zCOG);
294 row += round(xCOG);
295 col += round(zCOG);
296 }
297 if (patternsPtr) {
298 patternsPtr->emplace_back((unsigned char)rowSpanW);
299 patternsPtr->emplace_back((unsigned char)colSpanW);
300 int nBytes = rowSpanW * colSpanW / 8;
301 if (((rowSpanW * colSpanW) % 8) != 0) {
302 nBytes++;
303 }
304 patternsPtr->insert(patternsPtr->end(), std::begin(patt), std::begin(patt) + nBytes);
305 }
306 }
307 compClusPtr->emplace_back(row, col, pattID, bbox.chipID);
308}
309
310} // namespace itsmft
311} // namespace o2
312#endif /* ALICEO2_ITS_CLUSTERER_H */
std::vector< std::string > labels
Definition of the ITSMFT compact cluster.
int32_t i
Definition of the ITSMFT ROFrame (trigger) record.
Definition of the LookUp class.
Header to collect LHC related constants.
Transient data classes for single pixel and set of pixels from current chip.
Abstract class for Alpide data reader class.
uint32_t col
Definition RawData.h:4
uint32_t c
Definition RawData.h:2
Definition of the SegmentationAlpide class.
void addElement(uint32_t dataindex, TruthElement const &element, bool noElement=false)
static int getCOG(int rowSpan, int colSpan, const unsigned char patt[MaxPatternBytes], float &xCOG, float &zCOG)
Static: Compute pattern's COG position. Returns the number of fired pixels.
static constexpr uint8_t MaxRowSpan
static constexpr uint8_t MaxColSpan
int getMaxBCSeparationToMask() const
Definition Clusterer.h:212
void setMaxRowColDiffToMask(int v)
Definition Clusterer.h:216
int getMaxROFDepthToSquash() const
Definition Clusterer.h:218
void setMaxBCSeparationToMask(int n)
Definition Clusterer.h:213
TStopwatch & getTimerMerge()
Definition Clusterer.h:239
Clusterer & operator=(const Clusterer &)=delete
bool isDropHugeClusters() const
Definition Clusterer.h:209
void setDictionary(const TopologyDictionary *dict)
Definition Clusterer.h:236
int getMaxBCSeparationToSquash() const
Definition Clusterer.h:221
static constexpr int MaxLabels
Definition Clusterer.h:76
void setContinuousReadOut(bool v)
Definition Clusterer.h:207
int getMaxRowColDiffToMask() const
Definition Clusterer.h:215
void setMaxBCSeparationToSquash(int n)
Definition Clusterer.h:222
void setMaxROFDepthToSquash(int v)
Definition Clusterer.h:219
bool isContinuousReadOut() const
Definition Clusterer.h:206
void setDropHugeClusters(bool v)
Definition Clusterer.h:210
static constexpr int MaxHugeClusWarn
Definition Clusterer.h:77
static void streamCluster(const std::vector< PixelData > &pixbuf, const std::array< Label, MaxLabels > *lblBuff, const BBox &bbox, const LookUp &pattIdConverter, VCLUS *compClusPtr, VPAT *patternsPtr, MCTruth *labelsClusPtr, int nlab, bool isHuge=false)
Definition Clusterer.h:269
Clusterer(const Clusterer &)=delete
TStopwatch & getTimer()
Definition Clusterer.h:238
void loadDictionary(const std::string &fileName)
Definition Clusterer.h:235
void setNChips(int n)
load the dictionary of cluster topologies
Definition Clusterer.h:228
static constexpr unsigned short InvalidPatternID
Definition CompCluster.h:46
int size() const
Definition LookUp.h:44
void setDictionary(const TopologyDictionary *dict)
Definition LookUp.cxx:42
void loadDictionary(std::string fileName)
Definition LookUp.cxx:36
< single pixel datum, with possibility to set a flag of pixel being masked out
Definition PixelData.h:33
PixelReader class for the ITSMFT.
Definition PixelReader.h:34
GLdouble n
Definition glcorearb.h:1982
const GLdouble * v
Definition glcorearb.h:832
GLuint index
Definition glcorearb.h:781
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
Definition glcorearb.h:275
GLboolean r
Definition glcorearb.h:1233
GLuint id
Definition glcorearb.h:650
constexpr double LHCBunchSpacingNS
std::vector< unsigned char > PatternCont
Definition Clusterer.h:59
std::vector< ROFRecord > ROFRecCont
Definition Clusterer.h:60
std::vector< CompClusterExt > CompClusCont
Definition Clusterer.h:58
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void adjust(uint16_t row, uint16_t col)
Definition Clusterer.h:95
bool isInside(uint16_t row, uint16_t col) const
Definition Clusterer.h:86
bool isAcceptableSize() const
Definition Clusterer.h:89
int column2[SegmentationAlpide::NRows+2]
Definition Clusterer.h:133
int column1[SegmentationAlpide::NRows+2]
Definition Clusterer.h:132
std::vector< PixelData > pixArrBuff
temporary buffer for building cluster labels
Definition Clusterer.h:142
std::vector< PreCluster > preClusters
temporary buffer for pattern calc.
Definition Clusterer.h:143
void addNewPrecluster(uint32_t ip, uint16_t row)
Definition Clusterer.h:167
void initChip(const ChipPixelData *curChipData, uint32_t first)
void finishChip(ChipPixelData *curChipData, CompClusCont *compClus, PatternCont *patterns, const ConstMCTruth *labelsDig, MCTruth *labelsClus)
uint16_t currCol
Column being processed.
Definition Clusterer.h:139
std::vector< std::pair< int, uint32_t > > pixels
Definition Clusterer.h:138
bool noLeftCol
flag that there is no column on the left to check
Definition Clusterer.h:140
void expandPreCluster(uint32_t ip, uint16_t row, int preClusIndex)
add new precluster at given row of current column for the fired pixel with index ip in the ChipPixelD...
Definition Clusterer.h:158
void fetchMCLabels(int digID, const ConstMCTruth *labelsDig, int &nfilled)
ClustererThread(Clusterer *par=nullptr, int _id=-1)
Definition Clusterer.h:186
void swapColumnBuffers()
add cluster at row (entry ip in the ChipPixeData) to the precluster with given index
Definition Clusterer.h:155
void finishChipSingleHitFast(uint32_t hit, ChipPixelData *curChipData, CompClusCont *compClusPtr, PatternCont *patternsPtr, const ConstMCTruth *labelsDigPtr, MCTruth *labelsClusPTr)
std::array< Label, MaxLabels > labelsBuff
Definition Clusterer.h:141
std::vector< ThreadStat > stats
Definition Clusterer.h:149
CompClusCont compClusters
preclusters info
Definition Clusterer.h:146
void resetColumn(int *buff)
reset column buffer, for the performance reasons we use memset
Definition Clusterer.h:152
void updateChip(const ChipPixelData *curChipData, uint32_t ip)
methods and transient data used within a thread
Definition Clusterer.h:114
o2::InteractionRecord ir(0, 0)
std::vector< int > row
LookUp pattIdConverter