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