Skip to content

Commit

Permalink
refactor: TrackSelector operates on TrackContainer (#1874)
Browse files Browse the repository at this point in the history
Also adds a separate `TrackParameterSelector` which retains the functionality to select from track parameters. `TrackSelector` only operates on `TrackContainer`. There's no mechanism to select `Trajectory` objects anymore.

Blocked by:
- #1872 
- #1870
  • Loading branch information
paulgessinger committed Feb 20, 2023
1 parent bd9839a commit 24b4c7a
Show file tree
Hide file tree
Showing 15 changed files with 303 additions and 124 deletions.
2 changes: 0 additions & 2 deletions CI/physmon/physmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ def run_ckf_tracking(truthSmearedSeeded, truthEstimatedSeeded, label):
field,
CKFPerformanceConfig(ptMin=400.0 * u.MeV, nMeasurementsMin=6),
TrackSelectorRanges(
removeNeutral=True,
loc0=(-4.0 * u.mm, 4.0 * u.mm),
pt=(500 * u.MeV, None),
),
Expand Down Expand Up @@ -316,7 +315,6 @@ def run_vertexing(fitter, mu, events):
pt=(500 * u.MeV, None),
loc0=(-4.0 * u.mm, 4.0 * u.mm),
absEta=(None, 3.0),
removeNeutral=True,
),
)

Expand Down
11 changes: 11 additions & 0 deletions Core/include/Acts/EventData/Track.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,10 +624,21 @@ class TrackContainer {
return *m_traj;
}

/// Retrieve the holder of the track state container
/// @return The track state container including it's holder
template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
auto& trackStateContainerHolder() {
return m_traj;
}

/// Get a const reference to the track state container backend
/// @return a const reference to the backend
const auto& trackStateContainer() const { return *m_traj; }

/// Retrieve the holder of the track state container
/// @return The track state container including it's holder
const auto& trackStateContainerHolder() const { return m_traj; }

/// Get a mutable iterator to the first track in the container
/// @return a mutable iterator to the first track
template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
Expand Down
1 change: 0 additions & 1 deletion Core/src/EventData/VectorTrackContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ VectorTrackContainerBase::VectorTrackContainerBase(
for (const auto& [key, value] : other.m_dynamic) {
m_dynamic.insert({key, value->clone()});
}

assert(checkConsistency());
}
} // namespace detail_vtc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "ActsExamples/TruthTracking/TrackParameterSelector.hpp"

#include "Acts/Utilities/ThrowAssert.hpp"
#include "ActsExamples/EventData/Track.hpp"
#include "ActsExamples/EventData/Trajectories.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"

#include <cmath>
#include <cstdint>
#include <stdexcept>
#include <vector>

ActsExamples::TrackParameterSelector::TrackParameterSelector(
const Config& config, Acts::Logging::Level level)
: BareAlgorithm("TrackParameterSelector", level), m_cfg(config) {
if (m_cfg.inputTrackParameters.empty()) {
throw std::invalid_argument("Missing input track parameters");
}
if (m_cfg.outputTrackParameters.empty()) {
throw std::invalid_argument("Missing output track parameters");
}
}

ActsExamples::ProcessCode ActsExamples::TrackParameterSelector::execute(
const ActsExamples::AlgorithmContext& ctx) const {
// helper functions to select tracks
auto within = [](double x, double min, double max) {
return (min <= x) and (x < max);
};
auto isValidTrack = [&](const auto& trk) {
const auto theta = trk.template get<Acts::eBoundTheta>();
const auto eta = -std::log(std::tan(theta / 2));
// define charge selection
return within(trk.transverseMomentum(), m_cfg.ptMin, m_cfg.ptMax) and
within(std::abs(eta), m_cfg.absEtaMin, m_cfg.absEtaMax) and
within(eta, m_cfg.etaMin, m_cfg.etaMax) and
within(trk.template get<Acts::eBoundPhi>(), m_cfg.phiMin,
m_cfg.phiMax) and
within(trk.template get<Acts::eBoundLoc0>(), m_cfg.loc0Min,
m_cfg.loc0Max) and
within(trk.template get<Acts::eBoundLoc1>(), m_cfg.loc1Min,
m_cfg.loc1Max) and
within(trk.template get<Acts::eBoundTime>(), m_cfg.timeMin,
m_cfg.timeMax);
};

const auto& inputTrackParameters =
ctx.eventStore.get<TrackParametersContainer>(m_cfg.inputTrackParameters);
TrackParametersContainer outputTrackParameters;
outputTrackParameters.reserve(inputTrackParameters.size());

// copy selected tracks and record initial track index
for (uint32_t i = 0; i < inputTrackParameters.size(); ++i) {
const auto& trk = inputTrackParameters[i];
if (isValidTrack(trk)) {
outputTrackParameters.push_back(trk);
}
}
outputTrackParameters.shrink_to_fit();

ACTS_DEBUG("event " << ctx.eventNumber << " selected "
<< outputTrackParameters.size() << " from "
<< inputTrackParameters.size()
<< " tracks in track parameters");

ctx.eventStore.add(m_cfg.outputTrackParameters,
std::move(outputTrackParameters));

return ProcessCode::SUCCESS;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "ActsExamples/Framework/BareAlgorithm.hpp"

#include <limits>
#include <string>

namespace ActsExamples {

/// Select tracks by applying some selection cuts.
class TrackParameterSelector final : public BareAlgorithm {
public:
struct Config {
/// Input track parameters collection
std::string inputTrackParameters;
/// Output track parameters collection.
std::string outputTrackParameters;

// Minimum/maximum local positions.
double loc0Min = -std::numeric_limits<double>::infinity();
double loc0Max = std::numeric_limits<double>::infinity();
double loc1Min = -std::numeric_limits<double>::infinity();
double loc1Max = std::numeric_limits<double>::infinity();
// Minimum/maximum track time.
double timeMin = -std::numeric_limits<double>::infinity();
double timeMax = std::numeric_limits<double>::infinity();
// Direction cuts.
double phiMin = -std::numeric_limits<double>::infinity();
double phiMax = std::numeric_limits<double>::infinity();
double etaMin = -std::numeric_limits<double>::infinity();
double etaMax = std::numeric_limits<double>::infinity();
double absEtaMin = 0.0;
double absEtaMax = std::numeric_limits<double>::infinity();
// Momentum cuts.
double ptMin = 0.0;
double ptMax = std::numeric_limits<double>::infinity();
};

TrackParameterSelector(const Config& config, Acts::Logging::Level level);

ProcessCode execute(const AlgorithmContext& ctx) const final;

/// Get readonly access to the config parameters
const Config& config() const { return m_cfg; }

private:
Config m_cfg;
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// This file is part of the Acts project.
//
// Copyright (C) 2019-2020 CERN for the benefit of the Acts project
// Copyright (C) 2019-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "ActsExamples/TruthTracking/TrackSelector.hpp"

#include "Acts/EventData/VectorMultiTrajectory.hpp"
#include "Acts/EventData/VectorTrackContainer.hpp"
#include "Acts/Utilities/ThrowAssert.hpp"
#include "ActsExamples/EventData/Track.hpp"
#include "ActsExamples/EventData/Trajectories.hpp"
Expand All @@ -21,9 +23,12 @@
ActsExamples::TrackSelector::TrackSelector(const Config& config,
Acts::Logging::Level level)
: BareAlgorithm("TrackSelector", level), m_cfg(config) {
if (m_cfg.inputTrackParameters.empty() == m_cfg.inputTrajectories.empty()) {
throw std::invalid_argument(
"Exactly one of track parameters or trajectories input must be set");
if (m_cfg.inputTracks.empty()) {
throw std::invalid_argument("Input track collection is empty");
}

if (m_cfg.outputTracks.empty()) {
throw std::invalid_argument("Output track collection is empty");
}
}

Expand All @@ -34,85 +39,67 @@ ActsExamples::ProcessCode ActsExamples::TrackSelector::execute(
return (min <= x) and (x < max);
};
auto isValidTrack = [&](const auto& trk) {
const auto theta = trk.template get<Acts::eBoundTheta>();
const auto theta = trk.theta();
const auto eta = -std::log(std::tan(theta / 2));
// define charge selection
const bool validNeutral = (trk.charge() == 0) and not m_cfg.removeNeutral;
const bool validCharged = (trk.charge() != 0) and not m_cfg.removeCharged;
const bool validCharge = validNeutral or validCharged;
return validCharge and
within(trk.transverseMomentum(), m_cfg.ptMin, m_cfg.ptMax) and
return within(trk.transverseMomentum(), m_cfg.ptMin, m_cfg.ptMax) and
within(std::abs(eta), m_cfg.absEtaMin, m_cfg.absEtaMax) and
within(eta, m_cfg.etaMin, m_cfg.etaMax) and
within(trk.template get<Acts::eBoundPhi>(), m_cfg.phiMin,
m_cfg.phiMax) and
within(trk.template get<Acts::eBoundLoc0>(), m_cfg.loc0Min,
m_cfg.loc0Max) and
within(trk.template get<Acts::eBoundLoc1>(), m_cfg.loc1Min,
m_cfg.loc1Max) and
within(trk.template get<Acts::eBoundTime>(), m_cfg.timeMin,
m_cfg.timeMax);
within(trk.phi(), m_cfg.phiMin, m_cfg.phiMax) and
within(trk.loc0(), m_cfg.loc0Min, m_cfg.loc0Max) and
within(trk.loc1(), m_cfg.loc1Min, m_cfg.loc1Max) and
within(trk.time(), m_cfg.timeMin, m_cfg.timeMax);
};

if (!m_cfg.inputTrackParameters.empty()) {
const auto& inputTrackParameters =
ctx.eventStore.get<TrackParametersContainer>(
m_cfg.inputTrackParameters);
TrackParametersContainer outputTrackParameters;
outputTrackParameters.reserve(inputTrackParameters.size());

// copy selected tracks and record initial track index
for (uint32_t i = 0; i < inputTrackParameters.size(); ++i) {
const auto& trk = inputTrackParameters[i];
if (isValidTrack(trk)) {
outputTrackParameters.push_back(trk);
}
}
outputTrackParameters.shrink_to_fit();
ACTS_VERBOSE("Reading tracks from: " << m_cfg.inputTracks);

ACTS_DEBUG("event " << ctx.eventNumber << " selected "
<< outputTrackParameters.size() << " from "
<< inputTrackParameters.size()
<< " tracks in track parameters");
const auto& inputTracks =
ctx.eventStore.get<ConstTrackContainer>(m_cfg.inputTracks);

ctx.eventStore.add(m_cfg.outputTrackParameters,
std::move(outputTrackParameters));
}
std::shared_ptr<Acts::ConstVectorMultiTrajectory> trackStateContainer =
inputTracks.trackStateContainerHolder();

if (!m_cfg.inputTrajectories.empty()) {
const auto& inputTrajectories =
ctx.eventStore.get<TrajectoriesContainer>(m_cfg.inputTrajectories);
TrajectoriesContainer outputTrajectories;
outputTrajectories.reserve(inputTrajectories.size());

std::size_t inputCount = 0;
std::size_t outputCount = 0;
for (const auto& trajectories : inputTrajectories) {
std::vector<Acts::MultiTrajectoryTraits::IndexType> tips;
Trajectories::IndexedParameters parameters;

for (auto tip : trajectories.tips()) {
if (!trajectories.hasTrackParameters(tip)) {
continue;
}
++inputCount;
if (!isValidTrack(trajectories.trackParameters(tip))) {
continue;
}
tips.push_back(tip);
parameters.emplace(tip, trajectories.trackParameters(tip));
++outputCount;
}

outputTrajectories.emplace_back(trajectories.multiTrajectory(), tips,
parameters);
}
auto trackContainer = std::make_shared<Acts::VectorTrackContainer>(
inputTracks.container()); // mutable copy of the immutable
// source track container
auto tempTrackStateContainer =
std::make_shared<Acts::VectorMultiTrajectory>();

TrackContainer filteredTracks{trackContainer, tempTrackStateContainer};

ACTS_VERBOSE(
"Track container size before filtering: " << filteredTracks.size());

ACTS_DEBUG("event " << ctx.eventNumber << " selected " << outputCount
<< " from " << inputCount << " tracks in trajectories");
size_t nRemoved = 0;

ctx.eventStore.add(m_cfg.outputTrajectories, std::move(outputTrajectories));
for (Acts::MultiTrajectoryTraits::IndexType itrack = 0;
itrack < filteredTracks.size();) {
auto track = filteredTracks.getTrack(itrack);
if (isValidTrack(track)) {
// Track is valid, go to next index
ACTS_VERBOSE(" - Keeping track #" << itrack);
itrack++;
continue;
}
ACTS_VERBOSE(" - Removing track #" << itrack);
filteredTracks.removeTrack(itrack);
nRemoved++;
// Do not increment track index
}

if (nRemoved != inputTracks.size() - filteredTracks.size()) {
ACTS_ERROR("Inconsistent track container size after removing "
<< nRemoved << " tracks");
}

ACTS_VERBOSE(
"Track container size after filtering: " << filteredTracks.size());

ConstTrackContainer outputTracks{
std::make_shared<Acts::ConstVectorTrackContainer>(
std::move(*trackContainer)),
trackStateContainer};

ctx.eventStore.add(m_cfg.outputTracks, std::move(outputTracks));

return ProcessCode::SUCCESS;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of the Acts project.
//
// Copyright (C) 2019 CERN for the benefit of the Acts project
// Copyright (C) 2019-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -19,18 +19,10 @@ namespace ActsExamples {
class TrackSelector final : public BareAlgorithm {
public:
struct Config {
/// Optional. Input track parameters collection. Mutually exclusive with
/// trajectories input.
std::string inputTrackParameters;
/// Optional. Input trajectories container. Mutually exclusive with track
/// parameters input.
std::string inputTrajectories;
/// Optional. Output track parameters collection. Will only be set if track
/// parameters input was set.
std::string outputTrackParameters;
/// Optional. Output trajectories container. Will only be set if
/// trajectories input was set
std::string outputTrajectories;
/// Input track collection.
std::string inputTracks;
/// Output track collection
std::string outputTracks;

// Minimum/maximum local positions.
double loc0Min = -std::numeric_limits<double>::infinity();
Expand All @@ -50,10 +42,6 @@ class TrackSelector final : public BareAlgorithm {
// Momentum cuts.
double ptMin = 0.0;
double ptMax = std::numeric_limits<double>::infinity();
/// Remove charged particles.
bool removeCharged = false;
/// Remove neutral particles.
bool removeNeutral = false;
};

TrackSelector(const Config& config, Acts::Logging::Level level);
Expand Down

0 comments on commit 24b4c7a

Please sign in to comment.