46#include <oneapi/tbb/task_arena.h>
64constexpr std::array<LayerId, NLayers> detectorLocalToLayoutLayers()
66 std::array<LayerId, NLayers> order{};
67 for (
int i = 0;
i < NLayers; ++
i) {
68 order[
i] =
LayerId{
static_cast<uint16_t
>(
i)};
73inline constexpr auto kLayerToLayout = detectorLocalToLayoutLayers<ITSNLayers>();
76 std::vector<o2::its::TrackITS>
tracks;
84 if (
source.kind != SurfaceKind::Cylinder) {
87 o2::track::TrackParCovF::params_t parameters{};
88 o2::track::TrackParCovF::covMat_t covariance{};
89 for (uint8_t
i = 0;
i < 5; ++
i) {
90 parameters[
i] =
source.parameters[
i];
92 for (uint8_t
i = 0;
i < 15; ++
i) {
93 covariance[
i] =
source.covariance[
i];
96 destination = scratch;
102 const std::vector<std::vector<uint32_t>>* externalIndicesBySurface,
103 const std::vector<std::vector<uint32_t>>* clusterSizesBySurface)
106 const auto& layerMapping = kLayerToLayout;
108 std::array<const TrackClusterReference*, maxLayers> byLayer{};
110 const auto&
key = references[
ref];
111 if (!
key.isValid()) {
114 const auto where = std::find(layerMapping.begin(), layerMapping.end(),
key.layer);
115 if (where == layerMapping.end() ||
static_cast<uint32_t
>(where - layerMapping.begin()) >= maxLayers) {
118 const auto layer =
static_cast<uint32_t
>(where - layerMapping.begin());
119 if (byLayer[
layer] !=
nullptr) {
124 const int first =
static_cast<int>(outputIndices.size());
126 for (uint32_t
layer = maxLayers;
layer-- > 0;) {
131 uint32_t externalIndex =
reference->clusterId;
132 if (externalIndicesBySurface !=
nullptr) {
133 if (
reference->layer.value() >= externalIndicesBySurface->size() ||
134 reference->clusterId >= (*externalIndicesBySurface)[
reference->layer.value()].size()) {
137 externalIndex = (*externalIndicesBySurface)[
reference->layer.value()][
reference->clusterId];
139 if (externalIndex >
static_cast<uint32_t
>(std::numeric_limits<int>::max())) {
142 if (clusterSizesBySurface ==
nullptr ||
143 reference->layer.value() >= clusterSizesBySurface->size() ||
147 outputIndices.push_back(
static_cast<int>(externalIndex));
156std::optional<TrackOutput> stageTrackOutput(
const TimeFrame& frame,
158 gsl::span<const uint8_t> sharedClusterFlags,
160 const std::vector<std::vector<uint32_t>>* externalIndicesBySurface =
nullptr,
161 const std::vector<std::vector<uint32_t>>* clusterSizesBySurface =
nullptr)
176 staged.tracks.reserve(
ordered->size());
177 staged.labels.reserve(withMC ?
ordered->size() : 0);
178 std::vector<o2::its::TimeStamp>
times;
184 if (!exportTrackState(common.
innerState, inner) || !exportTrackState(common.
outerState, outer)) {
187 if (
index >= sharedClusterFlags.size() || sharedClusterFlags[
index] > 1) {
192 if (!collectReferences(frame, common, staged.clusterIndices,
output,
pattern,
193 externalIndicesBySurface, clusterSizesBySurface)) {
197 output.setSharedClusters(sharedClusterFlags[
index] != 0);
199 staged.tracks.push_back(std::move(
output));
200 times.push_back(timestamp);
209bool completePublication(PublicationAdapter& publication,
215 std::size_t firstTrack = 0;
216 for (std::size_t iteration = 0; iteration < configurations.size(); ++iteration) {
222 std::iota(trackIndices.begin(), trackIndices.end(),
static_cast<uint32_t
>(firstTrack));
223 if (!publication.completeAccepted(trackIndices, configurations[iteration].parameters, frame, iteration + 1 == configurations.size())) {
234 : mGGCCDBRequest(
std::move(gr)), mUseMC(options.useMC), mOptions(
std::move(options))
243 LOGP(info,
"ITS CA using truth seeds as vertices");
247 throw std::runtime_error(
"ITS CA truth seeding received invalid ROF timing");
251 throw std::runtime_error(
"ITS CA truth seeding could not load " + mOptions.
truthContext);
253 const auto& irs = dc->getEventRecords();
255 constexpr int iSrc = 0;
256 const auto eveId2colId = dc->getCollisionIndicesForSource(iSrc);
257 std::vector<std::pair<o2::its::TimeEstBC, int>> selected;
258 for (
int iEve = 0; iEve < mcReader.getNEvents(iSrc); ++iEve) {
259 const auto collision = eveId2colId.find(iEve);
260 if (collision == eveId2colId.end()) {
265 selected.emplace_back(*timestamp, iEve);
269 std::sort(selected.begin(), selected.end(), [](
const auto&
a,
const auto&
b) {
270 return std::pair{a.first.lower(), a.second} < std::pair{b.first.lower(), b.second};
272 for (
const auto& [timestamp, iEve] : selected) {
273 const auto&
event = mcReader.getMCEventHeader(iSrc, iEve);
276 vertex.setNContributors(std::max(1L, std::ranges::count_if(mcReader.getTracks(iSrc, iEve), [](
const auto& track) {
277 if (!track.isPrimary() || track.GetPt() < 0.05 || std::abs(track.GetEta()) > 1.1) {
281 return particle && particle->Charge() != 0;
283 vertex.setXYZ(
static_cast<float>(
event.GetX()),
static_cast<float>(
event.GetY()),
static_cast<float>(
event.GetZ()));
285 constexpr float covariance = 25.e-4f;
286 vertex.setSigmaX(covariance);
287 vertex.setSigmaY(covariance);
288 vertex.setSigmaZ(covariance);
289 mSession.frame.addPrimaryVertex(
vertex);
292 mcReader.releaseTracksForSourceAndEvent(iSrc, iEve);
294 LOGP(info,
"ITS CA imposed {} pv collisions from MC truth", mSession.frame.getPrimaryVertices().size());
297void CATrackerDPL::configureROFViews(gsl::span<const o2::itsmft::ROFRecord> rofs)
299 const auto& detector = mSession.frame.getDetectorConfiguration();
302 const auto timings = mSession.layerTimings(alpParams, nOrbitsPerTF, detector.addTimeError);
303 mSession.configureTiming(timings, [](
int) {
return true; });
307void CATrackerDPL::initialiseTracking()
309 const auto mode = mOptions.mode;
311 for (
auto& pass : plan.iterations) {
312 pass.UseDiamond = mOptions.vertexSource == VertexSource::Diamond;
314 LOGP(info,
"ITS CA tracker initialized in {} mode with {} iteration(s)",
316 if (plan.iterations.empty()) {
320 mTrackerTraits = std::make_unique<o2::itsmft::tracking::TrackerTraits>();
321 std::shared_ptr<tbb::task_arena> taskArena;
323 mTrackerTraits->setNThreads(mOptions.nThreads, taskArena);
325 const auto maxMemory = plan.execution.MaxMemory;
330 .plan = std::move(plan),
331 .memoryPool = std::make_shared<o2::itsmft::tracking::BoundedMemoryResource>(maxMemory)};
333 mTracker = std::make_unique<o2::itsmft::tracking::Tracker>();
334 if (!mTracker->initialize(mSession.frame, configuration)) {
335 LOGP(fatal,
"ITS CA tracker failed to initialize static configuration");
339bool CATrackerDPL::processTimeFrame(
340 gsl::span<const o2::itsmft::ROFRecord> rofs,
341 gsl::span<const o2::itsmft::CompClusterExt>
clusters,
342 gsl::span<const unsigned char> patterns,
346 LOGP(info,
"ITS CA tracking mode is off, skipping TimeFrame processing");
352 source.detector = o2::detectors::DetID::ITS;
354 source.patterns = patterns;
356 source.dictionary = mDictionary;
358 source.layerToSurface = kLayerToLayout;
360 if (mOptions.vertexSource == VertexSource::Truth) {
361 addTruthSeedingVertices(origin, rofs);
362 mSession.vertices.update(mSession.frame.getPrimaryVertices().data(), mSession.frame.getPrimaryVertices().size());
364 if (!completePublication(mPublication, mSession.frame, *mTracker, statistics)) {
365 throw std::runtime_error{
"failed to prepare ITS shared-cluster flags"};
376 auto publicationCleanup = mPublication.cleanupOnExit();
377 updateTimeDependentParams(pc);
379 auto rofsinput = pc.
inputs().
get<
const std::vector<o2::itsmft::ROFRecord>>(
"ROframes");
382 pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"ITSTrackROF", 0},
383 rofsinput.begin(), rofsinput.end());
389 auto compClusters = pc.
inputs().
get<
const std::vector<o2::itsmft::CompClusterExt>>(
"compClusters");
390 gsl::span<const unsigned char> patterns = pc.
inputs().
get<gsl::span<unsigned char>>(
"patterns");
397 LOGP(info,
"ITS CA input pulled {} compressed clusters in {} RO frames ({} pattern bytes)",
398 compClusters.size(), rofsinput.size(), patterns.size());
400 auto cleanup = mSession.cleanupOnExit();
401 configureROFViews(gsl::span<const o2::itsmft::ROFRecord>(rofsinput.data(), rofsinput.size()));
402 const auto trackingSucceeded = processTimeFrame(gsl::span<const o2::itsmft::ROFRecord>(rofsinput.data(), rofsinput.size()),
403 gsl::span<const o2::itsmft::CompClusterExt>(compClusters.data(), compClusters.size()),
407 LOGP(error,
"ITS CA tracking dropped this TimeFrame ({} ROFs, {} clusters); publishing nothing and continuing with the next TimeFrame",
408 rofsinput.size(), compClusters.size());
415 gsl::span<const o2::itsmft::ROFRecord>{rofsinput.data(), rofsinput.size()}, mSession.overlap.getView().getClockLayer()};
416 const auto staged = stageTrackOutput(mSession.frame, context, mPublication.sharedClusterFlags(), mUseMC,
417 &mSession.externalIndices, &mSession.clusterSizes);
419 throw std::runtime_error{
"ITS GenericTrack output staging failed"};
423 Output{
"ITS",
"TRACKS", 0},
Output{
"ITS",
"TRACKCLSID", 0}, *staged);
424 LOGP(info,
"ITS CA pushed {} tracks in {} ROFs", staged->tracks.size(), staged->trackROFs.size());
427 LOGP(info,
"ITS CA pushed {} track MC labels", staged->labels.size());
436 if (!mTrackingInitialised) {
437 mTrackingInitialised =
true;
438 initialiseTracking();
440 static bool initOnceDone =
false;
448 o2::math_utils::TransformType::T2GRot,
449 o2::math_utils::TransformType::T2G));
459 LOG(info) <<
"ITS CA input cluster dictionary updated";
464 LOG(info) <<
"ITS CA input Alpide param updated";
469 LOG(info) <<
"ITS CA input GeometryTGeo loaded from CCDB";
472 o2::math_utils::TransformType::T2GRot,
473 o2::math_utils::TransformType::T2G));
482 const bool useMC = options.
useMC;
484 std::vector<InputSpec> inputs;
485 inputs.emplace_back(
"compClusters",
"ITS",
"COMPCLUSTERS", 0, Lifetime::Timeframe);
486 inputs.emplace_back(
"patterns",
"ITS",
"PATTERNS", 0, Lifetime::Timeframe);
487 inputs.emplace_back(
"ROframes",
"ITS",
"CLUSTERSROF", 0, Lifetime::Timeframe);
488 inputs.emplace_back(
"itscldict",
"ITS",
"CLUSDICT", 0, Lifetime::Condition,
ccdbParamSpec(
"ITS/Calib/ClusterDictionary"));
489 inputs.emplace_back(
"itsalppar",
"ITS",
"ALPIDEPARAM", 0, Lifetime::Condition,
ccdbParamSpec(
"ITS/Config/AlpideParam"));
492 inputs.emplace_back(
"labels",
"ITS",
"CLUSTERSMCTR", 0, Lifetime::Timeframe);
495 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
504 ggRequest->addInput({
"itsTGeo",
"ITS",
"GEOMTGEO", 0, Lifetime::Condition,
framework::ccdbParamSpec(
"ITS/Config/Geometry")}, inputs);
507 std::vector<OutputSpec> outputs;
508 outputs.emplace_back(
"ITS",
"TRACKS", 0, Lifetime::Timeframe);
509 outputs.emplace_back(
"ITS",
"TRACKCLSID", 0, Lifetime::Timeframe);
510 outputs.emplace_back(
"ITS",
"ITSTrackROF", 0, Lifetime::Timeframe);
512 outputs.emplace_back(
"ITS",
"TRACKSMCTR", 0, Lifetime::Timeframe);
519 AlgorithmSpec{adaptFromTask<CATrackerDPL>(ggRequest, options)},
header::DataOrigin origin
std::vector< unsigned long > times
Definition of the ITSMFT compact cluster.
Definition of the GeometryManager class.
Definition of the GeometryTGeo class.
Shared cluster I/O utilities for ITS and MFT (based on ITStracking/IOUtils.h)
ITS common-CA tracker DPL device with tracker-only outputs.
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.
Definition of the ITS track.
static constexpr int maxTrackID()
static TDatabasePDG * Instance()
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.
static GeometryTGeo * Instance()
void fillMatrixCache(int mask) override
static void adopt(GeometryTGeo *raw, bool canDelete=false)
CATrackerDPL(std::shared_ptr< o2::base::GRPGeomRequest > gr, WorkflowOptions options)
gsl::span< const IterationConfiguration > getIterationConfigurations() const noexcept
static DigitizationContext * loadFromFile(std::string_view filename="")
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLuint GLsizei const GLchar * label
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLenum GLuint GLint GLint layer
GLboolean GLboolean GLboolean GLboolean a
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::optional< o2::its::TimeEstBC > truthSeedingWindow(gsl::span< const o2::itsmft::ROFRecord > rofs, const o2::InteractionRecord &origin, const o2::its::LayerTiming &timing) noexcept
std::optional< o2::its::TimeEstBC > truthSeedingTime(const o2::InteractionRecord &collision, const o2::InteractionRecord &origin, const o2::its::TimeEstBC &window, uint32_t duration) noexcept
o2::framework::DataProcessorSpec getCATrackerSpec(const WorkflowOptions &options)
const bool const int TrackITSInternal< NLayers > & track
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)
o2::its::VertexLabel VertexLabel
o2::its::TimeStamp makeOutputTimestamp(o2::its::TimeStamp timestamp, const o2::its::LayerTiming &clock) noexcept
constexpr std::array< SurfaceDescriptor, ITSNLayers > kITSSurfaces
constexpr int ITSNLayers
ITS CA 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)
bool isActive(const Node< T > &node)
TrackParametrizationWithError< float > TrackParCovF
struct o2::upgrades_utils::@470 collision
SurfaceTrackState outerState
o2::its::TimeStamp timestamp
SurfaceTrackState innerState
RuntimeROFOverlapView overlap
auto & getGenericTracks()
auto & getTrackClusterIndices()
const RuntimeROFViews & getROFViews() const noexcept
gsl::span< const o2::itsmft::ROFRecord > inputROFs
o2::its::LayerTiming clock
SurfaceCatalogView catalog
std::vector< std::size_t > acceptedTrackCounts
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters
std::array< uint16_t, 5 > pattern