File indexing completed on 2026-07-06 07:48:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/PadBlueprintNode.hpp"
0010
0011 #include "Acts/Geometry/CuboidPortalShell.hpp"
0012 #include "Acts/Geometry/CylinderPortalShell.hpp"
0013 #include "Acts/Geometry/Extent.hpp"
0014
0015 namespace Acts::Experimental {
0016
0017 PadBlueprintNode::PadBlueprintNode(const std::string &name,
0018 const ExtentEnvelope &envelope)
0019 : StaticBlueprintNode(nullptr), m_envelope(envelope), m_name(name) {}
0020
0021 Volume &PadBlueprintNode::build(const BlueprintOptions &options,
0022 const GeometryContext &gctx,
0023 const Logger &logger) {
0024 using enum AxisDirection;
0025
0026 if (children().size() != 1) {
0027 ACTS_ERROR(prefix() << "PadBlueprintNode must have exactly one child, "
0028 "but has "
0029 << children().size());
0030 throw std::invalid_argument("PadBlueprintNode must have exactly one child");
0031 }
0032
0033 Volume &topVolume = children().at(0).build(options, gctx, logger);
0034
0035 const auto &bounds = topVolume.volumeBounds();
0036
0037 std::stringstream ss;
0038 bounds.toStream(ss);
0039 ACTS_DEBUG(prefix() << "have top volume: " << ss.str() << "\n"
0040 << topVolume.localToGlobalTransform(gctx).matrix());
0041
0042 if (const auto *cyl = dynamic_cast<const CylinderVolumeBounds *>(&bounds);
0043 cyl != nullptr) {
0044 ACTS_VERBOSE(prefix() << "Expanding cylinder bounds");
0045 using enum CylinderVolumeBounds::BoundValues;
0046
0047
0048 auto newBounds = std::make_shared<CylinderVolumeBounds>(*cyl);
0049
0050 const auto &zEnv = m_envelope[AxisZ];
0051 if (zEnv[0] != zEnv[1]) {
0052 ACTS_ERROR(
0053 prefix() << "Root node cylinder envelope for z must be symmetric");
0054 throw std::logic_error(
0055 "Root node cylinder envelope for z must be "
0056 "symmetric");
0057 }
0058
0059 const auto &rEnv = m_envelope[AxisR];
0060
0061 newBounds->set({
0062 {eHalfLengthZ, newBounds->get(eHalfLengthZ) + zEnv[0]},
0063 {eMinR, std::max(0.0, newBounds->get(eMinR) - rEnv[0])},
0064 {eMaxR, newBounds->get(eMaxR) + rEnv[1]},
0065 });
0066
0067 ACTS_DEBUG(prefix() << "Applied envelope to cylinder: Z=" << zEnv[0]
0068 << ", Rmin=" << rEnv[0] << ", Rmax=" << rEnv[1]);
0069
0070 m_volume = std::make_unique<TrackingVolume>(
0071 topVolume.localToGlobalTransform(gctx), std::move(newBounds), m_name);
0072
0073 } else if (const auto *box =
0074 dynamic_cast<const CuboidVolumeBounds *>(&bounds);
0075 box != nullptr) {
0076 ACTS_VERBOSE(prefix() << "Expanding cuboid bounds");
0077
0078 auto newBounds = std::make_shared<CuboidVolumeBounds>(*box);
0079
0080
0081 double halfX = newBounds->get(CuboidVolumeBounds::eHalfLengthX);
0082 double halfY = newBounds->get(CuboidVolumeBounds::eHalfLengthY);
0083 double halfZ = newBounds->get(CuboidVolumeBounds::eHalfLengthZ);
0084
0085
0086 const auto &xEnv = m_envelope[AxisX];
0087 const auto &yEnv = m_envelope[AxisY];
0088 const auto &zEnv = m_envelope[AxisZ];
0089
0090
0091 if (xEnv[0] != xEnv[1]) {
0092 ACTS_ERROR(
0093 prefix() << "Root node cuboid envelope for X must be symmetric");
0094 throw std::logic_error(
0095 "Root node cuboid envelope for X must be symmetric");
0096 }
0097
0098 if (yEnv[0] != yEnv[1]) {
0099 ACTS_ERROR(
0100 prefix() << "Root node cuboid envelope for Y must be symmetric");
0101 throw std::logic_error(
0102 "Root node cuboid envelope for Y must be symmetric");
0103 }
0104
0105 if (zEnv[0] != zEnv[1]) {
0106 ACTS_ERROR(
0107 prefix() << "Root node cuboid envelope for Z must be symmetric");
0108 throw std::logic_error(
0109 "Root node cuboid envelope for Z must be symmetric");
0110 }
0111
0112 newBounds->set({
0113 {CuboidVolumeBounds::eHalfLengthX, halfX + xEnv[0]},
0114 {CuboidVolumeBounds::eHalfLengthY, halfY + yEnv[0]},
0115 {CuboidVolumeBounds::eHalfLengthZ, halfZ + zEnv[0]},
0116 });
0117
0118 ACTS_DEBUG(prefix() << "Applied envelope to cuboid: X=" << xEnv[0]
0119 << ", Y=" << yEnv[0] << ", Z=" << zEnv[0]);
0120
0121 m_volume = std::make_unique<TrackingVolume>(
0122 topVolume.localToGlobalTransform(gctx), std::move(newBounds), m_name);
0123
0124 } else {
0125 throw std::logic_error{"Unsupported volume bounds type"};
0126 }
0127
0128 return topVolume;
0129 }
0130
0131 TrackingVolume *PadBlueprintNode::trackingVolume() const {
0132 return m_volume.get();
0133 }
0134
0135 }