File indexing completed on 2025-08-05 08:10:18
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/Json/GridJsonConverter.hpp"
0010
0011 #include "Acts/Plugins/Json/AlgebraJsonConverter.hpp"
0012 #include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp"
0013 #include "Acts/Utilities/IAxis.hpp"
0014
0015 nlohmann::json Acts::AxisJsonConverter::toJson(const IAxis& ia) {
0016 nlohmann::json jAxis;
0017
0018 jAxis["boundary_type"] = ia.getBoundaryType();
0019
0020 if (ia.isEquidistant()) {
0021 jAxis["type"] = detail::AxisType::Equidistant;
0022 jAxis["range"] = std::array<ActsScalar, 2u>({ia.getMin(), ia.getMax()});
0023 jAxis["bins"] = ia.getNBins();
0024 } else {
0025 jAxis["type"] = detail::AxisType::Variable;
0026 jAxis["boundaries"] = ia.getBinEdges();
0027 }
0028 return jAxis;
0029 }
0030
0031 nlohmann::json Acts::AxisJsonConverter::toJsonDetray(const IAxis& ia) {
0032 nlohmann::json jAxis;
0033 jAxis["bounds"] =
0034 ia.getBoundaryType() == Acts::detail::AxisBoundaryType::Bound ? 1 : 2;
0035 jAxis["binning"] = ia.isEquidistant() ? 0 : 1;
0036 jAxis["bins"] = ia.getNBins();
0037 if (ia.isEquidistant()) {
0038 std::array<ActsScalar, 2u> range = {ia.getBinEdges().front(),
0039 ia.getBinEdges().back()};
0040 jAxis["edges"] = range;
0041
0042 } else {
0043 jAxis["edges"] = ia.getBinEdges();
0044 }
0045 return jAxis;
0046 }
0047
0048 namespace {
0049
0050 template <typename Subspace>
0051 void encodeSubspace(
0052 nlohmann::json& jGlobalToGridLocal,
0053 const Acts::GridAccess::IGlobalToGridLocal& globalToGridLocal,
0054 const Subspace& ) {
0055 const Subspace* subspace = dynamic_cast<const Subspace*>(&globalToGridLocal);
0056 if (subspace != nullptr) {
0057 jGlobalToGridLocal["type"] = "subspace";
0058 jGlobalToGridLocal["accessors"] = subspace->bValues;
0059 }
0060 }
0061
0062 template <typename Subspace>
0063 void encodeTransformedSubspace(
0064 nlohmann::json& jGlobalToGridLocal,
0065 const Acts::GridAccess::IGlobalToGridLocal& globalToGridLocal,
0066 const Subspace& subscpace) {
0067 const Acts::GridAccess::Affine3Transformed<Subspace>* tsubspace =
0068 dynamic_cast<const Acts::GridAccess::Affine3Transformed<Subspace>*>(
0069 &globalToGridLocal);
0070 if (tsubspace != nullptr) {
0071 encodeSubspace(jGlobalToGridLocal, tsubspace->globalToGridLocal, subscpace);
0072 jGlobalToGridLocal["transform"] =
0073 Acts::Transform3JsonConverter::toJson(tsubspace->transform);
0074 }
0075 }
0076
0077 template <typename... Args>
0078 void encodeSubspaces(
0079 nlohmann::json& jGlobalToGridLocal,
0080 const Acts::GridAccess::IGlobalToGridLocal& globalToGridLocal,
0081 bool transformed, const std::tuple<Args...>& tAcessors) {
0082 if (transformed) {
0083 std::apply(
0084 [&](auto&&... vals) {
0085 (encodeTransformedSubspace(jGlobalToGridLocal, globalToGridLocal,
0086 vals),
0087 ...);
0088 },
0089 tAcessors);
0090 } else {
0091 std::apply(
0092 [&](auto&&... vals) {
0093 (encodeSubspace(jGlobalToGridLocal, globalToGridLocal, vals), ...);
0094 },
0095 tAcessors);
0096 }
0097 }
0098
0099 template <Acts::BinningValue... Args>
0100 std::unique_ptr<const Acts::GridAccess::GlobalSubspace<Args...>> decodeSubspace(
0101 const nlohmann::json& ) {
0102 return std::make_unique<const Acts::GridAccess::GlobalSubspace<Args...>>();
0103 }
0104
0105 template <Acts::BinningValue... Args>
0106 std::unique_ptr<const Acts::GridAccess::Affine3Transformed<
0107 Acts::GridAccess::GlobalSubspace<Args...>>>
0108 decodeTransformedSubspace(const nlohmann::json& jGlobalToGridLocal) {
0109 Acts::Transform3 transform = Acts::Transform3JsonConverter::fromJson(
0110 jGlobalToGridLocal.at("transform"));
0111 Acts::GridAccess::GlobalSubspace<Args...> globalSubspace;
0112 return std::make_unique<const Acts::GridAccess::Affine3Transformed<
0113 Acts::GridAccess::GlobalSubspace<Args...>>>(std::move(globalSubspace),
0114 transform);
0115 }
0116
0117 template <Acts::BinningValue... Args>
0118 std::unique_ptr<const Acts::GridAccess::IGlobalToGridLocal>
0119 decodeGeneralSubspace(const nlohmann::json& jGlobalToGridLocal) {
0120 if (jGlobalToGridLocal.find("transform") != jGlobalToGridLocal.end()) {
0121 return decodeTransformedSubspace<Args...>(jGlobalToGridLocal);
0122 }
0123 return decodeSubspace<Args...>(jGlobalToGridLocal);
0124 }
0125
0126 template <typename Delegate, Acts::BinningValue... Args>
0127 void decorateGlobalDelegate(Delegate& delegate,
0128 const nlohmann::json& jGlobalToGridLocal) {
0129
0130 if (delegate.connected()) {
0131 return;
0132 }
0133
0134
0135 bool hasTransform =
0136 jGlobalToGridLocal.find("transform") != jGlobalToGridLocal.end();
0137
0138
0139 std::vector<Acts::BinningValue> accessors =
0140 jGlobalToGridLocal.at("accessors").get<std::vector<Acts::BinningValue>>();
0141
0142
0143 if constexpr (sizeof...(Args) == 1u) {
0144 if (std::get<0>(std::forward_as_tuple(Args...)) == accessors[0]) {
0145 if (hasTransform) {
0146 using TransformedSubspace = Acts::GridAccess::Affine3Transformed<
0147 Acts::GridAccess::GlobalSubspace<Args...>>;
0148 auto globalToGridLocal =
0149 decodeTransformedSubspace<Args...>(jGlobalToGridLocal);
0150 delegate.template connect<&TransformedSubspace::toGridLocal>(
0151 std::move(globalToGridLocal));
0152 } else {
0153 auto globalToGridLocal = decodeSubspace<Args...>(jGlobalToGridLocal);
0154 delegate.template connect<
0155 &Acts::GridAccess::GlobalSubspace<Args...>::toGridLocal>(
0156 std::move(globalToGridLocal));
0157 }
0158 }
0159 }
0160
0161
0162 if constexpr (sizeof...(Args) == 2u) {
0163 if (std::get<0>(std::forward_as_tuple(Args...)) == accessors[0] &&
0164 std::get<1>(std::forward_as_tuple(Args...)) == accessors[1]) {
0165 if (hasTransform) {
0166 using TransformedSubspace = Acts::GridAccess::Affine3Transformed<
0167 Acts::GridAccess::GlobalSubspace<Args...>>;
0168 auto globalToGridLocal =
0169 decodeTransformedSubspace<Args...>(jGlobalToGridLocal);
0170 delegate.template connect<&TransformedSubspace::toGridLocal>(
0171 std::move(globalToGridLocal));
0172 } else {
0173 auto globalToGridLocal = decodeSubspace<Args...>(jGlobalToGridLocal);
0174 delegate.template connect<
0175 &Acts::GridAccess::GlobalSubspace<Args...>::toGridLocal>(
0176 std::move(globalToGridLocal));
0177 }
0178 }
0179 }
0180 }
0181
0182 template <Acts::BinningValue... Args>
0183 void decorateGlobal1DimDelegate(
0184 Acts::GridAccess::GlobalToGridLocal1DimDelegate& delegate,
0185 const nlohmann::json& jGlobalToGridLocal) {
0186 (((decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal1DimDelegate,
0187 Args>(delegate, jGlobalToGridLocal))),
0188 ...);
0189 }
0190
0191 }
0192
0193 nlohmann::json Acts::GridAccessJsonConverter::toJson(
0194 const GridAccess::IGlobalToGridLocal& globalToGridLocal) {
0195 nlohmann::json jGlobalToGridLocal;
0196
0197 std::array<bool, 2u> transformOptions = {false, true};
0198
0199
0200 const std::tuple<
0201 GridAccess::GlobalSubspace<binX>, GridAccess::GlobalSubspace<binY>,
0202 GridAccess::GlobalSubspace<binZ>, GridAccess::GlobalSubspace<binR>,
0203 GridAccess::GlobalSubspace<binPhi>, GridAccess::GlobalSubspace<binEta>>
0204 oneDimSubspaces = {};
0205
0206 for (bool transform : transformOptions) {
0207 encodeSubspaces(jGlobalToGridLocal, globalToGridLocal, transform,
0208 oneDimSubspaces);
0209 if (!jGlobalToGridLocal.empty()) {
0210 return jGlobalToGridLocal;
0211 }
0212 }
0213
0214
0215 const std::tuple<GridAccess::GlobalSubspace<binX, binY>,
0216 GridAccess::GlobalSubspace<binY, binX>,
0217 GridAccess::GlobalSubspace<binX, binZ>,
0218 GridAccess::GlobalSubspace<binZ, binX>,
0219 GridAccess::GlobalSubspace<binY, binZ>,
0220 GridAccess::GlobalSubspace<binZ, binY>,
0221 GridAccess::GlobalSubspace<binR, binPhi>,
0222 GridAccess::GlobalSubspace<binPhi, binR>,
0223 GridAccess::GlobalSubspace<binZ, binPhi>,
0224 GridAccess::GlobalSubspace<binPhi, binZ>>
0225 twoDimSubspaces = {};
0226
0227 for (bool transform : transformOptions) {
0228 encodeSubspaces(jGlobalToGridLocal, globalToGridLocal, transform,
0229 twoDimSubspaces);
0230 if (!jGlobalToGridLocal.empty()) {
0231 return jGlobalToGridLocal;
0232 }
0233 }
0234 return jGlobalToGridLocal;
0235 }
0236
0237 std::unique_ptr<const Acts::GridAccess::IGlobalToGridLocal>
0238 Acts::GridAccessJsonConverter::globalToGridLocalFromJson(
0239 const nlohmann::json& jGlobalToGridLocal) {
0240 std::unique_ptr<const Acts::GridAccess::IGlobalToGridLocal>
0241 globalToGridLocal = nullptr;
0242
0243 std::vector<BinningValue> accessors =
0244 jGlobalToGridLocal.at("accessors").get<std::vector<BinningValue>>();
0245
0246
0247 if (accessors.size() == 1u) {
0248 switch (accessors[0]) {
0249 case binX:
0250 globalToGridLocal = decodeGeneralSubspace<binX>(jGlobalToGridLocal);
0251 break;
0252 case binY:
0253 globalToGridLocal = decodeGeneralSubspace<binY>(jGlobalToGridLocal);
0254 break;
0255 case binZ:
0256 globalToGridLocal = decodeGeneralSubspace<binZ>(jGlobalToGridLocal);
0257 break;
0258 case binR:
0259 globalToGridLocal = decodeGeneralSubspace<binR>(jGlobalToGridLocal);
0260 break;
0261 case binPhi:
0262 globalToGridLocal = decodeGeneralSubspace<binPhi>(jGlobalToGridLocal);
0263 break;
0264 case binEta:
0265 globalToGridLocal = decodeGeneralSubspace<binEta>(jGlobalToGridLocal);
0266 break;
0267 default:
0268
0269 break;
0270 }
0271 }
0272
0273
0274 if (accessors.size() == 2u) {
0275 if (accessors == std::vector<BinningValue>{binX, binY}) {
0276 globalToGridLocal = decodeGeneralSubspace<binX, binY>(jGlobalToGridLocal);
0277 } else if (accessors == std::vector<BinningValue>{binY, binX}) {
0278 globalToGridLocal = decodeGeneralSubspace<binY, binX>(jGlobalToGridLocal);
0279 } else if (accessors == std::vector<BinningValue>{binX, binZ}) {
0280 globalToGridLocal = decodeGeneralSubspace<binX, binZ>(jGlobalToGridLocal);
0281 } else if (accessors == std::vector<BinningValue>{binZ, binX}) {
0282 globalToGridLocal = decodeGeneralSubspace<binZ, binX>(jGlobalToGridLocal);
0283 } else if (accessors == std::vector<BinningValue>{binY, binZ}) {
0284 globalToGridLocal = decodeGeneralSubspace<binY, binZ>(jGlobalToGridLocal);
0285 } else if (accessors == std::vector<BinningValue>{binZ, binY}) {
0286 globalToGridLocal = decodeGeneralSubspace<binZ, binY>(jGlobalToGridLocal);
0287 } else if (accessors == std::vector<BinningValue>{binR, binPhi}) {
0288 globalToGridLocal =
0289 decodeGeneralSubspace<binR, binPhi>(jGlobalToGridLocal);
0290 } else if (accessors == std::vector<BinningValue>{binPhi, binR}) {
0291 globalToGridLocal =
0292 decodeGeneralSubspace<binPhi, binR>(jGlobalToGridLocal);
0293 } else if (accessors == std::vector<BinningValue>{binZ, binPhi}) {
0294 globalToGridLocal =
0295 decodeGeneralSubspace<binZ, binPhi>(jGlobalToGridLocal);
0296 } else if (accessors == std::vector<BinningValue>{binPhi, binZ}) {
0297 globalToGridLocal =
0298 decodeGeneralSubspace<binPhi, binZ>(jGlobalToGridLocal);
0299 }
0300
0301 }
0302 return globalToGridLocal;
0303 }
0304
0305 Acts::GridAccess::GlobalToGridLocal1DimDelegate
0306 Acts::GridAccessJsonConverter::globalToGridLocal1DimDelegateFromJson(
0307 const nlohmann::json& jGlobalToGridLocal) {
0308
0309 if (jGlobalToGridLocal.at("accessors").size() != 1u) {
0310 throw std::invalid_argument(
0311 "GridAccessJsonConverter: json input does not describe 1D case.");
0312 }
0313
0314 Acts::GridAccess::GlobalToGridLocal1DimDelegate delegate;
0315 decorateGlobal1DimDelegate<binX, binY, binZ, binR, binPhi, binEta>(
0316 delegate, jGlobalToGridLocal);
0317 return delegate;
0318 }
0319
0320 Acts::GridAccess::GlobalToGridLocal2DimDelegate
0321 Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(
0322 const nlohmann::json& jGlobalToGridLocal) {
0323
0324 if (jGlobalToGridLocal.at("accessors").size() != 2u) {
0325 throw std::invalid_argument(
0326 "GridAccessJsonConverter: json input does not describe 2D case.");
0327 }
0328
0329 Acts::GridAccess::GlobalToGridLocal2DimDelegate delegate;
0330
0331
0332 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binX,
0333 binY>(delegate, jGlobalToGridLocal);
0334 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binY,
0335 binX>(delegate, jGlobalToGridLocal);
0336 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binX,
0337 binZ>(delegate, jGlobalToGridLocal);
0338 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binZ,
0339 binX>(delegate, jGlobalToGridLocal);
0340 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binY,
0341 binZ>(delegate, jGlobalToGridLocal);
0342 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binZ,
0343 binY>(delegate, jGlobalToGridLocal);
0344 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binR,
0345 binPhi>(delegate, jGlobalToGridLocal);
0346 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate,
0347 binPhi, binR>(delegate, jGlobalToGridLocal);
0348 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate, binZ,
0349 binPhi>(delegate, jGlobalToGridLocal);
0350 decorateGlobalDelegate<Acts::GridAccess::GlobalToGridLocal2DimDelegate,
0351 binPhi, binZ>(delegate, jGlobalToGridLocal);
0352 return delegate;
0353 }
0354
0355 nlohmann::json Acts::GridAccessJsonConverter::toJson(
0356 const GridAccess::IBoundToGridLocal& boundToGridLocal) {
0357 nlohmann::json jBoundToGridLocal;
0358
0359 auto localSubSpace0 =
0360 dynamic_cast<const GridAccess::LocalSubspace<0u>*>(&boundToGridLocal);
0361 if (localSubSpace0 != nullptr) {
0362 jBoundToGridLocal["type"] = "subspace";
0363 jBoundToGridLocal["accessors"] = localSubSpace0->accessors;
0364 }
0365
0366 auto localSubSpace1 =
0367 dynamic_cast<const GridAccess::LocalSubspace<1u>*>(&boundToGridLocal);
0368 if (localSubSpace1 != nullptr) {
0369 jBoundToGridLocal["type"] = "subspace";
0370 jBoundToGridLocal["accessors"] = localSubSpace1->accessors;
0371 }
0372
0373 auto localSubSpace01 =
0374 dynamic_cast<const GridAccess::LocalSubspace<0u, 1u>*>(&boundToGridLocal);
0375 if (localSubSpace01 != nullptr) {
0376 jBoundToGridLocal["type"] = "subspace";
0377 jBoundToGridLocal["accessors"] = localSubSpace01->accessors;
0378 }
0379
0380 auto localSubSpace10 =
0381 dynamic_cast<const GridAccess::LocalSubspace<1u, 0u>*>(&boundToGridLocal);
0382 if (localSubSpace10 != nullptr) {
0383 jBoundToGridLocal["type"] = "subspace";
0384 jBoundToGridLocal["accessors"] = localSubSpace10->accessors;
0385 }
0386
0387 auto boundCylinderToZPhi =
0388 dynamic_cast<const GridAccess::BoundCylinderToZPhi*>(&boundToGridLocal);
0389 if (boundCylinderToZPhi != nullptr) {
0390 jBoundToGridLocal["type"] = "cylinder_to_zphi";
0391 jBoundToGridLocal["radius"] = boundCylinderToZPhi->radius;
0392 jBoundToGridLocal["shift"] = boundCylinderToZPhi->shift;
0393 }
0394
0395 return jBoundToGridLocal;
0396 }
0397
0398 std::unique_ptr<Acts::GridAccess::IBoundToGridLocal>
0399 Acts::GridAccessJsonConverter::boundToGridLocalFromJson(
0400 const nlohmann::json& jBoundToGridLocal) {
0401 std::unique_ptr<Acts::GridAccess::IBoundToGridLocal> boundToGridLocal =
0402 nullptr;
0403 std::string type = jBoundToGridLocal.at("type").get<std::string>();
0404 if (type == "subspace") {
0405 std::vector<std::size_t> accessors =
0406 jBoundToGridLocal.at("accessors").get<std::vector<std::size_t>>();
0407 if (accessors.size() == 1 && accessors[0] == 0) {
0408 boundToGridLocal =
0409 std::make_unique<Acts::GridAccess::LocalSubspace<0u>>();
0410 } else if (accessors.size() == 1 && accessors[0] == 1) {
0411 boundToGridLocal =
0412 std::make_unique<Acts::GridAccess::LocalSubspace<1u>>();
0413 } else if (accessors.size() == 2 && accessors[0] == 0 &&
0414 accessors[1] == 1) {
0415 boundToGridLocal =
0416 std::make_unique<Acts::GridAccess::LocalSubspace<0u, 1u>>();
0417 } else if (accessors.size() == 2 && accessors[0] == 1 &&
0418 accessors[1] == 0) {
0419 boundToGridLocal =
0420 std::make_unique<Acts::GridAccess::LocalSubspace<1u, 0u>>();
0421 }
0422 } else if (type == "cylinder_to_zphi") {
0423 ActsScalar radius = jBoundToGridLocal.at("radius").get<ActsScalar>();
0424 ActsScalar shift = jBoundToGridLocal.at("shift").get<ActsScalar>();
0425 boundToGridLocal =
0426 std::make_unique<Acts::GridAccess::BoundCylinderToZPhi>(radius, shift);
0427 }
0428 return boundToGridLocal;
0429 }
0430
0431 Acts::GridAccess::BoundToGridLocal1DimDelegate
0432 Acts::GridAccessJsonConverter::boundToGridLocal1DimDelegateFromJson(
0433 const nlohmann::json& jBoundToGridLocal) {
0434 Acts::GridAccess::BoundToGridLocal1DimDelegate delegate;
0435
0436 std::string type = jBoundToGridLocal.at("type").get<std::string>();
0437 if (type == "subspace") {
0438 std::vector<std::size_t> accessors =
0439 jBoundToGridLocal.at("accessors").get<std::vector<std::size_t>>();
0440
0441 if (accessors.size() != 1u) {
0442 throw std::invalid_argument(
0443 "GridAccessJsonConverter: json input does not describe 1D case.");
0444 }
0445
0446 if (accessors[0] == 0) {
0447 auto boundToGridLocal =
0448 std::make_unique<const Acts::GridAccess::LocalSubspace<0u>>();
0449 delegate.connect<&Acts::GridAccess::LocalSubspace<0u>::toGridLocal>(
0450 std::move(boundToGridLocal));
0451 } else if (accessors[0] == 1) {
0452 auto boundToGridLocal =
0453 std::make_unique<const Acts::GridAccess::LocalSubspace<1u>>();
0454 delegate.connect<&Acts::GridAccess::LocalSubspace<1u>::toGridLocal>(
0455 std::move(boundToGridLocal));
0456 }
0457 }
0458 return delegate;
0459 }
0460
0461 Acts::GridAccess::BoundToGridLocal2DimDelegate
0462 Acts::GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0463 const nlohmann::json& jBoundToGridLocal) {
0464 Acts::GridAccess::BoundToGridLocal2DimDelegate delegate;
0465
0466 std::string type = jBoundToGridLocal.at("type").get<std::string>();
0467 if (type == "subspace") {
0468 std::vector<std::size_t> accessors =
0469 jBoundToGridLocal.at("accessors").get<std::vector<std::size_t>>();
0470
0471
0472 if (accessors.size() != 2u) {
0473 throw std::invalid_argument(
0474 "GridAccessJsonConverter: json input does not describe 2D case.");
0475 }
0476 if (accessors[0] == 0u && accessors[1] == 1u) {
0477 auto boundToGridLocal =
0478 std::make_unique<const Acts::GridAccess::LocalSubspace<0u, 1u>>();
0479 delegate.connect<&Acts::GridAccess::LocalSubspace<0u, 1u>::toGridLocal>(
0480 std::move(boundToGridLocal));
0481 } else if (accessors[0] == 1u && accessors[1] == 0u) {
0482 auto boundToGridLocal =
0483 std::make_unique<const Acts::GridAccess::LocalSubspace<1u, 0u>>();
0484 delegate.connect<&Acts::GridAccess::LocalSubspace<1u, 0u>::toGridLocal>(
0485 std::move(boundToGridLocal));
0486 }
0487 } else if (type == "cylinder_to_zphi") {
0488 ActsScalar radius = jBoundToGridLocal.at("radius").get<ActsScalar>();
0489 ActsScalar shift = jBoundToGridLocal.at("shift").get<ActsScalar>();
0490 auto boundToGridLocal =
0491 std::make_unique<const Acts::GridAccess::BoundCylinderToZPhi>(radius,
0492 shift);
0493 delegate.connect<&Acts::GridAccess::BoundCylinderToZPhi::toGridLocal>(
0494 std::move(boundToGridLocal));
0495 }
0496
0497 return delegate;
0498 }