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 = 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 */
std::vector< std::string > labels
Definition of the ITSMFT compact cluster.
std::ostringstream debug
void print() const
int32_t i
Definition of the ITSMFT ROFrame (trigger) record.
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 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: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