Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Particle.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Particle.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-2021 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 
22 
23 #include <algorithm>
24 #include <cmath>
25 #include <iosfwd>
26 #include <limits>
27 #include <memory>
28 #include <optional>
29 
30 namespace ActsFatras {
31 
35 class Particle {
36  public:
40 
42  Particle() = default;
53  Scalar mass)
54  : m_particleId(particleId), m_pdg(pdg), m_charge(charge), m_mass(mass) {}
62  Particle(const Particle &) = default;
63  Particle(Particle &&) = default;
64  Particle &operator=(const Particle &) = default;
65  Particle &operator=(Particle &&) = default;
66 
73  Particle p = *this;
75  return p;
76  }
77 
80  m_process = proc;
81  return *this;
82  }
85  m_pdg = pdg;
86  return *this;
87  }
90  m_charge = charge;
91  return *this;
92  }
95  m_mass = mass;
96  return *this;
97  }
100  m_particleId = barcode;
101  return *this;
102  }
105  m_position4 = pos4;
106  return *this;
107  }
110  m_position4.segment<3>(Acts::ePos0) = position;
112  return *this;
113  }
120  return *this;
121  }
125  m_direction.normalize();
126  return *this;
127  }
130  m_direction[Acts::ePos0] = dx;
133  m_direction.normalize();
134  return *this;
135  }
139  return *this;
140  }
141 
148  const auto newEnergy = std::hypot(m_mass, m_absMomentum) + delta;
149  if (newEnergy <= m_mass) {
150  m_absMomentum = Scalar(0);
151  } else {
152  m_absMomentum = std::sqrt(newEnergy * newEnergy - m_mass * m_mass);
153  }
154  return *this;
155  }
156 
158  constexpr Barcode particleId() const { return m_particleId; }
160  constexpr ProcessType process() const { return m_process; }
162  constexpr Acts::PdgParticle pdg() const { return m_pdg; }
164  constexpr Acts::PdgParticle absolutePdg() const {
166  }
168  constexpr Scalar charge() const { return m_charge; }
170  constexpr Scalar absoluteCharge() const { return std::abs(m_charge); }
172  constexpr Scalar mass() const { return m_mass; }
173 
177  }
179  constexpr Scalar qOverP() const {
180  return hypothesis().qOverP(absoluteMomentum(), charge());
181  }
182 
184  constexpr const Vector4 &fourPosition() const { return m_position4; }
186  auto position() const { return m_position4.segment<3>(Acts::ePos0); }
188  Scalar time() const { return m_position4[Acts::eTime]; }
191  Vector4 mom4;
192  // stored direction is always normalized
194  mom4[Acts::eMom1] = m_absMomentum * m_direction[Acts::ePos1];
195  mom4[Acts::eMom2] = m_absMomentum * m_direction[Acts::ePos2];
196  mom4[Acts::eEnergy] = energy();
197  return mom4;
198  }
200  const Vector3 &direction() const { return m_direction; }
207  return m_absMomentum * m_direction.segment<2>(Acts::eMom0).norm();
208  }
210  constexpr Scalar absoluteMomentum() const { return m_absMomentum; }
212  Vector3 momentum() const { return absoluteMomentum() * direction(); }
214  Scalar energy() const { return std::hypot(m_mass, m_absMomentum); }
215 
217  constexpr bool isAlive() const { return Scalar(0) < m_absMomentum; }
218 
219  constexpr bool isSecondary() const {
220  return particleId().vertexSecondary() != 0 ||
221  particleId().generation() != 0 || particleId().subParticle() != 0;
222  }
223 
224  // simulation specific properties
225 
231  return *this;
232  }
234  constexpr Scalar properTime() const { return m_properTime; }
235 
243  return *this;
244  }
246  constexpr Scalar pathInX0() const { return m_pathInX0; }
248  constexpr Scalar pathInL0() const { return m_pathInL0; }
249 
255  return *this;
256  }
257 
260 
262  bool hasReferenceSurface() const { return m_referenceSurface != nullptr; }
263 
266  const Acts::GeometryContext &gctx) const {
267  if (!hasReferenceSurface()) {
269  std::error_code());
270  }
271  Acts::Result<Acts::Vector2> localResult =
273  if (!localResult.ok()) {
274  return localResult.error();
275  }
276  Acts::BoundVector params;
277  params << localResult.value(), phi(), theta(), qOverP(), time();
278  return Acts::BoundTrackParameters(referenceSurface()->getSharedPtr(),
279  params, std::nullopt, hypothesis());
280  }
281 
284  fourPosition(), direction(), qOverP(), std::nullopt, hypothesis());
285  }
286 
287  private:
288  // identity, i.e. things that do not change over the particle lifetime.
292  ProcessType m_process = ProcessType::eUndefined;
295  // Particle charge and mass.
298  // kinematics, i.e. things that change over the particle lifetime.
299  Vector3 m_direction = Vector3::UnitZ();
301  Vector4 m_position4 = Vector4::Zero();
302  // proper time in the particle rest frame
304  // accumulated material
307  // reference surface
309 };
310 
311 std::ostream &operator<<(std::ostream &os, const Particle &particle);
312 
313 } // namespace ActsFatras