Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13: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/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 = {Acts::Experimental::ProtoBinning(
0153       Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0154       -std::numbers::pi, std::numbers::pi, 22u, 1u)};
0155 
0156   auto layerBuilder =
0157       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0158           lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
0159                                            Acts::Logging::VERBOSE));
0160 
0161   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0162   shapeConfig.boundValues = {10, 100, 10., std::numbers::pi, 0.};
0163   shapeConfig.transform =
0164       Acts::Transform3{Acts::Transform3::Identity()}.pretranslate(
0165           Acts::Vector3(0., 0., -800.));
0166   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0167 
0168   auto shapeBuilder =
0169       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0170           shapeConfig,
0171           Acts::getDefaultLogger("EndcapShapeBuilder", Acts::Logging::VERBOSE));
0172 
0173   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0174   dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0175   dvCfg.name = "CylinderWithSurface";
0176   dvCfg.externalsBuilder = shapeBuilder;
0177   dvCfg.internalsBuilder = layerBuilder;
0178 
0179   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0180       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0181 
0182   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0183 
0184   auto volume = volumes.front();
0185   Acts::Svg::DetectorVolumeConverter::Options volumeOptions;
0186   volumeOptions.portalOptions.volumeIndices[volume.get()] = 0u;
0187 
0188   Acts::Svg::SurfaceConverter::Options surfaceOptions;
0189   surfaceOptions.style.fillColor = {50, 121, 168};
0190   surfaceOptions.style.fillOpacity = 0.5;
0191   volumeOptions.surfaceOptions = surfaceOptions;
0192 
0193   auto [pVolume, pGrid] = Acts::Svg::DetectorVolumeConverter::convert(
0194       tContext, *volume, volumeOptions);
0195 
0196   // x-y view
0197   auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0198   Acts::Svg::toFile({volumeXY}, "EndcapVolume_xy.svg");
0199 
0200   // z-r view
0201   auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0202   Acts::Svg::toFile({volumeZR}, "EndcapVolume_zr.svg");
0203 
0204   // The grid surfaces
0205   auto gridXY = Acts::Svg::View::xy(pGrid, "EndcapVolume_grid_xy");
0206   Acts::Svg::toFile({gridXY}, "EndcapVolume_grid_xy.svg");
0207 }
0208 
0209 BOOST_AUTO_TEST_CASE(BarrelVolumeWithSurfaces) {
0210   Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0211   auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
0212                                               3., 2., {32u, 14u});
0213 
0214   auto barrelSurfaces = std::make_shared<
0215       Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0216       unpackSurfaces(cSurfaces));
0217 
0218   // Configure the layer structure builder
0219   Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0220   lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
0221   lsConfig.surfacesProvider = barrelSurfaces;
0222   lsConfig.binnings = {
0223       Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ,
0224                                        Acts::AxisBoundaryType::Bound, -480.,
0225                                        480., 14u, 1u},
0226       Acts::Experimental::ProtoBinning(
0227           Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0228           -std::numbers::pi, std::numbers::pi, 32u, 1u)};
0229 
0230   auto barrelBuilder =
0231       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0232           lsConfig, Acts::getDefaultLogger("BarrelInternalsBuilder",
0233                                            Acts::Logging::VERBOSE));
0234 
0235   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0236   shapeConfig.boundValues = {60., 80., 800., std::numbers::pi, 0.};
0237   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0238 
0239   auto shapeBuilder =
0240       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0241           shapeConfig,
0242           Acts::getDefaultLogger("BarrelShapeBuilder", Acts::Logging::VERBOSE));
0243 
0244   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0245   dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0246   dvCfg.name = "CylinderWithSurface";
0247   dvCfg.externalsBuilder = shapeBuilder;
0248   dvCfg.internalsBuilder = barrelBuilder;
0249 
0250   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0251       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0252 
0253   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0254 
0255   auto volume = volumes.front();
0256   Acts::Svg::DetectorVolumeConverter::Options volumeOptions;
0257   volumeOptions.portalOptions.volumeIndices[volume.get()] = 0u;
0258 
0259   Acts::Svg::SurfaceConverter::Options surfaceOptions;
0260   surfaceOptions.style.fillColor = {50, 121, 168};
0261   surfaceOptions.style.fillOpacity = 0.5;
0262   volumeOptions.surfaceOptions = surfaceOptions;
0263 
0264   auto [pVolume, pGrid] = Acts::Svg::DetectorVolumeConverter::convert(
0265       tContext, *volume, volumeOptions);
0266 
0267   // x-y view
0268   auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0269   Acts::Svg::toFile({volumeXY}, "BarrelVolume_xy.svg");
0270 
0271   // z-r view
0272   auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0273   Acts::Svg::toFile({volumeZR}, "BarrelVolume_zr.svg");
0274 
0275   // The grid surfaces
0276   auto gridZPhi = Acts::Svg::View::zphi(pGrid, "BarrelVolume_grid_zphi");
0277   Acts::Svg::toFile({gridZPhi}, "BarrelVolume_grid_zphi.svg");
0278 }
0279 
0280 BOOST_AUTO_TEST_SUITE_END()