Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:19

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