50TrackingKernelParameters bindTrackingKernelParameters(
const IterationParameters&
params)
noexcept
52 TrackingKernelParameters out;
53 out.trackletMinPt =
params.TrackletMinPt;
54 out.nSigmaCut =
params.NSigmaCut;
55 out.maxChi2ClusterAttachment =
params.MaxChi2ClusterAttachment;
56 out.maxChi2NDF =
params.MaxChi2NDF;
57 out.pvResolution =
params.PVres;
65void validateSparsePlan(
const IterationConfiguration& configuration,
int iteration,
const TraversalTopologyView& layout)
67 const auto fail = [iteration]() {
throw std::invalid_argument{
"CA traversal: sparse topology mismatch (iteration " +
std::to_string(iteration) +
")"}; };
68 const auto& topology = layout;
69 if (layout.catalog.surfaces ==
nullptr || layout.catalog.nSurfaces == 0 ||
70 (topology.nEdges != 0 && (topology.edges ==
nullptr || topology.pathsByFirstEdgeOffsets ==
nullptr)) ||
71 (topology.nPaths != 0 && (topology.paths ==
nullptr || topology.pathsByFirstEdge ==
nullptr))) {
75 const auto edges = configuration.edgeIds();
76 const auto cells = configuration.cellIds();
77 if (
edges.empty() ||
edges.size() > topology.nEdges ||
cells.size() > topology.nPaths) {
80 for (
const auto id :
edges) {
81 if (!
id.
isValid() ||
id.
value() >= topology.nEdges || !configuration.getEdgeSlot(
id)) {
84 const auto& edge = topology.getEdge(
id);
85 if (!configuration.hasLayer(edge.from) || !configuration.hasLayer(edge.to)) {
89 for (
const auto id :
cells) {
90 if (!
id.
isValid() ||
id.
value() >= topology.nPaths || !configuration.getCellSlot(
id)) {
93 const auto&
path = topology.getPath(
id);
94 const auto& firstEdge = topology.getEdge(
path.first);
95 const auto& secondEdge = topology.getEdge(
path.second);
96 if (!configuration.getEdgeSlot(
path.first) || !configuration.getEdgeSlot(
path.second) ||
97 !configuration.hasLayer(firstEdge.from) || !configuration.hasLayer(firstEdge.to) ||
98 !configuration.hasLayer(secondEdge.to) ||
99 !configuration.topology.activeLayers.has(firstEdge.from.value()) ||
100 !configuration.topology.activeLayers.has(firstEdge.to.value()) ||
101 !configuration.topology.activeLayers.has(secondEdge.to.value())) {
105 for (
const auto id : configuration.topology.scheduledPaths) {
106 if (!configuration.getCellSlot(
id)) {
110 for (
const auto id : configuration.topology.roadStartPaths) {
111 if (!configuration.getCellSlot(
id)) {
117void prepareDetectorConfiguration(DetectorConfiguration& configuration,
const DetectorParameters& parameters)
119 const auto catalog = configuration.getSurfaceCatalog();
120 const auto surfaceCount = configuration.size();
122 parameters.AddTimeError.size() < surfaceCount ||
123 parameters.SystError2Col.size() < surfaceCount ||
124 parameters.SystError2Row.size() < surfaceCount ||
125 parameters.LayerResolution.size() < surfaceCount) {
126 throw std::invalid_argument{
"CA traversal: invalid surface parameters"};
128 configuration.addTimeError.assign(parameters.AddTimeError.begin(), parameters.AddTimeError.begin() + surfaceCount);
129 configuration.layerResolution.assign(parameters.LayerResolution.begin(), parameters.LayerResolution.begin() + surfaceCount);
130 configuration.systError2Row.assign(parameters.SystError2Row.begin(), parameters.SystError2Row.begin() + surfaceCount);
131 configuration.systError2Col.assign(parameters.SystError2Col.begin(), parameters.SystError2Col.begin() + surfaceCount);
132 configuration.positionResolutions.resize(surfaceCount);
133 std::array<SurfaceChartRange, MaxLayoutSurfaces> chartRanges{};
134 for (std::size_t position = 0; position < surfaceCount; ++position) {
135 const auto surface =
LayerId{
static_cast<uint16_t
>(position)};
136 const auto& descriptor = catalog.getSurface(surface);
137 chartRanges[position] = descriptor.chartRange;
138 configuration.positionResolutions[position] = o2::gpu::CAMath::Sqrt(
139 0.5f * (parameters.SystError2Col[position] + parameters.SystError2Row[position]) +
140 parameters.LayerResolution[position] * parameters.LayerResolution[position]);
142 if (!configuration.indexTableConfigs.reset(catalog)) {
143 throw std::invalid_argument{
"CA traversal: invalid index table configuration"};
145 const gsl::span<const SurfaceChartRange> chartRangeView{chartRanges.data(), surfaceCount};
147 if (configuration.indexTableConfigs.hasKind(
kind) &&
149 static_cast<int>(surfaceCount),
kind, chartRangeView)) {
150 throw std::invalid_argument{
"CA traversal: invalid index table configuration"};
155void prepareIterationConfiguration(
const DetectorConfiguration& detector,
156 IterationConfiguration& configuration,
int iteration)
158 const auto topology = configuration.getTopologyView(detector.getSurfaceCatalog());
159 const auto& parameters = configuration.parameters;
160 const auto layerCount = configuration.topology.nLayers;
162 parameters.NLayers !=
static_cast<int>(layerCount)) {
163 throw std::invalid_argument{
"CA traversal: legacy material mismatch (iteration " +
std::to_string(iteration) +
")"};
165 if (!topology.catalog.surfaces || topology.catalog.nSurfaces < layerCount ||
166 detector.positionResolutions.size() < layerCount ||
167 detector.indexTableConfigs.size() < layerCount) {
168 throw std::invalid_argument{
"CA traversal: invalid surface parameters (iteration " +
std::to_string(iteration) +
")"};
171 for (uint16_t position = 0; position < layerCount; ++position) {
172 const auto surface =
LayerId{position};
173 const auto& descriptor = topology.getSurface(surface);
175 throw std::invalid_argument{
"CA traversal: unsupported surface kind (iteration " +
std::to_string(iteration) +
")"};
177 const auto& material = descriptor.material;
178 if (!o2::gpu::GPUCommonMath::Finite(material.xOverX0) || material.xOverX0 < 0.f ||
179 !o2::gpu::GPUCommonMath::Finite(material.arealDensityGPerCm2) || material.arealDensityGPerCm2 < 0.f) {
180 throw std::invalid_argument{
"CA traversal: invalid surface parameters (iteration " +
std::to_string(iteration) +
")"};
184 configuration.kernelParameters = bindTrackingKernelParameters(parameters);
185 if (!configuration.kernelParameters.isValid()) {
186 throw std::invalid_argument{
"CA traversal: invalid surface parameters (iteration " +
std::to_string(iteration) +
")"};
188 validateSparsePlan(configuration, iteration, topology);
191float diskLayerMultipleScatteringAngle(
float layerxX0,
float layerRadius,
float referenceCoordinate,
float trackletMinPt)
193 const float invP = 1.f / trackletMinPt;
194 const float tanlRef = (std::abs(layerRadius) > 1e-6f)
195 ? referenceCoordinate / layerRadius
197 const float absTanl = std::abs(tanlRef);
198 const float cscLambda = (absTanl > 1e-6f)
199 ? std::sqrt(1.f + tanlRef * tanlRef) / absTanl
201 return 0.0136f * invP * std::sqrt(layerxX0 * cscLambda);
204float clampEdgeCurvature(
float oneOverR,
float outerRadius)
noexcept
206 return (outerRadius > 0.f && 0.5f * oneOverR >= 1.f / outerRadius)
207 ? (2.f / outerRadius) - o2::constants::math::Almost0
211struct EdgeScatteringBendingPrep {
216EdgeScatteringBendingPrep prepareEdgeScatteringAndBending(
217 gsl::span<const float> perLayerMSAngle,
int fromLayer,
int toLayer,
218 float r1,
float r2,
float clampedOneOverR,
float res1,
float res2)
noexcept
222 ms2 += o2::its::math_utils::Sq(perLayerMSAngle[
layer]);
224 const float msAngle = o2::gpu::CAMath::Sqrt(ms2);
225 const float cosTheta1half = o2::gpu::CAMath::Sqrt(1.f - o2::its::math_utils::Sq(0.5f * r1 * clampedOneOverR));
226 const float cosTheta2half = o2::gpu::CAMath::Sqrt(1.f - o2::its::math_utils::Sq(0.5f * r2 * clampedOneOverR));
227 const float x = (r2 * cosTheta1half) - (r1 * cosTheta2half);
228 const float delta = o2::gpu::CAMath::Sqrt(1.f / (1.f - 0.25f * o2::its::math_utils::Sq(
x * clampedOneOverR)) *
229 (o2::its::math_utils::Sq((0.25f * r1 * r2 * o2::its::math_utils::Sq(clampedOneOverR) / cosTheta2half) + cosTheta1half) * o2::its::math_utils::Sq(res1) +
230 o2::its::math_utils::Sq((0.25f * r1 * r2 * o2::its::math_utils::Sq(clampedOneOverR) / cosTheta1half) + cosTheta2half) * o2::its::math_utils::Sq(res2)));
231 const float phiCut = o2::gpu::CAMath::Min(o2::gpu::CAMath::ASin(0.5f *
x * clampedOneOverR) + 2.f *
msAngle + delta, o2::constants::math::PI * 0.5f);
235void prepareTraversalEdgeTolerances(
236 IterationContext& context,
239 auto& scratch = context.scratch;
240 const auto& graph = context.topology;
241 const auto& trkParam = context.configuration.parameters;
242 const auto& topology = graph;
244 const int layerCount = context.configuration.topology.nLayers;
245 std::array<float, MaxLayoutSurfaces> msAngles{};
246 for (
int iLayer{0}; iLayer < layerCount; ++iLayer) {
247 const auto surface =
LayerId{
static_cast<uint16_t
>(iLayer)};
248 const auto& descriptor = topology.getSurface(surface);
250 msAngles[iLayer] = o2::its::math_utils::MSangle(0.14f, trkParam.TrackletMinPt, descriptor.material.xOverX0);
252 msAngles[iLayer] = diskLayerMultipleScatteringAngle(
253 descriptor.material.xOverX0, context.detectorConfiguration.getRepresentativeRadius(surface),
254 descriptor.referenceCoordinate, trkParam.TrackletMinPt);
258 auto& edgeMSAngles = scratch.getEdgeMSAngles();
259 auto& edgePhiCuts = scratch.getEdgePhiCuts();
260 const float oneOverR{0.001f * 0.3f * std::abs(context.bz) / trkParam.TrackletMinPt};
261 for (
const auto edgeId : context.configuration.edgeIds()) {
262 const auto edgeSlot = context.configuration.getEdgeSlot(edgeId);
264 throw std::invalid_argument{
"CA traversal: traversal binding mismatch (iteration " +
std::to_string(iteration) +
")"};
266 const auto& edge = topology.getEdge(edgeId);
267 if (!context.configuration.hasLayer(edge.from) || !context.configuration.hasLayer(edge.to)) {
268 throw std::invalid_argument{
"CA traversal: traversal binding mismatch (iteration " +
std::to_string(iteration) +
")"};
270 const int fromLayer = edge.from.value();
271 const int toLayer = edge.to.value();
272 const float r1 = std::min(context.detectorConfiguration.getRepresentativeRadius(edge.from), context.detectorConfiguration.getRepresentativeRadius(edge.to));
273 const float r2 = std::max(context.detectorConfiguration.getRepresentativeRadius(edge.from), context.detectorConfiguration.getRepresentativeRadius(edge.to));
274 const float edgeOneOverR = clampEdgeCurvature(oneOverR, r2);
275 const float res1 = o2::gpu::CAMath::Hypot(trkParam.PVres, context.detectorConfiguration.positionResolutions[fromLayer]);
276 const float res2 = o2::gpu::CAMath::Hypot(trkParam.PVres, context.detectorConfiguration.positionResolutions[toLayer]);
277 const auto prep = prepareEdgeScatteringAndBending(
278 gsl::span<const float>(msAngles.data(),
static_cast<std::size_t
>(layerCount)), fromLayer, toLayer, r1, r2, edgeOneOverR, res1, res2);
279 edgeMSAngles[*edgeSlot] = prep.msAngle;
280 edgePhiCuts[*edgeSlot] = prep.phiCut;
286void Tracker::initializeIteration(IterationContext& context)
const
288 const int iteration = context.iteration;
289 if (iteration < 0 ||
static_cast<size_t>(iteration) >= mIterations.size()) {
290 throw std::invalid_argument{
"CA traversal: iteration out of range (iteration " +
std::to_string(iteration) +
")"};
292 const auto& configuration = context.configuration;
293 const auto& parameters = configuration.parameters;
294 auto& frame = context.frame;
295 auto& scratch = context.scratch;
296 const auto layerCount = configuration.topology.nLayers;
299 frame.prepareIndexTables(context.detectorConfiguration.indexTableConfigs);
301 for (std::size_t position = 0; position < layerCount; ++position) {
303 frame.getIndexTableUtils(
static_cast<int>(position)),
304 static_cast<int>(layerCount))) {
305 throw std::invalid_argument{
"CA traversal: index table configuration mismatch (iteration " +
std::to_string(iteration) +
")"};
310 frame.prepareClusters(
static_cast<int>(layerCount));
313 const auto edgeIds = context.configuration.edgeIds();
314 const auto cellIds = context.configuration.cellIds();
315 std::array<std::size_t, MaxLayoutEdges> trackletLookupSizes;
316 for (
const auto edgeId : edgeIds) {
317 const auto from = context.topology.getEdge(edgeId).from;
318 if (!configuration.hasLayer(from) || from.value() >= context.layerGlobalMeasurements.size()) {
319 throw std::invalid_argument{
"CA traversal: traversal binding mismatch (iteration " +
std::to_string(iteration) +
")"};
321 trackletLookupSizes[edgeId.value()] = context.layerGlobalMeasurements[from.value()].size();
323 scratch.beginIteration(edgeIds.size(), cellIds.size(), {trackletLookupSizes.data(), edgeIds.size()});
328 std::array<bool, MaxLayoutSurfaces> candidateReachableLayers{};
329 for (
const auto edgeId : edgeIds) {
330 const auto& edge = context.topology.getEdge(edgeId);
331 if (!configuration.hasLayer(edge.from) || !configuration.hasLayer(edge.to)) {
332 throw std::invalid_argument{
"CA traversal: sparse topology mismatch (iteration " +
std::to_string(iteration) +
")"};
334 candidateReachableLayers[edge.from.value()] =
true;
335 candidateReachableLayers[edge.to.value()] =
true;
338 if (!candidateReachableLayers[
layer]) {
341 const auto measurements = context.layerGlobalMeasurements[
layer];
342 const auto rofBoundaries = frame.getROFrameClusters(
static_cast<int>(
layer));
343 const auto rofMask = frame.getROFViews(
static_cast<int>(
layer)).mask;
345 if (rofMask.mFlatMask ==
nullptr || rofMask.mLayerROFOffsets ==
nullptr) {
348 for (
int rof = 0; rof < frame.getNrof(
static_cast<int>(
layer)); ++rof) {
349 const auto sorted = frame.getClustersOnLayer(rof,
static_cast<int>(
layer));
350 if (sorted.empty()) {
353 if (!frame.isROFEnabled(
static_cast<int>(
layer), rof)) {
356 const int first = rofBoundaries[rof];
357 const int last = rofBoundaries[rof + 1];
358 if (
first < 0 || last < first || last >
static_cast<int>(measurements.size()) ||
359 sorted.size() !=
static_cast<size_t>(last -
first)) {
360 throw std::invalid_argument{
"CA traversal: normalized measurement mismatch (iteration " +
std::to_string(iteration) +
")"};
362 std::vector<uint32_t> seen;
363 seen.reserve(sorted.size());
364 for (
const auto& measurement : sorted) {
365 if (!measurement.hasValidClusterId() ||
366 frame.getSurfaceMeasurement(
LayerId{static_cast<uint16_t>(layer)}, measurement.clusterId) ==
nullptr) {
367 throw std::invalid_argument{
"CA traversal: normalized measurement mismatch (iteration " +
std::to_string(iteration) +
")"};
369 seen.push_back(measurement.clusterId);
371 std::sort(seen.begin(), seen.end());
372 if (std::adjacent_find(seen.begin(), seen.end()) != seen.end()) {
373 throw std::invalid_argument{
"CA traversal: normalized measurement mismatch (iteration " +
std::to_string(iteration) +
")"};
378 prepareTraversalEdgeTolerances(context, iteration);
381gsl::span<const gsl::span<const GlobalMeasurement>> Tracker::prepareTimeFrame(
382 TimeFrame& frame, std::array<gsl::span<const GlobalMeasurement>,
MaxLayoutSurfaces>& measurements)
const
384 const auto layerCount = mIterations.front().topology.nLayers;
385 for (uint16_t position = 0; position < layerCount; ++position) {
386 const auto surface =
LayerId{position};
387 const auto globals = frame.getGlobalMeasurements(surface);
388 if (globals.size() >
static_cast<std::size_t
>(std::numeric_limits<int>::max())) {
389 throw std::invalid_argument{
"CA traversal: normalized measurement mismatch"};
391 for (
const auto& global : globals) {
392 if (!global.hasValidClusterId() || global.clusterId >
static_cast<uint32_t
>(std::numeric_limits<int>::max()) ||
393 frame.getSurfaceMeasurement(surface, global.clusterId) ==
nullptr) {
394 throw std::invalid_argument{
"CA traversal: normalized measurement mismatch"};
397 const auto rofBoundaries = frame.getROFrameClusters(
static_cast<int>(position));
398 if (rofBoundaries.empty() || rofBoundaries.front() != 0 ||
399 rofBoundaries.back() !=
static_cast<int>(globals.size())) {
400 throw std::invalid_argument{
"CA traversal: normalized measurement mismatch"};
402 for (std::size_t rof = 0; rof + 1 < rofBoundaries.size(); ++rof) {
403 const int first = rofBoundaries[rof];
404 const int last = rofBoundaries[rof + 1];
405 if (
first < 0 || last < first || last >
static_cast<int>(globals.size())) {
406 throw std::invalid_argument{
"CA traversal: normalized measurement mismatch"};
409 measurements[position] = globals;
411 return {measurements.data(), layerCount};
417 LOGP(error,
"CA tracker initialization failed: TimeFrame is already configured");
421 LOGP(error,
"CA tracker initialization failed: no tracking iterations configured");
425 LOGP(error,
"CA tracker initialization failed: missing surface catalog");
429 LOGP(error,
"CA tracker initialization failed: missing memory pool");
436 if (!detector.valid()) {
437 LOGP(error,
"CA tracker initialization failed: invalid detector layout (error={})",
static_cast<int>(detector.getError()));
441 prepareDetectorConfiguration(detector, configuration.
plan.
detector);
442 }
catch (
const std::invalid_argument& err) {
443 LOGP(error,
"CA tracker initialization failed: {}", err.what());
447 std::vector<IterationConfiguration> iterations;
448 std::size_t maxEdges = 0;
449 std::size_t maxCells = 0;
452 for (std::size_t iteration = 0; iteration < configuration.
plan.
iterations.size(); ++iteration) {
454 if (input.NLayers != 0 && input.NLayers != detector.size()) {
455 LOGP(error,
"CA tracker initialization failed at iteration {}: configured layer count {} differs from detector size {}",
456 iteration, input.NLayers, detector.size());
460 if (!topology.ok()) {
461 LOGP(error,
"CA tracker initialization failed at iteration {}: invalid traversal topology (error={})",
462 iteration,
static_cast<int>(topology.error));
468 iterationConfiguration.
topology = *topology.topology;
470 prepareIterationConfiguration(detector, iterationConfiguration,
static_cast<int>(iteration));
471 }
catch (
const std::invalid_argument& err) {
472 LOGP(error,
"CA tracker initialization failed at iteration {}: {}", iteration, err.what());
475 maxEdges = std::max(maxEdges, iterationConfiguration.
topology.
edges.size());
476 maxCells = std::max(maxCells, iterationConfiguration.
topology.
paths.size());
477 iterations.push_back(std::move(iterationConfiguration));
481 LOGP(error,
"CA tracker initialization failed: TimeFrame rejected the detector configuration or workspace capacity");
485 mIterations = std::move(iterations);
492 return mFrame == &frame && !mIterations.
empty() && frame.isConfigured();
495void Tracker::computeTracksMClabels(
TimeFrame& frame)
const
505 trackLabels.reserve(
tracks.size());
509 std::size_t
count{0};
510 std::size_t lastSeenCluster{0};
513 for (
const auto& track :
tracks) {
514 if (!isValidTrackRange(track,
static_cast<uint32_t
>(references.size()))) {
515 throw std::logic_error{
"Tracker::computeTracksMClabels(): invalid track cluster-reference range"};
518 std::vector<Candidate> candidates;
519 std::size_t attachedClusters = 0;
523 throw std::logic_error{
"Tracker::computeTracksMClabels(): unresolved track cluster reference"};
528 const auto candidate = std::find_if(candidates.begin(), candidates.end(), [&
label](
const auto& current) {
529 return label == current.representative;
531 if (candidate == candidates.end()) {
532 candidates.push_back({
label, 1, attachedClusters});
533 }
else if (candidate->lastSeenCluster != attachedClusters) {
535 candidate->lastSeenCluster = attachedClusters;
541 if (candidates.empty()) {
542 winner.setFakeFlag();
544 const auto best = std::max_element(candidates.begin(), candidates.end(), [](
const auto&
left,
const auto&
right) {
545 return left.count < right.count;
547 winner =
best->representative;
550 if (
best->count != attachedClusters) {
551 winner.setFakeFlag();
554 trackLabels.push_back(winner);
560void Tracker::configureBeamPosition(TimeFrame& frame)
const
562 const auto&
params = mIterations.front().parameters;
566 const auto& detector = frame.getDetectorConfiguration();
567 const float systErrY2 = detector.systError2Row.empty() ? 0.f : detector.systError2Row[0];
568 const float layerRes = detector.layerResolution.empty() ? 0.f : detector.layerResolution[0];
569 frame.setBeamPosition(
params.Diamond[0],
params.Diamond[1],
params.DiamondCov[3], layerRes, systErrY2);
576 throw std::invalid_argument{
"CA traversal: missing layout"};
578 const auto start = std::chrono::steady_clock::now();
579 std::vector<std::size_t> acceptedTrackCounts;
581 bool estimatorTransactionStarted{
false};
582 const auto rollbackEstimator = [&] {
583 if (estimatorTransactionStarted) {
585 estimatorTransactionStarted =
false;
589 estimator.beginTransaction();
590 estimatorTransactionStarted =
true;
591 configureBeamPosition(frame);
593 acceptedTrackCounts.reserve(mIterations.size());
594 std::array<gsl::span<const GlobalMeasurement>,
MaxLayoutSurfaces> measurementSpans;
595 const auto layerGlobalMeasurements = prepareTimeFrame(frame, measurementSpans);
599 if (mExecutionPolicy.
MaxMemory != std::numeric_limits<size_t>::max() &&
600 memoryPool->getMaxMemory() > mExecutionPolicy.
MaxMemory) {
601 memoryPool->setMaxMemory(mExecutionPolicy.
MaxMemory);
603 for (
int iteration = 0; iteration < static_cast<int>(mIterations.size()); ++iteration) {
604 const auto& configuration = mIterations[iteration];
605 const auto& trkParam = configuration.parameters;
612 configuration.getTopologyView(frame.getDetectorConfiguration().getSurfaceCatalog()),
613 configuration, layerGlobalMeasurements,
615 initializeIteration(context);
617 acceptedTrackCounts.push_back(frame.
getGenericTracks().size() - acceptedTrackBegin);
619 computeTracksMClabels(frame);
620 if (std::getenv(
"O2_ITSMFT_PRINT_SLAB_STATS") !=
nullptr) {
623 estimator.commitTransaction();
624 estimatorTransactionStarted =
false;
628 LOGP(error,
"CA tracker exceeded memory limit: {}", err.
what());
635 }
catch (
const std::bad_alloc& err) {
638 LOGP(error,
"CA tracker allocation failed: {}", err.
what());
645 }
catch (
const std::exception& err) {
648 LOGP(error,
"CA tracker failed with an unclassified exception; treating as structural: {}", err.
what());
654 mRunStatistics.
elapsedMs = std::chrono::duration<float, std::milli>(std::chrono::steady_clock::now() -
start).count();
std::vector< o2::its::TrackITS > tracks
std::vector< SidecarEdge > edges
const char * what() const noexcept final
void rollbackTransaction() noexcept
void runTraversal(IterationContext &view)
bool initialize(TimeFrame &frame, const TrackerInitialization &configuration)
bool run(TimeFrame &frame, TrackerTraits &traits)
bool isConfiguredFor(const TimeFrame &frame) const noexcept
GLsizei const GLfloat * value
GLenum const GLfloat * params
GLuint GLsizei const GLchar * label
GLsizei const GLchar *const * path
GLenum GLuint GLint GLint layer
const bool const bool const int FollowDirection BestTrial TrackITSInternal< NLayers > & best
const bool const int TrackITSInternal< NLayers > & track
bool indexTableConfigurationsMatch(const o2::itsmft::IndexTableUtilsCore &a, const o2::itsmft::IndexTableUtilsCore &b, int activeSurfaceCount) noexcept
detail::Identifier< LayerIdTag, uint16_t > LayerId
bool configureIndexTableUtils(o2::itsmft::IndexTableUtilsCore &destination, const DetectorParameters ¶ms, int activeSurfaceCount, SurfaceKind kind, gsl::span< const SurfaceChartRange > chartRanges) noexcept
constexpr uint32_t MaxLayoutSurfaces
std::pmr::vector< T > bounded_vector
TraversalTopologyBuildResult deriveTraversalTopology(const DetectorConfiguration &layout, const o2::itsmft::IterationParameters ¶meters)
std::unique_ptr< const o2::dataformats::MCTruthContainer< MCLabel > > getLabels(framework::ProcessingContext &pc, std::string_view dataBind, EventType eventType=EventType::Standard)
std::string to_string(gsl::span< T, Size > span)
bool isValid(std::string alias)
TrackingExecutionPolicy execution
DetectorParameters detector
std::vector< IterationParameters > iterations
TraversalTopology topology
IterationParameters parameters
const SurfaceDescriptor * surfaces
auto & getGenericTracks()
auto & getTrackClusterIndices()
bool hasMCinformation() const noexcept
void resetTimeFrame() noexcept
TimeFrameScratch & getScratch()
bool isConfigured() const noexcept
CapacityEstimator & getCapacityEstimator() noexcept
const SurfaceMeasurement * getSurfaceMeasurement(LayerId layer, uint32_t clusterId) const noexcept
void useUPCMask() noexcept
auto & getMemoryPool() const noexcept
bool configure(DetectorConfiguration &&layout, std::size_t maxEdges, std::size_t maxCells, std::shared_ptr< BoundedMemoryResource > memoryPool)
SurfaceCatalogView catalog
std::shared_ptr< BoundedMemoryResource > memoryPool
std::vector< uint16_t > componentOffsets
std::vector< std::size_t > acceptedTrackCounts
std::vector< Edge > edges
std::vector< CellPath > paths
std::vector< Cell > cells