Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
41e1eba
ITSMFT: unify cellular automaton tracking for ITS and MFT
mpuccio Sep 8, 2026
1afbfdc
Fix tests for ARM CI
mpuccio Sep 14, 2026
e86650b
Implement Maurice's comments
mpuccio Sep 14, 2026
cab7ed4
Fix forward tracklet-compatibility selection
mpuccio Sep 15, 2026
7d166bf
Remove unused MFTFwdTrackHelpers
mpuccio Sep 15, 2026
42b4d4e
Remove operation result/failure metadata structs
mpuccio Sep 15, 2026
a96d9fd
Cleanup ITSSharedClusterCompatibility and output errors
mpuccio Sep 15, 2026
122c0d8
Rationalise the track publication
mpuccio Sep 15, 2026
da414ee
Start migration of propagation bits into Propagator
mpuccio Sep 15, 2026
c179073
Rationalising IOUtils
mpuccio Sep 16, 2026
7a9af8a
Clenaup configuration and track parameter handling
mpuccio Sep 16, 2026
73e450d
Unclutter detector layout description
mpuccio Sep 16, 2026
fd1df7a
Cell -> Triplet rename + cleanups
mpuccio Sep 16, 2026
1b6f096
Cleanup helpers for the Tracker
mpuccio Sep 16, 2026
824fcf0
Cleanup indextable configuration
mpuccio Sep 16, 2026
f4a50d7
Using commond angle normalisation
mpuccio Sep 16, 2026
69dde8b
Unify application of systematics
mpuccio Sep 16, 2026
371f12c
Unclutter the configuration
mpuccio Sep 16, 2026
427b86e
Remove TrackingConfigParam duplication
mpuccio Sep 16, 2026
8b036bb
Further IOUtils cleanup
mpuccio Sep 16, 2026
4b93107
Consolidate the Propagator methods
mpuccio Sep 16, 2026
3c728a3
Use legacy timing classes
mpuccio Sep 16, 2026
1295950
Remove timing helpers
mpuccio Sep 16, 2026
72b2899
Remove stale function
mpuccio Sep 16, 2026
c0d6334
Stabilise propagation in forward direction
mpuccio Sep 17, 2026
3820a39
Use fma to improve even further numerical stability
mpuccio Sep 17, 2026
aad0f92
Improve common ITS/MFT refit initialization
mpuccio Sep 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Detectors/ITSMFT/ITS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_subdirectory(simulation)
add_subdirectory(reconstruction)
add_subdirectory(tracking)
add_subdirectory(workflow)
add_subdirectory(workflow-ca)
add_subdirectory(postprocessing)
add_subdirectory(macros)
add_subdirectory(QC)
48 changes: 48 additions & 0 deletions Detectors/ITSMFT/ITS/workflow-ca/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2019-2020 CERN and copyright holders of ALICE O2.
# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
# All rights not expressly granted are reserved.
#
# This software is distributed under the terms of the GNU General Public
# License v3 (GPL Version 3), copied verbatim in the file "COPYING".
#
# In applying this license CERN does not waive the privileges and immunities
# granted to it by virtue of its status as an Intergovernmental Organization
# or submit itself to any jurisdiction.

o2_add_library(ITSCAWorkflow
TARGETVARNAME targetName
SOURCES src/ConfigPreflight.cxx
src/CATrackerSpec.cxx
PUBLIC_LINK_LIBRARIES O2::Framework
O2::SimulationDataFormat
O2::DataFormatsITS
O2::DataFormatsITSMFT
O2::ITSBase
O2::ITSMFTTracking
O2::ITSMFTCAWriter
O2::MFTTracking
O2::Steer
O2::CCDB)

o2_add_executable(ca-tracker-workflow
SOURCES src/its-ca-tracker-workflow.cxx
COMPONENT_NAME its
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)

o2_add_test(its-ca-config-preflight
COMPONENT_NAME its
LABELS "its;workflow;itsmft"
SOURCES test/testITSCAConfigPreflight.cxx
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)

o2_add_test(its-ca-tracker-dpl-contract
COMPONENT_NAME its
LABELS "its;workflow;itsmft"
SOURCES test/testITSCATrackerDPLContract.cxx
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)

o2_add_test(its-ca-truth-seeding
COMPONENT_NAME its
LABELS "its;workflow;itsmft"
SOURCES test/testITSCATruthSeeding.cxx
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
///
/// \file CATrackerSpec.h
/// \brief ITS common-CA tracker DPL device with tracker-only outputs.

#ifndef O2_ITS_CA_WORKFLOW_CATRACKERSPEC_H_
#define O2_ITS_CA_WORKFLOW_CATRACKERSPEC_H_

#include <cstdint>
#include <memory>
#include <optional>
#include <vector>

#include <gsl/span>

#include "DataFormatsITSMFT/ROFRecord.h"
#include "DetectorsBase/GRPGeomHelper.h"
#include "Framework/DataProcessorSpec.h"
#include "Framework/Task.h"
#include "ITSMFTTracking/Configuration.h"
#include "ITSCAWorkflow/ConfigPreflight.h"
#include "ITSCAWorkflow/PublicationAdapter.h"
#include "ITSMFTTracking/Tracker.h"
#include "ITSMFTTracking/TrackerTraits.h"
#include "ITSMFTTracking/WorkflowSession.h"
#include "ITSMFTTracking/IOUtils.h"
#include "ITSMFTTracking/ITSMFTDetectorDefinitions.h"
#include "ITSMFTTracking/ROFViews.h"
#include "ITSMFTTracking/ROFLookupTables.h"
#include "DataFormatsITSMFT/TopologyDictionary.h"
#include "SimulationDataFormat/MCCompLabel.h"

namespace o2::its::ca
{

using o2::itsmft::tracking::CATrackerPublicationAction;
using o2::itsmft::tracking::decideCATrackerPublicationAction;

/// ITS common-CA tracker DPL task. Owns the TimeFrame and composes the
/// workflow input/timing/publication edge with Tracker.
class CATrackerDPL : public o2::framework::Task
{
public:
CATrackerDPL(std::shared_ptr<o2::base::GRPGeomRequest> gr, WorkflowOptions options);
~CATrackerDPL() override = default;

void init(framework::InitContext& ic) final;
void run(framework::ProcessingContext& pc) final;
void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final;

private:
void updateTimeDependentParams(framework::ProcessingContext& pc);
void addTruthSeedingVertices(const o2::InteractionRecord& origin, gsl::span<const o2::itsmft::ROFRecord> rofs);
void configureROFViews(gsl::span<const o2::itsmft::ROFRecord> rofs);
void initialiseTracking();
bool processTimeFrame(
gsl::span<const o2::itsmft::ROFRecord> rofs,
gsl::span<const o2::itsmft::CompClusterExt> clusters,
gsl::span<const unsigned char> patterns,
const o2::dataformats::MCTruthContainer<MCCompLabel>* labels);
bool isActive() const noexcept { return mTracker != nullptr && mTracker->isConfiguredFor(mSession.frame); }

std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
bool mUseMC = false;
bool mTrackingInitialised = false;
WorkflowOptions mOptions;
o2::itsmft::tracking::WorkflowSession mSession{"ITS", o2::itsmft::tracking::ITSNLayers};
std::unique_ptr<o2::itsmft::tracking::TrackerTraits> mTrackerTraits;
std::unique_ptr<o2::itsmft::tracking::Tracker> mTracker;
const o2::itsmft::TopologyDictionary* mDictionary = nullptr;
PublicationAdapter mPublication;
};

o2::framework::DataProcessorSpec getCATrackerSpec(const WorkflowOptions& options);

} // namespace o2::its::ca

#endif // O2_ITS_CA_WORKFLOW_CATRACKERSPEC_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
///
/// \file ConfigPreflight.h
/// \brief Driver-level configuration and vertex-constraint preflight for the
/// ITS common-CA tracker workflow.
///
/// Resolve driver options before constructing any DPL device.

#ifndef ALICEO2_ITS_CA_WORKFLOW_CONFIGPREFLIGHT_H_
#define ALICEO2_ITS_CA_WORKFLOW_CONFIGPREFLIGHT_H_

#include <string>

#include "ITSMFTTracking/Configuration.h"

namespace o2::framework
{
class ConfigContext;
}

namespace o2::its::ca
{

/// Rejects a raw --configKeyValues string carrying an ITSCATrackerParam.*
/// override before applying the accepted string to ConfigurableParam.
void applyConfigKeyValuesOrFatal(const std::string& configKeyValues);

/// Fatals unless mode is Sync or Async, naming the rejected mode explicitly,
/// before device construction.
void requireSupportedTrackingModeOrFatal(o2::itsmft::TrackingMode::Type mode);

enum class VertexSource { Diamond,
Truth };
struct WorkflowOptions {
bool useMC = true;
bool useFullGeometry = false;
bool writeRootOutput = true;
o2::itsmft::TrackingMode::Type mode = o2::itsmft::TrackingMode::Sync;
int nThreads = 1;
VertexSource vertexSource = VertexSource::Diamond;
std::string truthContext = "collisioncontext.root";
};

// An empty explicit source requires exactly one legacy alias. No physics
// constraint is enabled by default, and MC output labels are independent.
VertexSource resolveVertexSource(const std::string& explicitSource, bool useDiamond, bool useTruth);
WorkflowOptions readWorkflowOptions(const o2::framework::ConfigContext&);

} // namespace o2::its::ca

#endif // ALICEO2_ITS_CA_WORKFLOW_CONFIGPREFLIGHT_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#ifndef ALICEO2_ITS_CA_PUBLICATIONADAPTER_H_
#define ALICEO2_ITS_CA_PUBLICATIONADAPTER_H_

#ifndef GPUCA_GPUCODE

#include <algorithm>
#include <cstdint>
#include <cmath>
#include <limits>
#include <optional>
#include <vector>
#include <gsl/span>

#include "DetectorsCommonDataFormats/DetID.h"
#include "GPUCommonMath.h"
#include "ITSMFTTracking/GenericTrack.h"
#include "ITSMFTTracking/TimeFrame.h"
#include "ITSMFTTracking/MathUtils.h"

namespace o2::its::ca
{

// Workflow-owned shared-cluster flags indexed by the global GenericTrack index.
class PublicationAdapter
{
public:
gsl::span<const uint8_t> sharedClusterFlags() const noexcept
{
return mComplete ? gsl::span<const uint8_t>{mSharedClusterFlags} : gsl::span<const uint8_t>{};
}

bool completeAccepted(gsl::span<const uint32_t> trackIndices,
const o2::itsmft::IterationParameters& params,
const o2::itsmft::tracking::TimeFrame& frame,
bool final)
{
mComplete = false;
if (!stageSharedClusterFlags(trackIndices, params, frame)) {
return false;
}
mComplete = final;
return true;
}

void reset() noexcept
{
mSharedClusterFlags.clear();
mComplete = false;
}

class Cleanup
{
public:
explicit Cleanup(PublicationAdapter& adapter) : mAdapter(adapter) { mAdapter.reset(); }
Cleanup(const Cleanup&) = delete;
Cleanup& operator=(const Cleanup&) = delete;
~Cleanup() noexcept { mAdapter.reset(); }

private:
PublicationAdapter& mAdapter;
};
Cleanup cleanupOnExit() { return Cleanup{*this}; }

private:
struct SharedClusterTrackInfo {
int layer{-1};
uint32_t clusterId{std::numeric_limits<uint32_t>::max()};
int rof{-1};
float phi{0.f};
float eta{0.f};
int charge{0};
};

static std::optional<SharedClusterTrackInfo> makeSharedClusterTrackInfo(const o2::itsmft::tracking::GenericTrack& track,
const o2::itsmft::tracking::TimeFrame& frame)
{
const int layer = track.hitLayers.first();
const auto& references = frame.getTrackClusterIndices();
if (layer < 0 || !isValidTrackRange(track, static_cast<uint32_t>(references.size())) ||
track.firstClusterRef == track.clusterRefEnd ||
static_cast<std::size_t>(layer) >= frame.getDetectorConfiguration().size()) {
return std::nullopt;
}
const auto& reference = references[track.firstClusterRef];
if (reference.layer != o2::itsmft::tracking::LayerId{static_cast<uint16_t>(layer)} || !reference.isValid()) {
return std::nullopt;
}
const auto& state = track.innerState;
if (!state.hasRecognizedKind() || !o2::gpu::GPUCommonMath::Finite(state.parameters[3]) ||
!o2::gpu::GPUCommonMath::Finite(state.parameters[4])) {
return std::nullopt;
}
const float phi = state.kind == o2::itsmft::tracking::SurfaceKind::Cylinder ? std::asin(state.parameters[2]) + state.alpha : state.parameters[2];
const float eta = std::asinh(state.parameters[3]);
if (!o2::gpu::GPUCommonMath::Finite(phi) || !o2::gpu::GPUCommonMath::Finite(eta)) {
return std::nullopt;
}
return SharedClusterTrackInfo{layer, reference.clusterId, frame.getClusterROF(layer, static_cast<int>(reference.clusterId)),
phi, eta, state.parameters[4] < 0.f ? -1 : 1};
}

bool stageSharedClusterFlags(gsl::span<const uint32_t> trackIndices,
const o2::itsmft::IterationParameters& params,
const o2::itsmft::tracking::TimeFrame& frame)
{
auto nextIndex = mSharedClusterFlags.size();
for (const auto index : trackIndices) {
if (index >= frame.getGenericTracks().size() || index < nextIndex) {
return false;
}
nextIndex = static_cast<std::size_t>(index) + 1;
}
// Gaps belong to tracks not accepted by this adapter, and must not be
// mistaken for accepted tracks without shared clusters at publication.
mSharedClusterFlags.resize(nextIndex, std::numeric_limits<uint8_t>::max());
for (const auto index : trackIndices) {
mSharedClusterFlags[index] = 0;
}
if (!params.AllowSharingFirstCluster) {
return true;
}
std::vector<SharedClusterTrackInfo> trackInfo;
trackInfo.reserve(trackIndices.size());
for (const auto index : trackIndices) {
const auto info = makeSharedClusterTrackInfo(frame.getGenericTracks()[index], frame);
if (!info) {
return false;
}
trackInfo.push_back(*info);
}
for (size_t first = 0; first < trackInfo.size(); ++first) {
for (size_t second = first + 1; second < trackInfo.size(); ++second) {
if (trackInfo[second].layer != trackInfo[first].layer || trackInfo[second].clusterId != trackInfo[first].clusterId) {
continue;
}
if (trackInfo[first].rof != trackInfo[second].rof) {
continue;
}
if (!o2::its::math_utils::isPhiDifferenceBelow(trackInfo[first].phi, trackInfo[second].phi, params.SharedClusterMaxDeltaPhi)) {
continue;
}
if (std::abs(trackInfo[first].eta - trackInfo[second].eta) > params.SharedClusterMaxDeltaEta) {
continue;
}
if (params.SharedClusterOppositeSign && trackInfo[first].charge == trackInfo[second].charge) {
continue;
}
mSharedClusterFlags[trackIndices[first]] = 1;
mSharedClusterFlags[trackIndices[second]] = 1;
}
}
return true;
}

std::vector<uint8_t> mSharedClusterFlags;
bool mComplete = false;
};

} // namespace o2::its::ca

#endif // !GPUCA_GPUCODE

#endif // ALICEO2_ITS_CA_PUBLICATIONADAPTER_H_
Loading
Loading