Skip to content

Commit

Permalink
feat: Track parameters lookup estimation examples (#3823)
Browse files Browse the repository at this point in the history
The PR adding the simulation based track parameter estimation. 

The algorithm runs the `Fatras` simulation of the detector setup. A set of grids is imposed onto the user-defined reference layers of the tracking detector (e.g. first tracking layers sensitive surfaces). `CurvilinearTrackParameters` at the vertex and the reference tracking layers are recorded for the simulated particles and stored into the bins of the grids. 

After the simulation is finished, the contents of the grids' bins are averaged and the grids containing the correspondence between the particles' intersection points at the reference layers, track parameters at the vertex and track parameters at the reference layers are constructed. 

The constructed grids are stored into the json files. The grids are then readout and used for track parameters estimation in seeding algorithms, e.g. connected to the `PathSeeder`.    

This PR contains the lookup generation part of the  algorithm. When the interfaces, realisation and the general idea are agreed upon, the second part with the validation of the estimated lookups is going to be put up.
  • Loading branch information
ssdetlab authored Nov 21, 2024
1 parent f6e95c2 commit 6ff7d49
Show file tree
Hide file tree
Showing 17 changed files with 1,087 additions and 23 deletions.
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

0 comments on commit 6ff7d49

Please sign in to comment.