Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-24 08:20:54

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