File indexing completed on 2025-08-05 08:10:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/Json/MaterialJsonConverter.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Material/BinnedSurfaceMaterial.hpp"
0013 #include "Acts/Material/GridSurfaceMaterial.hpp"
0014 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0015 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0016 #include "Acts/Material/ISurfaceMaterial.hpp"
0017 #include "Acts/Material/IVolumeMaterial.hpp"
0018 #include "Acts/Material/InterpolatedMaterialMap.hpp"
0019 #include "Acts/Material/MaterialGridHelper.hpp"
0020 #include "Acts/Material/ProtoSurfaceMaterial.hpp"
0021 #include "Acts/Material/ProtoVolumeMaterial.hpp"
0022 #include "Acts/Plugins/Json/GeometryJsonKeys.hpp"
0023 #include "Acts/Plugins/Json/GridJsonConverter.hpp"
0024 #include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp"
0025 #include "Acts/Utilities/BinUtility.hpp"
0026 #include "Acts/Utilities/Grid.hpp"
0027 #include "Acts/Utilities/GridAccessHelpers.hpp"
0028 #include "Acts/Utilities/GridAxisGenerators.hpp"
0029 #include "Acts/Utilities/TypeList.hpp"
0030
0031 #include <algorithm>
0032 #include <cstddef>
0033 #include <functional>
0034 #include <iosfwd>
0035 #include <memory>
0036 #include <stdexcept>
0037 #include <string>
0038 #include <tuple>
0039 #include <utility>
0040 #include <vector>
0041
0042 namespace {
0043
0044
0045 template <typename value_type>
0046 using GridEqBound =
0047 Acts::Grid<value_type,
0048 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0049 Acts::detail::AxisBoundaryType::Bound>>;
0050
0051 template <typename value_type>
0052 using GridEqClosed =
0053 Acts::Grid<value_type,
0054 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0055 Acts::detail::AxisBoundaryType::Closed>>;
0056
0057
0058 template <typename value_type>
0059 using GridEqBoundEqBound =
0060 Acts::Grid<value_type,
0061 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0062 Acts::detail::AxisBoundaryType::Bound>,
0063 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0064 Acts::detail::AxisBoundaryType::Bound>>;
0065
0066
0067 template <typename value_type>
0068 using GridEqBoundEqClosed =
0069 Acts::Grid<value_type,
0070 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0071 Acts::detail::AxisBoundaryType::Bound>,
0072 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0073 Acts::detail::AxisBoundaryType::Closed>>;
0074
0075
0076 template <typename value_type>
0077 using GridEqClosedEqBound =
0078 Acts::Grid<value_type,
0079 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0080 Acts::detail::AxisBoundaryType::Closed>,
0081 Acts::detail::Axis<Acts::detail::AxisType::Equidistant,
0082 Acts::detail::AxisBoundaryType::Bound>>;
0083
0084
0085
0086
0087
0088
0089 template <typename indexed_grid_materital_t>
0090 void convertIndexedGridMaterial(
0091 nlohmann::json& jMaterial,
0092 const Acts::ISurfaceMaterial& indexedMaterialCandidate) {
0093
0094 const indexed_grid_materital_t* indexedMaterial =
0095 dynamic_cast<const indexed_grid_materital_t*>(&indexedMaterialCandidate);
0096
0097 if (indexedMaterial != nullptr) {
0098
0099 jMaterial[Acts::jsonKey().typekey] = "grid";
0100 nlohmann::json jMaterialAccessor;
0101
0102 jMaterialAccessor["type"] = "globally_indexed";
0103
0104
0105
0106 const auto& materialAccessor = indexedMaterial->materialAccessor();
0107
0108 if constexpr (std::is_same_v<decltype(materialAccessor),
0109 const Acts::IndexedMaterialAccessor&>) {
0110
0111 jMaterialAccessor["type"] = "indexed";
0112
0113 nlohmann::json jMaterialData;
0114 for (const auto& msl : materialAccessor.material) {
0115 jMaterialData.push_back(msl);
0116 }
0117 jMaterialAccessor["storage_vector"] = jMaterialData;
0118 }
0119
0120 jMaterialAccessor["grid"] =
0121 Acts::GridJsonConverter::toJson(indexedMaterial->grid());
0122 jMaterial["accessor"] = jMaterialAccessor;
0123
0124
0125 jMaterial["global_to_grid_local"] = Acts::GridAccessJsonConverter::toJson(
0126 *(indexedMaterial->globalToGridLocal().instance()));
0127
0128 jMaterial["bound_to_grid_local"] = Acts::GridAccessJsonConverter::toJson(
0129 *(indexedMaterial->boundToGridLocal().instance()));
0130 }
0131 }
0132
0133
0134
0135
0136
0137 template <typename... Args>
0138 void unrollIndexedGridConversion(nlohmann::json& jMaterial,
0139 const Acts::ISurfaceMaterial& indexedMaterial,
0140 Acts::TypeList<Args...> ) {
0141 (convertIndexedGridMaterial<Args>(jMaterial, indexedMaterial), ...);
0142 }
0143
0144 template <typename IndexedAccessorType>
0145 Acts::ISurfaceMaterial* indexedMaterialFromJson(nlohmann::json& jMaterial) {
0146
0147 nlohmann::json jMaterialAccessor = jMaterial["accessor"];
0148
0149
0150 IndexedAccessorType materialAccessor{};
0151
0152
0153 if constexpr (std::is_same_v<IndexedAccessorType,
0154 Acts::IndexedMaterialAccessor>) {
0155
0156 for (const auto& msl : jMaterialAccessor["storage_vector"]) {
0157 materialAccessor.material.push_back(msl);
0158 }
0159 }
0160
0161
0162 nlohmann::json jGrid = jMaterialAccessor["grid"];
0163 nlohmann::json jGridAxes = jGrid["axes"];
0164
0165 Acts::detail::AxisBoundaryType boundaryType0 = jGridAxes[0]["boundary_type"];
0166
0167
0168 if (jGridAxes.size() == 1u) {
0169
0170 if (boundaryType0 == Acts::detail::AxisBoundaryType::Bound) {
0171 Acts::GridAxisGenerators::EqBound eqBound{jGridAxes[0]["range"],
0172 jGridAxes[0]["bins"]};
0173 auto grid =
0174 Acts::GridJsonConverter::fromJson<decltype(eqBound), std::size_t>(
0175 jGrid, eqBound);
0176
0177 auto boundToGridLocal =
0178 Acts::GridAccessJsonConverter::boundToGridLocal1DimDelegateFromJson(
0179 jMaterial["bound_to_grid_local"]);
0180
0181 auto globalToGridLocal =
0182 Acts::GridAccessJsonConverter::globalToGridLocal1DimDelegateFromJson(
0183 jMaterial["global_to_grid_local"]);
0184
0185 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0186 std::move(grid), std::move(materialAccessor),
0187 std::move(boundToGridLocal), std::move(globalToGridLocal));
0188 }
0189
0190 if (boundaryType0 == Acts::detail::AxisBoundaryType::Closed) {
0191 Acts::GridAxisGenerators::EqClosed eqClosed{jGridAxes[0]["range"],
0192 jGridAxes[0]["bins"]};
0193 auto grid =
0194 Acts::GridJsonConverter::fromJson<decltype(eqClosed), std::size_t>(
0195 jGrid, eqClosed);
0196
0197 auto boundToGridLocal =
0198 Acts::GridAccessJsonConverter::boundToGridLocal1DimDelegateFromJson(
0199 jMaterial["bound_to_grid_local"]);
0200
0201 auto globalToGridLocal =
0202 Acts::GridAccessJsonConverter::globalToGridLocal1DimDelegateFromJson(
0203 jMaterial["global_to_grid_local"]);
0204
0205 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0206 std::move(grid), std::move(materialAccessor),
0207 std::move(boundToGridLocal), std::move(globalToGridLocal));
0208 }
0209 }
0210
0211
0212 if (jGridAxes.size() == 2u) {
0213
0214 Acts::detail::AxisBoundaryType boundaryType1 =
0215 jGridAxes[1]["boundary_type"];
0216
0217
0218 if (boundaryType0 == Acts::detail::AxisBoundaryType::Bound &&
0219 boundaryType1 == Acts::detail::AxisBoundaryType::Bound) {
0220 Acts::GridAxisGenerators::EqBoundEqBound eqBoundEqBound{
0221 jGridAxes[0]["range"], jGridAxes[0]["bins"], jGridAxes[1]["range"],
0222 jGridAxes[1]["bins"]};
0223 auto grid =
0224 Acts::GridJsonConverter::fromJson<decltype(eqBoundEqBound),
0225 std::size_t>(jGrid, eqBoundEqBound);
0226
0227 auto boundToGridLocal =
0228 Acts::GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0229 jMaterial["bound_to_grid_local"]);
0230
0231 auto globalToGridLocal =
0232 Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(
0233 jMaterial["global_to_grid_local"]);
0234
0235 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0236 std::move(grid), std::move(materialAccessor),
0237 std::move(boundToGridLocal), std::move(globalToGridLocal));
0238 }
0239
0240
0241 if (boundaryType0 == Acts::detail::AxisBoundaryType::Bound &&
0242 boundaryType1 == Acts::detail::AxisBoundaryType::Closed) {
0243 Acts::GridAxisGenerators::EqBoundEqClosed eqBoundEqClosed{
0244 jGridAxes[0]["range"], jGridAxes[0]["bins"], jGridAxes[1]["range"],
0245 jGridAxes[1]["bins"]};
0246 auto grid = Acts::GridJsonConverter::fromJson<decltype(eqBoundEqClosed),
0247 std::size_t>(
0248 jGrid, eqBoundEqClosed);
0249
0250 auto boundToGridLocal =
0251 Acts::GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0252 jMaterial["bound_to_grid_local"]);
0253
0254 auto globalToGridLocal =
0255 Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(
0256 jMaterial["global_to_grid_local"]);
0257
0258 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0259 std::move(grid), std::move(materialAccessor),
0260 std::move(boundToGridLocal), std::move(globalToGridLocal));
0261 }
0262
0263
0264 if (boundaryType0 == Acts::detail::AxisBoundaryType::Closed &&
0265 boundaryType1 == Acts::detail::AxisBoundaryType::Bound) {
0266 Acts::GridAxisGenerators::EqClosedEqBound eqClosedEqBound{
0267 jGridAxes[0]["range"], jGridAxes[0]["bins"], jGridAxes[1]["range"],
0268 jGridAxes[1]["bins"]};
0269 auto grid = Acts::GridJsonConverter::fromJson<decltype(eqClosedEqBound),
0270 std::size_t>(
0271 jGrid, eqClosedEqBound);
0272
0273 auto boundToGridLocal =
0274 Acts::GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0275 jMaterial["bound_to_grid_local"]);
0276
0277 auto globalToGridLocal =
0278 Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(
0279 jMaterial["global_to_grid_local"]);
0280
0281 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0282 std::move(grid), std::move(materialAccessor),
0283 std::move(boundToGridLocal), std::move(globalToGridLocal));
0284 }
0285 }
0286
0287 return nullptr;
0288 }
0289
0290 }
0291
0292 void Acts::to_json(nlohmann::json& j, const Material& t) {
0293 if (!t) {
0294 return;
0295 }
0296 for (unsigned i = 0; i < t.parameters().size(); ++i) {
0297 j.push_back(t.parameters()[i]);
0298 }
0299 }
0300
0301 void Acts::from_json(const nlohmann::json& j, Material& t) {
0302 if (j.is_null()) {
0303 return;
0304 }
0305 Acts::Material::ParametersVector params =
0306 Acts::Material::ParametersVector::Zero();
0307 for (auto i = params.size(); 0 < i--;) {
0308
0309 params[i] = j.at(i);
0310 }
0311 t = Acts::Material(params);
0312 return;
0313 }
0314
0315 void Acts::to_json(nlohmann::json& j, const MaterialSlab& t) {
0316 nlohmann::json jmat(t.material());
0317 j["material"] = jmat;
0318 j["thickness"] = t.thickness();
0319 }
0320
0321 void Acts::from_json(const nlohmann::json& j, MaterialSlab& t) {
0322 Material mat(j["material"].get<Material>());
0323 t = Acts::MaterialSlab(mat, j.at("thickness").get<float>());
0324 }
0325
0326 void Acts::from_json(const nlohmann::json& j, MaterialSlabMatrix& t) {
0327
0328 for (auto& outer : j) {
0329 Acts::MaterialSlabVector mpVector;
0330 for (auto& inner : outer) {
0331 MaterialSlab mat = inner.get<MaterialSlab>();
0332 mpVector.emplace_back(mat);
0333 }
0334 t.push_back(std::move(mpVector));
0335 }
0336 }
0337
0338 void Acts::to_json(nlohmann::json& j, const surfaceMaterialPointer& material) {
0339 nlohmann::json jMaterial;
0340
0341 const Acts::BinUtility* bUtility = nullptr;
0342
0343
0344 auto psMaterial = dynamic_cast<const Acts::ProtoSurfaceMaterial*>(material);
0345 if (psMaterial != nullptr) {
0346
0347 jMaterial[Acts::jsonKey().typekey] = "proto";
0348
0349 nlohmann::json mapType(material->mappingType());
0350 jMaterial[Acts::jsonKey().maptype] = mapType;
0351
0352 jMaterial[Acts::jsonKey().mapkey] = false;
0353
0354 bUtility = &(psMaterial->binning());
0355
0356 auto& binningData = bUtility->binningData();
0357 for (std::size_t ibin = 0; ibin < binningData.size(); ++ibin) {
0358 if (binningData[ibin].bins() > 1) {
0359 jMaterial[Acts::jsonKey().mapkey] = true;
0360 break;
0361 }
0362 }
0363 nlohmann::json jBin(*bUtility);
0364 jMaterial[Acts::jsonKey().binkey] = jBin;
0365 j[Acts::jsonKey().materialkey] = jMaterial;
0366 return;
0367 }
0368
0369
0370 auto hsMaterial =
0371 dynamic_cast<const Acts::HomogeneousSurfaceMaterial*>(material);
0372 if (hsMaterial != nullptr) {
0373
0374 jMaterial[Acts::jsonKey().typekey] = "homogeneous";
0375
0376 nlohmann::json mapType(material->mappingType());
0377 jMaterial[Acts::jsonKey().maptype] = mapType;
0378
0379 jMaterial[Acts::jsonKey().mapkey] = true;
0380 nlohmann::json jmat(hsMaterial->materialSlab(Acts::Vector3(0., 0., 0.)));
0381 jMaterial[Acts::jsonKey().datakey] = nlohmann::json::array({
0382 nlohmann::json::array({
0383 jmat,
0384 }),
0385 });
0386 j[Acts::jsonKey().materialkey] = jMaterial;
0387 return;
0388 }
0389
0390
0391 auto bsMaterial = dynamic_cast<const Acts::BinnedSurfaceMaterial*>(material);
0392 if (bsMaterial != nullptr) {
0393
0394 jMaterial[Acts::jsonKey().typekey] = "binned";
0395
0396 nlohmann::json mapType(material->mappingType());
0397 jMaterial[Acts::jsonKey().maptype] = mapType;
0398
0399 jMaterial[Acts::jsonKey().mapkey] = true;
0400 bUtility = &(bsMaterial->binUtility());
0401
0402
0403 nlohmann::json mmat = nlohmann::json::array();
0404 for (const auto& mpVector : bsMaterial->fullMaterial()) {
0405 nlohmann::json mvec = nlohmann::json::array();
0406 for (const auto& mp : mpVector) {
0407 nlohmann::json jmat(mp);
0408 mvec.push_back(jmat);
0409 }
0410 mmat.push_back(std::move(mvec));
0411 }
0412 jMaterial[Acts::jsonKey().datakey] = std::move(mmat);
0413
0414 nlohmann::json jBin(*bUtility);
0415 jMaterial[Acts::jsonKey().binkey] = jBin;
0416 j[Acts::jsonKey().materialkey] = jMaterial;
0417 return;
0418 }
0419
0420
0421 using IndexedSurfaceGrids = Acts::TypeList<
0422 Acts::IndexedSurfaceMaterial<GridEqBound<std::size_t>>,
0423 Acts::IndexedSurfaceMaterial<GridEqClosed<std::size_t>>,
0424 Acts::IndexedSurfaceMaterial<GridEqBoundEqBound<std::size_t>>,
0425 Acts::IndexedSurfaceMaterial<GridEqBoundEqClosed<std::size_t>>,
0426 Acts::IndexedSurfaceMaterial<GridEqClosedEqBound<std::size_t>>>;
0427
0428 unrollIndexedGridConversion(jMaterial, *material, IndexedSurfaceGrids{});
0429 if (!jMaterial.empty()) {
0430 j[Acts::jsonKey().materialkey] = jMaterial;
0431 return;
0432 }
0433
0434
0435 using GloballyIndexedSurfaceGrids = Acts::TypeList<
0436 Acts::GloballyIndexedSurfaceMaterial<GridEqBound<std::size_t>>,
0437 Acts::GloballyIndexedSurfaceMaterial<GridEqClosed<std::size_t>>,
0438 Acts::GloballyIndexedSurfaceMaterial<GridEqBoundEqBound<std::size_t>>,
0439 Acts::GloballyIndexedSurfaceMaterial<GridEqBoundEqClosed<std::size_t>>,
0440 Acts::GloballyIndexedSurfaceMaterial<GridEqClosedEqBound<std::size_t>>>;
0441
0442 unrollIndexedGridConversion(jMaterial, *material,
0443 GloballyIndexedSurfaceGrids{});
0444 if (!jMaterial.empty()) {
0445 j[Acts::jsonKey().materialkey] = jMaterial;
0446 return;
0447 }
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458 return;
0459 }
0460
0461 void Acts::from_json(const nlohmann::json& j,
0462 surfaceMaterialPointer& material) {
0463 if (j.find(Acts::jsonKey().materialkey) == j.end()) {
0464 return;
0465 }
0466 nlohmann::json jMaterial = j[Acts::jsonKey().materialkey];
0467
0468 material = nullptr;
0469 if (jMaterial[Acts::jsonKey().mapkey] == false) {
0470 return;
0471 }
0472
0473
0474 if (jMaterial[Acts::jsonKey().typekey] == "grid") {
0475 material =
0476 indexedMaterialFromJson<Acts::IndexedMaterialAccessor>(jMaterial);
0477 return;
0478 }
0479
0480
0481 Acts::BinUtility bUtility;
0482 Acts::MaterialSlabMatrix mpMatrix;
0483 Acts::MappingType mapType = Acts::MappingType::Default;
0484 for (auto& [key, value] : jMaterial.items()) {
0485 if (key == Acts::jsonKey().binkey && !value.empty()) {
0486 from_json(value, bUtility);
0487 }
0488 if (key == Acts::jsonKey().datakey && !value.empty()) {
0489 from_json(value, mpMatrix);
0490 }
0491 if (key == Acts::jsonKey().maptype && !value.empty()) {
0492 from_json(value, mapType);
0493 }
0494 }
0495
0496 if (mpMatrix.empty()) {
0497 material = new Acts::ProtoSurfaceMaterial(bUtility, mapType);
0498 } else if (bUtility.bins() == 1) {
0499 material = new Acts::HomogeneousSurfaceMaterial(mpMatrix[0][0], mapType);
0500 } else {
0501 material = new Acts::BinnedSurfaceMaterial(bUtility, mpMatrix, mapType);
0502 }
0503 }
0504
0505 void Acts::to_json(nlohmann::json& j, const volumeMaterialPointer& material) {
0506 nlohmann::json jMaterial;
0507
0508 const Acts::BinUtility* bUtility = nullptr;
0509
0510 auto pvMaterial = dynamic_cast<const Acts::ProtoVolumeMaterial*>(material);
0511 if (pvMaterial != nullptr) {
0512
0513 jMaterial[Acts::jsonKey().typekey] = "proto";
0514
0515 jMaterial[Acts::jsonKey().mapkey] = false;
0516 bUtility = &(pvMaterial->binUtility());
0517
0518 auto& binningData = bUtility->binningData();
0519 for (std::size_t ibin = 0; ibin < binningData.size(); ++ibin) {
0520 if (binningData[ibin].bins() > 1) {
0521 jMaterial[Acts::jsonKey().mapkey] = true;
0522 break;
0523 }
0524 }
0525
0526 nlohmann::json jBin(*bUtility);
0527 jMaterial[Acts::jsonKey().binkey] = jBin;
0528 j[Acts::jsonKey().materialkey] = jMaterial;
0529 return;
0530 }
0531
0532 auto hvMaterial =
0533 dynamic_cast<const Acts::HomogeneousVolumeMaterial*>(material);
0534 if (hvMaterial != nullptr) {
0535
0536 jMaterial[Acts::jsonKey().typekey] = "homogeneous";
0537 jMaterial[Acts::jsonKey().mapkey] = true;
0538
0539 nlohmann::json jmat(hvMaterial->material({0, 0, 0}));
0540 jMaterial[Acts::jsonKey().datakey] = nlohmann::json::array({
0541 jmat,
0542 });
0543 j[Acts::jsonKey().materialkey] = jMaterial;
0544 return;
0545 }
0546
0547 auto bvMaterial2D = dynamic_cast<const Acts::InterpolatedMaterialMap<
0548 Acts::MaterialMapper<Acts::MaterialGrid2D>>*>(material);
0549
0550 if (bvMaterial2D != nullptr) {
0551
0552 jMaterial[Acts::jsonKey().typekey] = "interpolated2D";
0553 jMaterial[Acts::jsonKey().mapkey] = true;
0554 bUtility = &(bvMaterial2D->binUtility());
0555
0556 nlohmann::json mmat = nlohmann::json::array();
0557 Acts::MaterialGrid2D grid = bvMaterial2D->getMapper().getGrid();
0558 for (std::size_t bin = 0; bin < grid.size(); bin++) {
0559 nlohmann::json jmat(Material(grid.at(bin)));
0560 mmat.push_back(jmat);
0561 }
0562 jMaterial[Acts::jsonKey().datakey] = std::move(mmat);
0563
0564 nlohmann::json jBin(*bUtility);
0565 jMaterial[Acts::jsonKey().binkey] = jBin;
0566 j[Acts::jsonKey().materialkey] = jMaterial;
0567 return;
0568 }
0569
0570 auto bvMaterial3D = dynamic_cast<const Acts::InterpolatedMaterialMap<
0571 Acts::MaterialMapper<Acts::MaterialGrid3D>>*>(material);
0572
0573 if (bvMaterial3D != nullptr) {
0574
0575 jMaterial[Acts::jsonKey().typekey] = "interpolated3D";
0576 jMaterial[Acts::jsonKey().mapkey] = true;
0577 bUtility = &(bvMaterial3D->binUtility());
0578
0579 nlohmann::json mmat = nlohmann::json::array();
0580 Acts::MaterialGrid3D grid = bvMaterial3D->getMapper().getGrid();
0581 for (std::size_t bin = 0; bin < grid.size(); bin++) {
0582 nlohmann::json jmat(Material(grid.at(bin)));
0583 mmat.push_back(jmat);
0584 }
0585 jMaterial[Acts::jsonKey().datakey] = std::move(mmat);
0586
0587 nlohmann::json jBin(*bUtility);
0588 jMaterial[Acts::jsonKey().binkey] = jBin;
0589 j[Acts::jsonKey().materialkey] = jMaterial;
0590 return;
0591 }
0592 }
0593
0594 void Acts::from_json(const nlohmann::json& j, volumeMaterialPointer& material) {
0595 if (j.find(Acts::jsonKey().materialkey) == j.end()) {
0596 return;
0597 }
0598 nlohmann::json jMaterial = j[Acts::jsonKey().materialkey];
0599
0600 material = nullptr;
0601 if (jMaterial[Acts::jsonKey().mapkey] == false) {
0602 return;
0603 }
0604
0605 Acts::BinUtility bUtility;
0606 std::vector<Acts::Material> mmat;
0607 for (auto& [key, value] : jMaterial.items()) {
0608 if (key == Acts::jsonKey().binkey && !value.empty()) {
0609 from_json(value, bUtility);
0610 }
0611 if (key == Acts::jsonKey().datakey && !value.empty()) {
0612 for (const auto& bin : value) {
0613 Acts::Material mat(bin.get<Acts::Material>());
0614 mmat.push_back(mat);
0615 }
0616 }
0617 }
0618
0619 if (mmat.empty()) {
0620 material = new Acts::ProtoVolumeMaterial(bUtility);
0621 return;
0622 }
0623 if (mmat.size() == 1) {
0624 material = new Acts::HomogeneousVolumeMaterial(mmat[0]);
0625 return;
0626 }
0627 if (bUtility.dimensions() == 2) {
0628 std::function<Acts::Vector2(Acts::Vector3)> transfoGlobalToLocal;
0629 Acts::Grid2D grid = createGrid2D(bUtility, transfoGlobalToLocal);
0630
0631 Acts::Grid2D::point_t min = grid.minPosition();
0632 Acts::Grid2D::point_t max = grid.maxPosition();
0633 Acts::Grid2D::index_t nBins = grid.numLocalBins();
0634
0635 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0636 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0637
0638
0639 Acts::MaterialGrid2D mGrid(std::make_tuple(axis1, axis2));
0640
0641 for (std::size_t bin = 0; bin < mmat.size(); bin++) {
0642 mGrid.at(bin) = mmat[bin].parameters();
0643 }
0644 Acts::MaterialMapper<Acts::MaterialGrid2D> matMap(transfoGlobalToLocal,
0645 mGrid);
0646 material = new Acts::InterpolatedMaterialMap<
0647 Acts::MaterialMapper<Acts::MaterialGrid2D>>(std::move(matMap),
0648 bUtility);
0649 return;
0650 }
0651 if (bUtility.dimensions() == 3) {
0652 std::function<Acts::Vector3(Acts::Vector3)> transfoGlobalToLocal;
0653 Acts::Grid3D grid = createGrid3D(bUtility, transfoGlobalToLocal);
0654
0655 Acts::Grid3D::point_t min = grid.minPosition();
0656 Acts::Grid3D::point_t max = grid.maxPosition();
0657 Acts::Grid3D::index_t nBins = grid.numLocalBins();
0658
0659 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0660 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0661 Acts::EAxis axis3(min[2], max[2], nBins[2]);
0662
0663
0664 Acts::MaterialGrid3D mGrid(std::make_tuple(axis1, axis2, axis3));
0665
0666 for (std::size_t bin = 0; bin < mmat.size(); bin++) {
0667 mGrid.at(bin) = mmat[bin].parameters();
0668 }
0669 Acts::MaterialMapper<Acts::MaterialGrid3D> matMap(transfoGlobalToLocal,
0670 mGrid);
0671 material = new Acts::InterpolatedMaterialMap<
0672 Acts::MaterialMapper<Acts::MaterialGrid3D>>(std::move(matMap),
0673 bUtility);
0674 return;
0675 }
0676 }