Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-30 08:04:28

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 #pragma once
0010 
0011 #include <boost/test/unit_test.hpp>
0012 
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/Definitions/Direction.hpp"
0015 #include "Acts/Definitions/Units.hpp"
0016 #include "Acts/Geometry/Blueprint.hpp"
0017 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0018 #include "Acts/Geometry/CuboidVolumeBuilder.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Geometry/StaticBlueprintNode.hpp"
0021 #include "Acts/Geometry/TrackingGeometry.hpp"
0022 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0023 #include "Acts/Geometry/TrackingVolume.hpp"
0024 #include "Acts/Propagator/NavigationTarget.hpp"
0025 #include "Acts/Propagator/Navigator.hpp"
0026 #include "Acts/Surfaces/PlaneSurface.hpp"
0027 #include "Acts/Surfaces/RectangleBounds.hpp"
0028 #include "Acts/Surfaces/Surface.hpp"
0029 #include "Acts/Utilities/Intersection.hpp"
0030 #include "Acts/Utilities/Logger.hpp"
0031 
0032 #include <memory>
0033 #include <vector>
0034 
0035 /// A telescope of two plane surfaces for both geometry generations
0036 namespace ActsTests::NavigatorTelescope {
0037 
0038 using namespace Acts;
0039 using namespace Acts::UnitLiterals;
0040 
0041 const GeometryContext gctx = GeometryContext::dangerouslyDefaultConstruct();
0042 
0043 const Logging::Level logLevel = Logging::INFO;
0044 
0045 // One 2x2x2 m volume around the origin with two plane surfaces at z = 0.5 m,
0046 // displaced to y = +-0.5 m. Their half extent in y is 0.2 m, so a track along
0047 // z through the origin misses both by 0.3 m.
0048 constexpr double surfaceZ = 0.5_m;
0049 constexpr double surfaceY = 0.5_m;
0050 constexpr double surfaceHalfX = 0.8_m;
0051 constexpr double surfaceHalfY = 0.2_m;
0052 
0053 struct Telescope {
0054   std::shared_ptr<const TrackingGeometry> geometry;
0055   const Surface* top{};
0056   const Surface* bottom{};
0057 };
0058 
0059 /// Build the telescope as a Gen1 tracking geometry.
0060 inline Telescope makeTelescopeGen1() {
0061   CuboidVolumeBuilder::Config conf;
0062   conf.position = {0., 0., 0.};
0063   conf.length = {2_m, 2_m, 2_m};
0064 
0065   CuboidVolumeBuilder::SurfaceConfig top;
0066   top.position = {0, surfaceY, surfaceZ};
0067   top.rBounds = std::make_shared<RectangleBounds>(surfaceHalfX, surfaceHalfY);
0068 
0069   CuboidVolumeBuilder::SurfaceConfig bottom;
0070   bottom.position = {0, -surfaceY, surfaceZ};
0071   bottom.rBounds =
0072       std::make_shared<RectangleBounds>(surfaceHalfX, surfaceHalfY);
0073 
0074   CuboidVolumeBuilder::LayerConfig layer;
0075   layer.binningDimension = AxisDirection::AxisZ;
0076   layer.surfaceCfg.push_back(top);
0077   layer.surfaceCfg.push_back(bottom);
0078 
0079   CuboidVolumeBuilder::VolumeConfig volume;
0080   volume.binningDimension = AxisDirection::AxisZ;
0081   volume.position = {0, 0, 0};
0082   volume.length = {1.9_m, 1.9_m, 1.9_m};
0083   volume.name = "telescope";
0084   volume.layerCfg.push_back(layer);
0085 
0086   conf.volumeCfg.push_back(volume);
0087 
0088   CuboidVolumeBuilder cvb(conf);
0089   TrackingGeometryBuilder::Config tgbCfg;
0090   tgbCfg.trackingVolumeBuilders.push_back(
0091       [=](const auto& context, const auto& inner, const auto&) {
0092         return cvb.trackingVolume(context, inner, nullptr);
0093       });
0094 
0095   Telescope telescope;
0096   telescope.geometry = TrackingGeometryBuilder(tgbCfg).trackingGeometry(gctx);
0097 
0098   std::vector<const Surface*> surfaces;
0099   telescope.geometry->visitSurfaces(
0100       [&](const Surface* surface) { surfaces.push_back(surface); });
0101   BOOST_REQUIRE_EQUAL(surfaces.size(), 2u);
0102   telescope.top = surfaces.at(0);
0103   telescope.bottom = surfaces.at(1);
0104   return telescope;
0105 }
0106 
0107 /// Build the same telescope as a Gen3 tracking geometry.
0108 inline Telescope makeTelescopeGen3(const Logger& logger) {
0109   Blueprint::Config cfg;
0110   cfg.envelope = ExtentEnvelope{{
0111       .x = {20_mm, 20_mm},
0112       .y = {20_mm, 20_mm},
0113       .z = {20_mm, 20_mm},
0114   }};
0115   Blueprint root{cfg};
0116 
0117   auto volume = std::make_unique<TrackingVolume>(
0118       Transform3::Identity(),
0119       std::make_shared<CuboidVolumeBounds>(0.95_m, 0.95_m, 0.95_m),
0120       "telescope");
0121 
0122   Telescope telescope;
0123   for (double y : {surfaceY, -surfaceY}) {
0124     auto surface = Surface::makeShared<PlaneSurface>(
0125         Transform3{Translation3{Vector3{0, y, surfaceZ}}},
0126         std::make_shared<const RectangleBounds>(surfaceHalfX, surfaceHalfY));
0127     if (y > 0) {
0128       telescope.top = surface.get();
0129     } else {
0130       telescope.bottom = surface.get();
0131     }
0132     volume->addSurface(std::move(surface));
0133   }
0134 
0135   root.addChild(std::make_shared<StaticBlueprintNode>(std::move(volume)));
0136   telescope.geometry = root.construct({}, gctx, logger);
0137   return telescope;
0138 }
0139 
0140 /// A plane surface with its normal along z, held by no volume, so it keeps
0141 /// the default geometry identifier.
0142 inline std::shared_ptr<Surface> makeOutOfGeometrySurface(const Vector3& center,
0143                                                          double halfX = 0.1_m,
0144                                                          double halfY = 0.1_m) {
0145   return Surface::makeShared<PlaneSurface>(
0146       Transform3{Translation3{center}},
0147       std::make_shared<const RectangleBounds>(halfX, halfY));
0148 }
0149 
0150 /// Move @p position onto @p surface along @p direction
0151 inline void stepOnto(Vector3& position, const Vector3& direction,
0152                      const Surface& surface) {
0153   const Intersection3D intersection =
0154       surface.intersect(gctx, position, direction).closestForward();
0155   BOOST_REQUIRE(intersection.isValid());
0156   position += intersection.pathLength() * direction;
0157 }
0158 
0159 /// Initialize the navigator at @p position along +z, return its first target
0160 inline NavigationTarget firstTarget(const Navigator& navigator,
0161                                     const Navigator::Options& options,
0162                                     const Vector3& position) {
0163   Navigator::State state = navigator.makeState(options);
0164   Vector3 pos = position;
0165   const Vector3 dir = Vector3::UnitZ();
0166   Result<void> result =
0167       navigator.initialize(state, {.position = pos, .direction = dir});
0168   BOOST_REQUIRE(result.ok());
0169   return navigator.nextTarget(state, pos, dir);
0170 }
0171 
0172 /// Walk the navigation and return every surface the propagation reaches.
0173 inline std::vector<const Surface*> walk(const Navigator& navigator,
0174                                         const Navigator::Options& options,
0175                                         const Vector3& start,
0176                                         const Vector3& dir, int maxSteps = 12) {
0177   Navigator::State state = navigator.makeState(options);
0178   Vector3 position = start;
0179   BOOST_REQUIRE(
0180       navigator.initialize(state, {.position = position, .direction = dir})
0181           .ok());
0182 
0183   std::vector<const Surface*> reached;
0184   for (int i = 0; i < maxSteps; ++i) {
0185     NavigationTarget target = navigator.nextTarget(state, position, dir);
0186     if (target.isNone()) {
0187       break;
0188     }
0189     reached.push_back(&target.surface());
0190     stepOnto(position, dir, target.surface());
0191     navigator.handleSurfaceReached(state, position, dir, target.surface());
0192   }
0193   return reached;
0194 }
0195 
0196 inline Navigator makeNavigator(std::shared_ptr<const TrackingGeometry> geometry,
0197                                const Logger& logger) {
0198   Navigator::Config cfg;
0199   cfg.trackingGeometry = std::move(geometry);
0200   cfg.resolveSensitive = true;
0201   cfg.resolveMaterial = true;
0202   cfg.resolvePassive = true;
0203   return Navigator(cfg, logger.clone("Navigator"));
0204 }
0205 
0206 }  // namespace ActsTests::NavigatorTelescope