Project
Loading...
Searching...
No Matches
CATrackerSpec.cxx
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
13
15
16#include <array>
17#include <algorithm>
18#include <limits>
19#include <memory>
20#include <utility>
21#include <vector>
22#include <stdexcept>
23
24#include <gsl/span>
25
35#include "Framework/Logger.h"
42#include <oneapi/tbb/task_arena.h>
44#include "MFTBase/GeometryTGeo.h"
45#include "MFTTracking/Constants.h"
49
50using namespace o2::framework;
51
52namespace o2::mft
53{
54
55namespace
56{
57using namespace o2::itsmft::tracking;
58
59template <int NLayers>
60constexpr std::array<LayerId, NLayers> detectorLocalToLayoutLayers()
61{
62 std::array<LayerId, NLayers> order{};
63 for (int i = 0; i < NLayers; ++i) {
64 order[i] = LayerId{static_cast<uint16_t>(i)};
65 }
66 return order;
67}
68
69inline constexpr auto kLayerToLayout = detectorLocalToLayoutLayers<MFTNLayers>();
70
71struct TrackOutput {
72 std::vector<o2::mft::TrackMFT> tracks;
73 std::vector<int> clusterIndices;
74 std::vector<o2::itsmft::ROFRecord> trackROFs;
75 std::vector<uint16_t> seedPatterns;
76 std::vector<o2::MCCompLabel> labels;
77};
78
79bool exportTrackState(const SurfaceTrackState& source, o2::track::TrackParCovFwd& destination) noexcept
80{
81 if (source.kind != SurfaceKind::Disk) {
82 return false;
83 }
84 o2::track::SMatrix5 parameters{};
85 o2::track::SMatrix55Sym covariance{};
86 for (uint8_t i = 0; i < 5; ++i) {
87 if (!o2::gpu::GPUCommonMath::Finite(source.parameters[i])) {
88 return false;
89 }
90 parameters[i] = source.parameters[i];
91 }
92 for (uint8_t row = 0; row < 5; ++row) {
93 for (uint8_t column = 0; column <= row; ++column) {
94 const auto value = source.covariance[packedCovarianceIndex(row, column)];
95 if (!o2::gpu::GPUCommonMath::Finite(value)) {
96 return false;
97 }
98 covariance(row, column) = value;
99 }
100 }
101 if (!o2::gpu::GPUCommonMath::Finite(source.referenceCoordinate)) {
102 return false;
103 }
104 destination = o2::track::TrackParCovFwd{source.referenceCoordinate, parameters, covariance, 0.};
105 return true;
106}
107
108bool collectReferences(const TimeFrame& frame, const GenericTrack& common, std::vector<int>& outputIndices, o2::mft::TrackMFT& output,
109 uint32_t& pattern,
110 const std::vector<std::vector<uint32_t>>* externalIndicesBySurface,
111 const std::vector<std::vector<uint32_t>>* clusterSizesBySurface)
112{
113 constexpr uint32_t maxLayers = MFTNLayers;
114 const auto& layerMapping = kLayerToLayout;
115 const auto& references = frame.getTrackClusterIndices();
116 std::array<const TrackClusterReference*, maxLayers> byLayer{};
117 for (uint32_t ref = common.firstClusterRef; ref < common.clusterRefEnd; ++ref) {
118 const auto& key = references[ref];
119 if (!key.isValid()) {
120 return false;
121 }
122 const auto where = std::find(layerMapping.begin(), layerMapping.end(), key.layer);
123 if (where == layerMapping.end() || static_cast<uint32_t>(where - layerMapping.begin()) >= maxLayers) {
124 return false;
125 }
126 const auto layer = static_cast<uint32_t>(where - layerMapping.begin());
127 if (byLayer[layer] != nullptr) {
128 return false;
129 }
130 byLayer[layer] = &key;
131 }
132 const int first = static_cast<int>(outputIndices.size());
133 uint32_t count = 0;
134 for (uint32_t layer = maxLayers; layer-- > 0;) {
135 const auto* reference = byLayer[layer];
136 if (reference == nullptr) {
137 continue;
138 }
139 uint32_t externalIndex = reference->clusterId;
140 if (externalIndicesBySurface != nullptr) {
141 if (reference->layer.value() >= externalIndicesBySurface->size() ||
142 reference->clusterId >= (*externalIndicesBySurface)[reference->layer.value()].size()) {
143 return false;
144 }
145 externalIndex = (*externalIndicesBySurface)[reference->layer.value()][reference->clusterId];
146 }
147 if (externalIndex > static_cast<uint32_t>(std::numeric_limits<int>::max())) {
148 return false;
149 }
150 if (clusterSizesBySurface == nullptr ||
151 reference->layer.value() >= clusterSizesBySurface->size() ||
152 reference->clusterId >= (*clusterSizesBySurface)[reference->layer.value()].size()) {
153 return false;
154 }
155 outputIndices.push_back(static_cast<int>(externalIndex));
156 output.setClusterSize(layer, (*clusterSizesBySurface)[reference->layer.value()][reference->clusterId]);
157 pattern |= 1u << layer;
158 ++count;
159 }
160 output.setExternalClusterIndexOffset(first);
161 output.setNumberOfPoints(static_cast<int>(count));
162 return true;
163}
164
165std::optional<TrackOutput> stageTrackOutput(const TimeFrame& frame,
166 const TrackPublicationTimingContext& context,
167 bool withMC,
168 const std::vector<std::vector<uint32_t>>* externalIndicesBySurface = nullptr,
169 const std::vector<std::vector<uint32_t>>* clusterSizesBySurface = nullptr)
170{
171 auto selection = selectGenericTracksForSurfaces(frame, kLayerToLayout);
172 if (!selection) {
173 return std::nullopt;
174 }
175 if (withMC && frame.getTrackLabels().size() != frame.getGenericTracks().size()) {
176 return std::nullopt;
177 }
178 const auto ordered = makeLegacyOutputOrder(frame, std::move(*selection), context.clock);
179 if (!ordered) {
180 return std::nullopt;
181 }
182 TrackOutput staged;
183 staged.trackROFs.assign(context.inputROFs.begin(), context.inputROFs.end());
184 staged.tracks.reserve(ordered->size());
185 staged.seedPatterns.reserve(ordered->size());
186 std::vector<o2::its::TimeStamp> times;
187 times.reserve(ordered->size());
188 for (const auto index : *ordered) {
189 const auto& common = frame.getGenericTracks()[index];
190 const auto timestamp = makeOutputTimestamp(common.timestamp, context.clock);
191 o2::track::TrackParCovFwd inner, outer;
192 if (!exportTrackState(common.innerState, inner) || !exportTrackState(common.outerState, outer)) {
193 return std::nullopt;
194 }
195 // Preserve the legacy TrackMFT object shape without claiming a seed-pT
196 // estimate from this tracker. TrackMFT does not initialize mInvQPtSeed.
197 outer.setTrackChi2(0.f);
199 static_cast<o2::track::TrackParCovFwd&>(output) = inner;
200 output.setOutParam(outer);
201 output.setTrackChi2(common.chi2);
202 output.setCA(true);
203 output.setInvQPtSeed(0.);
204 output.setChi2QPtSeed(0.);
205 uint32_t pattern = 0;
206 if (!collectReferences(frame, common, staged.clusterIndices, output, pattern,
207 externalIndicesBySurface, clusterSizesBySurface)) {
208 return std::nullopt;
209 }
210 staged.tracks.push_back(std::move(output));
211 staged.seedPatterns.push_back(static_cast<uint16_t>(pattern));
212 times.push_back(timestamp);
213 if (withMC) {
214 staged.labels.push_back(frame.getTrackLabels()[index]);
215 }
216 }
217 finalizeROFs(staged.trackROFs, times, context);
218 return staged;
219}
220
221bool rofOverlapsIRFrames(const o2::itsmft::ROFRecord& rof, int rofLengthInBC,
222 gsl::span<const o2::dataformats::IRFrame> irFrames)
223{
225 const o2::InteractionRecord end = start + rofLengthInBC - 1;
227 for (const auto& ir : irFrames) {
228 if (ir.info > 0 && reference.getOverlap(ir).isValid()) {
229 return true;
230 }
231 }
232 return false;
233}
234
235} // namespace
236
237CATrackerDPL::CATrackerDPL(std::shared_ptr<o2::base::GRPGeomRequest> gr, ca::TrackerOptions options)
238 : mGGCCDBRequest(std::move(gr)), mUseMC(options.useMC), mOptions(options)
239{
240}
241
242void CATrackerDPL::configureROFViews(gsl::span<const o2::itsmft::ROFRecord> rofs,
243 gsl::span<const o2::dataformats::IRFrame> irFrames)
244{
245 const auto& detector = mSession.frame.getDetectorConfiguration();
247 const bool continuous = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::MFT);
248 mMFTROFrameLengthInBC = continuous ? alpParams.roFrameLengthInBC : std::max(1, static_cast<int>(alpParams.roFrameLengthTrig / (o2::constants::lhc::LHCBunchSpacingNS * 1e3)));
249 const int nOrbitsPerTF = o2::base::GRPGeomHelper::getNHBFPerTF();
250 const auto timings = mSession.layerTimings(alpParams, nOrbitsPerTF, detector.addTimeError);
251 const auto& trackingParam = o2::mft::MFTTrackingParam::Instance();
252 const bool useIrFilter = mOptions.filterIRFrames && !irFrames.empty();
253 mSession.configureTiming(timings, [&](int rof) {
254 return rof >= static_cast<int>(rofs.size()) ||
255 ((!useIrFilter || rofOverlapsIRFrames(rofs[rof], mMFTROFrameLengthInBC, irFrames)) &&
256 (!trackingParam.isMultCutRequested() || trackingParam.isPassingMultCut(rofs[rof].getNEntries())));
257 });
258}
259
260void CATrackerDPL::initialiseTracking()
261{
262 const auto mode = mOptions.mode;
263 const auto& trackerParams = o2::itsmft::MFTCATrackerParam::Instance();
264 auto plan = o2::itsmft::TrackingMode::getTrackingPlan(o2::detectors::DetID::MFT, mode);
265 LOGP(info, "MFT CA tracker initialized in {} mode with {} iteration(s)",
266 o2::itsmft::TrackingMode::toString(mode), plan.iterations.size());
267 if (plan.iterations.empty()) {
268 return;
269 }
270
271 mTrackerTraits = std::make_unique<o2::itsmft::tracking::TrackerTraits>();
272 std::shared_ptr<tbb::task_arena> taskArena;
273 mTrackerTraits->setNThreads(mOptions.nThreads, taskArena);
274
275 const auto maxMemory = plan.execution.MaxMemory;
278 static_cast<uint32_t>(o2::itsmft::tracking::kMFTSurfaces.size())},
279 .holeLayers = o2::itsmft::tracking::LayerMask{trackerParams.holeLayerMask},
280 .plan = std::move(plan),
281 .memoryPool = std::make_shared<o2::itsmft::tracking::BoundedMemoryResource>(maxMemory)};
282
283 mTracker = std::make_unique<o2::itsmft::tracking::Tracker>();
284 if (!mTracker->initialize(mSession.frame, configuration)) {
285 LOGP(fatal, "MFT CA tracker failed to initialize static configuration");
286 }
287}
288
289bool CATrackerDPL::processTimeFrame(
290 gsl::span<const o2::itsmft::ROFRecord> rofs,
291 gsl::span<const o2::itsmft::CompClusterExt> clusters,
292 gsl::span<const unsigned char> patterns,
294{
295 if (!isActive()) {
296 LOGP(info, "MFT CA tracking mode is off, skipping TimeFrame processing");
297 return true;
298 }
299 mSession.frame.setBz(o2::base::Propagator::Instance()->getNominalBz());
302 source.detector = o2::detectors::DetID::MFT;
303 source.clusters = clusters;
304 source.patterns = patterns;
305 source.rofs = rofs;
306 source.dictionary = mDictionary;
307 source.labels = labels;
308 source.layerToSurface = kLayerToLayout;
309 return mSession.process(*mTracker, *mTrackerTraits, source, [](const o2::InteractionRecord&) {}, [](const o2::itsmft::tracking::TrackingStatistics&) {});
310}
311
316
318{
319 updateTimeDependentParams(pc);
320
321 auto rofsinput = pc.inputs().get<const std::vector<o2::itsmft::ROFRecord>>("ROframes");
322
323 if (decideCATrackerPublicationAction(isActive(), true) == CATrackerPublicationAction::PublishInactiveEmpty) {
324 // Existing production behavior, preserved exactly: publish the input
325 // ROFs verbatim (their firstEntry/nEntries are not rewritten here) plus
326 // empty track/cluster-index/seed-pattern outputs, when the tracker is
327 // not configured to run.
328 pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"MFT", "MFTTrackROF", 0},
329 rofsinput.begin(), rofsinput.end());
330 pc.outputs().make<std::vector<o2::mft::TrackMFT>>(Output{"MFT", "TRACKS", 0});
331 pc.outputs().make<std::vector<int>>(Output{"MFT", "TRACKCLSID", 0});
332 pc.outputs().make<std::vector<uint16_t>>(Output{"MFT", "TRACKSEEDPAT", 0});
333 return;
334 }
335
336 auto compClusters = pc.inputs().get<const std::vector<o2::itsmft::CompClusterExt>>("compClusters");
337 gsl::span<const unsigned char> patterns = pc.inputs().get<gsl::span<unsigned char>>("patterns");
338
340 if (mUseMC && pc.inputs().getPos("labels") >= 0) {
341 labels = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>("labels").release();
342 }
343
344 gsl::span<const o2::dataformats::IRFrame> irFrames;
345 if (pc.inputs().getPos("IRFramesITS") >= 0) {
346 irFrames = pc.inputs().get<gsl::span<o2::dataformats::IRFrame>>("IRFramesITS");
347 }
348
349 LOGP(info, "MFT CA input pulled {} compressed clusters in {} RO frames ({} pattern bytes)",
350 compClusters.size(), rofsinput.size(), patterns.size());
351
352 auto cleanup = mSession.cleanupOnExit();
353 configureROFViews(gsl::span<const o2::itsmft::ROFRecord>(rofsinput.data(), rofsinput.size()), irFrames);
354 const auto trackingSucceeded = processTimeFrame(gsl::span<const o2::itsmft::ROFRecord>(rofsinput.data(), rofsinput.size()),
355 gsl::span<const o2::itsmft::CompClusterExt>(compClusters.data(), compClusters.size()),
356 patterns, labels);
357
358 if (decideCATrackerPublicationAction(isActive(), trackingSucceeded) == CATrackerPublicationAction::SkipDroppedTimeFrame) {
359 LOGP(error, "MFT CA tracking dropped this TimeFrame ({} ROFs, {} clusters); publishing nothing and continuing with the next TimeFrame",
360 rofsinput.size(), compClusters.size());
361 cleanup.frameAlreadyReset();
362 return;
363 }
364
365 {
367 gsl::span<const o2::itsmft::ROFRecord>{rofsinput.data(), rofsinput.size()}, mSession.overlap.getView().getClockLayer()};
368 const auto staged = stageTrackOutput(mSession.frame, context, mUseMC,
369 &mSession.externalIndices, &mSession.clusterSizes);
370 if (!staged) {
371 throw std::runtime_error{"MFT GenericTrack output staging failed"};
372 }
373
375 Output{"MFT", "TRACKS", 0}, Output{"MFT", "TRACKCLSID", 0}, *staged);
376 auto& allSeedPatterns = pc.outputs().make<std::vector<uint16_t>>(Output{"MFT", "TRACKSEEDPAT", 0});
377 allSeedPatterns.assign(staged->seedPatterns.begin(), staged->seedPatterns.end());
378 LOGP(info, "MFT CA pushed {} tracks in {} ROFs", staged->tracks.size(), staged->trackROFs.size());
379 if (mUseMC) {
380 pc.outputs().snapshot(Output{"MFT", "TRACKSMCTR", 0}, staged->labels);
381 LOGP(info, "MFT CA pushed {} track MC labels", staged->labels.size());
382 }
383 }
384}
385
386void CATrackerDPL::updateTimeDependentParams(ProcessingContext& pc)
387{
389 if (!mTrackingInitialised) {
390 mTrackingInitialised = true;
391 initialiseTracking();
392 }
393 static bool initOnceDone = false;
394 if (!initOnceDone) {
395 initOnceDone = true;
396 if (pc.inputs().getPos("mftTGeo") >= 0) {
397 pc.inputs().get<o2::mft::GeometryTGeo*>("mftTGeo");
398 }
400 o2::mft::GeometryTGeo::Instance()->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L,
401 o2::math_utils::TransformType::T2GRot,
402 o2::math_utils::TransformType::T2G,
403 o2::math_utils::TransformType::L2G));
404 }
405}
406
408{
410 return;
411 }
412 if (matcher == ConcreteDataMatcher("MFT", "CLUSDICT", 0)) {
413 LOG(info) << "MFT CA input cluster dictionary updated";
414 mDictionary = static_cast<const o2::itsmft::TopologyDictionary*>(obj);
415 return;
416 }
417 if (matcher == ConcreteDataMatcher("MFT", "GEOMTGEO", 0)) {
418 LOG(info) << "MFT CA input GeometryTGeo loaded from CCDB";
420 o2::mft::GeometryTGeo::Instance()->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L,
421 o2::math_utils::TransformType::T2GRot,
422 o2::math_utils::TransformType::T2G,
423 o2::math_utils::TransformType::L2G));
424 // The catalog has static process lifetime; geometry adoption remains
425 // necessary for raw cluster decoding.
426 return;
427 }
428}
429
431{
432 const bool useMC = options.useMC;
433 const bool useGeom = options.geometry == ca::GeometrySource::Full;
434 std::vector<InputSpec> inputs;
435 inputs.emplace_back("compClusters", "MFT", "COMPCLUSTERS", 0, Lifetime::Timeframe);
436 inputs.emplace_back("patterns", "MFT", "PATTERNS", 0, Lifetime::Timeframe);
437 inputs.emplace_back("ROframes", "MFT", "CLUSTERSROF", 0, Lifetime::Timeframe);
438 inputs.emplace_back("cldict", "MFT", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("MFT/Calib/ClusterDictionary"));
439
440 if (useMC) {
441 inputs.emplace_back("labels", "MFT", "CLUSTERSMCTR", 0, Lifetime::Timeframe);
442 }
443
444 if (options.irFrames != ca::IRFrameSource::None) {
445 inputs.emplace_back("IRFramesITS", "ITS", "IRFRAMES", 0, Lifetime::Timeframe);
446 }
447
448 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false,
449 true,
450 false,
451 true,
452 true,
454 inputs,
455 true);
456 if (!useGeom) {
457 ggRequest->addInput({"mftTGeo", "MFT", "GEOMTGEO", 0, Lifetime::Condition, framework::ccdbParamSpec("MFT/Config/Geometry")}, inputs);
458 }
459
460 std::vector<OutputSpec> outputs;
461 outputs.emplace_back("MFT", "TRACKS", 0, Lifetime::Timeframe);
462 outputs.emplace_back("MFT", "MFTTrackROF", 0, Lifetime::Timeframe);
463 outputs.emplace_back("MFT", "TRACKCLSID", 0, Lifetime::Timeframe);
464 outputs.emplace_back("MFT", "TRACKSEEDPAT", 0, Lifetime::Timeframe);
465 if (useMC) {
466 outputs.emplace_back("MFT", "TRACKSMCTR", 0, Lifetime::Timeframe);
467 }
468
469 return DataProcessorSpec{
470 "mft-ca-tracker",
471 inputs,
472 outputs,
473 AlgorithmSpec{adaptFromTask<CATrackerDPL>(ggRequest, options)},
474 Options{}};
475}
476
477} // namespace o2::mft
std::vector< unsigned long > times
Definition of the ITSMFT compact cluster.
Definition of the ClusterTopology class.
Definition of the GeometryManager class.
int32_t i
Class to delimit start and end IR of certain time period.
Definition of the ITSMFT ROFrame (trigger) record.
Shared cluster I/O utilities for ITS and MFT (based on ITStracking/IOUtils.h)
Tracker orchestrator.
std::vector< o2::itsmft::ROFRecord > trackROFs
std::vector< int > clusterIndices
std::vector< o2::MCCompLabel > labels
std::vector< o2::its::TrackITS > tracks
Header to collect LHC related constants.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Definition of a container to keep Monte Carlo truth external to simulation objects.
std::vector< uint16_t > seedPatterns
StringRef key
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:180
A container to hold and manage MC truth information/labels.
void snapshot(const Output &spec, T const &object)
decltype(auto) make(const Output &spec, Args... args)
int getPos(const char *name) const
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
const BCData & getBCData() const
Definition ROFRecord.h:58
void configureTiming(gsl::span< const o2::its::LayerTiming > timings, AcceptROF &&accept)
std::vector< std::vector< uint32_t > > clusterSizes
bool process(Tracker &tracker, TrackerTraits &traits, ClusterSourceInput source, AfterLoad &&afterLoad, Complete &&complete)
std::vector< o2::its::LayerTiming > layerTimings(const AlpideParameters &alpide, int nOrbits, const std::vector< uint32_t > &addTimeError) const
std::vector< std::vector< uint32_t > > externalIndices
void run(framework::ProcessingContext &pc) final
void init(framework::InitContext &ic) final
CATrackerDPL(std::shared_ptr< o2::base::GRPGeomRequest > gr, ca::TrackerOptions options)
void finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj) final
void fillMatrixCache(Int_t mask) override
static GeometryTGeo * Instance()
static void adopt(GeometryTGeo *raw, bool canDelete=false)
void setTrackChi2(Double_t chi2)
set the chi2 of the track when the associated cluster was attached
Definition TrackFwd.h:124
GLenum mode
Definition glcorearb.h:266
GLint GLsizei count
Definition glcorearb.h:399
GLuint GLuint end
Definition glcorearb.h:469
GLuint index
Definition glcorearb.h:781
GLint first
Definition glcorearb.h:399
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLint reference
Definition glcorearb.h:5487
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLuint start
Definition glcorearb.h:469
GLint ref
Definition glcorearb.h:291
std::string timestamp() noexcept
Definition Clock.h:84
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
std::string toString(Type mode)
TrackingPlan getTrackingPlan(o2::detectors::DetID::ID detId, Type mode)
void copyTrackingOutputColumns(Allocator &outputs, Output rofs, Output tracks, Output indices, const Staged &staged)
std::optional< std::vector< uint32_t > > selectGenericTracksForSurfaces(const TimeFrame &frame, gsl::span< const LayerId > sourceSurfaces)
constexpr std::array< SurfaceDescriptor, MFTNLayers > kMFTSurfaces
o2::its::TimeStamp makeOutputTimestamp(o2::its::TimeStamp timestamp, const o2::its::LayerTiming &clock) noexcept
constexpr int MFTNLayers
MFT CA half-disk layer count.
void finalizeROFs(std::vector< o2::itsmft::ROFRecord > &rofs, const std::vector< o2::its::TimeStamp > &times, const TrackPublicationTimingContext &context)
CATrackerPublicationAction decideCATrackerPublicationAction(bool active, bool success) noexcept
std::optional< std::vector< uint32_t > > makeLegacyOutputOrder(const TimeFrame &frame, std::vector< uint32_t > selection, const o2::its::LayerTiming &clock)
o2::framework::DataProcessorSpec getCATrackerSpec(const ca::TrackerOptions &options)
void cleanup()
const DetectorConfiguration & getDetectorConfiguration() const noexcept
Definition TimeFrame.h:157
gsl::span< const o2::itsmft::ROFRecord > inputROFs
o2::itsmft::TrackingMode::Type mode
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
std::vector< Cluster > clusters
std::vector< int > row
std::array< uint16_t, 5 > pattern