File indexing completed on 2025-01-18 09:11:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0010
0011 #include "Acts/Detector/ProtoBinning.hpp"
0012 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0013 #include "Acts/Geometry/Portal.hpp"
0014 #include "Acts/Material/ProtoSurfaceMaterial.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Utilities/GraphViz.hpp"
0017 #include "Acts/Utilities/Helpers.hpp"
0018
0019 namespace Acts {
0020
0021 const std::string& MaterialDesignatorBlueprintNode::name() const {
0022 return m_name;
0023 }
0024
0025 void MaterialDesignatorBlueprintNode::toStream(std::ostream& os) const {
0026 os << "MaterialDesignatorBlueprintNode(" << name() << ")";
0027 }
0028
0029 Volume& MaterialDesignatorBlueprintNode::build(const BlueprintOptions& options,
0030 const GeometryContext& gctx,
0031 const Logger& logger) {
0032 if (children().size() != 1) {
0033 ACTS_ERROR(prefix() << "MaterialDesignatorBlueprintNode must have exactly "
0034 "one child, but has "
0035 << children().size());
0036 throw std::runtime_error(
0037 "MaterialDesignatorBlueprintNode must have exactly one child");
0038 }
0039
0040 if (!m_binning) {
0041 ACTS_ERROR(prefix() << "Binning is not set");
0042 throw std::runtime_error("Binning is not set");
0043 }
0044
0045 return children().at(0).build(options, gctx, logger);
0046 }
0047
0048 void MaterialDesignatorBlueprintNode::handleCylinderBinning(
0049 CylinderPortalShell& cylShell,
0050 const std::vector<
0051 std::tuple<CylinderPortalShell::Face, Experimental::ProtoBinning,
0052 Experimental::ProtoBinning>>& binning,
0053 const Logger& logger) {
0054 ACTS_DEBUG(prefix() << "Binning is set to compatible type");
0055 using enum CylinderVolumeBounds::Face;
0056
0057 for (auto& [face, loc0, loc1] : binning) {
0058 if (face == OuterCylinder || face == InnerCylinder) {
0059 if (loc0.axisDir != AxisDirection::AxisRPhi) {
0060 ACTS_ERROR(prefix() << "Binning is not in RPhi");
0061 throw std::runtime_error("Binning is not in RPhi");
0062 }
0063
0064 if (loc1.axisDir != AxisDirection::AxisZ) {
0065 ACTS_ERROR(prefix() << "Binning is not in Z");
0066 throw std::runtime_error("Binning is not in Z");
0067 }
0068 }
0069
0070 if (face == PositiveDisc || face == NegativeDisc) {
0071 if (loc0.axisDir != AxisDirection::AxisR) {
0072 ACTS_ERROR(prefix() << "Binning is not in R");
0073 throw std::runtime_error("Binning is not in R");
0074 }
0075 if (loc1.axisDir != AxisDirection::AxisPhi) {
0076 ACTS_ERROR(prefix() << "Binning is not in Phi");
0077 throw std::runtime_error("Binning is not in Phi");
0078 }
0079 }
0080
0081 Experimental::BinningDescription desc{.binning = {loc0, loc1}};
0082 ACTS_DEBUG(prefix() << "~> Assigning proto binning " << desc.toString()
0083 << " to face " << face);
0084
0085 auto material = std::make_shared<ProtoGridSurfaceMaterial>(std::move(desc));
0086
0087 auto portal = cylShell.portal(face);
0088 if (portal == nullptr) {
0089 ACTS_ERROR(prefix() << "Portal is nullptr");
0090 throw std::runtime_error("Portal is nullptr");
0091 }
0092 portal->surface().assignSurfaceMaterial(std::move(material));
0093 }
0094 }
0095
0096 PortalShellBase& MaterialDesignatorBlueprintNode::connect(
0097 const BlueprintOptions& options, const GeometryContext& gctx,
0098 const Logger& logger) {
0099 ACTS_DEBUG(prefix() << "MaterialDesignatorBlueprintNode::connect");
0100 if (children().size() != 1) {
0101 ACTS_ERROR(prefix() << "MaterialDesignatorBlueprintNode must have exactly "
0102 "one child, but has "
0103 << children().size());
0104 throw std::runtime_error(
0105 "MaterialDesignatorBlueprintNode must have exactly one child");
0106 }
0107 if (!m_binning) {
0108 ACTS_ERROR(prefix() << "Binning is not set");
0109 throw std::runtime_error("Binning is not set");
0110 }
0111
0112 auto& shell = children().at(0).connect(options, gctx, logger);
0113
0114 ACTS_DEBUG(prefix() << "Received shell from child "
0115 << children().at(0).name());
0116
0117 if (auto* cylShell = dynamic_cast<CylinderPortalShell*>(&shell)) {
0118 ACTS_DEBUG(prefix() << "Connecting cylinder shell");
0119
0120 if (const auto* binning = std::get_if<std::vector<
0121 std::tuple<CylinderPortalShell::Face, Experimental::ProtoBinning,
0122 Experimental::ProtoBinning>>>(&m_binning.value());
0123 binning != nullptr) {
0124 handleCylinderBinning(*cylShell, *binning, logger);
0125 } else {
0126 ACTS_ERROR(prefix() << "Binning is set to unknown type");
0127 throw std::runtime_error("Unknown binning type");
0128 }
0129
0130 }
0131
0132 else {
0133 ACTS_ERROR(prefix() << "Shell is not supported");
0134 throw std::runtime_error("Shell is not supported");
0135 }
0136
0137 return shell;
0138 }
0139
0140 void MaterialDesignatorBlueprintNode::finalize(const BlueprintOptions& options,
0141 const GeometryContext& gctx,
0142 TrackingVolume& parent,
0143 const Logger& logger) {
0144 if (children().size() != 1) {
0145 throw std::runtime_error(
0146 "MaterialDesignatorBlueprintNode must have exactly one child");
0147 }
0148 return children().at(0).finalize(options, gctx, parent, logger);
0149 }
0150
0151 void MaterialDesignatorBlueprintNode::addToGraphviz(std::ostream& os) const {
0152 if (!m_binning) {
0153 throw std::runtime_error("Binning is not set");
0154 }
0155
0156 std::stringstream ss;
0157 ss << "" + name() + "";
0158 ss << "<br/><i>CylinderContainer</i>";
0159
0160 std::visit(
0161 overloaded{
0162 [&](const std::vector<
0163 std::tuple<CylinderPortalShell::Face, Experimental::ProtoBinning,
0164 Experimental::ProtoBinning>>& binning) {
0165 for (const auto& [face, loc0, loc1] : binning) {
0166 ss << "<br/>" << face;
0167 ss << ": " << loc0.axisDir << "=" << loc0.bins();
0168 ss << ", " << loc1.axisDir << "=" << loc1.bins();
0169 }
0170 },
0171 [](const auto& ) {
0172
0173 }},
0174 m_binning.value());
0175 os << GraphViz::Node{
0176 .id = name(), .label = ss.str(), .shape = GraphViz::Shape::Hexagon};
0177 BlueprintNode::addToGraphviz(os);
0178 }
0179
0180 const std::optional<MaterialDesignatorBlueprintNode::BinningConfig>&
0181 MaterialDesignatorBlueprintNode::binning() const {
0182 return m_binning;
0183 }
0184
0185 MaterialDesignatorBlueprintNode& MaterialDesignatorBlueprintNode::setBinning(
0186 BinningConfig binning) {
0187 m_binning = std::move(binning);
0188 return *this;
0189 }
0190
0191 }