ATLAS Offline Software
Loading...
Searching...
No Matches
CylinderUtils.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
5
6
7#include "Acts/Utilities/MathHelpers.hpp"
8#include "Acts/Definitions/Tolerance.hpp"
9#include "Acts/EventData/BoundTrackParameters.hpp"
10#include "Acts/Surfaces/CylinderSurface.hpp"
11#include "Acts/Surfaces/CylinderBounds.hpp"
12#include "Acts/Definitions/Units.hpp"
13
14#include "Acts/Utilities/detail/RealQuadraticEquation.hpp"
15
16using namespace Acts::UnitLiterals;
17namespace {
18 constexpr double halfLength = 7.5_m;
19}
20
21
22namespace ActsTrk {
23 std::array<double, 2>
25 const Amg::Vector3D& dir,
26 const double cylinderR) {
35 assert (cylinderR > 0.);
36 Acts::detail::RealQuadraticEquation solution{dir.block<2,1>(0,0).perp2(),
37 2.*pos.block<2,1>(0,0).dot(dir.block<2,1>(0,0)),
38 pos.block<2,1>(0,0).perp2() - Acts::square(cylinderR)};
39 switch(solution.solutions) {
40 case 2: {
41 auto ret = std::array{solution.first, solution.second};
42 if ((ret[1] > 0 && (ret[0] < 0 || ret[0] > ret[1])) ||
43 (ret[1] < 0 && (ret[0] < ret[1]))) {
44 std::swap(ret[0], ret[1]);
45 }
46 return ret;
47 } case 1:
48 return std::array{solution.first, std::numeric_limits<double>::max()};
49 default:
50 break;
51 }
52 return std::array<double , 2>{};
53 }
54 std::optional<Acts::BoundTrackParameters>
55 expressOnCylinder(const Acts::GeometryContext& tgContext,
56 const Acts::BoundTrackParameters& boundPars,
57 const double cylinderR,
58 const Acts::Direction dir) {
59
60 const Amg::Vector3D globDir = boundPars.direction();
61 const std::array paths{cylinderIntersectPaths(boundPars.position(tgContext),
62 globDir, cylinderR)};
65 const double solution = (dir == Acts::Direction::Forward() ? paths[0] :
66 paths[0] < 0 ? paths[0] : paths[1]);
68 if ( (solution < 0. && dir == Acts::Direction::Forward()) ||
69 (solution > 0. && dir == Acts::Direction::Backward())) {
70 return std::nullopt;
71 }
72 auto outSurface = Acts::Surface::makeShared<Acts::CylinderSurface>(Acts::Transform3::Identity(),
73 cylinderR, halfLength);
74 const Amg::Vector3D globPos = boundPars.position(tgContext) + solution * globDir;
75 const auto locPos = outSurface->globalToLocal(tgContext, globPos);
76 if (!locPos.ok()) {
77 return std::nullopt;
78 }
79 Acts::BoundVector outPars{boundPars.parameters()};
80 outPars[Acts::eBoundLoc0] = (*locPos)[Acts::eX];
81 outPars[Acts::eBoundLoc1] = (*locPos)[Acts::eY];
82 // In Acts units the speed of light is 1 -> just add the path length
83 outPars[Acts::eBoundTime] += solution;
84
85 std::optional<Acts::BoundMatrix> cov = boundPars.covariance();
86 // The covariance
87 if (cov && outSurface->type() != boundPars.referenceSurface().type()) {
88 const Acts::BoundMatrix trf = outSurface->freeToBoundJacobian(tgContext, globPos, globDir) *
89 boundPars.referenceSurface().boundToFreeJacobian(tgContext, globPos, globDir);
90 (*cov) = trf.transpose() * (*cov) * trf;
91 }
92 return Acts::BoundTrackParameters{outSurface, outPars, cov,
93 boundPars.particleHypothesis()};
94 }
95 std::vector<Acts::BoundTrackParameters>
96 expressOnCylinders(const Acts::GeometryContext& tgContext,
97 const Acts::BoundTrackParameters& boundPars,
98 std::span<const double> cylinderRadii,
99 const Acts::Direction dir) {
100 std::vector<Acts::BoundTrackParameters> result{};
101 result.reserve(cylinderRadii.size());
102 for (const auto radius : cylinderRadii) {
103 auto pars = expressOnCylinder(tgContext, result.empty() ? boundPars :
104 result.back(),
105 radius, dir);
106 if (pars) {
107 result.emplace_back(std::move(*pars));
108 }
109 }
110 std::ranges::sort(result, [](const Acts::BoundTrackParameters& a,
111 const Acts::BoundTrackParameters& b){
112 using enum Acts::CylinderBounds::BoundValues;
113 return static_cast<const Acts::CylinderBounds&>(a.referenceSurface().bounds()).get(eR) <
114 static_cast<const Acts::CylinderBounds&>(b.referenceSurface().bounds()).get(eR) ;
115 });
116 return result;
117 }
118}
Scalar perp2() const
perp2 method - perpendicular length squared
static Double_t a
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
std::vector< Acts::BoundTrackParameters > expressOnCylinders(const Acts::GeometryContext &tgContext, const Acts::BoundTrackParameters &boundPars, std::span< const double > cylinderRadii, const Acts::Direction dir=Acts::Direction::Forward())
Propgate the track parameters to a set of cylinders.
std::array< double, 2 > cylinderIntersectPaths(const Amg::Vector3D &pos, const Amg::Vector3D &dir, const double cylinderR)
Returns the two path lengths for a track state with position and direction to intersect the cylinder ...
std::optional< Acts::BoundTrackParameters > expressOnCylinder(const Acts::GeometryContext &tgContext, const Acts::BoundTrackParameters &boundPars, const double cylinderR, const Acts::Direction dir=Acts::Direction::Forward())
Propagates the track parameters to a cylinder with radius R and expresses them as bound track paramet...
Eigen::Matrix< double, 3, 1 > Vector3D
Definition dot.py:1
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)