Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-06 07:48:24

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Geometry/PortalDesignatorBlueprintNode.hpp"
0010 
0011 #include "Acts/Geometry/CuboidPortalShell.hpp"
0012 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0013 #include "Acts/Geometry/CylinderPortalShell.hpp"
0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/Portal.hpp"
0016 #include "Acts/Geometry/PortalShell.hpp"
0017 #include "Acts/Utilities/GraphViz.hpp"
0018 
0019 #include "./PortalDesignator.hpp"
0020 
0021 namespace Acts::Experimental {
0022 
0023 namespace detail {
0024 class PortalDesignatorBlueprintNodeImpl {
0025  public:
0026   std::string m_name{};
0027   // Monostate is the null state, where no tags are configured.
0028   PortalTagDesignatorVariant m_designator{std::monostate{}};
0029   // The child shell captured during connect(), tagged during finalize().
0030   PortalShellBase* m_shell{nullptr};
0031 };
0032 
0033 }  // namespace detail
0034 
0035 PortalDesignatorBlueprintNode::PortalDesignatorBlueprintNode(
0036     std::string_view name) {
0037   m_impl = std::make_unique<detail::PortalDesignatorBlueprintNodeImpl>();
0038   m_impl->m_name = name;
0039 }
0040 
0041 const std::string& PortalDesignatorBlueprintNode::name() const {
0042   return impl().m_name;
0043 }
0044 
0045 void PortalDesignatorBlueprintNode::toStream(std::ostream& os) const {
0046   os << "PortalDesignatorBlueprintNode(" << name() << ")";
0047 }
0048 
0049 Volume& PortalDesignatorBlueprintNode::build(const BlueprintOptions& options,
0050                                              const GeometryContext& gctx,
0051                                              const Logger& logger) {
0052   if (children().size() != 1) {
0053     ACTS_ERROR(prefix() << "PortalDesignatorBlueprintNode must have exactly "
0054                            "one child, but has "
0055                         << children().size());
0056     throw std::runtime_error(
0057         "PortalDesignatorBlueprintNode must have exactly one child");
0058   }
0059 
0060   return children().at(0).build(options, gctx, logger);
0061 }
0062 
0063 PortalShellBase& PortalDesignatorBlueprintNode::connect(
0064     const BlueprintOptions& options, const GeometryContext& gctx,
0065     const Logger& logger) {
0066   ACTS_DEBUG(prefix() << "PortalDesignatorBlueprintNode::connect");
0067   if (children().size() != 1) {
0068     ACTS_ERROR(prefix() << "PortalDesignatorBlueprintNode must have exactly "
0069                            "one child, but has "
0070                         << children().size());
0071     throw std::runtime_error(
0072         "PortalDesignatorBlueprintNode must have exactly one child");
0073   }
0074 
0075   auto& shell = children().at(0).connect(options, gctx, logger);
0076 
0077   ACTS_DEBUG(prefix() << "Received shell from child "
0078                       << children().at(0).name());
0079 
0080   // Capture the shell so we can apply tags in finalize(). Tagging cannot happen
0081   // here: parent container nodes may still merge/fuse this shell's portals,
0082   // which replaces the portal objects. By finalize(), the stacking has written
0083   // the final shared portals back into the shell's face slots.
0084   impl().m_shell = &shell;
0085 
0086   return shell;
0087 }
0088 
0089 void PortalDesignatorBlueprintNode::finalize(const BlueprintOptions& options,
0090                                              const GeometryContext& gctx,
0091                                              TrackingVolume& parent,
0092                                              const Logger& logger) {
0093   if (children().size() != 1) {
0094     ACTS_ERROR(prefix() << "PortalDesignatorBlueprintNode must have exactly "
0095                            "one child, but has "
0096                         << children().size());
0097     throw std::runtime_error(
0098         "PortalDesignatorBlueprintNode must have exactly one child");
0099   }
0100 
0101   if (impl().m_shell == nullptr) {
0102     ACTS_ERROR(prefix() << "No shell captured during connect()");
0103     throw std::runtime_error(
0104         "PortalDesignatorBlueprintNode: no shell captured during connect()");
0105   }
0106 
0107   detail::applyTags(impl().m_designator, *impl().m_shell, logger, prefix());
0108 
0109   children().at(0).finalize(options, gctx, parent, logger);
0110 }
0111 
0112 PortalDesignatorBlueprintNode& PortalDesignatorBlueprintNode::tagFace(
0113     CylinderVolumeBounds::Face face, const std::string& label) {
0114   impl().m_designator = detail::mergeTags(
0115       impl().m_designator,
0116       detail::CylinderPortalTagDesignator(face, label, prefix()));
0117   return *this;
0118 }
0119 
0120 PortalDesignatorBlueprintNode& PortalDesignatorBlueprintNode::tagFace(
0121     CuboidVolumeBounds::Face face, const std::string& label) {
0122   impl().m_designator = detail::mergeTags(
0123       impl().m_designator,
0124       detail::CuboidPortalTagDesignator(face, label, prefix()));
0125   return *this;
0126 }
0127 
0128 void PortalDesignatorBlueprintNode::addToGraphviz(std::ostream& os) const {
0129   std::stringstream ss;
0130   ss << "<b>" + name() + "</b>";
0131   ss << "<br/>PortalDesignator";
0132 
0133   detail::graphvizLabelTags(impl().m_designator, ss);
0134 
0135   os << GraphViz::Node{
0136       .id = name(), .label = ss.str(), .shape = GraphViz::Shape::Hexagon};
0137   BlueprintNode::addToGraphviz(os);
0138 }
0139 
0140 detail::PortalDesignatorBlueprintNodeImpl&
0141 PortalDesignatorBlueprintNode::impl() {
0142   if (!m_impl) {
0143     throw std::runtime_error("PortalDesignatorBlueprintNodeImpl is not set");
0144   }
0145   return *m_impl;
0146 }
0147 
0148 const detail::PortalDesignatorBlueprintNodeImpl&
0149 PortalDesignatorBlueprintNode::impl() const {
0150   if (!m_impl) {
0151     throw std::runtime_error("PortalDesignatorBlueprintNodeImpl is not set");
0152   }
0153   return *m_impl;
0154 }
0155 
0156 PortalDesignatorBlueprintNode::~PortalDesignatorBlueprintNode() = default;
0157 
0158 }  // namespace Acts::Experimental