File indexing completed on 2025-12-16 09:23:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Utilities/SpacePointUtility.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/EventData/SourceLink.hpp"
0014 #include "Acts/Geometry/TrackingGeometry.hpp"
0015 #include "Acts/SpacePointFormation/SpacePointBuilderOptions.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/Helpers.hpp"
0018 #include "Acts/Utilities/MathHelpers.hpp"
0019
0020 #include <algorithm>
0021 #include <cmath>
0022 #include <memory>
0023
0024 namespace Acts {
0025
0026 Result<double> SpacePointUtility::differenceOfMeasurementsChecked(
0027 const Vector3& pos1, const Vector3& pos2, const Vector3& posVertex,
0028 const double maxDistance, const double maxAngleTheta2,
0029 const double maxAnglePhi2) const {
0030
0031 if ((pos1 - pos2).norm() > maxDistance) {
0032 return Result<double>::failure(m_error);
0033 }
0034
0035
0036 double phi1 = VectorHelpers::phi(pos1 - posVertex);
0037 double theta1 = VectorHelpers::theta(pos1 - posVertex);
0038 double phi2 = VectorHelpers::phi(pos2 - posVertex);
0039 double theta2 = VectorHelpers::theta(pos2 - posVertex);
0040
0041 double diffTheta2 = (theta1 - theta2) * (theta1 - theta2);
0042 if (diffTheta2 > maxAngleTheta2) {
0043 return Result<double>::failure(m_error);
0044 }
0045
0046 double diffPhi2 = (phi1 - phi2) * (phi1 - phi2);
0047 if (diffPhi2 > maxAnglePhi2) {
0048 return Result<double>::failure(m_error);
0049 }
0050
0051 return Result<double>::success(diffTheta2 + diffPhi2);
0052 }
0053
0054 std::tuple<Vector3, std::optional<double>, Vector2, std::optional<double>>
0055 SpacePointUtility::globalCoords(
0056 const GeometryContext& gctx, const SourceLink& slink,
0057 const SourceLinkSurfaceAccessor& surfaceAccessor, const BoundVector& par,
0058 const BoundSquareMatrix& cov) const {
0059 const Surface* surface = surfaceAccessor(slink);
0060 Vector2 localPos(par[eBoundLoc0], par[eBoundLoc1]);
0061 SquareMatrix2 localCov = cov.block<2, 2>(eBoundLoc0, eBoundLoc0);
0062 Vector3 globalPos = surface->localToGlobal(gctx, localPos, Vector3());
0063 RotationMatrix3 rotLocalToGlobal =
0064 surface->referenceFrame(gctx, globalPos, Vector3());
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 auto x = globalPos[ePos0];
0078 auto y = globalPos[ePos1];
0079 auto scale = 2 / fastHypot(x, y);
0080 ActsMatrix<2, 3> jacXyzToRhoZ = ActsMatrix<2, 3>::Zero();
0081 jacXyzToRhoZ(0, ePos0) = scale * x;
0082 jacXyzToRhoZ(0, ePos1) = scale * y;
0083 jacXyzToRhoZ(1, ePos2) = 1;
0084
0085 SquareMatrix2 jac = jacXyzToRhoZ * rotLocalToGlobal.block<3, 2>(ePos0, ePos0);
0086
0087 Vector2 var = (jac * localCov * jac.transpose()).diagonal();
0088
0089 auto gcov = Vector2(var[0], var[1]);
0090
0091
0092
0093
0094 std::optional<double> globalTime = par[eBoundTime];
0095 std::optional<double> tcov = cov(eBoundTime, eBoundTime);
0096 if (tcov.value() <= 0) {
0097 globalTime = std::nullopt;
0098 tcov = std::nullopt;
0099 }
0100
0101 return {globalPos, globalTime, gcov, tcov};
0102 }
0103
0104 Vector2 SpacePointUtility::calcRhoZVars(
0105 const GeometryContext& gctx, const SourceLink& slinkFront,
0106 const SourceLink& slinkBack,
0107 const SourceLinkSurfaceAccessor& surfaceAccessor,
0108 const ParamCovAccessor& paramCovAccessor, const Vector3& globalPos,
0109 const double theta) const {
0110 const auto var1 = paramCovAccessor(slinkFront).second(0, 0);
0111 const auto var2 = paramCovAccessor(slinkBack).second(0, 0);
0112
0113
0114 double sigma = fastHypot(var1, var2);
0115 double sigma_x = sigma / (2 * std::sin(theta * 0.5));
0116 double sigma_y = sigma / (2 * std::cos(theta * 0.5));
0117
0118
0119 double sig_x1 =
0120 sigma_x * std::cos(0.5 * theta) + sigma_y * std::sin(0.5 * theta);
0121 double sig_y1 =
0122 sigma_y * std::cos(0.5 * theta) + sigma_x * std::sin(0.5 * theta);
0123 SquareMatrix2 lcov;
0124 lcov << sig_x1, 0, 0, sig_y1;
0125
0126 const Surface& surface = *surfaceAccessor(slinkFront);
0127
0128 auto gcov = rhoZCovariance(gctx, surface, globalPos, lcov);
0129 return gcov;
0130 }
0131
0132 Vector2 SpacePointUtility::rhoZCovariance(const GeometryContext& gctx,
0133 const Surface& surface,
0134 const Vector3& globalPos,
0135 const SquareMatrix2& localCov) const {
0136 Vector3 globalFakeMom(1, 1, 1);
0137
0138 RotationMatrix3 rotLocalToGlobal =
0139 surface.referenceFrame(gctx, globalPos, globalFakeMom);
0140
0141 auto x = globalPos[ePos0];
0142 auto y = globalPos[ePos1];
0143 auto scale = 2 / globalPos.head<2>().norm();
0144 ActsMatrix<2, 3> jacXyzToRhoZ = ActsMatrix<2, 3>::Zero();
0145 jacXyzToRhoZ(0, ePos0) = scale * x;
0146 jacXyzToRhoZ(0, ePos1) = scale * y;
0147 jacXyzToRhoZ(1, ePos2) = 1;
0148
0149 SquareMatrix2 jac = jacXyzToRhoZ * rotLocalToGlobal.block<3, 2>(ePos0, ePos0);
0150
0151 Vector2 var = (jac * localCov * jac.transpose()).diagonal();
0152
0153 auto gcov = Vector2(var[0], var[1]);
0154
0155 return gcov;
0156 }
0157
0158 Result<void> SpacePointUtility::calculateStripSPPosition(
0159 const std::pair<Vector3, Vector3>& stripEnds1,
0160 const std::pair<Vector3, Vector3>& stripEnds2, const Vector3& posVertex,
0161 SpacePointParameters& spParams, const double stripLengthTolerance) const {
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 spParams.firstBtmToTop = stripEnds1.first - stripEnds1.second;
0184 spParams.secondBtmToTop = stripEnds2.first - stripEnds2.second;
0185 spParams.vtxToFirstMid2 =
0186 stripEnds1.first + stripEnds1.second - 2 * posVertex;
0187 spParams.vtxToSecondMid2 =
0188 stripEnds2.first + stripEnds2.second - 2 * posVertex;
0189 spParams.firstBtmToTopXvtxToFirstMid2 =
0190 spParams.firstBtmToTop.cross(spParams.vtxToFirstMid2);
0191 spParams.secondBtmToTopXvtxToSecondMid2 =
0192 spParams.secondBtmToTop.cross(spParams.vtxToSecondMid2);
0193 spParams.m =
0194 -spParams.vtxToFirstMid2.dot(spParams.secondBtmToTopXvtxToSecondMid2) /
0195 spParams.firstBtmToTop.dot(spParams.secondBtmToTopXvtxToSecondMid2);
0196 spParams.n =
0197 -spParams.vtxToSecondMid2.dot(spParams.firstBtmToTopXvtxToFirstMid2) /
0198 spParams.secondBtmToTop.dot(spParams.firstBtmToTopXvtxToFirstMid2);
0199
0200
0201 if (spParams.limit == 1. && stripLengthTolerance != 0.) {
0202 spParams.limit = 1. + stripLengthTolerance;
0203 }
0204
0205
0206 if (std::abs(spParams.m) <= spParams.limit &&
0207 std::abs(spParams.n) <= spParams.limit) {
0208 return Result<void>::success();
0209 }
0210 return Result<void>::failure(m_error);
0211 }
0212
0213 Result<void> SpacePointUtility::recoverSpacePoint(
0214 SpacePointParameters& spParams, double stripLengthGapTolerance) const {
0215
0216
0217 if (stripLengthGapTolerance <= 0.) {
0218 return Result<void>::failure(m_error);
0219 }
0220
0221 spParams.mag_firstBtmToTop = spParams.firstBtmToTop.norm();
0222
0223
0224 spParams.limitExtended =
0225 spParams.limit + stripLengthGapTolerance / spParams.mag_firstBtmToTop;
0226
0227
0228 if (std::abs(spParams.m) > spParams.limitExtended) {
0229 return Result<void>::failure(m_error);
0230 }
0231
0232 if (spParams.n == 0.) {
0233 spParams.n =
0234 -spParams.vtxToSecondMid2.dot(spParams.firstBtmToTopXvtxToFirstMid2) /
0235 spParams.secondBtmToTop.dot(spParams.firstBtmToTopXvtxToFirstMid2);
0236 }
0237
0238 if (std::abs(spParams.n) > spParams.limitExtended) {
0239 return Result<void>::failure(m_error);
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261 double secOnFirstScale =
0262 spParams.firstBtmToTop.dot(spParams.secondBtmToTop) /
0263 (spParams.mag_firstBtmToTop * spParams.mag_firstBtmToTop);
0264
0265 if (spParams.m > 1. && spParams.n > 1.) {
0266
0267 double mOvershoot = spParams.m - 1.;
0268 double nOvershoot =
0269 (spParams.n - 1.) * secOnFirstScale;
0270
0271 double biggerOvershoot = std::max(mOvershoot, nOvershoot);
0272
0273 spParams.m -= biggerOvershoot;
0274 spParams.n -= (biggerOvershoot / secOnFirstScale);
0275
0276
0277 if (std::abs(spParams.m) < spParams.limit &&
0278 std::abs(spParams.n) < spParams.limit) {
0279 return Result<void>::success();
0280 } else {
0281 return Result<void>::failure(m_error);
0282 }
0283 }
0284
0285 if (spParams.m < -1. && spParams.n < -1.) {
0286
0287 double mOvershoot = -(spParams.m + 1.);
0288 double nOvershoot =
0289 -(spParams.n + 1.) * secOnFirstScale;
0290
0291 double biggerOvershoot = std::max(mOvershoot, nOvershoot);
0292
0293 spParams.m += biggerOvershoot;
0294 spParams.n += (biggerOvershoot / secOnFirstScale);
0295
0296 if (std::abs(spParams.m) < spParams.limit &&
0297 std::abs(spParams.n) < spParams.limit) {
0298 return Result<void>::success();
0299 }
0300 }
0301
0302 return Result<void>::failure(m_error);
0303 }
0304
0305 Result<double> SpacePointUtility::calcPerpendicularProjection(
0306 const std::pair<Vector3, Vector3>& stripEnds1,
0307 const std::pair<Vector3, Vector3>& stripEnds2,
0308 SpacePointParameters& spParams) const {
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320 spParams.firstBtmToTop = stripEnds1.first - stripEnds1.second;
0321 spParams.secondBtmToTop = stripEnds2.first - stripEnds2.second;
0322
0323 Vector3 ac = stripEnds2.first - stripEnds1.first;
0324 double qr = (spParams.firstBtmToTop).dot(spParams.secondBtmToTop);
0325 double denom = spParams.firstBtmToTop.dot(spParams.firstBtmToTop) - qr * qr;
0326
0327 if (std::abs(denom) > 1e-6) {
0328
0329 return Result<double>::success(
0330 (ac.dot(spParams.secondBtmToTop) * qr -
0331 ac.dot(spParams.firstBtmToTop) *
0332 (spParams.secondBtmToTop).dot(spParams.secondBtmToTop)) /
0333 denom);
0334 }
0335 return Result<double>::failure(m_error);
0336 }
0337
0338 }