File indexing completed on 2025-09-17 08:04:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Detector/CylindricalContainerBuilder.hpp"
0013 #include "Acts/Detector/Detector.hpp"
0014 #include "Acts/Detector/DetectorBuilder.hpp"
0015 #include "Acts/Detector/DetectorVolume.hpp"
0016 #include "Acts/Detector/DetectorVolumeBuilder.hpp"
0017 #include "Acts/Detector/GeometryIdGenerator.hpp"
0018 #include "Acts/Detector/LayerStructureBuilder.hpp"
0019 #include "Acts/Detector/PortalGenerators.hpp"
0020 #include "Acts/Detector/VolumeStructureBuilder.hpp"
0021 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0022 #include "Acts/Geometry/GeometryContext.hpp"
0023 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0024 #include "Acts/Navigation/InternalNavigation.hpp"
0025 #include "Acts/Plugins/Json/DetectorJsonConverter.hpp"
0026 #include "Acts/Surfaces/CylinderBounds.hpp"
0027 #include "Acts/Surfaces/CylinderSurface.hpp"
0028 #include "Acts/Surfaces/Surface.hpp"
0029 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0030 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0031 #include "Acts/Utilities/Enumerate.hpp"
0032
0033 #include <fstream>
0034 #include <memory>
0035 #include <numbers>
0036 #include <vector>
0037
0038 #include <nlohmann/json.hpp>
0039
0040 namespace {
0041
0042
0043
0044
0045 std::vector<std::shared_ptr<Acts::Surface>> unpackSurfaces(
0046 const std::vector<Acts::Surface*>& surfaces) {
0047 std::vector<std::shared_ptr<Acts::Surface>> uSurfaces;
0048 uSurfaces.reserve(surfaces.size());
0049 for (auto* s : surfaces) {
0050 uSurfaces.push_back(s->getSharedPtr());
0051 }
0052 return uSurfaces;
0053 }
0054
0055 Acts::DetectorJsonConverter::Options detrayOptions() {
0056
0057 Acts::DetectorVolumeJsonConverter::Options detrayOptions;
0058 detrayOptions.transformOptions.writeIdentity = true;
0059 detrayOptions.transformOptions.transpose = true;
0060 detrayOptions.surfaceOptions.transformOptions =
0061 detrayOptions.transformOptions;
0062 detrayOptions.portalOptions.surfaceOptions = detrayOptions.surfaceOptions;
0063 return Acts::DetectorJsonConverter::Options{detrayOptions};
0064 }
0065
0066 }
0067
0068 Acts::GeometryContext tContext;
0069 auto cGeometry = Acts::Test::CylindricalTrackingGeometry(tContext);
0070
0071 BOOST_AUTO_TEST_SUITE(DetectorJsonConverter)
0072
0073 BOOST_AUTO_TEST_CASE(SingleEmptyVolumeDetector) {
0074 auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0075
0076
0077 Acts::Transform3 nominal = Acts::Transform3::Identity();
0078 auto bounds = std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
0079
0080 auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0081 portalGenerator, tContext, "Volume", nominal, std::move(bounds),
0082 Acts::Experimental::tryAllPortals());
0083
0084 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes = {
0085 volume};
0086
0087 Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0088 Acts::Experimental::GeometryIdGenerator generator(
0089 generatorConfig,
0090 Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE));
0091 auto cache = generator.generateCache();
0092 for (auto& vol : volumes) {
0093 generator.assignGeometryId(cache, *vol);
0094 }
0095
0096 auto detector = Acts::Experimental::Detector::makeShared(
0097 "Detector", volumes, Acts::Experimental::tryRootVolumes());
0098
0099 auto jDetector = Acts::DetectorJsonConverter::toJson(tContext, *detector);
0100
0101 std::ofstream out;
0102 out.open("single-empty-volume-detector.json");
0103 out << jDetector.dump(4);
0104 out.close();
0105 }
0106
0107 BOOST_AUTO_TEST_CASE(SingleVolumeOneSurfaceDetector) {
0108 auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0109
0110
0111 Acts::Transform3 nominal = Acts::Transform3::Identity();
0112 auto bounds = std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
0113
0114 auto cylinderBounds = std::make_shared<Acts::CylinderBounds>(30., 90.);
0115 auto surface =
0116 Acts::Surface::makeShared<Acts::CylinderSurface>(nominal, cylinderBounds);
0117
0118 auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0119 portalGenerator, tContext, "Volume", nominal, std::move(bounds),
0120 {surface}, {}, Acts::Experimental::tryNoVolumes(),
0121 Acts::Experimental::tryAllPortalsAndSurfaces());
0122
0123 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes = {
0124 volume};
0125
0126 Acts::Experimental::GeometryIdGenerator::Config generatorConfig;
0127 Acts::Experimental::GeometryIdGenerator generator(
0128 generatorConfig,
0129 Acts::getDefaultLogger("SequentialIdGenerator", Acts::Logging::VERBOSE));
0130 auto cache = generator.generateCache();
0131 for (auto& vol : volumes) {
0132 generator.assignGeometryId(cache, *vol);
0133 }
0134
0135 auto detector = Acts::Experimental::Detector::makeShared(
0136 "Detector", volumes, Acts::Experimental::tryRootVolumes());
0137
0138 auto jDetector = Acts::DetectorJsonConverter::toJson(tContext, *detector);
0139
0140 std::ofstream out;
0141 out.open("single-volume-one-surface-detector.json");
0142 out << jDetector.dump(4);
0143 out.close();
0144
0145 out.open("single-volume-one-surface-detector-detray.json");
0146 out << Acts::DetectorJsonConverter::toJsonDetray(tContext, *detector,
0147 detrayOptions())
0148 .dump(4);
0149 out.close();
0150 }
0151
0152 BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) {
0153
0154 Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0155
0156
0157 std::vector<std::shared_ptr<Acts::Experimental::IDetectorComponentBuilder>>
0158 endcapBuilders;
0159 for (auto [ie, ep] : Acts::enumerate(std::vector<double>({-710., 710.}))) {
0160 auto rSurfaces = cGeometry.surfacesRing(dStore, 6.4, 12.4, 36., 0.125, 0.,
0161 55., ep, 2., 22u);
0162
0163 auto endcapSurfaces = std::make_shared<
0164 Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0165 unpackSurfaces(rSurfaces));
0166
0167 Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0168 lsConfig.auxiliary = "*** Endcap with 22 surfaces ***";
0169 lsConfig.surfacesProvider = endcapSurfaces;
0170 lsConfig.binnings = {
0171 {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisPhi,
0172 Acts::AxisBoundaryType::Closed,
0173 -std::numbers::pi, std::numbers::pi, 22u),
0174 1u}};
0175
0176 auto layerBuilder =
0177 std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0178 lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
0179 Acts::Logging::VERBOSE));
0180
0181 Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0182 shapeConfig.boundValues = {18, 100, 10., std::numbers::pi, 0.};
0183 shapeConfig.transform =
0184 Acts::Transform3{Acts::Transform3::Identity()}.pretranslate(
0185 Acts::Vector3(0., 0., ep));
0186 shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0187
0188 auto shapeBuilder =
0189 std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0190 shapeConfig, Acts::getDefaultLogger("EndcapShapeBuilder",
0191 Acts::Logging::VERBOSE));
0192
0193 Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0194 dvCfg.name = "EndcapWithSurfaces_" + std::to_string(ie);
0195 dvCfg.externalsBuilder = shapeBuilder;
0196 dvCfg.internalsBuilder = layerBuilder;
0197
0198 auto dvBuilder =
0199 std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0200 dvCfg,
0201 Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0202 endcapBuilders.push_back(dvBuilder);
0203 }
0204
0205
0206 Acts::Experimental::VolumeStructureBuilder::Config innerShapeConfig;
0207 innerShapeConfig.boundValues = {18., 60., 700., std::numbers::pi, 0.};
0208 innerShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0209
0210 auto innerShapeBuilder =
0211 std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0212 innerShapeConfig,
0213 Acts::getDefaultLogger("InnerShapeBuilder", Acts::Logging::VERBOSE));
0214
0215 Acts::Experimental::DetectorVolumeBuilder::Config ivCfg;
0216 ivCfg.name = "InnerBarrelGap";
0217 ivCfg.externalsBuilder = innerShapeBuilder;
0218
0219 auto ivBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0220 ivCfg, Acts::getDefaultLogger("InnerBarrel", Acts::Logging::VERBOSE));
0221
0222
0223 auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
0224 3., 2., {32u, 14u});
0225
0226 auto barrelSurfaces = std::make_shared<
0227 Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0228 unpackSurfaces(cSurfaces));
0229
0230
0231 Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0232 lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
0233 lsConfig.surfacesProvider = barrelSurfaces;
0234 lsConfig.binnings = {
0235 {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisZ,
0236 Acts::AxisBoundaryType::Bound, -480., 480., 14u),
0237 1u},
0238 {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisPhi,
0239 Acts::AxisBoundaryType::Closed,
0240 -std::numbers::pi, std::numbers::pi, 32u),
0241 1u}};
0242
0243 auto barrelBuilder =
0244 std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0245 lsConfig, Acts::getDefaultLogger("BarrelInternalsBuilder",
0246 Acts::Logging::VERBOSE));
0247
0248 Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0249 shapeConfig.boundValues = {60., 80., 700., std::numbers::pi, 0.};
0250 shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0251
0252 auto shapeBuilder =
0253 std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0254 shapeConfig,
0255 Acts::getDefaultLogger("BarrelShapeBuilder", Acts::Logging::VERBOSE));
0256
0257 Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0258 dvCfg.name = "BarrelWithSurfaces";
0259 dvCfg.externalsBuilder = shapeBuilder;
0260 dvCfg.internalsBuilder = barrelBuilder;
0261
0262 auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0263 dvCfg, Acts::getDefaultLogger("BarrelBuilder", Acts::Logging::VERBOSE));
0264
0265
0266 Acts::Experimental::VolumeStructureBuilder::Config outerShapeConfig;
0267 outerShapeConfig.boundValues = {80., 100., 700., std::numbers::pi, 0.};
0268 outerShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0269
0270 auto outerShapeBuilder =
0271 std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0272 outerShapeConfig,
0273 Acts::getDefaultLogger("OuterShapeBuilder", Acts::Logging::VERBOSE));
0274
0275 Acts::Experimental::DetectorVolumeBuilder::Config ovCfg;
0276 ovCfg.name = "OuterBarrelGap";
0277 ovCfg.externalsBuilder = outerShapeBuilder;
0278
0279 auto ovBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0280 ovCfg, Acts::getDefaultLogger("OuterBarrel", Acts::Logging::VERBOSE));
0281
0282
0283 Acts::Experimental::CylindricalContainerBuilder::Config ccBarrelBuilderCfg;
0284 ccBarrelBuilderCfg.builders = {ivBuilder, dvBuilder, ovBuilder};
0285 ccBarrelBuilderCfg.binning = {Acts::AxisDirection::AxisR};
0286
0287 auto ccBarrelBuilder =
0288 std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0289 ccBarrelBuilderCfg,
0290 Acts::getDefaultLogger("BarrelBuilder", Acts::Logging::VERBOSE));
0291
0292
0293 Acts::Experimental::CylindricalContainerBuilder::Config ccBarrelEcBuilderCfg;
0294 ccBarrelEcBuilderCfg.builders = {endcapBuilders[0u], ccBarrelBuilder,
0295 endcapBuilders[1u]};
0296 ccBarrelEcBuilderCfg.binning = {Acts::AxisDirection::AxisZ};
0297
0298 auto ccBarrelEndcapBuilder =
0299 std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0300 ccBarrelEcBuilderCfg, Acts::getDefaultLogger("BarrelEndcapBuilder",
0301 Acts::Logging::VERBOSE));
0302
0303
0304 Acts::Experimental::VolumeStructureBuilder::Config bpShapeConfig;
0305 bpShapeConfig.boundValues = {0., 18., 720., std::numbers::pi, 0.};
0306 bpShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0307
0308 auto bpShapeBuilder =
0309 std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0310 bpShapeConfig, Acts::getDefaultLogger("BeamPipeShapeBuilder",
0311 Acts::Logging::VERBOSE));
0312
0313 Acts::Experimental::DetectorVolumeBuilder::Config bpCfg;
0314 bpCfg.name = "BeamPipe";
0315 bpCfg.externalsBuilder = bpShapeBuilder;
0316
0317 auto bpBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0318 bpCfg, Acts::getDefaultLogger("BeamPipe", Acts::Logging::VERBOSE));
0319
0320
0321 Acts::Experimental::CylindricalContainerBuilder::Config detCompBuilderCfg;
0322 detCompBuilderCfg.builders = {bpBuilder, ccBarrelEndcapBuilder};
0323 detCompBuilderCfg.binning = {Acts::AxisDirection::AxisR};
0324
0325 auto detCompBuilder =
0326 std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0327 detCompBuilderCfg);
0328
0329 auto gigConfig = Acts::Experimental::GeometryIdGenerator::Config();
0330 auto gig =
0331 std::make_shared<Acts::Experimental::GeometryIdGenerator>(gigConfig);
0332
0333 Acts::Experimental::DetectorBuilder::Config detBuilderCfg;
0334 detBuilderCfg.name = "Detector";
0335 detBuilderCfg.builder = detCompBuilder;
0336 detBuilderCfg.geoIdGenerator = gig;
0337
0338 auto detBuilder =
0339 std::make_shared<Acts::Experimental::DetectorBuilder>(detBuilderCfg);
0340
0341 auto detector = detBuilder->construct(tContext);
0342
0343 auto jDetector = Acts::DetectorJsonConverter::toJson(tContext, *detector);
0344
0345 std::ofstream out;
0346
0347 out.open("barrel-endcap-detector.json");
0348 out << jDetector.dump(4);
0349 out.close();
0350
0351 auto in = std::ifstream("barrel-endcap-detector.json",
0352 std::ifstream::in | std::ifstream::binary);
0353
0354 BOOST_CHECK(in.good());
0355 nlohmann::json jDetectorIn;
0356 in >> jDetectorIn;
0357 in.close();
0358
0359 auto detectorIn =
0360 Acts::DetectorJsonConverter::fromJson(tContext, jDetectorIn);
0361
0362 BOOST_CHECK_EQUAL(detectorIn->name(), detector->name());
0363
0364 auto jDetectorInOut =
0365 Acts::DetectorJsonConverter::toJson(tContext, *detectorIn);
0366
0367 out.open("barrel-endcap-detector-closure.json");
0368 out << jDetectorInOut.dump(4);
0369 out.close();
0370
0371 auto jDetectorDetray = Acts::DetectorJsonConverter::toJsonDetray(
0372 tContext, *detector, detrayOptions());
0373
0374 out.open("barrel-endcap-detector-detray.json");
0375 out << jDetectorDetray.dump(4);
0376 out.close();
0377 }
0378
0379 BOOST_AUTO_TEST_SUITE_END()