Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:08:28

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 "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   /// auto-calculate the unit length conversion
0034   static constexpr double unitLength =
0035       UnitConstants::mm / GeoModelKernelUnits::millimeter;
0036 
0037   // Create the surface transform
0038   Transform3 transform = Transform3::Identity();
0039   transform.translation() = unitLength * absTransform.translation();
0040 
0041   // GeoTrd coordinates: x is the extrusion direction, y is orthogonal to the
0042   // symmetry axis and z is along the symmetry axis
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   // The diffs
0050   double diffX = std::abs(halfX2 - halfX1);
0051   double diffY = std::abs(halfY2 - halfY1);
0052 
0053   // If both X and Y are trapezoidal - consider
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   // And its interpretation
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   // This is a convention of the TrapezoidBounds
0067   int swapZ = (maxHalfX < minHalfX) ? -1 : 1;
0068   if (swapZ < 0) {
0069     std::swap(minHalfX, maxHalfX);
0070   }
0071 
0072   // Adjust the rotation matrix
0073   RotationMatrix3 trotation = absTransform.rotation();
0074 
0075   if (diffX > diffY) {
0076     // Rotation is x, z, y ... acyclic, hence the sign change
0077     trotation.col(1) = swapZ * absTransform.rotation().col(2);
0078     trotation.col(2) = -swapZ * absTransform.rotation().col(1);
0079   } else {
0080     // Rotation is y, z, x ... cyclic, hence no sign change
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   // Create the element and the surface
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 }