Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:23:59

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 // Project include(s)
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 #include "detray/definitions/geometry.hpp"
0014 #include "detray/definitions/indexing.hpp"
0015 #include "detray/utils/bit_encoder.hpp"
0016 
0017 // System include(s)
0018 #include <cstdint>
0019 #include <ostream>
0020 #include <utility>
0021 
0022 namespace detray::geometry {
0023 
0024 /// @brief Unique identifier for geometry objects, based on the ACTS
0025 /// GeometryIdentifier
0026 ///
0027 /// Encodes the volume index, the type of surface (portal, sensitive, passive
0028 /// etc), an index to identify a surface in a geometry accelerator structure,
0029 /// as well as two extra bytes that can be used to tag surfaces arbitrarily.
0030 ///
0031 /// @note the detray identifier is not compatible with the ACTS
0032 /// GeometryIdentifier!
0033 ///
0034 /// @see
0035 /// https://github.com/acts-project/acts/blob/main/Core/include/Acts/Geometry/GeometryIdentifier.hpp
0036 class identifier {
0037  public:
0038   using value_t = std::uint_least64_t;
0039   using encoder = detail::bit_encoder<value_t>;
0040 
0041   /// Construct from an already encoded value.
0042   DETRAY_HOST_DEVICE
0043   constexpr explicit identifier(value_t encoded) : m_value(encoded) {}
0044 
0045   /// Construct default identifier with all values set to 1.
0046   constexpr identifier() = default;
0047 
0048   /// @returns the encoded value.
0049   DETRAY_HOST_DEVICE
0050   constexpr value_t value() const noexcept { return m_value; }
0051 
0052   /// @returns the volume index.
0053   DETRAY_HOST_DEVICE
0054   constexpr dindex volume() const {
0055     return static_cast<dindex>(
0056         encoder::template get_bits<k_volume_mask>(m_value));
0057   }
0058 
0059   /// @returns the surface id.
0060   DETRAY_HOST_DEVICE
0061   constexpr surface_id id() const {
0062     return static_cast<surface_id>(
0063         encoder::template get_bits<k_id_mask>(m_value));
0064   }
0065 
0066   /// @returns the surface index.
0067   DETRAY_HOST_DEVICE
0068   constexpr dindex index() const {
0069     return static_cast<dindex>(
0070         encoder::template get_bits<k_index_mask>(m_value));
0071   }
0072 
0073   /// @returns the transform index
0074   DETRAY_HOST_DEVICE
0075   constexpr dindex transform() const {
0076     return static_cast<dindex>(
0077         encoder::template get_bits<k_transform_mask>(m_value));
0078   }
0079 
0080   /// @returns the extra identifier
0081   DETRAY_HOST_DEVICE
0082   constexpr dindex extra() const {
0083     return static_cast<dindex>(
0084         encoder::template get_bits<k_extra_mask>(m_value));
0085   }
0086 
0087   /// Set the volume index.
0088   DETRAY_HOST_DEVICE
0089   constexpr identifier& set_volume(value_t volume) {
0090     encoder::template set_bits<k_volume_mask>(m_value, volume);
0091     return *this;
0092   }
0093 
0094   /// Set the surface id.
0095   DETRAY_HOST_DEVICE
0096   constexpr identifier& set_id(surface_id id) {
0097     encoder::template set_bits<k_id_mask>(
0098         m_value, static_cast<value_t>(
0099                      static_cast<std::underlying_type_t<surface_id>>(id)));
0100     return *this;
0101   }
0102 
0103   /// Set the surface index.
0104   DETRAY_HOST_DEVICE
0105   constexpr identifier& set_index(value_t index) {
0106     encoder::template set_bits<k_index_mask>(m_value, index);
0107     return *this;
0108   }
0109 
0110   /// Set the transform index.
0111   DETRAY_HOST_DEVICE
0112   constexpr identifier& set_transform(value_t index) {
0113     encoder::template set_bits<k_transform_mask>(m_value, index);
0114     return *this;
0115   }
0116 
0117   /// Set the extra identifier.
0118   DETRAY_HOST_DEVICE
0119   constexpr identifier& set_extra(value_t extra) {
0120     encoder::template set_bits<k_extra_mask>(m_value, extra);
0121     return *this;
0122   }
0123 
0124   /// Check whether the identifier is valid to use.
0125   /// @note The extra bits are allowed to be invalid and will not be checked
0126   DETRAY_HOST_DEVICE
0127   constexpr bool is_invalid() const noexcept {
0128     return encoder::template is_invalid<k_volume_mask, k_id_mask, k_index_mask,
0129                                         k_transform_mask>(m_value);
0130   }
0131 
0132   bool operator==(const identifier& rhs) const = default;
0133 
0134   /// Comparison operators
0135   DETRAY_HOST_DEVICE
0136   friend constexpr auto operator<=>(const identifier lhs,
0137                                     const identifier rhs) noexcept {
0138     const auto l{lhs.index()};
0139     const auto r{rhs.index()};
0140     if (l < r || (l == r && l < r)) {
0141       return std::strong_ordering::less;
0142     }
0143     if (l > r || (l == r && l > r)) {
0144       return std::strong_ordering::greater;
0145     }
0146     return std::strong_ordering::equivalent;
0147   }
0148 
0149  private:
0150   // clang-format off
0151     static constexpr value_t k_volume_mask    = 0xfff0000000000000; // (2^12)-1 = 4095 volumes
0152     static constexpr value_t k_id_mask        = 0x000f000000000000; // (2^4)-1 = 15 surface categories
0153     static constexpr value_t k_index_mask     = 0x0000fffff8000000; // (2^21)-1 = 2097151 surfaces
0154     static constexpr value_t k_transform_mask = 0x0000000007ffffc0; // (2^21)-1 = 2097151 transforms
0155     static constexpr value_t k_extra_mask     = 0x000000000000003f; // (2^6)-1 = 63 extra tags
0156   // clang-format on
0157 
0158   // The masks together must cover all bits
0159   static_assert(k_volume_mask + k_id_mask + k_index_mask + k_transform_mask +
0160                     k_extra_mask ==
0161                 ~static_cast<value_t>(0));
0162 
0163   /// The encoded value. Default: All bits set to 1 (invalid)
0164   value_t m_value{~static_cast<value_t>(0)};
0165 
0166   /// Print the surface identifier
0167   DETRAY_HOST
0168   friend std::ostream& operator<<(std::ostream& os, const identifier c) {
0169     if (c.is_invalid()) {
0170       os << "INVALID: ";
0171     }
0172 
0173     os << "vol = " << c.volume();
0174     os << " | id = " << c.id() << "(" << static_cast<int>(c.id()) << ")";
0175     os << " | index = " << c.index();
0176     os << " | trf = " << c.transform();
0177     os << " | extra = " << c.extra();
0178 
0179     return os;
0180   }
0181 };
0182 
0183 }  // namespace detray::geometry
0184 
0185 namespace std {
0186 
0187 // specialize std::hash so identifier can be used e.g. in an unordered_map
0188 template <>
0189 struct hash<detray::geometry::identifier> {
0190   auto operator()(detray::geometry::identifier gid) const noexcept {
0191     return std::hash<detray::geometry::identifier::value_t>()(gid.value());
0192   }
0193 };
0194 
0195 }  // namespace std