Skip to content

Commit 1d1d486

Browse files
committed
ITSMFT: unify cellular automaton tracking for ITS and MFT
Introduce shared tracking, propagation, material handling and runtime ROF tables with compatibility wrappers for legacy ITS callers. Add ITS and MFT CA workflows with checked configuration, reusable workflow sessions and workflow-owned publication. Include tracking and workflow tests.
1 parent aec41d2 commit 1d1d486

127 files changed

Lines changed: 30447 additions & 544 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Detectors/ITSMFT/ITS/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_subdirectory(simulation)
1515
add_subdirectory(reconstruction)
1616
add_subdirectory(tracking)
1717
add_subdirectory(workflow)
18+
add_subdirectory(workflow-ca)
1819
add_subdirectory(postprocessing)
1920
add_subdirectory(macros)
2021
add_subdirectory(QC)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
12+
o2_add_library(ITSCAWorkflow
13+
TARGETVARNAME targetName
14+
SOURCES src/ConfigPreflight.cxx
15+
src/CATrackerSpec.cxx
16+
PUBLIC_LINK_LIBRARIES O2::Framework
17+
O2::SimulationDataFormat
18+
O2::DataFormatsITS
19+
O2::DataFormatsITSMFT
20+
O2::ITSBase
21+
O2::ITSMFTTracking
22+
O2::ITSMFTCAWriter
23+
O2::MFTTracking
24+
O2::Steer
25+
O2::CCDB)
26+
27+
o2_add_executable(ca-tracker-workflow
28+
SOURCES src/its-ca-tracker-workflow.cxx
29+
COMPONENT_NAME its
30+
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)
31+
32+
o2_add_test(its-ca-config-preflight
33+
COMPONENT_NAME its
34+
LABELS "its;workflow;itsmft"
35+
SOURCES test/testITSCAConfigPreflight.cxx
36+
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)
37+
38+
o2_add_test(its-ca-tracker-dpl-contract
39+
COMPONENT_NAME its
40+
LABELS "its;workflow;itsmft"
41+
SOURCES test/testITSCATrackerDPLContract.cxx
42+
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)
43+
44+
o2_add_test(its-ca-truth-seeding
45+
COMPONENT_NAME its
46+
LABELS "its;workflow;itsmft"
47+
SOURCES test/testITSCATruthSeeding.cxx
48+
PUBLIC_LINK_LIBRARIES O2::ITSCAWorkflow)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
///
12+
/// \file CATrackerSpec.h
13+
/// \brief ITS common-CA tracker DPL device with tracker-only outputs.
14+
15+
#ifndef O2_ITS_CA_WORKFLOW_CATRACKERSPEC_H_
16+
#define O2_ITS_CA_WORKFLOW_CATRACKERSPEC_H_
17+
18+
#include <cstdint>
19+
#include <memory>
20+
#include <optional>
21+
#include <vector>
22+
23+
#include <gsl/span>
24+
25+
#include "DataFormatsITS/TrackITS.h"
26+
#include "DataFormatsITSMFT/ROFRecord.h"
27+
#include "DetectorsBase/GRPGeomHelper.h"
28+
#include "Framework/DataProcessorSpec.h"
29+
#include "Framework/Task.h"
30+
#include "ITSMFTTracking/GenericTrackOutputAdapter.h"
31+
#include "ITSMFTTracking/Configuration.h"
32+
#include "ITSCAWorkflow/ConfigPreflight.h"
33+
#include "ITSMFTTracking/ClusterDecoding.h"
34+
#include "ITSCAWorkflow/PublicationAdapter.h"
35+
#include "ITSMFTTracking/Tracker.h"
36+
#include "ITSMFTTracking/TrackerTraits.h"
37+
#include "ITSMFTTracking/WorkflowSession.h"
38+
#include "ITSMFTTracking/IOUtils.h"
39+
#include "ITSMFTTracking/ITSMFTDetectorDefinitions.h"
40+
#include "ITSMFTTracking/ROFViews.h"
41+
#include "ITSMFTTracking/ROFLookupTables.h"
42+
#include "DataFormatsITSMFT/TopologyDictionary.h"
43+
#include "SimulationDataFormat/MCCompLabel.h"
44+
45+
namespace o2::its::ca
46+
{
47+
48+
using o2::itsmft::tracking::CATrackerPublicationAction;
49+
using o2::itsmft::tracking::decideCATrackerPublicationAction;
50+
51+
/// ITS common-CA tracker DPL task. Owns the TimeFrame and composes the
52+
/// workflow input/timing/publication edge with Tracker.
53+
class CATrackerDPL : public o2::framework::Task
54+
{
55+
public:
56+
CATrackerDPL(std::shared_ptr<o2::base::GRPGeomRequest> gr, WorkflowOptions options);
57+
~CATrackerDPL() override = default;
58+
59+
void init(framework::InitContext& ic) final;
60+
void run(framework::ProcessingContext& pc) final;
61+
void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final;
62+
63+
private:
64+
void updateTimeDependentParams(framework::ProcessingContext& pc);
65+
void addTruthSeedingVertices(const o2::InteractionRecord& origin, gsl::span<const o2::itsmft::ROFRecord> rofs);
66+
void configureROFViews(gsl::span<const o2::itsmft::ROFRecord> rofs);
67+
void initialiseTracking();
68+
o2::itsmft::tracking::TrackingOutcome processTimeFrame(
69+
gsl::span<const o2::itsmft::ROFRecord> rofs,
70+
gsl::span<const o2::itsmft::CompClusterExt> clusters,
71+
gsl::span<const unsigned char> patterns,
72+
const o2::dataformats::MCTruthContainer<MCCompLabel>* labels);
73+
bool isActive() const noexcept { return mTracker != nullptr && mTracker->isConfiguredFor(mSession.frame); }
74+
75+
std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
76+
bool mUseMC = false;
77+
bool mTrackingInitialised = false;
78+
WorkflowOptions mOptions;
79+
o2::itsmft::tracking::WorkflowSession mSession{"ITS", o2::itsmft::tracking::ITSNLayers};
80+
std::unique_ptr<o2::itsmft::tracking::TrackerTraits> mTrackerTraits;
81+
std::unique_ptr<o2::itsmft::tracking::Tracker> mTracker;
82+
std::unique_ptr<o2::itsmft::tracking::ClusterDecoder> mClusterDecoder;
83+
const o2::itsmft::TopologyDictionary* mDictionary = nullptr;
84+
o2::itsmft::tracking::ITSSharedClusterCompatibility mCompatibility;
85+
PublicationAdapter mPublication;
86+
};
87+
88+
o2::framework::DataProcessorSpec getCATrackerSpec(const WorkflowOptions& options);
89+
90+
} // namespace o2::its::ca
91+
92+
#endif // O2_ITS_CA_WORKFLOW_CATRACKERSPEC_H_
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
///
12+
/// \file ConfigPreflight.h
13+
/// \brief Driver-level configuration and vertex-constraint preflight for the
14+
/// ITS common-CA tracker workflow.
15+
///
16+
/// Resolve driver options before constructing any DPL device.
17+
18+
#ifndef ALICEO2_ITS_CA_WORKFLOW_CONFIGPREFLIGHT_H_
19+
#define ALICEO2_ITS_CA_WORKFLOW_CONFIGPREFLIGHT_H_
20+
21+
#include <string>
22+
23+
#include "ITSMFTTracking/Configuration.h"
24+
25+
namespace o2::framework
26+
{
27+
class ConfigContext;
28+
}
29+
30+
namespace o2::its::ca
31+
{
32+
33+
/// Rejects a raw --configKeyValues string carrying an ITSCATrackerParam.*
34+
/// override before applying the accepted string to ConfigurableParam.
35+
void applyConfigKeyValuesOrFatal(const std::string& configKeyValues);
36+
37+
/// Fatals unless mode is Sync or Async, naming the rejected mode explicitly,
38+
/// before device construction.
39+
void requireSupportedTrackingModeOrFatal(o2::itsmft::TrackingMode::Type mode);
40+
41+
enum class VertexSource { Diamond,
42+
Truth };
43+
struct WorkflowOptions {
44+
bool useMC = true;
45+
bool useFullGeometry = false;
46+
bool writeRootOutput = true;
47+
o2::itsmft::TrackingMode::Type mode = o2::itsmft::TrackingMode::Sync;
48+
int nThreads = 1;
49+
VertexSource vertexSource = VertexSource::Diamond;
50+
std::string truthContext = "collisioncontext.root";
51+
};
52+
53+
// An empty explicit source requires exactly one legacy alias. No physics
54+
// constraint is enabled by default, and MC output labels are independent.
55+
VertexSource resolveVertexSource(const std::string& explicitSource, bool useDiamond, bool useTruth);
56+
WorkflowOptions readWorkflowOptions(const o2::framework::ConfigContext&);
57+
58+
} // namespace o2::its::ca
59+
60+
#endif // ALICEO2_ITS_CA_WORKFLOW_CONFIGPREFLIGHT_H_
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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+
12+
#ifndef ALICEO2_ITS_CA_PUBLICATIONADAPTER_H_
13+
#define ALICEO2_ITS_CA_PUBLICATIONADAPTER_H_
14+
15+
#ifndef GPUCA_GPUCODE
16+
17+
#include <algorithm>
18+
#include <cstdint>
19+
#include <cmath>
20+
#include <limits>
21+
#include <optional>
22+
#include <vector>
23+
24+
#include "DetectorsCommonDataFormats/DetID.h"
25+
#include "GPUCommonMath.h"
26+
#include "ITSMFTTracking/detail/ITSSharedClusterCompatibility.h"
27+
#include "ITSMFTTracking/GenericTrack.h"
28+
#include "ITSMFTTracking/TimeFrame.h"
29+
#include "ITSMFTTracking/MathUtils.h"
30+
31+
namespace o2::its::ca
32+
{
33+
34+
// Workflow-owned ITS compatibility for generic tracking results.
35+
class PublicationAdapter
36+
{
37+
public:
38+
void adoptITSSharedClusterCompatibility(o2::itsmft::tracking::ITSSharedClusterCompatibility* sidecar) noexcept { mSidecar = sidecar; }
39+
o2::itsmft::tracking::ITSSharedClusterCompatibility* getITSSharedClusterCompatibility() const noexcept { return mSidecar; }
40+
41+
bool completeAccepted(gsl::span<const uint32_t> trackIndices,
42+
const o2::itsmft::IterationParameters& params,
43+
const o2::itsmft::tracking::TimeFrame& frame,
44+
bool final)
45+
{
46+
if (mSidecar == nullptr) {
47+
return true;
48+
}
49+
if (!stageSharedClusterFlags(trackIndices, params, frame)) {
50+
return false;
51+
}
52+
return !final || mSidecar->replaceFromAcceptedTrackIndices(mAcceptedTrackIndices, mSharedClusterFlags);
53+
}
54+
55+
void reset() noexcept
56+
{
57+
mSharedClusterFlags.clear();
58+
mAcceptedTrackIndices.clear();
59+
if (mSidecar != nullptr) {
60+
mSidecar->clear();
61+
}
62+
}
63+
64+
class Cleanup
65+
{
66+
public:
67+
explicit Cleanup(PublicationAdapter& adapter) : mAdapter(adapter) { mAdapter.reset(); }
68+
Cleanup(const Cleanup&) = delete;
69+
Cleanup& operator=(const Cleanup&) = delete;
70+
~Cleanup() noexcept { mAdapter.reset(); }
71+
72+
private:
73+
PublicationAdapter& mAdapter;
74+
};
75+
Cleanup cleanupOnExit() { return Cleanup{*this}; }
76+
77+
private:
78+
struct SharedClusterTrackInfo {
79+
int layer{-1};
80+
uint32_t clusterId{std::numeric_limits<uint32_t>::max()};
81+
int rof{-1};
82+
float phi{0.f};
83+
float eta{0.f};
84+
int charge{0};
85+
};
86+
87+
static std::optional<SharedClusterTrackInfo> makeSharedClusterTrackInfo(const o2::itsmft::tracking::GenericTrack& track,
88+
const o2::itsmft::tracking::TimeFrame& frame)
89+
{
90+
const int layer = track.hitLayers.first();
91+
const auto& references = frame.getTrackClusterIndices();
92+
if (layer < 0 || !isValidTrackRange(track, static_cast<uint32_t>(references.size())) ||
93+
track.firstClusterRef == track.clusterRefEnd ||
94+
static_cast<std::size_t>(layer) >= frame.getLayout().size()) {
95+
return std::nullopt;
96+
}
97+
const auto& reference = references[track.firstClusterRef];
98+
if (reference.layer != o2::itsmft::tracking::LayerId{static_cast<uint16_t>(layer)} || !reference.isValid()) {
99+
return std::nullopt;
100+
}
101+
const auto& state = track.innerState;
102+
if (!state.hasRecognizedKind() || !o2::gpu::GPUCommonMath::Finite(state.parameters[3]) ||
103+
!o2::gpu::GPUCommonMath::Finite(state.parameters[4])) {
104+
return std::nullopt;
105+
}
106+
const float phi = state.kind == o2::itsmft::tracking::SurfaceKind::Cylinder ? std::asin(state.parameters[2]) + state.alpha : state.parameters[2];
107+
const float eta = std::asinh(state.parameters[3]);
108+
if (!o2::gpu::GPUCommonMath::Finite(phi) || !o2::gpu::GPUCommonMath::Finite(eta)) {
109+
return std::nullopt;
110+
}
111+
return SharedClusterTrackInfo{layer, reference.clusterId, frame.getClusterROF(layer, static_cast<int>(reference.clusterId)),
112+
phi, eta, state.parameters[4] < 0.f ? -1 : 1};
113+
}
114+
115+
bool stageSharedClusterFlags(gsl::span<const uint32_t> trackIndices,
116+
const o2::itsmft::IterationParameters& params,
117+
const o2::itsmft::tracking::TimeFrame& frame)
118+
{
119+
mAcceptedTrackIndices.reserve(mAcceptedTrackIndices.size() + trackIndices.size());
120+
for (const auto index : trackIndices) {
121+
if (index >= frame.getGenericTracks().size() ||
122+
(!mAcceptedTrackIndices.empty() && mAcceptedTrackIndices.back() >= index)) {
123+
return false;
124+
}
125+
mAcceptedTrackIndices.push_back(index);
126+
}
127+
if (!trackIndices.empty() && mSharedClusterFlags.size() <= trackIndices.back()) {
128+
mSharedClusterFlags.resize(static_cast<std::size_t>(trackIndices.back()) + 1, 0);
129+
}
130+
if (!params.AllowSharingFirstCluster) {
131+
return true;
132+
}
133+
std::vector<SharedClusterTrackInfo> trackInfo;
134+
trackInfo.reserve(trackIndices.size());
135+
for (const auto index : trackIndices) {
136+
const auto info = makeSharedClusterTrackInfo(frame.getGenericTracks()[index], frame);
137+
if (!info) {
138+
return false;
139+
}
140+
trackInfo.push_back(*info);
141+
}
142+
for (size_t first = 0; first < trackInfo.size(); ++first) {
143+
for (size_t second = first + 1; second < trackInfo.size(); ++second) {
144+
if (trackInfo[second].layer != trackInfo[first].layer || trackInfo[second].clusterId != trackInfo[first].clusterId) {
145+
continue;
146+
}
147+
if (trackInfo[first].rof != trackInfo[second].rof) {
148+
continue;
149+
}
150+
if (!o2::its::math_utils::isPhiDifferenceBelow(trackInfo[first].phi, trackInfo[second].phi, params.SharedClusterMaxDeltaPhi)) {
151+
continue;
152+
}
153+
if (std::abs(trackInfo[first].eta - trackInfo[second].eta) > params.SharedClusterMaxDeltaEta) {
154+
continue;
155+
}
156+
if (params.SharedClusterOppositeSign && trackInfo[first].charge == trackInfo[second].charge) {
157+
continue;
158+
}
159+
mSharedClusterFlags[trackIndices[first]] = 1;
160+
mSharedClusterFlags[trackIndices[second]] = 1;
161+
}
162+
}
163+
return true;
164+
}
165+
166+
o2::itsmft::tracking::ITSSharedClusterCompatibility* mSidecar = nullptr;
167+
std::vector<uint8_t> mSharedClusterFlags;
168+
std::vector<uint32_t> mAcceptedTrackIndices;
169+
};
170+
171+
} // namespace o2::its::ca
172+
173+
#endif // !GPUCA_GPUCODE
174+
175+
#endif // ALICEO2_ITS_CA_PUBLICATIONADAPTER_H_

0 commit comments

Comments
 (0)