Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:36

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