File indexing completed on 2025-01-18 09:13:06
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/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
0033
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 }
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
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
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
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
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
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
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
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
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
0197 auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0198 Acts::Svg::toFile({volumeXY}, "EndcapVolume_xy.svg");
0199
0200
0201 auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0202 Acts::Svg::toFile({volumeZR}, "EndcapVolume_zr.svg");
0203
0204
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
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
0268 auto volumeXY = Acts::Svg::View::xy(pVolume, pVolume._name);
0269 Acts::Svg::toFile({volumeXY}, "BarrelVolume_xy.svg");
0270
0271
0272 auto volumeZR = Acts::Svg::View::zr(pVolume, pVolume._name);
0273 Acts::Svg::toFile({volumeZR}, "BarrelVolume_zr.svg");
0274
0275
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()