Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Optionally decorate geometry dumps to json. #1732

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Examples/Io/Json/src/JsonDigitizationConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ void ActsExamples::writeDigiConfigToJson(
std::ofstream outfile(path, std::ofstream::out | std::ofstream::binary);
// rely on exception for error handling
outfile.exceptions(std::ofstream::failbit | std::ofstream::badbit);
outfile
<< DigiConfigConverter("digitization-configuration").toJson(cfg).dump(2);
outfile << DigiConfigConverter("digitization-configuration")
.toJson(cfg, nullptr)
.dump(2);
}
6 changes: 3 additions & 3 deletions Examples/Io/Json/src/JsonSurfacesWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ ProcessCode JsonSurfacesWriter::write(const AlgorithmContext& ctx) {
SurfaceContainer sContainer(cSurfaces);

if (not m_cfg.writeOnlyNames) {
auto j = SurfaceConverter("surfaces").toJson(sContainer);
auto j = SurfaceConverter("surfaces").toJson(sContainer, nullptr);
out << std::setprecision(m_cfg.outputPrecision) << j.dump(2);
out.close();
} else {
Expand All @@ -127,7 +127,7 @@ ProcessCode JsonSurfacesWriter::write(const AlgorithmContext& ctx) {
namedEntries.push_back({geometryId, geoTypeName.str()});
}
NamedContainer nContainer(namedEntries);
auto j = NamedConverter("surface_types").toJson(nContainer);
auto j = NamedConverter("surface_types").toJson(nContainer, nullptr);
out << j.dump(2);
out.close();
}
Expand All @@ -144,7 +144,7 @@ ProcessCode JsonSurfacesWriter::endRun() {
m_cfg.writeSensitive, m_cfg.writeBoundary);
SurfaceContainer sContainer(cSurfaces);

auto j = SurfaceConverter("surfaces").toJson(sContainer);
auto j = SurfaceConverter("surfaces").toJson(sContainer, nullptr);
out << std::setprecision(m_cfg.outputPrecision) << j.dump(2);
out.close();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of the Acts project.
//
// Copyright (C) 2020-2021 CERN for the benefit of the Acts project
// Copyright (C) 2020-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -13,7 +13,7 @@

#include <stdexcept>
#include <string>

#include <type_traits>
namespace Acts {

/// Convert a geometry hierarchy map to/from Json.
Expand All @@ -31,7 +31,8 @@ namespace Acts {
/// checked for consistency when decoding the Json object.
///
/// [1]: https://nlohmann.github.io/json/features/arbitrary_types/
template <typename value_t>
template <typename value_t,
class decorator_t = void /* e.g. ITrackingGeometryJsonDecorator */>
class GeometryHierarchyMapJsonConverter {
public:
using Value = value_t;
Expand All @@ -50,8 +51,11 @@ class GeometryHierarchyMapJsonConverter {
/// Encode the geometry hierarchy map into a Json object.
///
/// @param container Geometry hierarchy map that should be encoded
/// @param decorator nullptr or a decorator to add extra values to the json
/// output
/// @return Encoded Json object
nlohmann::json toJson(const Container& container) const;
nlohmann::json toJson(const Container& container,
const decorator_t* decorator) const;
goetzgaycken marked this conversation as resolved.
Show resolved Hide resolved

/// Decode a Json object into a geometry hierarchy map.
///
Expand Down Expand Up @@ -105,9 +109,35 @@ class GeometryHierarchyMapJsonConverter {

// implementations

template <typename value_t>
nlohmann::json GeometryHierarchyMapJsonConverter<value_t>::toJson(
const Container& container) const {
// auxiliary struct to indicate a missing specialization of a template which
// requires specialisation
template <typename T, class decorator_t>
struct missing_specialization : std::false_type {};

// methods to adapt type decorations for the given decorator
template <class T, class decorator_t>
void decorateJson([[maybe_unused]] const decorator_t* decorator,
[[maybe_unused]] const T& src,
[[maybe_unused]] nlohmann::json& dest) {
// this needs to be specialised
static_assert(
missing_specialization<T, decorator_t>::value,
"Explicit specialization needed for each decorator_t and src T");
}
template <class T, class decorator_t>
void decorateJson([[maybe_unused]] const decorator_t* decorator,
[[maybe_unused]] const T* src,
[[maybe_unused]] nlohmann::json& dest) {
// this needs to be specialised
static_assert(
missing_specialization<T, decorator_t>::value,
"Explicit specialization needed for each decorator_t and src T");
}

template <typename value_t, class decorator_t>
nlohmann::json GeometryHierarchyMapJsonConverter<value_t, decorator_t>::toJson(
const Container& container,
[[maybe_unused]] const decorator_t* decorator) const {
// encode header
nlohmann::json encoded = nlohmann::json::object();
encoded[kHeaderKey] = nlohmann::json::object();
Expand All @@ -117,15 +147,19 @@ nlohmann::json GeometryHierarchyMapJsonConverter<value_t>::toJson(
nlohmann::json entries = nlohmann::json::array();
for (std::size_t i = 0; i < container.size(); ++i) {
auto entry = encodeIdentifier(container.idAt(i));
entry["value"] = nlohmann::json(container.valueAt(i));
auto value_json = nlohmann::json(container.valueAt(i));
if constexpr (not std::is_same<decorator_t, void>::value) {
goetzgaycken marked this conversation as resolved.
Show resolved Hide resolved
decorateJson(decorator, container.valueAt(i), value_json);
}
entry["value"] = std::move(value_json);
entries.push_back(std::move(entry));
}
encoded[kEntriesKey] = std::move(entries);
return encoded;
}

template <typename value_t>
auto GeometryHierarchyMapJsonConverter<value_t>::fromJson(
template <typename value_t, class decorator_t>
auto GeometryHierarchyMapJsonConverter<value_t, decorator_t>::fromJson(
const nlohmann::json& encoded) const -> Container {
// verify json format header
auto header = encoded.find(kHeaderKey);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// This file is part of the Acts project.
//
// Copyright (C) 2017-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

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

namespace Acts {
class TrackingVolume;
class Surface;

/// helper class to add extra informtion to surface or volume json objects
class ITrackingGeometryJsonDecorator {
public:
virtual ~ITrackingGeometryJsonDecorator() = default;

/// Add extra elements to the json object already filled for the given
/// surface
///
/// @param surface the surface which was used to fill the json object
/// @param json the json object that is enhanced
virtual void decorate(const Acts::Surface &surface,
nlohmann::json &json) const = 0;

/// Add extra elements to the json object already filled for the given
/// volume
///
/// @param volume the volume which was used to fill the json object
/// @param json the json object that is enhanced
virtual void decorate(const Acts::TrackingVolume &volume,
nlohmann::json &json) const = 0;
};
} // namespace Acts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// This file is part of the Acts project.
//
// Copyright (C) 2017-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

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

namespace Acts {
class ISurfaceMaterial;
class IVolumeMaterial;

/// helper class to add extra informtion to surface or volume json objects
class IVolumeMaterialJsonDecorator {
public:
virtual ~IVolumeMaterialJsonDecorator() = default;

/// Add extra elements to the json object already filled for the given
/// surface material
///
/// @param material the surface material which was used to
/// fill the json object
/// @param json the json object that is enhanced
virtual void decorate(const Acts::ISurfaceMaterial &material,
nlohmann::json &json) const = 0;

/// Add extra elements to the json object already filled for the given
/// volume material
///
/// @param material the volume material which was used to
/// fill the json object
/// @param json the json object that is enhanced
virtual void decorate(const Acts::IVolumeMaterial &material,
nlohmann::json &json) const = 0;
};
} // namespace Acts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of the Acts project.
//
// Copyright (C) 2017-2021 CERN for the benefit of the Acts project
// Copyright (C) 2017-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -13,6 +13,8 @@
#include "Acts/Material/IVolumeMaterial.hpp"
#include "Acts/Plugins/Json/ActsJson.hpp"
#include "Acts/Plugins/Json/GeometryHierarchyMapJsonConverter.hpp"
#include "Acts/Plugins/Json/ITrackingGeometryJsonDecorator.hpp"
#include "Acts/Plugins/Json/IVolumeMaterialJsonDecorator.hpp"
#include "Acts/Utilities/Logger.hpp"
#include <Acts/Geometry/TrackingVolume.hpp>
#include <Acts/Surfaces/Surface.hpp>
Expand Down Expand Up @@ -81,13 +83,19 @@ class MaterialMapJsonConverter {
/// Convert a DetectorMaterialMaps to json
///
/// @param maps The material map collection
nlohmann::json materialMapsToJson(const DetectorMaterialMaps& maps);
/// @param decorator nullptr or a decorator to add extra attributes
nlohmann::json materialMapsToJson(
const DetectorMaterialMaps& maps,
const IVolumeMaterialJsonDecorator* decorator = nullptr);

/// Convert a tracking geometry to json.
/// Can be used to initialise the material mapping process.
///
/// @param tGeometry is the tracking geometry
nlohmann::json trackingGeometryToJson(const TrackingGeometry& tGeometry);
/// @param decorator nullptr or a decorator to add extra attributes
nlohmann::json trackingGeometryToJson(
const TrackingGeometry& tGeometry,
const ITrackingGeometryJsonDecorator* decorator = nullptr);

/// Go through a volume to find subvolume, layers and surfaces.
/// Store volumes and surfaces in two vector used to initialised the geometry
Expand All @@ -114,19 +122,23 @@ class MaterialMapJsonConverter {
/// Name of the volume hierarchy
std::string m_volumeName = "Material Volume Map";
/// Geometry hierarchy writer for volume material.
Acts::GeometryHierarchyMapJsonConverter<const IVolumeMaterial*>
Acts::GeometryHierarchyMapJsonConverter<const IVolumeMaterial*,
Acts::IVolumeMaterialJsonDecorator>
m_volumeMaterialConverter;
/// Geometry hierarchy writer for tracking volume.
Acts::GeometryHierarchyMapJsonConverter<Acts::TrackingVolumeAndMaterial>
Acts::GeometryHierarchyMapJsonConverter<Acts::TrackingVolumeAndMaterial,
Acts::ITrackingGeometryJsonDecorator>
m_volumeConverter;

/// Name of the surface hierarchy
std::string m_surfaceName = "Material Surface Map";
/// Geometry hierarchy writer for surface material.
Acts::GeometryHierarchyMapJsonConverter<const ISurfaceMaterial*>
Acts::GeometryHierarchyMapJsonConverter<const ISurfaceMaterial*,
Acts::IVolumeMaterialJsonDecorator>
m_surfaceMaterialConverter;
/// Geometry hierarchy writer for surface.
Acts::GeometryHierarchyMapJsonConverter<Acts::SurfaceAndMaterialWithContext>
Acts::GeometryHierarchyMapJsonConverter<Acts::SurfaceAndMaterialWithContext,
Acts::ITrackingGeometryJsonDecorator>
m_surfaceConverter;

/// Private access to the logging instance
Expand Down
56 changes: 49 additions & 7 deletions Plugins/Json/src/MaterialMapJsonConverter.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of the Acts project.
//
// Copyright (C) 2017-2021 CERN for the benefit of the Acts project
// Copyright (C) 2017-2023 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -28,6 +28,44 @@
#include <algorithm>
#include <map>

namespace Acts {
// specialisations of decoration helper function
// to pick correct objects from the contaier object
template <>
inline void decorateJson<Acts::SurfaceAndMaterialWithContext>(
const ITrackingGeometryJsonDecorator* decorator,
const Acts::SurfaceAndMaterialWithContext& src, nlohmann::json& dest) {
if (decorator != nullptr && std::get<0>(src) != nullptr) {
decorator->decorate(*std::get<0>(src), dest);
}
}
template <>
inline void decorateJson<Acts::TrackingVolumeAndMaterial>(
const ITrackingGeometryJsonDecorator* decorator,
const Acts::TrackingVolumeAndMaterial& src, nlohmann::json& dest) {
if (decorator != nullptr && src.first != nullptr) {
decorator->decorate(*src.first, dest);
}
}

template <>
inline void decorateJson<Acts::IVolumeMaterial>(
const IVolumeMaterialJsonDecorator* decorator,
const Acts::IVolumeMaterial* src, nlohmann::json& dest) {
if (decorator != nullptr && src != nullptr) {
decorator->decorate(*src, dest);
}
}
template <>
inline void decorateJson<Acts::ISurfaceMaterial>(
const IVolumeMaterialJsonDecorator* decorator,
const Acts::ISurfaceMaterial* src, nlohmann::json& dest) {
if (decorator != nullptr && src != nullptr) {
decorator->decorate(*src, dest);
}
}
} // namespace Acts

namespace {

Acts::SurfaceAndMaterialWithContext defaultSurfaceMaterial(
Expand Down Expand Up @@ -188,7 +226,8 @@ Acts::MaterialMapJsonConverter::MaterialMapJsonConverter(
/// Convert method
///
nlohmann::json Acts::MaterialMapJsonConverter::materialMapsToJson(
const DetectorMaterialMaps& maps) {
const DetectorMaterialMaps& maps,
const IVolumeMaterialJsonDecorator* decorator) {
VolumeMaterialMap volumeMap = maps.second;
std::vector<std::pair<GeometryIdentifier, const IVolumeMaterial*>>
mapVolumeInit;
Expand All @@ -198,7 +237,7 @@ nlohmann::json Acts::MaterialMapJsonConverter::materialMapsToJson(
GeometryHierarchyMap<const IVolumeMaterial*> hierarchyVolumeMap(
mapVolumeInit);
nlohmann::json materialVolume =
m_volumeMaterialConverter.toJson(hierarchyVolumeMap);
m_volumeMaterialConverter.toJson(hierarchyVolumeMap, decorator);
SurfaceMaterialMap surfaceMap = maps.first;
std::vector<std::pair<GeometryIdentifier, const ISurfaceMaterial*>>
mapSurfaceInit;
Expand All @@ -208,7 +247,7 @@ nlohmann::json Acts::MaterialMapJsonConverter::materialMapsToJson(
GeometryHierarchyMap<const ISurfaceMaterial*> hierarchySurfaceMap(
mapSurfaceInit);
nlohmann::json materialSurface =
m_surfaceMaterialConverter.toJson(hierarchySurfaceMap);
m_surfaceMaterialConverter.toJson(hierarchySurfaceMap, decorator);
nlohmann::json materialMap;
materialMap["Volumes"] = materialVolume;
materialMap["Surfaces"] = materialSurface;
Expand Down Expand Up @@ -245,7 +284,8 @@ Acts::MaterialMapJsonConverter::jsonToMaterialMaps(
}

nlohmann::json Acts::MaterialMapJsonConverter::trackingGeometryToJson(
const Acts::TrackingGeometry& tGeometry) {
const Acts::TrackingGeometry& tGeometry,
const ITrackingGeometryJsonDecorator* decorator) {
std::vector<std::pair<GeometryIdentifier, Acts::TrackingVolumeAndMaterial>>
volumeHierarchy;
std::vector<
Expand All @@ -255,10 +295,12 @@ nlohmann::json Acts::MaterialMapJsonConverter::trackingGeometryToJson(
tGeometry.highestTrackingVolume());
GeometryHierarchyMap<Acts::TrackingVolumeAndMaterial> hierarchyVolumeMap(
volumeHierarchy);
nlohmann::json jsonVolumes = m_volumeConverter.toJson(hierarchyVolumeMap);
nlohmann::json jsonVolumes =
m_volumeConverter.toJson(hierarchyVolumeMap, decorator);
GeometryHierarchyMap<Acts::SurfaceAndMaterialWithContext> hierarchySurfaceMap(
surfaceHierarchy);
nlohmann::json jsonSurfaces = m_surfaceConverter.toJson(hierarchySurfaceMap);
nlohmann::json jsonSurfaces =
m_surfaceConverter.toJson(hierarchySurfaceMap, decorator);
nlohmann::json hierarchyMap;
hierarchyMap["Volumes"] = jsonVolumes;
hierarchyMap["Surfaces"] = jsonSurfaces;
Expand Down
Loading