Back to home page

EIC code displayed by LXR

 
 

    


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

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/CylindricalContainerBuilder.hpp"
0013 #include "Acts/Detector/DetectorComponents.hpp"
0014 #include "Acts/Detector/DetectorVolume.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Detector/ProtoBinning.hpp"
0017 #include "Acts/Detector/interface/IDetectorComponentBuilder.hpp"
0018 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0019 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0020 #include "Acts/Geometry/GeometryContext.hpp"
0021 #include "Acts/Geometry/GeometryIdentifier.hpp"
0022 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0023 #include "Acts/Navigation/InternalNavigation.hpp"
0024 #include "Acts/Surfaces/CylinderBounds.hpp"
0025 #include "Acts/Surfaces/CylinderSurface.hpp"
0026 #include "Acts/Surfaces/DiscSurface.hpp"
0027 #include "Acts/Surfaces/RadialBounds.hpp"
0028 #include "Acts/Surfaces/Surface.hpp"
0029 #include "Acts/Tests/CommonHelpers/CylindricalDetector.hpp"
0030 #include "Acts/Utilities/BinningType.hpp"
0031 #include "Acts/Utilities/Enumerate.hpp"
0032 #include "Acts/Utilities/Logger.hpp"
0033 
0034 #include <any>
0035 #include <cmath>
0036 #include <iterator>
0037 #include <memory>
0038 #include <numbers>
0039 #include <stdexcept>
0040 #include <string>
0041 #include <utility>
0042 #include <vector>
0043 
0044 using namespace Acts;
0045 using namespace Acts::Test;
0046 using namespace Acts::Experimental;
0047 
0048 GeometryContext tContext;
0049 
0050 class VolumeGeoIdGenerator : public IGeometryIdGenerator {
0051  public:
0052   struct Cache {
0053     unsigned int volumeCount = 0;
0054   };
0055 
0056   IGeometryIdGenerator::GeoIdCache generateCache() const final {
0057     return Cache{0};
0058   }
0059 
0060   void assignGeometryId(IGeometryIdGenerator::GeoIdCache& cache,
0061                         DetectorVolume& dVolume) const final {
0062     auto& ccache = std::any_cast<Cache&>(cache);
0063     ccache.volumeCount += 1;
0064     Acts::GeometryIdentifier geoID;
0065     geoID.setVolume(ccache.volumeCount);
0066     dVolume.assignGeometryId(geoID);
0067   }
0068 
0069   void assignGeometryId(
0070       Acts::Experimental::IGeometryIdGenerator::GeoIdCache& /*cache*/,
0071       Acts::Experimental::Portal& /*portal*/) const final {}
0072 
0073   void assignGeometryId(
0074       Acts::Experimental::IGeometryIdGenerator::GeoIdCache& /*cache*/,
0075       Acts::Surface& /*surface*/) const final {}
0076 };
0077 
0078 BOOST_AUTO_TEST_SUITE(Detector)
0079 
0080 BOOST_AUTO_TEST_CASE(CylindricaContainerBuilder_Misconfiguration) {
0081   // misconfiruation: no builders
0082   CylindricalContainerBuilder::Config misCfg;
0083   BOOST_CHECK_THROW(auto a = CylindricalContainerBuilder(misCfg),
0084                     std::invalid_argument);
0085   // misconfiguration - 1D binning not in z, r, phi
0086   misCfg.builders = {nullptr};
0087   misCfg.binning = {Acts::AxisDirection::AxisX};
0088   BOOST_CHECK_THROW(auto b = CylindricalContainerBuilder(misCfg),
0089                     std::invalid_argument);
0090 
0091   // misconfiguration - 2D binning not in z, r,
0092   misCfg.builders = {nullptr, nullptr};
0093   misCfg.binning = {Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisPhi};
0094   BOOST_CHECK_THROW(auto c = CylindricalContainerBuilder(misCfg),
0095                     std::invalid_argument);
0096 
0097   // misconfiguration - 2D binning  in z, r, but not exactly 2 builders
0098   misCfg.builders = {nullptr, nullptr, nullptr};
0099   misCfg.binning = {Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisR};
0100   BOOST_CHECK_THROW(auto d = CylindricalContainerBuilder(misCfg),
0101                     std::invalid_argument);
0102 }
0103 
0104 BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingZ) {
0105   // Declare a negative disc builder
0106   Transform3 negZ = Transform3::Identity();
0107   negZ.pretranslate(Vector3(0., 0., -300.));
0108   auto negDisc =
0109       std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0110           negZ, CylinderVolumeBounds(50., 200., 100.), RadialBounds(60., 190.),
0111           "NegativeDisc");
0112 
0113   // Declare a barrel builder
0114   auto barrel = std::make_shared<
0115       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0116       Transform3::Identity(), CylinderVolumeBounds(50., 200., 200.),
0117       CylinderBounds(80., 190.), "Barrel");
0118   // Declare a positive disc builder
0119   Transform3 posZ = Transform3::Identity();
0120   posZ.pretranslate(Vector3(0., 0., 300.));
0121   auto posDisc =
0122       std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0123           posZ, CylinderVolumeBounds(50., 200., 100.), RadialBounds(60., 190.),
0124           "PositiveDisc");
0125 
0126   // Create the container builder
0127   CylindricalContainerBuilder::Config tripleZCfg;
0128   tripleZCfg.auxiliary = "*** Test 0 - Build triple in Z ***";
0129   tripleZCfg.builders = {negDisc, barrel, posDisc};
0130   tripleZCfg.binning = {AxisDirection::AxisZ};
0131   tripleZCfg.geoIdGenerator = std::make_shared<VolumeGeoIdGenerator>();
0132   // Create a materialBinning
0133   tripleZCfg.portalMaterialBinning[2u] = BinningDescription{
0134       {ProtoBinning(AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, 50),
0135        ProtoBinning(AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0136                     -std::numbers::pi, std::numbers::pi, 12)}};
0137 
0138   // Let's test the reverse generation
0139   tripleZCfg.geoIdReverseGen = true;
0140 
0141   auto tripleZ = std::make_shared<CylindricalContainerBuilder>(
0142       tripleZCfg, getDefaultLogger("TripleBuilderZ", Logging::VERBOSE));
0143 
0144   auto [volumes, portals, roots] = tripleZ->construct(tContext);
0145 
0146   BOOST_CHECK_EQUAL(portals.size(), 4u);
0147   BOOST_CHECK_EQUAL(roots.volumes.size(), 3u);
0148   BOOST_CHECK_EQUAL(roots.volumes[0]->geometryId().volume(), 3u);
0149   BOOST_CHECK_EQUAL(roots.volumes[1]->geometryId().volume(), 2u);
0150   BOOST_CHECK_EQUAL(roots.volumes[2]->geometryId().volume(), 1u);
0151 
0152   // The outside surface should have a proto material description now
0153   BOOST_CHECK_NE(portals[2u]->surface().surfaceMaterial(), nullptr);
0154   // others should not have a proto material description
0155   BOOST_CHECK_EQUAL(portals[0u]->surface().surfaceMaterial(), nullptr);
0156   BOOST_CHECK_EQUAL(portals[1u]->surface().surfaceMaterial(), nullptr);
0157   BOOST_CHECK_EQUAL(portals[3u]->surface().surfaceMaterial(), nullptr);
0158 }
0159 
0160 BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingR) {
0161   // Declare a barrel builder
0162   auto barrel0 = std::make_shared<
0163       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0164       Transform3::Identity(), CylinderVolumeBounds(50., 80., 200.),
0165       CylinderBounds(65., 190.), "Barrel0");
0166 
0167   // Declare a barrel builder
0168   auto barrel1 = std::make_shared<
0169       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0170       Transform3::Identity(), CylinderVolumeBounds(80., 110., 200.),
0171       CylinderBounds(95., 190.), "Barrel1");
0172 
0173   // Declare a barrel builder
0174   auto barrel2 = std::make_shared<
0175       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0176       Transform3::Identity(), CylinderVolumeBounds(110., 140., 200.),
0177       CylinderBounds(125., 190.), "Barrel2");
0178 
0179   // Create the container builder
0180   CylindricalContainerBuilder::Config barrelRCfg;
0181   barrelRCfg.auxiliary = "*** Test 1 - Build multilayer barrel ***";
0182   barrelRCfg.builders = {barrel0, barrel1, barrel2};
0183   barrelRCfg.binning = {AxisDirection::AxisR};
0184   barrelRCfg.geoIdGenerator = std::make_shared<VolumeGeoIdGenerator>();
0185 
0186   auto barrelR = std::make_shared<CylindricalContainerBuilder>(
0187       barrelRCfg, getDefaultLogger("BarrelBuilderR", Logging::VERBOSE));
0188 
0189   auto [volumes, portals, roots] = barrelR->construct(tContext);
0190 
0191   BOOST_CHECK_EQUAL(portals.size(), 4u);
0192   BOOST_CHECK_EQUAL(roots.volumes.size(), 3u);
0193   BOOST_CHECK_EQUAL(roots.volumes[0]->geometryId().volume(), 1u);
0194   BOOST_CHECK_EQUAL(roots.volumes[1]->geometryId().volume(), 2u);
0195   BOOST_CHECK_EQUAL(roots.volumes[2]->geometryId().volume(), 3u);
0196 }
0197 
0198 BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingPhi) {
0199   // Create the container builder
0200   CylindricalContainerBuilder::Config barrelPhiCfg;
0201   barrelPhiCfg.auxiliary = "*** Test 2 - Build segmented phi barrel ***";
0202   barrelPhiCfg.binning = {AxisDirection::AxisPhi};
0203 
0204   unsigned int phiSectors = 5;
0205   double phiHalfSector = std::numbers::pi / phiSectors;
0206 
0207   std::vector<std::shared_ptr<DetectorVolume>> phiVolumes = {};
0208   for (unsigned int i = 0; i < phiSectors; ++i) {
0209     // The volume bounds
0210     Acts::CylinderVolumeBounds volumeBounds(
0211         10., 100., 100., phiHalfSector,
0212         -std::numbers::pi + (2u * i + 1u) * phiHalfSector);
0213     // The surface bounds
0214     Acts::CylinderBounds surfaceBounds(
0215         50., 90., 0.99 * phiHalfSector,
0216         -std::numbers::pi + (2u * i + 1u) * phiHalfSector);
0217 
0218     auto builder = std::make_shared<
0219         CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0220         Transform3::Identity(), volumeBounds, surfaceBounds,
0221         std::string("Sector_") + std::to_string(i));
0222     barrelPhiCfg.builders.push_back(builder);
0223   }
0224 
0225   auto barrelPhi = std::make_shared<CylindricalContainerBuilder>(
0226       barrelPhiCfg, getDefaultLogger("BarrelBuilderPhi", Logging::VERBOSE));
0227 
0228   auto [volumes, portals, roots] = barrelPhi->construct(tContext);
0229 
0230   BOOST_CHECK_EQUAL(portals.size(), 4u);
0231   BOOST_CHECK_EQUAL(roots.volumes.size(), 5u);
0232 }
0233 
0234 BOOST_AUTO_TEST_CASE(CylindricalContainerBuilderDetector) {
0235   // Declare a barrel sub builder
0236   auto beampipe = std::make_shared<
0237       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0238       Transform3::Identity(), CylinderVolumeBounds(0., 50., 600.),
0239       CylinderBounds(25., 590.), "BeamPipe");
0240 
0241   // Declare a negative disc builder
0242   Transform3 negZ = Transform3::Identity();
0243   negZ.pretranslate(Vector3(0., 0., -300.));
0244   auto endcapN =
0245       std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0246           negZ, CylinderVolumeBounds(50., 140., 100.), RadialBounds(60., 130.),
0247           "NegativeEndcap");
0248 
0249   // Declare a barrel sub builder
0250   auto barrel0 = std::make_shared<
0251       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0252       Transform3::Identity(), CylinderVolumeBounds(50., 80., 200.),
0253       CylinderBounds(65., 190.), "Barrel0");
0254 
0255   // Declare a barrel sub builder
0256   auto barrel1 = std::make_shared<
0257       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0258       Transform3::Identity(), CylinderVolumeBounds(80., 110., 200.),
0259       CylinderBounds(95., 190.), "Barrel1");
0260 
0261   // Declare a barrel sub builder
0262   auto barrel2 = std::make_shared<
0263       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0264       Transform3::Identity(), CylinderVolumeBounds(110., 140., 200.),
0265       CylinderBounds(125., 190.), "Barrel2");
0266 
0267   // Create the barrel container builder
0268   CylindricalContainerBuilder::Config barrelRCfg;
0269   barrelRCfg.builders = {barrel0, barrel1, barrel2};
0270   barrelRCfg.binning = {AxisDirection::AxisR};
0271 
0272   auto barrel = std::make_shared<CylindricalContainerBuilder>(
0273       barrelRCfg, getDefaultLogger("BarrelBuilderR", Logging::VERBOSE));
0274 
0275   Transform3 posZ = Transform3::Identity();
0276   posZ.pretranslate(Vector3(0., 0., 300.));
0277   auto endcapP =
0278       std::make_shared<CylindricalVolumeBuilder<DiscSurface, RadialBounds>>(
0279           posZ, CylinderVolumeBounds(50., 140., 100.), RadialBounds(60., 130.),
0280           "PositiveEndcap");
0281 
0282   // Create the barrel container builder
0283   CylindricalContainerBuilder::Config barrelEndcapCfg;
0284   barrelEndcapCfg.builders = {endcapN, barrel, endcapP};
0285   barrelEndcapCfg.binning = {AxisDirection::AxisZ};
0286 
0287   auto barrelEndcap = std::make_shared<CylindricalContainerBuilder>(
0288       barrelEndcapCfg,
0289       getDefaultLogger("BarrelEndcapBuilder", Logging::VERBOSE));
0290 
0291   // Create the barrel container builder
0292   CylindricalContainerBuilder::Config detectorCfg;
0293   detectorCfg.builders = {beampipe, barrelEndcap};
0294   detectorCfg.binning = {AxisDirection::AxisR};
0295 
0296   auto detector = std::make_shared<CylindricalContainerBuilder>(
0297       detectorCfg, getDefaultLogger("DetectorBuilder", Logging::VERBOSE));
0298 
0299   auto [volumes, portals, roots] = detector->construct(tContext);
0300   BOOST_CHECK_EQUAL(portals.size(), 3u);
0301   BOOST_CHECK_EQUAL(roots.volumes.size(), 6u);
0302 }
0303 
0304 BOOST_AUTO_TEST_SUITE_END()