Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:52

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 <cstdint>
0012 #include <functional>
0013 #include <iosfwd>
0014 
0015 namespace Acts {
0016 
0017 class Surface;
0018 
0019 /// Identifier for geometry nodes within the geometry hierarchy.
0020 ///
0021 /// An identifier can be split into the following components. They define
0022 /// a hierarchy of objects starting from the high-level volumes:
0023 ///
0024 /// - Volume
0025 /// - Boundary surfaces (for a volume)
0026 /// - Layers (confined within a volume)
0027 /// - Approach surfaces (for a layer)
0028 /// - Sensitive surfaces (confined to a layer, also called modules)
0029 ///
0030 class GeometryIdentifier {
0031  public:
0032   using Value = std::uint64_t;
0033 
0034   /// Construct from an already encoded value.
0035   constexpr GeometryIdentifier(Value encoded) : m_value(encoded) {}
0036   /// Construct default GeometryIdentifier with all values set to zero.
0037   GeometryIdentifier() = default;
0038   GeometryIdentifier(GeometryIdentifier&&) = default;
0039   GeometryIdentifier(const GeometryIdentifier&) = default;
0040   ~GeometryIdentifier() = default;
0041   GeometryIdentifier& operator=(GeometryIdentifier&&) = default;
0042   GeometryIdentifier& operator=(const GeometryIdentifier&) = default;
0043 
0044   /// Return the encoded value.
0045   constexpr Value value() const { return m_value; }
0046 
0047   /// Return the volume identifier.
0048   constexpr Value volume() const { return getBits(kVolumeMask); }
0049   /// Return the boundary identifier.
0050   constexpr Value boundary() const { return getBits(kBoundaryMask); }
0051   /// Return the layer identifier.
0052   constexpr Value layer() const { return getBits(kLayerMask); }
0053   /// Return the approach identifier.
0054   constexpr Value approach() const { return getBits(kApproachMask); }
0055   /// Return the approach identifier.
0056   constexpr Value passive() const { return getBits(kApproachMask); }
0057   /// Return the sensitive identifier.
0058   constexpr Value sensitive() const { return getBits(kSensitiveMask); }
0059   /// Return the extra identifier
0060   /// Usage can be experiment-specific, like tagging which kind of detector a
0061   /// surface object corresponds to, or which subsystem it belongs to
0062   constexpr Value extra() const { return getBits(kExtraMask); }
0063 
0064   /// Set the volume identifier.
0065   constexpr GeometryIdentifier& setVolume(Value volume) {
0066     return setBits(kVolumeMask, volume);
0067   }
0068   /// Set the boundary identifier.
0069   constexpr GeometryIdentifier& setBoundary(Value boundary) {
0070     return setBits(kBoundaryMask, boundary);
0071   }
0072   /// Set the layer identifier.
0073   constexpr GeometryIdentifier& setLayer(Value layer) {
0074     return setBits(kLayerMask, layer);
0075   }
0076   /// Set the approach identifier.
0077   constexpr GeometryIdentifier& setApproach(Value approach) {
0078     return setBits(kApproachMask, approach);
0079   }
0080   /// Set the approach identifier - shared with Passive
0081   constexpr GeometryIdentifier& setPassive(Value approach) {
0082     return setBits(kApproachMask, approach);
0083   }
0084   /// Set the sensitive identifier.
0085   constexpr GeometryIdentifier& setSensitive(Value sensitive) {
0086     return setBits(kSensitiveMask, sensitive);
0087   }
0088   /// Set the extra identifier
0089   constexpr GeometryIdentifier& setExtra(Value extra) {
0090     return setBits(kExtraMask, extra);
0091   }
0092 
0093  private:
0094   // clang-format off
0095   /// (2^8)-1 = 255 volumes
0096   static constexpr Value kVolumeMask    = 0xff00000000000000;
0097   /// (2^8)-1 = 255 boundaries
0098   static constexpr Value kBoundaryMask  = 0x00ff000000000000;
0099   /// (2^12)-1 = 4095 layers
0100   static constexpr Value kLayerMask     = 0x0000fff000000000;
0101   /// (2^8)-1 = 255 approach surfaces
0102   static constexpr Value kApproachMask  = 0x0000000ff0000000;
0103   static constexpr Value kPassiveMask   = kApproachMask;
0104   /// (2^20)-1 = 1048575 sensitive surfaces
0105   static constexpr Value kSensitiveMask = 0x000000000fffff00;
0106   /// (2^8)-1 = 255 extra values
0107   static constexpr Value kExtraMask     = 0x00000000000000ff;
0108   // clang-format on
0109 
0110   Value m_value = 0;
0111 
0112   /// Extract the bit shift necessary to access the masked values.
0113   static constexpr int extractShift(Value mask) {
0114     // use compiler builtin to extract the number of trailing bits from the
0115     // mask. the builtin should be available on all supported compilers.
0116     // need unsigned long long version (...ll) to ensure std::uint64_t
0117     // compatibility.
0118     // WARNING undefined behaviour for mask == 0 which we should not have.
0119     return __builtin_ctzll(mask);
0120   }
0121   /// Extract the masked bits from the encoded value.
0122   constexpr Value getBits(Value mask) const {
0123     return (m_value & mask) >> extractShift(mask);
0124   }
0125   /// Set the masked bits to id in the encoded value.
0126   constexpr GeometryIdentifier& setBits(Value mask, Value id) {
0127     m_value = (m_value & ~mask) | ((id << extractShift(mask)) & mask);
0128     // return *this here that we need to write fewer lines in the setXXX methods
0129     return *this;
0130   }
0131 
0132   friend constexpr bool operator==(GeometryIdentifier lhs,
0133                                    GeometryIdentifier rhs) {
0134     return lhs.m_value == rhs.m_value;
0135   }
0136 
0137   friend constexpr bool operator<(GeometryIdentifier lhs,
0138                                   GeometryIdentifier rhs) {
0139     return lhs.m_value < rhs.m_value;
0140   }
0141 };
0142 
0143 std::ostream& operator<<(std::ostream& os, GeometryIdentifier id);
0144 
0145 /// Base class for hooks that can be used to modify the Geometry Identifier
0146 /// during construction. Most common use case is setting the extra bit fields.
0147 struct GeometryIdentifierHook {
0148   virtual ~GeometryIdentifierHook() = default;
0149   virtual Acts::GeometryIdentifier decorateIdentifier(
0150       Acts::GeometryIdentifier identifier, const Acts::Surface& surface) const;
0151 };
0152 
0153 }  // namespace Acts
0154 
0155 // specialize std::hash so GeometryIdentifier can be used e.g. in an
0156 // unordered_map
0157 namespace std {
0158 template <>
0159 struct hash<Acts::GeometryIdentifier> {
0160   auto operator()(Acts::GeometryIdentifier gid) const noexcept {
0161     return std::hash<Acts::GeometryIdentifier::Value>()(gid.value());
0162   }
0163 };
0164 }  // namespace std