Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-02 07:52:38

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/DetectorVolume.hpp"
0013 #include "Acts/Detector/DetectorVolumeBuilder.hpp"
0014 #include "Acts/Detector/LayerStructureBuilder.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Detector/VolumeStructureBuilder.hpp"
0017 #include "Acts/Geometry/ConeVolumeBounds.hpp"
0018 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0021 #include "Acts/Navigation/InternalNavigation.hpp"
0022 #include "Acts/Plugins/Json/DetectorVolumeJsonConverter.hpp"
0023 #include "Acts/Surfaces/CylinderBounds.hpp"
0024 #include "Acts/Surfaces/CylinderSurface.hpp"
0025 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0026 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0027 
0028 #include <fstream>
0029 #include <memory>
0030 #include <numbers>
0031 #include <vector>
0032 
0033 #include <nlohmann/json.hpp>
0034 
0035 namespace {
0036 /// Helper method that allows to use the already existing testing
0037 /// infrastructure with the new const-correct detector design
0038 ///
0039 std::vector<std::shared_ptr<Acts::Surface>> unpackSurfaces(
0040     const std::vector<const Acts::Surface*>& surfaces) {
0041   std::vector<std::shared_ptr<Acts::Surface>> uSurfaces;
0042   uSurfaces.reserve(surfaces.size());
0043   for (const auto s : surfaces) {
0044     auto* ncs = const_cast<Acts::Surface*>(s);
0045     uSurfaces.push_back(ncs->getSharedPtr());
0046   }
0047   return uSurfaces;
0048 }
0049 
0050 }  // namespace
0051 
0052 Acts::GeometryContext tContext;
0053 auto cGeometry = Acts::Test::CylindricalTrackingGeometry(tContext);
0054 
0055 auto portalGenerator = Acts::Experimental::defaultPortalGenerator();
0056 
0057 BOOST_AUTO_TEST_SUITE(DetectorVolumeJsonConverter)
0058 
0059 BOOST_AUTO_TEST_CASE(SingleEmptyVolume) {
0060   // Create a single cylindrical volume
0061   Acts::Transform3 nominal = Acts::Transform3::Identity();
0062   auto bounds = std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
0063 
0064   auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0065       portalGenerator, tContext, "EmptyVolume", nominal, std::move(bounds),
0066       Acts::Experimental::tryAllPortals());
0067 
0068   std::ofstream out;
0069 
0070   auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0071                                                            {volume.get()});
0072 
0073   out.open("single-empty-volume.json");
0074   out << jVolume.dump(4);
0075   out.close();
0076 
0077   auto in = std::ifstream("single-empty-volume.json",
0078                           std::ifstream::in | std::ifstream::binary);
0079 
0080   BOOST_CHECK(in.good());
0081   nlohmann::json jVolumeIn;
0082   in >> jVolumeIn;
0083   in.close();
0084 
0085   auto volumeIn =
0086       Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0087 
0088   BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0089   BOOST_CHECK(
0090       volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0091   BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0092   BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0093 }
0094 
0095 BOOST_AUTO_TEST_CASE(SingleSurfaceVolume) {
0096   // Create a single cylindrical volume
0097   Acts::Transform3 nominal = Acts::Transform3::Identity();
0098   auto volumeBounds =
0099       std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
0100   auto surfaceBounds = std::make_unique<Acts::CylinderBounds>(25., 100.);
0101 
0102   auto cylinderSurface = Acts::Surface::makeShared<Acts::CylinderSurface>(
0103       nominal, std::move(surfaceBounds));
0104 
0105   auto volume = Acts::Experimental::DetectorVolumeFactory::construct(
0106       portalGenerator, tContext, "CylinderVolume", nominal,
0107       std::move(volumeBounds), {cylinderSurface}, {},
0108       Acts::Experimental::tryRootVolumes(),
0109       Acts::Experimental::tryAllPortalsAndSurfaces());
0110 
0111   std::ofstream out;
0112 
0113   auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0114                                                            {volume.get()});
0115 
0116   out.open("single-surface-volume.json");
0117   out << jVolume.dump(4);
0118   out.close();
0119 
0120   auto in = std::ifstream("single-surface-volume.json",
0121                           std::ifstream::in | std::ifstream::binary);
0122 
0123   BOOST_CHECK(in.good());
0124   nlohmann::json jVolumeIn;
0125   in >> jVolumeIn;
0126   in.close();
0127 
0128   auto volumeIn =
0129       Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0130 
0131   BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0132   BOOST_CHECK(
0133       volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0134   BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0135   BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0136 }
0137 
0138 BOOST_AUTO_TEST_CASE(EndcapVolumeWithSurfaces) {
0139   Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0140 
0141   auto rSurfaces = cGeometry.surfacesRing(dStore, 6.4, 12.4, 36., 0.125, 0.,
0142                                           55., -800, 2., 22u);
0143 
0144   auto endcapSurfaces = std::make_shared<
0145       Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0146       unpackSurfaces(rSurfaces));
0147   // Configure the layer structure builder
0148   Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0149   lsConfig.auxiliary = "*** Endcap with 22 surfaces ***";
0150   lsConfig.surfacesProvider = endcapSurfaces;
0151   lsConfig.binnings = {
0152       {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisPhi,
0153                                Acts::AxisBoundaryType::Closed,
0154                                -std::numbers::pi, std::numbers::pi, 22u),
0155        1u}};
0156 
0157   auto layerBuilder =
0158       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0159           lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
0160                                            Acts::Logging::VERBOSE));
0161 
0162   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0163   shapeConfig.boundValues = {10, 100, 10., std::numbers::pi, 0.};
0164   shapeConfig.transform =
0165       Acts::Transform3{Acts::Transform3::Identity()}.pretranslate(
0166           Acts::Vector3(0., 0., -800.));
0167   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0168 
0169   auto shapeBuilder =
0170       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0171           shapeConfig,
0172           Acts::getDefaultLogger("EndcapShapeBuilder", Acts::Logging::VERBOSE));
0173 
0174   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0175   dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0176   dvCfg.name = "CylinderWithSurface";
0177   dvCfg.externalsBuilder = shapeBuilder;
0178   dvCfg.internalsBuilder = layerBuilder;
0179 
0180   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0181       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0182 
0183   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0184   auto volume = volumes.front();
0185 
0186   auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0187                                                            {volume.get()});
0188 
0189   std::ofstream out;
0190   out.open("endcap-volume-with-surfaces.json");
0191   out << jVolume.dump(4);
0192   out.close();
0193 
0194   auto in = std::ifstream("endcap-volume-with-surfaces.json",
0195                           std::ifstream::in | std::ifstream::binary);
0196 
0197   BOOST_CHECK(in.good());
0198   nlohmann::json jVolumeIn;
0199   in >> jVolumeIn;
0200   in.close();
0201 
0202   auto volumeIn =
0203       Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0204 
0205   BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0206   BOOST_CHECK(
0207       volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0208   BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0209   BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0210 
0211   // Cross-check writing
0212   jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volumeIn,
0213                                                       {volumeIn.get()});
0214   out.open("endcap-volume-with-surfaces-closure.json");
0215   out << jVolume.dump(4);
0216   out.close();
0217 }
0218 
0219 BOOST_AUTO_TEST_CASE(BarrelVolumeWithSurfaces) {
0220   Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0221   auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
0222                                               3., 2., {32u, 14u});
0223 
0224   auto barrelSurfaces = std::make_shared<
0225       Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0226       unpackSurfaces(cSurfaces));
0227 
0228   // Configure the layer structure builder
0229   Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0230   lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
0231   lsConfig.surfacesProvider = barrelSurfaces;
0232   lsConfig.binnings = {
0233       {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisZ,
0234                                Acts::AxisBoundaryType::Bound, -480., 480., 14u),
0235        1u},
0236       {Acts::DirectedProtoAxis(Acts::AxisDirection::AxisPhi,
0237                                Acts::AxisBoundaryType::Closed,
0238                                -std::numbers::pi, std::numbers::pi, 32u),
0239        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., 800., 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.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0257   dvCfg.name = "BarrelWithSurfaces";
0258   dvCfg.externalsBuilder = shapeBuilder;
0259   dvCfg.internalsBuilder = barrelBuilder;
0260 
0261   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0262       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0263 
0264   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0265 
0266   auto volume = volumes.front();
0267 
0268   auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0269                                                            {volume.get()});
0270 
0271   std::ofstream out;
0272   out.open("barrel-volume-with-surfaces.json");
0273   out << jVolume.dump(4);
0274   out.close();
0275 
0276   auto in = std::ifstream("barrel-volume-with-surfaces.json",
0277                           std::ifstream::in | std::ifstream::binary);
0278 
0279   BOOST_CHECK(in.good());
0280   nlohmann::json jVolumeIn;
0281   in >> jVolumeIn;
0282   in.close();
0283 
0284   auto volumeIn =
0285       Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0286 
0287   BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0288   BOOST_CHECK(
0289       volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0290   BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0291   BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0292 
0293   // Cross-check writing
0294   jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volumeIn,
0295                                                       {volumeIn.get()});
0296   out.open("barrel-volume-with-surfaces-closure.json");
0297   out << jVolume.dump(4);
0298   out.close();
0299 }
0300 
0301 BOOST_AUTO_TEST_SUITE_END()