Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-14 08:02:01

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/Definitions/Units.hpp"
0013 #include "Acts/Geometry/CuboidVolumeBuilder.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Geometry/ITrackingVolumeHelper.hpp"
0016 #include "Acts/Geometry/Layer.hpp"
0017 #include "Acts/Geometry/TrackingGeometry.hpp"
0018 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0019 #include "Acts/Geometry/TrackingVolume.hpp"
0020 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0021 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0022 #include "Acts/Material/MaterialSlab.hpp"
0023 #include "Acts/Surfaces/RectangleBounds.hpp"
0024 #include "Acts/Surfaces/Surface.hpp"
0025 #include "Acts/Surfaces/SurfaceArray.hpp"
0026 #include "ActsTests/CommonHelpers/DetectorElementStub.hpp"
0027 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0028 #include "ActsTests/CommonHelpers/PredefinedMaterials.hpp"
0029 
0030 #include <cmath>
0031 #include <functional>
0032 #include <memory>
0033 #include <numbers>
0034 #include <string>
0035 #include <vector>
0036 
0037 using namespace Acts;
0038 using namespace Acts::UnitLiterals;
0039 
0040 namespace ActsTests {
0041 
0042 BOOST_AUTO_TEST_CASE(CuboidVolumeBuilderTest) {
0043   // Construct builder
0044   CuboidVolumeBuilder cvb;
0045 
0046   // Create a test context
0047   GeometryContext tgContext = GeometryContext();
0048 
0049   // Create configurations for surfaces
0050   std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig;
0051   for (unsigned int i = 1; i < 5; i++) {
0052     // Position of the surfaces
0053     CuboidVolumeBuilder::SurfaceConfig cfg;
0054     cfg.position = {i * UnitConstants::m, 0., 0.};
0055 
0056     // Rotation of the surfaces
0057     double rotationAngle = std::numbers::pi / 2.;
0058     Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
0059     Vector3 yPos(0., 1., 0.);
0060     Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
0061     cfg.rotation.col(0) = xPos;
0062     cfg.rotation.col(1) = yPos;
0063     cfg.rotation.col(2) = zPos;
0064 
0065     // Boundaries of the surfaces
0066     cfg.rBounds =
0067         std::make_shared<const RectangleBounds>(RectangleBounds(0.5_m, 0.5_m));
0068 
0069     // Material of the surfaces
0070     MaterialSlab matProp(makeBeryllium(), 0.5_mm);
0071     cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
0072 
0073     // Thickness of the detector element
0074     cfg.thickness = 1_um;
0075 
0076     cfg.detElementConstructor =
0077         [](const Transform3& trans,
0078            const std::shared_ptr<const RectangleBounds>& bounds,
0079            double thickness) {
0080           return new DetectorElementStub(trans, bounds, thickness);
0081         };
0082     surfaceConfig.push_back(cfg);
0083   }
0084 
0085   // Test that there are actually 4 surface configurations
0086   BOOST_CHECK_EQUAL(surfaceConfig.size(), 4u);
0087 
0088   // Test that 4 surfaces can be built
0089   for (const auto& cfg : surfaceConfig) {
0090     std::shared_ptr<const Surface> pSur = cvb.buildSurface(tgContext, cfg);
0091     BOOST_REQUIRE_NE(pSur, nullptr);
0092     CHECK_CLOSE_ABS(pSur->center(tgContext), cfg.position, 1e-9);
0093     BOOST_CHECK_NE(pSur->surfaceMaterial(), nullptr);
0094     BOOST_CHECK_NE(pSur->associatedDetectorElement(), nullptr);
0095   }
0096 
0097   ////////////////////////////////////////////////////////////////////
0098   // Build layer configurations
0099   std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig;
0100   for (auto& sCfg : surfaceConfig) {
0101     CuboidVolumeBuilder::LayerConfig cfg;
0102     cfg.surfaceCfg = {sCfg};
0103     layerConfig.push_back(cfg);
0104   }
0105 
0106   // Test that there are actually 4 layer configurations
0107   BOOST_CHECK_EQUAL(layerConfig.size(), 4u);
0108 
0109   // Test that 4 layers with surfaces can be built
0110   for (auto& cfg : layerConfig) {
0111     LayerPtr layer = cvb.buildLayer(tgContext, cfg);
0112     BOOST_REQUIRE_NE(layer, nullptr);
0113     BOOST_CHECK(!cfg.surfaces.empty());
0114     BOOST_CHECK_EQUAL(layer->surfaceArray()->surfaces().size(), 1u);
0115     BOOST_CHECK_EQUAL(layer->layerType(), LayerType::active);
0116   }
0117 
0118   for (auto& cfg : layerConfig) {
0119     cfg.surfaces = {};
0120   }
0121 
0122   // Build volume configuration
0123   CuboidVolumeBuilder::VolumeConfig volumeConfig;
0124   volumeConfig.position = {2.5_m, 0., 0.};
0125   volumeConfig.length = {5_m, 1_m, 1_m};
0126   volumeConfig.layerCfg = layerConfig;
0127   volumeConfig.name = "Test volume";
0128   volumeConfig.volumeMaterial =
0129       std::make_shared<HomogeneousVolumeMaterial>(makeBeryllium());
0130 
0131   // Test the building
0132   std::shared_ptr<TrackingVolume> trVol =
0133       cvb.buildVolume(tgContext, volumeConfig);
0134   BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0135   BOOST_CHECK_EQUAL(trVol->confinedLayers()->arrayObjects().size(),
0136                     volumeConfig.layers.size() * 2 +
0137                         1u);  // #layers = navigation + material layers
0138   BOOST_CHECK_EQUAL(trVol->volumeName(), volumeConfig.name);
0139   BOOST_CHECK_NE(trVol->volumeMaterial(), nullptr);
0140 
0141   // Test the building
0142   volumeConfig.layers.clear();
0143   trVol = cvb.buildVolume(tgContext, volumeConfig);
0144   BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0145   BOOST_CHECK_EQUAL(trVol->confinedLayers()->arrayObjects().size(),
0146                     volumeConfig.layers.size() * 2 +
0147                         1u);  // #layers = navigation + material layers
0148   BOOST_CHECK_EQUAL(trVol->volumeName(), volumeConfig.name);
0149 
0150   volumeConfig.layers.clear();
0151   for (auto& lay : volumeConfig.layerCfg) {
0152     lay.surfaces = {};
0153     lay.active = true;
0154   }
0155   trVol = cvb.buildVolume(tgContext, volumeConfig);
0156   BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0157   for (auto& lay : volumeConfig.layers) {
0158     BOOST_CHECK_EQUAL(lay->layerType(), LayerType::active);
0159   }
0160 
0161   volumeConfig.layers.clear();
0162   for (auto& lay : volumeConfig.layerCfg) {
0163     lay.active = true;
0164   }
0165   trVol = cvb.buildVolume(tgContext, volumeConfig);
0166   BOOST_CHECK_EQUAL(volumeConfig.layers.size(), 4u);
0167   for (auto& lay : volumeConfig.layers) {
0168     BOOST_CHECK_EQUAL(lay->layerType(), LayerType::active);
0169   }
0170 
0171   ////////////////////////////////////////////////////////////////////
0172   // Build TrackingGeometry configuration
0173 
0174   // Build second volume
0175   std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig2;
0176   for (int i = 1; i < 5; i++) {
0177     // Position of the surfaces
0178     CuboidVolumeBuilder::SurfaceConfig cfg;
0179     cfg.position = {-i * UnitConstants::m, 0., 0.};
0180 
0181     // Rotation of the surfaces
0182     double rotationAngle = std::numbers::pi / 2.;
0183     Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
0184     Vector3 yPos(0., 1., 0.);
0185     Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
0186     cfg.rotation.col(0) = xPos;
0187     cfg.rotation.col(1) = yPos;
0188     cfg.rotation.col(2) = zPos;
0189 
0190     // Boundaries of the surfaces
0191     cfg.rBounds =
0192         std::make_shared<const RectangleBounds>(RectangleBounds(0.5_m, 0.5_m));
0193 
0194     // Material of the surfaces
0195     MaterialSlab matProp(makeBeryllium(), 0.5_mm);
0196     cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
0197 
0198     // Thickness of the detector element
0199     cfg.thickness = 1_um;
0200     surfaceConfig2.push_back(cfg);
0201   }
0202 
0203   std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig2;
0204   for (auto& sCfg : surfaceConfig2) {
0205     CuboidVolumeBuilder::LayerConfig cfg;
0206     cfg.surfaceCfg = {sCfg};
0207     layerConfig2.push_back(cfg);
0208   }
0209   CuboidVolumeBuilder::VolumeConfig volumeConfig2;
0210   volumeConfig2.position = {-2.5_m, 0., 0.};
0211   volumeConfig2.length = {5_m, 1_m, 1_m};
0212   volumeConfig2.layerCfg = layerConfig2;
0213   volumeConfig2.name = "Test volume2";
0214 
0215   CuboidVolumeBuilder::Config config;
0216   config.position = {0., 0., 0.};
0217   config.length = {10_m, 1_m, 1_m};
0218   config.volumeCfg = {volumeConfig2, volumeConfig};
0219 
0220   cvb.setConfig(config);
0221   TrackingGeometryBuilder::Config tgbCfg;
0222   tgbCfg.trackingVolumeBuilders.push_back(
0223       [=](const auto& context, const auto& inner, const auto&) {
0224         return cvb.trackingVolume(context, inner, nullptr);
0225       });
0226   TrackingGeometryBuilder tgb(tgbCfg);
0227 
0228   std::unique_ptr<const TrackingGeometry> detector =
0229       tgb.trackingGeometry(tgContext);
0230   BOOST_CHECK_EQUAL(
0231       detector->lowestTrackingVolume(tgContext, Vector3(1_mm, 0_mm, 0_mm))
0232           ->volumeName(),
0233       volumeConfig.name);
0234   BOOST_CHECK_EQUAL(
0235       detector->lowestTrackingVolume(tgContext, Vector3(-1_mm, 0_mm, 0_mm))
0236           ->volumeName(),
0237       volumeConfig2.name);
0238   BOOST_CHECK_EQUAL(
0239       detector->lowestTrackingVolume(tgContext, Vector3(1000_m, 0_m, 0_m)),
0240       nullptr);
0241 }
0242 
0243 }  // namespace ActsTests