File indexing completed on 2026-09-23 08:21:10
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsPlugins/Json/SurfaceJsonConverter.hpp"
0010
0011 #include "Acts/Surfaces/AnnulusBounds.hpp"
0012 #include "Acts/Surfaces/ConeBounds.hpp"
0013 #include "Acts/Surfaces/ConeSurface.hpp"
0014 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0015 #include "Acts/Surfaces/CylinderBounds.hpp"
0016 #include "Acts/Surfaces/CylinderSurface.hpp"
0017 #include "Acts/Surfaces/DiamondBounds.hpp"
0018 #include "Acts/Surfaces/DiscSurface.hpp"
0019 #include "Acts/Surfaces/DiscTrapezoidBounds.hpp"
0020 #include "Acts/Surfaces/EllipseBounds.hpp"
0021 #include "Acts/Surfaces/InfiniteBounds.hpp"
0022 #include "Acts/Surfaces/LineBounds.hpp"
0023 #include "Acts/Surfaces/PerigeeSurface.hpp"
0024 #include "Acts/Surfaces/PlaneSurface.hpp"
0025 #include "Acts/Surfaces/PointBounds.hpp"
0026 #include "Acts/Surfaces/PointSurface.hpp"
0027 #include "Acts/Surfaces/RadialBounds.hpp"
0028 #include "Acts/Surfaces/RectangleBounds.hpp"
0029 #include "Acts/Surfaces/StrawSurface.hpp"
0030 #include "Acts/Surfaces/Surface.hpp"
0031 #include "Acts/Surfaces/SurfaceBounds.hpp"
0032 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0033 #include "ActsPlugins/Json/GeometryIdentifierJsonConverter.hpp"
0034 #include "ActsPlugins/Json/GeometryJsonKeys.hpp"
0035 #include "ActsPlugins/Json/SurfaceBoundsJsonConverter.hpp"
0036 #include "ActsPlugins/Json/SurfaceMaterialJsonConverter.hpp"
0037
0038 #include <memory>
0039
0040 namespace {
0041
0042
0043
0044
0045 template <typename bounds_t>
0046 std::string getSurfaceBoundsKind() {
0047 if (std::is_same_v<bounds_t, Acts::EllipseBounds>) {
0048 return "Ellipse";
0049 } else if (std::is_same_v<bounds_t, Acts::RectangleBounds>) {
0050 return "Rectangle";
0051 } else if (std::is_same_v<bounds_t, Acts::TrapezoidBounds>) {
0052 return "Trapezoid";
0053 } else if (std::is_same_v<bounds_t, Acts::DiamondBounds>) {
0054 return "Diamond";
0055 } else if (std::is_same_v<bounds_t, Acts::AnnulusBounds>) {
0056 return "Annulus";
0057 } else if (std::is_same_v<bounds_t, Acts::RadialBounds>) {
0058 return "Radial";
0059 } else if (std::is_same_v<bounds_t, Acts::DiscTrapezoidBounds>) {
0060 return "DiscTrapezoid";
0061 } else if (std::is_same_v<bounds_t, Acts::CylinderBounds>) {
0062 return "Cylinder";
0063 } else if (std::is_same_v<bounds_t, Acts::ConeBounds>) {
0064 return "Cone";
0065 } else if (std::is_same_v<bounds_t, Acts::LineBounds>) {
0066 return "Line";
0067 } else if (std::is_same_v<bounds_t, Acts::PointBounds>) {
0068 return "Point";
0069 } else if (std::is_same_v<bounds_t, Acts::ConvexPolygonBoundsBase>) {
0070
0071
0072
0073 return "ConvexPolygon";
0074 } else if (std::is_same_v<bounds_t, Acts::SurfaceBounds>) {
0075 return "DefaultBounds";
0076 } else if (std::is_same_v<bounds_t, Acts::InfiniteBounds>) {
0077 return "Infinite";
0078 } else {
0079 throw std::invalid_argument("Unknown surface bounds kind");
0080 }
0081 }
0082
0083
0084
0085
0086 template <typename surface_t>
0087 std::string getSurfaceKind() {
0088 if (std::is_same_v<surface_t, Acts::PlaneSurface>) {
0089 return "Plane";
0090 } else if (std::is_same_v<surface_t, Acts::DiscSurface>) {
0091 return "Disc";
0092 } else if (std::is_same_v<surface_t, Acts::CylinderSurface>) {
0093 return "Cylinder";
0094 } else if (std::is_same_v<surface_t, Acts::ConeSurface>) {
0095 return "Cone";
0096 } else if (std::is_same_v<surface_t, Acts::StrawSurface>) {
0097 return "Straw";
0098 } else if (std::is_same_v<surface_t, Acts::PerigeeSurface>) {
0099 return "Perigee";
0100 } else if (std::is_same_v<surface_t, Acts::PointSurface>) {
0101 return "Point";
0102 } else {
0103 throw std::invalid_argument("Unknown surface kind");
0104 }
0105 }
0106
0107
0108
0109
0110
0111
0112
0113
0114 template <typename bounds_t>
0115 nlohmann::json surfaceBoundsToJsonT(const bounds_t& bounds) {
0116 nlohmann::json jBounds = Acts::SurfaceBoundsJsonConverter::toJson(bounds);
0117 jBounds["kind"] = getSurfaceBoundsKind<bounds_t>();
0118 return jBounds;
0119 }
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 template <typename surface_t>
0131 nlohmann::json surfaceToJsonT(const surface_t& surface,
0132 const Acts::GeometryContext& gctx,
0133 const Acts::SurfaceJsonConverter::Options& opt) {
0134 nlohmann::json jSurface;
0135 const auto sTransform = surface.localToGlobalTransform(gctx);
0136
0137 jSurface["transform"] =
0138 Acts::Transform3JsonConverter::toJson(sTransform, opt.transformOptions);
0139 jSurface["type"] = surface.type();
0140 jSurface["geo_id"] = nlohmann::json(surface.geometryId());
0141 jSurface["sensitive"] = surface.isSensitive();
0142 if (surface.hasMaterial() && opt.writeMaterial) {
0143 jSurface[Acts::jsonKey().materialkey] =
0144 Acts::SurfaceMaterialJsonConverter::toJson(*surface.surfaceMaterial());
0145 }
0146 jSurface["kind"] = getSurfaceKind<surface_t>();
0147 return jSurface;
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157 template <typename surface_t>
0158 std::shared_ptr<Acts::Surface> surfaceFromJsonT(const nlohmann::json& j) {
0159 nlohmann::json jTransform = j["transform"];
0160 Acts::Transform3 sTransform =
0161 Acts::Transform3JsonConverter::fromJson(jTransform);
0162 return Acts::Surface::makeShared<surface_t>(sTransform);
0163 }
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 template <typename surface_t, typename bounds_t>
0174 std::shared_ptr<Acts::Surface> surfaceFromJsonT(const nlohmann::json& j) {
0175 nlohmann::json jTransform = j["transform"];
0176 Acts::Transform3 sTransform =
0177 Acts::Transform3JsonConverter::fromJson(jTransform);
0178 nlohmann::json jBounds = j["bounds"];
0179 auto sBounds = Acts::SurfaceBoundsJsonConverter::fromJson<bounds_t>(jBounds);
0180 return Acts::Surface::makeShared<surface_t>(sTransform, std::move(sBounds));
0181 }
0182
0183 }
0184
0185 void Acts::to_json(nlohmann::json& j,
0186 const Acts::SurfaceAndMaterialWithContext& surface) {
0187 toJson(j, std::get<0>(surface), std::get<2>(surface));
0188 const auto& material = std::get<1>(surface);
0189 if (material != nullptr) {
0190 j[jsonKey().materialkey] = SurfaceMaterialJsonConverter::toJson(*material);
0191 }
0192 }
0193
0194 void Acts::to_json(nlohmann::json& j, const Acts::Surface& surface) {
0195 Acts::GeometryContext gctx =
0196 Acts::GeometryContext::dangerouslyDefaultConstruct();
0197 j = SurfaceJsonConverter::toJson(gctx, surface);
0198 }
0199
0200 void Acts::to_json(nlohmann::json& j,
0201 const std::shared_ptr<const Acts::Surface>& surface) {
0202 Acts::GeometryContext gctx =
0203 Acts::GeometryContext::dangerouslyDefaultConstruct();
0204 j = SurfaceJsonConverter::toJson(gctx, *surface);
0205 }
0206
0207 void Acts::toJson(nlohmann::json& j,
0208 const std::shared_ptr<const Acts::Surface>& surface,
0209 const Acts::GeometryContext& gctx) {
0210 j = SurfaceJsonConverter::toJson(gctx, *surface);
0211 }
0212
0213 Acts::SurfaceJsonConverter::Config
0214 Acts::SurfaceJsonConverter::Config::defaultConfig() {
0215 Config cfg;
0216
0217
0218 cfg.surfaceEncoder.registerFunction(surfaceToJsonT<PlaneSurface>);
0219 cfg.surfaceEncoder.registerFunction(surfaceToJsonT<DiscSurface>);
0220 cfg.surfaceEncoder.registerFunction(surfaceToJsonT<CylinderSurface>);
0221 cfg.surfaceEncoder.registerFunction(surfaceToJsonT<ConeSurface>);
0222 cfg.surfaceEncoder.registerFunction(surfaceToJsonT<StrawSurface>);
0223 cfg.surfaceEncoder.registerFunction(surfaceToJsonT<PerigeeSurface>);
0224 cfg.surfaceEncoder.registerFunction(surfaceToJsonT<PointSurface>);
0225
0226 cfg.surfaceBoundsEncoder.registerFunction(
0227 surfaceBoundsToJsonT<EllipseBounds>);
0228 cfg.surfaceBoundsEncoder.registerFunction(
0229 surfaceBoundsToJsonT<RectangleBounds>);
0230 cfg.surfaceBoundsEncoder.registerFunction(
0231 surfaceBoundsToJsonT<TrapezoidBounds>);
0232 cfg.surfaceBoundsEncoder.registerFunction(
0233 surfaceBoundsToJsonT<DiamondBounds>);
0234 cfg.surfaceBoundsEncoder.registerFunction(
0235 surfaceBoundsToJsonT<AnnulusBounds>);
0236 cfg.surfaceBoundsEncoder.registerFunction(surfaceBoundsToJsonT<RadialBounds>);
0237 cfg.surfaceBoundsEncoder.registerFunction(
0238 surfaceBoundsToJsonT<DiscTrapezoidBounds>);
0239 cfg.surfaceBoundsEncoder.registerFunction(
0240 surfaceBoundsToJsonT<CylinderBounds>);
0241 cfg.surfaceBoundsEncoder.registerFunction(surfaceBoundsToJsonT<ConeBounds>);
0242 cfg.surfaceBoundsEncoder.registerFunction(surfaceBoundsToJsonT<LineBounds>);
0243 cfg.surfaceBoundsEncoder.registerFunction(surfaceBoundsToJsonT<PointBounds>);
0244 cfg.surfaceBoundsEncoder.registerFunction(
0245 surfaceBoundsToJsonT<InfiniteBounds>);
0246
0247
0248
0249
0250
0251
0252
0253
0254 cfg.surfaceBoundsEncoder.registerFunction(
0255 surfaceBoundsToJsonT<ConvexPolygonBoundsBase>);
0256
0257
0258 cfg.surfaceDecoder.registerKind(
0259 getSurfaceKind<PlaneSurface>() + getSurfaceBoundsKind<EllipseBounds>(),
0260 surfaceFromJsonT<PlaneSurface, EllipseBounds>);
0261 cfg.surfaceDecoder.registerKind(
0262 getSurfaceKind<PlaneSurface>() + getSurfaceBoundsKind<RectangleBounds>(),
0263 surfaceFromJsonT<PlaneSurface, RectangleBounds>);
0264 cfg.surfaceDecoder.registerKind(
0265 getSurfaceKind<PlaneSurface>() + getSurfaceBoundsKind<TrapezoidBounds>(),
0266 surfaceFromJsonT<PlaneSurface, TrapezoidBounds>);
0267 cfg.surfaceDecoder.registerKind(
0268 getSurfaceKind<PlaneSurface>() + getSurfaceBoundsKind<DiamondBounds>(),
0269 surfaceFromJsonT<PlaneSurface, DiamondBounds>);
0270 cfg.surfaceDecoder.registerKind(
0271 getSurfaceKind<PlaneSurface>() + getSurfaceBoundsKind<InfiniteBounds>(),
0272 surfaceFromJsonT<PlaneSurface>);
0273
0274
0275
0276
0277
0278 cfg.surfaceDecoder.registerKind(
0279 getSurfaceKind<PlaneSurface>() +
0280 getSurfaceBoundsKind<ConvexPolygonBoundsBase>(),
0281 [](const nlohmann::json& j) -> std::shared_ptr<Surface> {
0282 Transform3 sTransform =
0283 Transform3JsonConverter::fromJson(j["transform"]);
0284 std::vector<double> bVector = j["bounds"]["values"];
0285 if (bVector.size() < 6 || bVector.size() % 2 != 0) {
0286 throw std::invalid_argument(
0287 "Invalid ConvexPolygonBounds 'values' array: need an even "
0288 "number of entries (>= 6) encoding at least 3 (x, y) vertices");
0289 }
0290 std::vector<Vector2> vertices;
0291 vertices.reserve(bVector.size() / 2);
0292 for (std::size_t i = 0; i < bVector.size(); i += 2) {
0293 vertices.emplace_back(bVector[i], bVector[i + 1]);
0294 }
0295 auto sBounds =
0296 std::make_shared<const ConvexPolygonBounds<PolygonDynamic>>(
0297 vertices);
0298 return Surface::makeShared<PlaneSurface>(sTransform,
0299 std::move(sBounds));
0300 });
0301
0302 cfg.surfaceDecoder.registerKind(
0303 getSurfaceKind<DiscSurface>() + getSurfaceBoundsKind<AnnulusBounds>(),
0304 surfaceFromJsonT<DiscSurface, AnnulusBounds>);
0305 cfg.surfaceDecoder.registerKind(
0306 getSurfaceKind<DiscSurface>() + getSurfaceBoundsKind<RadialBounds>(),
0307 surfaceFromJsonT<DiscSurface, RadialBounds>);
0308 cfg.surfaceDecoder.registerKind(
0309 getSurfaceKind<DiscSurface>() +
0310 getSurfaceBoundsKind<DiscTrapezoidBounds>(),
0311 surfaceFromJsonT<DiscSurface, DiscTrapezoidBounds>);
0312
0313 cfg.surfaceDecoder.registerKind(
0314 getSurfaceKind<CylinderSurface>() +
0315 getSurfaceBoundsKind<CylinderBounds>(),
0316 surfaceFromJsonT<CylinderSurface, CylinderBounds>);
0317 cfg.surfaceDecoder.registerKind(
0318 getSurfaceKind<ConeSurface>() + getSurfaceBoundsKind<ConeBounds>(),
0319 surfaceFromJsonT<ConeSurface, ConeBounds>);
0320 cfg.surfaceDecoder.registerKind(
0321 getSurfaceKind<StrawSurface>() + getSurfaceBoundsKind<LineBounds>(),
0322 surfaceFromJsonT<StrawSurface, LineBounds>);
0323
0324 cfg.surfaceDecoder.registerKind(
0325 getSurfaceKind<PerigeeSurface>() + getSurfaceBoundsKind<InfiniteBounds>(),
0326 surfaceFromJsonT<PerigeeSurface>);
0327
0328 cfg.surfaceDecoder.registerKind(
0329 getSurfaceKind<PointSurface>() + getSurfaceBoundsKind<PointBounds>(),
0330 surfaceFromJsonT<PointSurface, PointBounds>);
0331 cfg.surfaceDecoder.registerKind(
0332 getSurfaceKind<PointSurface>() + getSurfaceBoundsKind<InfiniteBounds>(),
0333 surfaceFromJsonT<PointSurface>);
0334 return cfg;
0335 }
0336
0337 Acts::SurfaceJsonConverter::Config Acts::SurfaceJsonConverter::m_cfg =
0338 Acts::SurfaceJsonConverter::Config::defaultConfig();
0339
0340 std::shared_ptr<Acts::Surface> Acts::SurfaceJsonConverter::fromJson(
0341 const nlohmann::json& j) {
0342 std::shared_ptr<Acts::Surface> mutableSf = nullptr;
0343 mutableSf = m_cfg.surfaceDecoder(j);
0344
0345 if (j.find("geo_id") != j.end() && !j["geo_id"].empty()) {
0346 GeometryIdentifier geoID = j["geo_id"].get<GeometryIdentifier>();
0347 mutableSf->assignGeometryId(geoID);
0348 } else {
0349 mutableSf->assignGeometryId(GeometryIdentifier(0));
0350 }
0351 mutableSf->assignIsSensitive(j["sensitive"].get<bool>());
0352
0353 if (j.find(jsonKey().materialkey) != j.end() &&
0354 !j[jsonKey().materialkey].empty()) {
0355 mutableSf->assignSurfaceMaterial(
0356 SurfaceMaterialJsonConverter::fromJson(j[jsonKey().materialkey]));
0357 }
0358 return mutableSf;
0359 }
0360
0361 nlohmann::json Acts::SurfaceJsonConverter::toJson(const GeometryContext& gctx,
0362 const Surface& surface,
0363 const Options& options) {
0364 nlohmann::json jSurface = m_cfg.surfaceEncoder(surface, gctx, options);
0365 nlohmann::json jBounds = m_cfg.surfaceBoundsEncoder(surface.bounds());
0366 jSurface["bounds"] = jBounds;
0367 jSurface["kind"] =
0368 jSurface["kind"].get<std::string>() + jBounds["kind"].get<std::string>();
0369 return jSurface;
0370 }