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(int layer = -1) const { return (layer < 0) ? mSquashingDepth : mSquashingLayerDepth[layer]; }
219 void setMaxROFDepthToSquash(int v) { mSquashingDepth = v; }
220 void addMaxROFDepthToSquash(int v) { mSquashingLayerDepth.push_back(v); }
221
222 int getMaxBCSeparationToSquash(int layer = -1) const { return (layer < 0) ? mMaxBCSeparationToSquash : mMaxBCSeparationToSquashLayer[layer]; }
223 void setMaxBCSeparationToSquash(int n) { mMaxBCSeparationToSquash = n; }
224 void addMaxBCSeparationToSquash(int n) { mMaxBCSeparationToSquashLayer.push_back(n); }
225
226 void print(bool showTiming = true) const;
227 void clear();
228 void reset();
229
230 void setNChips(int n)
231 {
232 mChips.resize(n);
233 mChipsOld.resize(n);
234 }
235
237 void loadDictionary(const std::string& fileName) { mPattIdConverter.loadDictionary(fileName); }
238 void setDictionary(const TopologyDictionary* dict) { mPattIdConverter.setDictionary(dict); }
239
240 TStopwatch& getTimer() { return mTimer; } // cannot be const
241 TStopwatch& getTimerMerge() { return mTimerMerge; } // cannot be const
242
243 private:
244 void flushClusters(CompClusCont* compClus, MCTruth* labels);
245
246 // clusterization options
247 bool mContinuousReadout = true;
248 bool mDropHugeClusters = false;
249
251 int mMaxBCSeparationToMask = 6000. / o2::constants::lhc::LHCBunchSpacingNS + 10;
252 int mMaxRowColDiffToMask = 0;
253 int mNHugeClus = 0;
254
256 int mSquashingDepth = 0;
257 int mMaxBCSeparationToSquash = 6000. / o2::constants::lhc::LHCBunchSpacingNS + 10;
258 std::vector<int> mSquashingLayerDepth;
259 std::vector<int> mMaxBCSeparationToSquashLayer;
260
261 std::vector<std::unique_ptr<ClustererThread>> mThreads; // buffers for threads
262 std::vector<ChipPixelData> mChips; // currently processed ROF's chips data
263 std::vector<ChipPixelData> mChipsOld; // previously processed ROF's chips data (for masking)
264 std::vector<ChipPixelData*> mFiredChipsPtr; // pointers on the fired chips data in the decoder cache
265
266 LookUp mPattIdConverter;
267
268 TStopwatch mTimer;
269 TStopwatch mTimerMerge;
270};
271
272template <typename VCLUS, typename VPAT>
273void Clusterer::streamCluster(const std::vector<PixelData>& pixbuf, const std::array<Label, MaxLabels>* lblBuff, const Clusterer::BBox& bbox, const LookUp& pattIdConverter,
274 VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isHuge)
275{
276 if (labelsClusPtr && lblBuff) { // MC labels were requested
277 auto cnt = compClusPtr->size();
278 for (int i = nlab; i--;) {
279 labelsClusPtr->addElement(cnt, (*lblBuff)[i]);
280 }
281 }
282 auto colSpanW = bbox.colSpan();
283 auto rowSpanW = bbox.rowSpan();
284 // add to compact clusters, which must be always filled
285 std::array<unsigned char, ClusterPattern::MaxPatternBytes> patt{};
286 for (const auto& pix : pixbuf) {
287 uint32_t ir = pix.getRowDirect() - bbox.rowMin, ic = pix.getCol() - bbox.colMin;
288 int nbits = ir * colSpanW + ic;
289 patt[nbits >> 3] |= (0x1 << (7 - (nbits % 8)));
290 }
291 uint16_t pattID = (isHuge || pattIdConverter.size() == 0) ? CompCluster::InvalidPatternID : pattIdConverter.findGroupID(rowSpanW, colSpanW, patt.data());
292 uint16_t row = bbox.rowMin, col = bbox.colMin;
293 if (pattID == CompCluster::InvalidPatternID || pattIdConverter.isGroup(pattID)) {
294 if (pattID != CompCluster::InvalidPatternID) {
295 // For grouped topologies, the reference pixel is the COG pixel
296 float xCOG = 0., zCOG = 0.;
297 ClusterPattern::getCOG(rowSpanW, colSpanW, patt.data(), xCOG, zCOG);
298 row += round(xCOG);
299 col += round(zCOG);
300 }
301 if (patternsPtr) {
302 patternsPtr->emplace_back((unsigned char)rowSpanW);
303 patternsPtr->emplace_back((unsigned char)colSpanW);
304 int nBytes = rowSpanW * colSpanW / 8;
305 if (((rowSpanW * colSpanW) % 8) != 0) {
306 nBytes++;
307 }
308 patternsPtr->insert(patternsPtr->end(), std::begin(patt), std::begin(patt) + nBytes);
309 }
310 }
311 compClusPtr->emplace_back(row, col, pattID, bbox.chipID);
312}
313
314} // namespace itsmft
315} // namespace o2
316#endif /* ALICEO2_ITS_CLUSTERER_H */
std::vector< std::string > labels
Definition of the ITSMFT compact cluster.
void print() const
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
void setMaxBCSeparationToMask(int n)
Definition Clusterer.h:213
TStopwatch & getTimerMerge()
Definition Clusterer.h:241
Clusterer & operator=(const Clusterer &)=delete
int getMaxROFDepthToSquash(int layer=-1) const
Definition Clusterer.h:218
bool isDropHugeClusters() const
Definition Clusterer.h:209
void setDictionary(const TopologyDictionary *dict)
Definition Clusterer.h:238
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:223
void addMaxBCSeparationToSquash(int n)
Definition Clusterer.h:224
void setMaxROFDepthToSquash(int v)
Definition Clusterer.h:219
bool isContinuousReadOut() const
Definition Clusterer.h:206
int getMaxBCSeparationToSquash(int layer=-1) const
Definition Clusterer.h:222
void addMaxROFDepthToSquash(int v)
Definition Clusterer.h:220
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:273
Clusterer(const Clusterer &)=delete
TStopwatch & getTimer()
Definition Clusterer.h:240
void loadDictionary(const std::string &fileName)
Definition Clusterer.h:237
void setNChips(int n)
load the dictionary of cluster topologies
Definition Clusterer.h:230
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
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
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