File indexing completed on 2025-10-25 07:56:26
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/Digitization/DigitizationError.hpp"
0017 #include "ActsFatras/EventData/Hit.hpp"
0018
0019 #include <array>
0020 #include <functional>
0021 #include <utility>
0022
0023 namespace ActsFatras {
0024
0025
0026
0027
0028
0029
0030
0031 template <typename generator_t>
0032 using SingleParameterSmearFunction =
0033 std::function<Acts::Result<std::pair<double, double>>(double,
0034 generator_t&)>;
0035
0036
0037
0038
0039
0040
0041
0042
0043 template <typename generator_t, std::size_t kSize>
0044 struct BoundParametersSmearer {
0045
0046 using ParametersVector = Acts::ActsVector<kSize>;
0047
0048 using CovarianceMatrix = Acts::ActsSquareMatrix<kSize>;
0049
0050 using Result = Acts::Result<std::pair<ParametersVector, CovarianceMatrix>>;
0051
0052
0053 std::array<Acts::BoundIndices, kSize> indices{};
0054
0055 std::array<SingleParameterSmearFunction<generator_t>, kSize> smearFunctions{};
0056
0057 std::array<bool, kSize> forcePositive = {};
0058
0059 std::size_t maxRetries = 0;
0060
0061
0062
0063 static constexpr std::size_t size() { return kSize; }
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 Result operator()(generator_t& rng, const Hit& hit,
0074 const Acts::Surface& surface,
0075 const Acts::GeometryContext& geoCtx) const {
0076
0077
0078
0079 const auto tolerance =
0080 surface.associatedDetectorElement() != nullptr
0081 ? surface.associatedDetectorElement()->thickness()
0082 : Acts::s_onSurfaceTolerance;
0083
0084
0085
0086 Acts::Result<Acts::BoundVector> boundParamsRes =
0087 Acts::transformFreeToBoundParameters(hit.position(), hit.time(),
0088 hit.direction(), 0, surface,
0089 geoCtx, tolerance);
0090
0091 if (!boundParamsRes.ok()) {
0092 return boundParamsRes.error();
0093 }
0094
0095 const auto& boundParams = *boundParamsRes;
0096 Acts::BoundVector smearedBoundParams = boundParams;
0097
0098 for (std::size_t k = 0; k < maxRetries + 1; ++k) {
0099 ParametersVector par = ParametersVector::Zero();
0100 CovarianceMatrix cov = CovarianceMatrix::Zero();
0101 for (std::size_t i = 0; i < kSize; ++i) {
0102 auto res = smearFunctions[i](boundParams[indices[i]], rng);
0103 if (!res.ok()) {
0104 return Result::failure(res.error());
0105 }
0106 auto [value, stddev] = res.value();
0107 par[i] = value;
0108 if (forcePositive[i]) {
0109 par[i] = std::abs(value);
0110 }
0111 smearedBoundParams[indices[i]] = par[i];
0112 cov(i, i) = stddev * stddev;
0113 }
0114
0115 if (!surface.insideBounds(smearedBoundParams.head<2>())) {
0116 continue;
0117 }
0118
0119 return Result::success(std::make_pair(par, cov));
0120 }
0121
0122 return Result::failure(DigitizationError::MaximumRetriesExceeded);
0123 }
0124 };
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 template <typename generator_t, std::size_t kSize>
0137 struct FreeParametersSmearer {
0138
0139 using ParametersVector = Acts::ActsVector<kSize>;
0140
0141 using CovarianceMatrix = Acts::ActsSquareMatrix<kSize>;
0142
0143 using Result = Acts::Result<std::pair<ParametersVector, CovarianceMatrix>>;
0144
0145
0146 std::array<Acts::FreeIndices, kSize> indices{};
0147
0148 std::array<SingleParameterSmearFunction<generator_t>, kSize> smearFunctions;
0149
0150
0151
0152 static constexpr std::size_t size() { return kSize; }
0153
0154
0155
0156
0157
0158
0159
0160
0161 Result operator()(generator_t& rng, const Hit& hit) const {
0162
0163
0164 Acts::FreeVector freeParams;
0165 freeParams.segment<3>(Acts::eFreePos0) = hit.position();
0166 freeParams[Acts::eFreeTime] = hit.time();
0167 freeParams.segment<3>(Acts::eFreeDir0) = hit.direction();
0168 freeParams[Acts::eFreeQOverP] = 0;
0169
0170 ParametersVector par = ParametersVector::Zero();
0171 CovarianceMatrix cov = CovarianceMatrix::Zero();
0172 for (std::size_t i = 0; i < kSize; ++i) {
0173 auto res = smearFunctions[i](freeParams[indices[i]], rng);
0174 if (!res.ok()) {
0175 return Result::failure(res.error());
0176 }
0177 auto [value, stddev] = res.value();
0178 par[i] = value;
0179 cov(i, i) = stddev * stddev;
0180 }
0181
0182 return Result::success(std::make_pair(par, cov));
0183 }
0184 };
0185
0186 }