File indexing completed on 2025-10-28 07:55:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsPlugins/GeoModel/detail/GeoUnionDoubleTrdConverter.hpp"
0010
0011 #include "Acts/Surfaces/PlaneSurface.hpp"
0012 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0013 #include "ActsPlugins/GeoModel/GeoModelConversionError.hpp"
0014 #include "ActsPlugins/GeoModel/detail/GeoShiftConverter.hpp"
0015
0016 namespace {
0017
0018 auto distanceLinePoint(const Acts::Vector3 &lineA, const Acts::Vector3 &lineB,
0019 const Acts::Vector3 &p) {
0020 auto dir = lineB - lineA;
0021 auto ap = p - lineA;
0022 return ap.cross(dir).norm() / dir.norm();
0023 }
0024
0025
0026 bool trapezoidsAreMergeable(const std::vector<Acts::Vector3> &vtxsa,
0027 const std::vector<Acts::Vector3> &vtxsb) {
0028
0029
0030
0031 auto P1 = vtxsa[0] + 0.5 * (vtxsb[3] - vtxsa[0]);
0032 auto dist1 = distanceLinePoint(vtxsa[3], vtxsb[0], P1);
0033
0034 auto P2 = vtxsa[1] + 0.5 * (vtxsb[2] - vtxsa[1]);
0035 auto dist2 = distanceLinePoint(vtxsa[2], vtxsb[1], P2);
0036
0037 if (dist1 > 1.e-3 || dist2 > 1.e-3) {
0038 return false;
0039 }
0040
0041
0042 return true;
0043 }
0044
0045 }
0046
0047 using namespace Acts;
0048
0049 namespace ActsPlugins::detail {
0050
0051 Result<GeoModelSensitiveSurface> GeoUnionDoubleTrdConverter::operator()(
0052 const PVConstLink &geoPV, const GeoShapeUnion &geoUnion,
0053 const Transform3 &absTransform, SurfaceBoundFactory &boundFactory,
0054 bool sensitive) const {
0055 const auto shiftA = dynamic_cast<const GeoShapeShift *>(geoUnion.getOpA());
0056 const auto shiftB = dynamic_cast<const GeoShapeShift *>(geoUnion.getOpB());
0057
0058 if (shiftA == nullptr || shiftB == nullptr) {
0059 return GeoModelConversionError::WrongShapeForConverter;
0060 }
0061
0062 auto shiftARes = detail::GeoShiftConverter{}(geoPV, *shiftA, absTransform,
0063 boundFactory, sensitive);
0064 if (!shiftARes.ok()) {
0065 return shiftARes.error();
0066 }
0067 auto shiftBRes = detail::GeoShiftConverter{}(geoPV, *shiftB, absTransform,
0068 boundFactory, sensitive);
0069 if (!shiftBRes.ok()) {
0070 return shiftBRes.error();
0071 }
0072
0073 const auto &[elA, surfaceA] = shiftARes.value();
0074 const auto &[elB, surfaceB] = shiftBRes.value();
0075
0076 if (!(surfaceA && surfaceB)) {
0077 return GeoModelConversionError::WrongShapeForConverter;
0078 }
0079
0080 if (surfaceA->bounds().type() != Acts::SurfaceBounds::eTrapezoid ||
0081 surfaceB->bounds().type() != Acts::SurfaceBounds::eTrapezoid) {
0082 return GeoModelConversionError::WrongShapeForConverter;
0083 }
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 const auto vtxsa = surfaceA->polyhedronRepresentation({}, 0).vertices;
0101 const auto vtxsb = surfaceB->polyhedronRepresentation({}, 0).vertices;
0102
0103 if (!trapezoidsAreMergeable(vtxsa, vtxsb)) {
0104 return GeoModelConversionError::WrongShapeForConverter;
0105 }
0106
0107
0108
0109 Acts::Vector3 mpA = vtxsa[3] + 0.5 * (vtxsa[2] - vtxsa[3]);
0110 Acts::Vector3 mpB = vtxsb[0] + 0.5 * (vtxsb[1] - vtxsb[0]);
0111
0112 auto halfLengthY = 0.5 * (mpB - mpA).norm();
0113
0114
0115 const auto &boundsA =
0116 static_cast<const TrapezoidBounds &>(surfaceA->bounds());
0117 const auto &boundsB =
0118 static_cast<const TrapezoidBounds &>(surfaceB->bounds());
0119
0120 const auto gap =
0121 halfLengthY - (boundsA.values()[TrapezoidBounds::eHalfLengthY] +
0122 boundsB.values()[TrapezoidBounds::eHalfLengthY]);
0123
0124 if (gap > gapTolerance) {
0125 return GeoModelConversionError::WrongShapeForConverter;
0126 }
0127
0128
0129 auto hlxny = boundsA.values()[TrapezoidBounds::eHalfLengthXposY];
0130 auto hlxpy = boundsB.values()[TrapezoidBounds::eHalfLengthXnegY];
0131
0132 auto trapezoidBounds =
0133 boundFactory.makeBounds<TrapezoidBounds>(hlxpy, hlxny, halfLengthY);
0134
0135
0136
0137 auto transform = surfaceA->transform({});
0138 transform.translate(Vector3{
0139 0.f, boundsA.values()[TrapezoidBounds::eHalfLengthY] - halfLengthY, 0.f});
0140
0141
0142 if (!sensitive) {
0143 auto surface =
0144 Surface::makeShared<PlaneSurface>(transform, trapezoidBounds);
0145 return std::make_tuple(nullptr, surface);
0146 }
0147
0148
0149 auto detectorElement =
0150 GeoModelDetectorElement::createDetectorElement<PlaneSurface>(
0151 geoPV, trapezoidBounds, transform, elA->thickness());
0152 auto surface = detectorElement->surface().getSharedPtr();
0153
0154 return std::make_tuple(detectorElement, surface);
0155 }
0156
0157 }