File indexing completed on 2025-08-05 08:10:18
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/Json/DetectorJsonConverter.hpp"
0010
0011 #include "Acts/Detector/Detector.hpp"
0012 #include "Acts/Detector/DetectorVolume.hpp"
0013 #include "Acts/Detector/Portal.hpp"
0014 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0015 #include "Acts/Plugins/Json/DetectorVolumeFinderJsonConverter.hpp"
0016 #include "Acts/Plugins/Json/DetectorVolumeJsonConverter.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/Utilities/Enumerate.hpp"
0021 #include "Acts/Utilities/Helpers.hpp"
0022
0023 #include <algorithm>
0024 #include <ctime>
0025 #include <set>
0026
0027 nlohmann::json Acts::DetectorJsonConverter::toJson(
0028 const GeometryContext& gctx, const Experimental::Detector& detector,
0029 const Options& options) {
0030
0031 std::time_t tt = 0;
0032 std::time(&tt);
0033 auto ti = std::localtime(&tt);
0034
0035 nlohmann::json jDetector;
0036
0037 std::size_t nSurfaces = 0;
0038 std::vector<const Experimental::Portal*> portals;
0039
0040 for (const auto* volume : detector.volumes()) {
0041 nSurfaces += volume->surfaces().size();
0042 for (const auto& portal : volume->portals()) {
0043 if (std::find(portals.begin(), portals.end(), portal) == portals.end()) {
0044 portals.push_back(portal);
0045 }
0046 }
0047 }
0048
0049
0050 nlohmann::json jData;
0051 jData["name"] = detector.name();
0052
0053
0054 auto volumes = detector.volumes();
0055 nlohmann::json jPortals;
0056
0057 for (const auto& portal : portals) {
0058 auto jPortal = PortalJsonConverter::toJson(
0059 gctx, *portal, volumes, options.volumeOptions.portalOptions);
0060 jPortals.push_back(jPortal);
0061 }
0062 jData["portals"] = jPortals;
0063
0064
0065
0066 nlohmann::json jVolumes;
0067 for (const auto& volume : volumes) {
0068 auto jVolume = DetectorVolumeJsonConverter::toJson(
0069 gctx, *volume, volumes, portals, options.volumeOptions);
0070 jVolumes.push_back(jVolume);
0071 }
0072 jData["volumes"] = jVolumes;
0073
0074 jData["volume_finder"] = DetectorVolumeFinderJsonConverter::toJson(
0075 detector.detectorVolumeFinder());
0076
0077
0078 nlohmann::json jHeader;
0079 jHeader["detector"] = detector.name();
0080 jHeader["type"] = "acts";
0081 jHeader["date"] = std::asctime(ti);
0082 jHeader["surface_count"] = nSurfaces;
0083 jHeader["portal_count"] = portals.size();
0084 jHeader["volume_count"] = detector.volumes().size();
0085 jDetector["header"] = jHeader;
0086 jDetector["data"] = jData;
0087 return jDetector;
0088 }
0089
0090 nlohmann::json Acts::DetectorJsonConverter::toJsonDetray(
0091 const GeometryContext& gctx, const Experimental::Detector& detector,
0092 const Options& options) {
0093
0094 std::time_t tt = 0;
0095 std::time(&tt);
0096 auto ti = std::localtime(&tt);
0097
0098 nlohmann::json jFile;
0099
0100
0101 nlohmann::json jGeometry;
0102 nlohmann::json jGeometryData;
0103 nlohmann::json jGeometryHeader;
0104 std::size_t nSurfaces = 0;
0105
0106 nlohmann::json jCommonHeader;
0107 jCommonHeader["detector"] = detector.name();
0108 jCommonHeader["date"] = std::asctime(ti);
0109 jCommonHeader["version"] = "detray - 0.44.0";
0110 jCommonHeader["tag"] = "geometry";
0111
0112 auto volumes = detector.volumes();
0113
0114
0115 nlohmann::json jVolumes;
0116 for (const auto& volume : volumes) {
0117 auto jVolume = DetectorVolumeJsonConverter::toJsonDetray(
0118 gctx, *volume, volumes, options.volumeOptions);
0119 jVolumes.push_back(jVolume);
0120 if (jVolume.find("surfaces") != jVolume.end() &&
0121 jVolume["surfaces"].is_array()) {
0122 nSurfaces += jVolume["surfaces"].size();
0123 }
0124 }
0125 jGeometryData["volumes"] = jVolumes;
0126 jGeometryData["volume_grid"] = DetectorVolumeFinderJsonConverter::toJson(
0127 detector.detectorVolumeFinder(), true);
0128
0129
0130
0131
0132 jGeometryHeader["type"] = "detray";
0133 jGeometryHeader["common"] = jCommonHeader;
0134 jGeometryHeader["surface_count"] = nSurfaces;
0135 jGeometryHeader["volume_count"] = detector.volumes().size();
0136 jGeometry["header"] = jGeometryHeader;
0137 jGeometry["data"] = jGeometryData;
0138 jFile["geometry"] = jGeometry;
0139
0140
0141 nlohmann::json jSurfaceGrids;
0142 nlohmann::json jSurfaceGridsData;
0143 nlohmann::json jSurfaceGridsCollection;
0144 nlohmann::json jSurfaceGridsHeader;
0145 for (const auto [iv, volume] : enumerate(volumes)) {
0146
0147 nlohmann::json jSurfacesDelegate = IndexedSurfacesJsonConverter::toJson(
0148 volume->surfaceCandidatesUpdater(), true);
0149 if (jSurfacesDelegate.is_null()) {
0150 continue;
0151 }
0152
0153
0154 auto jAccLink = jSurfacesDelegate["acc_link"];
0155 std::size_t accLinkType = jAccLink["type"];
0156 if (accLinkType == 4u) {
0157
0158 std::vector<ActsScalar> bValues = volume->volumeBounds().values();
0159 ActsScalar rRef = 0.5 * (bValues[1] + bValues[0]);
0160
0161 auto& jAxes = jSurfacesDelegate["axes"];
0162
0163 std::vector<ActsScalar> jAxesEdges = jAxes[0u]["edges"];
0164 std::for_each(jAxesEdges.begin(), jAxesEdges.end(),
0165 [rRef](ActsScalar& phi) { phi *= rRef; });
0166
0167 jSurfacesDelegate["axes"][0u]["edges"] = jAxesEdges;
0168 }
0169
0170 jSurfacesDelegate["volume_link"] = iv;
0171
0172 jSurfaceGridsCollection.push_back(jSurfacesDelegate);
0173 }
0174 jSurfaceGridsData["grids"] = jSurfaceGridsCollection;
0175
0176 jCommonHeader["tag"] = "surface_grids";
0177 jSurfaceGridsHeader["common"] = jCommonHeader;
0178 jSurfaceGridsHeader["grid_count"] = jSurfaceGridsCollection.size();
0179
0180 jSurfaceGrids["header"] = jSurfaceGridsHeader;
0181 jSurfaceGrids["data"] = jSurfaceGridsData;
0182
0183 jFile["surface_grids"] = jSurfaceGrids;
0184
0185
0186 nlohmann::json jMaterial;
0187
0188 jFile["material"] = jMaterial;
0189
0190 return jFile;
0191 }
0192
0193 std::shared_ptr<Acts::Experimental::Detector>
0194 Acts::DetectorJsonConverter::fromJson(const GeometryContext& gctx,
0195 const nlohmann::json& jDetector) {
0196
0197 auto jData = jDetector["data"];
0198 auto jVolumes = jData["volumes"];
0199 auto jPortals = jData["portals"];
0200 const std::string name = jData["name"];
0201
0202 std::vector<std::shared_ptr<Experimental::DetectorVolume>> volumes;
0203 std::vector<std::shared_ptr<Experimental::Portal>> portals;
0204
0205 for (const auto& jVolume : jVolumes) {
0206 auto volume = DetectorVolumeJsonConverter::fromJson(gctx, jVolume);
0207 volumes.push_back(volume);
0208 }
0209
0210 for (const auto& jPortal : jPortals) {
0211 auto portal = PortalJsonConverter::fromJson(gctx, jPortal, volumes);
0212 portals.push_back(portal);
0213 }
0214
0215
0216 for (auto [iv, v] : enumerate(volumes)) {
0217
0218 auto jVolume = jVolumes[iv];
0219 std::vector<std::size_t> portalLinks = jVolume["portal_links"];
0220 for (auto [ip, ipl] : enumerate(portalLinks)) {
0221 auto portal = portals[ipl];
0222 v->updatePortal(portal, ip);
0223 }
0224 }
0225 return Experimental::Detector::makeShared(name, volumes,
0226 Experimental::tryRootVolumes());
0227 }