Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:22

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2020 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Material/Material.hpp"
0012 #include "Acts/Material/MaterialSlab.hpp"
0013 #include "Acts/Material/detail/AverageMaterials.hpp"
0014 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0015 #include "Acts/Tests/CommonHelpers/PredefinedMaterials.hpp"
0016 
0017 #include <cmath>
0018 #include <limits>
0019 
0020 namespace {
0021 
0022 using Acts::detail::combineSlabs;
0023 
0024 constexpr auto eps = std::numeric_limits<float>::epsilon();
0025 
0026 // vacuum w/ different thickness
0027 const Acts::MaterialSlab zeroVacuum = Acts::MaterialSlab(0.0f);
0028 const Acts::MaterialSlab unitVacuum = Acts::MaterialSlab(1.0f);
0029 // same material corresponding to 0%, 1% and 100% radiation/interaction length
0030 const Acts::MaterialSlab zero(Acts::Test::makeSilicon(), 0.0f);
0031 const Acts::MaterialSlab percent = Acts::Test::makePercentSlab();
0032 const Acts::MaterialSlab unit = Acts::Test::makeUnitSlab();
0033 
0034 }  // namespace
0035 
0036 BOOST_AUTO_TEST_SUITE(AverageMaterials)
0037 
0038 // average two identical slabs
0039 
0040 BOOST_AUTO_TEST_CASE(CombineSlabsVacuum) {
0041   // vacuum with zero thickness
0042   {
0043     auto slab = combineSlabs(zeroVacuum, zeroVacuum);
0044     BOOST_CHECK(!slab.material());
0045     BOOST_CHECK_EQUAL(slab.thickness(), 0.0f);
0046     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 0.0f);
0047     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 0.0f);
0048   }
0049   // vacuum with unit thickness
0050   {
0051     auto slab = combineSlabs(unitVacuum, unitVacuum);
0052     BOOST_CHECK(!slab.material());
0053     BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
0054     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 0.0f);
0055     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 0.0f);
0056   }
0057 }
0058 
0059 BOOST_AUTO_TEST_CASE(CombineSlabsPercent) {
0060   auto slab = combineSlabs(percent, percent);
0061   // combining two identical slabs must give the same average material
0062   BOOST_CHECK(slab.material());
0063   BOOST_CHECK_EQUAL(slab.material(), percent);
0064   // thickness-like properties must double
0065   BOOST_CHECK_EQUAL(slab.thickness(), 2 * percent.thickness());
0066   BOOST_CHECK_EQUAL(slab.thicknessInX0(), 2 * percent.thicknessInX0());
0067   BOOST_CHECK_EQUAL(slab.thicknessInL0(), 2 * percent.thicknessInL0());
0068 }
0069 
0070 BOOST_AUTO_TEST_CASE(CombineSlabsUnit) {
0071   auto slab = combineSlabs(unit, unit);
0072   // combining two identical slabs must give the same average material
0073   BOOST_CHECK(slab.material());
0074   BOOST_CHECK_EQUAL(slab.material(), unit);
0075   // thickness-like properties must double
0076   BOOST_CHECK_EQUAL(slab.thickness(), 2 * unit.thickness());
0077   BOOST_CHECK_EQUAL(slab.thicknessInX0(), 2 * unit.thicknessInX0());
0078   BOOST_CHECK_EQUAL(slab.thicknessInL0(), 2 * unit.thicknessInL0());
0079 }
0080 
0081 // average a non-vacuum slab and a zero-thickness vacuum slab
0082 
0083 BOOST_AUTO_TEST_CASE(CombineSlabsPercentZeroVacuum) {
0084   {
0085     auto slab = combineSlabs(percent, zeroVacuum);
0086     BOOST_CHECK(slab.material());
0087     BOOST_CHECK_EQUAL(slab.material(), percent);
0088     BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness());
0089     BOOST_CHECK_EQUAL(slab.thicknessInX0(), percent.thicknessInX0());
0090     BOOST_CHECK_EQUAL(slab.thicknessInL0(), percent.thicknessInL0());
0091   }
0092   // reverse input order
0093   {
0094     auto slab = combineSlabs(zeroVacuum, percent);
0095     BOOST_CHECK(slab.material());
0096     BOOST_CHECK_EQUAL(slab.material(), percent);
0097     BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness());
0098     BOOST_CHECK_EQUAL(slab.thicknessInX0(), percent.thicknessInX0());
0099     BOOST_CHECK_EQUAL(slab.thicknessInL0(), percent.thicknessInL0());
0100   }
0101 }
0102 
0103 BOOST_AUTO_TEST_CASE(CombineSlabsUnitZeroVacuum) {
0104   {
0105     auto slab = combineSlabs(unit, zeroVacuum);
0106     BOOST_CHECK(slab.material());
0107     BOOST_CHECK_EQUAL(slab.material(), unit);
0108     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0109     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0110     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0111   }
0112   // reverse input order
0113   {
0114     auto slab = combineSlabs(zeroVacuum, unit);
0115     BOOST_CHECK(slab.material());
0116     BOOST_CHECK_EQUAL(slab.material(), unit);
0117     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0118     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0119     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0120   }
0121 }
0122 
0123 // average two non-vacuum slabs with the same material but different thickness
0124 
0125 BOOST_AUTO_TEST_CASE(CombineSlabsPercentUnit) {
0126   // the two slabs have the same material -> average should be identical
0127   {
0128     auto slab = combineSlabs(percent, unit);
0129     BOOST_CHECK(slab.material());
0130     BOOST_CHECK_EQUAL(slab.material(), percent);
0131     BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness() + unit.thickness());
0132     BOOST_CHECK_EQUAL(slab.thicknessInX0(),
0133                       percent.thicknessInX0() + unit.thicknessInX0());
0134     BOOST_CHECK_EQUAL(slab.thicknessInL0(),
0135                       percent.thicknessInL0() + unit.thicknessInL0());
0136   }
0137   // reverse input order
0138   {
0139     auto slab = combineSlabs(unit, percent);
0140     BOOST_CHECK(slab.material());
0141     BOOST_CHECK_EQUAL(slab.material(), unit);
0142     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness() + percent.thickness());
0143     BOOST_CHECK_EQUAL(slab.thicknessInX0(),
0144                       percent.thicknessInX0() + unit.thicknessInX0());
0145     BOOST_CHECK_EQUAL(slab.thicknessInL0(),
0146                       percent.thicknessInL0() + unit.thicknessInL0());
0147   }
0148 }
0149 
0150 // average two non-vacuum slabs where one has zero thickness
0151 
0152 BOOST_AUTO_TEST_CASE(CombineSlabsUnitZero) {
0153   // the two slabs have the same material -> average should be identical
0154   {
0155     auto slab = combineSlabs(unit, zero);
0156     BOOST_CHECK(slab.material());
0157     BOOST_CHECK_EQUAL(slab.material(), unit);
0158     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0159     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0160     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0161   }
0162   // reverse input order
0163   {
0164     auto slab = combineSlabs(zero, unit);
0165     BOOST_CHECK(slab.material());
0166     BOOST_CHECK_EQUAL(slab.material(), unit);
0167     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0168     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0169     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0170   }
0171 }
0172 
0173 // average a non-vacuum and a vacuum slab w/ equal thickness
0174 
0175 BOOST_AUTO_TEST_CASE(CombineSlabsEqualThicknessVacuum) {
0176   const auto mat = Acts::Test::makeSilicon();
0177   const auto slabMat = Acts::MaterialSlab(mat, 1.0f);
0178   const auto slabVac = Acts::MaterialSlab(Acts::Material(), 1.0f);
0179   {
0180     auto slab = combineSlabs(slabMat, slabVac);
0181     BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
0182     BOOST_CHECK_EQUAL(slab.thicknessInX0(), slabMat.thicknessInX0());
0183     BOOST_CHECK_EQUAL(slab.thicknessInL0(), slabMat.thicknessInL0());
0184     BOOST_CHECK(slab.material());
0185     // atomic mass and nuclear charge are per atom, adding any amount vacuum
0186     // does not change the average atom properties only their density
0187     BOOST_CHECK_EQUAL(slab.material().Ar(), mat.Ar());
0188     BOOST_CHECK_EQUAL(slab.material().Z(), 0.5 * mat.Z());
0189     // we have the same type of interactions just spread over twice the length
0190     CHECK_CLOSE_REL(slab.material().X0(), 2.0f * mat.X0(), eps);
0191     CHECK_CLOSE_REL(slab.material().L0(), 2.0f * mat.L0(), eps);
0192     // we have the same atoms just spread over more volume
0193     BOOST_CHECK_EQUAL(slab.material().molarDensity(),
0194                       0.5f * mat.molarDensity());
0195   }
0196   // reverse input order
0197   {
0198     auto slab = combineSlabs(slabVac, slabMat);
0199     BOOST_CHECK(slab.material());
0200     BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
0201     BOOST_CHECK_EQUAL(slab.thicknessInX0(), slabMat.thicknessInX0());
0202     BOOST_CHECK_EQUAL(slab.thicknessInL0(), slabMat.thicknessInL0());
0203     // atomic mass and nuclear charge are per atom, adding any amount vacuum
0204     // does not change the average atom properties only their density
0205     BOOST_CHECK_EQUAL(slab.material().Ar(), mat.Ar());
0206     BOOST_CHECK_EQUAL(slab.material().Z(), 0.5 * mat.Z());
0207     // we have the same type of interactions just spread over twice the length
0208     CHECK_CLOSE_REL(slab.material().X0(), 2.0f * mat.X0(), eps);
0209     CHECK_CLOSE_REL(slab.material().L0(), 2.0f * mat.L0(), eps);
0210     // we have the same atoms just spread over more volume
0211     BOOST_CHECK_EQUAL(slab.material().molarDensity(),
0212                       0.5f * mat.molarDensity());
0213   }
0214 }
0215 
0216 // average two non-vacuum slabs w/ different material and different thickness
0217 
0218 BOOST_AUTO_TEST_CASE(CombineSlabs) {
0219   const auto mat0 = Acts::Material::fromMolarDensity(1, 1, 8, 12, 2);
0220   const auto mat1 = Acts::Material::fromMolarDensity(2, 2, 2, 6, 5);
0221   const auto slabMat0 = Acts::MaterialSlab(mat0, 0.5f);
0222   const auto slabMat1 = Acts::MaterialSlab(mat1, 1.0f);
0223   // verify derived quantities for the input slabs. these tests are not really
0224   // needed, but to show the input values for the tests below.
0225   BOOST_CHECK_EQUAL(slabMat0.thickness(), 0.5f);
0226   BOOST_CHECK_EQUAL(slabMat0.thicknessInX0(), 0.5f);
0227   BOOST_CHECK_EQUAL(slabMat0.thicknessInL0(), 0.5f);
0228   BOOST_CHECK_EQUAL(slabMat1.thickness(), 1.0f);
0229   BOOST_CHECK_EQUAL(slabMat1.thicknessInX0(), 0.5f);
0230   BOOST_CHECK_EQUAL(slabMat1.thicknessInL0(), 0.5f);
0231   // check combined slabs
0232   {
0233     auto slab = combineSlabs(slabMat0, slabMat1);
0234     BOOST_CHECK(slab.material());
0235     BOOST_CHECK_EQUAL(slab.thickness(), 1.5f);
0236     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 1.0f);
0237     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 1.0f);
0238     BOOST_CHECK_EQUAL(slab.material().X0(), 1.5f);
0239     BOOST_CHECK_EQUAL(slab.material().L0(), 1.5f);
0240     BOOST_CHECK_EQUAL(slab.material().Ar(), 3.0f);
0241     BOOST_CHECK_EQUAL(slab.material().Z(),
0242                       static_cast<float>(
0243                           exp((0.5 / 1.5) * log(12.0) + (1.0 / 1.5) * log(6))));
0244     BOOST_CHECK_EQUAL(slab.material().molarDensity(), 4.0f);
0245   }
0246   // reverse input order
0247   {
0248     auto slab = combineSlabs(slabMat0, slabMat1);
0249     BOOST_CHECK(slab.material());
0250     BOOST_CHECK_EQUAL(slab.thickness(), 1.5f);
0251     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 1.0f);
0252     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 1.0f);
0253     BOOST_CHECK_EQUAL(slab.material().X0(), 1.5f);
0254     BOOST_CHECK_EQUAL(slab.material().L0(), 1.5f);
0255     BOOST_CHECK_EQUAL(slab.material().Ar(), 3.0f);
0256     BOOST_CHECK_EQUAL(slab.material().Z(),
0257                       static_cast<float>(
0258                           exp((0.5 / 1.5) * log(12.0) + (1.0 / 1.5) * log(6))));
0259     BOOST_CHECK_EQUAL(slab.material().molarDensity(), 4.0f);
0260   }
0261 }
0262 
0263 BOOST_AUTO_TEST_SUITE_END()