Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-03 07:48: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 "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Surfaces/RegularSurface.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/AxisDefinitions.hpp"
0016 #include "Acts/Utilities/Diagnostics.hpp"
0017 #include "Acts/Utilities/IAxis.hpp"
0018 
0019 #include <iostream>
0020 #include <vector>
0021 
0022 namespace Acts {
0023 
0024 using SurfaceVector = std::vector<const Surface*>;
0025 
0026 /// @brief Provides Surface binning in 2 dimensions
0027 ///
0028 /// Uses @c Grid under the hood to implement the storage and lookup
0029 /// Contains a lookup struct which talks to the @c Grid
0030 /// and performs utility actions. This struct needs to be initialised
0031 /// externally and passed to @c SurfaceArray on construction.
0032 class SurfaceArray {
0033  public:
0034   /// Base interface for all surface lookups.
0035   struct ISurfaceGridLookup {
0036     virtual ~ISurfaceGridLookup() = default;
0037 
0038     /// Fill provided surfaces into the contained @c Grid.
0039     /// @param gctx The current geometry context object, e.g. alignment
0040     /// @param surfaces Input surface pointers
0041     virtual void fill(const GeometryContext& gctx,
0042                       std::span<const Surface* const> surfaces) = 0;
0043 
0044     /// Performs lookup at @c pos and returns bin content as const reference
0045     /// @param position Lookup position
0046     /// @param direction Lookup direction
0047     /// @return A vector of surfaces at given bin
0048     [[deprecated("Use lookup with GeometryContext instead")]]
0049     virtual const std::vector<const Surface*>& lookup(
0050         const Vector3& position, const Vector3& direction) const = 0;
0051 
0052     /// Performs lookup at @c pos and returns bin content as const reference
0053     /// @param gctx The current geometry context object, e.g. alignment
0054     /// @param position Lookup position
0055     /// @param direction Lookup direction
0056     /// @return A span of surface pointers
0057     virtual std::span<const Surface* const> lookup(
0058         const GeometryContext& gctx, const Vector3& position,
0059         const Vector3& direction) const = 0;
0060 
0061     /// Performs lookup at global bin and returns bin content as reference
0062     /// @param bin Global lookup bin
0063     /// @return A vector of surfaces at given bin
0064     [[deprecated(
0065         "Mutable access will be removed without replacement in the future")]]
0066     virtual std::vector<const Surface*>& lookup(std::size_t bin) = 0;
0067 
0068     /// Performs lookup at global bin and returns bin content as const reference
0069     /// @param bin Global lookup bin
0070     /// @return A vector of surfaces at given bin
0071     [[deprecated("Use at(gridIndices, neighborDistance) instead")]]
0072     virtual const std::vector<const Surface*>& lookup(
0073         std::size_t bin) const = 0;
0074 
0075     /// Performs a lookup at @c pos, but returns neighbors as well
0076     /// @param position Lookup position
0077     /// @param direction Lookup direction
0078     /// @return A vector of surfaces at given bin. Copy of all bins selected
0079     [[deprecated("Use neighbors with GeometryContext instead")]]
0080     virtual const std::vector<const Surface*>& neighbors(
0081         const Vector3& position, const Vector3& direction) const = 0;
0082 
0083     /// Performs a lookup at @c pos, but returns neighbors as well
0084     /// @param gctx The current geometry context object, e.g. alignment
0085     /// @param position Lookup position
0086     /// @param direction Lookup direction
0087     /// @return A span of surface pointers
0088     virtual std::span<const Surface* const> neighbors(
0089         const GeometryContext& gctx, const Vector3& position,
0090         const Vector3& direction) const = 0;
0091 
0092     /// Returns the total size of the grid (including under/overflow bins)
0093     /// @return Size of the grid data structure
0094     virtual std::size_t size() const = 0;
0095 
0096     /// Gets the center position of bin @c bin in global coordinates
0097     /// @param bin the global bin index
0098     /// @return The bin center
0099     virtual Vector3 getBinCenter(std::size_t bin) const = 0;
0100 
0101     /// Returns copies of the axes used in the grid as @c AnyAxis
0102     /// @return The axes
0103     /// @note This returns copies. Use for introspection and querying.
0104     virtual std::vector<const IAxis*> getAxes() const = 0;
0105 
0106     /// Get the representative surface used for this lookup
0107     /// @return Surface pointer
0108     virtual const Surface* surfaceRepresentation() const = 0;
0109 
0110     /// Checks if global bin is valid
0111     /// @param bin the global bin index
0112     /// @return bool if the bin is valid
0113     /// @note Valid means that the index points to a bin which is not a under
0114     ///       or overflow bin or out of range in any axis.
0115     virtual bool isValidBin(std::size_t bin) const = 0;
0116 
0117     /// The binning values described by this surface grid lookup. They are in
0118     /// order of the axes (optional) and empty for eingle lookups
0119     /// @return Vector of axis directions for binning
0120     virtual std::vector<AxisDirection> binningValues() const { return {}; }
0121 
0122     /// Get the number of local bins in each dimension. This is used to
0123     /// determine the size of the grid for neighbor lookups.
0124     /// @return Array of number of local bins in each dimension
0125     virtual std::array<std::size_t, 2> numLocalBins() const = 0;
0126 
0127     /// Get the maximum neighbor distance that is supported by this lookup. This
0128     /// is used to determine how many neighbors to include in neighbor lookups.
0129     /// @return Maximum neighbor distance
0130     virtual std::uint8_t maxNeighborDistance() const = 0;
0131 
0132     /// Get all surfaces in bin given by local grid indices and neighbor
0133     /// distance.
0134     /// @param gridIndices the local grid indices
0135     /// @param neighborDistance the neighbor distance to include in the lookup
0136     /// @return span of surface pointers of the bin at that position and its neighbors
0137     virtual std::span<const Surface* const> at(
0138         std::array<std::size_t, 2> gridIndices,
0139         std::uint8_t neighborDistance) const = 0;
0140   };
0141 
0142  private:
0143   /// Factory method to create a surface grid lookup for a given representative
0144   /// surface, tolerance, and axes. This will internally create the appropriate
0145   /// lookup class based on the axes and concrete @ref Grid.
0146   /// @param representative The surface which is used as representative
0147   /// @param tolerance The tolerance used for intersection checks
0148   /// @param axes The axes used for the grid
0149   /// @param maxNeighborDistance Maximum next neighbor distance to be included in neighbor lookups
0150   /// @return A unique pointer to the surface grid lookup
0151   static std::unique_ptr<ISurfaceGridLookup> makeSurfaceGridLookup(
0152       std::shared_ptr<RegularSurface> representative, double tolerance,
0153       std::tuple<const IAxis&, const IAxis&> axes,
0154       std::uint8_t maxNeighborDistance = 1);
0155 
0156   // This is temporary until Gen1 is removed
0157   friend class SurfaceArrayCreator;
0158 
0159  public:
0160   /// Lookup helper which encapsulates a @c Grid
0161   /// @tparam Axis1 The first axis
0162   /// @tparam Axis2 The second axis
0163   /// @deprecated This is deprecated in favor of direct @ref SurfaceArray constructors.
0164   template <class Axis1, class Axis2>
0165   struct [[deprecated("Use makeSurfaceGridLookup instead")]] SurfaceGridLookup
0166       : ISurfaceGridLookup {
0167     /// Construct a surface grid lookup
0168     /// @param representative The surface which is used as representative
0169     /// @param tolerance The tolerance used for intersection checks
0170     /// @param axes The axes used for the grid
0171     /// @param bValues Optional vector of axis directions for binning
0172     /// @param maxNeighborDistance Maximum next neighbor distance to be included in neighbor lookups
0173     SurfaceGridLookup(std::shared_ptr<RegularSurface> representative,
0174                       double tolerance, std::tuple<Axis1, Axis2> axes,
0175                       const std::vector<AxisDirection>& bValues = {},
0176                       std::uint8_t maxNeighborDistance = 1)
0177         : m_impl(makeSurfaceGridLookup(std::move(representative), tolerance,
0178                                        std::move(axes), maxNeighborDistance)) {
0179       static_cast<void>(bValues);
0180     }
0181 
0182     /// Fill provided surfaces into the contained @c Grid.
0183     /// @param gctx The current geometry context object, e.g. alignment
0184     /// @param surfaces Input surface pointers
0185     void fill(const GeometryContext& gctx,
0186               std::span<const Surface* const> surfaces) override {
0187       m_impl->fill(gctx, surfaces);
0188     }
0189 
0190     /// Performs lookup at @c pos and returns bin content as const reference
0191     /// @param position Lookup position
0192     /// @param direction Lookup direction
0193     /// @return A vector of surfaces at given bin
0194     const std::vector<const Surface*>& lookup(
0195         const Vector3& position, const Vector3& direction) const override {
0196       ACTS_PUSH_IGNORE_DEPRECATED()
0197       return m_impl->lookup(position, direction);
0198       ACTS_POP_IGNORE_DEPRECATED()
0199     }
0200 
0201     /// Performs lookup at @c pos and returns bin content as const reference
0202     /// @param gctx The current geometry context object, e.g. alignment
0203     /// @param position Lookup position
0204     /// @param direction Lookup direction
0205     /// @return A span of surface pointers
0206     std::span<const Surface* const> lookup(
0207         const GeometryContext& gctx, const Vector3& position,
0208         const Vector3& direction) const override {
0209       return m_impl->lookup(gctx, position, direction);
0210     }
0211 
0212     /// Performs lookup at global bin and returns bin content as reference
0213     /// @param bin Global lookup bin
0214     /// @return A vector of surfaces at given bin
0215     std::vector<const Surface*>& lookup(std::size_t bin) override {
0216       ACTS_PUSH_IGNORE_DEPRECATED()
0217       return m_impl->lookup(bin);
0218       ACTS_POP_IGNORE_DEPRECATED()
0219     }
0220 
0221     /// Performs lookup at global bin and returns bin content as const reference
0222     /// @param bin Global lookup bin
0223     /// @return A vector of surfaces at given bin
0224     const std::vector<const Surface*>& lookup(std::size_t bin) const override {
0225       ACTS_PUSH_IGNORE_DEPRECATED()
0226       return m_impl->lookup(bin);
0227       ACTS_POP_IGNORE_DEPRECATED()
0228     }
0229 
0230     /// Performs a lookup at @c pos, but returns neighbors as well
0231     /// @param position Lookup position
0232     /// @param direction Lookup direction
0233     /// @return A vector of surfaces at given bin. Copy of all bins selected
0234     const std::vector<const Surface*>& neighbors(
0235         const Vector3& position, const Vector3& direction) const override {
0236       ACTS_PUSH_IGNORE_DEPRECATED()
0237       return m_impl->neighbors(position, direction);
0238       ACTS_POP_IGNORE_DEPRECATED()
0239     }
0240 
0241     /// Performs a lookup at @c pos, but returns neighbors as well
0242     /// @param gctx The current geometry context object, e.g. alignment
0243     /// @param position Lookup position
0244     /// @param direction Lookup direction
0245     /// @return A span of surface pointers
0246     std::span<const Surface* const> neighbors(
0247         const GeometryContext& gctx, const Vector3& position,
0248         const Vector3& direction) const override {
0249       return m_impl->neighbors(gctx, position, direction);
0250     }
0251 
0252     /// Returns the total size of the grid (including under/overflow bins)
0253     /// @return Size of the grid data structure
0254     std::size_t size() const override { return m_impl->size(); }
0255 
0256     /// Gets the center position of bin @c bin in global coordinates
0257     /// @param bin the global bin index
0258     /// @return The bin center
0259     Vector3 getBinCenter(std::size_t bin) const override {
0260       return m_impl->getBinCenter(bin);
0261     }
0262 
0263     /// Returns copies of the axes used in the grid as @c AnyAxis
0264     /// @return The axes
0265     /// @note This returns copies. Use for introspection and querying.
0266     std::vector<const IAxis*> getAxes() const override {
0267       return m_impl->getAxes();
0268     }
0269 
0270     /// Get the representative surface used for this lookup
0271     /// @return Surface pointer
0272     const Surface* surfaceRepresentation() const override {
0273       return m_impl->surfaceRepresentation();
0274     }
0275 
0276     /// Checks if global bin is valid
0277     /// @param bin the global bin index
0278     /// @return bool if the bin is valid
0279     /// @note Valid means that the index points to a bin which is not a under
0280     ///       or overflow bin or out of range in any axis.
0281     bool isValidBin(std::size_t bin) const override {
0282       return m_impl->isValidBin(bin);
0283     }
0284 
0285     /// The binning values described by this surface grid lookup. They are in
0286     /// order of the axes (optional) and empty for eingle lookups
0287     /// @return Vector of axis directions for binning
0288     std::vector<AxisDirection> binningValues() const override {
0289       return m_impl->binningValues();
0290     }
0291 
0292     std::array<std::size_t, 2> numLocalBins() const override {
0293       return m_impl->numLocalBins();
0294     }
0295 
0296     std::uint8_t maxNeighborDistance() const override {
0297       return m_impl->maxNeighborDistance();
0298     }
0299 
0300     std::span<const Surface* const> at(
0301         std::array<std::size_t, 2> gridIndices,
0302         std::uint8_t neighborDistance) const override {
0303       return m_impl->at(gridIndices, neighborDistance);
0304     }
0305 
0306    private:
0307     std::unique_ptr<ISurfaceGridLookup> m_impl;
0308   };
0309 
0310   /// Lookup implementation which wraps one element and always returns this
0311   /// element when lookup is called
0312   /// @deprecated Construct the @ref SurfaceArray directly with a single surface
0313   struct [[deprecated(
0314       "Construct the SurfaceArray directly with a single "
0315       "surface")]] SingleElementLookup : ISurfaceGridLookup {
0316     /// Default constructor.
0317     /// @param element the one and only element.
0318     explicit SingleElementLookup(const Surface* element)
0319         : m_element({element}) {}
0320 
0321     /// Default constructor.
0322     /// @param elements the surfaces that are provided through a single lookup
0323     explicit SingleElementLookup(const std::vector<const Surface*>& elements)
0324         : m_element(elements) {}
0325 
0326     /// Lookup, always returns @c element
0327     /// @return reference to vector containing only @c element
0328     const std::vector<const Surface*>& lookup(
0329         const Vector3& /*position*/,
0330         const Vector3& /*direction*/) const override {
0331       return m_element;
0332     }
0333 
0334     /// Lookup, always returns @c element
0335     /// @return span of surface pointers containing only @c element
0336     std::span<const Surface* const> lookup(
0337         const GeometryContext& /*gctx*/, const Vector3& /*position*/,
0338         const Vector3& /*direction*/) const override {
0339       return m_element;
0340     }
0341 
0342     /// Lookup, always returns @c element
0343     /// @return reference to vector containing only @c element
0344     std::vector<const Surface*>& lookup(std::size_t /*bin*/) override {
0345       return m_element;
0346     }
0347 
0348     /// Lookup, always returns @c element
0349     /// @return reference to vector containing only @c element
0350     const std::vector<const Surface*>& lookup(
0351         std::size_t /*bin*/) const override {
0352       return m_element;
0353     }
0354 
0355     /// Lookup, always returns @c element
0356     /// @return reference to vector containing only @c element
0357     const std::vector<const Surface*>& neighbors(
0358         const Vector3& /*position*/,
0359         const Vector3& /*direction*/) const override {
0360       return m_element;
0361     }
0362 
0363     /// Lookup, always returns @c element
0364     /// @return span of surface pointers containing only @c element
0365     std::span<const Surface* const> neighbors(
0366         const GeometryContext& /*gctx*/, const Vector3& /*position*/,
0367         const Vector3& /*direction*/) const override {
0368       return m_element;
0369     }
0370 
0371     /// Returns the total size of the grid (including under/overflow bins)
0372     /// @return 1
0373     std::size_t size() const override { return 1; }
0374 
0375     /// Gets the bin center, but always returns (0, 0, 0)
0376     /// @return (0, 0, 0)
0377     Vector3 getBinCenter(std::size_t /*bin*/) const override {
0378       return Vector3(0, 0, 0);
0379     }
0380 
0381     /// Returns an empty vector of @c AnyAxis
0382     /// @return empty vector
0383     std::vector<const IAxis*> getAxes() const override { return {}; }
0384 
0385     const Surface* surfaceRepresentation() const override { return nullptr; }
0386 
0387     /// Comply with concept and provide fill method
0388     /// @note Does nothing
0389     void fill(const GeometryContext& /*gctx*/,
0390               std::span<const Surface* const> /*surfaces*/) override {}
0391 
0392     /// Returns if the bin is valid (it is)
0393     /// @return always true
0394     bool isValidBin(std::size_t /*bin*/) const override { return true; }
0395 
0396     std::array<std::size_t, 2> numLocalBins() const override { return {1, 1}; }
0397 
0398     std::uint8_t maxNeighborDistance() const override { return 0; }
0399 
0400     std::span<const Surface* const> at(
0401         std::array<std::size_t, 2> gridIndices,
0402         std::uint8_t neighborDistance) const override {
0403       if (gridIndices != std::array<std::size_t, 2>{0, 0} ||
0404           neighborDistance != 0) {
0405         throw std::out_of_range(
0406             "SingleElementLookupImpl only contains one bin with zero neighbor "
0407             "distance");
0408       }
0409       return m_element;
0410     }
0411 
0412    private:
0413     std::vector<const Surface*> m_element;
0414   };
0415 
0416   /// Default constructor which takes a @c SurfaceLookup and a vector of surfaces
0417   /// @param gridLookup The grid storage. @c SurfaceArray does not fill it on its own
0418   /// @param surfaces The input vector of surfaces. This is only for bookkeeping, so we can ask
0419   /// @param transform Optional additional transform for this SurfaceArray
0420   [[deprecated("Use the constructor with axes instead")]]
0421   SurfaceArray(std::unique_ptr<ISurfaceGridLookup> gridLookup,
0422                std::vector<std::shared_ptr<const Surface>> surfaces,
0423                const Transform3& transform = Transform3::Identity());
0424 
0425   /// Constructor with a single surface
0426   /// @param srf The one and only surface
0427   explicit SurfaceArray(std::shared_ptr<const Surface> srf);
0428 
0429   /// Constructor to create a surface grid lookup for a given representative
0430   /// surface, tolerance, and axes.
0431   /// @param gctx The current geometry context object, e.g. alignment
0432   /// @param surfaces The input vector of surfaces that will be accessible
0433   ///                 through this @ref SurfaceArray.
0434   /// @param representative The surface which is used as representative
0435   /// @param tolerance The tolerance used for intersection checks
0436   /// @param axes The axes used for the grid
0437   SurfaceArray(const GeometryContext& gctx,
0438                std::vector<std::shared_ptr<const Surface>> surfaces,
0439                std::shared_ptr<RegularSurface> representative, double tolerance,
0440                std::tuple<const IAxis&, const IAxis&> axes);
0441 
0442   /// Get all surfaces in bin given by position @p pos.
0443   /// @param position the lookup position
0444   /// @param direction the lookup direction
0445   /// @return const reference to surface vector contained in bin at that position
0446   [[deprecated("Use at with GeometryContext instead")]]
0447   const std::vector<const Surface*>& at(const Vector3& position,
0448                                         const Vector3& direction) const {
0449     ACTS_PUSH_IGNORE_DEPRECATED()
0450     return m_gridLookup->lookup(position, direction);
0451     ACTS_POP_IGNORE_DEPRECATED()
0452   }
0453 
0454   /// Get all surfaces in bin given by position @p pos.
0455   /// @param gctx The current geometry context object, e.g. alignment
0456   /// @param position the lookup position
0457   /// @param direction the lookup direction
0458   /// @return span of surface pointers of the bin at that position
0459   std::span<const Surface* const> at(const GeometryContext& gctx,
0460                                      const Vector3& position,
0461                                      const Vector3& direction) const {
0462     return m_gridLookup->lookup(gctx, position, direction);
0463   }
0464 
0465   /// Get all surfaces in bin given by global bin index @p bin.
0466   /// @param bin the global bin index
0467   /// @return mutable reference to surface vector contained in bin
0468   [[deprecated(
0469       "Mutable access will be removed without replacement in the future")]]
0470   std::vector<const Surface*>& at(std::size_t bin) {
0471     ACTS_PUSH_IGNORE_DEPRECATED()
0472     return m_gridLookup->lookup(bin);
0473     ACTS_POP_IGNORE_DEPRECATED()
0474   }
0475 
0476   /// Get all surfaces in bin given by global bin index.
0477   /// @param bin the global bin index
0478   /// @return const reference to surface vector contained in bin
0479   [[deprecated("Use at(gridIndices, neighborDistance) instead")]]
0480   const std::vector<const Surface*>& at(std::size_t bin) const {
0481     ACTS_PUSH_IGNORE_DEPRECATED()
0482     return m_gridLookup->lookup(bin);
0483     ACTS_POP_IGNORE_DEPRECATED()
0484   }
0485 
0486   /// Get all surfaces in bin at @p pos and its neighbors
0487   /// @param position The position to lookup
0488   /// @param direction The direction to lookup
0489   /// @return Merged surface vector of neighbors and nominal
0490   [[deprecated("Use neighbors with GeometryContext instead")]]
0491   const std::vector<const Surface*>& neighbors(const Vector3& position,
0492                                                const Vector3& direction) const {
0493     ACTS_PUSH_IGNORE_DEPRECATED()
0494     return m_gridLookup->neighbors(position, direction);
0495     ACTS_POP_IGNORE_DEPRECATED()
0496   }
0497 
0498   /// Get all surfaces in bin at @p pos and its neighbors
0499   /// @param gctx The current geometry context object, e.g. alignment
0500   /// @param position The position to lookup
0501   /// @param direction The direction to lookup
0502   /// @return span of surface pointers of neighbors and nominal
0503   std::span<const Surface* const> neighbors(const GeometryContext& gctx,
0504                                             const Vector3& position,
0505                                             const Vector3& direction) const {
0506     return m_gridLookup->neighbors(gctx, position, direction);
0507   }
0508 
0509   /// Get the size of the underlying grid structure including under/overflow
0510   /// bins
0511   /// @return the size
0512   std::size_t size() const { return m_gridLookup->size(); }
0513 
0514   /// Get the center of the bin identified by global bin index @p bin
0515   /// @param bin the global bin index
0516   /// @return Center position of the bin in global coordinates
0517   Vector3 getBinCenter(std::size_t bin) const {
0518     return m_gridLookup->getBinCenter(bin);
0519   }
0520 
0521   /// Get all surfaces attached to this @c SurfaceArray
0522   /// @return Reference to vector of all surfaces
0523   /// @note This does not reflect the actual state of the grid. It only
0524   ///       returns what was given in the constructor, without any checks
0525   ///       if that is actually what's in the grid.
0526   const std::vector<const Surface*>& surfaces() const {
0527     return m_surfacesRawPointers;
0528   }
0529 
0530   /// Get vector of axes spanning the grid as @c AnyAxis
0531   /// @return vector of @c AnyAxis
0532   /// @note The axes in the vector are copies. Only use for introspection and
0533   ///       querying.
0534   std::vector<const IAxis*> getAxes() const { return m_gridLookup->getAxes(); }
0535 
0536   /// Checks if global bin is valid
0537   /// @param bin the global bin index
0538   /// @return bool if the bin is valid
0539   /// @note Valid means that the index points to a bin which is not a under
0540   ///       or overflow bin or out of range in any axis.
0541   bool isValidBin(std::size_t bin) const {
0542     return m_gridLookup->isValidBin(bin);
0543   }
0544 
0545   /// Get the transform of this surface array.
0546   /// @return Reference to the transformation matrix
0547   /// @deprecated This is an implementation detail and will be removed soon
0548   [[deprecated("This is an implementation detail and will be removed soon")]]
0549   const Transform3& transform() const {
0550     return m_transform;
0551   }
0552 
0553   /// The binning values described by this surface grid lookup. They are in
0554   /// order of the axes
0555   /// @return Vector of axis directions for binning
0556   std::vector<AxisDirection> binningValues() const {
0557     return m_gridLookup->binningValues();
0558   }
0559 
0560   /// Get string representation of this @c SurfaceArray
0561   /// @param gctx The current geometry context object, e.g. alignment
0562   /// @param sl Output stream to write to
0563   /// @return the output stream given as @p sl
0564   std::ostream& toStream(const GeometryContext& gctx, std::ostream& sl) const;
0565 
0566   /// Return the lookup object
0567   /// @return Reference to the surface grid lookup interface
0568   [[deprecated(
0569       "Grid lookup is an implementation detail and will be removed soon")]]
0570   const ISurfaceGridLookup& gridLookup() const {
0571     return *m_gridLookup;
0572   }
0573 
0574   /// Get the representative surface used for this surface array
0575   /// @return Surface pointer
0576   const Surface* surfaceRepresentation() const {
0577     return m_gridLookup->surfaceRepresentation();
0578   }
0579 
0580   /// Get the number of local bins in each dimension. This is used to
0581   /// determine the size of the grid for neighbor lookups.
0582   /// @return Array of number of local bins in each dimension
0583   std::array<std::size_t, 2> numLocalBins() const {
0584     return m_gridLookup->numLocalBins();
0585   }
0586 
0587   /// Get the maximum neighbor distance that is supported by this lookup. This
0588   /// is used to determine how many neighbors to include in neighbor lookups.
0589   /// @return Maximum neighbor distance
0590   std::uint8_t maxNeighborDistance() const {
0591     return m_gridLookup->maxNeighborDistance();
0592   }
0593 
0594   /// Get all surfaces in bin given by local grid indices and neighbor
0595   /// distance.
0596   /// @param gridIndices the local grid indices
0597   /// @param neighborDistance the neighbor distance to include in the lookup
0598   /// @return span of surface pointers of the bin at that position and its neighbors
0599   std::span<const Surface* const> at(std::array<std::size_t, 2> gridIndices,
0600                                      std::uint8_t neighborDistance) const {
0601     return m_gridLookup->at(gridIndices, neighborDistance);
0602   }
0603 
0604  private:
0605   /// The actual grid lookup implementation
0606   std::unique_ptr<ISurfaceGridLookup> m_gridLookup;
0607   /// this vector makes sure we have shared ownership over the surfaces
0608   std::vector<std::shared_ptr<const Surface>> m_surfaces;
0609   /// this vector is returned, so that (expensive) copying of the shared_ptr
0610   /// vector does not happen by default
0611   std::vector<const Surface*> m_surfacesRawPointers;
0612   /// this is only used to keep info on transform applied by l2g and g2l
0613   Transform3 m_transform;
0614 };
0615 
0616 }  // namespace Acts