File indexing completed on 2025-10-13 08:15:52
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Seeding/CompositeSpacePointLineSeeder.hpp"
0012
0013 namespace Acts::Experimental {
0014
0015 constexpr CompositeSpacePointLineSeeder::TangentAmbi
0016 CompositeSpacePointLineSeeder::encodeAmbiguity(const int signTop,
0017 const int signBottom) {
0018 assert(Acts::abs(signTop) == 1 && Acts::abs(signBottom) == 1);
0019 using enum TangentAmbi;
0020 if (signTop == 1 && signBottom == 1) {
0021 return RR;
0022 } else if (signTop == 1 && signBottom == -1) {
0023 return RL;
0024 } else if (signTop == -1 && signBottom == 1) {
0025 return LR;
0026 }
0027 return LL;
0028 }
0029
0030 inline std::string CompositeSpacePointLineSeeder::toString(
0031 const TangentAmbi ambi) {
0032 switch (ambi) {
0033 using enum TangentAmbi;
0034 case RR:
0035 return "Right - Right";
0036 case RL:
0037 return "Right - Left";
0038 case LR:
0039 return "Left - Right";
0040 case LL:
0041 return "Left - Left";
0042 }
0043 return "Undefined";
0044 }
0045
0046 template <CompositeSpacePoint SpacePoint_t>
0047 CompositeSpacePointLineSeeder::TwoCircleTangentPars
0048 CompositeSpacePointLineSeeder::constructTangentLine(
0049 const SpacePoint_t& topHit, const SpacePoint_t& bottomHit,
0050 const TangentAmbi ambi) {
0051 using ResidualIdx = detail::CompSpacePointAuxiliaries::ResidualIdx;
0052 TwoCircleTangentPars result{};
0053 const auto& [signTop, signBot] = s_signCombo[toUnderlying(ambi)];
0054
0055 const Vector& bottomPos{bottomHit.localPosition()};
0056 const Vector& topPos{topHit.localPosition()};
0057 const Vector& eY{bottomHit.toNextSensor()};
0058 const Vector& eZ{bottomHit.planeNormal()};
0059
0060 const Vector D = topPos - bottomPos;
0061
0062 assert(Acts::abs(eY.dot(eZ)) < std::numeric_limits<double>::epsilon());
0063 assert(Acts::abs(bottomHit.sensorDirection().dot(eY)) <
0064 std::numeric_limits<double>::epsilon());
0065 assert(Acts::abs(bottomHit.sensorDirection().dot(eZ)) <
0066 std::numeric_limits<double>::epsilon());
0067
0068 assert(topHit.isStraw() && bottomHit.isStraw());
0069 const double dY = D.dot(eY);
0070 const double dZ = D.dot(eZ);
0071
0072 const double thetaTubes = std::atan2(dY, dZ);
0073 const double distTubes = Acts::fastHypot(dY, dZ);
0074
0075 constexpr auto covIdx = Acts::toUnderlying(ResidualIdx::bending);
0076 const double combDriftUncert{topHit.covariance()[covIdx] +
0077 bottomHit.covariance()[covIdx]};
0078 const double R =
0079 -signBot * bottomHit.driftRadius() + signTop * topHit.driftRadius();
0080 result.theta = thetaTubes - std::asin(std::clamp(R / distTubes, -1., 1.));
0081 const double cosTheta = std::cos(result.theta);
0082 const double sinTheta = std::sin(result.theta);
0083 result.y0 = bottomPos.dot(eY) * cosTheta - bottomPos.dot(eZ) * sinTheta -
0084 signBot * bottomHit.driftRadius();
0085 assert(Acts::abs(topPos.dot(eY) * cosTheta - topPos.dot(eZ) * sinTheta -
0086 signTop * topHit.driftRadius() - result.y0) <
0087 std::numeric_limits<float>::epsilon());
0088 result.y0 /= cosTheta;
0089 const double denomSquare = 1. - Acts::pow(R / distTubes, 2);
0090 if (denomSquare < std::numeric_limits<double>::epsilon()) {
0091 return result;
0092 }
0093 result.dTheta = combDriftUncert / std::sqrt(denomSquare) / distTubes;
0094 result.dY0 =
0095 std::hypot(bottomPos.dot(eY) * sinTheta + bottomPos.dot(eZ) * cosTheta,
0096 1.) *
0097 result.dTheta;
0098 return result;
0099 }
0100 }