Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-02 07:51:08

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/LayerBlueprintNode.hpp"
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0013 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0014 #include "Acts/Geometry/ProtoLayer.hpp"
0015 #include "Acts/Geometry/VolumeBounds.hpp"
0016 #include "Acts/Utilities/GraphViz.hpp"
0017 
0018 namespace Acts::Experimental {
0019 
0020 namespace detail {
0021 struct LayerBlueprintNodeImpl {
0022   using LayerType = LayerBlueprintNode::LayerType;
0023 
0024   std::string m_name;
0025 
0026   std::vector<std::shared_ptr<Surface>> m_surfaces{};
0027 
0028   /// If a proto layer is already given externally, this node will not perform
0029   /// sizing from surfaces
0030   std::optional<MutableProtoLayer> m_protoLayer;
0031 
0032   Transform3 m_transform = Transform3::Identity();
0033   ExtentEnvelope m_envelope = ExtentEnvelope::Zero();
0034   LayerType m_layerType = LayerType::Cylinder;
0035   std::array<bool, 3> m_useCenterOfGravity = {true, true, true};
0036 };
0037 }  // namespace detail
0038 
0039 LayerBlueprintNode::LayerBlueprintNode(std::string_view name)
0040     : StaticBlueprintNode(nullptr) {
0041   m_impl = std::make_unique<detail::LayerBlueprintNodeImpl>();
0042   m_impl->m_name = name;
0043 }
0044 
0045 LayerBlueprintNode::~LayerBlueprintNode() = default;
0046 
0047 detail::LayerBlueprintNodeImpl& LayerBlueprintNode::impl() {
0048   assert(m_impl != nullptr);
0049   return *m_impl;
0050 }
0051 
0052 const detail::LayerBlueprintNodeImpl& LayerBlueprintNode::impl() const {
0053   assert(m_impl != nullptr);
0054   return *m_impl;
0055 }
0056 
0057 Volume& LayerBlueprintNode::build(const BlueprintOptions& options,
0058                                   const GeometryContext& gctx,
0059                                   const Logger& logger) {
0060   if (impl().m_surfaces.empty()) {
0061     ACTS_ERROR("LayerBlueprintNode: no surfaces provided");
0062     throw std::invalid_argument("LayerBlueprintNode: no surfaces provided");
0063   }
0064 
0065   ACTS_DEBUG(prefix() << "Building Layer " << name() << " from "
0066                       << impl().m_surfaces.size() << " surfaces");
0067   ACTS_VERBOSE(prefix() << " -> layer type: " << impl().m_layerType);
0068   ACTS_VERBOSE(prefix() << " -> transform:\n" << impl().m_transform.matrix());
0069 
0070   Extent extent;
0071 
0072   if (!impl().m_protoLayer.has_value()) {
0073     impl().m_protoLayer.emplace(gctx, impl().m_surfaces,
0074                                 impl().m_transform.inverse());
0075     ACTS_VERBOSE(prefix() << "Built proto layer: "
0076                           << impl().m_protoLayer.value());
0077   } else {
0078     ACTS_VERBOSE(prefix() << "Using provided proto layer");
0079   }
0080 
0081   auto& protoLayer = impl().m_protoLayer.value();
0082   extent.addConstrain(protoLayer.extent, impl().m_envelope);
0083 
0084   ACTS_VERBOSE(prefix() << " -> layer extent: " << extent);
0085 
0086   buildVolume(extent, logger);
0087   assert(m_volume != nullptr && "Volume not built from proto layer");
0088 
0089   for (auto& surface : impl().m_surfaces) {
0090     m_volume->addSurface(surface);
0091   }
0092 
0093   return StaticBlueprintNode::build(options, gctx, logger);
0094 }
0095 
0096 void LayerBlueprintNode::buildVolume(const Extent& extent,
0097                                      const Logger& logger) {
0098   ACTS_VERBOSE(prefix() << "Building volume for layer " << name());
0099   using enum AxisDirection;
0100   using enum LayerType;
0101 
0102   std::shared_ptr<VolumeBounds> bounds;
0103   switch (impl().m_layerType) {
0104     case Cylinder:
0105     case Disc: {
0106       double minR = extent.min(AxisR);
0107       double maxR = extent.max(AxisR);
0108       double hlZ = extent.interval(AxisZ) / 2.0;
0109       bounds = std::make_shared<CylinderVolumeBounds>(minR, maxR, hlZ);
0110       break;
0111     }
0112     case Plane: {
0113       double hlX = extent.interval(AxisX) / 2.0;
0114       double hlY = extent.interval(AxisY) / 2.0;
0115       double hlZ = extent.interval(AxisZ) / 2.0;
0116       bounds = std::make_shared<CuboidVolumeBounds>(hlX, hlY, hlZ);
0117       break;
0118     }
0119   }
0120 
0121   assert(bounds != nullptr);
0122 
0123   ACTS_VERBOSE(prefix() << " -> bounds: " << *bounds);
0124 
0125   Transform3 transform = impl().m_transform;
0126   Vector3 translation = Vector3::Zero();
0127   if (impl().m_useCenterOfGravity.at(toUnderlying(AxisX))) {
0128     translation.x() = extent.medium(AxisX);
0129   }
0130   if (impl().m_useCenterOfGravity.at(toUnderlying(AxisY))) {
0131     translation.y() = extent.medium(AxisY);
0132   }
0133   if (impl().m_useCenterOfGravity.at(toUnderlying(AxisZ))) {
0134     translation.z() = extent.medium(AxisZ);
0135   }
0136 
0137   transform.translation() = translation;
0138 
0139   ACTS_VERBOSE(prefix() << " -> adjusted transform:\n" << transform.matrix());
0140 
0141   m_volume = std::make_unique<TrackingVolume>(transform, std::move(bounds),
0142                                               impl().m_name);
0143 }
0144 
0145 const std::string& LayerBlueprintNode::name() const {
0146   return impl().m_name;
0147 }
0148 
0149 LayerBlueprintNode& LayerBlueprintNode::setSurfaces(
0150     std::vector<std::shared_ptr<Surface>> surfaces) {
0151   impl().m_surfaces = std::move(surfaces);
0152   impl().m_protoLayer.reset();
0153   return *this;
0154 }
0155 
0156 const std::vector<std::shared_ptr<Surface>>& LayerBlueprintNode::surfaces()
0157     const {
0158   return impl().m_surfaces;
0159 }
0160 
0161 LayerBlueprintNode& LayerBlueprintNode::setProtoLayer(
0162     std::optional<MutableProtoLayer> protoLayer) {
0163   impl().m_protoLayer = std::move(protoLayer);
0164   impl().m_surfaces.clear();
0165   // also take ownership of the surfaces now
0166   for (auto& surface : impl().m_protoLayer.value().surfaces()) {
0167     impl().m_surfaces.push_back(surface->getSharedPtr());
0168   }
0169   return *this;
0170 }
0171 
0172 const MutableProtoLayer* LayerBlueprintNode::protoLayer() const {
0173   return impl().m_protoLayer.has_value() ? &impl().m_protoLayer.value()
0174                                          : nullptr;
0175 }
0176 
0177 LayerBlueprintNode& LayerBlueprintNode::setTransform(
0178     const Transform3& transform) {
0179   impl().m_transform = transform;
0180   return *this;
0181 }
0182 
0183 const Transform3& LayerBlueprintNode::transform() const {
0184   return impl().m_transform;
0185 }
0186 
0187 LayerBlueprintNode& LayerBlueprintNode::setEnvelope(
0188     const ExtentEnvelope& envelope) {
0189   impl().m_envelope = envelope;
0190   return *this;
0191 }
0192 
0193 const ExtentEnvelope& LayerBlueprintNode::envelope() const {
0194   return impl().m_envelope;
0195 }
0196 
0197 LayerBlueprintNode& LayerBlueprintNode::setLayerType(LayerType layerType) {
0198   impl().m_layerType = layerType;
0199   return *this;
0200 }
0201 
0202 const LayerBlueprintNode::LayerType& LayerBlueprintNode::layerType() const {
0203   return impl().m_layerType;
0204 }
0205 
0206 LayerBlueprintNode& LayerBlueprintNode::setUseCenterOfGravity(bool x, bool y,
0207                                                               bool z) {
0208   impl().m_useCenterOfGravity = {x, y, z};
0209   return *this;
0210 }
0211 
0212 void LayerBlueprintNode::addToGraphviz(std::ostream& os) const {
0213   std::stringstream ss;
0214   ss << "<br/><b>" + name() + "</b>";
0215   ss << "<br/>Layer";
0216   ss << "<br/><i>" << impl().m_layerType << "</i>";
0217 
0218   GraphViz::Node node{
0219       .id = name(), .label = ss.str(), .shape = GraphViz::Shape::Diamond};
0220 
0221   os << node;
0222 
0223   BlueprintNode::addToGraphviz(os);
0224 }
0225 
0226 }  // namespace Acts::Experimental