File indexing completed on 2025-08-06 08:11:40
0001
0002
0003
0004
0005
0006
0007
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
0032
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 }
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
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
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
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
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
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
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
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
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
0195 auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0196 Acts::Svg::toFile({volumeXY}, "EndcapVolume_xy.svg");
0197
0198
0199 auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0200 Acts::Svg::toFile({volumeZR}, "EndcapVolume_zr.svg");
0201
0202
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
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
0265 auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0266 Acts::Svg::toFile({volumeXY}, "BarrelVolume_xy.svg");
0267
0268
0269 auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0270 Acts::Svg::toFile({volumeZR}, "BarrelVolume_zr.svg");
0271
0272
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()