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 
12 
13 #include <cmath>
14 #include <limits>
15 #include <utility>
16 
17 namespace Acts {
18 
28 template <typename T>
30  const auto coshEtaInv = 1 / std::cosh(eta);
31  return {
32  std::cos(phi) * coshEtaInv,
33  std::sin(phi) * coshEtaInv,
34  std::tanh(eta),
35  };
36 }
37 
47 template <typename T>
49  const auto cosTheta = std::cos(theta);
50  const auto sinTheta = std::sin(theta);
51  return {
52  std::cos(phi) * sinTheta,
53  std::sin(phi) * sinTheta,
54  cosTheta,
55  };
56 }
57 
65 template <typename InputVector>
67  const Eigen::MatrixBase<InputVector>& direction) {
68  EIGEN_STATIC_ASSERT_FIXED_SIZE(InputVector);
69  EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector);
70  static_assert(3 <= InputVector::RowsAtCompileTime,
71  "Direction vector must be at least three-dimensional.");
72 
73  using OutputVector = typename InputVector::PlainObject;
74  using OutputScalar = typename InputVector::Scalar;
75 
76  OutputVector unitU = OutputVector::Zero();
77  // explicit version of U = Z x T
78  unitU[0] = -direction[1];
79  unitU[1] = direction[0];
80  const auto scale = unitU.template head<2>().norm();
81  // if the absolute scale is tiny, the initial direction vector is aligned with
82  // the z-axis. the ZxT product is ill-defined since any vector in the x-y
83  // plane would be orthogonal to the direction. fix the U unit vector along the
84  // x-axis to avoid this numerical instability.
85  if (scale < (16 * std::numeric_limits<OutputScalar>::epsilon())) {
86  unitU[0] = 1;
87  unitU[1] = 0;
88  } else {
89  unitU.template head<2>() /= scale;
90  }
91  return unitU;
92 }
93 
107 template <typename InputVector>
109  const Eigen::MatrixBase<InputVector>& direction) {
110  EIGEN_STATIC_ASSERT_FIXED_SIZE(InputVector);
111  EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputVector);
112  static_assert(3 <= InputVector::RowsAtCompileTime,
113  "Direction vector must be at least three-dimensional.");
114 
115  using OutputVector = typename InputVector::PlainObject;
116 
117  std::pair<OutputVector, OutputVector> unitVectors;
118  unitVectors.first = makeCurvilinearUnitU(direction);
119  unitVectors.second = direction.cross(unitVectors.first);
120  unitVectors.second.normalize();
121  return unitVectors;
122 }
123 
124 } // namespace Acts