Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:34

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/Detector/detail/SupportSurfacesHelper.hpp"
0013 #include "Acts/Geometry/Extent.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Surfaces/SurfaceBounds.hpp"
0017 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0018 #include "Acts/Utilities/BinningType.hpp"
0019 
0020 #include <array>
0021 #include <cmath>
0022 #include <cstddef>
0023 #include <memory>
0024 #include <numbers>
0025 #include <optional>
0026 #include <stdexcept>
0027 #include <vector>
0028 
0029 Acts::GeometryContext tContext;
0030 
0031 using namespace Acts::Experimental::detail::SupportSurfacesHelper;
0032 
0033 BOOST_AUTO_TEST_SUITE(Detector)
0034 
0035 BOOST_AUTO_TEST_CASE(CylindricalSupportCase) {
0036   // This tests the basic functionally to add a cylindrical support structure
0037   // and then split it into planar sectors
0038 
0039   // As a single cylinder
0040   // radius = 100
0041   // half length = 400
0042   // phi min = 0
0043   // phi max = 2pi
0044 
0045   Acts::Extent lExtent;
0046   lExtent.set(Acts::AxisDirection::AxisR, 100., 110.);
0047   lExtent.set(Acts::AxisDirection::AxisZ, -400., 400.);
0048 
0049   // Test creation of surface components
0050   CylindricalSupport csCreator{10., {1., 1.}};
0051   auto csComponents = csCreator(lExtent);
0052   auto& [csType, csValues, csTransform] = csComponents;
0053 
0054   BOOST_CHECK_EQUAL(csType, Acts::Surface::SurfaceType::Cylinder);
0055   BOOST_CHECK_EQUAL(csValues.size(), 6u);
0056   BOOST_CHECK_EQUAL(csValues[0u], 120.);
0057   BOOST_CHECK_EQUAL(csValues[1u], 399.);
0058   BOOST_CHECK(csTransform.isApprox(Acts::Transform3::Identity()));
0059 
0060   // Test a single support from Extent generation
0061   auto singleSupport = cylindricalSupport(csComponents);
0062   BOOST_CHECK_EQUAL(singleSupport.size(), 1u);
0063   BOOST_CHECK_EQUAL(singleSupport[0u]->type(),
0064                     Acts::Surface::SurfaceType::Cylinder);
0065 
0066   // Test a split cylinder into 32 sectors
0067   auto splitSupport = cylindricalSupport(csComponents, 32u);
0068   BOOST_CHECK_EQUAL(splitSupport.size(), 32u);
0069   for (const auto& ss : splitSupport) {
0070     BOOST_CHECK_EQUAL(ss->type(), Acts::Surface::SurfaceType::Plane);
0071   }
0072 
0073   // As a split cylinder - sectoral start cylinder
0074   auto splitSectoralSupport =
0075       Acts::Experimental::detail::SupportSurfacesHelper::cylindricalSupport(
0076           csComponents, 128u);
0077   BOOST_CHECK_EQUAL(splitSectoralSupport.size(), 128u);
0078   for (const auto& ss : splitSectoralSupport) {
0079     BOOST_CHECK_EQUAL(ss->type(), Acts::Surface::SurfaceType::Plane);
0080   }
0081 
0082   // Invalid / runtime checks
0083   Acts::Extent invalid;
0084   BOOST_CHECK_THROW(csCreator(invalid), std::invalid_argument);
0085 
0086   csValues = {120., 399.};
0087   BOOST_CHECK_THROW(cylindricalSupport(csComponents), std::invalid_argument);
0088 
0089   csValues = {120., 399., 0., 0., 0., 0.};
0090   csType = Acts::Surface::SurfaceType::Disc;
0091   BOOST_CHECK_THROW(cylindricalSupport(csComponents), std::invalid_argument);
0092 }
0093 
0094 BOOST_AUTO_TEST_CASE(DiscSupportCase) {
0095   // This tests the basic functionality to add a disc support structure
0096   // and then split it into planar sectors
0097 
0098   // As a single disc
0099   // rmin = 100
0100   // rmax = 400
0101   // phi min = 0
0102   // phi max = 2pi
0103   Acts::Extent lExtent;
0104   lExtent.set(Acts::AxisDirection::AxisR, 100., 400.);
0105   lExtent.set(Acts::AxisDirection::AxisZ, -405., -395.);
0106 
0107   // Test creation of surface components
0108   DiscSupport dsCreator{0., {1., 1.}};
0109   auto dsComponents = dsCreator(lExtent);
0110   auto& [dsType, dsValues, dsTransform] = dsComponents;
0111 
0112   BOOST_CHECK_EQUAL(dsType, Acts::Surface::SurfaceType::Disc);
0113   BOOST_CHECK_EQUAL(dsValues.size(), 4u);
0114   BOOST_CHECK_EQUAL(dsValues[0u], 101.);
0115   BOOST_CHECK_EQUAL(dsValues[1u], 399.);
0116   BOOST_CHECK(dsTransform.translation().isApprox(Acts::Vector3(0., 0., -400.)));
0117 
0118   // Test as a single support surface
0119   auto singleSupport =
0120       Acts::Experimental::detail::SupportSurfacesHelper::discSupport(
0121           dsComponents);
0122   BOOST_CHECK_EQUAL(singleSupport.size(), 1u);
0123   BOOST_CHECK_EQUAL(singleSupport[0u]->type(),
0124                     Acts::Surface::SurfaceType::Disc);
0125 
0126   // As a split disc into 32 sectors
0127   auto splitSupport =
0128       Acts::Experimental::detail::SupportSurfacesHelper::discSupport(
0129           dsComponents, 32u);
0130   BOOST_CHECK_EQUAL(splitSupport.size(), 32u);
0131   for (const auto& ss : splitSupport) {
0132     BOOST_CHECK_EQUAL(ss->type(), Acts::Surface::SurfaceType::Plane);
0133   }
0134 
0135   // As a split disc - sectoral start disc
0136   auto splitSectoralSupport =
0137       Acts::Experimental::detail::SupportSurfacesHelper::discSupport(
0138           dsComponents, 16u);
0139   BOOST_CHECK_EQUAL(splitSectoralSupport.size(), 16u);
0140   for (const auto& ss : splitSectoralSupport) {
0141     BOOST_CHECK_EQUAL(ss->type(), Acts::Surface::SurfaceType::Plane);
0142   }
0143 
0144   // Invalid / runtime checks
0145   Acts::Extent invalid;
0146   BOOST_CHECK_THROW(dsCreator(invalid), std::invalid_argument);
0147 
0148   dsValues = {120., 399.};
0149   BOOST_CHECK_THROW(cylindricalSupport(dsComponents), std::invalid_argument);
0150 
0151   dsValues = {120., 399., std::numbers::pi, 0.};
0152   dsType = Acts::Surface::SurfaceType::Cylinder;
0153   BOOST_CHECK_THROW(cylindricalSupport(dsComponents), std::invalid_argument);
0154 }
0155 
0156 BOOST_AUTO_TEST_CASE(RectangularSupportCase) {
0157   // This tests the basic functionality to add a planar, rectangular support
0158   // structure
0159 
0160   // As a plane extent in z
0161   // dx = [-100,100]
0162   // dy = [-200,200]
0163   // dz = [-50, -60]
0164   Acts::Extent lExtent;
0165   lExtent.set(Acts::AxisDirection::AxisX, -100., 100.);
0166   lExtent.set(Acts::AxisDirection::AxisY, -200., 200.);
0167   lExtent.set(Acts::AxisDirection::AxisZ, -60., -50.);
0168 
0169   // place in Z with offset 2_mm
0170   // Asymmetric clearances in x an y for testing
0171   RectangularSupport rsCreator{
0172       Acts::AxisDirection::AxisZ, 2., {1., 2.}, {3., 4.}};
0173   auto rsComponents = rsCreator(lExtent);
0174   auto& [rsType, rsValues, rsTransform] = rsComponents;
0175 
0176   BOOST_CHECK_EQUAL(rsType, Acts::Surface::SurfaceType::Plane);
0177   BOOST_CHECK_EQUAL(rsValues.size(), 4u);
0178   BOOST_CHECK_EQUAL(rsValues[0u], -99.);
0179   BOOST_CHECK_EQUAL(rsValues[1u], -197.);
0180   BOOST_CHECK_EQUAL(rsValues[2u], 98.);
0181   BOOST_CHECK_EQUAL(rsValues[3u], 196.);
0182 
0183   BOOST_CHECK(rsTransform.translation().isApprox(Acts::Vector3(0., 0., -53.)));
0184 
0185   // Test the support surface creation
0186   auto singleSupport =
0187       Acts::Experimental::detail::SupportSurfacesHelper::rectangularSupport(
0188           rsComponents);
0189   BOOST_CHECK_EQUAL(singleSupport.size(), 1u);
0190   BOOST_CHECK_EQUAL(singleSupport[0u]->type(),
0191                     Acts::Surface::SurfaceType::Plane);
0192 
0193   // Invalid / runtime checks
0194   Acts::Extent invalid;
0195   invalid.set(Acts::AxisDirection::AxisX, -100., 100.);
0196   invalid.set(Acts::AxisDirection::AxisY, -200., 200.);
0197   BOOST_CHECK_THROW(rsCreator(invalid), std::invalid_argument);
0198 }
0199 
0200 BOOST_AUTO_TEST_CASE(addCylinderSupportCase) {
0201   // This tests the functionally to take the surfaces from a cylinder layer,
0202   // estimate their extend and use this to construct a support structure
0203   // with some given additional instructuions
0204   std::vector<std::shared_ptr<Acts::Surface>> lSurfaces;
0205   std::vector<std::size_t> assignToAll;
0206 
0207   // The Extent - estimated by surfaces and other constraints
0208   // In this example we assume that e.g. the surfaces were parsed
0209   // -> did yield and extend of 100 < r 110
0210   // The volume would give an extend of -400 < z < 400
0211   Acts::Extent lExtent;
0212   lExtent.set(Acts::AxisDirection::AxisR, 100., 110.);
0213   lExtent.set(Acts::AxisDirection::AxisZ, -400., 400.);
0214 
0215   // Cylinder support
0216   CylindricalSupport csCreator{10., {1., 1.}};
0217 
0218   // Add a single support cylinder
0219   Acts::Experimental::detail::SupportSurfacesHelper::addSupport(
0220       lSurfaces, assignToAll, lExtent, csCreator, 1u);
0221 
0222   BOOST_CHECK_EQUAL(lSurfaces.size(), 1u);
0223   BOOST_CHECK_EQUAL(lSurfaces[0u]->type(),
0224                     Acts::Surface::SurfaceType::Cylinder);
0225   BOOST_CHECK_EQUAL(assignToAll.size(), 1u);
0226   BOOST_CHECK_EQUAL(assignToAll[0u], 0u);
0227 
0228   // The radius of the support surface should be 10 out of the maximum
0229   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[0u], 120, 1e-3);
0230   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[1u], 399, 1e-3);
0231 
0232   // Clear up for the next test
0233   lSurfaces.clear();
0234   assignToAll.clear();
0235 
0236   // Add split surfaces as support to already existing surfaces
0237   Acts::Experimental::detail::SupportSurfacesHelper::addSupport(
0238       lSurfaces, assignToAll, lExtent, csCreator, 16u);
0239   BOOST_CHECK_EQUAL(lSurfaces.size(), 16u);
0240   BOOST_CHECK(assignToAll.empty());
0241 }
0242 
0243 BOOST_AUTO_TEST_CASE(addDiscSupportCase) {
0244   // This tests the functionally to take the surfaces from a disc layer,
0245   // estimate their extend and use this to construct a support structure
0246   // with some given additional instructuions
0247   std::vector<std::shared_ptr<Acts::Surface>> lSurfaces;
0248   std::vector<std::size_t> assignToAll;
0249 
0250   // The Extent
0251   Acts::Extent lExtent;
0252   lExtent.set(Acts::AxisDirection::AxisR, 100., 400.);
0253   lExtent.set(Acts::AxisDirection::AxisZ, -110., -100.);
0254 
0255   // Disc support: this would set the disc at the center
0256   DiscSupport dsCreator{0., {1., 1.}};
0257 
0258   // Add a single disc as a support surface
0259   Acts::Experimental::detail::SupportSurfacesHelper::addSupport(
0260       lSurfaces, assignToAll, lExtent, dsCreator, 1u);
0261   BOOST_CHECK_EQUAL(lSurfaces.size(), 1u);
0262   BOOST_CHECK_EQUAL(lSurfaces[0u]->type(), Acts::Surface::SurfaceType::Disc);
0263   BOOST_CHECK_EQUAL(assignToAll.size(), 1u);
0264   BOOST_CHECK_EQUAL(assignToAll[0u], 0u);
0265 
0266   // The position of the support surface should be at zenter z
0267   CHECK_CLOSE_ABS(lSurfaces[0u]->transform(tContext).translation().z(), -105,
0268                   1e-3);
0269   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[0u], 101, 1e-3);
0270   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[1u], 399, 1e-3);
0271 
0272   // Clear up for the next test
0273   lSurfaces.clear();
0274   assignToAll.clear();
0275   // Add split surfaces as support disc
0276   Acts::Experimental::detail::SupportSurfacesHelper::addSupport(
0277       lSurfaces, assignToAll, lExtent, dsCreator, 16u);
0278   BOOST_CHECK_EQUAL(lSurfaces.size(), 16u);
0279   BOOST_CHECK(assignToAll.empty());
0280 }
0281 
0282 BOOST_AUTO_TEST_CASE(addRectangularSupportCase) {
0283   // This tests the functionally to take the surfaces from a plane layer,
0284   // estimate their extend and use this to construct a support structure
0285   // with some given additional instructuions
0286   std::vector<std::shared_ptr<Acts::Surface>> lSurfaces;
0287   std::vector<std::size_t> assignToAll;
0288 
0289   // As a plane extent in z
0290   // dx = [-100,100]
0291   // dy = [-200,200]
0292   // dz = [-50, -60]
0293   Acts::Extent lExtent;
0294   lExtent.set(Acts::AxisDirection::AxisX, -100., 100.);
0295   lExtent.set(Acts::AxisDirection::AxisY, -200., 200.);
0296   lExtent.set(Acts::AxisDirection::AxisZ, -60., -50.);
0297 
0298   // place in Z with offset 2_mm
0299   // Asymmetric clearances in x an y for testing
0300   RectangularSupport rsCreator{
0301       Acts::AxisDirection::AxisZ, 2., {1., 2.}, {3., 4.}};
0302 
0303   // Add a single disc as a support surface
0304   Acts::Experimental::detail::SupportSurfacesHelper::addSupport(
0305       lSurfaces, assignToAll, lExtent, rsCreator);
0306 
0307   BOOST_CHECK_EQUAL(lSurfaces.size(), 1u);
0308   BOOST_CHECK_EQUAL(lSurfaces[0u]->type(), Acts::Surface::SurfaceType::Plane);
0309   BOOST_CHECK_EQUAL(assignToAll.size(), 1u);
0310   BOOST_CHECK_EQUAL(assignToAll[0u], 0u);
0311 
0312   // The position of the support surface should be z with offset
0313   CHECK_CLOSE_ABS(lSurfaces[0u]->transform(tContext).translation().z(), -53,
0314                   1e-3);
0315   // The bounds should be as given (including clearances)
0316   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[0u], -99, 1e-3);
0317   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[1u], -197, 1e-3);
0318   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[2u], 98, 1e-3);
0319   CHECK_CLOSE_ABS(lSurfaces[0u]->bounds().values()[3u], 196, 1e-3);
0320 }
0321 
0322 BOOST_AUTO_TEST_CASE(addMisconfiguredSupportCase) {
0323   std::vector<std::shared_ptr<Acts::Surface>> lSurfaces;
0324   std::vector<std::size_t> assignToAll;
0325 
0326   // Unconstrainted extent
0327   Acts::Extent lExtent;
0328 
0329   // Cylinder support
0330   CylindricalSupport csCreator{10., {1., 1.}};
0331 
0332   // R - Z are not constrained
0333   // Add a single disc as a support cylinder
0334   BOOST_CHECK_THROW(
0335       Acts::Experimental::detail::SupportSurfacesHelper::addSupport(
0336           lSurfaces, assignToAll, lExtent, csCreator, 1u),
0337       std::invalid_argument);
0338 
0339   // The Extent
0340   lExtent.set(Acts::AxisDirection::AxisR, 100., 400.);
0341   lExtent.set(Acts::AxisDirection::AxisZ, -110., -100.);
0342 
0343   // Wrong surface type
0344   struct InvalidCreator {
0345     auto operator()(const Acts::Extent& /*e*/) const {
0346       return std::make_tuple(Acts::Surface::SurfaceType::Perigee,
0347                              std::vector<double>{},
0348                              Acts::Transform3::Identity());
0349     }
0350   };
0351 
0352   // Add a single disc as a support cylinder
0353   BOOST_CHECK_THROW(
0354       Acts::Experimental::detail::SupportSurfacesHelper::addSupport(
0355           lSurfaces, assignToAll, lExtent, InvalidCreator{}, 1u),
0356       std::invalid_argument);
0357 }
0358 
0359 BOOST_AUTO_TEST_SUITE_END()