Back to home page

EIC code displayed by LXR

 
 

    


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

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/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   // @TODO: Handle cuboid volume shell here
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& /*binning*/) {
0172             // No output in all other cases
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 }  // namespace Acts