Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:09:59

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2016-2020 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/TrackParametrization.hpp"
0012 #include "Acts/EventData/SourceLink.hpp"
0013 #include "Acts/EventData/detail/CalculateResiduals.hpp"
0014 #include "Acts/EventData/detail/ParameterTraits.hpp"
0015 #include "Acts/EventData/detail/PrintParameters.hpp"
0016 #include "Acts/Utilities/detail/Subspace.hpp"
0017 
0018 #include <array>
0019 #include <cstddef>
0020 #include <iosfwd>
0021 #include <variant>
0022 
0023 namespace Acts {
0024 
0025 /// A measurement of a fixed-size subspace of the full parameters.
0026 ///
0027 /// @tparam indices_t Parameter index type, determines the full parameter space
0028 /// @tparam kSize Size of the parameter subset.
0029 ///
0030 /// The measurement intentionally does not store a pointer/reference to the
0031 /// reference object in the geometry hierarchy, i.e. the surface or volume. The
0032 /// reference object can already be identified via the geometry identifier
0033 /// provided by the source link. Since a measurement **must** be anchored within
0034 /// the geometry hierarchy, all measurement surfaces and volumes **must**
0035 /// provide valid geometry identifiers. In all use-cases, e.g. Kalman filtering,
0036 /// a pointer/reference to the reference object is available before the
0037 /// measurement is accessed; e.g. the propagator provides the surface pointer
0038 /// during navigation, which is then used to lookup possible measurements.
0039 ///
0040 /// The pointed-to geometry object would differ depending on the parameter type.
0041 /// This means either, that there needs to be an additional variable type or
0042 /// that a pointer to a base object is stored (requiring a `dynamic_cast` later
0043 /// on). Both variants add additional complications. Since the geometry object
0044 /// is not required anyway (as discussed above), not storing it removes all
0045 /// these complications altogether.
0046 template <typename indices_t, std::size_t kSize>
0047 class Measurement {
0048   static constexpr std::size_t kFullSize = detail::kParametersSize<indices_t>;
0049 
0050   using Subspace = detail::FixedSizeSubspace<kFullSize, kSize>;
0051 
0052  public:
0053   using Scalar = ActsScalar;
0054   /// Vector type containing for measured parameter values.
0055   using ParametersVector = ActsVector<kSize>;
0056   /// Matrix type for the measurement covariance.
0057   using CovarianceMatrix = ActsSquareMatrix<kSize>;
0058   /// Vector type containing all parameters in the same space.
0059   using FullParametersVector = ActsVector<kFullSize>;
0060   using ProjectionMatrix = ActsMatrix<kSize, kFullSize>;
0061   using ExpansionMatrix = ActsMatrix<kFullSize, kSize>;
0062 
0063   /// Construct from source link, subset indices, and measured data.
0064   ///
0065   /// @tparam parameters_t Input parameters vector type
0066   /// @tparam covariance_t Input covariance matrix type
0067   /// @param source The link that connects to the underlying detector readout
0068   /// @param indices Which parameters are measured
0069   /// @param params Measured parameters values
0070   /// @param cov Measured parameters covariance
0071   ///
0072   /// @note The indices must be ordered and must describe/match the content
0073   ///   of parameters and covariance.
0074   template <typename parameters_t, typename covariance_t>
0075   Measurement(SourceLink source, const std::array<indices_t, kSize>& indices,
0076               const Eigen::MatrixBase<parameters_t>& params,
0077               const Eigen::MatrixBase<covariance_t>& cov)
0078       : m_source(std::move(source)),
0079         m_subspace(indices),
0080         m_params(params),
0081         m_cov(cov) {
0082     // TODO we should be able to support arbitrary ordering, by sorting the
0083     //   indices and reordering parameters/covariance. since the parameter order
0084     //   can be modified by the user, the user can not always know what the
0085     //   right order is. another option is too remove the requirement for index
0086     //   ordering from the subspace types, but that will make it harder to
0087     //   refactor their implementation later on.
0088   }
0089   /// A measurement can only be constructed with valid parameters.
0090   Measurement() = delete;
0091   Measurement(const Measurement&) = default;
0092   Measurement(Measurement&&) = default;
0093   ~Measurement() = default;
0094   Measurement& operator=(const Measurement&) = default;
0095   Measurement& operator=(Measurement&&) = default;
0096 
0097   /// Source link that connects to the underlying detector readout.
0098   const SourceLink& sourceLink() const { return m_source; }
0099 
0100   /// Number of measured parameters.
0101   static constexpr std::size_t size() { return kSize; }
0102 
0103   /// Check if a specific parameter is part of this measurement.
0104   bool contains(indices_t i) const { return m_subspace.contains(i); }
0105 
0106   /// The measurement indices
0107   constexpr std::array<indices_t, kSize> indices() const {
0108     std::array<uint8_t, kSize> subInds = m_subspace.indices();
0109     std::array<indices_t, kSize> inds{};
0110     for (std::size_t i = 0; i < kSize; i++) {
0111       inds[i] = static_cast<indices_t>(subInds[i]);
0112     }
0113     return inds;
0114   }
0115 
0116   /// Measured parameters values.
0117   const ParametersVector& parameters() const { return m_params; }
0118 
0119   /// Measured parameters covariance.
0120   const CovarianceMatrix& covariance() const { return m_cov; }
0121 
0122   /// Projection matrix from the full space into the measured subspace.
0123   ProjectionMatrix projector() const {
0124     return m_subspace.template projector<Scalar>();
0125   }
0126 
0127   /// Expansion matrix from the measured subspace into the full space.
0128   ///
0129   /// This is equivalent to the transpose of the projection matrix only in the
0130   /// case of a trivial projection matrix. While this is the case here, it is
0131   /// still recommended to use the expansion matrix directly in cases where it
0132   /// is explicitly used.
0133   ExpansionMatrix expander() const {
0134     return m_subspace.template expander<Scalar>();
0135   }
0136 
0137   /// Compute residuals in the measured subspace.
0138   ///
0139   /// @param reference Reference parameters in the full space.
0140   ///
0141   /// This computes the difference `measured - reference` taking into account
0142   /// the allowed parameter ranges. Only the reference values in the measured
0143   /// subspace are used for the computation.
0144   ParametersVector residuals(const FullParametersVector& reference) const {
0145     ParametersVector res = ParametersVector::Zero();
0146     detail::calculateResiduals(static_cast<indices_t>(kSize),
0147                                m_subspace.indices(), reference, m_params, res);
0148     return res;
0149   }
0150 
0151   std::ostream& operator<<(std::ostream& os) const {
0152     detail::printMeasurement(os, static_cast<indices_t>(kSize),
0153                              m_subspace.indices().data(), m_params.data(),
0154                              m_cov.data());
0155     return os;
0156   }
0157 
0158  private:
0159   SourceLink m_source;
0160   Subspace m_subspace;
0161   ParametersVector m_params;
0162   CovarianceMatrix m_cov;
0163 };
0164 
0165 /// Construct a fixed-size measurement for the given indices.
0166 ///
0167 /// @tparam parameters_t Input parameters vector type
0168 /// @tparam covariance_t Input covariance matrix type
0169 /// @tparam indices_t Parameter index type, determines the full parameter space
0170 /// @tparam tail_indices_t Helper types required to support variadic arguments;
0171 ///   all types must be convertibale to `indices_t`.
0172 /// @param source The link that connects to the underlying detector readout
0173 /// @param params Measured parameters values
0174 /// @param cov Measured parameters covariance
0175 /// @param index0 Required parameter index, measurement must be at least 1d
0176 /// @param tailIndices Additional parameter indices for larger measurements
0177 /// @return Fixed-size measurement w/ the correct type and given inputs
0178 ///
0179 /// This helper function can be used to create a fixed-size measurement using an
0180 /// explicit set of indices, e.g.
0181 ///
0182 ///     auto m = makeMeasurement(s, p, c, eBoundLoc0, eBoundTime);
0183 ///
0184 /// for a 2d measurement w/ one position and time.
0185 ///
0186 /// @note The indices must be ordered and must be consistent with the content of
0187 ///   parameters and covariance.
0188 template <typename parameters_t, typename covariance_t, typename indices_t,
0189           typename... tail_indices_t>
0190 auto makeMeasurement(SourceLink source,
0191                      const Eigen::MatrixBase<parameters_t>& params,
0192                      const Eigen::MatrixBase<covariance_t>& cov,
0193                      indices_t index0, tail_indices_t... tailIndices)
0194     -> Measurement<indices_t, 1u + sizeof...(tail_indices_t)> {
0195   using IndexContainer = std::array<indices_t, 1u + sizeof...(tail_indices_t)>;
0196   return {std::move(source), IndexContainer{index0, tailIndices...}, params,
0197           cov};
0198 }
0199 
0200 namespace detail {
0201 /// @cond
0202 
0203 // Recursive construction of the measurement variant. `kN` is counted down until
0204 // zero while the sizes are accumulated in the parameter pack.
0205 //
0206 // Example:
0207 //
0208 //        VariantMeasurementGenerator<..., 4>
0209 //     -> VariantMeasurementGenerator<..., 3, 4>
0210 //     -> VariantMeasurementGenerator<..., 2, 3, 4>
0211 //     -> VariantMeasurementGenerator<..., 1, 2, 3, 4>
0212 //     -> VariantMeasurementGenerator<..., 0, 1, 2, 3, 4>
0213 //
0214 template <typename indices_t, std::size_t kN, std::size_t... kSizes>
0215 struct VariantMeasurementGenerator
0216     : VariantMeasurementGenerator<indices_t, kN - 1u, kN, kSizes...> {};
0217 template <typename indices_t, std::size_t... kSizes>
0218 struct VariantMeasurementGenerator<indices_t, 0u, kSizes...> {
0219   using Type = std::variant<Measurement<indices_t, kSizes>...>;
0220 };
0221 
0222 /// @endcond
0223 }  // namespace detail
0224 
0225 /// Variant that can contain all possible measurements in a parameter space.
0226 ///
0227 /// @tparam indices_t Parameter index type, determines the full parameter space
0228 template <typename indices_t>
0229 using VariantMeasurement = typename detail::VariantMeasurementGenerator<
0230     indices_t, detail::kParametersSize<indices_t>>::Type;
0231 
0232 /// Variant that can hold all possible bound measurements.
0233 ///
0234 using BoundVariantMeasurement = VariantMeasurement<BoundIndices>;
0235 
0236 /// Variant that can hold all possible free measurements.
0237 ///
0238 using FreeVariantMeasurement = VariantMeasurement<FreeIndices>;
0239 
0240 template <typename indices_t>
0241 std::ostream& operator<<(std::ostream& os,
0242                          const VariantMeasurement<indices_t>& vm) {
0243   return std::visit([&](const auto& m) { return (os << m); }, vm);
0244 }
0245 
0246 }  // namespace Acts