Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-28 07:45:41

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp"
0010 
0011 #include "Acts/Definitions/TrackParametrization.hpp"
0012 #include "Acts/Utilities/MathHelpers.hpp"
0013 
0014 Acts::FreeVector Acts::estimateTrackParamsFromSeed(const Vector3& sp0,
0015                                                    const Vector3& sp1,
0016                                                    const Vector3& sp2,
0017                                                    const Vector3& bField) {
0018   return estimateTrackParamsFromSeed(sp0, 0, sp1, sp2, bField);
0019 }
0020 
0021 Acts::FreeVector Acts::estimateTrackParamsFromSeed(const Vector3& sp0,
0022                                                    const double t0,
0023                                                    const Vector3& sp1,
0024                                                    const Vector3& sp2,
0025                                                    const Vector3& bField) {
0026   // Define a new coordinate frame with its origin at the bottom space point, z
0027   // axis long the magnetic field direction and y axis perpendicular to vector
0028   // from the bottom to middle space point. Hence, the projection of the middle
0029   // space point on the transverse plane will be located at the x axis of the
0030   // new frame.
0031   const Vector3 relVec = sp1 - sp0;
0032   const Vector3 newZAxis = bField.normalized();
0033   const Vector3 newYAxis = newZAxis.cross(relVec).normalized();
0034   const Vector3 newXAxis = newYAxis.cross(newZAxis);
0035   RotationMatrix3 rotation;
0036   rotation.col(0) = newXAxis;
0037   rotation.col(1) = newYAxis;
0038   rotation.col(2) = newZAxis;
0039   // The center of the new frame is at the bottom space point
0040   const Translation3 trans(sp0);
0041   // The transform which constructs the new frame
0042   const Transform3 transform(trans * rotation);
0043 
0044   // The coordinate of the middle and top space point in the new frame
0045   const Vector3 local1 = transform.inverse() * sp1;
0046   const Vector3 local2 = transform.inverse() * sp2;
0047 
0048   // Use the uv-plane to estimate the circle parameters
0049   const Vector2 uv1 = local1.head<2>() / local1.head<2>().squaredNorm();
0050   const Vector2 uv2 = local2.head<2>() / local2.head<2>().squaredNorm();
0051   const Vector2 deltaUV2 = uv2 - uv1;
0052   const double A = deltaUV2.y() / deltaUV2.x();
0053   const double bOverS =
0054       (uv1.y() * uv2.x() - uv2.y() * uv1.x()) / deltaUV2.norm();
0055 
0056   const double invTanTheta = local2.z() / local2.head<2>().norm();
0057   const Vector3 transDirection(1, A, fastHypot(1, A) * invTanTheta);
0058 
0059   // Transform it back to the original frame
0060   const Vector3 direction = rotation * transDirection.normalized();
0061 
0062   // Initialize the free parameters vector
0063   FreeVector params = FreeVector::Zero();
0064 
0065   // The bottom space point position
0066   params.segment<3>(eFreePos0) = sp0;
0067 
0068   // The estimated direction
0069   params.segment<3>(eFreeDir0) = direction;
0070 
0071   // The estimated q/pt in [GeV/c]^-1 (note that the pt is the projection of
0072   // momentum on the transverse plane of the new frame)
0073   const double qOverPt = 2 * bOverS / bField.norm();
0074   // The estimated q/p in [GeV/c]^-1
0075   params[eFreeQOverP] = qOverPt / fastHypot(1, invTanTheta);
0076 
0077   // The time parameter is set to the time of the bottom space point
0078   params[eFreeTime] = t0;
0079 
0080   return params;
0081 }
0082 
0083 Acts::Result<Acts::BoundVector> Acts::estimateTrackParamsFromSeed(
0084     const GeometryContext& gctx, const Surface& surface, const Vector3& sp0,
0085     const double t0, const Vector3& sp1, const Vector3& sp2,
0086     const Vector3& bField) {
0087   const FreeVector freeParams =
0088       estimateTrackParamsFromSeed(sp0, t0, sp1, sp2, bField);
0089   return transformFreeToBoundParameters(freeParams, surface, gctx);
0090 }
0091 
0092 Acts::BoundMatrix Acts::estimateTrackParamCovariance(
0093     const EstimateTrackParamCovarianceConfig& config, const BoundVector& params,
0094     bool hasTime) {
0095   assert((params[eBoundTheta] > 0 && params[eBoundTheta] < std::numbers::pi) &&
0096          "Theta must be in the range (0, pi)");
0097 
0098   BoundMatrix result = BoundMatrix::Zero();
0099 
0100   for (std::size_t i = eBoundLoc0; i < eBoundSize; ++i) {
0101     double sigma = config.initialSigmas[i];
0102     double variance = sigma * sigma;
0103 
0104     if (i == eBoundQOverP) {
0105       // note that we rely on the fact that sigma theta is already computed
0106       double varianceTheta = result(eBoundTheta, eBoundTheta);
0107 
0108       // contribution from sigma(q/pt)
0109       variance += std::pow(
0110           config.initialSigmaQoverPt * std::sin(params[eBoundTheta]), 2);
0111 
0112       // contribution from sigma(pt)/pt
0113       variance += std::pow(config.initialSigmaPtRel * params[eBoundQOverP], 2);
0114 
0115       // contribution from sigma(theta)
0116       variance +=
0117           varianceTheta *
0118           std::pow(params[eBoundQOverP] / std::tan(params[eBoundTheta]), 2);
0119     }
0120 
0121     if (i == eBoundTime && !hasTime) {
0122       // Inflate the time uncertainty if no time measurement is available
0123       variance *= config.noTimeVarInflation;
0124     }
0125 
0126     // Inflate the initial covariance
0127     variance *= config.initialVarInflation[i];
0128 
0129     result(i, i) = variance;
0130   }
0131 
0132   return result;
0133 }