Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:10:49

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2021 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 http://mozilla.org/MPL/2.0/.
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 /// Write all child surfaces and descend into confined volumes.
0065 void collectSurfaces(std::vector<SurfaceContainer::InputElement>& cSurfaces,
0066                      const Acts::TrackingVolume& volume, bool writeLayer,
0067                      bool writeApproach, bool writeSensitive,
0068                      bool writeBoundary) {
0069   // Process all layers that are directly stored within this volume
0070   if (volume.confinedLayers() != nullptr) {
0071     for (const auto& layer : volume.confinedLayers()->arrayObjects()) {
0072       // We jump navigation layers
0073       if (layer->layerType() == Acts::navigation) {
0074         continue;
0075       }
0076       // Layer surface
0077       if (writeLayer) {
0078         auto layerSurfacePtr = layer->surfaceRepresentation().getSharedPtr();
0079         cSurfaces.push_back(SurfaceContainer::InputElement{
0080             layer->surfaceRepresentation().geometryId(), layerSurfacePtr});
0081       }
0082       // Approach surfaces
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       // Check for sensitive surfaces
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     // This is a navigation volume, write the boundaries
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   // Step down into hierarchy to process all child volumnes
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 }  // namespace
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 }