Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-06 07:48: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/PadBlueprintNode.hpp"
0010 
0011 #include "Acts/Geometry/CuboidPortalShell.hpp"
0012 #include "Acts/Geometry/CylinderPortalShell.hpp"
0013 #include "Acts/Geometry/Extent.hpp"
0014 
0015 namespace Acts::Experimental {
0016 
0017 PadBlueprintNode::PadBlueprintNode(const std::string &name,
0018                                    const ExtentEnvelope &envelope)
0019     : StaticBlueprintNode(nullptr), m_envelope(envelope), m_name(name) {}
0020 
0021 Volume &PadBlueprintNode::build(const BlueprintOptions &options,
0022                                 const GeometryContext &gctx,
0023                                 const Logger &logger) {
0024   using enum AxisDirection;
0025 
0026   if (children().size() != 1) {
0027     ACTS_ERROR(prefix() << "PadBlueprintNode must have exactly one child, "
0028                            "but has "
0029                         << children().size());
0030     throw std::invalid_argument("PadBlueprintNode must have exactly one child");
0031   }
0032 
0033   Volume &topVolume = children().at(0).build(options, gctx, logger);
0034 
0035   const auto &bounds = topVolume.volumeBounds();
0036 
0037   std::stringstream ss;
0038   bounds.toStream(ss);
0039   ACTS_DEBUG(prefix() << "have top volume: " << ss.str() << "\n"
0040                       << topVolume.localToGlobalTransform(gctx).matrix());
0041 
0042   if (const auto *cyl = dynamic_cast<const CylinderVolumeBounds *>(&bounds);
0043       cyl != nullptr) {
0044     ACTS_VERBOSE(prefix() << "Expanding cylinder bounds");
0045     using enum CylinderVolumeBounds::BoundValues;
0046 
0047     // Make a copy that we'll modify
0048     auto newBounds = std::make_shared<CylinderVolumeBounds>(*cyl);
0049 
0050     const auto &zEnv = m_envelope[AxisZ];
0051     if (zEnv[0] != zEnv[1]) {
0052       ACTS_ERROR(
0053           prefix() << "Root node cylinder envelope for z must be symmetric");
0054       throw std::logic_error(
0055           "Root node cylinder envelope for z must be "
0056           "symmetric");
0057     }
0058 
0059     const auto &rEnv = m_envelope[AxisR];
0060 
0061     newBounds->set({
0062         {eHalfLengthZ, newBounds->get(eHalfLengthZ) + zEnv[0]},
0063         {eMinR, std::max(0.0, newBounds->get(eMinR) - rEnv[0])},
0064         {eMaxR, newBounds->get(eMaxR) + rEnv[1]},
0065     });
0066 
0067     ACTS_DEBUG(prefix() << "Applied envelope to cylinder: Z=" << zEnv[0]
0068                         << ", Rmin=" << rEnv[0] << ", Rmax=" << rEnv[1]);
0069 
0070     m_volume = std::make_unique<TrackingVolume>(
0071         topVolume.localToGlobalTransform(gctx), std::move(newBounds), m_name);
0072 
0073   } else if (const auto *box =
0074                  dynamic_cast<const CuboidVolumeBounds *>(&bounds);
0075              box != nullptr) {
0076     ACTS_VERBOSE(prefix() << "Expanding cuboid bounds");
0077     // Make a copy that we'll modify
0078     auto newBounds = std::make_shared<CuboidVolumeBounds>(*box);
0079 
0080     // Get the current half lengths
0081     double halfX = newBounds->get(CuboidVolumeBounds::eHalfLengthX);
0082     double halfY = newBounds->get(CuboidVolumeBounds::eHalfLengthY);
0083     double halfZ = newBounds->get(CuboidVolumeBounds::eHalfLengthZ);
0084 
0085     // Apply envelope to each dimension
0086     const auto &xEnv = m_envelope[AxisX];
0087     const auto &yEnv = m_envelope[AxisY];
0088     const auto &zEnv = m_envelope[AxisZ];
0089 
0090     // Check if envelopes are symmetric for all dimensions
0091     if (xEnv[0] != xEnv[1]) {
0092       ACTS_ERROR(
0093           prefix() << "Root node cuboid envelope for X must be symmetric");
0094       throw std::logic_error(
0095           "Root node cuboid envelope for X must be symmetric");
0096     }
0097 
0098     if (yEnv[0] != yEnv[1]) {
0099       ACTS_ERROR(
0100           prefix() << "Root node cuboid envelope for Y must be symmetric");
0101       throw std::logic_error(
0102           "Root node cuboid envelope for Y must be symmetric");
0103     }
0104 
0105     if (zEnv[0] != zEnv[1]) {
0106       ACTS_ERROR(
0107           prefix() << "Root node cuboid envelope for Z must be symmetric");
0108       throw std::logic_error(
0109           "Root node cuboid envelope for Z must be symmetric");
0110     }
0111 
0112     newBounds->set({
0113         {CuboidVolumeBounds::eHalfLengthX, halfX + xEnv[0]},
0114         {CuboidVolumeBounds::eHalfLengthY, halfY + yEnv[0]},
0115         {CuboidVolumeBounds::eHalfLengthZ, halfZ + zEnv[0]},
0116     });
0117 
0118     ACTS_DEBUG(prefix() << "Applied envelope to cuboid: X=" << xEnv[0]
0119                         << ", Y=" << yEnv[0] << ", Z=" << zEnv[0]);
0120 
0121     m_volume = std::make_unique<TrackingVolume>(
0122         topVolume.localToGlobalTransform(gctx), std::move(newBounds), m_name);
0123 
0124   } else {
0125     throw std::logic_error{"Unsupported volume bounds type"};
0126   }
0127 
0128   return topVolume;
0129 }
0130 
0131 TrackingVolume *PadBlueprintNode::trackingVolume() const {
0132   return m_volume.get();
0133 }
0134 
0135 }  // namespace Acts::Experimental