File indexing completed on 2026-08-26 08:38:34
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "ActsExamples/Utilities/GroupBy.hpp"
0012 #include "ActsFatras/EventData/Particle.hpp"
0013 #include "ActsFatras/EventData/SimulationOutcome.hpp"
0014
0015 #include <boost/container/flat_set.hpp>
0016
0017 namespace ActsExamples {
0018
0019 using SimBarcode = ::ActsFatras::Barcode;
0020 using SimBarcodeContainer = ::boost::container::flat_set<SimBarcode>;
0021
0022 using SimParticleState = ::ActsFatras::Particle;
0023
0024 class SimParticle final {
0025 public:
0026
0027 SimParticle() = default;
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 SimParticle(SimBarcode particleId, Acts::PdgParticle pdg, double charge,
0039 double mass)
0040 : m_initial(particleId, pdg, charge, mass),
0041 m_final(particleId, pdg, charge, mass) {}
0042
0043
0044
0045
0046
0047
0048
0049 SimParticle(SimBarcode particleId, Acts::PdgParticle pdg)
0050 : m_initial(particleId, pdg), m_final(particleId, pdg) {}
0051
0052 SimParticle(const SimParticleState& initial,
0053 const SimParticleState& finalState)
0054 : m_initial(initial), m_final(finalState) {
0055 if (m_initial.particleId() != m_final.particleId()) {
0056 throw std::invalid_argument("Particle id mismatch");
0057 }
0058 }
0059
0060 const SimParticleState& initialState() const { return m_initial; }
0061 const SimParticleState& finalState() const { return m_final; }
0062
0063 SimParticleState& initialState() { return m_initial; }
0064 SimParticleState& finalState() { return m_final; }
0065
0066
0067
0068
0069
0070
0071 SimParticle withParticleId(SimBarcode particleId) const {
0072 SimParticle copy(initialState().withParticleId(particleId),
0073 finalState().withParticleId(particleId));
0074 copy.setParentParticleId(parentParticleId());
0075 return copy;
0076 }
0077
0078
0079 SimParticle& setProcess(ActsFatras::GenerationProcess proc) {
0080 initialState().setProcess(proc);
0081 finalState().setProcess(proc);
0082 return *this;
0083 }
0084
0085 SimParticle& setPdg(Acts::PdgParticle pdg) {
0086 initialState().setPdg(pdg);
0087 finalState().setPdg(pdg);
0088 return *this;
0089 }
0090
0091 SimParticle& setCharge(double charge) {
0092 initialState().setCharge(charge);
0093 finalState().setCharge(charge);
0094 return *this;
0095 }
0096
0097 SimParticle& setMass(double mass) {
0098 initialState().setMass(mass);
0099 finalState().setMass(mass);
0100 return *this;
0101 }
0102
0103 SimParticle& setParticleId(SimBarcode barcode) {
0104 initialState().setParticleId(barcode);
0105 finalState().setParticleId(barcode);
0106 return *this;
0107 }
0108
0109 SimParticle& setParentParticleId(SimBarcode parentId) {
0110 initialState().setParentParticleId(parentId);
0111 finalState().setParentParticleId(parentId);
0112 return *this;
0113 }
0114
0115
0116 SimBarcode particleId() const { return initialState().particleId(); }
0117
0118 SimBarcode parentParticleId() const {
0119 return initialState().parentParticleId();
0120 }
0121
0122 ActsFatras::GenerationProcess process() const {
0123 return initialState().process();
0124 }
0125
0126 Acts::PdgParticle pdg() const { return initialState().pdg(); }
0127
0128 Acts::PdgParticle absolutePdg() const { return initialState().absolutePdg(); }
0129
0130 double charge() const { return initialState().charge(); }
0131
0132 double absoluteCharge() const { return initialState().absoluteCharge(); }
0133
0134 double mass() const { return initialState().mass(); }
0135
0136
0137 bool isSecondary() const { return initialState().isSecondary(); }
0138
0139
0140 Acts::ParticleHypothesis hypothesis() const {
0141 return initialState().hypothesis();
0142 }
0143
0144 double qOverP() const { return initialState().qOverP(); }
0145
0146
0147 const Acts::Vector4& fourPosition() const {
0148 return initialState().fourPosition();
0149 }
0150
0151 auto position() const { return initialState().position(); }
0152
0153 double time() const { return initialState().time(); }
0154
0155 Acts::Vector4 fourMomentum() const { return initialState().fourMomentum(); }
0156
0157 const Acts::Vector3& direction() const { return initialState().direction(); }
0158
0159 double theta() const { return initialState().theta(); }
0160
0161 double phi() const { return initialState().phi(); }
0162
0163 double transverseMomentum() const {
0164 return initialState().transverseMomentum();
0165 }
0166
0167 double absoluteMomentum() const { return initialState().absoluteMomentum(); }
0168
0169 Acts::Vector3 momentum() const { return initialState().momentum(); }
0170
0171 double energy() const { return initialState().energy(); }
0172
0173
0174 double energyLoss() const {
0175 return initialState().energy() - finalState().energy();
0176 }
0177
0178
0179 double pathInX0() const { return finalState().pathInX0(); }
0180
0181 double pathInL0() const { return finalState().pathInL0(); }
0182
0183
0184 std::uint32_t numberOfHits() const { return finalState().numberOfHits(); }
0185
0186
0187 ActsFatras::SimulationOutcome outcome() const {
0188 return finalState().outcome();
0189 }
0190
0191 private:
0192 SimParticleState m_initial;
0193 SimParticleState m_final;
0194 };
0195
0196 std::ostream& operator<<(std::ostream& os, const SimParticle& particle);
0197
0198 namespace detail {
0199 struct CompareParticleId {
0200 using is_transparent = void;
0201 bool operator()(const SimParticleState& lhs,
0202 const SimParticleState& rhs) const {
0203 return lhs.particleId() < rhs.particleId();
0204 }
0205 bool operator()(const SimParticle& lhs, const SimParticle& rhs) const {
0206 return lhs.particleId() < rhs.particleId();
0207 }
0208 bool operator()(SimBarcode lhs, const SimParticleState& rhs) const {
0209 return lhs < rhs.particleId();
0210 }
0211 bool operator()(SimBarcode lhs, const SimParticle& rhs) const {
0212 return lhs < rhs.particleId();
0213 }
0214 bool operator()(const SimParticleState& lhs, SimBarcode rhs) const {
0215 return lhs.particleId() < rhs;
0216 }
0217 bool operator()(const SimParticle& lhs, SimBarcode rhs) const {
0218 return lhs.particleId() < rhs;
0219 }
0220 };
0221 struct PrimaryVertexIdGetter {
0222 SimBarcode operator()(const SimParticleState& particle) const {
0223 return SimBarcode().withVertexPrimary(
0224 particle.particleId().vertexPrimary());
0225 }
0226 SimBarcode operator()(const SimParticle& particle) const {
0227 return SimBarcode().withVertexPrimary(
0228 particle.particleId().vertexPrimary());
0229 }
0230 };
0231 struct SecondaryVertexIdGetter {
0232 SimBarcode operator()(const SimParticleState& particle) const {
0233 return SimBarcode()
0234 .withVertexPrimary(particle.particleId().vertexPrimary())
0235 .withVertexSecondary(particle.particleId().vertexSecondary());
0236 }
0237 SimBarcode operator()(const SimParticle& particle) const {
0238 return SimBarcode()
0239 .withVertexPrimary(particle.particleId().vertexPrimary())
0240 .withVertexSecondary(particle.particleId().vertexSecondary());
0241 }
0242 };
0243 struct VertexIdGetter {
0244 SimBarcode operator()(const SimParticleState& particle) const {
0245 return particle.particleId().vertexId();
0246 }
0247 SimBarcode operator()(const SimParticle& particle) const {
0248 return particle.particleId().vertexId();
0249 }
0250 };
0251 }
0252
0253 using SimParticleStateContainer =
0254 ::boost::container::flat_set<SimParticleState, detail::CompareParticleId>;
0255
0256
0257 using SimParticleContainer =
0258 ::boost::container::flat_set<SimParticle, detail::CompareParticleId>;
0259
0260
0261 inline GroupBy<SimParticleContainer::const_iterator,
0262 detail::PrimaryVertexIdGetter>
0263 groupByPrimaryVertex(const SimParticleContainer& container) {
0264 return makeGroupBy(container, detail::PrimaryVertexIdGetter());
0265 }
0266
0267
0268
0269
0270
0271 inline GroupBy<SimParticleContainer::const_iterator,
0272 detail::SecondaryVertexIdGetter>
0273 groupBySecondaryVertex(const SimParticleContainer& container) {
0274 return makeGroupBy(container, detail::SecondaryVertexIdGetter());
0275 }
0276
0277
0278
0279
0280
0281 inline GroupBy<SimParticleContainer::const_iterator, detail::VertexIdGetter>
0282 groupByVertexId(const SimParticleContainer& container) {
0283 return makeGroupBy(container, detail::VertexIdGetter());
0284 }
0285
0286 }