Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-26 07:46:17

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/BlueprintNode.hpp"
0010 
0011 #include "Acts/Geometry/Blueprint.hpp"
0012 #include "Acts/Geometry/ContainerBlueprintNode.hpp"
0013 #include "Acts/Geometry/GeometryIdentifierBlueprintNode.hpp"
0014 #include "Acts/Geometry/LayerBlueprintNode.hpp"
0015 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0016 #include "Acts/Geometry/PortalDesignatorBlueprintNode.hpp"
0017 #include "Acts/Geometry/StaticBlueprintNode.hpp"
0018 #include "Acts/Navigation/INavigationPolicy.hpp"
0019 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0020 
0021 #include <ostream>
0022 
0023 namespace Acts::Experimental {
0024 
0025 namespace {
0026 bool hasDescendent(const BlueprintNode& descendent,
0027                    const BlueprintNode& ancestor) {
0028   if (&descendent == &ancestor) {
0029     return true;
0030   }
0031 
0032   return std::ranges::any_of(ancestor.children(),
0033                              [&](const auto& child) -> bool {
0034                                return hasDescendent(descendent, child);
0035                              });
0036 }
0037 }  // namespace
0038 
0039 void BlueprintNode::toStream(std::ostream& os) const {
0040   os << "BlueprintNode(" << name() << ")";
0041 }
0042 
0043 BlueprintNode& BlueprintNode::addChild(std::shared_ptr<BlueprintNode> child) {
0044   if (!child) {
0045     throw std::invalid_argument("Child is nullptr");
0046   }
0047 
0048   if (dynamic_cast<Blueprint*>(child.get()) != nullptr) {
0049     throw std::invalid_argument("Cannot add a Blueprint as a child");
0050   }
0051 
0052   if (child->depth() != 0) {
0053     throw std::invalid_argument("Child has already been added to another node");
0054   }
0055 
0056   if (hasDescendent(*this, *child)) {
0057     throw std::invalid_argument("Adding child would create a cycle");
0058   }
0059 
0060   child->setDepth(m_depth + 1);
0061   m_children.push_back(std::move(child));
0062   return *this;
0063 }
0064 
0065 BlueprintNode::MutableChildRange BlueprintNode::children() {
0066   return MutableChildRange{m_children};
0067 }
0068 
0069 BlueprintNode::ChildRange BlueprintNode::children() const {
0070   return ChildRange{m_children};
0071 }
0072 
0073 std::size_t BlueprintNode::depth() const {
0074   return m_depth;
0075 }
0076 
0077 void BlueprintNode::setDepth(std::size_t depth) {
0078   m_depth = depth;
0079   for (auto& child : children()) {
0080     child.setDepth(depth + 1);
0081   }
0082 }
0083 
0084 std::string BlueprintNode::indent() const {
0085   return std::string(m_depth * 2, ' ');
0086 }
0087 
0088 std::string BlueprintNode::prefix() const {
0089   return indent() + "[" + name() + "]: ";
0090 }
0091 
0092 StaticBlueprintNode& BlueprintNode::addStaticVolume(
0093     std::unique_ptr<TrackingVolume> volume,
0094     const std::function<void(StaticBlueprintNode& cylinder)>& callback) {
0095   if (!volume) {
0096     throw std::invalid_argument("Volume is nullptr");
0097   }
0098 
0099   auto child = std::make_shared<StaticBlueprintNode>(std::move(volume));
0100   addChild(child);
0101 
0102   if (callback) {
0103     callback(*child);
0104   }
0105   return *child;
0106 }
0107 
0108 StaticBlueprintNode& BlueprintNode::addStaticVolume(
0109     const Transform3& transform, std::shared_ptr<VolumeBounds> volumeBounds,
0110     const std::string& volumeName,
0111     const std::function<void(StaticBlueprintNode& node)>& callback) {
0112   return addStaticVolume(std::make_unique<TrackingVolume>(
0113                              transform, std::move(volumeBounds), volumeName),
0114                          callback);
0115 }
0116 
0117 CylinderContainerBlueprintNode& BlueprintNode::addCylinderContainer(
0118     const std::string& name, AxisDirection direction,
0119     const std::function<void(CylinderContainerBlueprintNode& cylinder)>&
0120         callback) {
0121   auto cylinder =
0122       std::make_shared<CylinderContainerBlueprintNode>(name, direction);
0123   addChild(cylinder);
0124   if (callback) {
0125     callback(*cylinder);
0126   }
0127   return *cylinder;
0128 }
0129 
0130 CuboidContainerBlueprintNode& BlueprintNode::addCuboidContainer(
0131     const std::string& name, AxisDirection direction,
0132     const std::function<void(CuboidContainerBlueprintNode& box)>& callback) {
0133   auto box = std::make_shared<CuboidContainerBlueprintNode>(name, direction);
0134   addChild(box);
0135   if (callback) {
0136     callback(*box);
0137   }
0138   return *box;
0139 }
0140 
0141 MaterialDesignatorBlueprintNode& BlueprintNode::addMaterial(
0142     const std::string& name,
0143     const std::function<void(MaterialDesignatorBlueprintNode& material)>&
0144         callback) {
0145   auto material = std::make_shared<MaterialDesignatorBlueprintNode>(name);
0146   addChild(material);
0147   if (callback) {
0148     callback(*material);
0149   }
0150   return *material;
0151 }
0152 
0153 PortalDesignatorBlueprintNode& BlueprintNode::addPortalDesignator(
0154     const std::string& name,
0155     const std::function<void(PortalDesignatorBlueprintNode& portals)>&
0156         callback) {
0157   auto portals = std::make_shared<PortalDesignatorBlueprintNode>(name);
0158   addChild(portals);
0159   if (callback) {
0160     callback(*portals);
0161   }
0162   return *portals;
0163 }
0164 
0165 LayerBlueprintNode& BlueprintNode::addLayer(
0166     const std::string& name,
0167     const std::function<void(LayerBlueprintNode& layer)>& callback) {
0168   auto layer = std::make_shared<LayerBlueprintNode>(name);
0169   addChild(layer);
0170   if (callback) {
0171     callback(*layer);
0172   }
0173   return *layer;
0174 }
0175 
0176 GeometryIdentifierBlueprintNode& BlueprintNode::withGeometryIdentifier(
0177     const std::function<
0178         void(GeometryIdentifierBlueprintNode& geometryIdentifier)>& callback) {
0179   auto geometryIdentifier = std::make_shared<GeometryIdentifierBlueprintNode>();
0180   addChild(geometryIdentifier);
0181   if (callback) {
0182     callback(*geometryIdentifier);
0183   }
0184   return *geometryIdentifier;
0185 }
0186 
0187 void BlueprintNode::clearChildren() {
0188   for (auto& child : children()) {
0189     child.setDepth(0);
0190   }
0191   m_children.clear();
0192 }
0193 
0194 void BlueprintNode::graphviz(std::ostream& os) const {
0195   os << "digraph BlueprintNode {" << std::endl;
0196   addToGraphviz(os);
0197   os << "}" << std::endl;
0198 }
0199 
0200 void BlueprintNode::addToGraphviz(std::ostream& os) const {
0201   for (const auto& child : children()) {
0202     os << indent() << "\"" << name() << "\" -> \"" << child.name() << "\";"
0203        << std::endl;
0204     child.addToGraphviz(os);
0205   }
0206 }
0207 
0208 }  // namespace Acts::Experimental