File indexing completed on 2025-01-18 09:13:05
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/PdgParticle.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/TrackingVolume.hpp"
0016 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0017 #include "Acts/Material/MaterialSlab.hpp"
0018 #include "Acts/Propagator/ConstrainedStep.hpp"
0019 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0020 #include "Acts/Surfaces/PlaneSurface.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0023 #include "Acts/Tests/CommonHelpers/PredefinedMaterials.hpp"
0024 #include "Acts/Utilities/Logger.hpp"
0025 #include "ActsFatras/EventData/Barcode.hpp"
0026 #include "ActsFatras/EventData/Particle.hpp"
0027 #include "ActsFatras/EventData/ProcessType.hpp"
0028 #include "ActsFatras/Kernel/detail/SimulationActor.hpp"
0029 #include "ActsFatras/Selectors/SurfaceSelectors.hpp"
0030
0031 #include <array>
0032 #include <cmath>
0033 #include <cstddef>
0034 #include <cstdint>
0035 #include <limits>
0036 #include <memory>
0037 #include <random>
0038 #include <utility>
0039 #include <vector>
0040
0041 using namespace Acts::UnitLiterals;
0042 using namespace ActsFatras;
0043
0044 namespace {
0045
0046 constexpr auto tol = 4 * std::numeric_limits<double>::epsilon();
0047 constexpr auto inf = std::numeric_limits<double>::infinity();
0048
0049 struct MockDecay {
0050 double properTimeLimit = inf;
0051
0052 template <typename generator_t>
0053 constexpr double generateProperTimeLimit(generator_t & ,
0054 const Particle &particle) const {
0055 return particle.properTime() + properTimeLimit;
0056 }
0057 template <typename generator_t>
0058 constexpr std::array<Particle, 0> run(generator_t & ,
0059 const Particle & ) const {
0060 return {};
0061 }
0062 };
0063
0064 struct MockInteractionList {
0065 struct Selection {
0066 double x0Limit = std::numeric_limits<double>::infinity();
0067 double l0Limit = std::numeric_limits<double>::infinity();
0068 std::size_t x0Process = std::numeric_limits<std::size_t>::max();
0069 std::size_t l0Process = std::numeric_limits<std::size_t>::max();
0070 };
0071
0072 double energyLoss = 0;
0073
0074 template <typename generator_t>
0075 bool runContinuous(generator_t & ,
0076 const Acts::MaterialSlab & , Particle &particle,
0077 std::vector<Particle> &generated) const {
0078 generated.push_back(particle);
0079 particle.correctEnergy(-energyLoss);
0080
0081 return !particle.isAlive();
0082 }
0083
0084 template <typename generator_t>
0085 Selection armPointLike(generator_t & ,
0086 const Particle & ) const {
0087 return {};
0088 }
0089
0090 template <typename generator_t>
0091 bool runPointLike(generator_t & , std::size_t ,
0092 Particle & ,
0093 std::vector<Particle> & ) const {
0094 return false;
0095 }
0096 };
0097
0098 struct MockStepperState {
0099 Acts::Vector3 pos = Acts::Vector3::Zero();
0100 double time = 0;
0101 Acts::Vector3 dir = Acts::Vector3::Zero();
0102 double p = 0;
0103 };
0104
0105 struct MockStepper {
0106 using State = MockStepperState;
0107
0108 auto position(const State &state) const { return state.pos; }
0109 auto time(const State &state) const { return state.time; }
0110 auto direction(const State &state) const { return state.dir; }
0111 auto absoluteMomentum(const State &state) const { return state.p; }
0112 void update(State &state, const Acts::Vector3 &pos, const Acts::Vector3 &dir,
0113 double qop, double time) {
0114 state.pos = pos;
0115 state.time = time;
0116 state.dir = dir;
0117 state.p = 1 / qop;
0118 }
0119 void updateStepSize(State & , double ,
0120 Acts::ConstrainedStep::Type ) const {}
0121 void releaseStepSize(State & ,
0122 Acts::ConstrainedStep::Type ) const {}
0123 };
0124
0125 struct MockNavigatorState {
0126 Acts::Surface *startSurface = nullptr;
0127 Acts::Surface *currentSurface = nullptr;
0128 };
0129
0130 struct MockNavigator {
0131 const Acts::Surface *startSurface(const MockNavigatorState &state) const {
0132 return state.startSurface;
0133 }
0134
0135 const Acts::Surface *currentSurface(const MockNavigatorState &state) const {
0136 return state.currentSurface;
0137 }
0138
0139 const Acts::TrackingVolume *currentVolume(
0140 const MockNavigatorState & ) const {
0141 return nullptr;
0142 }
0143
0144 bool endOfWorldReached(const MockNavigatorState & ) const {
0145 return false;
0146 }
0147 };
0148
0149 struct MockPropagatorState {
0150 MockNavigatorState navigation;
0151 MockStepperState stepping;
0152 Acts::GeometryContext geoContext;
0153 Acts::PropagatorStage stage = Acts::PropagatorStage::invalid;
0154
0155 struct {
0156 std::vector<std::uint32_t> constrainToVolumeIds;
0157 } options;
0158 };
0159
0160 template <typename SurfaceSelector>
0161 struct Fixture {
0162 using Generator = std::ranlux48;
0163 using Actor = typename ActsFatras::detail::SimulationActor<
0164 Generator, MockDecay, MockInteractionList, SurfaceSelector>;
0165 using Result = typename Actor::result_type;
0166
0167
0168 Barcode pid = Barcode().setVertexPrimary(12u).setParticle(3u);
0169 ProcessType proc = ProcessType::eUndefined;
0170 Acts::PdgParticle pdg = Acts::PdgParticle::eProton;
0171 double q = 1_e;
0172 double m = 1_GeV;
0173 double p = 1_GeV;
0174 double e;
0175 Generator generator;
0176 std::shared_ptr<Acts::Surface> surface;
0177 Actor actor;
0178 Result result;
0179 MockPropagatorState state;
0180 MockStepper stepper;
0181 MockNavigator navigator;
0182
0183 Fixture(double energyLoss, std::shared_ptr<Acts::Surface> surface_)
0184 : e(std::hypot(m, p)), generator(42), surface(std::move(surface_)) {
0185 const auto particle = Particle(pid, pdg, q, m)
0186 .setProcess(proc)
0187 .setPosition4(1_mm, 2_mm, 3_mm, 4_ns)
0188 .setDirection(1, 0, 0)
0189 .setAbsoluteMomentum(p);
0190 actor.generator = &generator;
0191 actor.interactions.energyLoss = energyLoss;
0192 actor.initialParticle = particle;
0193 state.stage = Acts::PropagatorStage::postStep;
0194 state.navigation.currentSurface = surface.get();
0195 state.stepping.pos = particle.position();
0196 state.stepping.time = particle.time();
0197 state.stepping.dir = particle.direction();
0198 state.stepping.p = particle.absoluteMomentum();
0199 }
0200 };
0201
0202
0203 std::shared_ptr<Acts::Surface> makeEmptySurface() {
0204 auto surface =
0205 Acts::CurvilinearSurface(Acts::Vector3(1, 2, 3), Acts::Vector3(1, 0, 0))
0206 .planeSurface();
0207 return surface;
0208 }
0209
0210
0211 std::shared_ptr<Acts::Surface> makeMaterialSurface() {
0212 auto surface = makeEmptySurface();
0213 auto slab = Acts::Test::makeUnitSlab();
0214 surface->assignSurfaceMaterial(
0215 std::make_shared<Acts::HomogeneousSurfaceMaterial>(slab));
0216 return surface;
0217 }
0218
0219 }
0220
0221 BOOST_AUTO_TEST_SUITE(FatrasSimulationActor)
0222
0223 BOOST_AUTO_TEST_CASE(HitsOnEmptySurface) {
0224 Fixture<EverySurface> f(125_MeV, makeEmptySurface());
0225
0226
0227 BOOST_CHECK_EQUAL(f.actor.initialParticle.particleId(), f.pid);
0228 BOOST_CHECK_EQUAL(f.actor.initialParticle.process(), f.proc);
0229 BOOST_CHECK_EQUAL(f.actor.initialParticle.pdg(), f.pdg);
0230 BOOST_CHECK_EQUAL(f.actor.initialParticle.mass(), f.m);
0231 BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p);
0232 BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e);
0233
0234
0235 f.state.stage = Acts::PropagatorStage::prePropagation;
0236 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0237 Acts::getDummyLogger());
0238
0239
0240 f.state.stage = Acts::PropagatorStage::postStep;
0241 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0242 Acts::getDummyLogger());
0243 BOOST_CHECK(f.result.isAlive);
0244 CHECK_CLOSE_REL(f.result.particle.energy(), f.e, tol);
0245 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 0u);
0246 BOOST_CHECK_EQUAL(f.result.hits.size(), 1u);
0247 BOOST_CHECK_EQUAL(f.result.hits[0].index(), 0u);
0248
0249 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0250
0251 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 0);
0252 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 0);
0253
0254 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0255 BOOST_CHECK_EQUAL(f.result.x0Process,
0256 std::numeric_limits<std::size_t>::max());
0257 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0258 BOOST_CHECK_EQUAL(f.result.l0Process,
0259 std::numeric_limits<std::size_t>::max());
0260
0261 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0262 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0263 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0264 BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum());
0265
0266
0267 f.state.stage = Acts::PropagatorStage::postStep;
0268 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0269 Acts::getDummyLogger());
0270 BOOST_CHECK(f.result.isAlive);
0271 CHECK_CLOSE_REL(f.result.particle.energy(), f.e, tol);
0272 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 0u);
0273 BOOST_CHECK_EQUAL(f.result.hits.size(), 2u);
0274 BOOST_CHECK_EQUAL(f.result.hits[0].index(), 0u);
0275 BOOST_CHECK_EQUAL(f.result.hits[1].index(), 1u);
0276
0277
0278 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0279
0280 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 0);
0281 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 0);
0282
0283 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0284 BOOST_CHECK_EQUAL(f.result.x0Process,
0285 std::numeric_limits<std::size_t>::max());
0286 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0287 BOOST_CHECK_EQUAL(f.result.l0Process,
0288 std::numeric_limits<std::size_t>::max());
0289
0290 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0291 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0292 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0293 BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum());
0294
0295
0296 BOOST_CHECK_EQUAL(f.result.particle.particleId(), f.pid);
0297 BOOST_CHECK_EQUAL(f.result.particle.process(), f.proc);
0298 BOOST_CHECK_EQUAL(f.result.particle.pdg(), f.pdg);
0299 BOOST_CHECK_EQUAL(f.result.particle.charge(), f.q);
0300 BOOST_CHECK_EQUAL(f.result.particle.mass(), f.m);
0301 }
0302
0303 BOOST_AUTO_TEST_CASE(HitsOnMaterialSurface) {
0304 Fixture<EverySurface> f(125_MeV, makeMaterialSurface());
0305
0306
0307 BOOST_CHECK_EQUAL(f.actor.initialParticle.particleId(), f.pid);
0308 BOOST_CHECK_EQUAL(f.actor.initialParticle.process(), f.proc);
0309 BOOST_CHECK_EQUAL(f.actor.initialParticle.pdg(), f.pdg);
0310 BOOST_CHECK_EQUAL(f.actor.initialParticle.mass(), f.m);
0311 BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p);
0312 BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e);
0313
0314
0315 f.state.stage = Acts::PropagatorStage::prePropagation;
0316 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0317 Acts::getDummyLogger());
0318
0319
0320 f.state.stage = Acts::PropagatorStage::postStep;
0321 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0322 Acts::getDummyLogger());
0323 BOOST_CHECK(f.result.isAlive);
0324 CHECK_CLOSE_REL(f.result.particle.energy(), f.e - 125_MeV, tol);
0325 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 1u);
0326 BOOST_CHECK_EQUAL(f.result.hits.size(), 1u);
0327 BOOST_CHECK_EQUAL(f.result.hits[0].index(), 0u);
0328
0329
0330 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0331
0332 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 1);
0333 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 1);
0334
0335 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0336 BOOST_CHECK_EQUAL(f.result.x0Process,
0337 std::numeric_limits<std::size_t>::max());
0338 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0339 BOOST_CHECK_EQUAL(f.result.l0Process,
0340 std::numeric_limits<std::size_t>::max());
0341
0342 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0343 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0344 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0345 CHECK_CLOSE_REL(f.state.stepping.p, f.result.particle.absoluteMomentum(),
0346 tol);
0347
0348
0349 f.state.stage = Acts::PropagatorStage::postStep;
0350 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0351 Acts::getDummyLogger());
0352 BOOST_CHECK(f.result.isAlive);
0353 CHECK_CLOSE_REL(f.result.particle.energy(), f.e - 250_MeV, tol);
0354 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 2u);
0355 BOOST_CHECK_EQUAL(f.result.hits.size(), 2u);
0356 BOOST_CHECK_EQUAL(f.result.hits[0].index(), 0u);
0357 BOOST_CHECK_EQUAL(f.result.hits[1].index(), 1u);
0358
0359
0360 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0361
0362 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 2);
0363 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 2);
0364
0365 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0366 BOOST_CHECK_EQUAL(f.result.x0Process,
0367 std::numeric_limits<std::size_t>::max());
0368 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0369 BOOST_CHECK_EQUAL(f.result.l0Process,
0370 std::numeric_limits<std::size_t>::max());
0371
0372 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0373 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0374 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0375 BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum());
0376
0377
0378 BOOST_CHECK_EQUAL(f.result.particle.particleId(), f.pid);
0379 BOOST_CHECK_EQUAL(f.result.particle.process(), f.proc);
0380 BOOST_CHECK_EQUAL(f.result.particle.pdg(), f.pdg);
0381 BOOST_CHECK_EQUAL(f.result.particle.charge(), f.q);
0382 BOOST_CHECK_EQUAL(f.result.particle.mass(), f.m);
0383 }
0384
0385 BOOST_AUTO_TEST_CASE(NoHitsEmptySurface) {
0386 Fixture<NoSurface> f(125_MeV, makeEmptySurface());
0387
0388
0389 BOOST_CHECK_EQUAL(f.actor.initialParticle.particleId(), f.pid);
0390 BOOST_CHECK_EQUAL(f.actor.initialParticle.process(), f.proc);
0391 BOOST_CHECK_EQUAL(f.actor.initialParticle.pdg(), f.pdg);
0392 BOOST_CHECK_EQUAL(f.actor.initialParticle.mass(), f.m);
0393 BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p);
0394 BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e);
0395
0396
0397 f.state.stage = Acts::PropagatorStage::prePropagation;
0398 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0399 Acts::getDummyLogger());
0400
0401
0402 f.state.stage = Acts::PropagatorStage::postStep;
0403 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0404 Acts::getDummyLogger());
0405 BOOST_CHECK(f.result.isAlive);
0406 CHECK_CLOSE_REL(f.result.particle.energy(), f.e, tol);
0407 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 0u);
0408 BOOST_CHECK_EQUAL(f.result.hits.size(), 0u);
0409
0410
0411 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0412
0413 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 0);
0414 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 0);
0415
0416 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0417 BOOST_CHECK_EQUAL(f.result.x0Process,
0418 std::numeric_limits<std::size_t>::max());
0419 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0420 BOOST_CHECK_EQUAL(f.result.l0Process,
0421 std::numeric_limits<std::size_t>::max());
0422
0423 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0424 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0425 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0426 BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum());
0427
0428
0429 f.state.stage = Acts::PropagatorStage::postStep;
0430 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0431 Acts::getDummyLogger());
0432 BOOST_CHECK(f.result.isAlive);
0433 CHECK_CLOSE_REL(f.result.particle.energy(), f.e, tol);
0434 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 0u);
0435 BOOST_CHECK_EQUAL(f.result.hits.size(), 0u);
0436
0437
0438 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0439
0440 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 0);
0441 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 0);
0442
0443 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0444 BOOST_CHECK_EQUAL(f.result.x0Process,
0445 std::numeric_limits<std::size_t>::max());
0446 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0447 BOOST_CHECK_EQUAL(f.result.l0Process,
0448 std::numeric_limits<std::size_t>::max());
0449
0450 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0451 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0452 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0453 BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum());
0454
0455
0456 BOOST_CHECK_EQUAL(f.result.particle.particleId(), f.pid);
0457 BOOST_CHECK_EQUAL(f.result.particle.process(), f.proc);
0458 BOOST_CHECK_EQUAL(f.result.particle.pdg(), f.pdg);
0459 BOOST_CHECK_EQUAL(f.result.particle.charge(), f.q);
0460 BOOST_CHECK_EQUAL(f.result.particle.mass(), f.m);
0461 }
0462
0463 BOOST_AUTO_TEST_CASE(NoHitsMaterialSurface) {
0464 Fixture<NoSurface> f(125_MeV, makeMaterialSurface());
0465
0466
0467 f.state.stage = Acts::PropagatorStage::prePropagation;
0468 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0469 Acts::getDummyLogger());
0470
0471
0472 f.state.stage = Acts::PropagatorStage::postStep;
0473 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0474 Acts::getDummyLogger());
0475 BOOST_CHECK(f.result.isAlive);
0476 CHECK_CLOSE_REL(f.result.particle.energy(), f.e - 125_MeV, tol);
0477 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 1u);
0478 BOOST_CHECK_EQUAL(f.result.hits.size(), 0u);
0479
0480
0481 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0482
0483 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 1);
0484 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 1);
0485
0486 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0487 BOOST_CHECK_EQUAL(f.result.x0Process,
0488 std::numeric_limits<std::size_t>::max());
0489 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0490 BOOST_CHECK_EQUAL(f.result.l0Process,
0491 std::numeric_limits<std::size_t>::max());
0492
0493 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0494 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0495 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0496 CHECK_CLOSE_REL(f.state.stepping.p, f.result.particle.absoluteMomentum(),
0497 tol);
0498
0499
0500 f.state.stage = Acts::PropagatorStage::postStep;
0501 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0502 Acts::getDummyLogger());
0503 BOOST_CHECK(f.result.isAlive);
0504 CHECK_CLOSE_REL(f.result.particle.energy(), f.e - 250_MeV, tol);
0505 BOOST_CHECK_EQUAL(f.result.generatedParticles.size(), 2u);
0506 BOOST_CHECK_EQUAL(f.result.hits.size(), 0u);
0507
0508
0509 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0);
0510
0511 BOOST_CHECK_EQUAL(f.result.particle.pathInX0(), 2);
0512 BOOST_CHECK_EQUAL(f.result.particle.pathInL0(), 2);
0513
0514 BOOST_CHECK_EQUAL(f.result.x0Limit, inf);
0515 BOOST_CHECK_EQUAL(f.result.x0Process,
0516 std::numeric_limits<std::size_t>::max());
0517 BOOST_CHECK_EQUAL(f.result.l0Limit, inf);
0518 BOOST_CHECK_EQUAL(f.result.l0Process,
0519 std::numeric_limits<std::size_t>::max());
0520
0521 BOOST_CHECK_EQUAL(f.state.stepping.pos, f.result.particle.position());
0522 BOOST_CHECK_EQUAL(f.state.stepping.time, f.result.particle.time());
0523 BOOST_CHECK_EQUAL(f.state.stepping.dir, f.result.particle.direction());
0524 BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum());
0525
0526
0527 BOOST_CHECK_EQUAL(f.result.particle.particleId(), f.pid);
0528 BOOST_CHECK_EQUAL(f.result.particle.process(), f.proc);
0529 BOOST_CHECK_EQUAL(f.result.particle.pdg(), f.pdg);
0530 BOOST_CHECK_EQUAL(f.result.particle.charge(), f.q);
0531 BOOST_CHECK_EQUAL(f.result.particle.mass(), f.m);
0532 }
0533
0534 BOOST_AUTO_TEST_CASE(Decay) {
0535
0536 Fixture<NoSurface> f(0_GeV, makeEmptySurface());
0537
0538
0539 const auto gammaInv = f.m / f.e;
0540
0541
0542 f.state.stage = Acts::PropagatorStage::prePropagation;
0543 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0544 Acts::getDummyLogger());
0545
0546
0547 f.state.stage = Acts::PropagatorStage::postStep;
0548 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0549 Acts::getDummyLogger());
0550 BOOST_CHECK(f.result.isAlive);
0551 BOOST_CHECK_EQUAL(f.result.particle.particleId(), f.pid);
0552 BOOST_CHECK_EQUAL(f.result.particle.process(), f.proc);
0553 BOOST_CHECK_EQUAL(f.result.particle.pdg(), f.pdg);
0554 BOOST_CHECK_EQUAL(f.result.particle.charge(), f.q);
0555 BOOST_CHECK_EQUAL(f.result.particle.mass(), f.m);
0556 CHECK_CLOSE_REL(f.result.particle.energy(), f.e, tol);
0557 BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0_ns);
0558
0559
0560 f.state.stage = Acts::PropagatorStage::postStep;
0561 f.state.stepping.time += 1_ns;
0562 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0563 Acts::getDummyLogger());
0564 BOOST_CHECK(f.result.isAlive);
0565 BOOST_CHECK_EQUAL(f.result.particle.particleId(), f.pid);
0566 BOOST_CHECK_EQUAL(f.result.particle.process(), f.proc);
0567 BOOST_CHECK_EQUAL(f.result.particle.pdg(), f.pdg);
0568 BOOST_CHECK_EQUAL(f.result.particle.charge(), f.q);
0569 BOOST_CHECK_EQUAL(f.result.particle.mass(), f.m);
0570 CHECK_CLOSE_REL(f.result.particle.energy(), f.e, tol);
0571 CHECK_CLOSE_REL(f.result.particle.properTime(), gammaInv * 1_ns, tol);
0572
0573
0574 f.state.stage = Acts::PropagatorStage::postStep;
0575 f.state.stepping.time += 1_ns;
0576 f.result.properTimeLimit = f.result.particle.properTime() + gammaInv * 0.5_ns;
0577 f.actor.act(f.state, f.stepper, f.navigator, f.result,
0578 Acts::getDummyLogger());
0579 BOOST_CHECK(!f.result.isAlive);
0580 BOOST_CHECK_EQUAL(f.result.particle.particleId(), f.pid);
0581 BOOST_CHECK_EQUAL(f.result.particle.process(), f.proc);
0582 BOOST_CHECK_EQUAL(f.result.particle.pdg(), f.pdg);
0583 BOOST_CHECK_EQUAL(f.result.particle.charge(), f.q);
0584 BOOST_CHECK_EQUAL(f.result.particle.mass(), f.m);
0585 CHECK_CLOSE_REL(f.result.particle.energy(), f.e, tol);
0586 CHECK_CLOSE_REL(f.result.particle.properTime(), gammaInv * 2_ns, tol);
0587 }
0588
0589 BOOST_AUTO_TEST_SUITE_END()