Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AverageMaterialsTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file AverageMaterialsTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/unit_test.hpp>
10 
16 
17 #include <cmath>
18 #include <limits>
19 
20 namespace {
21 
23 
24 constexpr auto eps = std::numeric_limits<float>::epsilon();
25 
26 // vacuum w/ different thickness
27 const Acts::MaterialSlab zeroVacuum = Acts::MaterialSlab(0.0f);
28 const Acts::MaterialSlab unitVacuum = Acts::MaterialSlab(1.0f);
29 // same material corresponding to 0%, 1% and 100% radiation/interaction length
33 
34 } // namespace
35 
36 BOOST_AUTO_TEST_SUITE(AverageMaterials)
37 
38 // average two identical slabs
39 
40 BOOST_AUTO_TEST_CASE(CombineSlabsVacuum) {
41  // vacuum with zero thickness
42  {
43  auto slab = combineSlabs(zeroVacuum, zeroVacuum);
44  BOOST_CHECK(not slab.material());
45  BOOST_CHECK_EQUAL(slab.thickness(), 0.0f);
46  BOOST_CHECK_EQUAL(slab.thicknessInX0(), 0.0f);
47  BOOST_CHECK_EQUAL(slab.thicknessInL0(), 0.0f);
48  }
49  // vacuum with unit thickness
50  {
51  auto slab = combineSlabs(unitVacuum, unitVacuum);
52  BOOST_CHECK(not slab.material());
53  BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
54  BOOST_CHECK_EQUAL(slab.thicknessInX0(), 0.0f);
55  BOOST_CHECK_EQUAL(slab.thicknessInL0(), 0.0f);
56  }
57 }
58 
59 BOOST_AUTO_TEST_CASE(CombineSlabsPercent) {
60  auto slab = combineSlabs(percent, percent);
61  // combining two identical slabs must give the same average material
62  BOOST_CHECK(slab.material());
63  BOOST_CHECK_EQUAL(slab.material(), percent);
64  // thickness-like properties must double
65  BOOST_CHECK_EQUAL(slab.thickness(), 2 * percent.thickness());
66  BOOST_CHECK_EQUAL(slab.thicknessInX0(), 2 * percent.thicknessInX0());
67  BOOST_CHECK_EQUAL(slab.thicknessInL0(), 2 * percent.thicknessInL0());
68 }
69 
70 BOOST_AUTO_TEST_CASE(CombineSlabsUnit) {
71  auto slab = combineSlabs(unit, unit);
72  // combining two identical slabs must give the same average material
73  BOOST_CHECK(slab.material());
74  BOOST_CHECK_EQUAL(slab.material(), unit);
75  // thickness-like properties must double
76  BOOST_CHECK_EQUAL(slab.thickness(), 2 * unit.thickness());
77  BOOST_CHECK_EQUAL(slab.thicknessInX0(), 2 * unit.thicknessInX0());
78  BOOST_CHECK_EQUAL(slab.thicknessInL0(), 2 * unit.thicknessInL0());
79 }
80 
81 // average a non-vacuum slab and a zero-thickness vacuum slab
82 
83 BOOST_AUTO_TEST_CASE(CombineSlabsPercentZeroVacuum) {
84  {
85  auto slab = combineSlabs(percent, zeroVacuum);
86  BOOST_CHECK(slab.material());
87  BOOST_CHECK_EQUAL(slab.material(), percent);
88  BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness());
89  BOOST_CHECK_EQUAL(slab.thicknessInX0(), percent.thicknessInX0());
90  BOOST_CHECK_EQUAL(slab.thicknessInL0(), percent.thicknessInL0());
91  }
92  // reverse input order
93  {
94  auto slab = combineSlabs(zeroVacuum, percent);
95  BOOST_CHECK(slab.material());
96  BOOST_CHECK_EQUAL(slab.material(), percent);
97  BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness());
98  BOOST_CHECK_EQUAL(slab.thicknessInX0(), percent.thicknessInX0());
99  BOOST_CHECK_EQUAL(slab.thicknessInL0(), percent.thicknessInL0());
100  }
101 }
102 
103 BOOST_AUTO_TEST_CASE(CombineSlabsUnitZeroVacuum) {
104  {
105  auto slab = combineSlabs(unit, zeroVacuum);
106  BOOST_CHECK(slab.material());
107  BOOST_CHECK_EQUAL(slab.material(), unit);
108  BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
109  BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
110  BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
111  }
112  // reverse input order
113  {
114  auto slab = combineSlabs(zeroVacuum, unit);
115  BOOST_CHECK(slab.material());
116  BOOST_CHECK_EQUAL(slab.material(), unit);
117  BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
118  BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
119  BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
120  }
121 }
122 
123 // average two non-vacuum slabs with the same material but different thickness
124 
125 BOOST_AUTO_TEST_CASE(CombineSlabsPercentUnit) {
126  // the two slabs have the same material -> average should be identical
127  {
128  auto slab = combineSlabs(percent, unit);
129  BOOST_CHECK(slab.material());
130  BOOST_CHECK_EQUAL(slab.material(), percent);
131  BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness() + unit.thickness());
132  BOOST_CHECK_EQUAL(slab.thicknessInX0(),
133  percent.thicknessInX0() + unit.thicknessInX0());
134  BOOST_CHECK_EQUAL(slab.thicknessInL0(),
135  percent.thicknessInL0() + unit.thicknessInL0());
136  }
137  // reverse input order
138  {
139  auto slab = combineSlabs(unit, percent);
140  BOOST_CHECK(slab.material());
141  BOOST_CHECK_EQUAL(slab.material(), unit);
142  BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness() + percent.thickness());
143  BOOST_CHECK_EQUAL(slab.thicknessInX0(),
144  percent.thicknessInX0() + unit.thicknessInX0());
145  BOOST_CHECK_EQUAL(slab.thicknessInL0(),
146  percent.thicknessInL0() + unit.thicknessInL0());
147  }
148 }
149 
150 // average two non-vacuum slabs where one has zero thickness
151 
152 BOOST_AUTO_TEST_CASE(CombineSlabsUnitZero) {
153  // the two slabs have the same material -> average should be identical
154  {
155  auto slab = combineSlabs(unit, zero);
156  BOOST_CHECK(slab.material());
157  BOOST_CHECK_EQUAL(slab.material(), unit);
158  BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
159  BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
160  BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
161  }
162  // reverse input order
163  {
164  auto slab = combineSlabs(zero, unit);
165  BOOST_CHECK(slab.material());
166  BOOST_CHECK_EQUAL(slab.material(), unit);
167  BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
168  BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
169  BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
170  }
171 }
172 
173 // average a non-vacuum and a vacuum slab w/ equal thickness
174 
175 BOOST_AUTO_TEST_CASE(CombineSlabsEqualThicknessVacuum) {
176  const auto mat = Acts::Test::makeSilicon();
177  const auto slabMat = Acts::MaterialSlab(mat, 1.0f);
178  const auto slabVac = Acts::MaterialSlab(Acts::Material(), 1.0f);
179  {
180  auto slab = combineSlabs(slabMat, slabVac);
181  BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
182  BOOST_CHECK_EQUAL(slab.thicknessInX0(), slabMat.thicknessInX0());
183  BOOST_CHECK_EQUAL(slab.thicknessInL0(), slabMat.thicknessInL0());
184  BOOST_CHECK(slab.material());
185  // atomic mass and nuclear charge are per atom, adding any amount vacuum
186  // does not change the average atom properties only their density
187  BOOST_CHECK_EQUAL(slab.material().Ar(), mat.Ar());
188  BOOST_CHECK_EQUAL(slab.material().Z(), 0.5 * mat.Z());
189  // we have the same type of interactions just spread over twice the length
190  CHECK_CLOSE_REL(slab.material().X0(), 2.0f * mat.X0(), eps);
191  CHECK_CLOSE_REL(slab.material().L0(), 2.0f * mat.L0(), eps);
192  // we have the same atoms just spread over more volume
193  BOOST_CHECK_EQUAL(slab.material().molarDensity(),
194  0.5f * mat.molarDensity());
195  }
196  // reverse input order
197  {
198  auto slab = combineSlabs(slabVac, slabMat);
199  BOOST_CHECK(slab.material());
200  BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
201  BOOST_CHECK_EQUAL(slab.thicknessInX0(), slabMat.thicknessInX0());
202  BOOST_CHECK_EQUAL(slab.thicknessInL0(), slabMat.thicknessInL0());
203  // atomic mass and nuclear charge are per atom, adding any amount vacuum
204  // does not change the average atom properties only their density
205  BOOST_CHECK_EQUAL(slab.material().Ar(), mat.Ar());
206  BOOST_CHECK_EQUAL(slab.material().Z(), 0.5 * mat.Z());
207  // we have the same type of interactions just spread over twice the length
208  CHECK_CLOSE_REL(slab.material().X0(), 2.0f * mat.X0(), eps);
209  CHECK_CLOSE_REL(slab.material().L0(), 2.0f * mat.L0(), eps);
210  // we have the same atoms just spread over more volume
211  BOOST_CHECK_EQUAL(slab.material().molarDensity(),
212  0.5f * mat.molarDensity());
213  }
214 }
215 
216 // average two non-vacuum slabs w/ different material and different thickness
217 
218 BOOST_AUTO_TEST_CASE(CombineSlabs) {
219  const auto mat0 = Acts::Material::fromMolarDensity(1, 1, 8, 12, 2);
220  const auto mat1 = Acts::Material::fromMolarDensity(2, 2, 2, 6, 5);
221  const auto slabMat0 = Acts::MaterialSlab(mat0, 0.5f);
222  const auto slabMat1 = Acts::MaterialSlab(mat1, 1.0f);
223  // verify derived quantities for the input slabs. these tests are not really
224  // needed, but to show the input values for the tests below.
225  BOOST_CHECK_EQUAL(slabMat0.thickness(), 0.5f);
226  BOOST_CHECK_EQUAL(slabMat0.thicknessInX0(), 0.5f);
227  BOOST_CHECK_EQUAL(slabMat0.thicknessInL0(), 0.5f);
228  BOOST_CHECK_EQUAL(slabMat1.thickness(), 1.0f);
229  BOOST_CHECK_EQUAL(slabMat1.thicknessInX0(), 0.5f);
230  BOOST_CHECK_EQUAL(slabMat1.thicknessInL0(), 0.5f);
231  // check combined slabs
232  {
233  auto slab = combineSlabs(slabMat0, slabMat1);
234  BOOST_CHECK(slab.material());
235  BOOST_CHECK_EQUAL(slab.thickness(), 1.5f);
236  BOOST_CHECK_EQUAL(slab.thicknessInX0(), 1.0f);
237  BOOST_CHECK_EQUAL(slab.thicknessInL0(), 1.0f);
238  BOOST_CHECK_EQUAL(slab.material().X0(), 1.5f);
239  BOOST_CHECK_EQUAL(slab.material().L0(), 1.5f);
240  BOOST_CHECK_EQUAL(slab.material().Ar(), 3.0f);
241  BOOST_CHECK_EQUAL(slab.material().Z(),
242  static_cast<float>(
243  exp((0.5 / 1.5) * log(12.0) + (1.0 / 1.5) * log(6))));
244  BOOST_CHECK_EQUAL(slab.material().molarDensity(), 4.0f);
245  }
246  // reverse input order
247  {
248  auto slab = combineSlabs(slabMat0, slabMat1);
249  BOOST_CHECK(slab.material());
250  BOOST_CHECK_EQUAL(slab.thickness(), 1.5f);
251  BOOST_CHECK_EQUAL(slab.thicknessInX0(), 1.0f);
252  BOOST_CHECK_EQUAL(slab.thicknessInL0(), 1.0f);
253  BOOST_CHECK_EQUAL(slab.material().X0(), 1.5f);
254  BOOST_CHECK_EQUAL(slab.material().L0(), 1.5f);
255  BOOST_CHECK_EQUAL(slab.material().Ar(), 3.0f);
256  BOOST_CHECK_EQUAL(slab.material().Z(),
257  static_cast<float>(
258  exp((0.5 / 1.5) * log(12.0) + (1.0 / 1.5) * log(6))));
259  BOOST_CHECK_EQUAL(slab.material().molarDensity(), 4.0f);
260  }
261 }
262 
263 BOOST_AUTO_TEST_SUITE_END()