Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-17 07:52:06

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/Material/GridSurfaceMaterial.hpp"
0012 #include "Acts/Material/Material.hpp"
0013 #include "Acts/Material/MaterialSlab.hpp"
0014 #include "Acts/Material/MergedMaterialMarker.hpp"
0015 #include "Acts/Utilities/GridAccessHelpers.hpp"
0016 #include "Acts/Utilities/GridAxisGenerators.hpp"
0017 #include "ActsPlugins/Json/MaterialJsonConverter.hpp"
0018 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0019 
0020 #include <memory>
0021 #include <numbers>
0022 #include <vector>
0023 
0024 #include <nlohmann/json.hpp>
0025 
0026 using namespace Acts;
0027 
0028 namespace ActsTests {
0029 
0030 BOOST_AUTO_TEST_SUITE(JsonSuite)
0031 
0032 BOOST_AUTO_TEST_CASE(IndexedSurfaceMaterial1DTests) {
0033   std::vector<MaterialSlab> material;
0034   material.emplace_back(Material::Vacuum(), 0.0);  // vacuum
0035   material.emplace_back(Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0),
0036                         1.0);
0037   material.emplace_back(
0038       Material::fromMolarDensity(11.0, 12.0, 13.0, 14.0, 15.0), 2.0);
0039   material.emplace_back(
0040       Material::fromMolarDensity(21.0, 22.0, 23.0, 24.0, 25.0), 3.0);
0041 
0042   using EqBound = GridAxisGenerators::EqBound;
0043   using EqGrid = EqBound::grid_type<std::size_t>;
0044   using Point = EqGrid::point_t;
0045 
0046   EqBound eqBound{{0., 5.}, 5};
0047   EqGrid eqGrid{eqBound()};
0048 
0049   eqGrid.atPosition(Point{0.5}) = 1u;  // material 1
0050   eqGrid.atPosition(Point{1.5}) = 0u;  // vacuum
0051   eqGrid.atPosition(Point{2.5}) = 2u;  // material 2
0052   eqGrid.atPosition(Point{3.5}) = 2u;  // material 2
0053   eqGrid.atPosition(Point{4.5}) = 3u;  // material 3
0054 
0055   auto localX = std::make_unique<const GridAccess::LocalSubspace<0u>>();
0056   IndexedSurfaceMaterial<EqGrid>::BoundToGridLocalDelegate bToX;
0057   bToX.connect<&GridAccess::LocalSubspace<0u>::toGridLocal>(std::move(localX));
0058 
0059   auto globalX = std::make_unique<
0060       const GridAccess::GlobalSubspace<AxisDirection::AxisX>>();
0061   IndexedSurfaceMaterial<EqGrid>::GlobalToGridLocalDelegate gToX;
0062   gToX.connect<&GridAccess::GlobalSubspace<AxisDirection::AxisX>::toGridLocal>(
0063       std::move(globalX));
0064 
0065   IndexedSurfaceMaterial<EqGrid> ism(
0066       std::move(eqGrid), IndexedMaterialAccessor{std::move(material)},
0067       std::move(bToX), std::move(gToX));
0068 
0069   nlohmann::json jMaterial = &ism;
0070 
0071   // Run a few tests
0072   BOOST_REQUIRE(jMaterial.find("material") != jMaterial.end());
0073 
0074   // Read it back in
0075   const ISurfaceMaterial* ismRead = nullptr;
0076   from_json(jMaterial, ismRead);
0077   BOOST_REQUIRE(ismRead != nullptr);
0078 
0079   // Check if it's the right type
0080   const IndexedSurfaceMaterial<EqGrid>* ismReadTyped =
0081       dynamic_cast<const IndexedSurfaceMaterial<EqGrid>*>(ismRead);
0082   BOOST_REQUIRE(ismReadTyped != nullptr);
0083 
0084   const auto& gridRead = ismReadTyped->grid();
0085   BOOST_CHECK(gridRead.atPosition(Point{0.5}) == 1u);  // material 1
0086   BOOST_CHECK(gridRead.atPosition(Point{1.5}) == 0u);  // vacuum
0087   BOOST_CHECK(gridRead.atPosition(Point{2.5}) == 2u);  // material 2
0088   BOOST_CHECK(gridRead.atPosition(Point{3.5}) == 2u);  // material 2
0089   BOOST_CHECK(gridRead.atPosition(Point{4.5}) == 3u);  // material 3
0090 
0091   // Check the accessor is there and the material is filled
0092   const auto& accessorRead = ismReadTyped->materialAccessor();
0093 
0094   auto materialRead = accessorRead.material;
0095   BOOST_REQUIRE(materialRead.size() == 4);
0096   CHECK_CLOSE_ABS(accessorRead.material[0].thickness(), 0.0, 1e-5);
0097   CHECK_CLOSE_ABS(accessorRead.material[1].thickness(), 1.0, 1e-5);
0098   CHECK_CLOSE_ABS(accessorRead.material[2].thickness(), 2.0, 1e-5);
0099   CHECK_CLOSE_ABS(accessorRead.material[3].thickness(), 3.0, 1e-5);
0100 }
0101 
0102 BOOST_AUTO_TEST_CASE(IndexedSurfaceMaterial2DTests) {
0103   std::vector<MaterialSlab> material;
0104   material.emplace_back(Material::Vacuum(), 1.0);  // vacuum
0105   material.emplace_back(Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0),
0106                         1.0);
0107   material.emplace_back(
0108       Material::fromMolarDensity(11.0, 12.0, 13.0, 14.0, 15.0), 1.0);
0109   material.emplace_back(
0110       Material::fromMolarDensity(21.0, 22.0, 23.0, 24.0, 25.0), 1.0);
0111 
0112   using EqBoundEqClosed = GridAxisGenerators::EqBoundEqClosed;
0113   using EqEqGrid = EqBoundEqClosed::grid_type<std::size_t>;
0114   using Point = EqEqGrid::point_t;
0115 
0116   EqBoundEqClosed eqeqBound{
0117       {-1., 1.}, 2, {-std::numbers::pi, std::numbers::pi}, 4};
0118   EqEqGrid eqeqGrid{eqeqBound()};
0119 
0120   eqeqGrid.atPosition(Point{-0.5, -std::numbers::pi * 0.75}) =
0121       1u;                                                          // material 1
0122   eqeqGrid.atPosition(Point{-0.5, -std::numbers::pi / 4.}) = 1u;   // material 1
0123   eqeqGrid.atPosition(Point{-0.5, std::numbers::pi / 4.}) = 0u;    // vacuum
0124   eqeqGrid.atPosition(Point{-0.5, std::numbers::pi * 0.75}) = 2u;  // material 2
0125 
0126   eqeqGrid.atPosition(Point{0.5, -std::numbers::pi * 0.75}) = 0u;  // vacuum
0127   eqeqGrid.atPosition(Point{0.5, -std::numbers::pi / 4.}) = 3u;    // material 3
0128   eqeqGrid.atPosition(Point{0.5, std::numbers::pi / 4.}) = 3u;     // material 3
0129   eqeqGrid.atPosition(Point{0.5, std::numbers::pi * 0.75}) = 0u;   // vacuum
0130 
0131   auto boundToGrid =
0132       std::make_unique<const GridAccess::LocalSubspace<0u, 1u>>();
0133   IndexedSurfaceMaterial<EqEqGrid>::BoundToGridLocalDelegate bToZPhi;
0134   bToZPhi.connect<&GridAccess::LocalSubspace<0u, 1u>::toGridLocal>(
0135       std::move(boundToGrid));
0136 
0137   // With z shift 10
0138   auto globalToGrid = std::make_unique<const GridAccess::GlobalSubspace<
0139       AxisDirection::AxisZ, AxisDirection::AxisPhi>>();
0140   IndexedSurfaceMaterial<EqEqGrid>::GlobalToGridLocalDelegate gToZphi;
0141   gToZphi.connect<&GridAccess::GlobalSubspace<
0142       AxisDirection::AxisZ, AxisDirection::AxisPhi>::toGridLocal>(
0143       std::move(globalToGrid));
0144 
0145   // Create the indexed material grid
0146   IndexedSurfaceMaterial<EqEqGrid> ism(
0147       std::move(eqeqGrid), IndexedMaterialAccessor{std::move(material)},
0148       std::move(bToZPhi), std::move(gToZphi));
0149 
0150   nlohmann::json jMaterial = &ism;
0151 
0152   // Run a few tests
0153   BOOST_REQUIRE(jMaterial.find("material") != jMaterial.end());
0154 
0155   // Read it back in
0156   const ISurfaceMaterial* ismRead = nullptr;
0157   from_json(jMaterial, ismRead);
0158   BOOST_REQUIRE(ismRead != nullptr);
0159 }
0160 
0161 BOOST_AUTO_TEST_CASE(MergedMaterialMarkerRoundTrip) {
0162   // The marker left behind by a lossy portal merge must survive a JSON
0163   // round-trip so it can be picked up by downstream tooling.
0164   const ISurfaceMaterial* marker = new MergedMaterialMarker();
0165 
0166   nlohmann::json jMaterial = marker;
0167   BOOST_REQUIRE(jMaterial.find("material") != jMaterial.end());
0168   BOOST_CHECK_EQUAL(jMaterial["material"]["type"], "merged-material-marker");
0169 
0170   const ISurfaceMaterial* markerRead = nullptr;
0171   from_json(jMaterial, markerRead);
0172   BOOST_REQUIRE(markerRead != nullptr);
0173   BOOST_CHECK(dynamic_cast<const MergedMaterialMarker*>(markerRead) != nullptr);
0174 
0175   delete marker;
0176   delete markerRead;
0177 }
0178 
0179 BOOST_AUTO_TEST_SUITE_END()
0180 
0181 }  // namespace ActsTests