30 mPrimaryVertices.emplace_back(vert);
31 if (!isBeamPositionOverridden) {
32 const float w = vert.getNContributors();
33 mBeamPos[0] = (mBeamPos[0] * mBeamPosWeight + vert.getX() *
w) / (mBeamPosWeight +
w);
34 mBeamPos[1] = (mBeamPos[1] * mBeamPosWeight + vert.getY() *
w) / (mBeamPosWeight +
w);
48 return surface.isValid() && surface.value() < mLayerGlobalMeasurements.size() ?
gsl::make_span(mLayerGlobalMeasurements[surface.value()]) : gsl::span<const GlobalMeasurement>{};
53 return surface.isValid() && surface.value() < mLayerGlobalMeasurements.size() ?
gsl::make_span(mLayerGlobalMeasurements[surface.value()]) : gsl::span<GlobalMeasurement>{};
59 if (!mConfigurationValid || !surface.isValid() || surface.value() >= mLayerGlobalMeasurements.size()) {
60 throw std::logic_error{
"TimeFrame::addMeasurement(): invalid or unconfigured surface"};
62 const auto position = surface.value();
63 const auto clusterId =
static_cast<uint32_t
>(mLayerSurfaceMeasurements[position].size());
65 mLayerGlobalMeasurements[position].push_back(global);
66 mLayerSurfaceMeasurements[position].push_back(measurement);
67 mLayerUsedClusters[position].push_back(uint8_t{0});
72 gsl::span<const o2::MCCompLabel>
labels)
75 const auto clusterId =
static_cast<uint32_t
>(mLayerSurfaceMeasurements[surface.value()].size() - 1);
76 mLayerClusterLabels[surface.value()].addElements(clusterId,
labels);
81 if (!
layer.isValid() ||
layer.value() >= mLayerSurfaceMeasurements.size()) {
84 const auto& measurements = mLayerSurfaceMeasurements[
layer.value()];
85 return clusterId < measurements.size() ? &measurements[clusterId] :
nullptr;
90 if (!
layer.isValid() ||
layer.value() >= mLayerClusterLabels.size()) {
93 return mLayerClusterLabels[
layer.value()].getLabels(clusterId);
98 std::size_t total = 0;
99 for (
const auto& measurements : mLayerGlobalMeasurements) {
100 total += measurements.size();
110 const int first = mROFramesClusters[
layer][rofId];
111 return {mLayerGlobalMeasurements[
layer].data() +
first,
112 static_cast<gsl::span<GlobalMeasurement>::size_type
>(mROFramesClusters[
layer][rofId + 1] -
first)};
120 const int first = mROFramesClusters[
layer][rofId];
121 return {mLayerGlobalMeasurements[
layer].data() +
first,
122 static_cast<gsl::span<const GlobalMeasurement>::size_type
>(mROFramesClusters[
layer][rofId + 1] -
first)};
130 const int first = mROFramesClusters[
layer][rofMin];
132 return {mLayerGlobalMeasurements[
layer].data() +
first,
static_cast<gsl::span<const GlobalMeasurement>::size_type
>(last -
first)};
138 return {mROFramesClusters[
layer].data() + rofMin,
static_cast<gsl::span<const int>::size_type
>(checkedRange)};
151 const int tableSize = mIndexTableUtils[
layer].getNrowBins() * mIndexTableUtils[
layer].getNcolBins() + 1;
152 return {mIndexTables[
layer].data() + rofId * tableSize,
static_cast<gsl::span<int>::size_type
>(tableSize)};
157 return static_cast<int>(std::lower_bound(mROFramesClusters[
layer].begin(), mROFramesClusters[
layer].
end(), cluster + 1) -
158 mROFramesClusters[
layer].begin() - 1);
164 return mROFramesClusters[
layer][last] - mROFramesClusters[
layer][rofMin];
169 return layer >= 0 &&
static_cast<std::size_t
>(
layer) < mLayerUsedClusters.size() ?
gsl::make_span(mLayerUsedClusters[
layer]) : gsl::span<unsigned char>{};
174 return layer >= 0 &&
static_cast<std::size_t
>(
layer) < mLayerUsedClusters.size() && clusterId < mLayerUsedClusters[
layer].size() && mLayerUsedClusters[
layer][clusterId] != 0;
179 if (
layer >= 0 &&
static_cast<std::size_t
>(
layer) < mLayerUsedClusters.size() && clusterId < mLayerUsedClusters[
layer].size()) {
180 mLayerUsedClusters[
layer][clusterId] = 1;
186 return std::accumulate(mLayerGlobalMeasurements.begin(), mLayerGlobalMeasurements.end(), std::size_t{0},
187 [](std::size_t total,
const auto&
layer) { return total + layer.size(); });
192 return std::accumulate(mLayerUsedClusters.begin(), mLayerUsedClusters.end(), std::size_t{0}, [](std::size_t total,
const auto&
layer) {
193 return total + static_cast<std::size_t>(std::count(layer.begin(), layer.end(), uint8_t{1}));
200 mROFViewsBySurface.assign(mDetectorConfiguration.size(), views);
201 mROFLocalLayerBySurface.resize(mROFViewsBySurface.size());
202 std::iota(mROFLocalLayerBySurface.begin(), mROFLocalLayerBySurface.end(), uint16_t{0});
206void TimeFrame::setROFClusters(std::size_t position, gsl::span<const int> boundaries)
208 if (!mConfigurationValid || position >= mROFramesClusters.size()) {
209 throw std::logic_error{
"TimeFrame::setROFClusters(): invalid or unconfigured surface position"};
211 mROFramesClusters[position].assign(boundaries.begin(), boundaries.end());
214void TimeFrame::setROFViews(std::size_t position,
RuntimeROFViews views, uint16_t localLayer)
216 if (!mConfigurationValid || position >= mROFViewsBySurface.size()) {
217 throw std::logic_error{
"TimeFrame::setROFViews(): invalid or unconfigured surface position"};
219 mROFViewsBySurface[position] = views;
220 mROFLocalLayerBySurface[position] = localLayer;
226 return getROFViews(fromLayer).overlap.getOverlap(getROFLocalLayer(fromLayer), getROFLocalLayer(toLayer), rof);
229bool TimeFrame::isROFEnabled(
int layer,
int rof)
const noexcept
231 const auto& views = getROFViews(
layer);
232 return (mUseUPC ? views.upcMask : views.mask).isROFEnabled(getROFLocalLayer(
layer), rof);
237 return getROFViews(
layer).vertexLookup.isVertexCompatible(getROFLocalLayer(
layer), rof,
vertex);
240o2::its::TimeEstBC TimeFrame::getROFTimeStamp(
int fromLayer,
int fromROF,
int toLayer,
int toROF)
const noexcept
242 return getROFViews(fromLayer).overlap.getTimeStamp(getROFLocalLayer(fromLayer), fromROF,
243 getROFLocalLayer(toLayer), toROF);
246int TimeFrame::getMaxVerticesPerROF() const noexcept
248 if (mROFViewsBySurface.empty()) {
249 return mROFViews.vertexLookup.getMaxVerticesPerROF();
252 for (
auto it = mROFViewsBySurface.begin(); it != mROFViewsBySurface.end(); ++it) {
253 const auto&
lookup = it->vertexLookup;
255 const auto alreadyScanned = std::any_of(mROFViewsBySurface.begin(), it, [&](
const auto& views) {
256 return views.vertexLookup.mFlatTable == lookup.mFlatTable &&
257 views.vertexLookup.mIndices == lookup.mIndices &&
258 views.vertexLookup.mLayerCount == lookup.mLayerCount;
260 if (!alreadyScanned) {
267gsl::span<const Vertex> TimeFrame::getPrimaryVertices(
int layer,
int rofId)
const
269 if (rofId < 0 || rofId >= getNrof(
layer)) {
272 const auto&
entry = getROFViews(
layer).vertexLookup.getVertices(getROFLocalLayer(
layer), rofId);
273 return {mPrimaryVertices.data() +
entry.getFirstEntry(),
274 static_cast<gsl::span<const Vertex>::size_type
>(
entry.getEntries())};
277bool TimeFrame::hasMCinformation() const noexcept
279 return mHasMCInformation;
282gsl::span<const MCCompLabel> TimeFrame::getClusterLabels(
int layer,
int cluster)
const
284 if (
layer < 0 ||
static_cast<std::size_t
>(
layer) >= mLayerGlobalMeasurements.size() || cluster < 0 ||
static_cast<std::size_t
>(cluster) >= mLayerGlobalMeasurements[
layer].size()) {
287 return getLabels(
LayerId{
static_cast<uint16_t
>(
layer)}, mLayerGlobalMeasurements[
layer][cluster].clusterId);
291 std::shared_ptr<BoundedMemoryResource> memoryPool)
293 if (mConfigurationValid || !memoryPool || !layout.valid() || layout.empty()) {
296 const auto nOwnedSurfaces = layout.size();
297 const auto nMeasurementSurfaces = layout.size();
298 mScratch.setMemoryPool(memoryPool);
299 setMemoryPool(std::move(memoryPool));
301 mScratch.configureStorage(maxEdges, maxCells);
302 mROFramesClusters.resize(nOwnedSurfaces);
303 mROFViewsBySurface.resize(nOwnedSurfaces);
304 mROFLocalLayerBySurface.resize(nOwnedSurfaces);
305 mLayerGlobalMeasurements.resize(nMeasurementSurfaces);
306 mLayerSurfaceMeasurements.resize(nMeasurementSurfaces);
307 mLayerUsedClusters.resize(nMeasurementSurfaces);
308 mLayerClusterLabels.resize(nMeasurementSurfaces);
310 mIndexTableUtils.reset(layout.getSurfaceCatalog());
311 mMinR.assign(nOwnedSurfaces, std::numeric_limits<float>::max());
312 mMaxR.assign(nOwnedSurfaces, std::numeric_limits<float>::lowest());
313 mMinZ.assign(nOwnedSurfaces, std::numeric_limits<float>::max());
314 mMaxZ.assign(nOwnedSurfaces, std::numeric_limits<float>::lowest());
315 }
catch (
const std::bad_alloc&) {
317 mScratch.clearStorage();
318 mROFramesClusters.clear();
319 mROFViewsBySurface.clear();
320 mROFLocalLayerBySurface.clear();
321 mLayerGlobalMeasurements.clear();
322 mLayerSurfaceMeasurements.clear();
323 mLayerUsedClusters.clear();
324 mLayerClusterLabels.clear();
325 mIndexTables.clear();
326 mIndexTableUtils.clear();
333 mDetectorConfiguration = std::move(layout);
334 mCapacityEstimator.reset();
335 mConfigurationValid =
true;
349void TimeFrame::resetTimeFrame() noexcept
359 for (
auto& measurements : mLayerGlobalMeasurements) {
360 measurements.clear();
362 for (
auto& measurements : mLayerSurfaceMeasurements) {
363 measurements.clear();
365 for (
auto& used : mLayerUsedClusters) {
368 for (
auto&
labels : mLayerClusterLabels) {
371 mHasMCInformation =
false;
373 std::fill(mROFViewsBySurface.begin(), mROFViewsBySurface.end(),
RuntimeROFViews{});
374 std::fill(mROFLocalLayerBySurface.begin(), mROFLocalLayerBySurface.end(), uint16_t{0});
376 for (
auto& boundaries : mROFramesClusters) {
380 std::fill(mMinR.begin(), mMinR.end(), std::numeric_limits<float>::max());
381 std::fill(mMaxR.begin(), mMaxR.end(), std::numeric_limits<float>::lowest());
382 std::fill(mMinZ.begin(), mMinZ.end(), std::numeric_limits<float>::max());
383 std::fill(mMaxZ.begin(), mMaxZ.end(), std::numeric_limits<float>::lowest());
386void TimeFrame::setMemoryPool(std::shared_ptr<BoundedMemoryResource> pool)
394 initVector(mPrimaryVertices);
395 initVector(mPrimaryVerticesLabels);
396 initVector(mGenericTracks);
397 initVector(mTrackLabels);
398 initVector(mTrackClusterIndices);
399 for (
auto& table : mIndexTables) {
406 if (indexTableConfigs.
size() != mIndexTables.size()) {
407 throw std::logic_error{
"TimeFrame::prepareIndexTables(): configuration extent mismatch"};
409 mIndexTableUtils = indexTableConfigs;
412 if (!checkedIndexTableSizeProduct(
static_cast<std::size_t
>(mIndexTableUtils[
layer].getNrowBins()),
413 static_cast<std::size_t
>(mIndexTableUtils[
layer].getNcolBins()),
stride) ||
414 stride == std::numeric_limits<std::size_t>::max()) {
415 throw std::bad_alloc{};
420 throw std::bad_alloc{};
424 std::fill(mMinR.begin(), mMinR.end(), std::numeric_limits<float>::max());
425 std::fill(mMaxR.begin(), mMaxR.end(), std::numeric_limits<float>::lowest());
426 std::fill(mMinZ.begin(), mMinZ.end(), std::numeric_limits<float>::max());
427 std::fill(mMaxZ.begin(), mMaxZ.end(), std::numeric_limits<float>::lowest());
430void TimeFrame::prepareClusters(
int maxLayers)
432 struct SortingHelper {
435 int measurementIndex;
438 const int stopLayer = std::min(maxLayers,
static_cast<int>(mLayerGlobalMeasurements.size()));
441 const int colBinsCount =
utils.getNcolBins();
442 std::size_t numBins = 0;
444 static_cast<std::size_t
>(colBinsCount), numBins) ||
445 numBins == std::numeric_limits<std::size_t>::max()) {
446 throw std::bad_alloc{};
448 const std::size_t
stride = numBins + 1;
449 bounded_vector<SortingHelper> helpers(mMemoryPool.get());
450 bounded_vector<GlobalMeasurement> sortedMeasurements(mMemoryPool.get());
451 bounded_vector<int> counts(numBins, 0, mMemoryPool.get());
452 bounded_vector<int>
offsets(numBins, 0, mMemoryPool.get());
454 for (
int rof = 0; rof < getNrof(
layer); ++rof) {
455 if (!isROFEnabled(
layer, rof)) {
458 const int first = mROFramesClusters[
layer][rof];
459 const int last = mROFramesClusters[
layer][rof + 1];
461 auto* tableBase = mIndexTables[
layer].data() + rof *
stride;
462 helpers.resize(
count);
463 sortedMeasurements.resize(
count);
466 for (
int local = 0; local <
count; ++local) {
467 const int measurementIndex =
first + local;
468 const auto& measurement = mLayerGlobalMeasurements[
layer][measurementIndex];
469 auto& helper = helpers[local];
470 int colBin =
utils.getColBinIndex(
layer, usePhiRBinning ? measurement.radius : measurement.
z);
471 if (colBin < 0 || colBin >= colBinsCount) {
472 colBin = std::clamp(colBin, 0, colBinsCount - 1);
474 helper.bin =
utils.getBinIndex(colBin,
utils.getRowBinIndex(measurement.phi));
475 helper.indexWithinBin = counts[helper.bin]++;
476 helper.measurementIndex = measurementIndex;
477 mMinR[
layer] = o2::gpu::GPUCommonMath::Min(measurement.radius, mMinR[
layer]);
478 mMaxR[
layer] = o2::gpu::GPUCommonMath::Max(measurement.radius, mMaxR[
layer]);
479 mMinZ[
layer] = o2::gpu::GPUCommonMath::Min(measurement.z, mMinZ[
layer]);
480 mMaxZ[
layer] = o2::gpu::GPUCommonMath::Max(measurement.z, mMaxZ[
layer]);
482 std::exclusive_scan(counts.begin(), counts.end(),
offsets.begin(), 0);
484 for (
const auto& helper : helpers) {
485 sortedMeasurements[
offsets[helper.bin] + helper.indexWithinBin] = mLayerGlobalMeasurements[
layer][helper.measurementIndex];
487 std::copy(sortedMeasurements.begin(), sortedMeasurements.end(), mLayerGlobalMeasurements[
layer].begin() +
first);
488 std::copy_n(
offsets.data(), counts.size(), tableBase);
489 std::fill_n(tableBase + counts.size(),
stride - counts.size(),
count);
490 std::fill(counts.begin(), counts.end(), 0);
492 sortedMeasurements.clear();
uint8_t lookup(const char input) noexcept
Passive common TimeFrame owner.
std::vector< o2::MCCompLabel > labels
size_t size() const noexcept
void reset()
Clear iteration state without changing plan sizes.
GLuint GLsizei const GLuint const GLintptr * offsets
GLint GLenum GLboolean GLsizei stride
GLenum GLuint GLint GLint layer
GLubyte GLubyte GLubyte GLubyte w
GLdouble GLdouble GLdouble z
auto make_span(const o2::rans::internal::simd::AlignedArray< T, width_V, size_V > &array)
bool checkedIndexTableSizeProduct(std::size_t a, std::size_t b, std::size_t &result) noexcept
void deepVectorClear(std::vector< T > &vec)
void clearResizeBoundedVector(bounded_vector< T > &vec, size_t sz, std::pmr::memory_resource *mr=nullptr, T def=T())
uint32_t trackClusterIndicesSize noexcept
std::pmr::vector< T > bounded_vector
Common utility functions.
gsl::span< const int > getROFrameClusters(int layer) const
void markUsedCluster(int layer, uint32_t clusterId)
void addPrimaryVertex(const Vertex &vertex)
void addMeasurement(LayerId surface, GlobalMeasurement global, const SurfaceMeasurement &measurement)
int getNrof(int layer) const
std::size_t getTotalMeasurements() const noexcept
gsl::span< const o2::MCCompLabel > getLabels(LayerId layer, uint32_t clusterId) const
bool isClusterUsed(int layer, uint32_t clusterId) const
gsl::span< int > getIndexTable(int rofId, int layer)
const SurfaceMeasurement * getSurfaceMeasurement(LayerId layer, uint32_t clusterId) const noexcept
gsl::span< const int > getROFramesClustersPerROFrange(int rofMin, int range, int layer) const
void resetBeamXY(const float x, const float y, const float w=0)
int getTotalClustersPerROFrange(int rofMin, int range, int layer) const
std::size_t getNumberOfClusters() const
gsl::span< const GlobalMeasurement > getGlobalMeasurements(LayerId surface) const
int getClusterROF(int layer, int cluster) const
gsl::span< unsigned char > getUsedClusters(int layer)
std::size_t getNumberOfUsedClusters() const
gsl::span< GlobalMeasurement > getClustersOnLayer(int rofId, int layer)
gsl::span< const GlobalMeasurement > getClustersPerROFrange(int rofMin, int range, int layer) const
std::vector< o2::ctf::BufferType > vec