Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:11

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 = {Acts::Experimental::ProtoBinning(
0172         Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0173         -std::numbers::pi, std::numbers::pi, 22u, 1u)};
0174 
0175     auto layerBuilder =
0176         std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0177             lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
0178                                              Acts::Logging::VERBOSE));
0179 
0180     Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0181     shapeConfig.boundValues = {18, 100, 10., std::numbers::pi, 0.};
0182     shapeConfig.transform =
0183         Acts::Transform3{Acts::Transform3::Identity()}.pretranslate(
0184             Acts::Vector3(0., 0., ep));
0185     shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0186 
0187     auto shapeBuilder =
0188         std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0189             shapeConfig, Acts::getDefaultLogger("EndcapShapeBuilder",
0190                                                 Acts::Logging::VERBOSE));
0191 
0192     Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0193     dvCfg.name = "EndcapWithSurfaces_" + std::to_string(ie);
0194     dvCfg.externalsBuilder = shapeBuilder;
0195     dvCfg.internalsBuilder = layerBuilder;
0196 
0197     auto dvBuilder =
0198         std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0199             dvCfg,
0200             Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0201     endcapBuilders.push_back(dvBuilder);
0202   }
0203 
0204   // Central barrel
0205   Acts::Experimental::VolumeStructureBuilder::Config innerShapeConfig;
0206   innerShapeConfig.boundValues = {18., 60., 700., std::numbers::pi, 0.};
0207   innerShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0208 
0209   auto innerShapeBuilder =
0210       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0211           innerShapeConfig,
0212           Acts::getDefaultLogger("InnerShapeBuilder", Acts::Logging::VERBOSE));
0213 
0214   Acts::Experimental::DetectorVolumeBuilder::Config ivCfg;
0215   ivCfg.name = "InnerBarrelGap";
0216   ivCfg.externalsBuilder = innerShapeBuilder;
0217 
0218   auto ivBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0219       ivCfg, Acts::getDefaultLogger("InnerBarrel", Acts::Logging::VERBOSE));
0220 
0221   ///  Barrel surfaces
0222   auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
0223                                               3., 2., {32u, 14u});
0224 
0225   auto barrelSurfaces = std::make_shared<
0226       Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0227       unpackSurfaces(cSurfaces));
0228 
0229   // Configure the layer structure builder
0230   Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0231   lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
0232   lsConfig.surfacesProvider = barrelSurfaces;
0233   lsConfig.binnings = {
0234       Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ,
0235                                        Acts::AxisBoundaryType::Bound, -480.,
0236                                        480., 14u, 1u},
0237       Acts::Experimental::ProtoBinning(
0238           Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0239           -std::numbers::pi, std::numbers::pi, 32u, 1u)};
0240 
0241   auto barrelBuilder =
0242       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0243           lsConfig, Acts::getDefaultLogger("BarrelInternalsBuilder",
0244                                            Acts::Logging::VERBOSE));
0245 
0246   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0247   shapeConfig.boundValues = {60., 80., 700., std::numbers::pi, 0.};
0248   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0249 
0250   auto shapeBuilder =
0251       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0252           shapeConfig,
0253           Acts::getDefaultLogger("BarrelShapeBuilder", Acts::Logging::VERBOSE));
0254 
0255   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0256   dvCfg.name = "BarrelWithSurfaces";
0257   dvCfg.externalsBuilder = shapeBuilder;
0258   dvCfg.internalsBuilder = barrelBuilder;
0259 
0260   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0261       dvCfg, Acts::getDefaultLogger("BarrelBuilder", Acts::Logging::VERBOSE));
0262 
0263   // Outer shape
0264   Acts::Experimental::VolumeStructureBuilder::Config outerShapeConfig;
0265   outerShapeConfig.boundValues = {80., 100., 700., std::numbers::pi, 0.};
0266   outerShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0267 
0268   auto outerShapeBuilder =
0269       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0270           outerShapeConfig,
0271           Acts::getDefaultLogger("OuterShapeBuilder", Acts::Logging::VERBOSE));
0272 
0273   Acts::Experimental::DetectorVolumeBuilder::Config ovCfg;
0274   ovCfg.name = "OuterBarrelGap";
0275   ovCfg.externalsBuilder = outerShapeBuilder;
0276 
0277   auto ovBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0278       ovCfg, Acts::getDefaultLogger("OuterBarrel", Acts::Logging::VERBOSE));
0279 
0280   // Build the combined barrel
0281   Acts::Experimental::CylindricalContainerBuilder::Config ccBarrelBuilderCfg;
0282   ccBarrelBuilderCfg.builders = {ivBuilder, dvBuilder, ovBuilder};
0283   ccBarrelBuilderCfg.binning = {Acts::AxisDirection::AxisR};
0284 
0285   auto ccBarrelBuilder =
0286       std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0287           ccBarrelBuilderCfg,
0288           Acts::getDefaultLogger("BarrelBuilder", Acts::Logging::VERBOSE));
0289 
0290   // Builder the combined endcap barrel system
0291   Acts::Experimental::CylindricalContainerBuilder::Config ccBarrelEcBuilderCfg;
0292   ccBarrelEcBuilderCfg.builders = {endcapBuilders[0u], ccBarrelBuilder,
0293                                    endcapBuilders[1u]};
0294   ccBarrelEcBuilderCfg.binning = {Acts::AxisDirection::AxisZ};
0295 
0296   auto ccBarrelEndcapBuilder =
0297       std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0298           ccBarrelEcBuilderCfg, Acts::getDefaultLogger("BarrelEndcapBuilder",
0299                                                        Acts::Logging::VERBOSE));
0300 
0301   // Beam Pipe
0302   Acts::Experimental::VolumeStructureBuilder::Config bpShapeConfig;
0303   bpShapeConfig.boundValues = {0., 18., 720., std::numbers::pi, 0.};
0304   bpShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0305 
0306   auto bpShapeBuilder =
0307       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0308           bpShapeConfig, Acts::getDefaultLogger("BeamPipeShapeBuilder",
0309                                                 Acts::Logging::VERBOSE));
0310 
0311   Acts::Experimental::DetectorVolumeBuilder::Config bpCfg;
0312   bpCfg.name = "BeamPipe";
0313   bpCfg.externalsBuilder = bpShapeBuilder;
0314 
0315   auto bpBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0316       bpCfg, Acts::getDefaultLogger("BeamPipe", Acts::Logging::VERBOSE));
0317 
0318   // Full detector
0319   Acts::Experimental::CylindricalContainerBuilder::Config detCompBuilderCfg;
0320   detCompBuilderCfg.builders = {bpBuilder, ccBarrelEndcapBuilder};
0321   detCompBuilderCfg.binning = {Acts::AxisDirection::AxisR};
0322 
0323   auto detCompBuilder =
0324       std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
0325           detCompBuilderCfg);
0326 
0327   auto gigConfig = Acts::Experimental::GeometryIdGenerator::Config();
0328   auto gig =
0329       std::make_shared<Acts::Experimental::GeometryIdGenerator>(gigConfig);
0330 
0331   Acts::Experimental::DetectorBuilder::Config detBuilderCfg;
0332   detBuilderCfg.name = "Detector";
0333   detBuilderCfg.builder = detCompBuilder;
0334   detBuilderCfg.geoIdGenerator = gig;
0335 
0336   auto detBuilder =
0337       std::make_shared<Acts::Experimental::DetectorBuilder>(detBuilderCfg);
0338 
0339   auto detector = detBuilder->construct(tContext);
0340 
0341   auto jDetector = Acts::DetectorJsonConverter::toJson(tContext, *detector);
0342 
0343   std::ofstream out;
0344 
0345   out.open("barrel-endcap-detector.json");
0346   out << jDetector.dump(4);
0347   out.close();
0348 
0349   auto in = std::ifstream("barrel-endcap-detector.json",
0350                           std::ifstream::in | std::ifstream::binary);
0351 
0352   BOOST_CHECK(in.good());
0353   nlohmann::json jDetectorIn;
0354   in >> jDetectorIn;
0355   in.close();
0356 
0357   auto detectorIn =
0358       Acts::DetectorJsonConverter::fromJson(tContext, jDetectorIn);
0359 
0360   BOOST_CHECK_EQUAL(detectorIn->name(), detector->name());
0361 
0362   auto jDetectorInOut =
0363       Acts::DetectorJsonConverter::toJson(tContext, *detectorIn);
0364 
0365   out.open("barrel-endcap-detector-closure.json");
0366   out << jDetectorInOut.dump(4);
0367   out.close();
0368 
0369   auto jDetectorDetray = Acts::DetectorJsonConverter::toJsonDetray(
0370       tContext, *detector, detrayOptions());
0371 
0372   out.open("barrel-endcap-detector-detray.json");
0373   out << jDetectorDetray.dump(4);
0374   out.close();
0375 }
0376 
0377 BOOST_AUTO_TEST_SUITE_END()