File indexing completed on 2026-07-16 08:08:28
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsPlugins/GeoModel/detail/GeoTrdConverter.hpp"
0010
0011 #include "Acts/Definitions/Common.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/Surfaces/PlaneSurface.hpp"
0014 #include "Acts/Surfaces/RectangleBounds.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0017 #include "ActsPlugins/GeoModel/GeoModelConversionError.hpp"
0018
0019 #include <GeoModelKernel/GeoBox.h>
0020 #include <GeoModelKernel/GeoFullPhysVol.h>
0021 #include <GeoModelKernel/GeoLogVol.h>
0022 #include <GeoModelKernel/GeoShape.h>
0023 #include <GeoModelKernel/GeoTrd.h>
0024 #include <GeoModelKernel/Units.h>
0025
0026 using namespace Acts;
0027
0028 Result<ActsPlugins::GeoModelSensitiveSurface>
0029 ActsPlugins::detail::GeoTrdConverter::operator()(
0030 const PVConstLink& geoPV, const GeoTrd& geoTrd,
0031 const Transform3& absTransform, SurfaceBoundFactory& boundFactory,
0032 bool sensitive) const {
0033
0034 static constexpr double unitLength =
0035 UnitConstants::mm / GeoModelKernelUnits::millimeter;
0036
0037
0038 Transform3 transform = Transform3::Identity();
0039 transform.translation() = unitLength * absTransform.translation();
0040
0041
0042
0043 double halfX1 = geoTrd.getXHalfLength1();
0044 double halfX2 = geoTrd.getXHalfLength2();
0045 double halfY1 = geoTrd.getYHalfLength1();
0046 double halfY2 = geoTrd.getYHalfLength2();
0047 double halfZ = geoTrd.getZHalfLength();
0048
0049
0050 double diffX = std::abs(halfX2 - halfX1);
0051 double diffY = std::abs(halfY2 - halfY1);
0052
0053
0054 if (diffX > 2 * std::numeric_limits<double>::epsilon() &&
0055 diffY > 2 * std::numeric_limits<double>::epsilon()) {
0056 throw std::invalid_argument(
0057 "GeoModelSurfaceConverter: GeoTrd conversion to Trapezoid "
0058 "ambiguous.");
0059 }
0060
0061
0062 double minHalfX = unitLength * (diffX > diffY ? halfX1 : halfY1);
0063 double maxHalfX = unitLength * (diffX > diffY ? halfX2 : halfY2);
0064 double thickness = unitLength * (diffX > diffY ? diffY : diffX);
0065
0066
0067 int swapZ = (maxHalfX < minHalfX) ? -1 : 1;
0068 if (swapZ < 0) {
0069 std::swap(minHalfX, maxHalfX);
0070 }
0071
0072
0073 RotationMatrix3 trotation = absTransform.rotation();
0074
0075 if (diffX > diffY) {
0076
0077 trotation.col(1) = swapZ * absTransform.rotation().col(2);
0078 trotation.col(2) = -swapZ * absTransform.rotation().col(1);
0079 } else {
0080
0081 trotation.col(0) = absTransform.rotation().col(1);
0082 trotation.col(1) = swapZ * absTransform.rotation().col(2);
0083 trotation.col(2) = swapZ * absTransform.rotation().col(0);
0084 }
0085 transform.linear() = trotation;
0086
0087 auto trapezoidBounds =
0088 boundFactory.makeBounds<TrapezoidBounds>(minHalfX, maxHalfX, halfZ);
0089
0090 if (!sensitive) {
0091 auto surface =
0092 Surface::makeShared<PlaneSurface>(transform, trapezoidBounds);
0093 return std::make_tuple(nullptr, surface);
0094 }
0095
0096
0097
0098 auto detectorElement =
0099 GeoModelDetectorElement::createDetectorElement<PlaneSurface>(
0100 geoPV, trapezoidBounds, transform, thickness);
0101 auto surface = detectorElement->surface().getSharedPtr();
0102 return std::make_tuple(detectorElement, surface);
0103 }