Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Charge.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Charge.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 
14 
15 #include <cassert>
16 #include <cmath>
17 
18 namespace Acts {
19 
53 
55 struct Neutral {
56  constexpr Neutral() = default;
57 
58  // TODO remove this method after grad refactor; currently track parameters
59  // depend on it
63  constexpr Neutral(float absQ) noexcept {
64  assert((absQ == 0) and "Input charge must be zero");
65  (void)absQ;
66  }
67 
68  constexpr float absQ() const noexcept { return 0; }
69 
70  template <typename T>
71  constexpr auto extractCharge(T /*qOverP*/) const noexcept {
72  return 0.0f;
73  }
74 
75  template <typename T>
76  constexpr auto extractMomentum(T qOverP) const noexcept {
77  assert(qOverP >= 0 && "qOverP cannot be negative");
78  return 1.0f / qOverP;
79  }
80 
81  template <typename P, typename Q>
82  constexpr auto qOverP(P momentum, Q signedQ) const noexcept {
83  assert((signedQ != 0) and "charge must be 0");
84  (void)signedQ;
85  return 1.0f / momentum;
86  }
87 
92  friend constexpr bool operator==(Neutral /*lhs*/, Neutral /*rhs*/) noexcept {
93  return true;
94  }
95 };
96 
97 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, Neutral);
98 
101  constexpr SinglyCharged() = default;
102 
103  // TODO remove this method after grad refactor; currently track parameters
104  // depend on it
108  constexpr SinglyCharged(float absQ) noexcept {
109  assert((absQ == UnitConstants::e) and "Input charge magnitude must be e");
110  (void)absQ;
111  }
112 
113  constexpr float absQ() const noexcept { return UnitConstants::e; }
114 
115  template <typename T>
116  constexpr auto extractCharge(T qOverP) const noexcept {
117  // using because of autodiff
118  using std::copysign;
120  }
121 
122  template <typename T>
123  constexpr auto extractMomentum(T qOverP) const noexcept {
124  // using because of autodiff
125  using std::abs;
126  return extractCharge(qOverP) / qOverP;
127  }
128 
129  template <typename P, typename Q>
130  constexpr auto qOverP(P momentum, Q signedQ) const noexcept {
131  using std::abs;
132  assert((abs(signedQ) == UnitConstants::e) && "absolute charge must be e");
133  return signedQ / momentum;
134  }
135 
140  friend constexpr bool operator==(SinglyCharged /*lhs*/,
141  SinglyCharged /*rhs*/) noexcept {
142  return true;
143  }
144 };
145 
146 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, SinglyCharged);
147 
151  public:
153  constexpr NonNeutralCharge(float absQ) noexcept : m_absQ{absQ} {
154  assert((0 < absQ) and "Input charge magnitude must be positive");
155  }
156  constexpr NonNeutralCharge(SinglyCharged /*unused*/) noexcept
157  : m_absQ{UnitConstants::e} {}
158 
159  constexpr float absQ() const noexcept { return m_absQ; }
160 
161  template <typename T>
162  constexpr auto extractCharge(T qOverP) const noexcept {
163  // using because of autodiff
164  using std::copysign;
165  return copysign(m_absQ, qOverP);
166  }
167  template <typename T>
168  constexpr auto extractMomentum(T qOverP) const noexcept {
169  // using because of autodiff
170  using std::abs;
171  return extractCharge(qOverP) / qOverP;
172  }
173 
174  template <typename P, typename Q>
175  constexpr auto qOverP(P momentum, Q signedQ) const noexcept {
176  // using because of autodiff
177  using std::abs;
178  assert(abs(signedQ) == m_absQ && "inconsistent charge");
179  return signedQ / momentum;
180  }
181 
183  friend constexpr bool operator==(NonNeutralCharge lhs,
184  NonNeutralCharge rhs) noexcept {
185  return lhs.m_absQ == rhs.m_absQ;
186  }
187 
188  private:
189  float m_absQ{};
190 };
191 
192 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, NonNeutralCharge);
193 
199 class AnyCharge {
200  public:
202  constexpr AnyCharge(float absQ) noexcept : m_absQ{absQ} {
203  assert((0 <= absQ) and "Input charge magnitude must be zero or positive");
204  }
205  constexpr AnyCharge(SinglyCharged /*unused*/) noexcept
206  : m_absQ{UnitConstants::e} {}
207  constexpr AnyCharge(Neutral /*unused*/) noexcept {}
208 
209  constexpr float absQ() const noexcept { return m_absQ; }
210 
211  template <typename T>
212  constexpr auto extractCharge(T qOverP) const noexcept {
213  // using because of autodiff
214  using std::copysign;
215  return copysign(m_absQ, qOverP);
216  }
217  template <typename T>
218  constexpr auto extractMomentum(T qOverP) const noexcept {
219  // using because of autodiff
220  using std::abs;
221  return (m_absQ != 0.0f) ? extractCharge(qOverP) / qOverP : 1.0f / qOverP;
222  }
223 
224  template <typename P, typename Q>
225  constexpr auto qOverP(P momentum, Q signedQ) const noexcept {
226  // using because of autodiff
227  using std::abs;
228  assert(abs(signedQ) == m_absQ && "inconsistent charge");
229  return (m_absQ != 0.0f) ? signedQ / momentum : 1.0f / momentum;
230  }
231 
233  friend constexpr bool operator==(AnyCharge lhs, AnyCharge rhs) noexcept {
234  return lhs.m_absQ == rhs.m_absQ;
235  }
236 
237  private:
238  float m_absQ{};
239 };
240 
241 ACTS_STATIC_CHECK_CONCEPT(ChargeConcept, AnyCharge);
242 
244 
245 } // namespace Acts