File indexing completed on 2025-12-17 09:37:57
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/ParticleOutcome.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, const SimParticleState& final)
0053 : m_initial(initial), m_final(final) {
0054 if (m_initial.particleId() != m_final.particleId()) {
0055 throw std::invalid_argument("Particle id mismatch");
0056 }
0057 }
0058
0059 const SimParticleState& initialState() const { return m_initial; }
0060 const SimParticleState& finalState() const { return m_final; }
0061
0062 SimParticleState& initialState() { return m_initial; }
0063 SimParticleState& finalState() { return m_final; }
0064
0065
0066
0067
0068
0069
0070 SimParticle withParticleId(SimBarcode particleId) const {
0071 return SimParticle(initialState().withParticleId(particleId),
0072 finalState().withParticleId(particleId));
0073 }
0074
0075
0076 SimParticle& setProcess(ActsFatras::ProcessType proc) {
0077 initialState().setProcess(proc);
0078 finalState().setProcess(proc);
0079 return *this;
0080 }
0081
0082 SimParticle& setPdg(Acts::PdgParticle pdg) {
0083 initialState().setPdg(pdg);
0084 finalState().setPdg(pdg);
0085 return *this;
0086 }
0087
0088 SimParticle& setCharge(double charge) {
0089 initialState().setCharge(charge);
0090 finalState().setCharge(charge);
0091 return *this;
0092 }
0093
0094 SimParticle& setMass(double mass) {
0095 initialState().setMass(mass);
0096 finalState().setMass(mass);
0097 return *this;
0098 }
0099
0100 SimParticle& setParticleId(SimBarcode barcode) {
0101 initialState().setParticleId(barcode);
0102 finalState().setParticleId(barcode);
0103 return *this;
0104 }
0105
0106
0107 SimBarcode particleId() const { return initialState().particleId(); }
0108
0109 ActsFatras::ProcessType process() const { return initialState().process(); }
0110
0111 Acts::PdgParticle pdg() const { return initialState().pdg(); }
0112
0113 Acts::PdgParticle absolutePdg() const { return initialState().absolutePdg(); }
0114
0115 double charge() const { return initialState().charge(); }
0116
0117 double absoluteCharge() const { return initialState().absoluteCharge(); }
0118
0119 double mass() const { return initialState().mass(); }
0120
0121
0122 bool isSecondary() const { return initialState().isSecondary(); }
0123
0124
0125 Acts::ParticleHypothesis hypothesis() const {
0126 return initialState().hypothesis();
0127 }
0128
0129 double qOverP() const { return initialState().qOverP(); }
0130
0131
0132 const Acts::Vector4& fourPosition() const {
0133 return initialState().fourPosition();
0134 }
0135
0136 auto position() const { return initialState().position(); }
0137
0138 double time() const { return initialState().time(); }
0139
0140 Acts::Vector4 fourMomentum() const { return initialState().fourMomentum(); }
0141
0142 const Acts::Vector3& direction() const { return initialState().direction(); }
0143
0144 double theta() const { return initialState().theta(); }
0145
0146 double phi() const { return initialState().phi(); }
0147
0148 double transverseMomentum() const {
0149 return initialState().transverseMomentum();
0150 }
0151
0152 double absoluteMomentum() const { return initialState().absoluteMomentum(); }
0153
0154 Acts::Vector3 momentum() const { return initialState().momentum(); }
0155
0156 double energy() const { return initialState().energy(); }
0157
0158
0159 double energyLoss() const {
0160 return initialState().energy() - finalState().energy();
0161 }
0162
0163
0164 double pathInX0() const { return finalState().pathInX0(); }
0165
0166 double pathInL0() const { return finalState().pathInL0(); }
0167
0168
0169 std::uint32_t numberOfHits() const { return finalState().numberOfHits(); }
0170
0171
0172 ActsFatras::ParticleOutcome outcome() const { return finalState().outcome(); }
0173
0174 private:
0175 SimParticleState m_initial;
0176 SimParticleState m_final;
0177 };
0178
0179 std::ostream& operator<<(std::ostream& os, const SimParticle& particle);
0180
0181 namespace detail {
0182 struct CompareParticleId {
0183 using is_transparent = void;
0184 bool operator()(const SimParticleState& lhs,
0185 const SimParticleState& rhs) const {
0186 return lhs.particleId() < rhs.particleId();
0187 }
0188 bool operator()(const SimParticle& lhs, const SimParticle& rhs) const {
0189 return lhs.particleId() < rhs.particleId();
0190 }
0191 bool operator()(SimBarcode lhs, const SimParticleState& rhs) const {
0192 return lhs < rhs.particleId();
0193 }
0194 bool operator()(SimBarcode lhs, const SimParticle& rhs) const {
0195 return lhs < rhs.particleId();
0196 }
0197 bool operator()(const SimParticleState& lhs, SimBarcode rhs) const {
0198 return lhs.particleId() < rhs;
0199 }
0200 bool operator()(const SimParticle& lhs, SimBarcode rhs) const {
0201 return lhs.particleId() < rhs;
0202 }
0203 };
0204 struct PrimaryVertexIdGetter {
0205 SimBarcode operator()(const SimParticleState& particle) const {
0206 return SimBarcode().withVertexPrimary(
0207 particle.particleId().vertexPrimary());
0208 }
0209 SimBarcode operator()(const SimParticle& particle) const {
0210 return SimBarcode().withVertexPrimary(
0211 particle.particleId().vertexPrimary());
0212 }
0213 };
0214 struct SecondaryVertexIdGetter {
0215 SimBarcode operator()(const SimParticleState& particle) const {
0216 return SimBarcode()
0217 .withVertexPrimary(particle.particleId().vertexPrimary())
0218 .withVertexSecondary(particle.particleId().vertexSecondary());
0219 }
0220 SimBarcode operator()(const SimParticle& particle) const {
0221 return SimBarcode()
0222 .withVertexPrimary(particle.particleId().vertexPrimary())
0223 .withVertexSecondary(particle.particleId().vertexSecondary());
0224 }
0225 };
0226 struct VertexIdGetter {
0227 SimBarcode operator()(const SimParticleState& particle) const {
0228 return particle.particleId().vertexId();
0229 }
0230 SimBarcode operator()(const SimParticle& particle) const {
0231 return particle.particleId().vertexId();
0232 }
0233 };
0234 }
0235
0236 using SimParticleStateContainer =
0237 ::boost::container::flat_set<SimParticleState, detail::CompareParticleId>;
0238
0239
0240 using SimParticleContainer =
0241 ::boost::container::flat_set<SimParticle, detail::CompareParticleId>;
0242
0243
0244 inline GroupBy<SimParticleContainer::const_iterator,
0245 detail::PrimaryVertexIdGetter>
0246 groupByPrimaryVertex(const SimParticleContainer& container) {
0247 return makeGroupBy(container, detail::PrimaryVertexIdGetter());
0248 }
0249
0250
0251
0252
0253
0254 inline GroupBy<SimParticleContainer::const_iterator,
0255 detail::SecondaryVertexIdGetter>
0256 groupBySecondaryVertex(const SimParticleContainer& container) {
0257 return makeGroupBy(container, detail::SecondaryVertexIdGetter());
0258 }
0259
0260
0261
0262
0263
0264 inline GroupBy<SimParticleContainer::const_iterator, detail::VertexIdGetter>
0265 groupByVertexId(const SimParticleContainer& container) {
0266 return makeGroupBy(container, detail::VertexIdGetter());
0267 }
0268
0269 }