Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-06 07:53:38

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/Detector/DetectorVolume.hpp"
0012 #include "Acts/Detector/DetectorVolumeBuilder.hpp"
0013 #include "Acts/Detector/LayerStructureBuilder.hpp"
0014 #include "Acts/Detector/PortalGenerators.hpp"
0015 #include "Acts/Detector/VolumeStructureBuilder.hpp"
0016 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Navigation/InternalNavigation.hpp"
0019 #include "Acts/Navigation/NavigationStateUpdaters.hpp"
0020 #include "Acts/Plugins/ActSVG/DetectorVolumeSvgConverter.hpp"
0021 #include "Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp"
0022 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0023 #include "Acts/Utilities/Enumerate.hpp"
0024 #include "Acts/Utilities/Logger.hpp"
0025 
0026 #include <fstream>
0027 #include <memory>
0028 #include <numbers>
0029 #include <vector>
0030 
0031 namespace {
0032 /// Helper method that allows to use the already existing testing
0033 /// infrastructure with the new const-correct detector design
0034 ///
0035 std::vector<std::shared_ptr<Acts::Surface>> unpackSurfaces(
0036     const std::vector<const Acts::Surface*>& surfaces) {
0037   std::vector<std::shared_ptr<Acts::Surface>> uSurfaces;
0038   uSurfaces.reserve(surfaces.size());
0039   for (const auto& s : surfaces) {
0040     auto* ncs = const_cast<Acts::Surface*>(s);
0041     uSurfaces.push_back(ncs->getSharedPtr());
0042   }
0043   return uSurfaces;
0044 }
0045 
0046 }  // namespace
0047 
0048 Acts::GeometryContext tContext;
0049 
0050 auto cGeometry = Acts::Test::CylindricalTrackingGeometry(tContext);
0051 auto nominal = Acts::Transform3::Identity();
0052 
0053 BOOST_AUTO_TEST_SUITE(ActSvg)
0054 
0055 BOOST_AUTO_TEST_CASE(TubeCylindricalDetectorVolume) {
0056   auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0057 
0058   // The volume definitions
0059   double rInner = 10.;
0060   double rOuter = 100.;
0061   double zHalfL = 300.;
0062 
0063   Acts::Svg::Style portalStyle;
0064   portalStyle.fillColor = {255, 255, 255};
0065   portalStyle.fillOpacity = 0.;
0066 
0067   // A tube cylinder
0068   auto tubeCylinderBounds =
0069       std::make_unique<Acts::CylinderVolumeBounds>(rInner, rOuter, zHalfL);
0070 
0071   auto tubeCylinderVolume =
0072       Acts::Experimental::DetectorVolumeFactory::construct(
0073           portalGenerator, tContext, "TubeCylinderVolume", nominal,
0074           std::move(tubeCylinderBounds), Acts::Experimental::tryAllPortals());
0075 
0076   Acts::Svg::DetectorVolumeConverter::Options volumeOptions;
0077   volumeOptions.portalOptions.volumeIndices[tubeCylinderVolume.get()] = 0u;
0078 
0079   auto [pVolume, pGrid] = Acts::Svg::DetectorVolumeConverter::convert(
0080       tContext, *tubeCylinderVolume, volumeOptions);
0081   pVolume._name = tubeCylinderVolume->name();
0082 
0083   // Colorize in red
0084   actsvg::style::color red({{255, 0, 0}});
0085   red._opacity = 0.1;
0086   std::vector<actsvg::style::color> colors = {red};
0087   pVolume.colorize(colors);
0088 
0089   // As sheet
0090   auto pv = Acts::Svg::View::zr(pVolume, pVolume._name);
0091   Acts::Svg::toFile({pv}, pVolume._name + "_zr.svg");
0092 }
0093 
0094 BOOST_AUTO_TEST_CASE(TubeSectorCylindricalDetectorVolume) {
0095   auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0096 
0097   // The volume definitions
0098   double rInner = 10.;
0099   double rOuter = 100.;
0100   double zHalfL = 300.;
0101   double phiSector = std::numbers::pi / 4.;
0102   std::vector<double> avgPhi = {0., 0.75};
0103   std::vector<std::string> avgPhiTag = {"zero", "nonzero"};
0104 
0105   Acts::Svg::Style portalStyle;
0106   portalStyle.fillColor = {255, 255, 255};
0107   portalStyle.fillOpacity = 0.;
0108 
0109   std::vector<actsvg::svg::object> volumesXY;
0110   for (auto [iphi, aphi] : Acts::enumerate(avgPhi)) {
0111     // A tube cylinder
0112     auto sectorCylinderBounds = std::make_unique<Acts::CylinderVolumeBounds>(
0113         rInner, rOuter, zHalfL, phiSector, aphi);
0114 
0115     auto sectorCylinderVolume =
0116         Acts::Experimental::DetectorVolumeFactory::construct(
0117             portalGenerator, tContext, "SectoralCylinderVolume", nominal,
0118             std::move(sectorCylinderBounds),
0119             Acts::Experimental::tryAllPortals());
0120 
0121     Acts::Svg::DetectorVolumeConverter::Options volumeOptions;
0122     volumeOptions.portalOptions.volumeIndices[sectorCylinderVolume.get()] = 0u;
0123 
0124     auto [pVolume, pGrid] = Acts::Svg::DetectorVolumeConverter::convert(
0125         tContext, *sectorCylinderVolume, volumeOptions);
0126 
0127     // Colorize in blue
0128     actsvg::style::color blue({{0, 0, 255}});
0129     blue._opacity = 0.1;
0130     std::vector<actsvg::style::color> colors = {blue};
0131     pVolume.colorize(colors);
0132 
0133     volumesXY.push_back(Acts::Svg::View::xy(pVolume, pVolume._name));
0134   }
0135 
0136   Acts::Svg::toFile(volumesXY, "SectorVolumes_xy.svg");
0137 }
0138 
0139 BOOST_AUTO_TEST_CASE(EndcapVolumeWithSurfaces) {
0140   Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0141 
0142   auto rSurfaces = cGeometry.surfacesRing(dStore, 6.4, 12.4, 36., 0.125, 0.,
0143                                           55., -800, 2., 22u);
0144 
0145   auto endcapSurfaces = std::make_shared<
0146       Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0147       unpackSurfaces(rSurfaces));
0148   // Configure the layer structure builder
0149   Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0150   lsConfig.auxiliary = "*** Endcap with 22 surfaces ***";
0151   lsConfig.surfacesProvider = endcapSurfaces;
0152   lsConfig.binnings = {
0153       {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisPhi,
0154                                Acts::AxisBoundaryType::Closed,
0155                                -std::numbers::pi, std::numbers::pi, 22u),
0156        1u}};
0157 
0158   auto layerBuilder =
0159       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0160           lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
0161                                            Acts::Logging::VERBOSE));
0162 
0163   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0164   shapeConfig.boundValues = {10, 100, 10., std::numbers::pi, 0.};
0165   shapeConfig.transform =
0166       Acts::Transform3{Acts::Transform3::Identity()}.pretranslate(
0167           Acts::Vector3(0., 0., -800.));
0168   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0169 
0170   auto shapeBuilder =
0171       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0172           shapeConfig,
0173           Acts::getDefaultLogger("EndcapShapeBuilder", Acts::Logging::VERBOSE));
0174 
0175   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0176   dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0177   dvCfg.name = "CylinderWithSurface";
0178   dvCfg.externalsBuilder = shapeBuilder;
0179   dvCfg.internalsBuilder = layerBuilder;
0180 
0181   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0182       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0183 
0184   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0185 
0186   auto volume = volumes.front();
0187   Acts::Svg::DetectorVolumeConverter::Options volumeOptions;
0188   volumeOptions.portalOptions.volumeIndices[volume.get()] = 0u;
0189 
0190   Acts::Svg::SurfaceConverter::Options surfaceOptions;
0191   surfaceOptions.style.fillColor = {50, 121, 168};
0192   surfaceOptions.style.fillOpacity = 0.5;
0193   volumeOptions.surfaceOptions = surfaceOptions;
0194 
0195   auto [pVolume, pGrid] = Acts::Svg::DetectorVolumeConverter::convert(
0196       tContext, *volume, volumeOptions);
0197 
0198   // x-y view
0199   auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0200   Acts::Svg::toFile({volumeXY}, "EndcapVolume_xy.svg");
0201 
0202   // z-r view
0203   auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0204   Acts::Svg::toFile({volumeZR}, "EndcapVolume_zr.svg");
0205 
0206   // The grid surfaces
0207   auto gridXY = Acts::Svg::View::xy(pGrid, "EndcapVolume_grid_xy");
0208   Acts::Svg::toFile({gridXY}, "EndcapVolume_grid_xy.svg");
0209 }
0210 
0211 BOOST_AUTO_TEST_CASE(BarrelVolumeWithSurfaces) {
0212   Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0213   auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
0214                                               3., 2., {32u, 14u});
0215 
0216   auto barrelSurfaces = std::make_shared<
0217       Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0218       unpackSurfaces(cSurfaces));
0219 
0220   // Configure the layer structure builder
0221   Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0222   lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
0223   lsConfig.surfacesProvider = barrelSurfaces;
0224   lsConfig.binnings = {
0225       {Acts::DirectedProtoAxis{Acts::AxisDirection::AxisZ,
0226                                Acts::AxisBoundaryType::Bound, -480., 480., 14u},
0227        1u},
0228       {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisPhi,
0229                                Acts::AxisBoundaryType::Closed,
0230                                -std::numbers::pi, std::numbers::pi, 32u),
0231        1u}};
0232 
0233   auto barrelBuilder =
0234       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0235           lsConfig, Acts::getDefaultLogger("BarrelInternalsBuilder",
0236                                            Acts::Logging::VERBOSE));
0237 
0238   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0239   shapeConfig.boundValues = {60., 80., 800., std::numbers::pi, 0.};
0240   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0241 
0242   auto shapeBuilder =
0243       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0244           shapeConfig,
0245           Acts::getDefaultLogger("BarrelShapeBuilder", Acts::Logging::VERBOSE));
0246 
0247   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0248   dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0249   dvCfg.name = "CylinderWithSurface";
0250   dvCfg.externalsBuilder = shapeBuilder;
0251   dvCfg.internalsBuilder = barrelBuilder;
0252 
0253   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0254       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0255 
0256   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0257 
0258   auto volume = volumes.front();
0259   Acts::Svg::DetectorVolumeConverter::Options volumeOptions;
0260   volumeOptions.portalOptions.volumeIndices[volume.get()] = 0u;
0261 
0262   Acts::Svg::SurfaceConverter::Options surfaceOptions;
0263   surfaceOptions.style.fillColor = {50, 121, 168};
0264   surfaceOptions.style.fillOpacity = 0.5;
0265   volumeOptions.surfaceOptions = surfaceOptions;
0266 
0267   auto [pVolume, pGrid] = Acts::Svg::DetectorVolumeConverter::convert(
0268       tContext, *volume, volumeOptions);
0269 
0270   // x-y view
0271   auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0272   Acts::Svg::toFile({volumeXY}, "BarrelVolume_xy.svg");
0273 
0274   // z-r view
0275   auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0276   Acts::Svg::toFile({volumeZR}, "BarrelVolume_zr.svg");
0277 
0278   // The grid surfaces
0279   auto gridZPhi = Acts::Svg::View::zphi(pGrid, "BarrelVolume_grid_zphi");
0280   Acts::Svg::toFile({gridZPhi}, "BarrelVolume_grid_zphi.svg");
0281 }
0282 
0283 BOOST_AUTO_TEST_SUITE_END()