Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DetectorJsonConverterTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DetectorJsonConverterTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 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 
9 #include <boost/test/unit_test.hpp>
10 
32 
33 #include <fstream>
34 #include <memory>
35 #include <vector>
36 
37 #include <nlohmann/json.hpp>
38 
39 namespace {
40 
44 std::vector<std::shared_ptr<Acts::Surface>> unpackSurfaces(
45  const std::vector<const Acts::Surface*>& surfaces) {
46  std::vector<std::shared_ptr<Acts::Surface>> uSurfaces;
47  uSurfaces.reserve(surfaces.size());
48  for (const auto s : surfaces) {
49  auto* ncs = const_cast<Acts::Surface*>(s);
50  uSurfaces.push_back(ncs->getSharedPtr());
51  }
52  return uSurfaces;
53 }
54 
56  // Detray format test - manipulate for detray
58  detrayOptions.transformOptions.writeIdentity = true;
59  detrayOptions.transformOptions.transpose = true;
60  detrayOptions.surfaceOptions.transformOptions =
61  detrayOptions.transformOptions;
62  detrayOptions.portalOptions.surfaceOptions = detrayOptions.surfaceOptions;
63  return Acts::DetectorJsonConverter::Options{detrayOptions};
64 }
65 
66 } // namespace
67 
70 
71 BOOST_AUTO_TEST_SUITE(DetectorJsonConverter)
72 
73 BOOST_AUTO_TEST_CASE(SingleEmptyVolumeDetector) {
75 
76  // Create a single cylindrical volume
77  Acts::Transform3 nominal = Acts::Transform3::Identity();
78  auto bounds = std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
79 
81  portalGenerator, tContext, "Volume", nominal, std::move(bounds),
83 
84  std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes = {
85  volume};
86 
88  "Detector", volumes, Acts::Experimental::tryRootVolumes());
89 
90  auto jDetector = Acts::DetectorJsonConverter::toJson(tContext, *detector);
91 
92  std::ofstream out;
93  out.open("single-empty-volume-detector.json");
94  out << jDetector.dump(4);
95  out.close();
96 }
97 
98 BOOST_AUTO_TEST_CASE(SingleVolumeOneSurfaceDetector) {
100 
101  // Create a single cylindrical volume
102  Acts::Transform3 nominal = Acts::Transform3::Identity();
103  auto bounds = std::make_unique<Acts::CylinderVolumeBounds>(0., 50., 100.);
104 
105  auto cylinderBounds = std::make_shared<Acts::CylinderBounds>(30., 90.);
106  auto surface =
107  Acts::Surface::makeShared<Acts::CylinderSurface>(nominal, cylinderBounds);
108 
110  portalGenerator, tContext, "Volume", nominal, std::move(bounds),
113 
114  std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>> volumes = {
115  volume};
116 
118  "Detector", volumes, Acts::Experimental::tryRootVolumes());
119 
120  auto jDetector = Acts::DetectorJsonConverter::toJson(tContext, *detector);
121 
122  std::ofstream out;
123  out.open("single-volume-one-surface-detector.json");
124  out << jDetector.dump(4);
125  out.close();
126 
127  out.open("single-volume-one-surface-detector-detray.json");
129  detrayOptions())
130  .dump(4);
131  out.close();
132 }
133 
134 BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) {
135  // Detector store
137 
138  // Endcaps
139  std::vector<std::shared_ptr<Acts::Experimental::IDetectorComponentBuilder>>
140  endcapBuilders;
141  for (auto [ie, ep] :
142  Acts::enumerate(std::vector<Acts::ActsScalar>({-710., 710.}))) {
143  auto rSurfaces = cGeometry.surfacesRing(dStore, 6.4, 12.4, 36., 0.125, 0.,
144  55., ep, 2., 22u);
145 
146  auto endcapSurfaces = std::make_shared<
148  unpackSurfaces(rSurfaces));
149  // Configure the layer structure builder
151  lsConfig.auxiliary = "*** Endcap with 22 surfaces ***";
152  lsConfig.surfacesProvider = endcapSurfaces;
153  lsConfig.binnings = {Acts::Experimental::ProtoBinning(
154  Acts::binPhi, Acts::detail::AxisBoundaryType::Closed, -M_PI, M_PI, 22u,
155  1u)};
156 
157  auto layerBuilder =
158  std::make_shared<Acts::Experimental::LayerStructureBuilder>(
159  lsConfig, Acts::getDefaultLogger("EndcapInteralsBuilder",
161 
163  shapeConfig.boundValues = {20, 100, 10., M_PI, 0.};
164  shapeConfig.transform = Acts::Transform3(Acts::Transform3::Identity())
165  .pretranslate(Acts::Vector3(0., 0., ep));
166  shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
167 
168  auto shapeBuilder =
169  std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
170  shapeConfig, Acts::getDefaultLogger("EndcapShapeBuilder",
172 
174  dvCfg.name = "EndcapWithSurfaces_" + std::to_string(ie);
175  dvCfg.externalsBuilder = shapeBuilder;
176  dvCfg.internalsBuilder = layerBuilder;
177 
178  auto dvBuilder =
179  std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
180  dvCfg,
182  endcapBuilders.push_back(dvBuilder);
183  }
184 
185  // Central barrel
187  innerShapeConfig.boundValues = {20., 60., 700., M_PI, 0.};
188  innerShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
189 
190  auto innerShapeBuilder =
191  std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
192  innerShapeConfig,
193  Acts::getDefaultLogger("InnerShapeBuilder", Acts::Logging::VERBOSE));
194 
196  ivCfg.name = "InnerBarrelGap";
197  ivCfg.externalsBuilder = innerShapeBuilder;
198 
199  auto ivBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
200  ivCfg, Acts::getDefaultLogger("InnerBarrel", Acts::Logging::VERBOSE));
201 
203  auto cSurfaces = cGeometry.surfacesCylinder(dStore, 8.4, 36., 0.15, 0.145, 72,
204  3., 2., {32u, 14u});
205 
206  auto barrelSurfaces = std::make_shared<
208  unpackSurfaces(cSurfaces));
209 
210  // Configure the layer structure builder
212  lsConfig.auxiliary = "*** Barrel with 448 surfaces ***";
213  lsConfig.surfacesProvider = barrelSurfaces;
214  lsConfig.binnings = {Acts::Experimental::ProtoBinning{
215  Acts::binZ, Acts::detail::AxisBoundaryType::Bound,
216  -480., 480., 14u, 1u},
218  Acts::binPhi, Acts::detail::AxisBoundaryType::Closed,
219  -M_PI, M_PI, 32u, 1u)};
220 
221  auto barrelBuilder =
222  std::make_shared<Acts::Experimental::LayerStructureBuilder>(
223  lsConfig, Acts::getDefaultLogger("BarrelInternalsBuilder",
225 
227  shapeConfig.boundValues = {60., 80., 700., M_PI, 0.};
228  shapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
229 
230  auto shapeBuilder =
231  std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
232  shapeConfig,
233  Acts::getDefaultLogger("BarrelShapeBuilder", Acts::Logging::VERBOSE));
234 
236  dvCfg.name = "BarrelWithSurfaces";
237  dvCfg.externalsBuilder = shapeBuilder;
238  dvCfg.internalsBuilder = barrelBuilder;
239 
240  auto dvBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
241  dvCfg, Acts::getDefaultLogger("BarrelBuilder", Acts::Logging::VERBOSE));
242 
243  // Outer shape
245  outerShapeConfig.boundValues = {80., 100., 700., M_PI, 0.};
246  outerShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
247 
248  auto outerShapeBuilder =
249  std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
250  outerShapeConfig,
251  Acts::getDefaultLogger("OuterShapeBuilder", Acts::Logging::VERBOSE));
252 
254  ovCfg.name = "OuterBarrelGap";
255  ovCfg.externalsBuilder = outerShapeBuilder;
256 
257  auto ovBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
258  ovCfg, Acts::getDefaultLogger("OuterBarrel", Acts::Logging::VERBOSE));
259 
260  // Build the combined barrel
262  ccBarrelBuilderCfg.builders = {ivBuilder, dvBuilder, ovBuilder};
263  ccBarrelBuilderCfg.binning = {Acts::binR};
264 
265  auto ccBarrelBuilder =
266  std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
267  ccBarrelBuilderCfg,
269 
270  // Builder the combined endcap barrel system
272  ccBarrelEcBuilderCfg.builders = {endcapBuilders[0u], ccBarrelBuilder,
273  endcapBuilders[1u]};
274  ccBarrelEcBuilderCfg.binning = {Acts::binZ};
275 
276  auto ccBarrelEndcapBuilder =
277  std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
278  ccBarrelEcBuilderCfg, Acts::getDefaultLogger("BarrelEndcapBuilder",
280 
281  // Beam Pipe
283  bpShapeConfig.boundValues = {0., 20., 720., M_PI, 0.};
284  bpShapeConfig.boundsType = Acts::VolumeBounds::BoundsType::eCylinder;
285 
286  auto bpShapeBuilder =
287  std::make_shared<Acts::Experimental::VolumeStructureBuilder>(
288  bpShapeConfig, Acts::getDefaultLogger("BeamPipeShapeBuilder",
290 
292  bpCfg.name = "BeamPipe";
293  bpCfg.externalsBuilder = bpShapeBuilder;
294 
295  auto bpBuilder = std::make_shared<Acts::Experimental::DetectorVolumeBuilder>(
296  bpCfg, Acts::getDefaultLogger("BeamPipe", Acts::Logging::VERBOSE));
297 
298  // Full detector
300  detCompBuilderCfg.builders = {bpBuilder, ccBarrelEndcapBuilder};
301  detCompBuilderCfg.binning = {Acts::binR};
302 
303  auto detCompBuilder =
304  std::make_shared<Acts::Experimental::CylindricalContainerBuilder>(
305  detCompBuilderCfg);
306 
308  auto gig =
309  std::make_shared<Acts::Experimental::GeometryIdGenerator>(gigConfig);
310 
312  detBuilderCfg.name = "Detector";
313  detBuilderCfg.builder = detCompBuilder;
314  detBuilderCfg.geoIdGenerator = gig;
315 
316  auto detBuilder =
317  std::make_shared<Acts::Experimental::DetectorBuilder>(detBuilderCfg);
318 
319  auto detector = detBuilder->construct(tContext);
320 
321  auto jDetector = Acts::DetectorJsonConverter::toJson(tContext, *detector);
322 
323  std::ofstream out;
324 
325  out.open("barrel-endcap-detector.json");
326  out << jDetector.dump(4);
327  out.close();
328 
329  auto in = std::ifstream("barrel-endcap-detector.json",
330  std::ifstream::in | std::ifstream::binary);
331 
332  BOOST_CHECK(in.good());
333  nlohmann::json jDetectorIn;
334  in >> jDetectorIn;
335  in.close();
336 
337  auto detectorIn =
338  Acts::DetectorJsonConverter::fromJson(tContext, jDetectorIn);
339 
340  BOOST_CHECK(detectorIn->name() == detector->name());
341 
342  auto jDetectorInOut =
343  Acts::DetectorJsonConverter::toJson(tContext, *detectorIn);
344 
345  out.open("barrel-endcap-detector-closure.json");
346  out << jDetectorInOut.dump(4);
347  out.close();
348 
349  auto jDetectorDetray = Acts::DetectorJsonConverter::toJsonDetray(
350  tContext, *detector, detrayOptions());
351 
352  out.open("barrel-endcap-detector-detray.json");
353  out << jDetectorDetray.dump(4);
354  out.close();
355 }
356 
357 BOOST_AUTO_TEST_SUITE_END()