Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JsonSurfacesWriter.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file JsonSurfacesWriter.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
15 #include "Acts/Geometry/Layer.hpp"
27 
28 #include <cstddef>
29 #include <iomanip>
30 #include <sstream>
31 #include <stdexcept>
32 #include <string>
33 #include <utility>
34 #include <vector>
35 
36 #include <nlohmann/json.hpp>
37 
38 using namespace ActsExamples;
39 
42  : m_cfg(config),
43  m_logger(Acts::getDefaultLogger("JsonSurfacesWriter", level)) {
44  if (not m_cfg.trackingGeometry) {
45  throw std::invalid_argument("Missing tracking geometry");
46  }
47  m_world = m_cfg.trackingGeometry->highestTrackingVolume();
48  if (m_world == nullptr) {
49  throw std::invalid_argument("Could not identify the world volume");
50  }
51 }
52 
54  return "JsonSurfacesWriter";
55 }
56 
57 namespace {
58 
59 using SurfaceContainer =
61 using SurfaceConverter = Acts::GeometryHierarchyMapJsonConverter<
62  std::shared_ptr<const Acts::Surface>>;
63 
65 void collectSurfaces(std::vector<SurfaceContainer::InputElement>& cSurfaces,
66  const Acts::TrackingVolume& volume, bool writeLayer,
67  bool writeApproach, bool writeSensitive,
68  bool writeBoundary) {
69  // Process all layers that are directly stored within this volume
70  if (volume.confinedLayers() != nullptr) {
71  for (const auto& layer : volume.confinedLayers()->arrayObjects()) {
72  // We jump navigation layers
73  if (layer->layerType() == Acts::navigation) {
74  continue;
75  }
76  // Layer surface
77  if (writeLayer) {
78  auto layerSurfacePtr = layer->surfaceRepresentation().getSharedPtr();
79  cSurfaces.push_back(SurfaceContainer::InputElement{
80  layer->surfaceRepresentation().geometryId(), layerSurfacePtr});
81  }
82  // Approach surfaces
83  if (writeApproach and layer->approachDescriptor() != nullptr) {
84  for (auto sf : layer->approachDescriptor()->containedSurfaces()) {
85  cSurfaces.push_back(SurfaceContainer::InputElement{
86  sf->geometryId(), sf->getSharedPtr()});
87  }
88  }
89  // Check for sensitive surfaces
90  if (layer->surfaceArray() != nullptr and writeSensitive) {
91  for (const auto& surface : layer->surfaceArray()->surfaces()) {
92  if (surface != nullptr) {
93  cSurfaces.push_back(SurfaceContainer::InputElement{
94  surface->geometryId(), surface->getSharedPtr()});
95  }
96  }
97  }
98  }
99  // This is a navigation volume, write the boundaries
100  if (writeBoundary) {
101  for (const auto& bsurface : volume.boundarySurfaces()) {
102  const auto& bsRep = bsurface->surfaceRepresentation();
103  cSurfaces.push_back(SurfaceContainer::InputElement{
104  bsRep.geometryId(), bsRep.getSharedPtr()});
105  }
106  }
107  }
108  // Step down into hierarchy to process all child volumnes
109  if (volume.confinedVolumes()) {
110  for (const auto& confined : volume.confinedVolumes()->arrayObjects()) {
111  collectSurfaces(cSurfaces, *confined.get(), writeLayer, writeApproach,
112  writeSensitive, writeBoundary);
113  }
114  }
115 }
116 } // namespace
117 
119  if (not m_cfg.writePerEvent) {
120  return ProcessCode::SUCCESS;
121  }
122 
123  std::ofstream out;
124  out.open(perEventFilepath(m_cfg.outputDir, "detector.json", ctx.eventNumber));
125 
126  std::vector<SurfaceContainer::InputElement> cSurfaces;
127  collectSurfaces(cSurfaces, *m_world, m_cfg.writeLayer, m_cfg.writeApproach,
129  SurfaceContainer sContainer(cSurfaces);
130 
131  if (not m_cfg.writeOnlyNames) {
132  auto j = SurfaceConverter("surfaces").toJson(sContainer, nullptr);
133  out << std::setprecision(m_cfg.outputPrecision) << j.dump(2);
134  out.close();
135  } else {
136  using NamedContainer = Acts::GeometryHierarchyMap<std::string>;
138 
139  std::vector<std::pair<Acts::GeometryIdentifier, std::string>> namedEntries;
140  for (size_t is = 0; is < sContainer.size(); ++is) {
141  Acts::GeometryIdentifier geometryId = sContainer.idAt(is);
142  std::stringstream geoTypeName;
143  geoTypeName << geometryId;
144  namedEntries.push_back({geometryId, geoTypeName.str()});
145  }
146  NamedContainer nContainer(namedEntries);
147  auto j = NamedConverter("surface_types").toJson(nContainer, nullptr);
148  out << j.dump(2);
149  out.close();
150  }
151 
152  return ProcessCode::SUCCESS;
153 }
154 
156  std::ofstream out;
157  out.open(joinPaths(m_cfg.outputDir, "detector.csv"));
158 
159  std::vector<SurfaceContainer::InputElement> cSurfaces;
160  collectSurfaces(cSurfaces, *m_world, m_cfg.writeLayer, m_cfg.writeApproach,
162  SurfaceContainer sContainer(cSurfaces);
163 
164  auto j = SurfaceConverter("surfaces").toJson(sContainer, nullptr);
165  out << std::setprecision(m_cfg.outputPrecision) << j.dump(2);
166  out.close();
167 
168  return ProcessCode::SUCCESS;
169 }