File indexing completed on 2025-08-06 08:11:39
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Material/MaterialSlab.hpp"
0013 #include "Acts/Tests/CommonHelpers/PredefinedMaterials.hpp"
0014 #include "ActsFatras/EventData/Barcode.hpp"
0015 #include "ActsFatras/EventData/Particle.hpp"
0016 #include "ActsFatras/Kernel/InteractionList.hpp"
0017
0018 #include <cstdint>
0019 #include <limits>
0020 #include <random>
0021 #include <utility>
0022 #include <vector>
0023
0024 using namespace Acts::UnitLiterals;
0025 using namespace ActsFatras;
0026
0027 using Acts::MaterialSlab;
0028 using Scalar = Particle::Scalar;
0029
0030 namespace {
0031
0032
0033 struct SterileContinuousProcess {
0034 template <typename generator_t>
0035 bool operator()(generator_t & , const MaterialSlab & ,
0036 Particle & ,
0037 std::vector<Particle> & ) const {
0038 return false;
0039 }
0040 };
0041
0042 static_assert(detail::IsContinuousProcess<SterileContinuousProcess>::value,
0043 "Is not a continuous process");
0044 static_assert(!detail::IsPointLikeProcess<SterileContinuousProcess>::value,
0045 "Is a point-like process");
0046
0047
0048 struct FatalContinuousProcess {
0049 template <typename generator_t>
0050 bool operator()(generator_t & , const MaterialSlab & ,
0051 Particle & ,
0052 std::vector<Particle> & ) const {
0053 return true;
0054 }
0055 };
0056 static_assert(detail::IsContinuousProcess<FatalContinuousProcess>::value,
0057 "Is not a continuous process");
0058 static_assert(!detail::IsPointLikeProcess<FatalContinuousProcess>::value,
0059 "Is a point-like process");
0060
0061
0062
0063
0064 struct X0PointLikeProcess {
0065 template <typename generator_t>
0066 std::pair<Scalar, Scalar> generatePathLimits(
0067 generator_t & , const Particle & ) const {
0068 return {0.5, std::numeric_limits<Scalar>::infinity()};
0069 }
0070
0071 template <typename generator_t>
0072 bool run(generator_t & , Particle &particle,
0073 std::vector<Particle> &generated) const {
0074 auto pid0 = particle.particleId().makeDescendant(0);
0075 generated.emplace_back(particle.withParticleId(pid0));
0076 return false;
0077 }
0078 };
0079
0080 static_assert(!detail::IsContinuousProcess<X0PointLikeProcess>::value,
0081 "Is a continuous process");
0082 static_assert(detail::IsPointLikeProcess<X0PointLikeProcess>::value,
0083 "Is not a point-like process");
0084
0085
0086
0087
0088 struct L0PointLikeProcess {
0089 template <typename generator_t>
0090 std::pair<Scalar, Scalar> generatePathLimits(
0091 generator_t & , const Particle & ) const {
0092 return {std::numeric_limits<Scalar>::infinity(), 1.5};
0093 }
0094
0095 template <typename generator_t>
0096 bool run(generator_t & , Particle &particle,
0097 std::vector<Particle> &generated) const {
0098 auto pid0 = particle.particleId().makeDescendant(0);
0099 auto pid1 = particle.particleId().makeDescendant(1);
0100 generated.emplace_back(particle.withParticleId(pid0));
0101 generated.emplace_back(particle.withParticleId(pid1));
0102 return true;
0103 }
0104 };
0105
0106 static_assert(!detail::IsContinuousProcess<L0PointLikeProcess>::value,
0107 "Is a continuous process");
0108 static_assert(detail::IsPointLikeProcess<L0PointLikeProcess>::value,
0109 "Is not a point-like process");
0110
0111 struct Fixture {
0112 std::ranlux48 rng{23};
0113 Acts::MaterialSlab slab =
0114 Acts::MaterialSlab(Acts::Test::makeBeryllium(), 1_mm);
0115 Particle incoming;
0116 std::vector<Particle> outgoing;
0117 };
0118
0119 }
0120
0121 BOOST_AUTO_TEST_SUITE(FatrasInteractionList)
0122
0123 BOOST_AUTO_TEST_CASE(Empty) {
0124 Fixture f;
0125 InteractionList<> l;
0126
0127
0128 BOOST_CHECK(!l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0129
0130
0131 auto sel = l.armPointLike(f.rng, f.incoming);
0132 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<Scalar>::infinity());
0133 BOOST_CHECK_EQUAL(sel.l0Limit, std::numeric_limits<Scalar>::infinity());
0134 BOOST_CHECK_EQUAL(sel.x0Process, SIZE_MAX);
0135 BOOST_CHECK_EQUAL(sel.l0Process, SIZE_MAX);
0136
0137
0138
0139 BOOST_CHECK(!l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0140 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0141
0142 BOOST_CHECK(!l.runPointLike(f.rng, SIZE_MAX, f.incoming, f.outgoing));
0143 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0144 }
0145
0146 BOOST_AUTO_TEST_CASE(ContinuousSterile) {
0147 Fixture f;
0148 InteractionList<SterileContinuousProcess> l;
0149
0150
0151 BOOST_CHECK(!l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0152 }
0153
0154 BOOST_AUTO_TEST_CASE(ContinuousFatal) {
0155 Fixture f;
0156 InteractionList<FatalContinuousProcess> l;
0157
0158
0159 BOOST_CHECK(l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0160 }
0161
0162 BOOST_AUTO_TEST_CASE(ContinuousSterileFatal) {
0163 Fixture f;
0164 InteractionList<SterileContinuousProcess, FatalContinuousProcess> physicsList;
0165
0166
0167 BOOST_CHECK(physicsList.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0168
0169 physicsList.disable<FatalContinuousProcess>();
0170 BOOST_CHECK(
0171 !physicsList.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0172 }
0173
0174 BOOST_AUTO_TEST_CASE(PointLikeX0) {
0175 Fixture f;
0176 InteractionList<X0PointLikeProcess> l;
0177
0178
0179 auto sel = l.armPointLike(f.rng, f.incoming);
0180 BOOST_CHECK_EQUAL(sel.x0Limit, 0.5);
0181 BOOST_CHECK_EQUAL(sel.l0Limit, std::numeric_limits<Scalar>::infinity());
0182 BOOST_CHECK_EQUAL(sel.x0Process, 0u);
0183 BOOST_CHECK_EQUAL(sel.l0Process, SIZE_MAX);
0184
0185
0186 BOOST_CHECK(!l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0187 BOOST_CHECK_EQUAL(f.outgoing.size(), 1u);
0188
0189 BOOST_CHECK(!l.runPointLike(f.rng, SIZE_MAX, f.incoming, f.outgoing));
0190 BOOST_CHECK_EQUAL(f.outgoing.size(), 1u);
0191 }
0192
0193 BOOST_AUTO_TEST_CASE(PointLikeL0) {
0194 Fixture f;
0195 InteractionList<L0PointLikeProcess> l;
0196
0197
0198 auto sel = l.armPointLike(f.rng, f.incoming);
0199 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<Scalar>::infinity());
0200 BOOST_CHECK_EQUAL(sel.l0Limit, 1.5);
0201 BOOST_CHECK_EQUAL(sel.x0Process, SIZE_MAX);
0202 BOOST_CHECK_EQUAL(sel.l0Process, 0u);
0203
0204
0205 BOOST_CHECK(l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0206 BOOST_CHECK_EQUAL(f.outgoing.size(), 2u);
0207
0208 BOOST_CHECK(!l.runPointLike(f.rng, SIZE_MAX, f.incoming, f.outgoing));
0209 BOOST_CHECK_EQUAL(f.outgoing.size(), 2u);
0210 }
0211
0212 BOOST_AUTO_TEST_CASE(PointLikeX0L0) {
0213 Fixture f;
0214 InteractionList<X0PointLikeProcess, L0PointLikeProcess> l;
0215
0216
0217 auto sel = l.armPointLike(f.rng, f.incoming);
0218 BOOST_CHECK_EQUAL(sel.x0Limit, 0.5);
0219 BOOST_CHECK_EQUAL(sel.l0Limit, 1.5);
0220 BOOST_CHECK_EQUAL(sel.x0Process, 0u);
0221 BOOST_CHECK_EQUAL(sel.l0Process, 1u);
0222
0223
0224 BOOST_CHECK(!l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0225 BOOST_CHECK_EQUAL(f.outgoing.size(), 1u);
0226
0227 BOOST_CHECK(l.runPointLike(f.rng, 1u, f.incoming, f.outgoing));
0228 BOOST_CHECK_EQUAL(f.outgoing.size(), 3u);
0229
0230 BOOST_CHECK(!l.runPointLike(f.rng, SIZE_MAX, f.incoming, f.outgoing));
0231 BOOST_CHECK_EQUAL(f.outgoing.size(), 3u);
0232 }
0233
0234
0235
0236 BOOST_AUTO_TEST_CASE(Disable) {
0237 Fixture f;
0238 InteractionList<SterileContinuousProcess, FatalContinuousProcess,
0239 X0PointLikeProcess, L0PointLikeProcess>
0240 l;
0241
0242
0243 BOOST_CHECK(l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0244
0245 l.disable<FatalContinuousProcess>();
0246 BOOST_CHECK(!l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0247
0248
0249 l.disable<X0PointLikeProcess>();
0250 {
0251 auto sel = l.armPointLike(f.rng, f.incoming);
0252 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<Scalar>::infinity());
0253 BOOST_CHECK_EQUAL(sel.l0Limit, 1.5);
0254 BOOST_CHECK_EQUAL(sel.x0Process, SIZE_MAX);
0255 BOOST_CHECK_EQUAL(sel.l0Process, 3u);
0256
0257
0258 f.outgoing.clear();
0259 BOOST_CHECK(!l.runPointLike(f.rng, 2u, f.incoming, f.outgoing));
0260 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0261
0262 BOOST_CHECK(l.runPointLike(f.rng, 3u, f.incoming, f.outgoing));
0263 BOOST_CHECK_EQUAL(f.outgoing.size(), 2u);
0264 }
0265
0266
0267 l.disable<L0PointLikeProcess>();
0268 {
0269 auto sel = l.armPointLike(f.rng, f.incoming);
0270 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<Scalar>::infinity());
0271 BOOST_CHECK_EQUAL(sel.l0Limit, std::numeric_limits<Scalar>::infinity());
0272 BOOST_CHECK_EQUAL(sel.x0Process, SIZE_MAX);
0273 BOOST_CHECK_EQUAL(sel.l0Process, SIZE_MAX);
0274
0275
0276 f.outgoing.clear();
0277 BOOST_CHECK(!l.runPointLike(f.rng, 2u, f.incoming, f.outgoing));
0278 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0279
0280 BOOST_CHECK(!l.runPointLike(f.rng, 3u, f.incoming, f.outgoing));
0281 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0282 }
0283
0284
0285 f.outgoing.clear();
0286 BOOST_CHECK(!l.runPointLike(f.rng, SIZE_MAX, f.incoming, f.outgoing));
0287 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0288 }
0289
0290 BOOST_AUTO_TEST_SUITE_END()