File indexing completed on 2026-04-08 07:47:25
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/SubspaceHelpers.hpp"
0014 #include "Acts/EventData/Types.hpp"
0015 #include "Acts/Geometry/GeometryIdentifier.hpp"
0016 #include "Acts/Utilities/detail/ContainerIterator.hpp"
0017 #include "ActsExamples/EventData/GeometryContainers.hpp"
0018 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0019 #include "ActsExamples/EventData/MeasurementConcept.hpp"
0020
0021 #include <cstddef>
0022 #include <iterator>
0023 #include <type_traits>
0024 #include <vector>
0025
0026 #include <boost/container/static_vector.hpp>
0027
0028 namespace ActsExamples {
0029
0030 template <typename Derived, std::size_t FullSize, bool ReadOnly>
0031 class MeasurementProxyBase;
0032 template <std::size_t FullSize, std::size_t Size, bool ReadOnly>
0033 class FixedMeasurementProxy;
0034 template <std::size_t FullSize, bool ReadOnly>
0035 class VariableMeasurementProxy;
0036
0037 template <std::size_t Size>
0038 using FixedBoundMeasurementProxy =
0039 FixedMeasurementProxy<Acts::eBoundSize, Size, false>;
0040 template <std::size_t Size>
0041 using ConstFixedBoundMeasurementProxy =
0042 FixedMeasurementProxy<Acts::eBoundSize, Size, true>;
0043 using VariableBoundMeasurementProxy =
0044 VariableMeasurementProxy<Acts::eBoundSize, false>;
0045 using ConstVariableBoundMeasurementProxy =
0046 VariableMeasurementProxy<Acts::eBoundSize, true>;
0047
0048
0049
0050
0051
0052
0053
0054
0055 class MeasurementContainer {
0056 public:
0057 using size_type = std::size_t;
0058 using Index = size_type;
0059 template <std::size_t Size>
0060 using FixedProxy = FixedMeasurementProxy<Acts::eBoundSize, Size, false>;
0061 template <std::size_t Size>
0062 using ConstFixedProxy = FixedMeasurementProxy<Acts::eBoundSize, Size, true>;
0063 using VariableProxy = VariableMeasurementProxy<Acts::eBoundSize, false>;
0064 using ConstVariableProxy = VariableMeasurementProxy<Acts::eBoundSize, true>;
0065 using OrderedIndices = GeometryIdMultiset<IndexSourceLink>;
0066
0067 MeasurementContainer();
0068
0069
0070
0071 std::size_t size() const;
0072
0073
0074
0075 void reserve(std::size_t size);
0076
0077
0078
0079
0080
0081 Index addMeasurement(std::uint8_t size, Acts::GeometryIdentifier geometryId);
0082
0083
0084
0085
0086 VariableProxy at(Index index);
0087
0088
0089
0090 ConstVariableProxy at(Index index) const;
0091
0092
0093
0094
0095 VariableProxy getMeasurement(Index index);
0096
0097
0098
0099 ConstVariableProxy getMeasurement(Index index) const;
0100
0101
0102
0103
0104
0105 template <std::size_t Size>
0106 FixedProxy<Size> getMeasurement(Index index) {
0107 return FixedProxy<Size>{*this, index};
0108 }
0109
0110
0111
0112
0113 template <std::size_t Size>
0114 ConstFixedProxy<Size> getMeasurement(Index index) const {
0115 return ConstFixedProxy<Size>{*this, index};
0116 }
0117
0118
0119
0120
0121
0122 VariableProxy makeMeasurement(std::uint8_t size,
0123 Acts::GeometryIdentifier geometryId);
0124
0125
0126
0127
0128 template <std::size_t Size>
0129 FixedProxy<Size> makeMeasurement(Acts::GeometryIdentifier geometryId) {
0130 return getMeasurement<Size>(addMeasurement(Size, geometryId));
0131 }
0132
0133 template <MeasurementConcept OtherDerived>
0134 VariableProxy copyMeasurement(const OtherDerived& other);
0135 template <MeasurementConcept OtherDerived, std::size_t Size>
0136 FixedProxy<Size> copyMeasurement(const OtherDerived& other);
0137
0138 template <typename... Args>
0139 VariableProxy emplaceMeasurement(std::uint8_t size,
0140 Acts::GeometryIdentifier geometryId,
0141 Args&&... args);
0142
0143 template <std::size_t Size, typename... Args>
0144 FixedProxy<Size> emplaceMeasurement(Acts::GeometryIdentifier geometryId,
0145 Args&&... args);
0146
0147 const OrderedIndices& orderedIndices() const;
0148
0149 using iterator = Acts::detail::ContainerIterator<MeasurementContainer,
0150 VariableProxy, Index, false>;
0151 using const_iterator =
0152 Acts::detail::ContainerIterator<const MeasurementContainer,
0153 ConstVariableProxy, Index, true>;
0154
0155 iterator begin();
0156 iterator end();
0157 const_iterator begin() const;
0158 const_iterator end() const;
0159 const_iterator cbegin() const;
0160 const_iterator cend() const;
0161
0162 public:
0163 struct MeasurementEntry {
0164 std::size_t subspaceIndexOffset{};
0165 std::size_t parameterOffset{};
0166 std::size_t covarianceOffset{};
0167 std::uint8_t size{};
0168 };
0169
0170 std::vector<MeasurementEntry> m_entries;
0171
0172 std::vector<Acts::GeometryIdentifier> m_geometryIds;
0173 std::vector<std::uint8_t> m_subspaceIndices;
0174 std::vector<double> m_parameters;
0175 std::vector<double> m_covariances;
0176
0177 OrderedIndices m_orderedIndices;
0178 };
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 template <typename Derived, std::size_t FullSize, bool ReadOnly>
0189 class MeasurementProxyBase {
0190 public:
0191 using Index = MeasurementContainer::Index;
0192 using SubspaceIndex = std::uint8_t;
0193 using Scalar = double;
0194
0195 using FullVector = Acts::Vector<FullSize>;
0196 using FullSquareMatrix = Acts::SquareMatrix<FullSize>;
0197
0198 using Container = std::conditional_t<ReadOnly, const MeasurementContainer,
0199 MeasurementContainer>;
0200
0201 MeasurementProxyBase(Container& container_, Index index_)
0202 : m_container(&container_), m_index(index_) {}
0203 template <typename OtherDerived, bool OtherReadOnly>
0204 explicit MeasurementProxyBase(
0205 const MeasurementProxyBase<OtherDerived, FullSize, OtherReadOnly>& other)
0206 requires(ReadOnly == OtherReadOnly || ReadOnly)
0207 : m_container(&other.container()), m_index(other.index()) {}
0208
0209
0210
0211 Container& container() const { return *m_container; }
0212
0213
0214 Index index() const { return m_index; }
0215
0216
0217
0218 std::size_t size() const { return container().m_entries.at(m_index).size; }
0219
0220
0221
0222
0223 template <typename indices_t>
0224 bool contains(indices_t i) const {
0225 return self().subspaceHelper().contains(i);
0226 }
0227
0228
0229
0230
0231 template <typename indices_t>
0232 std::size_t indexOf(indices_t i) const {
0233 return self().subspaceHelper().indexOf(i);
0234 }
0235
0236
0237
0238 Acts::GeometryIdentifier geometryId() const {
0239 return container().m_geometryIds.at(m_index);
0240 }
0241
0242
0243
0244 template <typename IndexContainer>
0245 void setSubspaceIndices(const IndexContainer& indices)
0246 requires(!ReadOnly)
0247 {
0248 assert(Acts::checkSubspaceIndices(indices, FullSize, size()) &&
0249 "Invalid indices");
0250 std::transform(indices.begin(), indices.end(),
0251 self().subspaceIndexVector().begin(),
0252 [](auto index) { return static_cast<Index>(index); });
0253 }
0254
0255
0256
0257 FullVector fullParameters() const {
0258 return self().subspaceHelper().expandVector(self().parameters());
0259 }
0260
0261
0262
0263 FullSquareMatrix fullCovariance() const {
0264 return self().subspaceHelper().expandMatrix(self().covariance());
0265 }
0266
0267
0268
0269
0270 template <typename Subspace, typename ParameterDerived,
0271 typename CovarianceDerived>
0272 void fill(Subspace&& subspace,
0273 const Eigen::DenseBase<ParameterDerived>& parameters,
0274 const Eigen::DenseBase<CovarianceDerived>& covariance)
0275 requires(!ReadOnly)
0276 {
0277 self().setSubspaceIndices(std::forward<Subspace>(subspace));
0278 self().parameters() = parameters;
0279 self().covariance() = covariance;
0280 }
0281
0282
0283
0284
0285 template <MeasurementConcept OtherDerived>
0286 void fill(const OtherDerived& other)
0287 requires(!ReadOnly)
0288 {
0289 assert(size() == other.size() && "Size mismatch");
0290 fill(other.subspaceIndexVector(), other.parameters(), other.covariance());
0291 }
0292
0293
0294
0295
0296
0297 template <typename OtherDerived>
0298 void copyFrom(const OtherDerived& other)
0299 requires(!ReadOnly) && requires {
0300 { this->fill(other) };
0301 }
0302 {
0303 fill(other);
0304 }
0305
0306 protected:
0307 Derived& self() { return static_cast<Derived&>(*this); }
0308 const Derived& self() const { return static_cast<const Derived&>(*this); }
0309
0310 Container* m_container;
0311 Index m_index;
0312 };
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 template <std::size_t FullSize, std::size_t Size, bool ReadOnly>
0323 class FixedMeasurementProxy
0324 : public MeasurementProxyBase<
0325 FixedMeasurementProxy<FullSize, Size, ReadOnly>, FullSize, ReadOnly> {
0326 public:
0327 using Base =
0328 MeasurementProxyBase<FixedMeasurementProxy<FullSize, Size, ReadOnly>,
0329 FullSize, ReadOnly>;
0330 using Index = typename Base::Index;
0331 using SubspaceIndex = typename Base::SubspaceIndex;
0332 using Scalar = typename Base::Scalar;
0333 using Container = typename Base::Container;
0334
0335 using SubspaceHelper = Acts::FixedSubspaceHelper<FullSize, Size>;
0336
0337 using SubspaceVector = Eigen::Matrix<SubspaceIndex, Size, 1>;
0338 using SubspaceVectorMap =
0339 std::conditional_t<ReadOnly, Eigen::Map<const SubspaceVector>,
0340 Eigen::Map<SubspaceVector>>;
0341
0342 using ParametersVector = Eigen::Matrix<Scalar, Size, 1>;
0343 using ParametersVectorMap =
0344 std::conditional_t<ReadOnly, Eigen::Map<const ParametersVector>,
0345 Eigen::Map<ParametersVector>>;
0346
0347 using CovarianceMatrix = Eigen::Matrix<Scalar, Size, Size>;
0348 using CovarianceMatrixMap =
0349 std::conditional_t<ReadOnly, Eigen::Map<const CovarianceMatrix>,
0350 Eigen::Map<CovarianceMatrix>>;
0351
0352 FixedMeasurementProxy(Container& container_, Index index_)
0353 : Base(container_, index_) {
0354 assert(container().m_entries.at(index()).size == Size && "Size mismatch");
0355 }
0356 template <typename OtherDerived, bool OtherReadOnly>
0357 explicit FixedMeasurementProxy(
0358 const MeasurementProxyBase<OtherDerived, FullSize, OtherReadOnly>& other)
0359 requires(ReadOnly == OtherReadOnly || ReadOnly)
0360 : Base(other) {
0361 assert(container().m_entries.at(index()).size == Size && "Size mismatch");
0362 }
0363
0364 using Base::container;
0365 using Base::index;
0366
0367
0368
0369 static constexpr std::size_t size() { return Size; }
0370
0371
0372
0373 SubspaceHelper subspaceHelper() const {
0374 return SubspaceHelper{subspaceIndexVector()};
0375 }
0376
0377
0378
0379 Acts::SubspaceIndices<Size> subspaceIndices() const {
0380 return subspaceHelper().indices();
0381 }
0382
0383
0384
0385 SubspaceVectorMap subspaceIndexVector() const {
0386 return SubspaceVectorMap{
0387 container().m_subspaceIndices.data() +
0388 container().m_entries.at(index()).subspaceIndexOffset};
0389 }
0390
0391
0392
0393 ParametersVectorMap parameters() const {
0394 return ParametersVectorMap{
0395 container().m_parameters.data() +
0396 container().m_entries.at(index()).parameterOffset};
0397 }
0398
0399
0400
0401 CovarianceMatrixMap covariance() const {
0402 return CovarianceMatrixMap{
0403 container().m_covariances.data() +
0404 container().m_entries.at(index()).covarianceOffset};
0405 }
0406 };
0407
0408
0409
0410
0411
0412
0413
0414
0415 template <std::size_t FullSize, bool ReadOnly>
0416 class VariableMeasurementProxy
0417 : public MeasurementProxyBase<VariableMeasurementProxy<FullSize, ReadOnly>,
0418 FullSize, ReadOnly> {
0419 public:
0420 using Base =
0421 MeasurementProxyBase<VariableMeasurementProxy<FullSize, ReadOnly>,
0422 FullSize, ReadOnly>;
0423 using Index = typename Base::Index;
0424 using SubspaceIndex = typename Base::SubspaceIndex;
0425 using Scalar = typename Base::Scalar;
0426 using Container = typename Base::Container;
0427
0428 using SubspaceHelper = Acts::VariableSubspaceHelper<FullSize>;
0429
0430 using SubspaceVector = Eigen::Matrix<SubspaceIndex, Eigen::Dynamic, 1>;
0431 using SubspaceVectorMap =
0432 std::conditional_t<ReadOnly, Eigen::Map<const SubspaceVector>,
0433 Eigen::Map<SubspaceVector>>;
0434
0435 using ParametersVector = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
0436 using ParametersVectorMap =
0437 std::conditional_t<ReadOnly, Eigen::Map<const ParametersVector>,
0438 Eigen::Map<ParametersVector>>;
0439
0440 using CovarianceMatrix =
0441 Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
0442 using CovarianceMatrixMap =
0443 std::conditional_t<ReadOnly, Eigen::Map<const CovarianceMatrix>,
0444 Eigen::Map<CovarianceMatrix>>;
0445
0446 VariableMeasurementProxy(Container& container_, Index index_)
0447 : Base(container_, index_) {}
0448 template <typename OtherDerived, bool OtherReadOnly>
0449 explicit VariableMeasurementProxy(
0450 const MeasurementProxyBase<OtherDerived, FullSize, OtherReadOnly>& other)
0451 requires(ReadOnly == OtherReadOnly || ReadOnly)
0452 : Base(other) {}
0453
0454 using Base::container;
0455 using Base::index;
0456
0457
0458
0459 SubspaceHelper subspaceHelper() const {
0460 return SubspaceHelper{subspaceIndexVector()};
0461 }
0462
0463
0464
0465 SubspaceVectorMap subspaceIndexVector() const {
0466 const auto size = static_cast<Eigen::Index>(this->size());
0467 return SubspaceVectorMap{
0468 container().m_subspaceIndices.data() +
0469 container().m_entries.at(index()).subspaceIndexOffset,
0470 size};
0471 }
0472
0473
0474
0475 ParametersVectorMap parameters() const {
0476 const auto size = static_cast<Eigen::Index>(this->size());
0477 return ParametersVectorMap{
0478 container().m_parameters.data() +
0479 container().m_entries.at(index()).parameterOffset,
0480 size};
0481 }
0482
0483
0484
0485 CovarianceMatrixMap covariance() const {
0486 const auto size = static_cast<Eigen::Index>(this->size());
0487 return CovarianceMatrixMap{
0488 container().m_covariances.data() +
0489 container().m_entries.at(index()).covarianceOffset,
0490 size, size};
0491 }
0492 };
0493
0494 template <MeasurementConcept OtherDerived>
0495 MeasurementContainer::VariableProxy MeasurementContainer::copyMeasurement(
0496 const OtherDerived& other) {
0497 VariableProxy meas = makeMeasurement(other.size(), other.geometryId());
0498 meas.copyFrom(other);
0499 return meas;
0500 }
0501
0502 template <MeasurementConcept OtherDerived, std::size_t Size>
0503 MeasurementContainer::FixedProxy<Size> MeasurementContainer::copyMeasurement(
0504 const OtherDerived& other) {
0505 FixedProxy<Size> meas = makeMeasurement<Size>(other.geometryId());
0506 meas.copyFrom(other);
0507 return meas;
0508 }
0509
0510 template <typename... Args>
0511 MeasurementContainer::VariableProxy MeasurementContainer::emplaceMeasurement(
0512 std::uint8_t size, Acts::GeometryIdentifier geometryId, Args&&... args) {
0513 VariableProxy meas = makeMeasurement(size, geometryId);
0514
0515 meas.fill(std::forward<Args>(args)...);
0516
0517 return meas;
0518 }
0519
0520 template <std::size_t Size, typename... Args>
0521 MeasurementContainer::FixedProxy<Size> MeasurementContainer::emplaceMeasurement(
0522 Acts::GeometryIdentifier geometryId, Args&&... args) {
0523 FixedProxy<Size> meas = makeMeasurement<Size>(geometryId);
0524
0525 meas.fill(std::forward<Args>(args)...);
0526
0527 return meas;
0528 }
0529
0530 static_assert(
0531 std::random_access_iterator<MeasurementContainer::iterator> &&
0532 std::random_access_iterator<MeasurementContainer::const_iterator>);
0533
0534 }