Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-09 09:28:49

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/ParticleHypothesis.hpp"
0015 #include "Acts/Propagator/detail/MaterialEffectsAccumulator.hpp"
0016 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0017 #include "ActsTests/CommonHelpers/PredefinedMaterials.hpp"
0018 
0019 #include <utility>
0020 
0021 using namespace Acts;
0022 using namespace Acts::UnitLiterals;
0023 
0024 namespace {
0025 
0026 const ParticleHypothesis particle = ParticleHypothesis::pion();
0027 const double momentum = 1_GeV;
0028 const double qOverP = particle.qOverP(momentum, 1);
0029 const double maxXOverX0Step = 0.01;
0030 const Vector3 direction = Vector3::UnitZ();
0031 
0032 detail::MaterialEffectsAccumulator makeAccumulator() {
0033   detail::MaterialEffectsAccumulator accumulator;
0034   accumulator.initialize(maxXOverX0Step, particle, momentum);
0035   return accumulator;
0036 }
0037 
0038 }  // namespace
0039 
0040 namespace ActsTests {
0041 
0042 BOOST_AUTO_TEST_SUITE(PropagatorSuite)
0043 
0044 BOOST_AUTO_TEST_CASE(MaterialEffectsAccumulatorStepBack) {
0045   const Material material = makeSilicon();
0046 
0047   auto overstep = makeAccumulator();
0048   overstep.accumulate(material, 50_mm, qOverP, qOverP);
0049   BOOST_REQUIRE_NO_THROW(overstep.accumulate(material, -5_mm, qOverP, qOverP));
0050 
0051   auto direct = makeAccumulator();
0052   direct.accumulate(material, 45_mm, qOverP, qOverP);
0053 
0054   const auto overstepCov = overstep.computeAdditionalFreeCovariance(direction);
0055   const auto directCov = direct.computeAdditionalFreeCovariance(direction);
0056   BOOST_REQUIRE(overstepCov.has_value());
0057   BOOST_REQUIRE(directCov.has_value());
0058 
0059   for (const auto i : {eFreePos0, eFreeDir0, eFreeQOverP}) {
0060     BOOST_CHECK_GT((*overstepCov)(i, i), 0.);
0061   }
0062   CHECK_CLOSE_REL((*overstepCov)(eFreeDir0, eFreeDir0),
0063                   (*directCov)(eFreeDir0, eFreeDir0), 1e-3);
0064   CHECK_CLOSE_REL((*overstepCov)(eFreePos0, eFreePos0),
0065                   (*directCov)(eFreePos0, eFreePos0), 1e-3);
0066   CHECK_CLOSE_REL((*overstepCov)(eFreePos0, eFreeDir0),
0067                   (*directCov)(eFreePos0, eFreeDir0), 1e-3);
0068   CHECK_CLOSE_REL((*overstepCov)(eFreeQOverP, eFreeQOverP),
0069                   (*directCov)(eFreeQOverP, eFreeQOverP), 1e-3);
0070 }
0071 
0072 BOOST_AUTO_TEST_CASE(MaterialEffectsAccumulatorStepBackBeyondStart) {
0073   auto accumulator = makeAccumulator();
0074   accumulator.accumulate(makeSilicon(), 1_mm, qOverP, qOverP);
0075   BOOST_REQUIRE_NO_THROW(
0076       accumulator.accumulate(makeSilicon(), -2_mm, qOverP, qOverP));
0077   BOOST_CHECK(accumulator.isVacuum());
0078   BOOST_CHECK(!accumulator.computeAdditionalFreeCovariance(direction));
0079 }
0080 
0081 void checkSameCovariance(detail::MaterialEffectsAccumulator& overstep,
0082                          detail::MaterialEffectsAccumulator& direct) {
0083   const auto overstepCov = overstep.computeAdditionalFreeCovariance(direction);
0084   const auto directCov = direct.computeAdditionalFreeCovariance(direction);
0085   BOOST_REQUIRE(overstepCov.has_value());
0086   BOOST_REQUIRE(directCov.has_value());
0087   for (const auto& [i, j] :
0088        {std::pair{eFreeDir0, eFreeDir0}, std::pair{eFreePos0, eFreePos0},
0089         std::pair{eFreePos0, eFreeDir0}, std::pair{eFreeQOverP, eFreeQOverP}}) {
0090     CHECK_CLOSE_REL((*overstepCov)(i, j), (*directCov)(i, j), 1e-3);
0091   }
0092 }
0093 
0094 BOOST_AUTO_TEST_CASE(MaterialEffectsAccumulatorStepBackDenseOverstep) {
0095   // Overstep from a light into a dense material, then step back. The step back
0096   // has to remove the dense material, not the average one.
0097   auto overstep = makeAccumulator();
0098   overstep.accumulate(makeLiquidArgon(), 100_mm, qOverP, qOverP);
0099   overstep.accumulate(makeIron(), 1_mm, qOverP, qOverP);
0100   overstep.accumulate(makeIron(), -1_mm, qOverP, qOverP);
0101 
0102   auto direct = makeAccumulator();
0103   direct.accumulate(makeLiquidArgon(), 100_mm, qOverP, qOverP);
0104 
0105   checkSameCovariance(overstep, direct);
0106 }
0107 
0108 BOOST_AUTO_TEST_CASE(MaterialEffectsAccumulatorStepBackVacuum) {
0109   // Stepping back through vacuum must not remove any material.
0110   auto overstep = makeAccumulator();
0111   overstep.accumulate(makeSilicon(), 10_mm, qOverP, qOverP);
0112   overstep.accumulate(Material::Vacuum(), 5_mm, qOverP, qOverP);
0113   overstep.accumulate(Material::Vacuum(), -5_mm, qOverP, qOverP);
0114 
0115   auto direct = makeAccumulator();
0116   direct.accumulate(makeSilicon(), 10_mm, qOverP, qOverP);
0117 
0118   checkSameCovariance(overstep, direct);
0119 }
0120 
0121 BOOST_AUTO_TEST_CASE(MaterialEffectsAccumulatorStepBackMismatchedMaterial) {
0122   // The step back claims more matter than was accumulated, e.g. for binned
0123   // volume material sampled at a different position. The result must stay
0124   // finite.
0125   auto accumulator = makeAccumulator();
0126   accumulator.accumulate(makeLiquidArgon(), 10_mm, qOverP, qOverP);
0127   BOOST_REQUIRE_NO_THROW(
0128       accumulator.accumulate(makeIron(), -5_mm, qOverP, qOverP));
0129   const auto cov = accumulator.computeAdditionalFreeCovariance(direction);
0130   BOOST_REQUIRE(cov.has_value());
0131   BOOST_CHECK(cov->allFinite());
0132 }
0133 
0134 BOOST_AUTO_TEST_SUITE_END()
0135 
0136 }  // namespace ActsTests