Back to home page

EIC code displayed by LXR

 
 

    


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