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