File indexing completed on 2025-01-18 09:28:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/TrackParametrization.hpp"
0012 #include "Acts/EventData/TransformationHelpers.hpp"
0013 #include "Acts/Geometry/DetectorElementBase.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/Result.hpp"
0016 #include "ActsFatras/EventData/Hit.hpp"
0017
0018 #include <array>
0019 #include <functional>
0020 #include <utility>
0021
0022 namespace ActsFatras {
0023
0024
0025
0026
0027
0028
0029
0030 template <typename generator_t>
0031 using SingleParameterSmearFunction =
0032 std::function<Acts::Result<std::pair<double, double>>(double,
0033 generator_t&)>;
0034
0035
0036
0037
0038
0039
0040
0041
0042 template <typename generator_t, std::size_t kSize>
0043 struct BoundParametersSmearer {
0044 using Scalar = Acts::ActsScalar;
0045 using ParametersVector = Acts::ActsVector<kSize>;
0046 using CovarianceMatrix = Acts::ActsSquareMatrix<kSize>;
0047 using Result = Acts::Result<std::pair<ParametersVector, CovarianceMatrix>>;
0048
0049
0050 std::array<Acts::BoundIndices, kSize> indices{};
0051 std::array<SingleParameterSmearFunction<generator_t>, kSize> smearFunctions{};
0052 std::array<bool, kSize> forcePositive = {};
0053
0054 static constexpr std::size_t size() { return kSize; }
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 Result operator()(generator_t& rng, const Hit& hit,
0065 const Acts::Surface& surface,
0066 const Acts::GeometryContext& geoCtx) const {
0067
0068
0069
0070 const auto tolerance =
0071 surface.associatedDetectorElement() != nullptr
0072 ? surface.associatedDetectorElement()->thickness()
0073 : Acts::s_onSurfaceTolerance;
0074
0075
0076
0077 Acts::Result<Acts::BoundVector> boundParamsRes =
0078 Acts::transformFreeToBoundParameters(hit.position(), hit.time(),
0079 hit.direction(), 0, surface,
0080 geoCtx, tolerance);
0081
0082 if (!boundParamsRes.ok()) {
0083 return boundParamsRes.error();
0084 }
0085
0086 const auto& boundParams = *boundParamsRes;
0087
0088 ParametersVector par = ParametersVector::Zero();
0089 CovarianceMatrix cov = CovarianceMatrix::Zero();
0090 for (int i = 0; i < static_cast<int>(kSize); ++i) {
0091 auto res = smearFunctions[i](boundParams[indices[i]], rng);
0092 if (!res.ok()) {
0093 return Result::failure(res.error());
0094 }
0095 auto [value, stddev] = res.value();
0096 par[i] = value;
0097 if (forcePositive[i]) {
0098 par[i] = std::abs(value);
0099 }
0100 cov(i, i) = stddev * stddev;
0101 }
0102
0103 return Result::success(std::make_pair(par, cov));
0104 }
0105 };
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 template <typename generator_t, std::size_t kSize>
0118 struct FreeParametersSmearer {
0119 using Scalar = Acts::ActsScalar;
0120 using ParametersVector = Acts::ActsVector<kSize>;
0121 using CovarianceMatrix = Acts::ActsSquareMatrix<kSize>;
0122 using Result = Acts::Result<std::pair<ParametersVector, CovarianceMatrix>>;
0123
0124
0125 std::array<Acts::FreeIndices, kSize> indices{};
0126 std::array<SingleParameterSmearFunction<generator_t>, kSize> smearFunctions;
0127
0128 static constexpr std::size_t size() { return kSize; }
0129
0130
0131
0132
0133
0134
0135
0136
0137 Result operator()(generator_t& rng, const Hit& hit) const {
0138
0139
0140 Acts::FreeVector freeParams;
0141 freeParams.segment<3>(Acts::eFreePos0) = hit.position();
0142 freeParams[Acts::eFreeTime] = hit.time();
0143 freeParams.segment<3>(Acts::eFreeDir0) = hit.direction();
0144 freeParams[Acts::eFreeQOverP] = 0;
0145
0146 ParametersVector par = ParametersVector::Zero();
0147 CovarianceMatrix cov = CovarianceMatrix::Zero();
0148 for (std::size_t i = 0; i < kSize; ++i) {
0149 auto res = smearFunctions[i](freeParams[indices[i]], rng);
0150 if (!res.ok()) {
0151 return Result::failure(res.error());
0152 }
0153 auto [value, stddev] = res.value();
0154 par[i] = value;
0155 cov(i, i) = stddev * stddev;
0156 }
0157
0158 return Result::success(std::make_pair(par, cov));
0159 }
0160 };
0161
0162 }