File indexing completed on 2025-08-05 08:10:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/TGeo/TGeoCylinderDiscSplitter.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Plugins/TGeo/TGeoDetectorElement.hpp"
0013 #include "Acts/Surfaces/CylinderBounds.hpp"
0014 #include "Acts/Surfaces/RadialBounds.hpp"
0015 #include "Acts/Surfaces/RectangleBounds.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Surfaces/SurfaceBounds.hpp"
0018 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0019
0020 #include <cmath>
0021 #include <cstdlib>
0022 #include <utility>
0023
0024 Acts::TGeoCylinderDiscSplitter::TGeoCylinderDiscSplitter(
0025 const TGeoCylinderDiscSplitter::Config& cfg,
0026 std::unique_ptr<const Acts::Logger> logger)
0027 : m_cfg(cfg), m_logger(std::move(logger)) {}
0028
0029 std::vector<std::shared_ptr<const Acts::TGeoDetectorElement>>
0030 Acts::TGeoCylinderDiscSplitter::split(
0031 const GeometryContext& gctx,
0032 std::shared_ptr<const Acts::TGeoDetectorElement> tgde) const {
0033 const Acts::Surface& sf = tgde->surface();
0034
0035 auto tgIdentifier = tgde->identifier();
0036 const TGeoNode& tgNode = tgde->tgeoNode();
0037 ActsScalar tgThickness = tgde->thickness();
0038
0039
0040 if (m_cfg.discPhiSegments > 0 || m_cfg.discRadialSegments > 0) {
0041
0042 if (sf.type() == Acts::Surface::Disc &&
0043 sf.bounds().type() == Acts::SurfaceBounds::eDisc) {
0044 ACTS_DEBUG("- splitting detected for a Disc shaped sensor.");
0045
0046 std::vector<std::shared_ptr<const Acts::TGeoDetectorElement>>
0047 tgDetectorElements = {};
0048 tgDetectorElements.reserve(std::abs(m_cfg.discPhiSegments) *
0049 std::abs(m_cfg.discRadialSegments));
0050
0051 const Acts::Vector3 discCenter = sf.center(gctx);
0052
0053 const auto& boundValues = sf.bounds().values();
0054 ActsScalar discMinR = boundValues[Acts::RadialBounds::eMinR];
0055 ActsScalar discMaxR = boundValues[Acts::RadialBounds::eMaxR];
0056
0057 ActsScalar phiStep = 2 * M_PI / m_cfg.discPhiSegments;
0058 ActsScalar cosPhiHalf = std::cos(0.5 * phiStep);
0059 ActsScalar sinPhiHalf = std::sin(0.5 * phiStep);
0060
0061 std::vector<ActsScalar> radialValues = {};
0062 if (m_cfg.discRadialSegments > 1) {
0063 ActsScalar rStep = (discMaxR - discMinR) / m_cfg.discRadialSegments;
0064 radialValues.reserve(m_cfg.discRadialSegments);
0065 for (int ir = 0; ir <= m_cfg.discRadialSegments; ++ir) {
0066 radialValues.push_back(discMinR + ir * rStep);
0067 }
0068 } else {
0069 radialValues = {discMinR, discMaxR};
0070 }
0071
0072 for (std::size_t ir = 1; ir < radialValues.size(); ++ir) {
0073 ActsScalar minR = radialValues[ir - 1];
0074 ActsScalar maxR = radialValues[ir];
0075
0076 ActsScalar maxLocY = maxR * cosPhiHalf;
0077 ActsScalar minLocY = minR * cosPhiHalf;
0078
0079 ActsScalar hR = 0.5 * (maxLocY + minLocY);
0080 ActsScalar hY = 0.5 * (maxLocY - minLocY);
0081 ActsScalar hXminY = minR * sinPhiHalf;
0082 ActsScalar hXmaxY = maxR * sinPhiHalf;
0083
0084 auto tgTrapezoid =
0085 std::make_shared<Acts::TrapezoidBounds>(hXminY, hXmaxY, hY);
0086
0087 for (int im = 0; im < m_cfg.discPhiSegments; ++im) {
0088
0089 ActsScalar phi = -M_PI + im * phiStep;
0090 auto tgTransform =
0091 Transform3(Translation3(hR * std::cos(phi), hR * std::sin(phi),
0092 discCenter.z()) *
0093 AngleAxis3(phi - 0.5 * M_PI, Vector3::UnitZ()));
0094
0095
0096 auto tgDetectorElement = std::make_shared<Acts::TGeoDetectorElement>(
0097 tgIdentifier, tgNode, tgTransform, tgTrapezoid, tgThickness);
0098
0099 tgDetectorElements.push_back(tgDetectorElement);
0100 }
0101 }
0102
0103 return tgDetectorElements;
0104 }
0105 }
0106
0107
0108 if (m_cfg.cylinderPhiSegments > 0 || m_cfg.cylinderLongitudinalSegments > 0) {
0109 if (sf.type() == Acts::Surface::Cylinder &&
0110 sf.bounds().type() == Acts::SurfaceBounds::eCylinder) {
0111 ACTS_DEBUG("- splitting detected for a Cylinder shaped sensor.");
0112
0113 std::vector<std::shared_ptr<const Acts::TGeoDetectorElement>>
0114 tgDetectorElements = {};
0115 tgDetectorElements.reserve(std::abs(m_cfg.cylinderPhiSegments) *
0116 std::abs(m_cfg.cylinderLongitudinalSegments));
0117
0118 const auto& boundValues = sf.bounds().values();
0119 ActsScalar cylinderR = boundValues[Acts::CylinderBounds::eR];
0120 ActsScalar cylinderHalfZ =
0121 boundValues[Acts::CylinderBounds::eHalfLengthZ];
0122
0123 ActsScalar phiStep = 2 * M_PI / m_cfg.cylinderPhiSegments;
0124 ActsScalar cosPhiHalf = std::cos(0.5 * phiStep);
0125 ActsScalar sinPhiHalf = std::sin(0.5 * phiStep);
0126
0127 std::vector<ActsScalar> zValues = {};
0128 if (m_cfg.cylinderLongitudinalSegments > 1) {
0129 ActsScalar zStep =
0130 2 * cylinderHalfZ / m_cfg.cylinderLongitudinalSegments;
0131 zValues.reserve(m_cfg.cylinderLongitudinalSegments);
0132 for (int ir = 0; ir <= m_cfg.cylinderLongitudinalSegments; ++ir) {
0133 zValues.push_back(-cylinderHalfZ + ir * zStep);
0134 }
0135 } else {
0136 zValues = {-cylinderHalfZ, cylinderHalfZ};
0137 }
0138
0139 ActsScalar planeR = cylinderR * cosPhiHalf;
0140 ActsScalar planeHalfX = cylinderR * sinPhiHalf;
0141
0142 for (std::size_t iz = 1; iz < zValues.size(); ++iz) {
0143 ActsScalar minZ = zValues[iz - 1];
0144 ActsScalar maxZ = zValues[iz];
0145
0146 ActsScalar planeZ = 0.5 * (minZ + maxZ);
0147 ActsScalar planeHalfY = 0.5 * (maxZ - minZ);
0148
0149 auto tgRectangle =
0150 std::make_shared<Acts::RectangleBounds>(planeHalfX, planeHalfY);
0151
0152 for (int im = 0; im < m_cfg.cylinderPhiSegments; ++im) {
0153
0154 ActsScalar phi = -M_PI + im * phiStep;
0155 ActsScalar cosPhi = std::cos(phi);
0156 ActsScalar sinPhi = std::sin(phi);
0157 ActsScalar planeX = planeR * cosPhi;
0158 ActsScalar planeY = planeR * sinPhi;
0159
0160 Acts::Vector3 planeCenter(planeX, planeY, planeZ);
0161 Acts::Vector3 planeAxisZ = {cosPhi, sinPhi, 0.};
0162 Acts::Vector3 planeAxisY{0., 0., 1.};
0163 Acts::Vector3 planeAxisX = planeAxisY.cross(planeAxisZ);
0164
0165 RotationMatrix3 planeRotation;
0166 planeRotation.col(0) = planeAxisX;
0167 planeRotation.col(1) = planeAxisY;
0168 planeRotation.col(2) = planeAxisZ;
0169
0170
0171 Transform3 planeTransform{planeRotation};
0172 planeTransform.pretranslate(planeCenter);
0173
0174 Transform3 tgTransform = planeTransform;
0175
0176
0177 auto tgDetectorElement = std::make_shared<Acts::TGeoDetectorElement>(
0178 tgIdentifier, tgNode, tgTransform, tgRectangle, tgThickness);
0179
0180 tgDetectorElements.push_back(tgDetectorElement);
0181 }
0182 }
0183 return tgDetectorElements;
0184 }
0185 }
0186 return {tgde};
0187 }