EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SingleFreeTrackParameters.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SingleFreeTrackParameters.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019-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 
15 
16 #include <cassert>
17 #include <cmath>
18 #include <type_traits>
19 
20 namespace Acts {
21 
28 template <class charge_t>
30  public:
31  using Scalar = FreeScalar;
34 
47  std::optional<CovarianceMatrix> cov = std::nullopt)
48  : m_paramSet(std::move(cov), params), m_chargeInterpreter(std::abs(q)) {
49  assert((0 <= (params[eFreeQOverP] * q)) and "Inconsistent q/p and q signs");
50  }
51 
60  template <typename T = charge_t,
61  std::enable_if_t<std::is_default_constructible_v<T>, int> = 0>
63  std::optional<CovarianceMatrix> cov = std::nullopt)
64  : m_paramSet(std::move(cov), params), m_chargeInterpreter(T()) {}
65 
75  Scalar p, Scalar q,
76  std::optional<CovarianceMatrix> cov = std::nullopt)
77  : m_paramSet(std::move(cov), ParametersVector::Zero()),
78  m_chargeInterpreter(std::abs(q)) {
79  assert((0 <= p) and "Absolute momentum must be positive");
80 
81  m_paramSet.setParameter<eFreePos0>(pos4[ePos0]);
82  m_paramSet.setParameter<eFreePos1>(pos4[ePos1]);
83  m_paramSet.setParameter<eFreePos2>(pos4[ePos2]);
84  m_paramSet.setParameter<eFreeTime>(pos4[eTime]);
85  auto dir = makeDirectionUnitFromPhiTheta(phi, theta);
86  m_paramSet.setParameter<eFreeDir0>(dir[eMom0]);
87  m_paramSet.setParameter<eFreeDir1>(dir[eMom1]);
88  m_paramSet.setParameter<eFreeDir2>(dir[eMom2]);
89  m_paramSet.setParameter<eFreeQOverP>((q != Scalar(0)) ? (q / p) : (1 / p));
90  }
91 
102  template <typename T = charge_t,
103  std::enable_if_t<std::is_default_constructible_v<T>, int> = 0>
105  Scalar qOverP,
106  std::optional<CovarianceMatrix> cov = std::nullopt)
107  : m_paramSet(std::move(cov), ParametersVector::Zero()),
109  m_paramSet.setParameter<eFreePos0>(pos4[ePos0]);
110  m_paramSet.setParameter<eFreePos1>(pos4[ePos1]);
111  m_paramSet.setParameter<eFreePos2>(pos4[ePos2]);
112  m_paramSet.setParameter<eFreeTime>(pos4[eTime]);
113  auto dir = makeDirectionUnitFromPhiTheta(phi, theta);
114  m_paramSet.setParameter<eFreeDir0>(dir[eMom0]);
115  m_paramSet.setParameter<eFreeDir1>(dir[eMom1]);
116  m_paramSet.setParameter<eFreeDir2>(dir[eMom2]);
117  m_paramSet.setParameter<eFreeQOverP>(qOverP);
118  }
119 
120  // this class does not have a custom default constructor and thus should not
121  // provide any custom default cstors, dstor, or assignment. see ISOCPP C.20.
122 
124  ParametersVector parameters() const { return m_paramSet.getParameters(); }
126  const std::optional<CovarianceMatrix>& covariance() const {
127  return m_paramSet.getCovariance();
128  }
129 
133  template <FreeIndices kIndex>
134  Scalar get() const {
135  return m_paramSet.template getParameter<kIndex>();
136  }
142  template <FreeIndices kIndex>
143  Scalar uncertainty() const {
144  return m_paramSet.template getUncertainty<kIndex>();
145  }
146 
149  Vector4D pos4;
150  pos4[ePos0] = get<eFreePos0>();
151  pos4[ePos1] = get<eFreePos1>();
152  pos4[ePos2] = get<eFreePos2>();
153  pos4[eTime] = get<eFreeTime>();
154  return pos4;
155  }
157  Vector3D position() const {
158  return parameters().template segment<3>(eFreePos0);
159  }
161  Scalar time() const { return get<eFreeTime>(); }
162 
165  return parameters().template segment<3>(eFreeDir0).normalized();
166  }
169  return m_chargeInterpreter.extractMomentum(get<eFreeQOverP>());
170  }
173  // direction vector w/ arbitrary normalization can be parametrized as
174  // [f*sin(theta)*cos(phi), f*sin(theta)*sin(phi), f*cos(theta)]
175  // w/ f,sin(theta) positive, the transverse magnitude is then
176  // sqrt(f^2*sin^2(theta)) = f*sin(theta)
177  Scalar transverseMagnitude = std::hypot(get<eFreeDir0>(), get<eFreeDir1>());
178  // absolute magnitude is f by construction
179  Scalar magnitude = std::hypot(transverseMagnitude, get<eFreeDir2>());
180  // such that we can extract sin(theta) = f*sin(theta) / f
181  return (transverseMagnitude / magnitude) * absoluteMomentum();
182  }
185 
187  constexpr Scalar charge() const {
188  return m_chargeInterpreter.extractCharge(get<eFreeQOverP>());
189  }
190 
191  private:
193  // TODO use [[no_unique_address]] once we switch to C++20
195 
197  friend std::ostream& operator<<(std::ostream& os,
198  const SingleFreeTrackParameters& tp) {
200  os, tp.parameters(),
201  tp.covariance().has_value() ? &tp.covariance().value() : nullptr);
202  return os;
203  }
204 };
205 
206 } // namespace Acts