File indexing completed on 2025-01-18 09:11:31
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 * sin(theta * 0.5));
0116 double sigma_y = sigma / (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 / globalPos.head<2>().norm();
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 SquareMatrix2 jac = jacXyzToRhoZ * rotLocalToGlobal.block<3, 2>(ePos0, ePos0);
0148
0149 Vector2 var = (jac * localCov * jac.transpose()).diagonal();
0150
0151 auto gcov = Vector2(var[0], var[1]);
0152
0153 return gcov;
0154 }
0155
0156 Result<void> SpacePointUtility::calculateStripSPPosition(
0157 const std::pair<Vector3, Vector3>& stripEnds1,
0158 const std::pair<Vector3, Vector3>& stripEnds2, const Vector3& posVertex,
0159 SpacePointParameters& spParams, const double stripLengthTolerance) const {
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 spParams.firstBtmToTop = stripEnds1.first - stripEnds1.second;
0182 spParams.secondBtmToTop = stripEnds2.first - stripEnds2.second;
0183 spParams.vtxToFirstMid2 =
0184 stripEnds1.first + stripEnds1.second - 2 * posVertex;
0185 spParams.vtxToSecondMid2 =
0186 stripEnds2.first + stripEnds2.second - 2 * posVertex;
0187 spParams.firstBtmToTopXvtxToFirstMid2 =
0188 spParams.firstBtmToTop.cross(spParams.vtxToFirstMid2);
0189 spParams.secondBtmToTopXvtxToSecondMid2 =
0190 spParams.secondBtmToTop.cross(spParams.vtxToSecondMid2);
0191 spParams.m =
0192 -spParams.vtxToFirstMid2.dot(spParams.secondBtmToTopXvtxToSecondMid2) /
0193 spParams.firstBtmToTop.dot(spParams.secondBtmToTopXvtxToSecondMid2);
0194 spParams.n =
0195 -spParams.vtxToSecondMid2.dot(spParams.firstBtmToTopXvtxToFirstMid2) /
0196 spParams.secondBtmToTop.dot(spParams.firstBtmToTopXvtxToFirstMid2);
0197
0198
0199 if (spParams.limit == 1. && stripLengthTolerance != 0.) {
0200 spParams.limit = 1. + stripLengthTolerance;
0201 }
0202
0203
0204 if (std::abs(spParams.m) <= spParams.limit &&
0205 std::abs(spParams.n) <= spParams.limit) {
0206 return Result<void>::success();
0207 }
0208 return Result<void>::failure(m_error);
0209 }
0210
0211 Result<void> SpacePointUtility::recoverSpacePoint(
0212 SpacePointParameters& spParams, double stripLengthGapTolerance) const {
0213
0214
0215 if (stripLengthGapTolerance <= 0.) {
0216 return Result<void>::failure(m_error);
0217 }
0218
0219 spParams.mag_firstBtmToTop = spParams.firstBtmToTop.norm();
0220
0221
0222 spParams.limitExtended =
0223 spParams.limit + stripLengthGapTolerance / spParams.mag_firstBtmToTop;
0224
0225
0226 if (std::abs(spParams.m) > spParams.limitExtended) {
0227 return Result<void>::failure(m_error);
0228 }
0229
0230 if (spParams.n == 0.) {
0231 spParams.n =
0232 -spParams.vtxToSecondMid2.dot(spParams.firstBtmToTopXvtxToFirstMid2) /
0233 spParams.secondBtmToTop.dot(spParams.firstBtmToTopXvtxToFirstMid2);
0234 }
0235
0236 if (std::abs(spParams.n) > spParams.limitExtended) {
0237 return Result<void>::failure(m_error);
0238 }
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 double secOnFirstScale =
0260 spParams.firstBtmToTop.dot(spParams.secondBtmToTop) /
0261 (spParams.mag_firstBtmToTop * spParams.mag_firstBtmToTop);
0262
0263 if (spParams.m > 1. && spParams.n > 1.) {
0264
0265 double mOvershoot = spParams.m - 1.;
0266 double nOvershoot =
0267 (spParams.n - 1.) * secOnFirstScale;
0268
0269 double biggerOvershoot = std::max(mOvershoot, nOvershoot);
0270
0271 spParams.m -= biggerOvershoot;
0272 spParams.n -= (biggerOvershoot / secOnFirstScale);
0273
0274
0275 if (std::abs(spParams.m) < spParams.limit &&
0276 std::abs(spParams.n) < spParams.limit) {
0277 return Result<void>::success();
0278 } else {
0279 return Result<void>::failure(m_error);
0280 }
0281 }
0282
0283 if (spParams.m < -1. && spParams.n < -1.) {
0284
0285 double mOvershoot = -(spParams.m + 1.);
0286 double nOvershoot =
0287 -(spParams.n + 1.) * secOnFirstScale;
0288
0289 double biggerOvershoot = std::max(mOvershoot, nOvershoot);
0290
0291 spParams.m += biggerOvershoot;
0292 spParams.n += (biggerOvershoot / secOnFirstScale);
0293
0294 if (std::abs(spParams.m) < spParams.limit &&
0295 std::abs(spParams.n) < spParams.limit) {
0296 return Result<void>::success();
0297 }
0298 }
0299
0300 return Result<void>::failure(m_error);
0301 }
0302
0303 Result<double> SpacePointUtility::calcPerpendicularProjection(
0304 const std::pair<Vector3, Vector3>& stripEnds1,
0305 const std::pair<Vector3, Vector3>& stripEnds2,
0306 SpacePointParameters& spParams) const {
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318 spParams.firstBtmToTop = stripEnds1.first - stripEnds1.second;
0319 spParams.secondBtmToTop = stripEnds2.first - stripEnds2.second;
0320
0321 Vector3 ac = stripEnds2.first - stripEnds1.first;
0322 double qr = (spParams.firstBtmToTop).dot(spParams.secondBtmToTop);
0323 double denom = spParams.firstBtmToTop.dot(spParams.firstBtmToTop) - qr * qr;
0324
0325 if (std::abs(denom) > 1e-6) {
0326
0327 return Result<double>::success(
0328 (ac.dot(spParams.secondBtmToTop) * qr -
0329 ac.dot(spParams.firstBtmToTop) *
0330 (spParams.secondBtmToTop).dot(spParams.secondBtmToTop)) /
0331 denom);
0332 }
0333 return Result<double>::failure(m_error);
0334 }
0335
0336 }