Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:20

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