Back to home page

sPhenix code displayed by LXR

 
 

    


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

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