File indexing completed on 2025-08-05 08:10:18
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/Json/DetectorVolumeJsonConverter.hpp"
0010
0011 #include "Acts/Detector/DetectorVolume.hpp"
0012 #include "Acts/Detector/Portal.hpp"
0013 #include "Acts/Detector/PortalGenerators.hpp"
0014 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0015 #include "Acts/Navigation/SurfaceCandidatesUpdaters.hpp"
0016 #include "Acts/Plugins/Json/AlgebraJsonConverter.hpp"
0017 #include "Acts/Plugins/Json/DetrayJsonHelper.hpp"
0018 #include "Acts/Plugins/Json/IndexedSurfacesJsonConverter.hpp"
0019 #include "Acts/Plugins/Json/PortalJsonConverter.hpp"
0020 #include "Acts/Plugins/Json/SurfaceJsonConverter.hpp"
0021 #include "Acts/Plugins/Json/VolumeBoundsJsonConverter.hpp"
0022 #include "Acts/Utilities/Enumerate.hpp"
0023
0024 #include <ctime>
0025
0026 namespace {
0027
0028
0029
0030
0031
0032
0033
0034 int findVolume(
0035 const Acts::Experimental::DetectorVolume* volume,
0036 const std::vector<const Acts::Experimental::DetectorVolume*>& volumes) {
0037 auto candidate = std::find(volumes.begin(), volumes.end(), volume);
0038 if (candidate != volumes.end()) {
0039 return std::distance(volumes.begin(), candidate);
0040 }
0041 return -1;
0042 }
0043 }
0044
0045 nlohmann::json Acts::DetectorVolumeJsonConverter::toJson(
0046 const GeometryContext& gctx, const Experimental::DetectorVolume& volume,
0047 const std::vector<const Experimental::DetectorVolume*>& detectorVolumes,
0048 const std::vector<const Experimental::Portal*>& portals,
0049 const Options& options) {
0050 nlohmann::json jVolume;
0051 jVolume["name"] = volume.name();
0052 jVolume["geometryId"] = volume.geometryId().volume();
0053 jVolume["transform"] = Transform3JsonConverter::toJson(
0054 volume.transform(gctx), options.transformOptions);
0055 jVolume["bounds"] = VolumeBoundsJsonConverter::toJson(volume.volumeBounds());
0056
0057 nlohmann::json jSurfaces;
0058 std::for_each(
0059 volume.surfaces().begin(), volume.surfaces().end(), [&](const auto& s) {
0060 jSurfaces.push_back(
0061 SurfaceJsonConverter::toJson(gctx, *s, options.surfaceOptions));
0062 });
0063 jVolume["surfaces"] = jSurfaces;
0064
0065 nlohmann::json jSurfacesDelegate =
0066 IndexedSurfacesJsonConverter::toJson(volume.surfaceCandidatesUpdater());
0067 jVolume["surface_navigation"] = jSurfacesDelegate;
0068
0069
0070 nlohmann::json jVolumes;
0071 std::for_each(
0072 volume.volumes().begin(), volume.volumes().end(), [&](const auto& v) {
0073 jVolumes.push_back(toJson(gctx, *v, detectorVolumes, portals, options));
0074 });
0075 jVolume["volumes"] = jVolumes;
0076
0077
0078 nlohmann::json jPortals;
0079 if (!portals.empty()) {
0080 for (const auto* p : volume.portals()) {
0081 auto it = std::find(portals.begin(), portals.end(), p);
0082 if (it != portals.end()) {
0083 jPortals.push_back(std::distance(portals.begin(), it));
0084 } else {
0085 throw std::runtime_error("Portal not found in the list of portals");
0086 }
0087 }
0088 jVolume["portal_links"] = jPortals;
0089 } else {
0090 for (const auto& p : volume.portals()) {
0091 nlohmann::json jPortal = PortalJsonConverter::toJson(
0092 gctx, *p, detectorVolumes, options.portalOptions);
0093 jPortals.push_back(jPortal);
0094 }
0095 jVolume["portals"] = jPortals;
0096 }
0097 return jVolume;
0098 }
0099
0100 nlohmann::json Acts::DetectorVolumeJsonConverter::toJsonDetray(
0101 const GeometryContext& gctx, const Experimental::DetectorVolume& volume,
0102 const std::vector<const Experimental::DetectorVolume*>& detectorVolumes,
0103 const Options& options) {
0104 nlohmann::json jVolume;
0105 jVolume["name"] = volume.name();
0106
0107
0108 jVolume["transform"] = Transform3JsonConverter::toJson(
0109 volume.transform(gctx), options.transformOptions);
0110 jVolume["bounds"] = VolumeBoundsJsonConverter::toJson(volume.volumeBounds());
0111 auto volumeBoundsType = volume.volumeBounds().type();
0112 if (volumeBoundsType == VolumeBounds::BoundsType::eCylinder) {
0113 jVolume["type"] = 0u;
0114 } else if (volumeBoundsType == VolumeBounds::BoundsType::eCuboid) {
0115 jVolume["type"] = 4u;
0116 } else {
0117 throw std::runtime_error("Unsupported volume bounds type");
0118 }
0119
0120
0121 int vIndex = findVolume(&volume, detectorVolumes);
0122 jVolume["index"] = vIndex;
0123
0124 std::size_t sIndex = 0;
0125
0126 nlohmann::json jSurfaces;
0127 for (const auto& s : volume.surfaces()) {
0128 auto jSurface =
0129 SurfaceJsonConverter::toJsonDetray(gctx, *s, options.surfaceOptions);
0130 DetrayJsonHelper::addVolumeLink(jSurface["mask"], vIndex);
0131 jSurface["index_in_coll"] = sIndex++;
0132 jSurfaces.push_back(jSurface);
0133 }
0134
0135
0136
0137 auto orientedSurfaces =
0138 volume.volumeBounds().orientedSurfaces(volume.transform(gctx));
0139
0140
0141 for (const auto& [ip, p] : enumerate(volume.portals())) {
0142 auto jPortalSurfaces =
0143 (toJsonDetray(gctx, *p, ip, volume, orientedSurfaces, detectorVolumes,
0144 options.portalOptions));
0145 std::for_each(jPortalSurfaces.begin(), jPortalSurfaces.end(),
0146 [&](auto& jSurface) {
0147 jSurface["index_in_coll"] = sIndex++;
0148 jSurfaces.push_back(jSurface);
0149 });
0150 }
0151 jVolume["surfaces"] = jSurfaces;
0152
0153 return jVolume;
0154 }
0155
0156 std::shared_ptr<Acts::Experimental::DetectorVolume>
0157 Acts::DetectorVolumeJsonConverter::fromJson(const GeometryContext& gctx,
0158 const nlohmann::json& jVolume) {
0159 std::string name = jVolume["name"];
0160 GeometryIdentifier geoId;
0161 geoId.setVolume(jVolume["geometryId"]);
0162 Transform3 transform =
0163 Transform3JsonConverter::fromJson(jVolume["transform"]);
0164 auto bounds = VolumeBoundsJsonConverter::fromJson(jVolume["bounds"]);
0165
0166 auto jSurfaces = jVolume["surfaces"];
0167 auto jVolumes = jVolume["volumes"];
0168
0169
0170 auto portalGenerator = Experimental::defaultPortalGenerator();
0171
0172 if (jSurfaces.empty() && jVolumes.empty()) {
0173 auto volume = Experimental::DetectorVolumeFactory::construct(
0174 portalGenerator, gctx, name, transform, std::move(bounds),
0175 Experimental::tryAllPortals());
0176 volume->assignGeometryId(geoId);
0177 return volume;
0178 }
0179
0180 std::vector<std::shared_ptr<Surface>> surfaces;
0181 for (const auto& js : jSurfaces) {
0182 surfaces.push_back(SurfaceJsonConverter::fromJson(js));
0183 }
0184
0185 std::vector<std::shared_ptr<Experimental::DetectorVolume>> volumes;
0186 for (const auto& jv : jVolumes) {
0187 volumes.push_back(DetectorVolumeJsonConverter::fromJson(gctx, jv));
0188 }
0189
0190 auto jSurfaceNavigation = jVolume["surface_navigation"];
0191
0192 auto volume = Experimental::DetectorVolumeFactory::construct(
0193 portalGenerator, gctx, name, transform, std::move(bounds), surfaces,
0194 volumes, Experimental::tryRootVolumes(),
0195 IndexedSurfacesJsonConverter::fromJson(jSurfaceNavigation));
0196 volume->assignGeometryId(geoId);
0197 return volume;
0198 }