Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:12:45

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/Detector.hpp"
0013 #include "Acts/Detector/DetectorVolume.hpp"
0014 #include "Acts/Detector/MultiWireStructureBuilder.hpp"
0015 #include "Acts/Geometry/MultiWireVolumeBuilder.hpp"
0016 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0017 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0018 #include "Acts/Navigation/InternalNavigation.hpp"
0019 #include "Acts/Navigation/NavigationState.hpp"
0020 #include "Acts/Navigation/NavigationStateFillers.hpp"
0021 #include "Acts/Navigation/NavigationStateUpdaters.hpp"
0022 #include "Acts/Surfaces/RectangleBounds.hpp"
0023 #include "Acts/Surfaces/StrawSurface.hpp"
0024 #include "Acts/Surfaces/Surface.hpp"
0025 #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
0026 #include "Acts/Utilities/Grid.hpp"
0027 #include "Acts/Utilities/VectorHelpers.hpp"
0028 
0029 #include <fstream>
0030 #include <memory>
0031 #include <numbers>
0032 #include <string>
0033 #include <vector>
0034 
0035 using namespace Acts;
0036 using namespace Acts::Experimental;
0037 using namespace Acts::detail;
0038 using namespace Acts::Test;
0039 
0040 GeometryContext tContext;
0041 constexpr std::size_t nSurfacesX = 15;
0042 constexpr std::size_t nSurfacesY = 4;
0043 constexpr double radius = 15.0;
0044 constexpr double halfZ = 250.0;
0045 
0046 BOOST_AUTO_TEST_SUITE(Experimental)
0047 auto logger = getDefaultLogger("MultiWireNavigationTests", Logging::VERBOSE);
0048 
0049 // a function that constructs and returns detector elements for straw surfaces
0050 void generateStrawSurfaces(
0051     std::size_t nStraws, std::size_t nLayers, double radius, double halfZ,
0052     std::vector<std::shared_ptr<Surface>>& strawSurfaces,
0053     std::vector<std::unique_ptr<DetectorElementStub>>& elements) {
0054   // The transform of the 1st surface
0055   Vector3 ipos = {-0.5 * nStraws * 2 * radius + radius,
0056                   -0.5 * nLayers * 2 * radius + radius, 0.};
0057 
0058   Vector3 pos = ipos;
0059   auto lineBounds = std::make_shared<LineBounds>(radius, halfZ);
0060   int id = 1;
0061 
0062   // Generate the surfaces
0063   for (std::size_t i = 0; i < nLayers; i++) {
0064     for (std::size_t j = 0; j < nStraws; j++) {
0065       pos.x() = ipos.x() + 2 * j * radius;
0066 
0067       auto& element =
0068           elements.emplace_back(std::make_unique<DetectorElementStub>(
0069               Transform3(Translation3(pos)), lineBounds, 0));
0070 
0071       element->surface().assignGeometryId(GeometryIdentifier(id++));
0072 
0073       element->surface().assignDetectorElement(*element);
0074 
0075       strawSurfaces.push_back(element->surface().getSharedPtr());
0076     }
0077 
0078     pos.y() = ipos.y() + 2 * (i + 1) * radius;
0079   }
0080 }
0081 
0082 BOOST_AUTO_TEST_CASE(Navigation_in_Indexed_Surfaces) {
0083   std::vector<std::shared_ptr<Surface>> strawSurfaces = {};
0084   std::vector<std::unique_ptr<DetectorElementStub>> detElements = {};
0085 
0086   generateStrawSurfaces(nSurfacesX, nSurfacesY, radius, halfZ, strawSurfaces,
0087                         detElements);
0088 
0089   std::vector<double> vBounds = {0.5 * nSurfacesX * 2 * radius,
0090                                  0.5 * nSurfacesX * 2 * radius,
0091                                  0.5 * nSurfacesY * 2 * radius, halfZ};
0092 
0093   MultiWireStructureBuilder::Config mlCfg;
0094   mlCfg.name = "Multi_Layer_With_Wires";
0095   mlCfg.mlSurfaces = strawSurfaces;
0096 
0097   mlCfg.mlBinning = {
0098       {DirectedProtoAxis(AxisDirection::AxisX, AxisBoundaryType::Bound,
0099                          -vBounds[0], vBounds[0], nSurfacesX),
0100        1u},
0101       {DirectedProtoAxis(AxisDirection::AxisY, AxisBoundaryType::Bound,
0102                          -vBounds[2], vBounds[2], nSurfacesY),
0103        0u}};
0104   auto boundsPtr = std::make_unique<TrapezoidVolumeBounds>(
0105       vBounds[0], vBounds[1], vBounds[2], vBounds[3]);
0106   mlCfg.mlBounds = boundsPtr->values();
0107 
0108   MultiWireStructureBuilder mlBuilder(mlCfg);
0109   auto [volumes, portals, roots] = mlBuilder.construct(tContext);
0110 
0111   Acts::Experimental::NavigationState nState;
0112   nState.position = Acts::Vector3(0., -59., 0.);
0113   nState.direction = Acts::Vector3(0., 1., 0.);
0114 
0115   nState.currentVolume = volumes.front().get();
0116   nState.currentVolume->updateNavigationState(tContext, nState);
0117 
0118   // check the surface candidates after update (12 surfaces + 6 portals but only
0119   // 4 surfaces are reachable (one of each layer and one portal)
0120   BOOST_CHECK_EQUAL(nState.surfaceCandidates.size(), 5u);
0121 }
0122 
0123 // This tests the multilayer navigation policy for gen3 geometry interface
0124 BOOST_AUTO_TEST_CASE(MultiLayer_NavigationPolicy) {
0125   // Create the surfaces
0126   std::vector<std::shared_ptr<Surface>> strawSurfaces = {};
0127   std::vector<std::unique_ptr<DetectorElementStub>> detElements = {};
0128 
0129   generateStrawSurfaces(nSurfacesX, nSurfacesY, radius, halfZ, strawSurfaces,
0130                         detElements);
0131 
0132   std::vector<double> vBounds = {0.5 * nSurfacesX * 2 * radius,
0133                                  0.5 * nSurfacesX * 2 * radius,
0134                                  0.5 * nSurfacesY * 2 * radius, halfZ};
0135   // Create the multi wire volume (tracking volume this time!)
0136   MultiWireVolumeBuilder::Config mwCfg;
0137   mwCfg.name = "MultiWireVolume";
0138   mwCfg.mlSurfaces = strawSurfaces;
0139   mwCfg.binning = {
0140       {DirectedProtoAxis(AxisDirection::AxisX, AxisBoundaryType::Bound,
0141                          -vBounds[0], vBounds[0], nSurfacesX),
0142        1u},
0143       {DirectedProtoAxis(AxisDirection::AxisY, AxisBoundaryType::Bound,
0144                          -vBounds[2], vBounds[2], nSurfacesY),
0145        0u}};
0146   auto boundsPtr = std::make_shared<Acts::TrapezoidVolumeBounds>(
0147       vBounds[0], vBounds[1], vBounds[2], vBounds[3]);
0148   mwCfg.bounds = boundsPtr;
0149   mwCfg.transform = Transform3(Translation3(Vector3(0., 0., 0.)));
0150 
0151   // Build the volume
0152   MultiWireVolumeBuilder mwBuilder(mwCfg);
0153   std::unique_ptr<Acts::TrackingVolume> volume =
0154       mwBuilder.buildVolume(tContext);
0155 
0156   // Check the volume
0157   // we do not except any children volumes
0158   BOOST_CHECK(volume->volumes().empty());
0159 
0160   // we expect 15*4 = 60 surfaces
0161   BOOST_CHECK(volume->surfaces().size() == 60u);
0162 
0163   BOOST_CHECK(volume->portals().size() == 6u);
0164 
0165   // check the navigation policy
0166   NavigationStream main;
0167   AppendOnlyNavigationStream stream{main};
0168   Vector3 startPos = {0., -59., 0.};
0169   Vector3 startDir = {0., 1., 0.};
0170   NavigationArguments args{startPos, startDir};
0171 
0172   volume->initializeNavigationCandidates(args, stream, *logger);
0173 
0174   // we expect 18 candidates (12 surfaces + 6 portals)
0175   BOOST_CHECK_EQUAL(main.candidates().size(), 18u);
0176 
0177   // check if we have duplicated surface candidates
0178   auto it = std::unique(main.candidates().begin(), main.candidates().end(),
0179                         [](const auto& lhs, const auto& rhs) {
0180                           return lhs.surface() == rhs.surface();
0181                         });
0182   BOOST_CHECK(it == main.candidates().end());
0183 
0184   // try with a different direction
0185   double angle = std::numbers::pi / 4.;
0186   startDir = {std::cos(angle), std::sin(angle), 0.};
0187   args.direction = startDir;
0188   // clear the candidates and re initialize with new arguments
0189   main.candidates().clear();
0190   volume->initializeNavigationCandidates(args, stream, *logger);
0191   // we expect 18 candidates (12 surfaces + 6 portals)
0192   BOOST_CHECK_EQUAL(main.candidates().size(), 18u);
0193 }
0194 
0195 BOOST_AUTO_TEST_SUITE_END()