File indexing completed on 2025-10-28 07:54:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp"
0010
0011 #include "Acts/Definitions/TrackParametrization.hpp"
0012 #include "Acts/Utilities/MathHelpers.hpp"
0013
0014 Acts::FreeVector Acts::estimateTrackParamsFromSeed(const Vector3& sp0,
0015 const Vector3& sp1,
0016 const Vector3& sp2,
0017 const Vector3& bField) {
0018
0019
0020
0021
0022
0023 const Vector3 relVec = sp1 - sp0;
0024 const Vector3 newZAxis = bField.normalized();
0025 const Vector3 newYAxis = newZAxis.cross(relVec).normalized();
0026 const Vector3 newXAxis = newYAxis.cross(newZAxis);
0027 RotationMatrix3 rotation;
0028 rotation.col(0) = newXAxis;
0029 rotation.col(1) = newYAxis;
0030 rotation.col(2) = newZAxis;
0031
0032 const Translation3 trans(sp0);
0033
0034 const Transform3 transform(trans * rotation);
0035
0036
0037 const Vector3 local1 = transform.inverse() * sp1;
0038 const Vector3 local2 = transform.inverse() * sp2;
0039
0040
0041
0042 Vector2 circleCenter = Vector2::Zero();
0043 {
0044 const double det = 2 * (local1.x() * local2.y() - local2.x() * local1.y());
0045
0046
0047 if (std::abs(det) < 1e-12) {
0048 FreeVector params = FreeVector::Zero();
0049 params.segment<3>(eFreePos0) = sp0;
0050 params.segment<3>(eFreeDir0) = (sp2 - sp0).normalized();
0051 params[eFreeQOverP] = 0;
0052 return params;
0053 }
0054
0055 const double z1 = local1.head<2>().squaredNorm();
0056 const double z2 = local2.head<2>().squaredNorm();
0057
0058 const double nom1 = local1.y() * z2 - local2.y() * z1;
0059 const double nom2 = local2.x() * z1 - local1.x() * z2;
0060
0061 circleCenter.x() = nom1 / det;
0062 circleCenter.y() = nom2 / det;
0063 }
0064 const int sign = circleCenter.y() >= 0 ? 1 : -1;
0065 const double R = circleCenter.norm();
0066
0067 const double invTanTheta =
0068 local2.z() / (2 * R * std::asin(local2.head<2>().norm() / (2 * R)));
0069
0070
0071 const double A = -circleCenter.x() / circleCenter.y();
0072 const Vector3 transDirection(1., A, fastHypot(1, A) * invTanTheta);
0073
0074 const Vector3 direction = rotation * transDirection.normalized();
0075
0076
0077 FreeVector params = FreeVector::Zero();
0078
0079
0080 params.segment<3>(eFreePos0) = sp0;
0081
0082
0083 params.segment<3>(eFreeDir0) = direction;
0084
0085
0086
0087 const double qOverPt = sign / (bField.norm() * R);
0088
0089 params[eFreeQOverP] = qOverPt / fastHypot(1., invTanTheta);
0090
0091 return params;
0092 }
0093
0094 Acts::BoundMatrix Acts::estimateTrackParamCovariance(
0095 const EstimateTrackParamCovarianceConfig& config, const BoundVector& params,
0096 bool hasTime) {
0097 assert((params[eBoundTheta] > 0 && params[eBoundTheta] < std::numbers::pi) &&
0098 "Theta must be in the range (0, pi)");
0099
0100 BoundSquareMatrix result = BoundSquareMatrix::Zero();
0101
0102 for (std::size_t i = eBoundLoc0; i < eBoundSize; ++i) {
0103 double sigma = config.initialSigmas[i];
0104 double variance = sigma * sigma;
0105
0106 if (i == eBoundQOverP) {
0107
0108 double varianceTheta = result(eBoundTheta, eBoundTheta);
0109
0110
0111 variance += std::pow(
0112 config.initialSigmaQoverPt * std::sin(params[eBoundTheta]), 2);
0113
0114
0115 variance += std::pow(config.initialSigmaPtRel * params[eBoundQOverP], 2);
0116
0117
0118 variance +=
0119 varianceTheta *
0120 std::pow(params[eBoundQOverP] / std::tan(params[eBoundTheta]), 2);
0121 }
0122
0123 if (i == eBoundTime && !hasTime) {
0124
0125 variance *= config.noTimeVarInflation;
0126 }
0127
0128
0129 variance *= config.initialVarInflation[i];
0130
0131 result(i, i) = variance;
0132 }
0133
0134 return result;
0135 }