Skip to content

Commit

Permalink
feat: add json IO for GridAccess delegates (#3047)
Browse files Browse the repository at this point in the history
This PR adds the json IO for the grid access delegates, so that they can be used for writing material files and navigation IO formats.
  • Loading branch information
asalzburger committed Mar 21, 2024
1 parent e9ea680 commit 0982f68
Show file tree
Hide file tree
Showing 3 changed files with 487 additions and 0 deletions.
35 changes: 35 additions & 0 deletions Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "Acts/Plugins/Json/ActsJson.hpp"
#include "Acts/Utilities/GridAccessHelpers.hpp"
#include "Acts/Utilities/IAxis.hpp"
#include "Acts/Utilities/detail/AxisFwd.hpp"

Expand All @@ -35,6 +36,40 @@ nlohmann::json toJsonDetray(const IAxis& ia);

} // namespace AxisJsonConverter

namespace GridAccessJsonConverter {

/// Convert a global to local access to json
///
/// @param globalToGridLocal the global to grid local access
///
/// @return a json object to represent global class
nlohmann::json toJson(const GridAccess::IGlobalToGridLocal& globalToGridLocal);

/// Create a global grid to local instance
///
/// @param jGlobalToGridLocal the json snippet
///
/// @return a newly created object
std::unique_ptr<GridAccess::IGlobalToGridLocal> globalToGridLocalFromJson(
const nlohmann::json& jGlobalToGridLocal);

/// Convert a local to local access to json
///
/// @param boundToGridLocal the local to local access
///
/// @return a json object to represent local class
nlohmann::json toJson(const GridAccess::IBoundToGridLocal& boundToGridLocal);

/// Create a local grid to local instance
///
/// @param jBoundToGridLocal the json snippet
///
/// @return a newly created object
std::unique_ptr<GridAccess::IBoundToGridLocal> boundToGridLocalFromJson(
const nlohmann::json& jBoundToGridLocal);

} // namespace GridAccessJsonConverter

namespace GridJsonConverter {

/// @brief Templated grid conversion to json
Expand Down
257 changes: 257 additions & 0 deletions Plugins/Json/src/GridJsonConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "Acts/Plugins/Json/GridJsonConverter.hpp"

#include "Acts/Plugins/Json/AlgebraJsonConverter.hpp"
#include "Acts/Utilities/IAxis.hpp"

nlohmann::json Acts::AxisJsonConverter::toJson(const IAxis& ia) {
Expand Down Expand Up @@ -42,3 +43,259 @@ nlohmann::json Acts::AxisJsonConverter::toJsonDetray(const IAxis& ia) {
}
return jAxis;
}

namespace {

template <typename Subspace>
void encodeSubspace(
nlohmann::json& jGlobalToGridLocal,
const Acts::GridAccess::IGlobalToGridLocal& globalToGridLocal,
const Subspace& /*unused*/) {
const Subspace* subspace = dynamic_cast<const Subspace*>(&globalToGridLocal);
if (subspace != nullptr) {
jGlobalToGridLocal["type"] = "subspace";
jGlobalToGridLocal["accessors"] = subspace->bValues;
}
}

template <typename Subspace>
void encodeTransformedSubspace(
nlohmann::json& jGlobalToGridLocal,
const Acts::GridAccess::IGlobalToGridLocal& globalToGridLocal,
const Subspace& subscpace) {
const Acts::GridAccess::Affine3Transformed<Subspace>* tsubspace =
dynamic_cast<const Acts::GridAccess::Affine3Transformed<Subspace>*>(
&globalToGridLocal);
if (tsubspace != nullptr) {
encodeSubspace(jGlobalToGridLocal, tsubspace->globalToGridLocal, subscpace);
jGlobalToGridLocal["transform"] =
Acts::Transform3JsonConverter::toJson(tsubspace->transform);
}
}

template <typename... Args>
void encodeSubspaces(
nlohmann::json& jGlobalToGridLocal,
const Acts::GridAccess::IGlobalToGridLocal& globalToGridLocal,
bool transformed, const std::tuple<Args...>& tAcessors) {
if (transformed) {
std::apply(
[&](auto&&... vals) {
(encodeTransformedSubspace(jGlobalToGridLocal, globalToGridLocal,
vals),
...);
},
tAcessors);
} else {
std::apply(
[&](auto&&... vals) {
(encodeSubspace(jGlobalToGridLocal, globalToGridLocal, vals), ...);
},
tAcessors);
}
}

template <Acts::BinningValue... Args>
std::unique_ptr<Acts::GridAccess::IGlobalToGridLocal> decodeSubspace(
const nlohmann::json& jGlobalToGridLocal) {
std::unique_ptr<Acts::GridAccess::IGlobalToGridLocal> globalToGridLocal =
nullptr;
if (jGlobalToGridLocal.find("transform") != jGlobalToGridLocal.end()) {
Acts::Transform3 transform = Acts::Transform3JsonConverter::fromJson(
jGlobalToGridLocal.at("transform"));
Acts::GridAccess::GlobalSubspace<Args...> globalSubspace;
globalToGridLocal = std::make_unique<Acts::GridAccess::Affine3Transformed<
Acts::GridAccess::GlobalSubspace<Args...>>>(std::move(globalSubspace),
transform);
} else {
globalToGridLocal =
std::make_unique<Acts::GridAccess::GlobalSubspace<Args...>>();
}
return globalToGridLocal;
}

} // namespace

nlohmann::json Acts::GridAccessJsonConverter::toJson(
const GridAccess::IGlobalToGridLocal& globalToGridLocal) {
nlohmann::json jGlobalToGridLocal;

std::array<bool, 2u> transformOptions = {false, true};

// One dimensional sub spaces
const std::tuple<
GridAccess::GlobalSubspace<binX>, GridAccess::GlobalSubspace<binY>,
GridAccess::GlobalSubspace<binZ>, GridAccess::GlobalSubspace<binR>,
GridAccess::GlobalSubspace<binPhi>, GridAccess::GlobalSubspace<binEta>>
oneDimSubspaces = {};

for (bool transform : transformOptions) {
encodeSubspaces(jGlobalToGridLocal, globalToGridLocal, transform,
oneDimSubspaces);
if (!jGlobalToGridLocal.empty()) {
return jGlobalToGridLocal;
}
}

// Useful two dimensional sub spaces
const std::tuple<GridAccess::GlobalSubspace<binX, binY>,
GridAccess::GlobalSubspace<binY, binX>,
GridAccess::GlobalSubspace<binX, binZ>,
GridAccess::GlobalSubspace<binZ, binX>,
GridAccess::GlobalSubspace<binY, binZ>,
GridAccess::GlobalSubspace<binZ, binY>,
GridAccess::GlobalSubspace<binR, binPhi>,
GridAccess::GlobalSubspace<binPhi, binR>,
GridAccess::GlobalSubspace<binZ, binPhi>,
GridAccess::GlobalSubspace<binPhi, binZ>>
twoDimSubspaces = {};

for (bool transform : transformOptions) {
encodeSubspaces(jGlobalToGridLocal, globalToGridLocal, transform,
twoDimSubspaces);
if (!jGlobalToGridLocal.empty()) {
return jGlobalToGridLocal;
}
}
return jGlobalToGridLocal;
}

std::unique_ptr<Acts::GridAccess::IGlobalToGridLocal>
Acts::GridAccessJsonConverter::globalToGridLocalFromJson(
const nlohmann::json& jGlobalToGridLocal) {
std::unique_ptr<Acts::GridAccess::IGlobalToGridLocal> globalToGridLocal =
nullptr;

std::vector<BinningValue> accessors =
jGlobalToGridLocal.at("accessors").get<std::vector<BinningValue>>();

// Switch and fill for 1D
if (accessors.size() == 1u) {
switch (accessors[0]) {
case binX:
globalToGridLocal = decodeSubspace<binX>(jGlobalToGridLocal);
break;
case binY:
globalToGridLocal = decodeSubspace<binY>(jGlobalToGridLocal);
break;
case binZ:
globalToGridLocal = decodeSubspace<binZ>(jGlobalToGridLocal);
break;
case binR:
globalToGridLocal = decodeSubspace<binR>(jGlobalToGridLocal);
break;
case binPhi:
globalToGridLocal = decodeSubspace<binPhi>(jGlobalToGridLocal);
break;
case binEta:
globalToGridLocal = decodeSubspace<binEta>(jGlobalToGridLocal);
break;
default:
// globalToGridLocal = nullptr;
break;
}
}

// Switch and fill for 2D
if (accessors.size() == 2u) {
if (accessors == std::vector<BinningValue>{binX, binY}) {
globalToGridLocal = decodeSubspace<binX, binY>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binY, binX}) {
globalToGridLocal = decodeSubspace<binY, binX>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binX, binZ}) {
globalToGridLocal = decodeSubspace<binX, binZ>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binZ, binX}) {
globalToGridLocal = decodeSubspace<binZ, binX>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binY, binZ}) {
globalToGridLocal = decodeSubspace<binY, binZ>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binZ, binY}) {
globalToGridLocal = decodeSubspace<binZ, binY>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binR, binPhi}) {
globalToGridLocal = decodeSubspace<binR, binPhi>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binPhi, binR}) {
globalToGridLocal = decodeSubspace<binPhi, binR>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binZ, binPhi}) {
globalToGridLocal = decodeSubspace<binZ, binPhi>(jGlobalToGridLocal);
} else if (accessors == std::vector<BinningValue>{binPhi, binZ}) {
globalToGridLocal = decodeSubspace<binPhi, binZ>(jGlobalToGridLocal);
}
// else globalToGridLocal = nullptr;
}
return globalToGridLocal;
}

nlohmann::json Acts::GridAccessJsonConverter::toJson(
const GridAccess::IBoundToGridLocal& boundToGridLocal) {
nlohmann::json jBoundtoGridLocal;

auto localSubSpace0 =
dynamic_cast<const GridAccess::LocalSubspace<0u>*>(&boundToGridLocal);
if (localSubSpace0 != nullptr) {
jBoundtoGridLocal["type"] = "subspace";
jBoundtoGridLocal["accessors"] = localSubSpace0->accessors;
}

auto localSubSpace1 =
dynamic_cast<const GridAccess::LocalSubspace<1u>*>(&boundToGridLocal);
if (localSubSpace1 != nullptr) {
jBoundtoGridLocal["type"] = "subspace";
jBoundtoGridLocal["accessors"] = localSubSpace1->accessors;
}

auto localSubSpace01 =
dynamic_cast<const GridAccess::LocalSubspace<0u, 1u>*>(&boundToGridLocal);
if (localSubSpace01 != nullptr) {
jBoundtoGridLocal["type"] = "subspace";
jBoundtoGridLocal["accessors"] = localSubSpace01->accessors;
}

auto localSubSpace10 =
dynamic_cast<const GridAccess::LocalSubspace<1u, 0u>*>(&boundToGridLocal);
if (localSubSpace10 != nullptr) {
jBoundtoGridLocal["type"] = "subspace";
jBoundtoGridLocal["accessors"] = localSubSpace10->accessors;
}

auto boundCylinderToZPhi =
dynamic_cast<const GridAccess::BoundCylinderToZPhi*>(&boundToGridLocal);
if (boundCylinderToZPhi != nullptr) {
jBoundtoGridLocal["type"] = "cylinder_to_zphi";
jBoundtoGridLocal["radius"] = boundCylinderToZPhi->radius;
jBoundtoGridLocal["shift"] = boundCylinderToZPhi->shift;
}

return jBoundtoGridLocal;
}

std::unique_ptr<Acts::GridAccess::IBoundToGridLocal>
Acts::GridAccessJsonConverter::boundToGridLocalFromJson(
const nlohmann::json& jBoundtoGridLocal) {
std::unique_ptr<Acts::GridAccess::IBoundToGridLocal> boundToGridLocal =
nullptr;
std::string type = jBoundtoGridLocal.at("type").get<std::string>();
if (type == "subspace") {
std::vector<std::size_t> accessors =
jBoundtoGridLocal.at("accessors").get<std::vector<std::size_t>>();
if (accessors.size() == 1 && accessors[0] == 0) {
boundToGridLocal =
std::make_unique<Acts::GridAccess::LocalSubspace<0u>>();
} else if (accessors.size() == 1 && accessors[0] == 1) {
boundToGridLocal =
std::make_unique<Acts::GridAccess::LocalSubspace<1u>>();
} else if (accessors.size() == 2 && accessors[0] == 0 &&
accessors[1] == 1) {
boundToGridLocal =
std::make_unique<Acts::GridAccess::LocalSubspace<0u, 1u>>();
} else if (accessors.size() == 2 && accessors[0] == 1 &&
accessors[1] == 0) {
boundToGridLocal =
std::make_unique<Acts::GridAccess::LocalSubspace<1u, 0u>>();
}
} else if (type == "cylinder_to_zphi") {
ActsScalar radius = jBoundtoGridLocal.at("radius").get<ActsScalar>();
ActsScalar shift = jBoundtoGridLocal.at("shift").get<ActsScalar>();
boundToGridLocal =
std::make_unique<Acts::GridAccess::BoundCylinderToZPhi>(radius, shift);
}
return boundToGridLocal;
}

0 comments on commit 0982f68

Please sign in to comment.