EIC 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-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 <cmath>
17 #include <iosfwd>
18 #include <limits>
19 
20 namespace ActsFatras {
21 
23 class Particle {
24  public:
25  using Scalar = double;
28 
30  Particle() = default;
41  Scalar mass)
42  : m_particleId(particleId), m_pdg(pdg), m_charge(charge), m_mass(mass) {}
50  Particle(const Particle &) = default;
51  Particle(Particle &&) = default;
52  Particle &operator=(const Particle &) = default;
53  Particle &operator=(Particle &&) = default;
54 
61  Particle p = *this;
63  return p;
64  }
65 
67  Particle &setProcess(ProcessType proc) { return m_process = proc, *this; }
70  m_position4 = pos4;
71  return *this;
72  }
75  m_position4.segment<3>(Acts::ePos0) = position;
77  return *this;
78  }
85  return *this;
86  }
88  Particle &setDirection(const Vector3 &direction) {
89  m_unitDirection = direction;
90  m_unitDirection.normalize();
91  return *this;
92  }
98  m_unitDirection.normalize();
99  return *this;
100  }
104  return *this;
105  }
112  const auto newEnergy = std::hypot(m_mass, m_absMomentum) + delta;
113  if (newEnergy <= m_mass) {
114  m_absMomentum = Scalar(0);
115  } else {
116  m_absMomentum = std::sqrt(newEnergy * newEnergy - m_mass * m_mass);
117  }
118  return *this;
119  }
120 
122  constexpr Barcode particleId() const { return m_particleId; }
124  constexpr ProcessType process() const { return m_process; }
126  constexpr Acts::PdgParticle pdg() const { return m_pdg; }
128  constexpr Scalar charge() const { return m_charge; }
130  constexpr Scalar mass() const { return m_mass; }
131 
133  constexpr const Vector4 &position4() const { return m_position4; }
135  auto position() const { return m_position4.segment<3>(Acts::ePos0); }
137  Scalar time() const { return m_position4[Acts::eTime]; }
139  Vector4 momentum4() const {
140  Vector4 mom4;
141  // stored direction is always normalized
143  mom4[Acts::eMom1] = m_absMomentum * m_unitDirection[Acts::ePos1];
144  mom4[Acts::eMom2] = m_absMomentum * m_unitDirection[Acts::ePos2];
145  mom4[Acts::eEnergy] = energy();
146  return mom4;
147  }
149  const Vector3 &unitDirection() const { return m_unitDirection; }
152  return m_absMomentum * m_unitDirection.segment<2>(Acts::eMom0).norm();
153  }
155  constexpr Scalar absMomentum() const { return m_absMomentum; }
157  Scalar energy() const { return std::hypot(m_mass, m_absMomentum); }
158 
160  constexpr operator bool() const { return Scalar(0) < m_absMomentum; }
162  constexpr bool operator!() const { return m_absMomentum <= Scalar(0); }
163 
168  constexpr Particle &setMaterialPassed(Scalar pathX0, Scalar pathL0) {
169  m_pathX0 = pathX0;
170  m_pathL0 = pathL0;
171  return *this;
172  }
177  constexpr Particle &setMaterialLimits(Scalar limitX0, Scalar limitL0) {
178  m_limitX0 = limitX0;
179  m_limitL0 = limitL0;
180  return *this;
181  }
183  constexpr Scalar pathInX0() const { return m_pathX0; }
185  constexpr Scalar pathInL0() const { return m_pathL0; }
187  constexpr Scalar pathLimitX0() const { return m_limitX0; }
189  constexpr Scalar pathLimitL0() const { return m_limitL0; }
190 
191  private:
192  // identity, i.e. things that do not change over the particle lifetime.
196  ProcessType m_process = ProcessType::eUndefined;
199  // Particle charge and mass.
202  // kinematics, i.e. things that change over the particle lifetime.
203  Vector3 m_unitDirection = Vector3::UnitZ();
205  Vector4 m_position4 = Vector4::Zero();
206  // simulation-specific X0/L0 information and limits
207  // these values are here to simplify the simulation of (nuclear) interactions.
208  // instead of checking at every surface whether an interaction should occur we
209  // can draw an overall limit once. the relevant interaction only needs to
210  // be executed once the limit is reached.
211  // this information is not really particle-specific and should probably be
212  // handled separately. for now, storing it directly here is the simplest
213  // solution.
218 };
219 
220 std::ostream &operator<<(std::ostream &os, const Particle &particle);
221 
222 } // namespace ActsFatras