File indexing completed on 2026-04-17 07:46:27
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Seeding/CombinatorialSeedSolver.hpp"
0012
0013 namespace Acts::Experimental::detail {
0014
0015 template <Experimental::CompositeSpacePointPtr Point_t>
0016 std::array<std::size_t, 3> separateLayers(
0017 const std::array<Point_t, 3>& layerTriplet) {
0018
0019 auto n2D = std::ranges::count_if(layerTriplet, [](const auto& sp) {
0020 unsigned int dimension = sp->measuresLoc0() + sp->measuresLoc1();
0021 return dimension == 2;
0022 });
0023
0024 auto n1D = std::ranges::count_if(layerTriplet, [](const auto& sp) {
0025 unsigned int dimension = sp->measuresLoc0() + sp->measuresLoc1();
0026 return dimension == 1;
0027 });
0028
0029 if (n2D != 1 || n1D != 2) {
0030 throw std::runtime_error(
0031 "Triplet must contain exactly one 2D and two 1D space points");
0032 }
0033
0034 std::array<std::size_t, 3> retIndices{
0035 std::numeric_limits<std::size_t>::max()};
0036
0037 for (std::size_t idx = 0; idx < layerTriplet.size(); ++idx) {
0038 const Point_t& spacePoint = layerTriplet[idx];
0039 unsigned int dimension =
0040 spacePoint->measuresLoc0() + spacePoint->measuresLoc1();
0041 if (dimension == 1) {
0042 retIndices[0] == std::numeric_limits<std::size_t>::max()
0043 ? retIndices[0] = idx
0044 : retIndices[1] = idx;
0045 } else {
0046 retIndices[2] = idx;
0047 }
0048 }
0049
0050 return retIndices;
0051 }
0052
0053 }
0054
0055 namespace Acts::Experimental::CombinatorialSeedSolver {
0056
0057 using Acts::Experimental::detail::separateLayers;
0058
0059 template <Experimental::CompositeSpacePointPtr Point_t>
0060 SquareMatrix2 betaMatrix(const std::array<Point_t, 4>& layerQuartett) {
0061 SquareMatrix2 bMatrix{SquareMatrix2::Identity()};
0062
0063 Vector3 b1Aterm = (layerQuartett[3]->sensorDirection().dot(
0064 layerQuartett[1]->sensorDirection())) *
0065 layerQuartett[1]->sensorDirection() -
0066 layerQuartett[3]->sensorDirection();
0067 Vector3 b1Gterm = (layerQuartett[3]->sensorDirection().dot(
0068 layerQuartett[0]->sensorDirection())) *
0069 layerQuartett[0]->sensorDirection() -
0070 (layerQuartett[3]->sensorDirection().dot(
0071 layerQuartett[1]->sensorDirection())) *
0072 layerQuartett[1]->sensorDirection();
0073
0074 Vector3 b2Aterm = layerQuartett[2]->sensorDirection() -
0075 (layerQuartett[2]->sensorDirection().dot(
0076 layerQuartett[1]->sensorDirection())) *
0077 layerQuartett[1]->sensorDirection();
0078 Vector3 b2Kterm = (layerQuartett[2]->sensorDirection().dot(
0079 layerQuartett[1]->sensorDirection())) *
0080 layerQuartett[1]->sensorDirection() -
0081 (layerQuartett[2]->sensorDirection().dot(
0082 layerQuartett[0]->sensorDirection())) *
0083 layerQuartett[0]->sensorDirection();
0084
0085
0086 double A = (layerQuartett[0]->localPosition().z() -
0087 layerQuartett[1]->localPosition().z());
0088 double G = (layerQuartett[0]->localPosition().z() -
0089 layerQuartett[2]->localPosition().z());
0090 double K = (layerQuartett[0]->localPosition().z() -
0091 layerQuartett[3]->localPosition().z());
0092
0093
0094 Vector3 b1 = A * b1Aterm + G * b1Gterm;
0095 Vector3 b2 = K * b2Kterm + A * b2Aterm;
0096
0097 bMatrix.col(0) = Vector2(b1.x(), b1.y());
0098 bMatrix.col(1) = Vector2(b2.x(), b2.y());
0099
0100 return bMatrix;
0101 }
0102
0103 template <Experimental::CompositeSpacePointPtr Point_t>
0104 std::array<double, 4> defineParameters(
0105 const SquareMatrix2& betaMatrix,
0106 const std::array<Point_t, 4>& layerQuartett) {
0107 double A = (layerQuartett[0]->localPosition().z() -
0108 layerQuartett[1]->localPosition().z());
0109 double G = (layerQuartett[0]->localPosition().z() -
0110 layerQuartett[2]->localPosition().z());
0111 double K = (layerQuartett[0]->localPosition().z() -
0112 layerQuartett[3]->localPosition().z());
0113
0114
0115 Vector3 y0 = K * (layerQuartett[2]->localPosition() -
0116 layerQuartett[0]->localPosition()) +
0117 G * (layerQuartett[0]->localPosition() -
0118 layerQuartett[3]->localPosition());
0119 Vector3 y1 = A * (layerQuartett[3]->localPosition() -
0120 layerQuartett[2]->localPosition()) +
0121 G * (layerQuartett[1]->localPosition() -
0122 layerQuartett[3]->localPosition()) +
0123 K * (layerQuartett[2]->localPosition() -
0124 layerQuartett[1]->localPosition());
0125 Vector3 y2 = (K - G) * (layerQuartett[0]->localPosition() -
0126 layerQuartett[1]->localPosition()) -
0127 (y1.dot(layerQuartett[1]->sensorDirection())) *
0128 layerQuartett[1]->sensorDirection() +
0129 (y0.dot(layerQuartett[0]->sensorDirection())) *
0130 layerQuartett[0]->sensorDirection() +
0131 A * (layerQuartett[3]->localPosition() -
0132 layerQuartett[2]->localPosition());
0133
0134 Vector2 solution = betaMatrix.inverse() * y2.block<2, 1>(0, 0);
0135 double kappa = solution.x();
0136 double gamma = solution.y();
0137
0138 double lambda = (y0.dot(layerQuartett[0]->sensorDirection()) +
0139 K * gamma *
0140 (layerQuartett[0]->sensorDirection().dot(
0141 layerQuartett[2]->sensorDirection())) -
0142 G * kappa *
0143 (layerQuartett[0]->sensorDirection().dot(
0144 layerQuartett[3]->sensorDirection()))) /
0145 (K - G);
0146 double alpha = (y1.dot(layerQuartett[1]->sensorDirection()) +
0147 (A - G) * kappa *
0148 layerQuartett[3]->sensorDirection().dot(
0149 layerQuartett[1]->sensorDirection()) +
0150 (K - A) * gamma *
0151 layerQuartett[2]->sensorDirection().dot(
0152 layerQuartett[1]->sensorDirection())) /
0153 (K - G);
0154
0155 return std::array<double, 4>({lambda, alpha, gamma, kappa});
0156 }
0157
0158 template <Experimental::CompositeSpacePointPtr Point_t>
0159 std::pair<Vector3, Vector3> seedSolution(
0160 const std::array<Point_t, 4>& layerQuartett,
0161 const std::array<double, 4>& parameters) {
0162
0163
0164 Vector3 seedPosition = layerQuartett[0]->localPosition() +
0165 parameters[0] * layerQuartett[0]->sensorDirection();
0166
0167
0168
0169 Vector3 seedDirection =
0170 ((layerQuartett[1]->localPosition() +
0171 parameters[1] * layerQuartett[1]->sensorDirection() - seedPosition))
0172 .normalized();
0173
0174
0175 Intersection3D intersectionZ0 = PlanarHelper::intersectPlane(
0176 seedPosition, seedDirection, Vector3::UnitZ(), 0.0);
0177 Vector3 seedPositionZ0 = intersectionZ0.position();
0178
0179 return std::make_pair(seedPositionZ0,
0180 copySign(seedDirection, seedDirection.z()));
0181 }
0182
0183 template <Experimental::CompositeSpacePointPtr Point_t>
0184 SquareMatrix2 betaMatrix(const std::array<Point_t, 3>& layerTriplet) {
0185 SquareMatrix2 bMatrix{SquareMatrix2::Identity()};
0186
0187
0188
0189 std::array<std::size_t, 3> indices = separateLayers(layerTriplet);
0190 Point_t spacePoint2D{layerTriplet[indices[2]]};
0191 std::array<Point_t, 2> spacePoints1D{layerTriplet[indices[0]],
0192 layerTriplet[indices[1]]};
0193
0194 double R =
0195 spacePoint2D->localPosition().z() - spacePoints1D[0]->localPosition().z();
0196 double L =
0197 spacePoint2D->localPosition().z() - spacePoints1D[1]->localPosition().z();
0198 double dotProd = spacePoints1D[0]->sensorDirection().dot(
0199 spacePoints1D[1]->sensorDirection());
0200
0201
0202 bMatrix.col(0) = Vector2(L, L * dotProd);
0203 bMatrix.col(1) = Vector2(-R * dotProd, -R);
0204
0205 return bMatrix;
0206 }
0207
0208 template <Experimental::CompositeSpacePointPtr Point_t>
0209 std::array<double, 2> defineParameters(
0210 const SquareMatrix2& betaMatrix,
0211 const std::array<Point_t, 3>& layerTriplet) {
0212 std::array<std::size_t, 3> indices = separateLayers(layerTriplet);
0213 const Point_t& spacePoint2D{layerTriplet[indices[2]]};
0214 std::array<Point_t, 2> spacePoints1D{layerTriplet[indices[0]],
0215 layerTriplet[indices[1]]};
0216
0217 const Vector3& M = spacePoint2D->localPosition();
0218 double R =
0219 spacePoint2D->localPosition().z() - spacePoints1D[0]->localPosition().z();
0220 double L =
0221 spacePoint2D->localPosition().z() - spacePoints1D[1]->localPosition().z();
0222
0223 Vector3 y = R * spacePoints1D[1]->localPosition() -
0224 L * spacePoints1D[0]->localPosition() + (L - R) * M;
0225 Vector2 y2 = {y.dot(spacePoints1D[0]->sensorDirection()),
0226 y.dot(spacePoints1D[1]->sensorDirection())};
0227
0228 Vector2 solution = betaMatrix.inverse() * y2.block<2, 1>(0, 0);
0229 double beta = solution.x();
0230 double delta = solution.y();
0231
0232 return std::array<double, 2>({beta, delta});
0233 }
0234
0235 template <Experimental::CompositeSpacePointPtr Point_t>
0236 std::pair<Vector3, Vector3> seedSolution(
0237 const std::array<Point_t, 3>& layerTriplet,
0238 const std::array<double, 2>& parameters) {
0239
0240 std::array<std::size_t, 3> indices = separateLayers(layerTriplet);
0241 Point_t spacePoint2D{layerTriplet[indices[2]]};
0242 std::array<Point_t, 2> spacePoints1D{layerTriplet[indices[0]],
0243 layerTriplet[indices[1]]};
0244
0245
0246 const Vector3& seedPosition = spacePoint2D->localPosition();
0247
0248 Vector3 seedDirection =
0249 (spacePoints1D[0]->localPosition() +
0250 parameters[0] * spacePoints1D[0]->sensorDirection() - seedPosition)
0251 .normalized();
0252
0253 Intersection3D intersectionZ0 = PlanarHelper::intersectPlane(
0254 seedPosition, seedDirection, Vector3::UnitZ(), 0.0);
0255 Vector3 seedPositionZ0 = intersectionZ0.position();
0256
0257 return std::make_pair(seedPositionZ0,
0258 copySign(seedDirection, seedDirection.z()));
0259 }
0260
0261 }