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

refactor!: Clean track EDM projector #3605

Merged
merged 22 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from 19 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
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ TrackAlignmentState trackAlignmentState(
measdim) = measCovariance;

// (b) Get and fill the bound parameters to measurement projection matrix
const ActsDynamicMatrix H = state.effectiveProjector();
const ActsDynamicMatrix H =
state.projectorSubspaceHelper().fullProjector().topLeftCorner(
measdim, eBoundSize);
alignState.projectionMatrix.block(iMeasurement, iParams, measdim,
eBoundSize) = H;
// (c) Get and fill the residual
Expand Down
30 changes: 14 additions & 16 deletions Core/include/Acts/EventData/SubspaceHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
#include "Acts/Utilities/AlgebraHelpers.hpp"
#include "Acts/Utilities/Enumerate.hpp"

#include <bitset>
#include <span>

#include <boost/container/static_vector.hpp>

namespace Acts {
Expand All @@ -25,30 +22,30 @@ namespace Acts {
///
/// Indices must be unique and within the full size of the subspace
///
/// @tparam Container type of the container
/// @tparam index_range_t the type of the container of indices
///
/// @param container the container of indices
/// @param indexRange the range of indices
/// @param fullSize the full size of the subspace
/// @param subspaceSize the size of the subspace
///
/// @return true if the indices are consistent
template <typename Container>
inline static bool checkSubspaceIndices(const Container& container,
template <std::ranges::range index_range_t>
inline static bool checkSubspaceIndices(const index_range_t& indexRange,
std::size_t fullSize,
std::size_t subspaceSize) {
if (subspaceSize > fullSize) {
return false;
}
if (static_cast<std::size_t>(container.size()) != subspaceSize) {
if (static_cast<std::size_t>(indexRange.size()) != subspaceSize) {
return false;
}
for (auto it = container.begin(); it != container.end();) {
for (auto it = indexRange.begin(); it != indexRange.end();) {
auto index = *it;
if (index >= fullSize) {
return false;
}
++it;
if (std::find(it, container.end(), index) != container.end()) {
if (std::find(it, indexRange.end(), index) != indexRange.end()) {
return false;
}
}
Expand All @@ -69,7 +66,8 @@ inline static SerializedSubspaceIndices serializeSubspaceIndices(
{
SerializedSubspaceIndices result = 0;
for (std::size_t i = 0; i < FullSize; ++i) {
result |= static_cast<SerializedSubspaceIndices>(indices[i]) << (i * 8);
result |= static_cast<SerializedSubspaceIndices>(indices[i] & 0xFF)
andiwand marked this conversation as resolved.
Show resolved Hide resolved
<< (i * 8);
}
return result;
}
Expand All @@ -88,7 +86,7 @@ inline static SubspaceIndices<FullSize> deserializeSubspaceIndices(
{
SubspaceIndices<FullSize> result;
for (std::size_t i = 0; i < FullSize; ++i) {
result[i] = static_cast<std::uint8_t>(serialized >> (i * 8));
result[i] = static_cast<std::uint8_t>((serialized >> (i * 8)) & 0xFF);
}
return result;
}
Expand Down Expand Up @@ -187,8 +185,8 @@ class VariableSubspaceHelper
using IndexType = index_t;
using Container = boost::container::static_vector<IndexType, FullSize>;

template <typename OtherContainer>
explicit VariableSubspaceHelper(const OtherContainer& indices) {
template <std::ranges::range other_index_range_t>
explicit VariableSubspaceHelper(const other_index_range_t& indices) {
assert(checkSubspaceIndices(indices, kFullSize, indices.size()) &&
"Invalid indices");
m_indices.resize(indices.size());
Expand Down Expand Up @@ -236,8 +234,8 @@ class FixedSubspaceHelper
using IndexType = index_t;
using Container = std::array<IndexType, kSubspaceSize>;

template <typename OtherContainer>
explicit FixedSubspaceHelper(const OtherContainer& indices) {
template <std::ranges::range other_index_range_t>
explicit FixedSubspaceHelper(const other_index_range_t& indices) {
assert(checkSubspaceIndices(indices, kFullSize, kSubspaceSize) &&
"Invalid indices");
std::transform(indices.begin(), indices.end(), m_indices.begin(),
Expand Down
194 changes: 66 additions & 128 deletions Core/include/Acts/EventData/TrackStateProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#pragma once

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Definitions/TrackParametrization.hpp"
#include "Acts/EventData/SourceLink.hpp"
#include "Acts/EventData/SubspaceHelpers.hpp"
Expand All @@ -17,7 +16,6 @@
#include "Acts/EventData/TrackStateType.hpp"
#include "Acts/EventData/Types.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/AlgebraHelpers.hpp"
#include "Acts/Utilities/HashedString.hpp"
#include "Acts/Utilities/Helpers.hpp"

Expand Down Expand Up @@ -127,11 +125,6 @@ struct TrackStateTraits {
typename detail_lt::DynamicSizeTypes<ReadOnly>::CoefficientsMap;
using EffectiveCalibratedCovariance =
typename detail_lt::DynamicSizeTypes<ReadOnly>::CovarianceMap;

constexpr static auto ProjectorFlags = Eigen::RowMajor | Eigen::AutoAlign;
using Projector = Eigen::Matrix<double, M, eBoundSize, ProjectorFlags>;
using EffectiveProjector = Eigen::Matrix<double, Eigen::Dynamic, eBoundSize,
ProjectorFlags, M, eBoundSize>;
};

/// Proxy object to access a single point on the trajectory.
Expand Down Expand Up @@ -207,17 +200,6 @@ class TrackStateProxy {
/// Sentinel value that indicates an invalid index
static constexpr IndexType kInvalid = kTrackIndexInvalid;

/// Matrix representing the projector (measurement mapping function) for a
/// measurement. This is not a map type, but an actual matrix. This matrix
/// is always \f$M \times M\f$, even if the local measurement dimension is lower.
/// The actual \f$N\times M\f$ projector is given by the top \f$N\f$ rows.
using Projector = typename TrackStateTraits<M, ReadOnly>::Projector;

/// Dynamic variant of the projector matrix
/// @warning Using this type is discouraged, as it has a runtime overhead
using EffectiveProjector =
typename TrackStateTraits<M, ReadOnly>::EffectiveProjector;

/// The track state container backend given as a template parameter
using Trajectory = trajectory_t;

Expand Down Expand Up @@ -615,145 +597,101 @@ class TrackStateProxy {
///
/// @{

/// Returns the projector (measurement mapping function) for this track
/// state. It is derived from the uncalibrated measurement
/// @note This function returns the overallocated projector. This means it
/// is of dimension MxM, where M is the maximum number of measurement
/// dimensions. The NxM submatrix, where N is the actual dimension of the
/// measurement, is located in the top left corner, everything else is zero.
/// @return The overallocated projector
Projector projector() const;

/// Returns whether a projector is set
/// @return Whether it is set
bool hasProjector() const { return has<hashString("projector")>(); }

/// Returns the projector (measurement mapping function) for this track
/// state. It is derived from the uncalibrated measurement
/// @warning This function returns the effective projector. This means it
/// is of dimension \f$N\times M\f$, where \f$N\f$ is the actual dimension of the
/// measurement.
/// @return The effective projector
EffectiveProjector effectiveProjector() const {
return projector().topLeftCorner(calibratedSize(), M);
}

/// Set the projector on this track state
/// This will convert the projector to a more compact bitset representation
/// and store it.
/// @param projector The projector in the form of a dense matrix
/// @note @p projector is assumed to only have 0s or 1s as components.
template <typename Derived>
[[deprecated("use setProjector(span) instead")]] void setProjector(
const Eigen::MatrixBase<Derived>& projector)
requires(!ReadOnly)
{
constexpr int rows = Eigen::MatrixBase<Derived>::RowsAtCompileTime;
constexpr int cols = Eigen::MatrixBase<Derived>::ColsAtCompileTime;

static_assert(rows != -1 && cols != -1,
"Assignment of dynamic matrices is currently not supported.");

assert(has<hashString("projector")>());

static_assert(rows <= M, "Given projector has too many rows");
static_assert(cols <= eBoundSize, "Given projector has too many columns");

// set up full size projector with only zeros
typename TrackStateProxy::Projector fullProjector =
decltype(fullProjector)::Zero();

// assign (potentially) smaller actual projector to matrix, preserving
// zeroes outside of smaller matrix block.
fullProjector.template topLeftCorner<rows, cols>() = projector;

// convert to bitset before storing
ProjectorBitset projectorBitset = matrixToBitset(fullProjector).to_ulong();
setProjectorBitset(projectorBitset);
}

/// Directly get the projector bitset, a compressed form of a projection
/// matrix
/// @note This is mainly to copy explicitly a projector from one state
/// to another. Use the `projector` or `effectiveProjector` method if
/// you want to access the matrix.
/// @return The projector bitset
[[deprecated("use projector() instead")]] ProjectorBitset projectorBitset()
const {
return variableBoundSubspaceHelper().projectorBitset();
}

/// Set the projector bitset, a compressed form of a projection matrix
/// @param proj The projector bitset
///
/// @note This is mainly to copy explicitly a projector from one state
/// to another. If you have a projection matrix, set it with
/// `setProjector`.
[[deprecated("use setProjector(span) instead")]] void setProjectorBitset(
ProjectorBitset proj)
requires(!ReadOnly)
{
BoundMatrix projMatrix = bitsetToMatrix<BoundMatrix>(proj);
BoundSubspaceIndices boundSubspace =
projectorToSubspaceIndices<eBoundSize>(projMatrix);
setBoundSubspaceIndices(boundSubspace);
}

BoundSubspaceIndices boundSubspaceIndices() const {
assert(has<hashString("projector")>());
return deserializeSubspaceIndices<eBoundSize>(
component<SerializedSubspaceIndices, hashString("projector")>());
}

template <std::size_t measdim>
SubspaceIndices<measdim> subspaceIndices() const {
BoundSubspaceIndices boundSubspace = BoundSubspaceIndices();
SubspaceIndices<measdim> subspace;
std::copy(boundSubspace.begin(), boundSubspace.begin() + measdim,
subspace.begin());
return subspace;
}

void setBoundSubspaceIndices(BoundSubspaceIndices boundSubspace)
/// Set the projector subspace indices
/// @param boundSubspace The projector subspace indices to set
void setProjectorSubspaceIndices(BoundSubspaceIndices boundSubspace)
requires(!ReadOnly)
{
assert(has<hashString("projector")>());
component<SerializedSubspaceIndices, hashString("projector")>() =
serializeSubspaceIndices(boundSubspace);
}

/// Set the projector subspace indices
/// @param subspace The projector subspace indices to set
template <std::size_t measdim>
void setSubspaceIndices(SubspaceIndices<measdim> subspace)
void setProjectorSubspaceIndices(SubspaceIndices<measdim> subspace)
requires(!ReadOnly && measdim <= eBoundSize)
{
assert(has<hashString("projector")>());
BoundSubspaceIndices boundSubspace{};
std::copy(subspace.begin(), subspace.end(), boundSubspace.begin());
setBoundSubspaceIndices(boundSubspace);
setProjectorSubspaceIndices(boundSubspace);
}

/// Set the projector subspace indices
/// @param subspaceIndices The projector subspace indices to set
template <std::size_t measdim, typename index_t>
void setSubspaceIndices(std::array<index_t, measdim> subspaceIndices)
void setProjectorSubspaceIndices(std::span<index_t, measdim> subspaceIndices)
requires(!ReadOnly && measdim <= eBoundSize)
{
assert(has<hashString("projector")>());
BoundSubspaceIndices boundSubspace{};
std::transform(subspaceIndices.begin(), subspaceIndices.end(),
boundSubspace.begin(),
[](index_t i) { return static_cast<std::uint8_t>(i); });
setBoundSubspaceIndices(boundSubspace);
setProjectorSubspaceIndices(boundSubspace);
}

/// Set the projector subspace indices
/// @param subspaceIndices The projector subspace indices to set
template <typename index_t>
void setProjectorSubspaceIndices(std::span<index_t> subspaceIndices) {
andiwand marked this conversation as resolved.
Show resolved Hide resolved
assert(has<hashString("projector")>());
assert(subspaceIndices.size() <= eBoundSize);
BoundSubspaceIndices boundSubspace{};
std::transform(subspaceIndices.begin(), subspaceIndices.end(),
boundSubspace.begin(),
[](index_t i) { return static_cast<std::uint8_t>(i); });
setProjectorSubspaceIndices(boundSubspace);
}

/// Set the projector subspace indices
/// @param subspaceIndices The projector subspace indices to set
template <std::size_t measdim, typename index_t>
void setProjectorSubspaceIndices(std::array<index_t, measdim> subspaceIndices)
andiwand marked this conversation as resolved.
Show resolved Hide resolved
requires(!ReadOnly && measdim <= eBoundSize)
{
setProjectorSubspaceIndices(std::span(subspaceIndices));
}

/// Returns whether a projector is set
/// @return Whether it is set
bool hasProjector() const { return has<hashString("projector")>(); }
paulgessinger marked this conversation as resolved.
Show resolved Hide resolved

/// Returns the projector subspace indices
/// @return The projector subspace indices
BoundSubspaceIndices projectorSubspaceIndices() const {
assert(has<hashString("projector")>());
return deserializeSubspaceIndices<eBoundSize>(
component<SerializedSubspaceIndices, hashString("projector")>());
}

/// Returns the projector subspace indices
/// @return The projector subspace indices
template <std::size_t measdim>
SubspaceIndices<measdim> projectorSubspaceIndices() const {
BoundSubspaceIndices boundSubspace = projectorSubspaceIndices();
SubspaceIndices<measdim> subspace;
std::copy(boundSubspace.begin(), boundSubspace.begin() + measdim,
subspace.begin());
return subspace;
}

VariableBoundSubspaceHelper variableBoundSubspaceHelper() const {
BoundSubspaceIndices boundSubspace = boundSubspaceIndices();
/// Creates a variable size subspace helper
/// @return The subspace helper
VariableBoundSubspaceHelper projectorSubspaceHelper() const {
BoundSubspaceIndices boundSubspace = projectorSubspaceIndices();
std::span<std::uint8_t> validSubspaceIndices(
boundSubspace.begin(), boundSubspace.begin() + calibratedSize());
return VariableBoundSubspaceHelper(validSubspaceIndices);
}

/// Creates a fixed size subspace helper
/// @return The subspace helper
template <std::size_t measdim>
FixedBoundSubspaceHelper<measdim> fixedBoundSubspaceHelper() const {
SubspaceIndices<measdim> subspace = subspaceIndices<measdim>();
FixedBoundSubspaceHelper<measdim> projectorSubspaceHelper() const {
SubspaceIndices<measdim> subspace = projectorSubspaceIndices<measdim>();
return FixedBoundSubspaceHelper<measdim>(subspace);
}

Expand Down Expand Up @@ -1028,7 +966,7 @@ class TrackStateProxy {
other.template calibratedCovariance<measdim>().eval());
});

setBoundSubspaceIndices(other.boundSubspaceIndices());
setProjectorSubspaceIndices(other.projectorSubspaceIndices());
andiwand marked this conversation as resolved.
Show resolved Hide resolved
}
} else {
if (ACTS_CHECK_BIT(mask, PM::Predicted) &&
Expand Down Expand Up @@ -1073,7 +1011,7 @@ class TrackStateProxy {
other.template calibratedCovariance<measdim>().eval());
});

setBoundSubspaceIndices(other.boundSubspaceIndices());
setProjectorSubspaceIndices(other.projectorSubspaceIndices());
}
}

Expand Down
5 changes: 0 additions & 5 deletions Core/include/Acts/EventData/TrackStateProxy.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@ inline auto TrackStateProxy<D, M, ReadOnly>::covariance() const
}
}

template <typename D, std::size_t M, bool ReadOnly>
inline auto TrackStateProxy<D, M, ReadOnly>::projector() const -> Projector {
return variableBoundSubspaceHelper().fullProjector();
}

template <typename D, std::size_t M, bool ReadOnly>
inline auto TrackStateProxy<D, M, ReadOnly>::getUncalibratedSourceLink() const
-> SourceLink {
Expand Down
6 changes: 0 additions & 6 deletions Core/include/Acts/EventData/TrackStateProxyConcept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,6 @@ concept TrackStateProxyConcept =
{ cv.hasProjector() } -> std::same_as<bool>;
{ v.hasProjector() } -> std::same_as<bool>;

{ cv.effectiveProjector() } -> std::same_as<detail::EffectiveProjector>;
{ v.effectiveProjector() } -> std::same_as<detail::EffectiveProjector>;

{ cv.projectorBitset() } -> std::same_as<ProjectorBitset>;
{ v.projectorBitset() } -> std::same_as<ProjectorBitset>;

{ cv.getUncalibratedSourceLink() } -> std::same_as<SourceLink>;
{ v.getUncalibratedSourceLink() } -> std::same_as<SourceLink>;

Expand Down
Loading
Loading