File indexing completed on 2024-11-15 09:01:27
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Tolerance.hpp"
0012 #include "Acts/EventData/detail/PrintParameters.hpp"
0013 #include "Acts/EventData/detail/TransformationFreeToBound.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/UnitVectors.hpp"
0016 #include "Acts/Utilities/detail/periodic.hpp"
0017
0018 #include <cassert>
0019 #include <cmath>
0020 #include <memory>
0021 #include <type_traits>
0022
0023 namespace Acts {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 template <class particle_hypothesis_t>
0037 class GenericBoundTrackParameters {
0038 public:
0039 using Scalar = ActsScalar;
0040 using ParametersVector = BoundVector;
0041 using CovarianceMatrix = BoundSquareMatrix;
0042 using ParticleHypothesis = particle_hypothesis_t;
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 GenericBoundTrackParameters(std::shared_ptr<const Surface> surface,
0057 const ParametersVector& params,
0058 std::optional<CovarianceMatrix> cov,
0059 ParticleHypothesis particleHypothesis)
0060 : m_params(params),
0061 m_cov(std::move(cov)),
0062 m_surface(std::move(surface)),
0063 m_particleHypothesis(std::move(particleHypothesis)) {
0064 assert(m_surface);
0065 normalizePhiTheta();
0066 }
0067
0068
0069 template <typename other_particle_hypothesis_t>
0070 GenericBoundTrackParameters(
0071 const GenericBoundTrackParameters<other_particle_hypothesis_t>& other)
0072 : GenericBoundTrackParameters(other.referenceSurface().getSharedPtr(),
0073 other.parameters(), other.covariance(),
0074 other.particleHypothesis()) {}
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 static Result<GenericBoundTrackParameters> create(
0091 std::shared_ptr<const Surface> surface, const GeometryContext& geoCtx,
0092 const Vector4& pos4, const Vector3& dir, Scalar qOverP,
0093 std::optional<CovarianceMatrix> cov,
0094 ParticleHypothesis particleHypothesis,
0095 ActsScalar tolerance = s_onSurfaceTolerance) {
0096 Result<BoundVector> bound = detail::transformFreeToBoundParameters(
0097 pos4.segment<3>(ePos0), pos4[eTime], dir, qOverP, *surface, geoCtx,
0098 tolerance);
0099
0100 if (!bound.ok()) {
0101 return bound.error();
0102 }
0103
0104 return GenericBoundTrackParameters{std::move(surface), std::move(*bound),
0105 std::move(cov),
0106 std::move(particleHypothesis)};
0107 }
0108
0109
0110 GenericBoundTrackParameters() = delete;
0111 GenericBoundTrackParameters(const GenericBoundTrackParameters&) = default;
0112 GenericBoundTrackParameters(GenericBoundTrackParameters&&) = default;
0113 ~GenericBoundTrackParameters() = default;
0114 GenericBoundTrackParameters& operator=(const GenericBoundTrackParameters&) =
0115 default;
0116 GenericBoundTrackParameters& operator=(GenericBoundTrackParameters&&) =
0117 default;
0118
0119
0120 ParametersVector& parameters() { return m_params; }
0121
0122 const ParametersVector& parameters() const { return m_params; }
0123
0124 ActsVector<2> spatialImpactParameters() const { return m_params.head<2>(); }
0125
0126 ActsVector<3> impactParameters() const {
0127 ActsVector<3> ip;
0128 ip.template head<2>() = m_params.template head<2>();
0129 ip(2) = m_params(eBoundTime);
0130 return ip;
0131 }
0132
0133
0134 std::optional<CovarianceMatrix>& covariance() { return m_cov; }
0135
0136 const std::optional<CovarianceMatrix>& covariance() const { return m_cov; }
0137
0138 std::optional<ActsSquareMatrix<2>> spatialImpactParameterCovariance() const {
0139 if (!m_cov.has_value()) {
0140 return std::nullopt;
0141 }
0142
0143 return m_cov.value().template topLeftCorner<2, 2>();
0144 }
0145
0146
0147
0148 std::optional<ActsSquareMatrix<3>> impactParameterCovariance() const {
0149 if (!m_cov.has_value()) {
0150 return std::nullopt;
0151 }
0152
0153 ActsSquareMatrix<3> ipCov;
0154 ipCov.template topLeftCorner<2, 2>() =
0155 m_cov.value().template topLeftCorner<2, 2>();
0156 ipCov.template block<2, 1>(0, 2) =
0157 m_cov.value().template block<2, 1>(0, eBoundTime);
0158 ipCov.template block<1, 2>(2, 0) =
0159 m_cov.value().template block<1, 2>(eBoundTime, 0);
0160 ipCov(2, 2) = m_cov.value()(eBoundTime, eBoundTime);
0161 return ipCov;
0162 }
0163
0164
0165
0166
0167 template <BoundIndices kIndex>
0168 Scalar get() const {
0169 return m_params[kIndex];
0170 }
0171
0172
0173 Vector2 localPosition() const { return m_params.segment<2>(eBoundLoc0); }
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 Vector4 fourPosition(const GeometryContext& geoCtx) const {
0184 Vector4 pos4;
0185 pos4.segment<3>(ePos0) =
0186 m_surface->localToGlobal(geoCtx, localPosition(), direction());
0187 pos4[eTime] = m_params[eBoundTime];
0188 return pos4;
0189 }
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 Vector3 position(const GeometryContext& geoCtx) const {
0200 return m_surface->localToGlobal(geoCtx, localPosition(), direction());
0201 }
0202
0203 Scalar time() const { return m_params[eBoundTime]; }
0204
0205
0206 Scalar phi() const { return m_params[eBoundPhi]; }
0207
0208 Scalar theta() const { return m_params[eBoundTheta]; }
0209
0210 Scalar qOverP() const { return m_params[eBoundQOverP]; }
0211
0212
0213
0214 Vector3 direction() const {
0215 return makeDirectionFromPhiTheta(m_params[eBoundPhi],
0216 m_params[eBoundTheta]);
0217 }
0218
0219 Scalar absoluteMomentum() const {
0220 return m_particleHypothesis.extractMomentum(m_params[eBoundQOverP]);
0221 }
0222
0223 Scalar transverseMomentum() const {
0224 return std::sin(m_params[eBoundTheta]) * absoluteMomentum();
0225 }
0226
0227 Vector3 momentum() const { return absoluteMomentum() * direction(); }
0228
0229
0230 Scalar charge() const {
0231 return m_particleHypothesis.extractCharge(get<eBoundQOverP>());
0232 }
0233
0234
0235 const ParticleHypothesis& particleHypothesis() const {
0236 return m_particleHypothesis;
0237 }
0238
0239
0240 const Surface& referenceSurface() const { return *m_surface; }
0241
0242
0243
0244
0245
0246
0247
0248
0249 RotationMatrix3 referenceFrame(const GeometryContext& geoCtx) const {
0250 return m_surface->referenceFrame(geoCtx, position(geoCtx), momentum());
0251 }
0252
0253 private:
0254 BoundVector m_params;
0255 std::optional<BoundSquareMatrix> m_cov;
0256
0257 std::shared_ptr<const Surface> m_surface;
0258
0259 ParticleHypothesis m_particleHypothesis;
0260
0261
0262 void normalizePhiTheta() {
0263 auto [phi, theta] =
0264 detail::normalizePhiTheta(m_params[eBoundPhi], m_params[eBoundTheta]);
0265 m_params[eBoundPhi] = phi;
0266 m_params[eBoundTheta] = theta;
0267 }
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 friend bool operator==(const GenericBoundTrackParameters& lhs,
0280 const GenericBoundTrackParameters& rhs) {
0281 return (lhs.m_params == rhs.m_params) && (lhs.m_cov == rhs.m_cov) &&
0282 (lhs.m_surface == rhs.m_surface) &&
0283 (lhs.m_particleHypothesis == rhs.m_particleHypothesis);
0284 }
0285
0286 friend bool operator!=(const GenericBoundTrackParameters& lhs,
0287 const GenericBoundTrackParameters& rhs) {
0288 return !(lhs == rhs);
0289 }
0290
0291 friend std::ostream& operator<<(std::ostream& os,
0292 const GenericBoundTrackParameters& tp) {
0293 detail::printBoundParameters(
0294 os, tp.referenceSurface(), tp.parameters(),
0295 tp.covariance().has_value() ? &tp.covariance().value() : nullptr);
0296 return os;
0297 }
0298 };
0299
0300 }