Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Track parameters lookup estimation examples #3823

Merged
merged 26 commits into from
Nov 21, 2024
Merged
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
49 changes: 49 additions & 0 deletions Core/include/Acts/EventData/detail/TrackParametersUtils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/EventData/GenericBoundTrackParameters.hpp"
#include "Acts/EventData/TrackParametersConcept.hpp"

namespace Acts::detail {

/// @brief Shorthand for Bound or Free track parameters
template <class parameters_t>
concept isBoundOrFreeTrackParams =
Acts::FreeTrackParametersConcept<parameters_t> ||
Acts::BoundTrackParametersConcept<parameters_t>;

/// @brief Shorthand for GenericBoundTrackParameters
template <class parameters_t>
concept isGenericBoundTrackParams =
std::same_as<parameters_t, Acts::GenericBoundTrackParameters<
typename parameters_t::ParticleHypothesis>>;

/// @brief Concept that restricts the type of the
/// accumulation grid cell
template <typename grid_t>
concept TrackParamsGrid = requires {
typename grid_t::value_type::first_type;
typename grid_t::value_type::second_type;

requires isBoundOrFreeTrackParams<
typename grid_t::value_type::first_type::element_type>;
requires isBoundOrFreeTrackParams<
typename grid_t::value_type::second_type::element_type>;

requires requires(typename grid_t::value_type val) {
{
val.first
} -> std::same_as<
std::shared_ptr<typename decltype(val.first)::element_type>&>;
{ val.second } -> std::same_as<decltype(val.first)&>;
};
};

} // namespace Acts::detail
179 changes: 179 additions & 0 deletions Core/include/Acts/TrackFinding/TrackParamsLookupAccumulator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/EventData/detail/TrackParametersUtils.hpp"
#include "Acts/Geometry/GeometryContext.hpp"

#include <map>
#include <memory>
#include <mutex>
#include <stdexcept>
#include <utility>

namespace Acts {

/// @brief Class to accumulate and average track lookup tables
///
/// @tparam Grid type for track parameters accumulation
///
/// This class is used to accumulate track parameters in
/// reference layer grids and average them to create a lookup
/// table for track parameter estimation in seeding
///
/// @note Geometry context is left to be handled by the user
/// outside of accumulation
template <detail::TrackParamsGrid grid_t>
class TrackParamsLookupAccumulator {
public:
using LookupGrid = grid_t;
using TrackParameters = typename std::pointer_traits<
typename grid_t::value_type::first_type>::element_type;

/// @brief Constructor
explicit TrackParamsLookupAccumulator(grid_t grid)
: m_grid(std::move(grid)) {}

/// @brief Add track parameters to the accumulator
///
/// @param ipTrackParameters Track parameters at the IP
/// @param refTrackParameters Track parameters at the reference layer
/// @param position Local position of the track hit on the reference layer
void addTrack(const TrackParameters& ipTrackParameters,
const TrackParameters& refTrackParameters,
const Vector2& position) {
std::lock_guard<std::mutex> lock(m_gridMutex);

auto bin = m_grid.localBinsFromPosition(position);

if (m_countGrid[bin] == 0) {
m_grid.atLocalBins(bin).first =
std::make_shared<TrackParameters>(ipTrackParameters);
m_grid.atLocalBins(bin).second =
std::make_shared<TrackParameters>(refTrackParameters);

m_countGrid.at(bin)++;
return;
}

*m_grid.atLocalBins(bin).first =
addTrackParameters(*m_grid.atLocalBins(bin).first, ipTrackParameters);
*m_grid.atLocalBins(bin).second =
addTrackParameters(*m_grid.atLocalBins(bin).second, refTrackParameters);
m_countGrid.at(bin)++;
}

/// @brief Finalize the lookup table
///
/// @return Grid with the bin track parameters averaged
LookupGrid finalizeLookup() {
auto meanTrack = [&](const TrackParameters& track, std::size_t count) {
if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
Acts::GeometryContext gctx;

auto res = TrackParameters::create(
track.referenceSurface().getSharedPtr(), gctx,
track.fourPosition(gctx) / count, track.momentum().normalized(),
count * track.charge() / track.momentum().norm(),
track.covariance(), track.particleHypothesis());

if (!res.ok()) {
throw std::invalid_argument("Bound track grid finalization failed");
}
return res.value();
} else {
return TrackParameters(track.fourPosition() / count,
track.momentum().normalized(),
count * track.charge() / track.momentum().norm(),
track.covariance(), track.particleHypothesis());
}
};

for (auto [bin, count] : m_countGrid) {
if (count == 0) {
continue;
}
*m_grid.atLocalBins(bin).first =
meanTrack(*m_grid.atLocalBins(bin).first, count);
*m_grid.atLocalBins(bin).second =
meanTrack(*m_grid.atLocalBins(bin).second, count);
}

return m_grid;
}

private:
/// @brief Add two track parameters
///
/// @param a First track parameter in the sum
/// @param b Second track parameter in the sum
///
/// @return Sum of track parameters a + b
///
/// @note Covariances of the track parameters
/// are not added and instead assumed to be
/// generated by the same random process for
/// both a and b, making its averaging redundant
TrackParameters addTrackParameters(const TrackParameters& a,
const TrackParameters& b) {
if (a.particleHypothesis() != b.particleHypothesis()) {
throw std::invalid_argument(
"Cannot accumulate track parameters with different particle "
"hypotheses");
}
if (a.charge() != b.charge()) {
throw std::invalid_argument(
"Cannot accumulate track parameters with different charges");
}
if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
if (a.referenceSurface() != b.referenceSurface()) {
throw std::invalid_argument(
"Cannot accumulate bound track parameters with different reference "
"surfaces");
}
}

Acts::Vector3 momentum = a.momentum() + b.momentum();

// Assume track parameters being i.i.d.
if constexpr (detail::isGenericBoundTrackParams<TrackParameters>) {
Acts::GeometryContext gctx;

Acts::Vector4 fourPosition = a.fourPosition(gctx) + b.fourPosition(gctx);

auto res = TrackParameters::create(
a.referenceSurface().getSharedPtr(), gctx, fourPosition,
momentum.normalized(), a.charge() / momentum.norm(), a.covariance(),
a.particleHypothesis());

if (!res.ok()) {
throw std::runtime_error("Invalid bound track parameters");
}
return res.value();
} else {
Acts::Vector4 fourPosition = a.fourPosition() + b.fourPosition();
return TrackParameters(fourPosition, momentum.normalized(),
a.charge() / momentum.norm(), a.covariance(),
a.particleHypothesis());
}
}

/// Grids to accumulate IP and reference
/// layer track parameters
LookupGrid m_grid;

/// Mutex for protecting grid access
std::mutex m_gridMutex;

/// Map to keep the accumulation count
/// in the occupied grid bins
std::map<std::array<std::size_t, LookupGrid::DIM>, std::size_t> m_countGrid;
};

} // namespace Acts
1 change: 1 addition & 0 deletions Examples/Algorithms/TrackFinding/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_library(
src/TrackParamsEstimationAlgorithm.cpp
src/MuonHoughSeeder.cpp
src/GbtsSeedingAlgorithm.cpp
src/TrackParamsLookupEstimation.cpp
)

target_include_directories(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.

#pragma once

#include "ActsExamples/TrackFinding/TrackParamsLookupTable.hpp"

namespace ActsExamples {

/// @brief Interface for reading track parameter lookup tables
class ITrackParamsLookupReader {
public:
/// Virtual Destructor
virtual ~ITrackParamsLookupReader() = default;

/// Reader method
///
/// @param path the path to the file to read
virtual TrackParamsLookup readLookup(const std::string& path) const = 0;
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.

#pragma once

#include "ActsExamples/TrackFinding/TrackParamsLookupTable.hpp"

namespace ActsExamples {

/// @brief Interface for writing track parameter lookup tables
class ITrackParamsLookupWriter {
public:
/// Virtual Destructor
virtual ~ITrackParamsLookupWriter() = default;

/// Writer method
///
/// @param lookup track lookup to write
virtual void writeLookup(const TrackParamsLookup& lookup) const = 0;
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/TrackFinding/TrackParamsLookupAccumulator.hpp"
#include "ActsExamples/EventData/SimHit.hpp"
#include "ActsExamples/EventData/SimParticle.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Framework/IAlgorithm.hpp"
#include "ActsExamples/TrackFinding/ITrackParamsLookupWriter.hpp"

#include <memory>

namespace ActsExamples {

/// @brief Algorithm to estimate track parameters lookup tables
///
/// This algorithm is used to estimate track parameters lookup tables
/// for track parameter estimation in seeding. The algorithm imposes
/// grids onto the reference tracking layers and accumulates track
/// parameters in the grid bins. The track parameters are then averaged
/// to create a lookup table for track parameter estimation in seeding.
class TrackParamsLookupEstimation : public IAlgorithm {
public:
using TrackParamsLookupAccumulator =
Acts::TrackParamsLookupAccumulator<TrackParamsLookupGrid>;

/// @brief Nested configuration struct
struct Config {
/// Reference tracking layers
std::unordered_map<Acts::GeometryIdentifier, const Acts::Surface*>
refLayers;
/// Binning of the grid to be emposed
/// onto the reference layers
std::pair<std::size_t, std::size_t> bins;
/// Input SimHit container
std::string inputHits = "InputHits";
/// Input SimParticle container
std::string inputParticles = "InputParticles";
/// Track lookup writers
std::vector<std::shared_ptr<ITrackParamsLookupWriter>>
trackLookupGridWriters{};
};

/// @brief Constructor
TrackParamsLookupEstimation(const Config& config, Acts::Logging::Level level);

/// @brief The execute method
ProcessCode execute(const AlgorithmContext& ctx) const override;

ProcessCode finalize() override;

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

private:
/// Configuration
Config m_cfg;

/// Input data handles
ReadDataHandle<SimParticleContainer> m_inputParticles{this,
"InputSimParticles"};

ReadDataHandle<SimHitContainer> m_inputSimHits{this, "InputSimHits"};

/// Accumulators for the track parameters
std::unordered_map<Acts::GeometryIdentifier,
std::unique_ptr<TrackParamsLookupAccumulator>>
m_accumulators;
};

} // namespace ActsExamples
Loading
Loading