File indexing completed on 2025-11-06 09:18:59
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/Geometry/GeometryContext.hpp"
0013 #include "Acts/Geometry/GeometryIdentifier.hpp"
0014 #include "Acts/Material/Material.hpp"
0015 #include "Acts/Material/MaterialInteraction.hpp"
0016 #include "Acts/Material/MaterialInteractionAssignment.hpp"
0017 #include "Acts/Material/MaterialSlab.hpp"
0018 #include "Acts/Material/interface/IAssignmentFinder.hpp"
0019 #include "Acts/Propagator/SurfaceCollector.hpp"
0020 #include "Acts/Surfaces/CylinderSurface.hpp"
0021 #include "Acts/Utilities/Enumerate.hpp"
0022 #include "Acts/Utilities/VectorHelpers.hpp"
0023
0024 #include <limits>
0025
0026 using namespace Acts;
0027
0028 namespace ActsTests {
0029
0030 auto tContext = GeometryContext();
0031
0032 BOOST_AUTO_TEST_SUITE(MaterialSuite)
0033
0034 BOOST_AUTO_TEST_CASE(AssignToClosest) {
0035
0036 std::vector<std::shared_ptr<Surface>> surfaces = {
0037 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 20.0, 100.0),
0038 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 30.0, 100.0),
0039 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 50.0,
0040 100.0)};
0041
0042 for (auto [is, surface] : enumerate(surfaces)) {
0043 surface->assignGeometryId(GeometryIdentifier().withSensitive(is + 1));
0044 }
0045
0046 std::vector<IAssignmentFinder::SurfaceAssignment> intersectedSurfaces = {
0047 {surfaces[0].get(), {20., 0., 0.}, {1., 0., 0.}},
0048 {surfaces[1].get(), {30., 0., 0.}, {1., 0., 0.}},
0049 {surfaces[2].get(), {50., 0., 0.}, {1., 0., 0.}}};
0050
0051
0052 Material material = Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0);
0053
0054 std::vector<MaterialInteraction> materialInteractions;
0055 materialInteractions.reserve(50);
0056
0057 for (unsigned int i = 1; i < 50; ++i) {
0058 MaterialInteraction materialInteraction;
0059 materialInteraction.materialSlab = MaterialSlab(material, 0.1);
0060 materialInteraction.position = Vector3{i * 1.0, 0, 0};
0061 materialInteraction.direction = Vector3{1.0, 0., 0.};
0062 materialInteractions.push_back(materialInteraction);
0063 }
0064
0065 MaterialInteractionAssignment::Options options;
0066
0067
0068 auto [assigned, unassigned, surfacesLeft] =
0069 MaterialInteractionAssignment::assign(tContext, materialInteractions,
0070 intersectedSurfaces, options);
0071
0072
0073 BOOST_CHECK_EQUAL(assigned.size(), materialInteractions.size());
0074 BOOST_CHECK_EQUAL(unassigned.size(), 0u);
0075 BOOST_CHECK_EQUAL(surfacesLeft.size(), 0u);
0076
0077
0078 for (const auto& mi : assigned) {
0079 double minDistance = std::numeric_limits<double>::max();
0080 const Surface* closestSurface = nullptr;
0081 for (const auto& [surface, position, direction] : intersectedSurfaces) {
0082 double distance = (mi.position - position).norm();
0083 if (distance < minDistance) {
0084 minDistance = distance;
0085 closestSurface = surface;
0086 }
0087 }
0088 BOOST_CHECK_EQUAL(mi.surface, closestSurface);
0089 }
0090 }
0091
0092 BOOST_AUTO_TEST_CASE(AssignToClosest_withGlobalVeto) {
0093
0094 std::vector<std::shared_ptr<Surface>> surfaces = {
0095 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 20.0, 100.0),
0096 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 30.0, 100.0),
0097 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 50.0,
0098 100.0)};
0099
0100 for (auto [is, surface] : enumerate(surfaces)) {
0101 surface->assignGeometryId(GeometryIdentifier().withSensitive(is + 1));
0102 }
0103
0104 std::vector<IAssignmentFinder::SurfaceAssignment> intersectedSurfaces = {
0105 {surfaces[0].get(), {20., 0., 0.}, {1., 0., 0.}},
0106 {surfaces[1].get(), {30., 0., 0.}, {1., 0., 0.}},
0107 {surfaces[2].get(), {50., 0., 0.}, {1., 0., 0.}}};
0108
0109
0110 Material material = Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0);
0111
0112 std::vector<MaterialInteraction> materialInteractions;
0113 materialInteractions.reserve(50);
0114
0115 for (unsigned int i = 1; i < 50; ++i) {
0116 MaterialInteraction materialInteraction;
0117 materialInteraction.materialSlab = MaterialSlab(material, 0.1);
0118 materialInteraction.position = Vector3{i * 1.0, 0, 0};
0119 materialInteraction.direction = Vector3{1.0, 0., 0.};
0120 materialInteractions.push_back(materialInteraction);
0121 }
0122
0123
0124 struct RadialVeto {
0125 double rMax = 40.0;
0126 bool operator()(const MaterialInteraction& mi) const {
0127 return VectorHelpers::perp(mi.position) > rMax;
0128 }
0129 };
0130 MaterialInteractionAssignment::Options options;
0131 options.globalVetos.push_back(RadialVeto{40});
0132
0133
0134 auto [assigned, unassigned, surfacesLeft] =
0135 MaterialInteractionAssignment::assign(tContext, materialInteractions,
0136 intersectedSurfaces, options);
0137
0138
0139 BOOST_CHECK_EQUAL(assigned.size(), 40u);
0140 BOOST_CHECK_EQUAL(unassigned.size(), 9u);
0141 BOOST_CHECK_EQUAL(surfacesLeft.size(), 1u);
0142 }
0143
0144 BOOST_AUTO_TEST_CASE(AssignToClosest_withLocalVeto) {
0145
0146 std::vector<std::shared_ptr<Surface>> surfaces = {
0147 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 20.0, 100.0),
0148 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 30.0, 100.0),
0149 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 50.0,
0150 100.0)};
0151
0152 for (auto [is, surface] : enumerate(surfaces)) {
0153 surface->assignGeometryId(GeometryIdentifier().withSensitive(is + 1));
0154 }
0155
0156 std::vector<IAssignmentFinder::SurfaceAssignment> intersectedSurfaces = {
0157 {surfaces[0].get(), {20., 0., 0.}, {1., 0., 0.}},
0158 {surfaces[1].get(), {30., 0., 0.}, {1., 0., 0.}},
0159 {surfaces[2].get(), {50., 0., 0.}, {1., 0., 0.}}};
0160
0161
0162 Material material = Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0);
0163
0164 std::vector<MaterialInteraction> materialInteractions;
0165 materialInteractions.reserve(50);
0166
0167 for (unsigned int i = 1; i < 50; ++i) {
0168 MaterialInteraction materialInteraction;
0169 materialInteraction.materialSlab = MaterialSlab(material, 0.1);
0170 materialInteraction.position = Vector3{i * 1.0, 0, 0};
0171 materialInteraction.direction = Vector3{1.0, 0., 0.};
0172 materialInteractions.push_back(materialInteraction);
0173 }
0174
0175
0176 struct VetoThisOne {
0177 bool operator()(
0178 const MaterialInteraction& ,
0179 const IAssignmentFinder::SurfaceAssignment& )
0180 const {
0181 return true;
0182 }
0183 };
0184
0185
0186 std::vector<
0187 std::pair<GeometryIdentifier, MaterialInteractionAssignment::LocalVeto>>
0188 localVetoVector = {
0189 {GeometryIdentifier().withSensitive(2), VetoThisOne{}}};
0190 GeometryHierarchyMap<MaterialInteractionAssignment::LocalVeto> localVetos(
0191 localVetoVector);
0192 MaterialInteractionAssignment::Options options;
0193 options.localVetos = localVetos;
0194
0195
0196 auto [assigned, unassigned, surfacesLeft] =
0197 MaterialInteractionAssignment::assign(tContext, materialInteractions,
0198 intersectedSurfaces, options);
0199
0200
0201 BOOST_CHECK_EQUAL(assigned.size(), 34u);
0202 BOOST_CHECK_EQUAL(unassigned.size(), 15u);
0203 BOOST_CHECK_EQUAL(surfacesLeft.size(), 1u);
0204 }
0205
0206 BOOST_AUTO_TEST_CASE(AssignToClosest_withReassignment) {
0207
0208 std::vector<std::shared_ptr<Surface>> surfaces = {
0209 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 20.0, 100.0),
0210 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 30.0, 100.0),
0211 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 50.0,
0212 100.0)};
0213
0214 for (auto [is, surface] : enumerate(surfaces)) {
0215 surface->assignGeometryId(GeometryIdentifier().withSensitive(is + 1));
0216 }
0217
0218 std::vector<IAssignmentFinder::SurfaceAssignment> intersectedSurfaces = {
0219 {surfaces[0].get(), {20., 0., 0.}, {1., 0., 0.}},
0220 {surfaces[1].get(), {30., 0., 0.}, {1., 0., 0.}},
0221 {surfaces[2].get(), {50., 0., 0.}, {1., 0., 0.}}};
0222
0223
0224 Material material = Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0);
0225
0226 std::vector<MaterialInteraction> materialInteractions;
0227 materialInteractions.reserve(50);
0228
0229 for (unsigned int i = 1; i < 50; ++i) {
0230 MaterialInteraction materialInteraction;
0231 materialInteraction.materialSlab = MaterialSlab(material, 0.1);
0232 materialInteraction.position = Vector3{i * 1.0, 0, 0};
0233 materialInteraction.direction = Vector3{1.0, 0., 0.};
0234 materialInteractions.push_back(materialInteraction);
0235 }
0236
0237
0238 struct ReAssignToNeighbor {
0239 void operator()(
0240 MaterialInteraction& m,
0241 const IAssignmentFinder::SurfaceAssignment& ,
0242 const IAssignmentFinder::SurfaceAssignment& n) const {
0243 auto [surface, position, direction] = n;
0244 m.surface = surface;
0245 m.position = position;
0246 m.direction = direction;
0247 m.intersectionID = surface->geometryId();
0248 return;
0249 }
0250 };
0251
0252
0253 std::vector<std::pair<GeometryIdentifier,
0254 MaterialInteractionAssignment::ReAssignment>>
0255 reassignmentVector = {
0256 {GeometryIdentifier().withSensitive(2), ReAssignToNeighbor{}}};
0257 GeometryHierarchyMap<MaterialInteractionAssignment::ReAssignment>
0258 reassignments(reassignmentVector);
0259 MaterialInteractionAssignment::Options options;
0260 options.reAssignments = reassignments;
0261
0262
0263 auto [assigned, unassigned, surfaceLeft] =
0264 MaterialInteractionAssignment::assign(tContext, materialInteractions,
0265 intersectedSurfaces, options);
0266
0267
0268 BOOST_CHECK_EQUAL(assigned.size(), 49u);
0269 BOOST_CHECK_EQUAL(unassigned.size(), 0u);
0270 BOOST_CHECK_EQUAL(surfaceLeft.size(), 1u);
0271
0272
0273 for (const auto& mi : assigned) {
0274 BOOST_CHECK_NE(mi.intersectionID, GeometryIdentifier().withSensitive(2));
0275 }
0276 }
0277
0278 BOOST_AUTO_TEST_CASE(AssignWithPathLength) {
0279 auto surface =
0280 Surface::makeShared<CylinderSurface>(Transform3::Identity(), 20.0, 100.0);
0281 surface->assignGeometryId(GeometryIdentifier().withSensitive(1));
0282
0283 Vector3 position = {20., 10., 0.};
0284 Vector3 direction = position.normalized();
0285
0286 IAssignmentFinder::SurfaceAssignment surfaceHit{surface.get(), position,
0287 direction};
0288
0289 Material material = Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0);
0290
0291 MaterialInteraction materialInteraction;
0292 materialInteraction.materialSlab = MaterialSlab(material, 0.1);
0293 materialInteraction.position = position + 0.5 * direction;
0294 materialInteraction.direction = direction;
0295
0296 MaterialInteractionAssignment::Options options;
0297
0298 auto [assigned, unassigned, surfaceLeft] =
0299 MaterialInteractionAssignment::assign(tContext, {materialInteraction},
0300 {surfaceHit}, options);
0301
0302
0303 BOOST_CHECK_EQUAL(assigned.size(), 1u);
0304 BOOST_CHECK_EQUAL(unassigned.size(), 0u);
0305 BOOST_CHECK_EQUAL(surfaceLeft.size(), 0u);
0306
0307
0308 BOOST_CHECK_NE(assigned[0].pathCorrection, 0.);
0309 }
0310
0311 BOOST_AUTO_TEST_SUITE_END()
0312
0313 }