Project
Loading...
Searching...
No Matches
ROFViews.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
12#ifndef ALICEO2_ITSMFT_TRACKING_ROFVIEWS_H_
13#define ALICEO2_ITSMFT_TRACKING_ROFVIEWS_H_
14
15#include <cassert>
16#include <cstddef>
17#include <cstdint>
18#include <string>
19
20#ifndef GPUCA_GPUCODE
21#include <format>
22#endif
23
28#include "GPUCommonMath.h"
29#include "GPUCommonDef.h"
30
31#ifndef GPUCA_GPUCODE
32#include "Framework/Logger.h"
33#endif
34
36{
37
44
50
51 GPUhdi() BCType getROFStartInBC(BCType rofId) const noexcept
52 {
53 assert(rofId < mNROFsTF && rofId >= 0);
54 return (mROFLength * rofId) + mROFDelay + mROFBias;
55 }
56
57 GPUhdi() BCType getROFEndInBC(BCType rofId) const noexcept
58 {
59 assert(rofId < mNROFsTF);
60 return getROFStartInBC(rofId) + mROFLength;
61 }
62
63 GPUhdi() o2::its::TimeEstBC getROFTimeBounds(BCType rofId, bool withError = false) const noexcept
64 {
65 if (withError) {
66 int64_t start = getROFStartInBC(rofId);
67 int64_t end = getROFEndInBC(rofId);
68 start = o2::gpu::CAMath::Max(start - mROFAddTimeErr, int64_t(0));
70 return {static_cast<BCType>(start), static_cast<o2::its::TimeStampErrorType>(end - start)};
71 }
72 return {getROFStartInBC(rofId), static_cast<o2::its::TimeStampErrorType>(mROFLength)};
73 }
74
75 GPUhdi() BCType getROF(BCType bc) const noexcept
76 {
78 if (bc <= offset) {
79 return 0;
80 }
81 return (bc - offset) / mROFLength;
82 }
83
84 GPUhdi() BCType getROF(o2::its::TimeStamp ts) const noexcept
85 {
87 const BCType bc = (ts.getTimeStamp() < ts.getTimeStampError()) ? BCType(0) : static_cast<BCType>(o2::gpu::CAMath::Floor(ts.getTimeStamp() - ts.getTimeStampError()));
88 if (bc <= offset) {
89 return 0;
90 }
91 return (bc - offset) / mROFLength;
92 }
93
94 GPUhdi() BCType getROF(float time) const noexcept
95 {
96 const float offset = static_cast<float>(mROFDelay + mROFBias);
97 if (time <= offset) {
98 return 0;
99 }
100 return static_cast<BCType>((time - offset) / mROFLength);
101 }
102
103 GPUhdi() bool intersectROF(BCType rof, float lower, float upper) const noexcept
104 {
105 const auto rofTS = getROFTimeBounds(rof, true);
106 return static_cast<float>(rofTS.upper()) > lower && upper > static_cast<float>(rofTS.lower());
107 }
108
109 GPUhdi() BCRange getROFRange(o2::its::TimeStamp ts) const noexcept
110 {
111 return getROFRange(ts.getTimeStamp() - ts.getTimeStampError(), ts.getTimeStamp() + ts.getTimeStampError());
112 }
113
114 GPUhdi() BCRange getROFRange(o2::its::TimeEstBC ts) const noexcept
115 {
116 return getROFRange(static_cast<float>(ts.lower()), static_cast<float>(ts.upper()));
117 }
118
119 GPUhdi() BCRange getROFRange(float lower, float upper) const noexcept
120 {
121 const BCType maxROF = mNROFsTF - 1;
122 BCType first = o2::gpu::CAMath::Clamp(getROF(lower - mROFAddTimeErr), BCType{0}, maxROF);
123 BCType last = o2::gpu::CAMath::Clamp(getROF(upper + mROFAddTimeErr), BCType{0}, maxROF);
124
125 if (first <= last && !intersectROF(first, lower, upper)) {
126 ++first;
127 }
128 if (last >= first && !intersectROF(last, lower, upper)) {
129 --last;
130 }
131 return {first, first <= last ? static_cast<BCType>(last - first + 1) : BCType{0}};
132 }
133
134#ifndef GPUCA_GPUCODE
135 GPUh() std::string asString() const
136 {
137 return std::format("NROFsPerTF {:4} ROFLength {:4} ({:4} per Orbit) ROFDelay {:4} ROFBias {:4} ROFAddTimeErr {:4}", mNROFsTF, mROFLength, (o2::constants::lhc::LHCMaxBunches / mROFLength), mROFDelay, mROFBias, mROFAddTimeErr);
138 }
139
140 GPUh() void print() const
141 {
142 LOG(info) << asString();
143 }
144#endif
145};
146
147template <typename TableEntry, typename TableIndex>
149 const TableEntry* mFlatTable{nullptr};
150 const TableIndex* mIndices{nullptr};
151 const ROFTimingLayer* mLayers{nullptr};
152 int32_t mLayerCount{0};
153
154 GPUhdi() const ROFTimingLayer& getLayer(int32_t layer) const noexcept
155 {
156 assert(layer >= 0 && layer < mLayerCount);
157 return mLayers[layer];
158 }
159
160 GPUh() int32_t getClock() const noexcept
161 {
162 int32_t fastest = 0;
163 uint32_t maxNROFs{0};
164 for (int32_t iL{0}; iL < mLayerCount; ++iL) {
165 const auto& layer = getLayer(iL);
166 if (layer.mNROFsTF > maxNROFs) {
167 fastest = iL;
168 maxNROFs = layer.mNROFsTF;
169 }
170 }
171 return fastest;
172 }
173
174 GPUh() const ROFTimingLayer& getClockLayer() const noexcept { return mLayers[getClock()]; }
175
176 GPUhdi() const TableEntry& getOverlap(int32_t from, int32_t to, size_t rofIdx) const noexcept
177 {
178 assert(from < mLayerCount && to < mLayerCount);
179 const auto& idx = mIndices[(from * mLayerCount) + to];
180 assert(rofIdx < idx.getEntries());
181 return mFlatTable[idx.getFirstEntry() + rofIdx];
182 }
183
184 GPUhdi() bool doROFsOverlap(int32_t layer0, size_t rof0, int32_t layer1, size_t rof1) const noexcept
185 {
186 if (layer0 == layer1) {
187 return rof0 == rof1;
188 }
189 assert(layer0 < mLayerCount && layer1 < mLayerCount);
190 const auto& idx = mIndices[(layer0 * mLayerCount) + layer1];
191 if (rof0 >= idx.getEntries()) {
192 return false;
193 }
194 const auto& overlap = mFlatTable[idx.getFirstEntry() + rof0];
195 if (overlap.getEntries() == 0) {
196 return false;
197 }
198 const size_t firstCompatible = overlap.getFirstEntry();
199 const size_t lastCompatible = firstCompatible + overlap.getEntries() - 1;
200 return rof1 >= firstCompatible && rof1 <= lastCompatible;
201 }
202
203 GPUhdi() o2::its::TimeEstBC getTimeStamp(int32_t layer0, size_t rof0, int32_t layer1, size_t rof1) const noexcept
204 {
205 assert(layer0 < mLayerCount && layer1 < mLayerCount);
206 assert(doROFsOverlap(layer0, rof0, layer1, rof1));
207 return mLayers[layer0].getROFTimeBounds(rof0, true) + mLayers[layer1].getROFTimeBounds(rof1, true);
208 }
209
210#ifndef GPUCA_GPUCODE
211 GPUh() void printAll() const
212 {
213 for (int32_t i = 0; i < mLayerCount; ++i) {
214 for (int32_t j = 0; j < mLayerCount; ++j) {
215 if (i != j) {
216 printMapping(i, j);
217 }
218 }
219 }
220 printSummary();
221 }
222
223 GPUh() void printMapping(int32_t from, int32_t to) const
224 {
225 if (from == to) {
226 LOGP(error, "No self-lookup supported");
227 return;
228 }
229 const auto& idx = mIndices[(from * mLayerCount) + to];
230 LOGF(info, "Overlap mapping: Layer %d -> Layer %d", from, to);
231 LOGP(info, "From: {}", mLayers[from].asString());
232 LOGP(info, "To : {}", mLayers[to].asString());
233 for (int32_t i = 0; i < idx.getEntries(); ++i) {
234 const auto& overlap = getOverlap(from, to, i);
235 LOGF(info, "%d -> first %d count %d", i, overlap.getFirstEntry(), overlap.getEntries());
236 }
237 }
238
239 GPUh() void printSummary() const
240 {
241 uint32_t totalEntries{0};
242 size_t flatTableSize{0};
243 for (int32_t i = 0; i < mLayerCount; ++i) {
244 for (int32_t j = 0; j < mLayerCount; ++j) {
245 if (i != j) {
246 const auto& idx = mIndices[(i * mLayerCount) + j];
247 totalEntries += idx.getEntries();
248 flatTableSize += idx.getEntries();
249 }
250 }
251 }
252 LOGF(info, "Total overlap table size: %u entries", totalEntries);
253 LOGF(info, "Flat table size: %zu entries", flatTableSize);
254 }
255#endif
256};
257
258template <typename TableEntry, typename TableIndex>
260 const TableEntry* mFlatTable{nullptr};
261 const TableIndex* mIndices{nullptr};
262 const ROFTimingLayer* mLayers{nullptr};
263 int32_t mLayerCount{0};
264
265 GPUhdi() const ROFTimingLayer& getLayer(int32_t layer) const noexcept
266 {
267 assert(layer >= 0 && layer < mLayerCount);
268 return mLayers[layer];
269 }
270
271 GPUhdi() const TableEntry& getVertices(int32_t layer, size_t rofIdx) const noexcept
272 {
273 assert(layer >= 0 && layer < mLayerCount);
274 const auto& idx = mIndices[layer];
275 assert(rofIdx < idx.getEntries());
276 return mFlatTable[idx.getFirstEntry() + rofIdx];
277 }
278
279 GPUh() int32_t getMaxVerticesPerROF() const noexcept
280 {
281 int32_t maxCount = 0;
282 for (int32_t layer = 0; layer < mLayerCount; ++layer) {
283 const auto& idx = mIndices[layer];
284 for (int32_t i = 0; i < idx.getEntries(); ++i) {
285 maxCount = o2::gpu::CAMath::Max(maxCount, static_cast<int32_t>(mFlatTable[idx.getFirstEntry() + i].getEntries()));
286 }
287 }
288 return maxCount;
289 }
290
291 GPUhdi() bool isVertexCompatible(int32_t layer, size_t rofIdx, const o2::its::Vertex& vertex) const noexcept
292 {
293 assert(layer >= 0 && layer < mLayerCount);
294 const auto& layerDef = mLayers[layer];
295 int64_t rofLower = o2::gpu::CAMath::Max(static_cast<int64_t>(layerDef.getROFStartInBC(rofIdx)) - static_cast<int64_t>(layerDef.mROFAddTimeErr), int64_t(0));
296 int64_t rofUpper = static_cast<int64_t>(layerDef.getROFEndInBC(rofIdx)) + layerDef.mROFAddTimeErr;
297 auto vLower = static_cast<int64_t>(vertex.getTimeStamp().lower());
298 auto vUpper = static_cast<int64_t>(vertex.getTimeStamp().upper());
299 return vUpper >= rofLower && vLower < rofUpper;
300 }
301
302#ifndef GPUCA_GPUCODE
303 GPUh() void printAll() const
304 {
305 for (int32_t layer = 0; layer < mLayerCount; ++layer) {
306 const auto& idx = mIndices[layer];
307 LOGF(info, "Vertex lookup: Layer %d, ROFs %u", layer, idx.getEntries());
308 }
309 }
310#endif
311};
312
313template <typename TableEntry, typename TableIndex>
315 const TableEntry* mFlatMask{nullptr};
316 const TableIndex* mLayerROFOffsets{nullptr};
317 int32_t mLayerCount{0};
318
319 GPUhdi() bool isROFEnabled(int32_t layer, int32_t rofId) const noexcept
320 {
321 assert(layer >= 0 && layer < mLayerCount);
322 return mFlatMask[mLayerROFOffsets[layer] + rofId] != 0u;
323 }
324
325#ifndef GPUCA_GPUCODE
326 GPUh() void printLayer(int32_t layer) const
327 {
328 constexpr int wROF = 10;
329 constexpr int wActive = 10;
330 const int32_t nROFs = mLayerROFOffsets[layer + 1] - mLayerROFOffsets[layer];
331 LOGF(info, "Mask table: Layer %d", layer);
332 LOGF(info, "%*s | %*s", wROF, "ROF", wActive, "Enabled");
333 LOGF(info, "%.*s-+-%.*s", wROF, "----------", wActive, "----------");
334 for (int32_t rof = 0; rof < nROFs; ++rof) {
335 LOGF(info, "%*d | %*d", wROF, rof, wActive, static_cast<int>(isROFEnabled(layer, rof)));
336 }
337 }
338
339 GPUh() std::string asString(int32_t layer) const
340 {
341 const int32_t nROFs = mLayerROFOffsets[layer + 1] - mLayerROFOffsets[layer];
342 int32_t enabledROFs = 0;
343 for (int32_t rof = 0; rof < nROFs; ++rof) {
344 if (isROFEnabled(layer, rof)) {
345 ++enabledROFs;
346 }
347 }
348 return std::format("ROFMask on Layer {} ROFs enabled: {}/{}", layer, enabledROFs, nROFs);
349 }
350
351 GPUh() void print(int32_t layer) const
352 {
353 LOG(info) << asString(layer);
354 }
355
356 GPUh() void printAll() const
357 {
358 for (int32_t layer = 0; layer < mLayerCount; ++layer) {
359 printLayer(layer);
360 }
361 }
362#endif
363};
364
369
379
380} // namespace o2::itsmft::tracking
381
382#endif // ALICEO2_ITSMFT_TRACKING_ROFVIEWS_H_
std::string asString(TDataMember const &dm, char *pointer)
uint64_t vertex
Definition RawEventData.h:9
uint64_t bc
Definition RawEventData.h:5
void print() const
int16_t time
Definition RawEventData.h:4
int32_t i
#define GPUhdi()
#define GPUh()
Header to collect LHC related constants.
double lower[3]
double upper[3]
Class to refer to the 1st entry and N elements of some group in the continuous container.
uint32_t j
Definition RawData.h:0
GLuint GLuint end
Definition glcorearb.h:469
GLint first
Definition glcorearb.h:399
GLsizei maxCount
Definition glcorearb.h:792
GLintptr offset
Definition glcorearb.h:660
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLuint start
Definition glcorearb.h:469
GLint GLuint mask
Definition glcorearb.h:291
uint32_t TimeStampErrorType
Definition TimeEstBC.h:27
uint32_t TimeStampType
Definition TimeEstBC.h:26
uint32_t trackClusterIndicesSize noexcept
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
GPUh() void printLayer(int32_t layer) const
Definition ROFViews.h:326
GPUhdi() bool isROFEnabled(int32_t layer
GPUhdi() bool doROFsOverlap(int32_t layer0
GPUhdi() const TableEntry &getOverlap(int32_t from
GPUh() const ROFTimingLayer &getClockLayer() const noexcept
Definition ROFViews.h:174
GPUhdi() const ROFTimingLayer &getLayer(int32_t layer) const noexcept
Definition ROFViews.h:154
GPUh() int32_t getClock() const noexcept
Definition ROFViews.h:160
assert(rofIdx< idx.getEntries())
GPUhdi() BCType getROFEndInBC(BCType rofId) const noexcept
Definition ROFViews.h:57
GPUhdi() BCType getROFStartInBC(BCType rofId) const noexcept
Definition ROFViews.h:51
o2::dataformats::RangeReference< BCType, BCType > BCRange
Definition ROFViews.h:43
o2::its::TimeStampType BCType
Definition ROFViews.h:42
GPUh() int32_t getMaxVerticesPerROF() const noexcept
Definition ROFViews.h:279
GPUhdi() bool isVertexCompatible(int32_t layer
GPUhdi() const TableEntry &getVertices(int32_t layer
GPUhdi() const ROFTimingLayer &getLayer(int32_t layer) const noexcept
Definition ROFViews.h:265
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"