Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:53:42

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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/InternalNavigation.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 <algorithm>
0025 #include <ctime>
0026 #include <ranges>
0027 
0028 nlohmann::json Acts::DetectorVolumeJsonConverter::toJson(
0029     const GeometryContext& gctx, const Experimental::DetectorVolume& volume,
0030     const std::vector<const Experimental::DetectorVolume*>& detectorVolumes,
0031     const std::vector<const Experimental::Portal*>& portals,
0032     const Options& options) {
0033   nlohmann::json jVolume;
0034   jVolume["name"] = volume.name();
0035   jVolume["geometryId"] = volume.geometryId().volume();
0036   jVolume["transform"] = Transform3JsonConverter::toJson(
0037       volume.transform(gctx), options.transformOptions);
0038   jVolume["bounds"] = VolumeBoundsJsonConverter::toJson(volume.volumeBounds());
0039   // Write the surfaces
0040   nlohmann::json jSurfaces;
0041   std::ranges::for_each(volume.surfaces(), [&](const auto& s) {
0042     jSurfaces.push_back(
0043         SurfaceJsonConverter::toJson(gctx, *s, options.surfaceOptions));
0044   });
0045   jVolume["surfaces"] = jSurfaces;
0046   // And its surface navigation delegates
0047   nlohmann::json jSurfacesDelegate =
0048       IndexedSurfacesJsonConverter::toJson(volume.internalNavigation());
0049   jVolume["surface_navigation"] = jSurfacesDelegate;
0050 
0051   // Write the sub volumes
0052   nlohmann::json jVolumes;
0053   std::ranges::for_each(volume.volumes(), [&](const auto& v) {
0054     jVolumes.push_back(toJson(gctx, *v, detectorVolumes, portals, options));
0055   });
0056   jVolume["volumes"] = jVolumes;
0057 
0058   // Write the portals if pre-converted as link
0059   nlohmann::json jPortals;
0060   if (!portals.empty()) {
0061     for (const auto* p : volume.portals()) {
0062       auto it = std::ranges::find(portals, p);
0063       if (it != portals.end()) {
0064         jPortals.push_back(std::distance(portals.begin(), it));
0065       } else {
0066         throw std::runtime_error("Portal not found in the list of portals");
0067       }
0068     }
0069     jVolume["portal_links"] = jPortals;
0070   } else {
0071     for (const auto& p : volume.portals()) {
0072       nlohmann::json jPortal = PortalJsonConverter::toJson(
0073           gctx, *p, detectorVolumes, options.portalOptions);
0074       jPortals.push_back(jPortal);
0075     }
0076     jVolume["portals"] = jPortals;
0077   }
0078   return jVolume;
0079 }
0080 
0081 std::shared_ptr<Acts::Experimental::DetectorVolume>
0082 Acts::DetectorVolumeJsonConverter::fromJson(const GeometryContext& gctx,
0083                                             const nlohmann::json& jVolume) {
0084   std::string name = jVolume["name"];
0085   auto geoId = GeometryIdentifier().withVolume(jVolume["geometryId"]);
0086   Transform3 transform =
0087       Transform3JsonConverter::fromJson(jVolume["transform"]);
0088   auto bounds = VolumeBoundsJsonConverter::fromJson(jVolume["bounds"]);
0089 
0090   auto jSurfaces = jVolume["surfaces"];
0091   auto jVolumes = jVolume["volumes"];
0092 
0093   // Some tooling
0094   auto portalGenerator = Experimental::defaultPortalGenerator();
0095 
0096   if (jSurfaces.empty() && jVolumes.empty()) {
0097     auto volume = Experimental::DetectorVolumeFactory::construct(
0098         portalGenerator, gctx, name, transform, std::move(bounds),
0099         Experimental::tryAllPortals());
0100     volume->assignGeometryId(geoId);
0101     return volume;
0102   }
0103   // Convert the surfaces
0104   std::vector<std::shared_ptr<Surface>> surfaces;
0105   for (const auto& js : jSurfaces) {
0106     surfaces.push_back(SurfaceJsonConverter::fromJson(js));
0107   }
0108   // Convert the volumes
0109   std::vector<std::shared_ptr<Experimental::DetectorVolume>> volumes;
0110   for (const auto& jv : jVolumes) {
0111     volumes.push_back(DetectorVolumeJsonConverter::fromJson(gctx, jv));
0112   }
0113 
0114   auto jSurfaceNavigation = jVolume["surface_navigation"];
0115 
0116   auto volume = Experimental::DetectorVolumeFactory::construct(
0117       portalGenerator, gctx, name, transform, std::move(bounds), surfaces,
0118       volumes, Experimental::tryRootVolumes(),
0119       IndexedSurfacesJsonConverter::fromJson(jSurfaceNavigation));
0120   volume->assignGeometryId(geoId);
0121   return volume;
0122 }