ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UnitVectors.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file UnitVectors.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
11 #include <cmath>
12 #include <limits>
13 #include <utility>
14 
16 
17 namespace Acts {
18 
28 template <typename T>
30  const auto coshEta = std::cosh(eta);
31  const auto tanhEta = std::tanh(eta);
32  return {
33  std::cos(phi) / coshEta,
34  std::sin(phi) / coshEta,
35  std::tanh(eta),
36  };
37 }
38 
48 template <typename T>
50  const auto cosTheta = std::cos(theta);
51  const auto sinTheta = std::sin(theta);
52  return {
53  std::cos(phi) * sinTheta,
54  std::sin(phi) * sinTheta,
55  cosTheta,
56  };
57 }
58 
66 template <typename InputVector>
68  const Eigen::MatrixBase<InputVector>& direction) {
69  EIGEN_STATIC_ASSERT_FIXED_SIZE(InputVector);
70  EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector);
71  static_assert(3 <= InputVector::RowsAtCompileTime,
72  "Direction vector must be at least three-dimensional.");
73 
74  using OutputVector = typename InputVector::PlainObject;
75  using OutputScalar = typename InputVector::Scalar;
76 
77  OutputVector unitU = OutputVector::Zero();
78  // explicit version of U = Z x T
79  unitU[0] = -direction[1];
80  unitU[1] = direction[0];
81  const auto scale = unitU.template head<2>().norm();
82  // if the absolute scale is tiny, the initial direction vector is aligned with
83  // the z-axis. the ZxT product is ill-defined since any vector in the x-y
84  // plane would be orthogonal to the direction. fix the U unit vector along the
85  // x-axis to avoid this numerical instability.
87  unitU[0] = 1;
88  unitU[1] = 0;
89  } else {
90  unitU.template head<2>() /= scale;
91  }
92  return unitU;
93 }
94 
108 template <typename InputVector>
110  const Eigen::MatrixBase<InputVector>& direction) {
111  EIGEN_STATIC_ASSERT_FIXED_SIZE(InputVector);
112  EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector);
113  static_assert(3 <= InputVector::RowsAtCompileTime,
114  "Direction vector must be at least three-dimensional.");
115 
116  using OutputVector = typename InputVector::PlainObject;
117 
118  std::pair<OutputVector, OutputVector> unitVectors;
119  unitVectors.first = makeCurvilinearUnitU(direction);
120  unitVectors.second = direction.cross(unitVectors.first);
121  unitVectors.second.normalize();
122  return unitVectors;
123 }
124 
125 } // namespace Acts