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/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 = {Acts::Experimental::ProtoBinning(
0152       Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0153       -std::numbers::pi, std::numbers::pi, 22u, 1u)};
0154 
0155   auto layerBuilder =
0156       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0157           lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
0158                                            Acts::Logging::VERBOSE));
0159 
0160   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0161   shapeConfig.boundValues = {10, 100, 10., std::numbers::pi, 0.};
0162   shapeConfig.transform =
0163       Acts::Transform3{Acts::Transform3::Identity()}.pretranslate(
0164           Acts::Vector3(0., 0., -800.));
0165   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0166 
0167   auto shapeBuilder =
0168       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0169           shapeConfig,
0170           Acts::getDefaultLogger("EndcapShapeBuilder", Acts::Logging::VERBOSE));
0171 
0172   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0173   dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0174   dvCfg.name = "CylinderWithSurface";
0175   dvCfg.externalsBuilder = shapeBuilder;
0176   dvCfg.internalsBuilder = layerBuilder;
0177 
0178   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0179       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0180 
0181   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0182   auto volume = volumes.front();
0183 
0184   auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0185                                                            {volume.get()});
0186 
0187   std::ofstream out;
0188   out.open("endcap-volume-with-surfaces.json");
0189   out << jVolume.dump(4);
0190   out.close();
0191 
0192   auto in = std::ifstream("endcap-volume-with-surfaces.json",
0193                           std::ifstream::in | std::ifstream::binary);
0194 
0195   BOOST_CHECK(in.good());
0196   nlohmann::json jVolumeIn;
0197   in >> jVolumeIn;
0198   in.close();
0199 
0200   auto volumeIn =
0201       Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0202 
0203   BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0204   BOOST_CHECK(
0205       volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0206   BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0207   BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0208 
0209   // Cross-check writing
0210   jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volumeIn,
0211                                                       {volumeIn.get()});
0212   out.open("endcap-volume-with-surfaces-closure.json");
0213   out << jVolume.dump(4);
0214   out.close();
0215 }
0216 
0217 BOOST_AUTO_TEST_CASE(BarrelVolumeWithSurfaces) {
0218   Acts::Test::CylindricalTrackingGeometry::DetectorStore dStore;
0219   auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
0220                                               3., 2., {32u, 14u});
0221 
0222   auto barrelSurfaces = std::make_shared<
0223       Acts::Experimental::LayerStructureBuilder::SurfacesHolder>(
0224       unpackSurfaces(cSurfaces));
0225 
0226   // Configure the layer structure builder
0227   Acts::Experimental::LayerStructureBuilder::Config lsConfig;
0228   lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
0229   lsConfig.surfacesProvider = barrelSurfaces;
0230   lsConfig.binnings = {
0231       Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ,
0232                                        Acts::AxisBoundaryType::Bound, -480.,
0233                                        480., 14u, 1u},
0234       Acts::Experimental::ProtoBinning(
0235           Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed,
0236           -std::numbers::pi, std::numbers::pi, 32u, 1u)};
0237 
0238   auto barrelBuilder =
0239       std::make_shared<Acts::Experimental::LayerStructureBuilder>(
0240           lsConfig, Acts::getDefaultLogger("BarrelInternalsBuilder",
0241                                            Acts::Logging::VERBOSE));
0242 
0243   Acts::Experimental::VolumeStructureBuilder::Config shapeConfig;
0244   shapeConfig.boundValues = {60., 80., 800., std::numbers::pi, 0.};
0245   shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
0246 
0247   auto shapeBuilder =
0248       std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
0249           shapeConfig,
0250           Acts::getDefaultLogger("BarrelShapeBuilder", Acts::Logging::VERBOSE));
0251 
0252   Acts::Experimental::DetectorVolumeBuilder::Config dvCfg;
0253   dvCfg.auxiliary = "*** Test 1 - Cylinder with internal Surface ***";
0254   dvCfg.name = "BarrelWithSurfaces";
0255   dvCfg.externalsBuilder = shapeBuilder;
0256   dvCfg.internalsBuilder = barrelBuilder;
0257 
0258   auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
0259       dvCfg, Acts::getDefaultLogger("EndcapBuilder", Acts::Logging::VERBOSE));
0260 
0261   auto [volumes, portals, roots] = dvBuilder->construct(tContext);
0262 
0263   auto volume = volumes.front();
0264 
0265   auto jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volume,
0266                                                            {volume.get()});
0267 
0268   std::ofstream out;
0269   out.open("barrel-volume-with-surfaces.json");
0270   out << jVolume.dump(4);
0271   out.close();
0272 
0273   auto in = std::ifstream("barrel-volume-with-surfaces.json",
0274                           std::ifstream::in | std::ifstream::binary);
0275 
0276   BOOST_CHECK(in.good());
0277   nlohmann::json jVolumeIn;
0278   in >> jVolumeIn;
0279   in.close();
0280 
0281   auto volumeIn =
0282       Acts::DetectorVolumeJsonConverter::fromJson(tContext, jVolumeIn);
0283 
0284   BOOST_CHECK_EQUAL(volumeIn->name(), volume->name());
0285   BOOST_CHECK(
0286       volumeIn->transform(tContext).isApprox(volume->transform(tContext)));
0287   BOOST_CHECK_EQUAL(volumeIn->surfaces().size(), volume->surfaces().size());
0288   BOOST_CHECK_EQUAL(volumeIn->volumes().size(), volume->volumes().size());
0289 
0290   // Cross-check writing
0291   jVolume = Acts::DetectorVolumeJsonConverter::toJson(tContext, *volumeIn,
0292                                                       {volumeIn.get()});
0293   out.open("barrel-volume-with-surfaces-closure.json");
0294   out << jVolume.dump(4);
0295   out.close();
0296 }
0297 
0298 BOOST_AUTO_TEST_SUITE_END()