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 <algorithm>
24#include <utility>
25#include <vector>
26#include <cstring>
27#include <memory>
28#include <gsl/span>
29
38
39#ifdef _PERFORM_TIMING_
40#include <TStopwatch.h>
41#endif
42
43class TTree;
44
45namespace o2
46{
47class MCCompLabel;
48namespace dataformats
49{
50template <typename T>
51class ConstMCTruthContainerView;
52template <typename T>
54} // namespace dataformats
55
56namespace its3
57{
58
59using CompClusCont = std::vector<itsmft::CompClusterExt>;
60using PatternCont = std::vector<unsigned char>;
61using ROFRecCont = std::vector<itsmft::ROFRecord>;
62
63// template <class CompClusCont, class PatternCont, class ROFRecCont> // container types (PMR or std::vectors)
64
66{
72 using Label = o2::MCCompLabel;
75
76 public:
77 static constexpr int MaxLabels = 10;
78 static constexpr int MaxHugeClusWarn = 5; // max number of warnings for HugeCluster
79
80 struct BBox {
81 uint16_t chipID = 0xffff;
82 uint16_t rowMin = 0xffff;
83 uint16_t colMin = 0xffff;
84 uint16_t rowMax = 0;
85 uint16_t colMax = 0;
86 BBox(uint16_t c) : chipID(c) {}
87 bool isInside(uint16_t row, uint16_t col) const { return row >= rowMin && row <= rowMax && col >= colMin && col <= colMax; }
88 [[nodiscard]] auto rowSpan() const { return rowMax - rowMin + 1; }
89 [[nodiscard]] auto colSpan() const { return colMax - colMin + 1; }
91 void clear()
92 {
93 rowMin = colMin = 0xffff;
94 rowMax = colMax = 0;
95 }
96 void adjust(uint16_t row, uint16_t col)
97 {
98 rowMin = std::min(row, rowMin);
99 rowMax = std::max(row, rowMax);
100 colMin = std::min(col, colMin);
101 colMax = std::max(col, colMax);
102 }
103 };
104
105 //=========================================================
107 struct ThreadStat {
108 uint16_t firstChip = 0;
109 uint16_t nChips = 0;
110 uint32_t firstClus = 0;
111 uint32_t firstPatt = 0;
112 uint32_t nClus = 0;
113 uint32_t nPatt = 0;
114 };
115
117 struct PreCluster {
118 int head = 0; // index of precluster head in the pixels
119 int index = 0;
120 };
121 Clusterer* parent = nullptr; // parent clusterer
122 int id = -1;
123 // buffers for entries in preClusterIndices in 2 columns, to avoid boundary checks, we reserve
124 // extra elements in the beginning and the end
125 int* column1 = nullptr;
126 int* column2 = nullptr;
127 int* curr = nullptr; // pointer on the 1st row of currently processed columnsX
128 int* prev = nullptr; // pointer on the 1st row of previously processed columnsX
130 // pixels[].first is the index of the next pixel of the same precluster in the pixels
131 // pixels[].second is the index of the referred pixel in the ChipPixelData (element of mChips)
132 std::vector<std::pair<int, uint32_t>> pixels;
133 uint16_t currCol = 0xffff;
134 bool noLeftCol = true;
135 std::array<Label, MaxLabels> labelsBuff;
136 std::vector<PixelData> pixArrBuff;
137 std::vector<PreCluster> preClusters;
138 //
143 std::vector<ThreadStat> stats; // statistics for each thread results, used at merging
146 void resetColumn(int* buff) const { std::memset(buff, -1, sizeof(int) * (size - 2)); }
147
149 void swapColumnBuffers() { std::swap(prev, curr); }
150
153 void expandPreCluster(uint32_t ip, uint16_t row, int preClusIndex)
154 {
155 auto& firstIndex = preClusters[preClusters[preClusIndex].index].head;
156 pixels.emplace_back(firstIndex, ip);
157 firstIndex = pixels.size() - 1;
158 curr[row] = preClusIndex;
159 }
160
162 void addNewPrecluster(uint32_t ip, uint16_t row)
163 {
164 int lastIndex = preClusters.size();
165 preClusters.emplace_back(pixels.size(), lastIndex);
166 // new head does not point yet (-1) on other pixels, store just the entry of the pixel in the ChipPixelData
167 pixels.emplace_back(-1, ip);
168 curr[row] = lastIndex; // store index of the new precluster in the current column buffer
169 }
170
171 void fetchMCLabels(int digID, const ConstMCTruth* labelsDig, int& nfilled);
172 void initChip(const ChipPixelData* curChipData, uint32_t first);
173 void updateChip(const ChipPixelData* curChipData, uint32_t ip);
174 void finishChip(ChipPixelData* curChipData, CompClusCont* compClus, PatternCont* patterns,
175 const ConstMCTruth* labelsDig, MCTruth* labelsClus);
176 void finishChipSingleHitFast(uint32_t hit, ChipPixelData* curChipData, CompClusCont* compClusPtr,
177 PatternCont* patternsPtr, const ConstMCTruth* labelsDigPtr, MCTruth* labelsClusPTr);
178 void process(uint16_t chip, uint16_t nChips, CompClusCont* compClusPtr, PatternCont* patternsPtr,
179 const ConstMCTruth* labelsDigPtr, MCTruth* labelsClPtr, const itsmft::ROFRecord& rofPtr);
180
182 {
183 delete[] column1;
184 delete[] column2;
185 }
186
187 ClustererThread(Clusterer* par = nullptr, int _id = -1) : parent(par), id(_id), curr(column2 + 1), prev(column1 + 1) {}
192 };
193 //=========================================================
194
195 Clusterer();
196 Clusterer(Clusterer&&) = delete;
198 ~Clusterer() = default;
199 Clusterer(const Clusterer&) = delete;
200 Clusterer& operator=(const Clusterer&) = delete;
201
202 void process(int nThreads, PixelReader& r, CompClusCont* compClus, PatternCont* patterns, ROFRecCont* vecROFRec, MCTruth* labelsCl = nullptr);
203
204 template <typename VCLUS, typename VPAT>
205 static void streamCluster(const std::vector<PixelData>& pixbuf, const std::array<Label, MaxLabels>* lblBuff, const BBox& bbox, const its3::LookUp& pattIdConverter,
206 VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isIB, bool isHuge = false);
207
208 bool isContinuousReadOut() const { return mContinuousReadout; }
209 void setContinuousReadOut(bool v) { mContinuousReadout = v; }
210
211 bool isDropHugeClusters() const { return mDropHugeClusters; }
212 void setDropHugeClusters(bool v) { mDropHugeClusters = v; }
213
214 int getMaxBCSeparationToMask() const { return mMaxBCSeparationToMask; }
215 void setMaxBCSeparationToMask(int n) { mMaxBCSeparationToMask = n; }
216
217 int getMaxRowColDiffToMask() const { return mMaxRowColDiffToMask; }
218 void setMaxRowColDiffToMask(int v) { mMaxRowColDiffToMask = v; }
219
220 int getMaxROFDepthToSquash(int layer = -1) const { return (layer < 0) ? mSquashingDepth : mSquashingLayerDepth[layer]; }
221 void setMaxROFDepthToSquash(int v) { mSquashingDepth = v; }
222 void addMaxROFDepthToSquash(int v) { mSquashingLayerDepth.push_back(v); }
223
224 int getMaxBCSeparationToSquash(int layer = -1) const { return (layer < 0) ? mMaxBCSeparationToSquash : mMaxBCSeparationToSquashLayer[layer]; }
225 void setMaxBCSeparationToSquash(int n) { mMaxBCSeparationToSquash = n; }
226 void addMaxBCSeparationToSquash(int n) { mMaxBCSeparationToSquashLayer.push_back(n); }
227
228 void print(bool showsTiming) const;
229 void reset();
230 void clear();
231
234 {
235 LOGP(info, "Setting TopologyDictionary with IB size={} & OB size={}", dict->getSize(true), dict->getSize(false));
236 mPattIdConverter.setDictionary(dict);
237 // dict->print();
238 }
239
240 TStopwatch& getTimer() { return mTimer; } // cannot be const
241 TStopwatch& getTimerMerge() { return mTimerMerge; } // cannot be const
242
243 void setNChips(int n)
244 {
245 mChips.resize(n);
246 mChipsOld.resize(n);
247 }
248
249 private:
250 void flushClusters(CompClusCont* compClus, MCTruth* labels);
251
252 // clusterization options
253 bool mContinuousReadout = true;
254 bool mDropHugeClusters = false;
255
257 int mMaxBCSeparationToMask = static_cast<int>(6000. / o2::constants::lhc::LHCBunchSpacingNS + 10);
258 int mMaxRowColDiffToMask = 0;
259 int mNHugeClus = 0;
260
262 int mSquashingDepth = 0;
263 int mMaxBCSeparationToSquash = 6000. / o2::constants::lhc::LHCBunchSpacingNS + 10;
264 std::vector<int> mSquashingLayerDepth;
265 std::vector<int> mMaxBCSeparationToSquashLayer;
266
267 std::vector<std::unique_ptr<ClustererThread>> mThreads; // buffers for threads
268 std::vector<ChipPixelData> mChips; // currently processed ROF's chips data
269 std::vector<ChipPixelData> mChipsOld; // previously processed ROF's chips data (for masking)
270 std::vector<ChipPixelData*> mFiredChipsPtr; // pointers on the fired chips data in the decoder cache
271
272 its3::LookUp mPattIdConverter;
273 //
274#ifdef _PERFORM_TIMING_
275 TStopwatch mTimer;
276 TStopwatch mTimerMerge;
277#endif
278};
279
280template <typename VCLUS, typename VPAT>
281void Clusterer::streamCluster(const std::vector<PixelData>& pixbuf, const std::array<Label, MaxLabels>* lblBuff, const Clusterer::BBox& bbox, const its3::LookUp& pattIdConverter,
282 VCLUS* compClusPtr, VPAT* patternsPtr, MCTruth* labelsClusPtr, int nlab, bool isIB, bool isHuge)
283{
284 if (labelsClusPtr && lblBuff) { // MC labels were requested
285 auto cnt = compClusPtr->size();
286 for (int i = 0; i < nlab; i++) {
287 labelsClusPtr->addElement(cnt, (*lblBuff)[i]);
288 }
289 }
290 auto colSpanW = bbox.colSpan();
291 auto rowSpanW = bbox.rowSpan();
292 // add to compact clusters, which must be always filled
293 std::array<unsigned char, itsmft::ClusterPattern::MaxPatternBytes> patt{};
294 for (const auto& pix : pixbuf) {
295 uint32_t ir = pix.getRowDirect() - bbox.rowMin, ic = pix.getCol() - bbox.colMin;
296 int nbits = ir * colSpanW + ic;
297 patt[nbits >> 3] |= (0x1 << (7 - (nbits % 8)));
298 }
299 uint16_t pattID = (isHuge || pattIdConverter.size(isIB) == 0) ? CompCluster::InvalidPatternID : pattIdConverter.findGroupID(rowSpanW, colSpanW, isIB, patt.data());
300 uint16_t row = bbox.rowMin, col = bbox.colMin;
301 LOGP(debug, "PattID: findGroupID({},{},{})={}", row, col, patt[0], pattID);
302 if (pattID == CompCluster::InvalidPatternID || pattIdConverter.isGroup(pattID, isIB)) {
303 if (pattID != CompCluster::InvalidPatternID) {
304 // For groupped topologies, the reference pixel is the COG pixel
305 float xCOG = 0., zCOG = 0.;
306 itsmft::ClusterPattern::getCOG(rowSpanW, colSpanW, patt.data(), xCOG, zCOG);
307 row += round(xCOG);
308 col += round(zCOG);
309 }
310 if (patternsPtr) {
311 patternsPtr->emplace_back((unsigned char)rowSpanW);
312 patternsPtr->emplace_back((unsigned char)colSpanW);
313 int nBytes = rowSpanW * colSpanW / 8;
314 if (((rowSpanW * colSpanW) % 8) != 0) {
315 nBytes++;
316 }
317 patternsPtr->insert(patternsPtr->end(), std::begin(patt), std::begin(patt) + nBytes);
318 }
319 }
320 compClusPtr->emplace_back(row, col, pattID, bbox.chipID);
321}
322
323} // namespace its3
324} // namespace o2
325#endif /* ALICEO2_ITS_CLUSTERER_H */
Definition of the ITSMFT compact cluster.
std::ostringstream debug
void print() const
int32_t i
Definition of the ITSMFT ROFrame (trigger) record.
std::vector< o2::MCCompLabel > labels
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.
Definition of the LookUp class for its3.
void addElement(uint32_t dataindex, TruthElement const &element, bool noElement=false)
void setDictionary(const its3::TopologyDictionary *dict)
Definition Clusterer.h:233
void setContinuousReadOut(bool v)
Definition Clusterer.h:209
static constexpr int MaxLabels
Definition Clusterer.h:77
int getMaxBCSeparationToSquash(int layer=-1) const
Definition Clusterer.h:224
void setDropHugeClusters(bool v)
Definition Clusterer.h:212
int getMaxBCSeparationToMask() const
Definition Clusterer.h:214
int getMaxRowColDiffToMask() const
Definition Clusterer.h:217
TStopwatch & getTimerMerge()
Definition Clusterer.h:241
int getMaxROFDepthToSquash(int layer=-1) const
Definition Clusterer.h:220
void addMaxBCSeparationToSquash(int n)
Definition Clusterer.h:226
Clusterer & operator=(Clusterer &&)=delete
void process(int nThreads, PixelReader &r, CompClusCont *compClus, PatternCont *patterns, ROFRecCont *vecROFRec, MCTruth *labelsCl=nullptr)
Definition Clusterer.cxx:29
void setMaxBCSeparationToMask(int n)
Definition Clusterer.h:215
void setNChips(int n)
Definition Clusterer.h:243
bool isContinuousReadOut() const
Definition Clusterer.h:208
Clusterer(Clusterer &&)=delete
void clear()
load the dictionary of cluster topologies
static void streamCluster(const std::vector< PixelData > &pixbuf, const std::array< Label, MaxLabels > *lblBuff, const BBox &bbox, const its3::LookUp &pattIdConverter, VCLUS *compClusPtr, VPAT *patternsPtr, MCTruth *labelsClusPtr, int nlab, bool isIB, bool isHuge=false)
Definition Clusterer.h:281
Clusterer & operator=(const Clusterer &)=delete
void addMaxROFDepthToSquash(int v)
Definition Clusterer.h:222
void setMaxRowColDiffToMask(int v)
Definition Clusterer.h:218
TStopwatch & getTimer()
Definition Clusterer.h:240
Clusterer(const Clusterer &)=delete
void setMaxBCSeparationToSquash(int n)
Definition Clusterer.h:225
bool isDropHugeClusters() const
Definition Clusterer.h:211
static constexpr int MaxHugeClusWarn
Definition Clusterer.h:78
void setMaxROFDepthToSquash(int v)
Definition Clusterer.h:221
int size(bool IB) const
Definition LookUp.h:40
void setDictionary(const TopologyDictionary *dict)
Definition LookUp.cxx:38
int getSize(bool IB) const
Returns the number of elements in the dicionary;.
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
static constexpr unsigned short InvalidPatternID
Definition CompCluster.h:46
< 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
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLuint index
Definition glcorearb.h:781
GLint first
Definition glcorearb.h:399
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
std::vector< unsigned char > PatternCont
Definition Clusterer.h:60
std::vector< itsmft::CompClusterExt > CompClusCont
Definition Clusterer.h:59
std::vector< itsmft::ROFRecord > ROFRecCont
Definition Clusterer.h:61
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
bool isInside(uint16_t row, uint16_t col) const
Definition Clusterer.h:87
bool isAcceptableSize() const
Definition Clusterer.h:90
void adjust(uint16_t row, uint16_t col)
Definition Clusterer.h:96
ClustererThread & operator=(ClustererThread &&)=delete
std::vector< PixelData > pixArrBuff
temporary buffer for building cluster labels
Definition Clusterer.h:136
void addNewPrecluster(uint32_t ip, uint16_t row)
Definition Clusterer.h:162
std::vector< ThreadStat > stats
Definition Clusterer.h:143
void finishChipSingleHitFast(uint32_t hit, ChipPixelData *curChipData, CompClusCont *compClusPtr, PatternCont *patternsPtr, const ConstMCTruth *labelsDigPtr, MCTruth *labelsClusPTr)
std::array< Label, MaxLabels > labelsBuff
Definition Clusterer.h:135
void process(uint16_t chip, uint16_t nChips, CompClusCont *compClusPtr, PatternCont *patternsPtr, const ConstMCTruth *labelsDigPtr, MCTruth *labelsClPtr, const itsmft::ROFRecord &rofPtr)
void updateChip(const ChipPixelData *curChipData, uint32_t ip)
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:153
std::vector< PreCluster > preClusters
temporary buffer for pattern calc.
Definition Clusterer.h:137
ClustererThread(const ClustererThread &)=delete
void fetchMCLabels(int digID, const ConstMCTruth *labelsDig, int &nfilled)
std::vector< std::pair< int, uint32_t > > pixels
Definition Clusterer.h:132
ClustererThread(ClustererThread &&)=delete
bool noLeftCol
flag that there is no column on the left to check
Definition Clusterer.h:134
ClustererThread & operator=(const ClustererThread &)=delete
ClustererThread(Clusterer *par=nullptr, int _id=-1)
Definition Clusterer.h:187
CompClusCont compClusters
preclusters info
Definition Clusterer.h:140
void initChip(const ChipPixelData *curChipData, uint32_t first)
void resetColumn(int *buff) const
reset column buffer, for the performance reasons we use memset
Definition Clusterer.h:146
void finishChip(ChipPixelData *curChipData, CompClusCont *compClus, PatternCont *patterns, const ConstMCTruth *labelsDig, MCTruth *labelsClus)
uint16_t currCol
Column being processed.
Definition Clusterer.h:133
methods and transient data used within a thread
Definition Clusterer.h:107
o2::InteractionRecord ir(0, 0)
std::vector< int > row
LookUp pattIdConverter