Back to home page

EIC code displayed by LXR

 
 

    


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

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/Geometry/CylinderVolumeBounds.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Plugins/Detray/DetrayGeometryConverter.hpp"
0016 #include "Acts/Surfaces/CylinderBounds.hpp"
0017 #include "Acts/Surfaces/CylinderSurface.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019 #include "Acts/Tests/CommonHelpers/CylindricalDetector.hpp"
0020 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0021 #include "Acts/Utilities/BinningType.hpp"
0022 #include "Acts/Utilities/Enumerate.hpp"
0023 #include "Acts/Utilities/Logger.hpp"
0024 
0025 #include <memory>
0026 #include <numbers>
0027 #include <vector>
0028 
0029 #include <detray/io/frontend/payloads.hpp>
0030 
0031 using namespace Acts;
0032 using namespace Acts::Experimental;
0033 using namespace Acts::Test;
0034 
0035 GeometryContext tContext;
0036 
0037 auto logger =
0038     Acts::getDefaultLogger("DetrayGeometryConverterTests", Acts::Logging::INFO);
0039 
0040 BOOST_AUTO_TEST_SUITE(DetrayConversion)
0041 
0042 BOOST_AUTO_TEST_CASE(DetrayTransformConversion) {
0043   auto transform = Transform3::Identity();
0044   transform.pretranslate(Vector3(1., 2., 3.));
0045   transform.rotate(Eigen::AngleAxisd(std::numbers::pi / 2., Vector3::UnitZ()));
0046 
0047   detray::io::transform_payload payload =
0048       DetrayGeometryConverter::convertTransform(transform);
0049   // Transform is correctly translated
0050   CHECK_CLOSE_ABS(payload.tr[0u], 1., std::numeric_limits<double>::epsilon());
0051   CHECK_CLOSE_ABS(payload.tr[1u], 2., std::numeric_limits<double>::epsilon());
0052   CHECK_CLOSE_ABS(payload.tr[2u], 3., std::numeric_limits<double>::epsilon());
0053   // Rotation is correctly translated
0054   RotationMatrix3 rotation = transform.rotation().transpose();
0055   CHECK_CLOSE_ABS(payload.rot[0u], rotation(0, 0),
0056                   std::numeric_limits<double>::epsilon());
0057   CHECK_CLOSE_ABS(payload.rot[1u], rotation(0, 1),
0058                   std::numeric_limits<double>::epsilon());
0059   CHECK_CLOSE_ABS(payload.rot[2u], rotation(0, 2),
0060                   std::numeric_limits<double>::epsilon());
0061   CHECK_CLOSE_ABS(payload.rot[3u], rotation(1, 0),
0062                   std::numeric_limits<double>::epsilon());
0063   CHECK_CLOSE_ABS(payload.rot[4u], rotation(1, 1),
0064                   std::numeric_limits<double>::epsilon());
0065   CHECK_CLOSE_ABS(payload.rot[5u], rotation(1, 2),
0066                   std::numeric_limits<double>::epsilon());
0067   CHECK_CLOSE_ABS(payload.rot[6u], rotation(2, 0),
0068                   std::numeric_limits<double>::epsilon());
0069   CHECK_CLOSE_ABS(payload.rot[7u], rotation(2, 1),
0070                   std::numeric_limits<double>::epsilon());
0071   CHECK_CLOSE_ABS(payload.rot[8u], rotation(2, 2),
0072                   std::numeric_limits<double>::epsilon());
0073 }
0074 
0075 BOOST_AUTO_TEST_CASE(DetrayMaskConversion) {
0076   // Placeholder, masks are tested for the moment through the DetrayJsonHelper,
0077   // this code will move over here when the "toJsonDetray" will become
0078   // deprecated
0079 }
0080 
0081 BOOST_AUTO_TEST_CASE(DetraySurfaceConversion) {
0082   // Translate a cylinder
0083   auto cylinderSurface = Acts::Surface::makeShared<CylinderSurface>(
0084       Transform3::Identity(), std::make_shared<CylinderBounds>(20., 100.));
0085 
0086   auto sgID = Acts::GeometryIdentifier().setSensitive(1);
0087   cylinderSurface->assignGeometryId(sgID);
0088 
0089   detray::io::surface_payload payload = DetrayGeometryConverter::convertSurface(
0090       tContext, *cylinderSurface, false);
0091 
0092   // Check the payload
0093   BOOST_CHECK(!payload.index_in_coll.has_value());
0094   BOOST_CHECK(payload.mask.shape == detray::io::shape_id::cylinder2);
0095   BOOST_CHECK_EQUAL(payload.source, sgID.value());
0096   BOOST_CHECK(payload.type == detray::surface_id::e_sensitive);
0097 }
0098 
0099 BOOST_AUTO_TEST_CASE(DetrayVolumeConversion) {
0100   auto beampipe = std::make_shared<
0101       CylindricalVolumeBuilder<CylinderSurface, CylinderBounds>>(
0102       Transform3::Identity(), CylinderVolumeBounds(0., 50., 400.),
0103       CylinderBounds(25., 380.), "BeamPipe");
0104 
0105   auto [volumes, portals, rootVolumes] = beampipe->construct(tContext);
0106   auto volume = volumes.front();
0107 
0108   std::vector<const Experimental::DetectorVolume*> dVolumes = {volume.get()};
0109   DetrayConversionUtils::Cache cCache(dVolumes);
0110 
0111   detray::io::volume_payload payload = DetrayGeometryConverter::convertVolume(
0112       cCache, tContext, *volume, *logger);
0113 
0114   // Check the volume payload
0115   BOOST_CHECK(payload.name == "BeamPipe");
0116   BOOST_CHECK(payload.type == detray::volume_id::e_cylinder);
0117   // 3 portals and 1 surface contained
0118   BOOST_CHECK_EQUAL(payload.surfaces.size(), 4u);
0119   // Let's count
0120   std::size_t nPortals = 0;
0121   for (auto& s : payload.surfaces) {
0122     if (s.type == detray::surface_id::e_portal) {
0123       nPortals++;
0124     }
0125   }
0126   BOOST_CHECK_EQUAL(nPortals, 3u);
0127   // No acceleration structure for the moment
0128   BOOST_CHECK(!payload.acc_links.has_value());
0129 }
0130 
0131 BOOST_AUTO_TEST_CASE(CylindricalDetector) {
0132   // Load the detector from the Test utilities
0133   auto detector = buildCylindricalDetector(tContext);
0134 
0135   // Convert the detector
0136   DetrayConversionUtils::Cache cCache(detector->volumes());
0137 
0138   detray::io::detector_payload payload =
0139       DetrayGeometryConverter::convertDetector(cCache, tContext, *detector,
0140                                                *logger);
0141 
0142   // Test the payload - we have six volumes
0143   BOOST_CHECK_EQUAL(payload.volumes.size(), 6u);
0144 
0145   // The first volume is the beam pipe volume
0146   BOOST_CHECK_EQUAL(payload.volumes[0].name, "BeamPipe");
0147   // The beam pipe should have 1 surface and 5 portals
0148   // the original cylinder cover is split into 3 portals
0149   BOOST_CHECK_EQUAL(payload.volumes[0].surfaces.size(), 6u);
0150   // The second volume should be the negative endcap
0151   BOOST_CHECK_EQUAL(payload.volumes[1].name, "NegativeEndcap");
0152   // The negative endcap should have 1 surface and 6 portals
0153   BOOST_CHECK_EQUAL(payload.volumes[1].surfaces.size(), 7u);
0154   // Barrel 0,1,2 follow
0155   BOOST_CHECK_EQUAL(payload.volumes[2].name, "Barrel0");
0156   BOOST_CHECK_EQUAL(payload.volumes[3].name, "Barrel1");
0157   BOOST_CHECK_EQUAL(payload.volumes[4].name, "Barrel2");
0158   // No portal splitting for those, hence we remain at 5 surfaces
0159   // i.e. 4 portals and one surface
0160   BOOST_CHECK_EQUAL(payload.volumes[2].surfaces.size(), 5u);
0161   BOOST_CHECK_EQUAL(payload.volumes[3].surfaces.size(), 5u);
0162   BOOST_CHECK_EQUAL(payload.volumes[4].surfaces.size(), 5u);
0163   // Finally the positive endcap
0164   BOOST_CHECK_EQUAL(payload.volumes[5].name, "PositiveEndcap");
0165   // The positive endcap should have again 1 surface and 6 portals
0166   BOOST_CHECK_EQUAL(payload.volumes[5].surfaces.size(), 7u);
0167 }
0168 
0169 BOOST_AUTO_TEST_SUITE_END()