|
|
|||
File indexing completed on 2026-10-23 08:19:41
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 "Acts/Definitions/Tolerance.hpp" 0012 #include "Acts/Geometry/PortalLinkBase.hpp" 0013 #include "Acts/Geometry/TrackingVolume.hpp" 0014 #include "Acts/Surfaces/CylinderSurface.hpp" 0015 #include "Acts/Surfaces/DiscSurface.hpp" 0016 #include "Acts/Surfaces/PlaneSurface.hpp" 0017 #include "Acts/Utilities/AxisDefinitions.hpp" 0018 #include "Acts/Utilities/Grid.hpp" 0019 #include "Acts/Utilities/Logger.hpp" 0020 #include "Acts/Utilities/ThrowAssert.hpp" 0021 0022 #include <iosfwd> 0023 0024 namespace Acts { 0025 0026 class IGrid; 0027 class TrivialPortalLink; 0028 0029 template <typename... Axes> 0030 requires(sizeof...(Axes) <= 2) 0031 class GridPortalLinkT; 0032 0033 /// GridPortalLink implements a subdivided surface where the target volume 0034 /// depends on the position on the surface. The link can be in two states: 0035 /// 1. One-dimensional binning with an associated *direction* to determine which 0036 /// local coordinate to use for the lookup 0037 /// 2. Two-dimensional binning 0038 /// @note The grid dimensions and boundaries are **required** (and checked) to be 0039 /// consistent with the surface bounds. 0040 class GridPortalLink : public PortalLinkBase { 0041 protected: 0042 /// Constructor from a surface and a direction, for initialization by derived 0043 /// class 0044 /// @param surface The surface 0045 /// @param direction The binning direction 0046 GridPortalLink(std::shared_ptr<RegularSurface> surface, 0047 AxisDirection direction); 0048 0049 public: 0050 /// Override the destructor so we can get away with forward declaration of 0051 /// `TrivialPortalLink` 0052 ~GridPortalLink() override; 0053 0054 /// Factory function for a one-dimensional grid portal link, which allows 0055 /// using template deduction to figure out the right type 0056 /// @tparam axis_t The axis type 0057 /// @param surface The surface 0058 /// @param direction The binning direction 0059 /// @param axis The axis to use for the binning 0060 /// @note The axis boundaries are checked against the bounds of @p surface. 0061 /// @return A unique pointer to the grid portal link 0062 template <AxisConcept axis_t> 0063 static std::unique_ptr<GridPortalLinkT<axis_t>> make( 0064 const std::shared_ptr<RegularSurface>& surface, AxisDirection direction, 0065 axis_t&& axis) { 0066 using enum AxisDirection; 0067 if (dynamic_cast<const CylinderSurface*>(surface.get()) != nullptr) { 0068 if (direction != AxisZ && direction != AxisRPhi) { 0069 throw std::invalid_argument{"Invalid binning direction"}; 0070 } 0071 } else if (dynamic_cast<const DiscSurface*>(surface.get()) != nullptr && 0072 direction != AxisR && direction != AxisPhi) { 0073 throw std::invalid_argument{"Invalid binning direction"}; 0074 } else if (dynamic_cast<const PlaneSurface*>(surface.get()) != nullptr && 0075 direction != AxisX && direction != AxisY) { 0076 throw std::invalid_argument{"Invalid binning direction"}; 0077 } 0078 0079 return std::make_unique<GridPortalLinkT<axis_t>>( 0080 surface, direction, std::forward<axis_t>(axis)); 0081 } 0082 0083 /// Factory function for a two-dimensional grid portal link, which allows 0084 /// using template deduction to figure out the right type. 0085 /// @tparam axis_1_t The first axis type 0086 /// @tparam axis_2_t The second axis type 0087 /// @param surface The surface 0088 /// @param axis1 The first axis to use for the binning 0089 /// @param axis2 The second axis to use for the binning 0090 /// @note The axis boundaries are checked against the bounds of @p surface. 0091 /// @return A unique pointer to the grid portal link 0092 template <AxisConcept axis_1_t, AxisConcept axis_2_t> 0093 static std::unique_ptr<GridPortalLinkT<axis_1_t, axis_2_t>> make( 0094 const std::shared_ptr<RegularSurface>& surface, axis_1_t axis1, 0095 axis_2_t axis2) { 0096 std::optional<AxisDirection> direction; 0097 if (dynamic_cast<const CylinderSurface*>(surface.get()) != nullptr) { 0098 direction = AxisDirection::AxisRPhi; 0099 } else if (dynamic_cast<const DiscSurface*>(surface.get()) != nullptr) { 0100 direction = AxisDirection::AxisR; 0101 } else if (dynamic_cast<const PlaneSurface*>(surface.get()) != nullptr) { 0102 direction = AxisDirection::AxisX; 0103 } 0104 0105 return std::make_unique<GridPortalLinkT<axis_1_t, axis_2_t>>( 0106 surface, direction.value(), std::move(axis1), std::move(axis2)); 0107 } 0108 0109 /// Factory function for an automatically sized one-dimensional grid. This produces a single-bin grid with boundaries taken from the bounds of @p surface along @p direction. 0110 /// @param surface The surface 0111 /// @param volume The tracking volume 0112 /// @param direction The binning direction 0113 /// @return A unique pointer to the grid portal link 0114 static std::unique_ptr<GridPortalLink> make( 0115 const std::shared_ptr<RegularSurface>& surface, TrackingVolume& volume, 0116 AxisDirection direction); 0117 0118 /// Factory function for a one-dimensional grid portal link from a 0119 /// type-erased axis. Dispatches to the templated overload inside Core, so 0120 /// callers do not instantiate every axis type themselves. 0121 /// @param surface The surface 0122 /// @param direction The binning direction 0123 /// @param axis The axis to use for the binning 0124 /// @return A unique pointer to the grid portal link 0125 static std::unique_ptr<GridPortalLink> make( 0126 const std::shared_ptr<RegularSurface>& surface, AxisDirection direction, 0127 const IAxis& axis); 0128 0129 /// Factory function for a two-dimensional grid portal link from type-erased 0130 /// axes, see the one-dimensional overload. 0131 /// @param surface The surface 0132 /// @param axis0 The first axis to use for the binning 0133 /// @param axis1 The second axis to use for the binning 0134 /// @return A unique pointer to the grid portal link 0135 static std::unique_ptr<GridPortalLink> make( 0136 const std::shared_ptr<RegularSurface>& surface, const IAxis& axis0, 0137 const IAxis& axis1); 0138 0139 /// Merge two grid portal links into a single one. The routine can merge 0140 /// one-dimensional, two-dimensional and mixed links. The merge will try to 0141 /// preserve equidistant binning in case bin widths match. Otherwise, the 0142 /// merge falls back to variable binning. 0143 /// 0144 /// 1D merge scenarios: 0145 /// 0146 /// ``` 0147 /// +----------------------------------------------------------+ 0148 /// |Colinear | 0149 /// | | 0150 /// | +-------+-------+-------+ +-------+-------+-------+ | 0151 /// | | | | | | | | | | 0152 /// | | | | | + | | | | | 0153 /// | | | | | | | | | | 0154 /// | +-------+-------+-------+ +-------+-------+-------+ | 0155 /// | +-------+-------+-------+-------+-------+-------+ | 0156 /// | | | | | | | | | 0157 /// | = | | | | | | | | 0158 /// | | | | | | | | | 0159 /// | +-------+-------+-------+-------+-------+-------+ | 0160 /// | | 0161 /// +----------------------------------------------------------+ 0162 /// ``` 0163 /// 0164 /// Two grid along a shared direction are merged along their shared direction 0165 /// 0166 /// ``` 0167 /// +-------------------------------------------------+ 0168 /// |Parallel | 0169 /// | | 0170 /// | +-------+ +-------+ +-------+-------+ | 0171 /// | | | | | | | | | 0172 /// | | | | | | | | | 0173 /// | | | | | | | | | 0174 /// | +-------+ +-------+ +-------+-------+ | 0175 /// | | | | | | | | | 0176 /// | | | + | | = | | | | 0177 /// | | | | | | | | | 0178 /// | +-------+ +-------+ +-------+-------+ | 0179 /// | | | | | | | | | 0180 /// | | | | | | | | | 0181 /// | | | | | | | | | 0182 /// | +-------+ +-------+ +-------+-------+ | 0183 /// | | 0184 /// +-------------------------------------------------+ 0185 /// ``` 0186 /// 0187 /// Two grids along a shared direction a merged in the direction that is 0188 /// orthogonal to their shared direction. 0189 /// 0190 /// ``` 0191 /// +-------------------------------------------+ 0192 /// |Perpendicular | 0193 /// | | 0194 /// | +-------+ | 0195 /// | | | | 0196 /// | | | | 0197 /// | | | | 0198 /// | +-------+ +-------+-------+-------+ | 0199 /// | | | | | | | | 0200 /// | | | + | | | | | 0201 /// | | | | | | | | 0202 /// | +-------+ +-------+-------+-------+ | 0203 /// | | | | 0204 /// | | | | 0205 /// | | | +-------+-------+-------+ | 0206 /// | +-------+ | | | | | 0207 /// | | | | | | 0208 /// | | | | | | 0209 /// | +-------+-------+-------+ | 0210 /// | | | | | | 0211 /// | = | | | | | 0212 /// | | | | | | 0213 /// | +-------+-------+-------+ | 0214 /// | | | | | | 0215 /// | | | | | | 0216 /// | | | | | | 0217 /// | +-------+-------+-------+ | 0218 /// | | 0219 /// +-------------------------------------------+ 0220 /// ``` 0221 /// 0222 /// Two grids whose directions are not shared are merged (ordering does not 0223 /// matter here). The routine will expand one of the grids to match the 0224 /// other's binning, by subdividing the grid in the as-of-yet unbinned 0225 /// direction, while filling all bins with the original bin contents. 0226 /// Afterwards, a conventional mixed-dimension merge is performed. 0227 /// 0228 /// Mixed merge scenarios 0229 /// The order is normalized by always taking the 2D grid as the left hand 0230 /// side. The 1D grid is expanded to match the binning in the as-of-yet 0231 /// unbinned direction with the binning taken from the 2D grid. 0232 /// 0233 /// ``` 0234 /// +-----------------------------------------+ 0235 /// |2D + 1D | 0236 /// | | 0237 /// | +-------+-------+ +-------+-------+ | 0238 /// | | | | | | | | 0239 /// | | | | | | | | 0240 /// | | | | | | | | 0241 /// | +-------+-------+ +-------+-------+ | 0242 /// | | | | | | | | 0243 /// | | | | | | | | 0244 /// | | | | | | | | 0245 /// | +-------+-------+ = +-------+-------+ | 0246 /// | | | | | | | | 0247 /// | | | | | | | | 0248 /// | | | | | | | | 0249 /// | +-------+-------+ +-------+-------+ | 0250 /// | + | | | | 0251 /// | +-------+-------+ | | | | 0252 /// | | | | | | | | 0253 /// | | | | +-------+-------+ | 0254 /// | | | | | 0255 /// | +-------+-------+ | 0256 /// +-----------------------------------------+ 0257 /// ``` 0258 /// 0259 /// ``` 0260 /// +--------------------------------------------------------------+ 0261 /// |2D + 1D | 0262 /// | | 0263 /// | +-------+-------+ +-------+ +-------+-------+-------+ | 0264 /// | | | | | | | | | | | 0265 /// | | | | | | | | | | | 0266 /// | | | | | | | | | | | 0267 /// | +-------+-------+ +-------+ +-------+-------+-------+ | 0268 /// | | | | | | | | | | | 0269 /// | | | | + | | = | | | | | 0270 /// | | | | | | | | | | | 0271 /// | +-------+-------+ +-------+ +-------+-------+-------+ | 0272 /// | | | | | | | | | | | 0273 /// | | | | | | | | | | | 0274 /// | | | | | | | | | | | 0275 /// | +-------+-------+ +-------+ +-------+-------+-------+ | 0276 /// | | 0277 /// +--------------------------------------------------------------+ 0278 /// ``` 0279 /// 0280 /// 2D merges 0281 /// The grids need to already share a common axis. If that is not the case, 0282 /// the merge routine returns a `nullptr`. This can be handled by composite 0283 /// merging as a fallback if needed. 0284 /// Ordering and direction does not matter here. 0285 /// 0286 /// ``` 0287 /// +-----------------------------------------+ 0288 /// |2D + 2D | 0289 /// | | 0290 /// | +-------+-------+ +-------+-------+ | 0291 /// | | | | | | | | 0292 /// | | | | | | | | 0293 /// | | | | | | | | 0294 /// | +-------+-------+ +-------+-------+ | 0295 /// | | | | | | | | 0296 /// | | | | + | | | | 0297 /// | | | | | | | | 0298 /// | +-------+-------+ +-------+-------+ | 0299 /// | | | | | | | | 0300 /// | | | | | | | | 0301 /// | | | | | | | | 0302 /// | +-------+-------+ +-------+-------+ | 0303 /// | | 0304 /// | +-------+-------+-------+-------+ | 0305 /// | | | | | | | 0306 /// | | | | | | | 0307 /// | | | | | | | 0308 /// | +-------+-------+-------+-------+ | 0309 /// | | | | | | | 0310 /// | = | | | | | | 0311 /// | | | | | | | 0312 /// | +-------+-------+-------+-------+ | 0313 /// | | | | | | | 0314 /// | | | | | | | 0315 /// | | | | | | | 0316 /// | +-------+-------+-------+-------+ | 0317 /// | | 0318 /// +-----------------------------------------+ 0319 /// ``` 0320 /// 0321 /// @param a The first grid portal link 0322 /// @param b The second grid portal link 0323 /// @param direction The merging direction 0324 /// @param logger The logger to use for messages 0325 /// @return The merged grid portal link or nullptr if grid merging did not succeed 0326 /// @note The returned pointer can be nullptr, if the grids 0327 /// given are not mergeable, because their binnings are 0328 /// not compatible. This is not an error case, and needs 0329 /// to be handled by the caller! Invalid input is handled 0330 /// via exceptions. 0331 static std::unique_ptr<PortalLinkBase> merge( 0332 const GridPortalLink& a, const GridPortalLink& b, AxisDirection direction, 0333 const Logger& logger = getDummyLogger()); 0334 0335 /// Return the associated grid in a type-erased form 0336 /// @return The grid 0337 virtual const IGrid& grid() const = 0; 0338 0339 /// Return the associated grid in a type-erased form 0340 /// @return The grid 0341 virtual IGrid& grid() = 0; 0342 0343 /// Set the volume on all grid bins 0344 /// @param volume The volume to set 0345 virtual void setVolume(TrackingVolume* volume) = 0; 0346 0347 /// Get the number of dimensions of the grid 0348 /// @return The number of dimensions 0349 virtual unsigned int dim() const = 0; 0350 0351 /// Expand a 1D grid to a 2D one, by using the provided axis along the 0352 /// *missing* direction. 0353 /// @param other The axis to use for the missing direction, 0354 /// can be null for auto determination 0355 /// @return A unique pointer to the 2D grid portal link 0356 virtual std::unique_ptr<GridPortalLink> extendTo2d( 0357 const IAxis* other) const = 0; 0358 0359 /// The binning direction of the grid 0360 /// @note For 2D grids, this will always be the loc0 0361 /// direction, depending on the surface type. 0362 /// @return The binning direction 0363 AxisDirection direction() const { return m_direction; } 0364 0365 /// Helper function to fill the bin contents after merging. 0366 /// This called by the merging routine, and requires access to the internal 0367 /// grid state. 0368 /// @param a The first grid portal link 0369 /// @param b The second grid portal link 0370 /// @param merged The merged grid portal link 0371 /// @param direction The merging direction 0372 /// @param logger The logger to use for messages 0373 static void fillMergedGrid(const GridPortalLink& a, const GridPortalLink& b, 0374 GridPortalLink& merged, AxisDirection direction, 0375 const Logger& logger); 0376 0377 /// Helper function that prints a textual representation of the grid with the 0378 /// volume names. 0379 /// @param os The output stream 0380 void printContents(std::ostream& os) const; 0381 0382 /// Get the artifact portal links 0383 /// @return Span of artifact portal links 0384 std::span<const TrivialPortalLink> artifactPortalLinks() const; 0385 /// Set the artifact portal links 0386 /// @param links Vector of trivial portal links to set 0387 void setArtifactPortalLinks(std::vector<TrivialPortalLink> links); 0388 0389 protected: 0390 /// Helper function to check consistency for grid on a cylinder surface 0391 /// @param grid the grid to check 0392 /// @param direction The binning direction 0393 /// @param cyl The cylinder surface 0394 static void checkConsistency(const IGrid& grid, AxisDirection direction, 0395 const CylinderSurface& cyl); 0396 0397 /// Helper function to check consistency for grid on a disc surface 0398 /// @param grid the grid to check 0399 /// @param direction The binning direction 0400 /// @param disc The disc surface 0401 static void checkConsistency(const IGrid& grid, AxisDirection direction, 0402 const DiscSurface& disc); 0403 /// Helper function to check consistency for grid on a plane surface 0404 /// @param grid the grid to check 0405 /// @param direction The binning direction 0406 /// @param plane The plane surface 0407 static void checkConsistency(const IGrid& grid, AxisDirection direction, 0408 const PlaneSurface& plane); 0409 /// Expand a 1D grid to a 2D one for a cylinder surface 0410 /// @param surface The cylinder surface 0411 /// @param other The axis to use for the missing direction, 0412 /// can be null for auto determination 0413 /// @return A unique pointer to the 2D grid portal link 0414 std::unique_ptr<GridPortalLink> extendTo2dImpl( 0415 const std::shared_ptr<CylinderSurface>& surface, 0416 const IAxis* other) const; 0417 0418 /// Expand a 1D grid to a 2D one for a disc surface 0419 /// @param surface The disc surface 0420 /// @param other The axis to use for the missing direction, 0421 /// can be null for auto determination 0422 /// @return A unique pointer to the 2D grid portal link 0423 std::unique_ptr<GridPortalLink> extendTo2dImpl( 0424 const std::shared_ptr<DiscSurface>& surface, const IAxis* other) const; 0425 0426 /// Expand a 1D grid to a 2D one for a plane surface 0427 /// @param surface The plane surface 0428 /// @param other The axis to use for the missing direction, 0429 /// can be null for auto determination 0430 /// @return A unique pointer to the 2D grid portal link 0431 std::unique_ptr<GridPortalLink> extendTo2dImpl( 0432 const std::shared_ptr<PlaneSurface>& surface, const IAxis* other) const; 0433 0434 /// Helper enum to declare which local direction to fill 0435 enum class FillDirection { 0436 loc0, 0437 loc1, 0438 }; 0439 0440 /// Helper function to fill a 2D grid from a 1D grid, by extending all 0441 /// bins along the different direction. 0442 /// @param dir The direction to fill 0443 /// @param grid1d The 1D grid 0444 /// @param grid2d The 2D grid 0445 static void fillGrid1dTo2d(FillDirection dir, const GridPortalLink& grid1d, 0446 GridPortalLink& grid2d); 0447 0448 private: 0449 AxisDirection m_direction; 0450 0451 /// Stores the trivial portal links that were used to build this grid portal 0452 /// link, if any 0453 std::vector<TrivialPortalLink> m_artifactPortalLinks; 0454 }; 0455 0456 /// Concrete class deriving from @c GridPortalLink that boxes a concrete grid for lookup. 0457 /// @tparam Axes The axis types of the grid 0458 template <typename... Axes> 0459 requires(sizeof...(Axes) <= 2) 0460 class GridPortalLinkT : public GridPortalLink { 0461 public: 0462 /// The internal grid type 0463 using GridType = Grid<const TrackingVolume*, Axes...>; 0464 0465 /// The dimension of the grid 0466 static constexpr std::size_t DIM = sizeof...(Axes); 0467 0468 /// Constructor from a surface, axes and direction 0469 /// @param surface The surface 0470 /// @param direction The binning direction 0471 /// @param axes The axes for the grid 0472 /// @note The axes are checked for consistency with the bounds of @p surface. 0473 GridPortalLinkT(std::shared_ptr<RegularSurface> surface, 0474 AxisDirection direction, Axes&&... axes) 0475 : GridPortalLink(std::move(surface), direction), 0476 m_grid(std::tuple{std::move(axes)...}) { 0477 using enum AxisDirection; 0478 0479 if (const auto* cylinder = 0480 dynamic_cast<const CylinderSurface*>(m_surface.get())) { 0481 checkConsistency(m_grid, direction, *cylinder); 0482 0483 if (direction == AxisRPhi) { 0484 m_projection = &projection<CylinderSurface, AxisRPhi>; 0485 } else if (direction == AxisZ) { 0486 m_projection = &projection<CylinderSurface, AxisZ>; 0487 } else { 0488 throw std::invalid_argument{"Invalid binning direction"}; 0489 } 0490 0491 } else if (const auto* disc = 0492 dynamic_cast<const DiscSurface*>(m_surface.get())) { 0493 checkConsistency(m_grid, direction, *disc); 0494 0495 if (direction == AxisR) { 0496 m_projection = &projection<DiscSurface, AxisR>; 0497 } else if (direction == AxisDirection::AxisPhi) { 0498 m_projection = &projection<DiscSurface, AxisPhi>; 0499 } else { 0500 throw std::invalid_argument{"Invalid binning direction"}; 0501 } 0502 } else if (const auto* plane = 0503 dynamic_cast<const PlaneSurface*>(m_surface.get())) { 0504 checkConsistency(m_grid, direction, *plane); 0505 0506 if (direction == AxisX) { 0507 m_projection = &projection<PlaneSurface, AxisX>; 0508 } else if (direction == AxisDirection::AxisY) { 0509 m_projection = &projection<PlaneSurface, AxisY>; 0510 } else { 0511 throw std::invalid_argument{"Invalid binning direction"}; 0512 } 0513 0514 } else { 0515 throw std::logic_error{"Surface type is not supported"}; 0516 } 0517 } 0518 0519 /// Get the grid 0520 /// @return The grid 0521 const GridType& grid() const override { return m_grid; } 0522 0523 /// Get the grid 0524 /// @return The grid 0525 GridType& grid() override { return m_grid; } 0526 0527 /// Get the number of dimensions of the grid 0528 /// @return The number of dimensions 0529 unsigned int dim() const override { return DIM; } 0530 0531 /// Prints an identification to the output stream 0532 /// @param os The output stream 0533 void toStream(std::ostream& os) const override { 0534 os << "GridPortalLink<dim=" << dim() << ">"; 0535 } 0536 0537 /// Makes a 2D grid from a 1D grid by extending it using an optional axis 0538 /// @param other The axis to use for the missing direction, 0539 /// can be null for auto determination 0540 /// @return A unique pointer to the 2D grid portal link 0541 std::unique_ptr<GridPortalLink> extendTo2d( 0542 const IAxis* other) const override { 0543 if constexpr (DIM == 2) { 0544 return std::make_unique<GridPortalLinkT<Axes...>>(*this); 0545 } else { 0546 if (auto cylinder = 0547 std::dynamic_pointer_cast<CylinderSurface>(m_surface)) { 0548 return extendTo2dImpl(cylinder, other); 0549 } else if (auto disc = 0550 std::dynamic_pointer_cast<DiscSurface>(m_surface)) { 0551 return extendTo2dImpl(disc, other); 0552 } else if (auto plane = 0553 std::dynamic_pointer_cast<PlaneSurface>(m_surface)) { 0554 return extendTo2dImpl(plane, other); 0555 } else { 0556 throw std::logic_error{ 0557 "Surface type is not supported (this should not happen)"}; 0558 } 0559 } 0560 } 0561 0562 /// Set the volume on all grid bins 0563 /// @param volume The volume to set 0564 void setVolume(TrackingVolume* volume) override { 0565 auto loc = m_grid.multiAxis().getNBins(); 0566 if constexpr (GridType::DIM == 1) { 0567 for (std::size_t i = 1; i <= loc[0]; i++) { 0568 m_grid.atLocalBins({i}) = volume; 0569 } 0570 } else { 0571 for (std::size_t i = 1; i <= loc[0]; i++) { 0572 for (std::size_t j = 1; j <= loc[1]; j++) { 0573 m_grid.atLocalBins({i, j}) = volume; 0574 } 0575 } 0576 } 0577 } 0578 0579 /// Lookup the tracking volume at a position on the surface 0580 /// @param gctx The geometry context 0581 /// @param position The local position 0582 /// @param tolerance The tolerance for the lookup 0583 /// @note The position is required to be on the associated surface 0584 /// @return The tracking volume (can be null) 0585 Result<const TrackingVolume*> resolveVolume( 0586 const GeometryContext& gctx, const Vector3& position, 0587 double tolerance = s_onSurfaceTolerance) const override { 0588 auto res = m_surface->globalToLocal(gctx, position, tolerance); 0589 if (!res.ok()) { 0590 return res.error(); 0591 } 0592 0593 const Vector2& local = *res; 0594 return resolveVolume(gctx, local, tolerance); 0595 } 0596 0597 /// Lookup the tracking volume at a position on the surface 0598 /// @param position The local position 0599 /// @note The position is required to be on the associated surface 0600 /// @return The tracking volume (can be null) 0601 Result<const TrackingVolume*> resolveVolume( 0602 const GeometryContext& /*gctx*/, const Vector2& position, 0603 double /*tolerance*/ = s_onSurfaceTolerance) const override { 0604 throw_assert(surface().insideBounds(position, BoundaryTolerance::None()), 0605 "Checking volume outside of bounds"); 0606 return m_grid.atPosition(m_projection(position)); 0607 } 0608 0609 private: 0610 /// Helper function that's assigned to project from the 2D local position to a 0611 /// possible 1D grid. 0612 template <class surface_t, AxisDirection direction> 0613 static Vector<DIM> projection(const Vector2& position) { 0614 using enum AxisDirection; 0615 if constexpr (DIM == 2) { 0616 return position; 0617 } else { 0618 if constexpr (std::is_same_v<surface_t, CylinderSurface>) { 0619 static_assert(direction == AxisRPhi || direction == AxisZ, 0620 "Invalid binning direction"); 0621 0622 if constexpr (direction == AxisRPhi) { 0623 return Vector<1>{position[0]}; 0624 } else if constexpr (direction == AxisZ) { 0625 return Vector<1>{position[1]}; 0626 } 0627 } else if constexpr (std::is_same_v<surface_t, DiscSurface>) { 0628 static_assert(direction == AxisR || direction == AxisPhi, 0629 "Invalid binning direction"); 0630 0631 if constexpr (direction == AxisR) { 0632 return Vector<1>{position[0]}; 0633 } else if constexpr (direction == AxisPhi) { 0634 return Vector<1>{position[1]}; 0635 } 0636 } else if constexpr (std::is_same_v<surface_t, PlaneSurface>) { 0637 static_assert(direction == AxisX || direction == AxisY, 0638 "Invalid binning direction"); 0639 0640 if constexpr (direction == AxisX) { 0641 return Vector<1>{position[0]}; 0642 } else if constexpr (direction == AxisY) { 0643 return Vector<1>{position[1]}; 0644 } 0645 } 0646 } 0647 } 0648 0649 GridType m_grid; 0650 0651 /// Stores a function pointer that can project from 2D to 1D if needed 0652 Vector<DIM> (*m_projection)(const Vector2& position); 0653 }; 0654 0655 } // namespace Acts
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|