File indexing completed on 2025-12-11 09:40:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Geometry/GeometryHierarchyMap.hpp"
0012 #include "ActsPlugins/Json/ActsJson.hpp"
0013 #include "ActsPlugins/Json/GeometryIdentifierJsonConverter.hpp"
0014
0015 #include <stdexcept>
0016 #include <string>
0017 #include <type_traits>
0018
0019 namespace Acts {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 template <typename value_t,
0037 class decorator_t = void >
0038 class GeometryHierarchyMapJsonConverter {
0039 public:
0040 using Value = value_t;
0041 using Container = GeometryHierarchyMap<value_t>;
0042
0043
0044
0045
0046 explicit GeometryHierarchyMapJsonConverter(std::string valueIdentifier)
0047 : m_valueIdentifier(std::move(valueIdentifier)) {
0048 if (m_valueIdentifier.empty()) {
0049 throw std::invalid_argument("Value identifier must be non-empty");
0050 }
0051 }
0052
0053
0054
0055
0056
0057
0058
0059 nlohmann::json toJson(const Container& container,
0060 const decorator_t* decorator) const;
0061
0062
0063
0064
0065
0066
0067 Container fromJson(const nlohmann::json& encoded) const;
0068
0069 private:
0070 static constexpr const char* kHeaderKey = "acts-geometry-hierarchy-map";
0071 static constexpr const char* kEntriesKey = "entries";
0072
0073
0074 static constexpr int kFormatVersion = 0;
0075
0076 std::string m_valueIdentifier;
0077 };
0078
0079
0080
0081
0082
0083 template <typename T, class decorator_t>
0084 struct missing_specialization : std::false_type {};
0085
0086
0087 template <class T, class decorator_t>
0088 void decorateJson([[maybe_unused]] const decorator_t* decorator,
0089 [[maybe_unused]] const T& src,
0090 [[maybe_unused]] nlohmann::json& dest) {
0091
0092 static_assert(
0093 missing_specialization<T, decorator_t>::value,
0094 "Explicit specialization needed for each decorator_t and src T");
0095 }
0096 template <class T, class decorator_t>
0097 void decorateJson([[maybe_unused]] const decorator_t* decorator,
0098 [[maybe_unused]] const T* src,
0099 [[maybe_unused]] nlohmann::json& dest) {
0100
0101 static_assert(
0102 missing_specialization<T, decorator_t>::value,
0103 "Explicit specialization needed for each decorator_t and src T");
0104 }
0105
0106 template <typename value_t, class decorator_t>
0107 nlohmann::json GeometryHierarchyMapJsonConverter<value_t, decorator_t>::toJson(
0108 const Container& container,
0109 [[maybe_unused]] const decorator_t* decorator) const {
0110
0111 nlohmann::json encoded = nlohmann::json::object();
0112 encoded[kHeaderKey] = nlohmann::json::object();
0113 encoded[kHeaderKey]["format-version"] = kFormatVersion;
0114 encoded[kHeaderKey]["value-identifier"] = m_valueIdentifier;
0115
0116 nlohmann::json entries = nlohmann::json::array();
0117 for (std::size_t i = 0; i < container.size(); ++i) {
0118 auto entry =
0119 GeometryIdentifierJsonConverter::encodeIdentifier(container.idAt(i));
0120 auto value_json = nlohmann::json(container.valueAt(i));
0121 if constexpr (!std::is_same_v<decorator_t, void>) {
0122 decorateJson(decorator, container.valueAt(i), value_json);
0123 }
0124 entry["value"] = std::move(value_json);
0125 entries.push_back(std::move(entry));
0126 }
0127 encoded[kEntriesKey] = std::move(entries);
0128 return encoded;
0129 }
0130
0131 template <typename value_t, class decorator_t>
0132 auto GeometryHierarchyMapJsonConverter<value_t, decorator_t>::fromJson(
0133 const nlohmann::json& encoded) const -> Container {
0134
0135 auto header = encoded.find(kHeaderKey);
0136 if (header == encoded.end()) {
0137 throw std::invalid_argument(
0138 "Missing header entry in json geometry hierarchy map");
0139 }
0140 if (header->at("format-version").get<int>() != kFormatVersion) {
0141 throw std::invalid_argument(
0142 "Invalid format version in json geometry hierarchy map");
0143 }
0144 if (header->at("value-identifier").get<std::string>() != m_valueIdentifier) {
0145 throw std::invalid_argument(
0146 "Inconsistent value identifier in Json geometry hierarchy map");
0147 }
0148
0149 if (!encoded.contains(kEntriesKey)) {
0150 throw std::invalid_argument(
0151 "Missing entries in json geometry hierarchy map");
0152 }
0153 std::vector<std::pair<GeometryIdentifier, Value>> elements;
0154 for (const auto& entry : encoded.at(kEntriesKey)) {
0155 auto id = GeometryIdentifierJsonConverter::decodeIdentifier(entry);
0156 auto value = entry.at("value").get<Value>();
0157 elements.emplace_back(id, std::move(value));
0158 }
0159 return Container(std::move(elements));
0160 }
0161
0162 }