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