File indexing completed on 2025-01-30 09:15:18
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/Geometry/GeometryContext.hpp"
0013 #include "Acts/Material/BinnedSurfaceMaterial.hpp"
0014 #include "Acts/Material/GridSurfaceMaterial.hpp"
0015 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0016 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0017 #include "Acts/Material/ISurfaceMaterial.hpp"
0018 #include "Acts/Material/IVolumeMaterial.hpp"
0019 #include "Acts/Material/InterpolatedMaterialMap.hpp"
0020 #include "Acts/Material/MaterialGridHelper.hpp"
0021 #include "Acts/Material/ProtoSurfaceMaterial.hpp"
0022 #include "Acts/Material/ProtoVolumeMaterial.hpp"
0023 #include "Acts/Plugins/Json/GeometryJsonKeys.hpp"
0024 #include "Acts/Plugins/Json/GridJsonConverter.hpp"
0025 #include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Utilities/BinUtility.hpp"
0028 #include "Acts/Utilities/Grid.hpp"
0029 #include "Acts/Utilities/GridAccessHelpers.hpp"
0030 #include "Acts/Utilities/GridAxisGenerators.hpp"
0031 #include "Acts/Utilities/TypeList.hpp"
0032
0033 #include <algorithm>
0034 #include <cstddef>
0035 #include <functional>
0036 #include <iosfwd>
0037 #include <memory>
0038 #include <numbers>
0039 #include <stdexcept>
0040 #include <string>
0041 #include <tuple>
0042 #include <utility>
0043 #include <vector>
0044
0045 namespace {
0046
0047
0048 template <typename value_type>
0049 using GridEqBound =
0050 Acts::Grid<value_type, Acts::Axis<Acts::AxisType::Equidistant,
0051 Acts::AxisBoundaryType::Bound>>;
0052
0053 template <typename value_type>
0054 using GridEqClosed =
0055 Acts::Grid<value_type, Acts::Axis<Acts::AxisType::Equidistant,
0056 Acts::AxisBoundaryType::Closed>>;
0057
0058
0059 template <typename value_type>
0060 using GridEqBoundEqBound = Acts::Grid<
0061 value_type,
0062 Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Bound>,
0063 Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Bound>>;
0064
0065
0066 template <typename value_type>
0067 using GridEqBoundEqClosed = Acts::Grid<
0068 value_type,
0069 Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Bound>,
0070 Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Closed>>;
0071
0072
0073 template <typename value_type>
0074 using GridEqClosedEqBound = Acts::Grid<
0075 value_type,
0076 Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Closed>,
0077 Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Bound>>;
0078
0079
0080
0081
0082
0083
0084 template <typename indexed_grid_materital_t>
0085 void convertIndexedGridMaterial(
0086 nlohmann::json& jMaterial,
0087 const Acts::ISurfaceMaterial& indexedMaterialCandidate) {
0088
0089 const indexed_grid_materital_t* indexedMaterial =
0090 dynamic_cast<const indexed_grid_materital_t*>(&indexedMaterialCandidate);
0091
0092 if (indexedMaterial != nullptr) {
0093
0094 jMaterial[Acts::jsonKey().typekey] = "grid";
0095 nlohmann::json jMaterialAccessor;
0096
0097 jMaterialAccessor["type"] = "globally_indexed";
0098
0099
0100
0101 const auto& materialAccessor = indexedMaterial->materialAccessor();
0102
0103 if constexpr (std::is_same_v<decltype(materialAccessor),
0104 const Acts::IndexedMaterialAccessor&>) {
0105
0106 jMaterialAccessor["type"] = "indexed";
0107
0108 nlohmann::json jMaterialData;
0109 for (const auto& msl : materialAccessor.material) {
0110 jMaterialData.push_back(msl);
0111 }
0112 jMaterialAccessor["storage_vector"] = jMaterialData;
0113 }
0114
0115 jMaterialAccessor["grid"] =
0116 Acts::GridJsonConverter::toJson(indexedMaterial->grid());
0117 jMaterial["accessor"] = jMaterialAccessor;
0118
0119
0120 jMaterial["global_to_grid_local"] = Acts::GridAccessJsonConverter::toJson(
0121 *(indexedMaterial->globalToGridLocal().instance()));
0122
0123 jMaterial["bound_to_grid_local"] = Acts::GridAccessJsonConverter::toJson(
0124 *(indexedMaterial->boundToGridLocal().instance()));
0125 }
0126 }
0127
0128
0129
0130
0131
0132 template <typename... Args>
0133 void unrollIndexedGridConversion(nlohmann::json& jMaterial,
0134 const Acts::ISurfaceMaterial& indexedMaterial,
0135 Acts::TypeList<Args...> ) {
0136 (convertIndexedGridMaterial<Args>(jMaterial, indexedMaterial), ...);
0137 }
0138
0139 template <typename IndexedAccessorType>
0140 Acts::ISurfaceMaterial* indexedMaterialFromJson(nlohmann::json& jMaterial) {
0141
0142 nlohmann::json jMaterialAccessor = jMaterial["accessor"];
0143
0144
0145 IndexedAccessorType materialAccessor{};
0146
0147
0148 if constexpr (std::is_same_v<IndexedAccessorType,
0149 Acts::IndexedMaterialAccessor>) {
0150
0151 for (const auto& msl : jMaterialAccessor["storage_vector"]) {
0152 materialAccessor.material.push_back(msl);
0153 }
0154 }
0155
0156
0157 nlohmann::json jGrid = jMaterialAccessor["grid"];
0158 nlohmann::json jGridAxes = jGrid["axes"];
0159
0160 Acts::AxisBoundaryType boundaryType0 = jGridAxes[0]["boundary_type"];
0161
0162
0163 if (jGridAxes.size() == 1u) {
0164
0165 if (boundaryType0 == Acts::AxisBoundaryType::Bound) {
0166 Acts::GridAxisGenerators::EqBound eqBound{jGridAxes[0]["range"],
0167 jGridAxes[0]["bins"]};
0168 auto grid =
0169 Acts::GridJsonConverter::fromJson<decltype(eqBound), std::size_t>(
0170 jGrid, eqBound);
0171
0172 auto boundToGridLocal =
0173 Acts::GridAccessJsonConverter::boundToGridLocal1DimDelegateFromJson(
0174 jMaterial["bound_to_grid_local"]);
0175
0176 auto globalToGridLocal =
0177 Acts::GridAccessJsonConverter::globalToGridLocal1DimDelegateFromJson(
0178 jMaterial["global_to_grid_local"]);
0179
0180 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0181 std::move(grid), std::move(materialAccessor),
0182 std::move(boundToGridLocal), std::move(globalToGridLocal));
0183 }
0184
0185 if (boundaryType0 == Acts::AxisBoundaryType::Closed) {
0186 Acts::GridAxisGenerators::EqClosed eqClosed{jGridAxes[0]["range"],
0187 jGridAxes[0]["bins"]};
0188 auto grid =
0189 Acts::GridJsonConverter::fromJson<decltype(eqClosed), std::size_t>(
0190 jGrid, eqClosed);
0191
0192 auto boundToGridLocal =
0193 Acts::GridAccessJsonConverter::boundToGridLocal1DimDelegateFromJson(
0194 jMaterial["bound_to_grid_local"]);
0195
0196 auto globalToGridLocal =
0197 Acts::GridAccessJsonConverter::globalToGridLocal1DimDelegateFromJson(
0198 jMaterial["global_to_grid_local"]);
0199
0200 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0201 std::move(grid), std::move(materialAccessor),
0202 std::move(boundToGridLocal), std::move(globalToGridLocal));
0203 }
0204 }
0205
0206
0207 if (jGridAxes.size() == 2u) {
0208
0209 Acts::AxisBoundaryType boundaryType1 = jGridAxes[1]["boundary_type"];
0210
0211
0212 if (boundaryType0 == Acts::AxisBoundaryType::Bound &&
0213 boundaryType1 == Acts::AxisBoundaryType::Bound) {
0214 Acts::GridAxisGenerators::EqBoundEqBound eqBoundEqBound{
0215 jGridAxes[0]["range"], jGridAxes[0]["bins"], jGridAxes[1]["range"],
0216 jGridAxes[1]["bins"]};
0217 auto grid =
0218 Acts::GridJsonConverter::fromJson<decltype(eqBoundEqBound),
0219 std::size_t>(jGrid, eqBoundEqBound);
0220
0221 auto boundToGridLocal =
0222 Acts::GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0223 jMaterial["bound_to_grid_local"]);
0224
0225 auto globalToGridLocal =
0226 Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(
0227 jMaterial["global_to_grid_local"]);
0228
0229 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0230 std::move(grid), std::move(materialAccessor),
0231 std::move(boundToGridLocal), std::move(globalToGridLocal));
0232 }
0233
0234
0235 if (boundaryType0 == Acts::AxisBoundaryType::Bound &&
0236 boundaryType1 == Acts::AxisBoundaryType::Closed) {
0237 Acts::GridAxisGenerators::EqBoundEqClosed eqBoundEqClosed{
0238 jGridAxes[0]["range"], jGridAxes[0]["bins"], jGridAxes[1]["range"],
0239 jGridAxes[1]["bins"]};
0240 auto grid = Acts::GridJsonConverter::fromJson<decltype(eqBoundEqClosed),
0241 std::size_t>(
0242 jGrid, eqBoundEqClosed);
0243
0244 auto boundToGridLocal =
0245 Acts::GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0246 jMaterial["bound_to_grid_local"]);
0247
0248 auto globalToGridLocal =
0249 Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(
0250 jMaterial["global_to_grid_local"]);
0251
0252 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0253 std::move(grid), std::move(materialAccessor),
0254 std::move(boundToGridLocal), std::move(globalToGridLocal));
0255 }
0256
0257
0258 if (boundaryType0 == Acts::AxisBoundaryType::Closed &&
0259 boundaryType1 == Acts::AxisBoundaryType::Bound) {
0260 Acts::GridAxisGenerators::EqClosedEqBound eqClosedEqBound{
0261 jGridAxes[0]["range"], jGridAxes[0]["bins"], jGridAxes[1]["range"],
0262 jGridAxes[1]["bins"]};
0263 auto grid = Acts::GridJsonConverter::fromJson<decltype(eqClosedEqBound),
0264 std::size_t>(
0265 jGrid, eqClosedEqBound);
0266
0267 auto boundToGridLocal =
0268 Acts::GridAccessJsonConverter::boundToGridLocal2DimDelegateFromJson(
0269 jMaterial["bound_to_grid_local"]);
0270
0271 auto globalToGridLocal =
0272 Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson(
0273 jMaterial["global_to_grid_local"]);
0274
0275 return new Acts::IndexedSurfaceMaterial<decltype(grid)>(
0276 std::move(grid), std::move(materialAccessor),
0277 std::move(boundToGridLocal), std::move(globalToGridLocal));
0278 }
0279 }
0280
0281 return nullptr;
0282 }
0283
0284 }
0285
0286 void Acts::to_json(nlohmann::json& j, const Material& t) {
0287 if (!t.isValid()) {
0288 return;
0289 }
0290 for (unsigned i = 0; i < t.parameters().size(); ++i) {
0291 j.push_back(t.parameters()[i]);
0292 }
0293 }
0294
0295 void Acts::from_json(const nlohmann::json& j, Material& t) {
0296 if (j.is_null()) {
0297 return;
0298 }
0299 Acts::Material::ParametersVector params =
0300 Acts::Material::ParametersVector::Zero();
0301 for (auto i = params.size(); 0 < i--;) {
0302
0303 params[i] = j.at(i);
0304 }
0305 t = Acts::Material(params);
0306 return;
0307 }
0308
0309 void Acts::to_json(nlohmann::json& j, const MaterialSlab& t) {
0310 nlohmann::json jmat(t.material());
0311 j["material"] = jmat;
0312 j["thickness"] = t.thickness();
0313 }
0314
0315 void Acts::from_json(const nlohmann::json& j, MaterialSlab& t) {
0316 Material mat(j["material"].get<Material>());
0317 t = Acts::MaterialSlab(mat, j.at("thickness").get<float>());
0318 }
0319
0320 void Acts::from_json(const nlohmann::json& j, MaterialSlabMatrix& t) {
0321
0322 for (auto& outer : j) {
0323 Acts::MaterialSlabVector mpVector;
0324 for (auto& inner : outer) {
0325 MaterialSlab mat = inner.get<MaterialSlab>();
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 auto psMaterial = dynamic_cast<const Acts::ProtoSurfaceMaterial*>(material);
0339 if (psMaterial != nullptr) {
0340
0341 jMaterial[Acts::jsonKey().typekey] = "proto";
0342
0343 nlohmann::json mapType(material->mappingType());
0344 jMaterial[Acts::jsonKey().maptype] = mapType;
0345
0346 jMaterial[Acts::jsonKey().mapkey] = false;
0347
0348 bUtility = &(psMaterial->binning());
0349
0350 auto& binningData = bUtility->binningData();
0351 for (std::size_t ibin = 0; ibin < binningData.size(); ++ibin) {
0352 if (binningData[ibin].bins() > 1) {
0353 jMaterial[Acts::jsonKey().mapkey] = true;
0354 break;
0355 }
0356 }
0357 nlohmann::json jBin(*bUtility);
0358 jMaterial[Acts::jsonKey().binkey] = jBin;
0359 j[Acts::jsonKey().materialkey] = jMaterial;
0360 return;
0361 }
0362
0363
0364 auto hsMaterial =
0365 dynamic_cast<const Acts::HomogeneousSurfaceMaterial*>(material);
0366 if (hsMaterial != nullptr) {
0367
0368 jMaterial[Acts::jsonKey().typekey] = "homogeneous";
0369
0370 nlohmann::json mapType(material->mappingType());
0371 jMaterial[Acts::jsonKey().maptype] = mapType;
0372
0373 jMaterial[Acts::jsonKey().mapkey] = true;
0374 nlohmann::json jmat(hsMaterial->materialSlab(Acts::Vector3(0., 0., 0.)));
0375 jMaterial[Acts::jsonKey().datakey] = nlohmann::json::array({
0376 nlohmann::json::array({
0377 jmat,
0378 }),
0379 });
0380 j[Acts::jsonKey().materialkey] = jMaterial;
0381 return;
0382 }
0383
0384
0385 auto bsMaterial = dynamic_cast<const Acts::BinnedSurfaceMaterial*>(material);
0386 if (bsMaterial != nullptr) {
0387
0388 jMaterial[Acts::jsonKey().typekey] = "binned";
0389
0390 nlohmann::json mapType(material->mappingType());
0391 jMaterial[Acts::jsonKey().maptype] = mapType;
0392
0393 jMaterial[Acts::jsonKey().mapkey] = true;
0394 bUtility = &(bsMaterial->binUtility());
0395
0396
0397 nlohmann::json mmat = nlohmann::json::array();
0398 for (const auto& mpVector : bsMaterial->fullMaterial()) {
0399 nlohmann::json mvec = nlohmann::json::array();
0400 for (const auto& mp : mpVector) {
0401 nlohmann::json jmat(mp);
0402 mvec.push_back(jmat);
0403 }
0404 mmat.push_back(std::move(mvec));
0405 }
0406 jMaterial[Acts::jsonKey().datakey] = std::move(mmat);
0407
0408 nlohmann::json jBin(*bUtility);
0409 jMaterial[Acts::jsonKey().binkey] = jBin;
0410 j[Acts::jsonKey().materialkey] = jMaterial;
0411 return;
0412 }
0413
0414
0415 using IndexedSurfaceGrids = Acts::TypeList<
0416 Acts::IndexedSurfaceMaterial<GridEqBound<std::size_t>>,
0417 Acts::IndexedSurfaceMaterial<GridEqClosed<std::size_t>>,
0418 Acts::IndexedSurfaceMaterial<GridEqBoundEqBound<std::size_t>>,
0419 Acts::IndexedSurfaceMaterial<GridEqBoundEqClosed<std::size_t>>,
0420 Acts::IndexedSurfaceMaterial<GridEqClosedEqBound<std::size_t>>>;
0421
0422 unrollIndexedGridConversion(jMaterial, *material, IndexedSurfaceGrids{});
0423 if (!jMaterial.empty()) {
0424 j[Acts::jsonKey().materialkey] = jMaterial;
0425 return;
0426 }
0427
0428
0429 using GloballyIndexedSurfaceGrids = Acts::TypeList<
0430 Acts::GloballyIndexedSurfaceMaterial<GridEqBound<std::size_t>>,
0431 Acts::GloballyIndexedSurfaceMaterial<GridEqClosed<std::size_t>>,
0432 Acts::GloballyIndexedSurfaceMaterial<GridEqBoundEqBound<std::size_t>>,
0433 Acts::GloballyIndexedSurfaceMaterial<GridEqBoundEqClosed<std::size_t>>,
0434 Acts::GloballyIndexedSurfaceMaterial<GridEqClosedEqBound<std::size_t>>>;
0435
0436 unrollIndexedGridConversion(jMaterial, *material,
0437 GloballyIndexedSurfaceGrids{});
0438 if (!jMaterial.empty()) {
0439 j[Acts::jsonKey().materialkey] = jMaterial;
0440 return;
0441 }
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452 return;
0453 }
0454
0455 void Acts::from_json(const nlohmann::json& j,
0456 surfaceMaterialPointer& material) {
0457 if (j.find(Acts::jsonKey().materialkey) == j.end()) {
0458 return;
0459 }
0460 nlohmann::json jMaterial = j[Acts::jsonKey().materialkey];
0461
0462 material = nullptr;
0463 if (jMaterial[Acts::jsonKey().mapkey] == false) {
0464 return;
0465 }
0466
0467
0468 if (jMaterial[Acts::jsonKey().typekey] == "grid") {
0469 material =
0470 indexedMaterialFromJson<Acts::IndexedMaterialAccessor>(jMaterial);
0471 return;
0472 }
0473
0474
0475 Acts::BinUtility bUtility;
0476 Acts::MaterialSlabMatrix mpMatrix;
0477 Acts::MappingType mapType = Acts::MappingType::Default;
0478 for (auto& [key, value] : jMaterial.items()) {
0479 if (key == Acts::jsonKey().binkey && !value.empty()) {
0480 from_json(value, bUtility);
0481 }
0482 if (key == Acts::jsonKey().datakey && !value.empty()) {
0483 from_json(value, mpMatrix);
0484 }
0485 if (key == Acts::jsonKey().maptype && !value.empty()) {
0486 from_json(value, mapType);
0487 }
0488 }
0489
0490 if (mpMatrix.empty()) {
0491 material = new Acts::ProtoSurfaceMaterial(bUtility, mapType);
0492 } else if (bUtility.bins() == 1) {
0493 material = new Acts::HomogeneousSurfaceMaterial(mpMatrix[0][0], mapType);
0494 } else {
0495 material = new Acts::BinnedSurfaceMaterial(bUtility, mpMatrix, mapType);
0496 }
0497 }
0498
0499 void Acts::to_json(nlohmann::json& j, const volumeMaterialPointer& material) {
0500 nlohmann::json jMaterial;
0501
0502 const Acts::BinUtility* bUtility = nullptr;
0503
0504 auto pvMaterial = dynamic_cast<const Acts::ProtoVolumeMaterial*>(material);
0505 if (pvMaterial != nullptr) {
0506
0507 jMaterial[Acts::jsonKey().typekey] = "proto";
0508
0509 jMaterial[Acts::jsonKey().mapkey] = false;
0510 bUtility = &(pvMaterial->binUtility());
0511
0512 auto& binningData = bUtility->binningData();
0513 for (std::size_t ibin = 0; ibin < binningData.size(); ++ibin) {
0514 if (binningData[ibin].bins() > 1) {
0515 jMaterial[Acts::jsonKey().mapkey] = true;
0516 break;
0517 }
0518 }
0519
0520 nlohmann::json jBin(*bUtility);
0521 jMaterial[Acts::jsonKey().binkey] = jBin;
0522 j[Acts::jsonKey().materialkey] = jMaterial;
0523 return;
0524 }
0525
0526 auto hvMaterial =
0527 dynamic_cast<const Acts::HomogeneousVolumeMaterial*>(material);
0528 if (hvMaterial != nullptr) {
0529
0530 jMaterial[Acts::jsonKey().typekey] = "homogeneous";
0531 jMaterial[Acts::jsonKey().mapkey] = true;
0532
0533 nlohmann::json jmat(hvMaterial->material({0, 0, 0}));
0534 jMaterial[Acts::jsonKey().datakey] = nlohmann::json::array({
0535 jmat,
0536 });
0537 j[Acts::jsonKey().materialkey] = jMaterial;
0538 return;
0539 }
0540
0541 auto bvMaterial2D = dynamic_cast<const Acts::InterpolatedMaterialMap<
0542 Acts::MaterialMapper<Acts::MaterialGrid2D>>*>(material);
0543
0544 if (bvMaterial2D != nullptr) {
0545
0546 jMaterial[Acts::jsonKey().typekey] = "interpolated2D";
0547 jMaterial[Acts::jsonKey().mapkey] = true;
0548 bUtility = &(bvMaterial2D->binUtility());
0549
0550 nlohmann::json mmat = nlohmann::json::array();
0551 Acts::MaterialGrid2D grid = bvMaterial2D->getMapper().getGrid();
0552 for (std::size_t bin = 0; bin < grid.size(); bin++) {
0553 nlohmann::json jmat(Material(grid.at(bin)));
0554 mmat.push_back(jmat);
0555 }
0556 jMaterial[Acts::jsonKey().datakey] = std::move(mmat);
0557
0558 nlohmann::json jBin(*bUtility);
0559 jMaterial[Acts::jsonKey().binkey] = jBin;
0560 j[Acts::jsonKey().materialkey] = jMaterial;
0561 return;
0562 }
0563
0564 auto bvMaterial3D = dynamic_cast<const Acts::InterpolatedMaterialMap<
0565 Acts::MaterialMapper<Acts::MaterialGrid3D>>*>(material);
0566
0567 if (bvMaterial3D != nullptr) {
0568
0569 jMaterial[Acts::jsonKey().typekey] = "interpolated3D";
0570 jMaterial[Acts::jsonKey().mapkey] = true;
0571 bUtility = &(bvMaterial3D->binUtility());
0572
0573 nlohmann::json mmat = nlohmann::json::array();
0574 Acts::MaterialGrid3D grid = bvMaterial3D->getMapper().getGrid();
0575 for (std::size_t bin = 0; bin < grid.size(); bin++) {
0576 nlohmann::json jmat(Material(grid.at(bin)));
0577 mmat.push_back(jmat);
0578 }
0579 jMaterial[Acts::jsonKey().datakey] = std::move(mmat);
0580
0581 nlohmann::json jBin(*bUtility);
0582 jMaterial[Acts::jsonKey().binkey] = jBin;
0583 j[Acts::jsonKey().materialkey] = jMaterial;
0584 return;
0585 }
0586 }
0587
0588 void Acts::from_json(const nlohmann::json& j, volumeMaterialPointer& material) {
0589 if (j.find(Acts::jsonKey().materialkey) == j.end()) {
0590 return;
0591 }
0592 nlohmann::json jMaterial = j[Acts::jsonKey().materialkey];
0593
0594 material = nullptr;
0595 if (jMaterial[Acts::jsonKey().mapkey] == false) {
0596 return;
0597 }
0598
0599 Acts::BinUtility bUtility;
0600 std::vector<Acts::Material> mmat;
0601 for (auto& [key, value] : jMaterial.items()) {
0602 if (key == Acts::jsonKey().binkey && !value.empty()) {
0603 from_json(value, bUtility);
0604 }
0605 if (key == Acts::jsonKey().datakey && !value.empty()) {
0606 for (const auto& bin : value) {
0607 Acts::Material mat(bin.get<Acts::Material>());
0608 mmat.push_back(mat);
0609 }
0610 }
0611 }
0612
0613 if (mmat.empty()) {
0614 material = new Acts::ProtoVolumeMaterial(bUtility);
0615 return;
0616 }
0617 if (mmat.size() == 1) {
0618 material = new Acts::HomogeneousVolumeMaterial(mmat[0]);
0619 return;
0620 }
0621 if (bUtility.dimensions() == 2) {
0622 std::function<Acts::Vector2(Acts::Vector3)> transfoGlobalToLocal;
0623 Acts::Grid2D grid = createGrid2D(bUtility, transfoGlobalToLocal);
0624
0625 Acts::Grid2D::point_t min = grid.minPosition();
0626 Acts::Grid2D::point_t max = grid.maxPosition();
0627 Acts::Grid2D::index_t nBins = grid.numLocalBins();
0628
0629 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0630 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0631
0632
0633 Acts::MaterialGrid2D mGrid(std::make_tuple(axis1, axis2));
0634
0635 for (std::size_t bin = 0; bin < mmat.size(); bin++) {
0636 mGrid.at(bin) = mmat[bin].parameters();
0637 }
0638 Acts::MaterialMapper<Acts::MaterialGrid2D> matMap(transfoGlobalToLocal,
0639 mGrid);
0640 material = new Acts::InterpolatedMaterialMap<
0641 Acts::MaterialMapper<Acts::MaterialGrid2D>>(std::move(matMap),
0642 bUtility);
0643 return;
0644 }
0645 if (bUtility.dimensions() == 3) {
0646 std::function<Acts::Vector3(Acts::Vector3)> transfoGlobalToLocal;
0647 Acts::Grid3D grid = createGrid3D(bUtility, transfoGlobalToLocal);
0648
0649 Acts::Grid3D::point_t min = grid.minPosition();
0650 Acts::Grid3D::point_t max = grid.maxPosition();
0651 Acts::Grid3D::index_t nBins = grid.numLocalBins();
0652
0653 Acts::EAxis axis1(min[0], max[0], nBins[0]);
0654 Acts::EAxis axis2(min[1], max[1], nBins[1]);
0655 Acts::EAxis axis3(min[2], max[2], nBins[2]);
0656
0657
0658 Acts::MaterialGrid3D mGrid(std::make_tuple(axis1, axis2, axis3));
0659
0660 for (std::size_t bin = 0; bin < mmat.size(); bin++) {
0661 mGrid.at(bin) = mmat[bin].parameters();
0662 }
0663 Acts::MaterialMapper<Acts::MaterialGrid3D> matMap(transfoGlobalToLocal,
0664 mGrid);
0665 material = new Acts::InterpolatedMaterialMap<
0666 Acts::MaterialMapper<Acts::MaterialGrid3D>>(std::move(matMap),
0667 bUtility);
0668 return;
0669 }
0670 }
0671
0672 nlohmann::json Acts::MaterialJsonConverter::toJsonDetray(
0673 const Acts::ISurfaceMaterial& surfaceMaterial, const Acts::Surface& surface,
0674 std::size_t surfaceIndex, std::map<std::size_t, std::size_t>& gridLink) {
0675 nlohmann::json jSurfaceMaterial;
0676
0677
0678 if (auto binnedMaterial =
0679 dynamic_cast<const BinnedSurfaceMaterial*>(&surfaceMaterial);
0680 binnedMaterial != nullptr) {
0681
0682 bool swapped = false;
0683
0684
0685
0686 BinUtility bUtility = binnedMaterial->binUtility();
0687
0688 if (bUtility.dimensions() == 1u) {
0689 if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisR) {
0690
0691 bUtility += BinUtility(1u, -std::numbers::pi, std::numbers::pi, closed,
0692 AxisDirection::AxisPhi);
0693 } else if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisZ) {
0694
0695 BinUtility nbUtility(1u, -std::numbers::pi, std::numbers::pi, closed,
0696 AxisDirection::AxisPhi);
0697 nbUtility += bUtility;
0698 bUtility = std::move(nbUtility);
0699 swapped = true;
0700 } else {
0701 std::runtime_error("Unsupported binning for Detray");
0702 }
0703 } else if (bUtility.dimensions() == 2u &&
0704 bUtility.binningData()[0u].binvalue == AxisDirection::AxisZ &&
0705 bUtility.binningData()[1u].binvalue == AxisDirection::AxisPhi) {
0706 BinUtility nbUtility(bUtility.binningData()[1u]);
0707 nbUtility += BinUtility{bUtility.binningData()[0u]};
0708 bUtility = std::move(nbUtility);
0709 swapped = true;
0710 }
0711
0712 AxisDirection bVal0 = bUtility.binningData()[0u].binvalue;
0713 AxisDirection bVal1 = bUtility.binningData()[1u].binvalue;
0714
0715
0716 int gridIndexType = 0;
0717 if (bVal0 == AxisDirection::AxisR && bVal1 == AxisDirection::AxisPhi) {
0718 gridIndexType = 0;
0719 } else if (bVal0 == AxisDirection::AxisPhi &&
0720 bVal1 == AxisDirection::AxisZ) {
0721 gridIndexType = 3;
0722 } else if (bVal0 == AxisDirection::AxisX && bVal1 == AxisDirection::AxisY) {
0723 gridIndexType = 2;
0724 } else {
0725 std::runtime_error("Unsupported binning for Detray");
0726 }
0727
0728 nlohmann::json jAxes = toJsonDetray(bUtility, surface);
0729
0730 nlohmann::json jGridLink;
0731 jGridLink["type"] = gridIndexType;
0732 std::size_t gridIndex = 0;
0733 if (gridLink.contains(gridIndexType)) {
0734 std::size_t& fGridIndex = gridLink[gridIndex];
0735 gridIndex = fGridIndex;
0736 fGridIndex++;
0737 } else {
0738 gridLink[gridIndexType] = 1;
0739 }
0740 jGridLink["index"] = gridIndex;
0741
0742
0743 jSurfaceMaterial["axes"] = jAxes;
0744 jSurfaceMaterial["grid_link"] = jGridLink;
0745 jSurfaceMaterial["owner_link"] = surfaceIndex;
0746
0747
0748 nlohmann::json jBins;
0749 auto materialMatrix = binnedMaterial->fullMaterial();
0750 for (std::size_t ib1 = 0; ib1 < materialMatrix.size(); ++ib1) {
0751 for (std::size_t ib0 = 0; ib0 < materialMatrix[0u].size(); ++ib0) {
0752 nlohmann::json jBin;
0753
0754 MaterialSlab slab = materialMatrix[ib1][ib0];
0755
0756 std::size_t lb0 = swapped ? ib1 : ib0;
0757 std::size_t lb1 = swapped ? ib0 : ib1;
0758 jBin["loc_index"] = std::array<std::size_t, 2u>{lb0, lb1};
0759
0760 const Material& material = slab.material();
0761
0762 nlohmann::json jContent;
0763 jContent["thickness"] = slab.thickness();
0764
0765 nlohmann::json jMaterialParams;
0766 if (slab.thickness() > 0.) {
0767 jMaterialParams["params"] =
0768 std::vector<double>{material.X0(),
0769 material.L0(),
0770 material.Ar(),
0771 material.Z(),
0772 material.massDensity(),
0773 material.molarDensity(),
0774 0.};
0775
0776 } else {
0777 jMaterialParams["params"] =
0778 std::vector<double>{0., 0., 0., 0., 0., 0., 0.};
0779 }
0780 jContent["material"] = jMaterialParams;
0781 jContent["type"] = 6;
0782 jContent["surface_idx"] = surfaceIndex;
0783
0784 nlohmann::json jContentVector;
0785 jContentVector.push_back(jContent);
0786 jBin["content"] = jContentVector;
0787 jBins.push_back(jBin);
0788 }
0789 }
0790 jSurfaceMaterial["bins"] = jBins;
0791 }
0792 return jSurfaceMaterial;
0793 }
0794
0795 nlohmann::json Acts::MaterialJsonConverter::toJsonDetray(
0796 const Acts::BinUtility& binUtility, const Surface& surface) {
0797 nlohmann::json jAxes;
0798 for (const auto [ib, bData] : enumerate(binUtility.binningData())) {
0799 nlohmann::json jAxis;
0800 jAxis["bounds"] = bData.option == closed ? 2 : 1;
0801 jAxis["binning"] = 0u;
0802 jAxis["label"] = ib;
0803 jAxis["bins"] = bData.bins();
0804 double offset = 0;
0805 if (bData.binvalue == AxisDirection::AxisZ) {
0806 offset = surface.center(Acts::GeometryContext{}).z();
0807 }
0808 jAxis["edges"] =
0809 std::array<double, 2>{bData.min + offset, bData.max + offset};
0810 jAxes.push_back(jAxis);
0811 }
0812 return jAxes;
0813 }