Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:15:00

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