Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:00

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 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Utilities/Zip.hpp"
0017 
0018 #include <array>
0019 #include <optional>
0020 #include <stdexcept>
0021 
0022 namespace Acts {
0023 
0024 /// Estimate the full track parameters from three space points
0025 ///
0026 /// This method is based on the conformal map transformation. It estimates the
0027 /// full free track parameters, i.e. (x, y, z, t, dx, dy, dz, q/p) at the bottom
0028 /// space point. The bottom space is assumed to be the first element in the
0029 /// range defined by the iterators. The magnetic field (which might be along any
0030 /// direction) is also necessary for the momentum estimation.
0031 ///
0032 /// This is a purely spatial estimation, i.e. the time parameter will be set to
0033 /// 0.
0034 ///
0035 /// It resembles the method used in ATLAS for the track parameters estimated
0036 /// from seed, i.e. the function InDet::SiTrackMaker_xk::getAtaPlane here:
0037 /// https://acode-browser.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
0038 ///
0039 /// @tparam spacepoint_iterator_t  The type of space point iterator
0040 ///
0041 /// @param sp0 is the bottom space point
0042 /// @param sp1 is the middle space point
0043 /// @param sp2 is the top space point
0044 /// @param bField is the magnetic field vector
0045 ///
0046 /// @return the free parameters
0047 FreeVector estimateTrackParamsFromSeed(const Vector3& sp0, const Vector3& sp1,
0048                                        const Vector3& sp2,
0049                                        const Vector3& bField);
0050 
0051 /// Estimate the full track parameters from three space points
0052 ///
0053 /// This method is based on the conformal map transformation. It estimates the
0054 /// full free track parameters, i.e. (x, y, z, t, dx, dy, dz, q/p) at the bottom
0055 /// space point. The bottom space is assumed to be the first element in the
0056 /// range defined by the iterators. The magnetic field (which might be along any
0057 /// direction) is also necessary for the momentum estimation.
0058 ///
0059 /// It resembles the method used in ATLAS for the track parameters estimated
0060 /// from seed, i.e. the function InDet::SiTrackMaker_xk::getAtaPlane here:
0061 /// https://acode-browser.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
0062 ///
0063 /// @tparam spacepoint_iterator_t  The type of space point iterator
0064 ///
0065 /// @param spRange is the range of space points
0066 /// @param bField is the magnetic field vector
0067 ///
0068 /// @return the free parameters
0069 template <std::ranges::range spacepoint_range_t>
0070 FreeVector estimateTrackParamsFromSeed(spacepoint_range_t spRange,
0071                                        const Vector3& bField) {
0072   // Check the number of provided space points
0073   if (spRange.size() != 3) {
0074     throw std::invalid_argument(
0075         "There should be exactly three space points provided.");
0076   }
0077 
0078   // The global positions of the bottom, middle and space points
0079   std::array<Vector3, 3> spPositions = {Vector3::Zero(), Vector3::Zero(),
0080                                         Vector3::Zero()};
0081   std::array<std::optional<double>, 3> spTimes = {std::nullopt, std::nullopt,
0082                                                   std::nullopt};
0083   // The first, second and third space point are assumed to be bottom, middle
0084   // and top space point, respectively
0085   for (auto [sp, spPosition, spTime] :
0086        Acts::zip(spRange, spPositions, spTimes)) {
0087     if (sp == nullptr) {
0088       throw std::invalid_argument("Empty space point found.");
0089     }
0090     spPosition = Vector3(sp->x(), sp->y(), sp->z());
0091     spTime = sp->t();
0092   }
0093 
0094   FreeVector params = estimateTrackParamsFromSeed(
0095       spPositions[0], spPositions[1], spPositions[2], bField);
0096   params[eFreeTime] = spTimes[0].value_or(0);
0097   return params;
0098 }
0099 
0100 /// Estimate the full track parameters from three space points
0101 ///
0102 /// This method is based on the conformal map transformation. It estimates the
0103 /// full bound track parameters, i.e. (loc0, loc1, phi, theta, q/p, t) at the
0104 /// bottom space point. The bottom space is assumed to be the first element
0105 /// in the range defined by the iterators. It must lie on the surface provided
0106 /// for the representation of the bound track parameters. The magnetic field
0107 /// (which might be along any direction) is also necessary for the momentum
0108 /// estimation.
0109 ///
0110 /// It resembles the method used in ATLAS for the track parameters estimated
0111 /// from seed, i.e. the function InDet::SiTrackMaker_xk::getAtaPlane here:
0112 /// https://acode-browser.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
0113 ///
0114 /// @tparam spacepoint_iterator_t  The type of space point iterator
0115 ///
0116 /// @param gctx is the geometry context
0117 /// @param spRange is the range of space points
0118 /// @param surface is the surface of the bottom space point. The estimated bound
0119 /// track parameters will be represented also at this surface
0120 /// @param bField is the magnetic field vector
0121 ///
0122 /// @return bound parameters
0123 template <std::ranges::range spacepoint_range_t>
0124 Result<BoundVector> estimateTrackParamsFromSeed(const GeometryContext& gctx,
0125                                                 spacepoint_range_t spRange,
0126                                                 const Surface& surface,
0127                                                 const Vector3& bField) {
0128   FreeVector freeParams = estimateTrackParamsFromSeed(spRange, bField);
0129 
0130   const auto* sp0 = *spRange.begin();
0131   Vector3 origin = Vector3(sp0->x(), sp0->y(), sp0->z());
0132   Vector3 direction = freeParams.segment<3>(eFreeDir0);
0133 
0134   BoundVector params = BoundVector::Zero();
0135   params[eBoundPhi] = VectorHelpers::phi(direction);
0136   params[eBoundTheta] = VectorHelpers::theta(direction);
0137   params[eBoundQOverP] = freeParams[eFreeQOverP];
0138 
0139   // Transform the bottom space point to local coordinates of the provided
0140   // surface
0141   auto lpResult = surface.globalToLocal(gctx, origin, direction);
0142   if (!lpResult.ok()) {
0143     return Result<BoundVector>::failure(lpResult.error());
0144   }
0145   Vector2 bottomLocalPos = lpResult.value();
0146   // The estimated loc0 and loc1
0147   params[eBoundLoc0] = bottomLocalPos.x();
0148   params[eBoundLoc1] = bottomLocalPos.y();
0149   params[eBoundTime] = sp0->t().value_or(0);
0150 
0151   return Result<BoundVector>::success(params);
0152 }
0153 
0154 /// Configuration for the estimation of the covariance matrix of the track
0155 /// parameters with `estimateTrackParamCovariance`.
0156 struct EstimateTrackParamCovarianceConfig {
0157   /// The initial sigmas for the track parameters
0158   BoundVector initialSigmas = {1. * UnitConstants::mm,
0159                                1. * UnitConstants::mm,
0160                                1. * UnitConstants::degree,
0161                                1. * UnitConstants::degree,
0162                                1. * UnitConstants::e / UnitConstants::GeV,
0163                                1. * UnitConstants::ns};
0164 
0165   /// The initial relative uncertainty of the q/pt
0166   double initialSigmaPtRel = 0.1;
0167 
0168   /// The inflation factors for the variances of the track parameters
0169   BoundVector initialVarInflation = {1., 1., 1., 1., 1., 1.};
0170   /// The inflation factor for time uncertainty if the time parameter was not
0171   /// estimated
0172   double noTimeVarInflation = 100.;
0173 };
0174 
0175 /// Estimate the covariance matrix of the given track parameters based on the
0176 /// provided configuration. The assumption is that we can model the uncertainty
0177 /// of the track parameters as a diagonal matrix with the provided initial
0178 /// sigmas. The inflation factors are used to inflate the initial variances
0179 /// based on the provided configuration. The uncertainty of q/p is estimated
0180 /// based on the relative uncertainty of the q/pt and the theta uncertainty.
0181 ///
0182 /// @param config is the configuration for the estimation
0183 /// @param params is the track parameters
0184 /// @param hasTime is true if the track parameters have time
0185 ///
0186 /// @return the covariance matrix of the track parameters
0187 BoundMatrix estimateTrackParamCovariance(
0188     const EstimateTrackParamCovarianceConfig& config, const BoundVector& params,
0189     bool hasTime);
0190 
0191 }  // namespace Acts