Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 07:53:41

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
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 /// Helper method that allows to use the already existing testing
0043 /// infrastructure with the new const-correct detector design
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   // Detray format test - manipulate for detray
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 }  // namespace
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   // Create a single cylindrical volume
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   // Create a single cylindrical volume
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   // Detector store
0155   Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0156 
0157   // Endcaps
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     // Configure the layer structure builder
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   // Central barrel
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   ///  Barrel surfaces
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   // Configure the layer structure builder
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   // Outer shape
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   // Build the combined barrel
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   // Builder the combined endcap barrel system
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   // Beam Pipe
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   // Full detector
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()