Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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,92 @@
// 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 "DataFormatsITS/TrackITS.h"
#include "DataFormatsITSMFT/ROFRecord.h"
#include "DetectorsBase/GRPGeomHelper.h"
#include "Framework/DataProcessorSpec.h"
#include "Framework/Task.h"
#include "ITSMFTTracking/GenericTrackOutputAdapter.h"
#include "ITSMFTTracking/Configuration.h"
#include "ITSCAWorkflow/ConfigPreflight.h"
#include "ITSMFTTracking/ClusterDecoding.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();
o2::itsmft::tracking::TrackingOutcome 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;
std::unique_ptr<o2::itsmft::tracking::ClusterDecoder> mClusterDecoder;
const o2::itsmft::TopologyDictionary* mDictionary = nullptr;
o2::itsmft::tracking::ITSSharedClusterCompatibility mCompatibility;
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,175 @@
// 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 "DetectorsCommonDataFormats/DetID.h"
#include "GPUCommonMath.h"
#include "ITSMFTTracking/detail/ITSSharedClusterCompatibility.h"
#include "ITSMFTTracking/GenericTrack.h"
#include "ITSMFTTracking/TimeFrame.h"
#include "ITSMFTTracking/MathUtils.h"

namespace o2::its::ca
{

// Workflow-owned ITS compatibility for generic tracking results.
class PublicationAdapter
{
public:
void adoptITSSharedClusterCompatibility(o2::itsmft::tracking::ITSSharedClusterCompatibility* sidecar) noexcept { mSidecar = sidecar; }
o2::itsmft::tracking::ITSSharedClusterCompatibility* getITSSharedClusterCompatibility() const noexcept { return mSidecar; }

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

void reset() noexcept
{
mSharedClusterFlags.clear();
mAcceptedTrackIndices.clear();
if (mSidecar != nullptr) {
mSidecar->clear();
}
}

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.getLayout().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)
{
mAcceptedTrackIndices.reserve(mAcceptedTrackIndices.size() + trackIndices.size());
for (const auto index : trackIndices) {
if (index >= frame.getGenericTracks().size() ||
(!mAcceptedTrackIndices.empty() && mAcceptedTrackIndices.back() >= index)) {
return false;
}
mAcceptedTrackIndices.push_back(index);
}
if (!trackIndices.empty() && mSharedClusterFlags.size() <= trackIndices.back()) {
mSharedClusterFlags.resize(static_cast<std::size_t>(trackIndices.back()) + 1, 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;
}

o2::itsmft::tracking::ITSSharedClusterCompatibility* mSidecar = nullptr;
std::vector<uint8_t> mSharedClusterFlags;
std::vector<uint32_t> mAcceptedTrackIndices;
};

} // namespace o2::its::ca

#endif // !GPUCA_GPUCODE

#endif // ALICEO2_ITS_CA_PUBLICATIONADAPTER_H_
Loading