Back to home page

sPhenix code displayed by LXR

 
 

    


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

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