File indexing completed on 2025-08-06 08:10:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/Json/JsonSurfacesWriter.hpp"
0010
0011 #include "Acts/Geometry/ApproachDescriptor.hpp"
0012 #include "Acts/Geometry/BoundarySurfaceT.hpp"
0013 #include "Acts/Geometry/GeometryHierarchyMap.hpp"
0014 #include "Acts/Geometry/GeometryIdentifier.hpp"
0015 #include "Acts/Geometry/Layer.hpp"
0016 #include "Acts/Geometry/TrackingGeometry.hpp"
0017 #include "Acts/Geometry/TrackingVolume.hpp"
0018 #include "Acts/Plugins/Json/GeometryHierarchyMapJsonConverter.hpp"
0019 #include "Acts/Plugins/Json/SurfaceJsonConverter.hpp"
0020 #include "Acts/Plugins/Json/VolumeJsonConverter.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Surfaces/SurfaceArray.hpp"
0023 #include "Acts/Utilities/BinnedArray.hpp"
0024 #include "Acts/Utilities/Logger.hpp"
0025 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0026 #include "ActsExamples/Utilities/Paths.hpp"
0027
0028 #include <cstddef>
0029 #include <iomanip>
0030 #include <sstream>
0031 #include <stdexcept>
0032 #include <string>
0033 #include <utility>
0034 #include <vector>
0035
0036 #include <nlohmann/json.hpp>
0037
0038 using namespace ActsExamples;
0039
0040 JsonSurfacesWriter::JsonSurfacesWriter(const JsonSurfacesWriter::Config& config,
0041 Acts::Logging::Level level)
0042 : m_cfg(config),
0043 m_logger(Acts::getDefaultLogger("JsonSurfacesWriter", level)) {
0044 if (!m_cfg.trackingGeometry) {
0045 throw std::invalid_argument("Missing tracking geometry");
0046 }
0047 m_world = m_cfg.trackingGeometry->highestTrackingVolume();
0048 if (m_world == nullptr) {
0049 throw std::invalid_argument("Could not identify the world volume");
0050 }
0051 }
0052
0053 std::string JsonSurfacesWriter::name() const {
0054 return "JsonSurfacesWriter";
0055 }
0056
0057 namespace {
0058
0059 using SurfaceContainer =
0060 Acts::GeometryHierarchyMap<std::shared_ptr<const Acts::Surface>>;
0061 using SurfaceConverter = Acts::GeometryHierarchyMapJsonConverter<
0062 std::shared_ptr<const Acts::Surface>>;
0063
0064
0065 void collectSurfaces(std::vector<SurfaceContainer::InputElement>& cSurfaces,
0066 const Acts::TrackingVolume& volume, bool writeLayer,
0067 bool writeApproach, bool writeSensitive,
0068 bool writeBoundary) {
0069
0070 if (volume.confinedLayers() != nullptr) {
0071 for (const auto& layer : volume.confinedLayers()->arrayObjects()) {
0072
0073 if (layer->layerType() == Acts::navigation) {
0074 continue;
0075 }
0076
0077 if (writeLayer) {
0078 auto layerSurfacePtr = layer->surfaceRepresentation().getSharedPtr();
0079 cSurfaces.push_back(SurfaceContainer::InputElement{
0080 layer->surfaceRepresentation().geometryId(), layerSurfacePtr});
0081 }
0082
0083 if (writeApproach && layer->approachDescriptor() != nullptr) {
0084 for (auto sf : layer->approachDescriptor()->containedSurfaces()) {
0085 cSurfaces.push_back(SurfaceContainer::InputElement{
0086 sf->geometryId(), sf->getSharedPtr()});
0087 }
0088 }
0089
0090 if (layer->surfaceArray() != nullptr && writeSensitive) {
0091 for (const auto& surface : layer->surfaceArray()->surfaces()) {
0092 if (surface != nullptr) {
0093 cSurfaces.push_back(SurfaceContainer::InputElement{
0094 surface->geometryId(), surface->getSharedPtr()});
0095 }
0096 }
0097 }
0098 }
0099
0100 if (writeBoundary) {
0101 for (const auto& bsurface : volume.boundarySurfaces()) {
0102 const auto& bsRep = bsurface->surfaceRepresentation();
0103 cSurfaces.push_back(SurfaceContainer::InputElement{
0104 bsRep.geometryId(), bsRep.getSharedPtr()});
0105 }
0106 }
0107 }
0108
0109 if (volume.confinedVolumes()) {
0110 for (const auto& confined : volume.confinedVolumes()->arrayObjects()) {
0111 collectSurfaces(cSurfaces, *confined.get(), writeLayer, writeApproach,
0112 writeSensitive, writeBoundary);
0113 }
0114 }
0115 }
0116 }
0117
0118 ProcessCode JsonSurfacesWriter::write(const AlgorithmContext& ctx) {
0119 if (!m_cfg.writePerEvent) {
0120 return ProcessCode::SUCCESS;
0121 }
0122
0123 std::ofstream out;
0124 out.open(perEventFilepath(m_cfg.outputDir, "detector.json", ctx.eventNumber));
0125
0126 std::vector<SurfaceContainer::InputElement> cSurfaces;
0127 collectSurfaces(cSurfaces, *m_world, m_cfg.writeLayer, m_cfg.writeApproach,
0128 m_cfg.writeSensitive, m_cfg.writeBoundary);
0129 SurfaceContainer sContainer(cSurfaces);
0130
0131 if (!m_cfg.writeOnlyNames) {
0132 auto j = SurfaceConverter("surfaces").toJson(sContainer, nullptr);
0133 out << std::setprecision(m_cfg.outputPrecision) << j.dump(2);
0134 out.close();
0135 } else {
0136 using NamedContainer = Acts::GeometryHierarchyMap<std::string>;
0137 using NamedConverter = Acts::GeometryHierarchyMapJsonConverter<std::string>;
0138
0139 std::vector<std::pair<Acts::GeometryIdentifier, std::string>> namedEntries;
0140 for (std::size_t is = 0; is < sContainer.size(); ++is) {
0141 Acts::GeometryIdentifier geometryId = sContainer.idAt(is);
0142 std::stringstream geoTypeName;
0143 geoTypeName << geometryId;
0144 namedEntries.push_back({geometryId, geoTypeName.str()});
0145 }
0146 NamedContainer nContainer(namedEntries);
0147 auto j = NamedConverter("surface_types").toJson(nContainer, nullptr);
0148 out << j.dump(2);
0149 out.close();
0150 }
0151
0152 return ProcessCode::SUCCESS;
0153 }
0154
0155 ProcessCode JsonSurfacesWriter::finalize() {
0156 std::ofstream out;
0157 out.open(joinPaths(m_cfg.outputDir, "detector.csv"));
0158
0159 std::vector<SurfaceContainer::InputElement> cSurfaces;
0160 collectSurfaces(cSurfaces, *m_world, m_cfg.writeLayer, m_cfg.writeApproach,
0161 m_cfg.writeSensitive, m_cfg.writeBoundary);
0162 SurfaceContainer sContainer(cSurfaces);
0163
0164 auto j = SurfaceConverter("surfaces").toJson(sContainer, nullptr);
0165 out << std::setprecision(m_cfg.outputPrecision) << j.dump(2);
0166 out.close();
0167
0168 return ProcessCode::SUCCESS;
0169 }