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