42#include <oneapi/tbb/task_arena.h>
44#include "MFTBase/GeometryTGeo.h"
45#include "MFTTracking/Constants.h"
60constexpr std::array<LayerId, NLayers> detectorLocalToLayoutLayers()
62 std::array<LayerId, NLayers> order{};
63 for (
int i = 0;
i < NLayers; ++
i) {
64 order[
i] =
LayerId{
static_cast<uint16_t
>(
i)};
69inline constexpr auto kLayerToLayout = detectorLocalToLayoutLayers<MFTNLayers>();
72 std::vector<o2::mft::TrackMFT>
tracks;
81 if (
source.kind != SurfaceKind::Disk) {
86 for (uint8_t
i = 0;
i < 5; ++
i) {
87 if (!o2::gpu::GPUCommonMath::Finite(
source.parameters[
i])) {
90 parameters[
i] =
source.parameters[
i];
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)) {
101 if (!o2::gpu::GPUCommonMath::Finite(
source.referenceCoordinate)) {
110 const std::vector<std::vector<uint32_t>>* externalIndicesBySurface,
111 const std::vector<std::vector<uint32_t>>* clusterSizesBySurface)
114 const auto& layerMapping = kLayerToLayout;
116 std::array<const TrackClusterReference*, maxLayers> byLayer{};
118 const auto&
key = references[
ref];
119 if (!
key.isValid()) {
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) {
126 const auto layer =
static_cast<uint32_t
>(where - layerMapping.begin());
127 if (byLayer[
layer] !=
nullptr) {
132 const int first =
static_cast<int>(outputIndices.size());
134 for (uint32_t
layer = maxLayers;
layer-- > 0;) {
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()) {
145 externalIndex = (*externalIndicesBySurface)[
reference->layer.value()][
reference->clusterId];
147 if (externalIndex >
static_cast<uint32_t
>(std::numeric_limits<int>::max())) {
150 if (clusterSizesBySurface ==
nullptr ||
151 reference->layer.value() >= clusterSizesBySurface->size() ||
155 outputIndices.push_back(
static_cast<int>(externalIndex));
165std::optional<TrackOutput> stageTrackOutput(
const TimeFrame& frame,
168 const std::vector<std::vector<uint32_t>>* externalIndicesBySurface =
nullptr,
169 const std::vector<std::vector<uint32_t>>* clusterSizesBySurface =
nullptr)
184 staged.tracks.reserve(
ordered->size());
185 staged.seedPatterns.reserve(
ordered->size());
186 std::vector<o2::its::TimeStamp>
times;
192 if (!exportTrackState(common.
innerState, inner) || !exportTrackState(common.
outerState, outer)) {
200 output.setOutParam(outer);
204 output.setChi2QPtSeed(0.);
206 if (!collectReferences(frame, common, staged.clusterIndices,
output,
pattern,
207 externalIndicesBySurface, clusterSizesBySurface)) {
210 staged.tracks.push_back(std::move(
output));
211 staged.seedPatterns.push_back(
static_cast<uint16_t
>(
pattern));
212 times.push_back(timestamp);
222 gsl::span<const o2::dataformats::IRFrame> irFrames)
227 for (
const auto&
ir : irFrames) {
238 : mGGCCDBRequest(
std::move(gr)), mUseMC(options.useMC), mOptions(options)
242void CATrackerDPL::configureROFViews(gsl::span<const o2::itsmft::ROFRecord> rofs,
243 gsl::span<const o2::dataformats::IRFrame> irFrames)
248 mMFTROFrameLengthInBC = continuous ? alpParams.roFrameLengthInBC : std::max(1,
static_cast<int>(alpParams.roFrameLengthTrig / (o2::constants::lhc::LHCBunchSpacingNS * 1e3)));
250 const auto timings = mSession.
layerTimings(alpParams, nOrbitsPerTF, detector.addTimeError);
252 const bool useIrFilter = mOptions.
filterIRFrames && !irFrames.empty();
254 return rof >=
static_cast<int>(rofs.size()) ||
255 ((!useIrFilter || rofOverlapsIRFrames(rofs[rof], mMFTROFrameLengthInBC, irFrames)) &&
256 (!trackingParam.isMultCutRequested() || trackingParam.isPassingMultCut(rofs[rof].getNEntries())));
260void CATrackerDPL::initialiseTracking()
265 LOGP(info,
"MFT CA tracker initialized in {} mode with {} iteration(s)",
267 if (plan.iterations.empty()) {
271 mTrackerTraits = std::make_unique<o2::itsmft::tracking::TrackerTraits>();
272 std::shared_ptr<tbb::task_arena> taskArena;
273 mTrackerTraits->setNThreads(mOptions.
nThreads, taskArena);
275 const auto maxMemory = plan.execution.MaxMemory;
280 .plan = std::move(plan),
281 .memoryPool = std::make_shared<o2::itsmft::tracking::BoundedMemoryResource>(maxMemory)};
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");
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,
296 LOGP(info,
"MFT CA tracking mode is off, skipping TimeFrame processing");
302 source.detector = o2::detectors::DetID::MFT;
304 source.patterns = patterns;
306 source.dictionary = mDictionary;
308 source.layerToSurface = kLayerToLayout;
319 updateTimeDependentParams(pc);
321 auto rofsinput = pc.
inputs().
get<
const std::vector<o2::itsmft::ROFRecord>>(
"ROframes");
328 pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"MFT",
"MFTTrackROF", 0},
329 rofsinput.begin(), rofsinput.end());
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");
344 gsl::span<const o2::dataformats::IRFrame> irFrames;
346 irFrames = pc.
inputs().
get<gsl::span<o2::dataformats::IRFrame>>(
"IRFramesITS");
349 LOGP(info,
"MFT CA input pulled {} compressed clusters in {} RO frames ({} pattern bytes)",
350 compClusters.size(), rofsinput.size(), patterns.size());
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()),
359 LOGP(error,
"MFT CA tracking dropped this TimeFrame ({} ROFs, {} clusters); publishing nothing and continuing with the next TimeFrame",
360 rofsinput.size(), compClusters.size());
367 gsl::span<const o2::itsmft::ROFRecord>{rofsinput.data(), rofsinput.size()}, mSession.
overlap.getView().getClockLayer()};
368 const auto staged = stageTrackOutput(mSession.
frame, context, mUseMC,
371 throw std::runtime_error{
"MFT GenericTrack output staging failed"};
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());
381 LOGP(info,
"MFT CA pushed {} track MC labels", staged->labels.size());
389 if (!mTrackingInitialised) {
390 mTrackingInitialised =
true;
391 initialiseTracking();
393 static bool initOnceDone =
false;
401 o2::math_utils::TransformType::T2GRot,
402 o2::math_utils::TransformType::T2G,
403 o2::math_utils::TransformType::L2G));
413 LOG(info) <<
"MFT CA input cluster dictionary updated";
418 LOG(info) <<
"MFT CA input GeometryTGeo loaded from CCDB";
421 o2::math_utils::TransformType::T2GRot,
422 o2::math_utils::TransformType::T2G,
423 o2::math_utils::TransformType::L2G));
432 const bool useMC = options.
useMC;
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"));
441 inputs.emplace_back(
"labels",
"MFT",
"CLUSTERSMCTR", 0, Lifetime::Timeframe);
445 inputs.emplace_back(
"IRFramesITS",
"ITS",
"IRFRAMES", 0, Lifetime::Timeframe);
448 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
457 ggRequest->addInput({
"mftTGeo",
"MFT",
"GEOMTGEO", 0, Lifetime::Condition,
framework::ccdbParamSpec(
"MFT/Config/Geometry")}, inputs);
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);
466 outputs.emplace_back(
"MFT",
"TRACKSMCTR", 0, Lifetime::Timeframe);
473 AlgorithmSpec{adaptFromTask<CATrackerDPL>(ggRequest, options)},
std::vector< unsigned long > times
Definition of the ITSMFT compact cluster.
Definition of the GeometryManager class.
Class to delimit start and end IR of certain time period.
Shared cluster I/O utilities for ITS and MFT (based on ITStracking/IOUtils.h)
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.
Definition of a container to keep Monte Carlo truth external to simulation objects.
std::vector< uint16_t > seedPatterns
void checkUpdates(o2::framework::ProcessingContext &pc)
static int getNHBFPerTF()
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)
static const DPLAlpideParam< N > & Instance()
void snapshot(const Output &spec, T const &object)
decltype(auto) make(const Output &spec, Args... args)
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
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
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLenum GLuint GLint GLint layer
std::string timestamp() noexcept
Defining ITS Vertex explicitly as messageable.
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 > ×, 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)
SurfaceTrackState outerState
o2::its::TimeStamp timestamp
SurfaceTrackState innerState
auto & getGenericTracks()
auto & getTrackClusterIndices()
const DetectorConfiguration & getDetectorConfiguration() const noexcept
gsl::span< const o2::itsmft::ROFRecord > inputROFs
o2::its::LayerTiming clock
SurfaceCatalogView catalog
o2::itsmft::TrackingMode::Type mode
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
std::vector< Cluster > clusters
std::array< uint16_t, 5 > pattern