Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-29 07:47:30

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 <cstddef>
0012 #include <cstdint>
0013 #include <format>
0014 #include <span>
0015 #include <stdexcept>
0016 #include <string>
0017 #include <type_traits>
0018 #include <vector>
0019 
0020 namespace ActsPodioEdm::detail {
0021 
0022 /// Encoded index type for local measurement subspace coordinates.
0023 using SubspaceIndex = std::uint8_t;
0024 /// Largest allowed local subspace index value.
0025 constexpr std::uint8_t kMaxSubspaceIndex = 6u;
0026 /// Maximum number of coordinates in an encoded local subspace.
0027 constexpr std::size_t kMaxSubspaceSize = 6u;
0028 
0029 /// Encode a list of bound parameter indices into a 32-bit integer.
0030 ///
0031 /// This function bit-packs up to `kMaxSubspaceSize` parameter indices into a
0032 /// single 32-bit unsigned integer for storage in EDM4hep format.
0033 ///
0034 /// Bit layout:
0035 ///   - Bits 0-3:   Number of indices (size)
0036 ///   - Bits 4-7:   First index
0037 ///   - Bits 8-11:  Second index
0038 ///   - Bits 12-15: Third index
0039 ///   - (and so on, up to `kMaxSubspaceSize` indices total)
0040 ///
0041 /// @param indices Span of parameter indices to encode (max
0042 /// `kMaxSubspaceSize` elements)
0043 /// @return Packed 32-bit unsigned integer containing all indices
0044 inline std::int32_t encodeIndices(std::span<const std::uint8_t> indices) {
0045   if (indices.size() > kMaxSubspaceSize) {
0046     throw std::runtime_error(
0047         std::format("Number of indices exceeds maximum of {} for EDM4hep",
0048                     kMaxSubspaceSize));
0049   }
0050 
0051   std::int32_t result = 0;
0052   std::uint8_t shift = 0;
0053   result |= (indices.size() << 0);
0054   shift += 4;
0055 
0056   for (std::uint8_t index : indices) {
0057     if (index > kMaxSubspaceIndex) {
0058       throw std::runtime_error(std::format(
0059           "Index out of range: maximum allowed is {}", kMaxSubspaceIndex));
0060     }
0061     result |= (static_cast<std::int32_t>(index) << shift);
0062     shift += 4;
0063   }
0064   return result;
0065 }
0066 
0067 /// Decode a 32-bit integer back into a list of bound parameter indices.
0068 ///
0069 /// This function unpacks a bit-packed integer (created by encodeIndices) back
0070 /// into the original list of parameter indices. See encodeIndices for the bit
0071 /// layout specification.
0072 ///
0073 /// @param type Packed 32-bit unsigned integer containing encoded indices
0074 /// @return Vector of decoded parameter indices (each in
0075 /// `[0, kMaxSubspaceIndex]`)
0076 inline std::vector<SubspaceIndex> decodeIndices(std::int32_t type) {
0077   std::vector<SubspaceIndex> result;
0078   std::uint8_t size = type & 0xF;
0079   if (size > kMaxSubspaceSize) {
0080     throw std::runtime_error(
0081         std::format("Number of indices exceeds maximum of {} for EDM4hep",
0082                     kMaxSubspaceSize));
0083   }
0084   result.resize(size);
0085   for (std::size_t i = 0; i < result.size(); ++i) {
0086     result[i] = (type >> ((i + 1) * 4)) & 0xF;
0087     if (result[i] > kMaxSubspaceIndex) {
0088       throw std::runtime_error(std::format(
0089           "Index out of range: maximum allowed is {}", kMaxSubspaceIndex));
0090     }
0091   }
0092   return result;
0093 }
0094 
0095 /// Find the measurement-vector position of an enum-coded subspace coordinate.
0096 ///
0097 /// Searches @p indices for the given enum value (cast to SubspaceIndex) and
0098 /// returns its position. This position is the index into the measurement and
0099 /// covariance vectors stored in a TrackerHitLocal.
0100 ///
0101 /// @tparam E  Enum type whose underlying value encodes a subspace index
0102 /// @param indices  Active subspace indices (e.g. from decodeIndices())
0103 /// @param enumVal  The enum value to look up
0104 /// @return  Position of @p enumVal in @p indices
0105 /// @throws std::runtime_error if @p enumVal is not present in @p indices
0106 template <typename E>
0107   requires std::is_enum_v<E>
0108 inline std::size_t findSubspaceIndex(std::span<const SubspaceIndex> indices,
0109                                      E enumVal) {
0110   const auto target = static_cast<SubspaceIndex>(enumVal);
0111   for (std::size_t i = 0; i < indices.size(); ++i) {
0112     if (indices[i] == target) {
0113       return i;
0114     }
0115   }
0116   throw std::runtime_error(
0117       std::format("Enum value {} not found in subspace indices",
0118                   static_cast<int>(enumVal)));
0119 }
0120 
0121 }  // namespace ActsPodioEdm::detail