File indexing completed on 2025-07-12 07:52:51
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/GeoModel/detail/GeoUnionDoubleTrdConverter.hpp"
0010
0011 #include "Acts/Plugins/GeoModel/GeoModelConversionError.hpp"
0012 #include "Acts/Plugins/GeoModel/detail/GeoShiftConverter.hpp"
0013 #include "Acts/Surfaces/PlaneSurface.hpp"
0014 #include "Acts/Surfaces/TrapezoidBounds.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 namespace Acts::detail {
0048
0049 Result<GeoModelSensitiveSurface> GeoUnionDoubleTrdConverter::operator()(
0050 const PVConstLink &geoPV, const GeoShapeUnion &geoUnion,
0051 const Transform3 &absTransform, SurfaceBoundFactory &boundFactory,
0052 bool sensitive) const {
0053 const auto shiftA = dynamic_cast<const GeoShapeShift *>(geoUnion.getOpA());
0054 const auto shiftB = dynamic_cast<const GeoShapeShift *>(geoUnion.getOpB());
0055
0056 if (shiftA == nullptr || shiftB == nullptr) {
0057 return GeoModelConversionError::WrongShapeForConverter;
0058 }
0059
0060 auto shiftARes = detail::GeoShiftConverter{}(geoPV, *shiftA, absTransform,
0061 boundFactory, sensitive);
0062 if (!shiftARes.ok()) {
0063 return shiftARes.error();
0064 }
0065 auto shiftBRes = detail::GeoShiftConverter{}(geoPV, *shiftB, absTransform,
0066 boundFactory, sensitive);
0067 if (!shiftBRes.ok()) {
0068 return shiftBRes.error();
0069 }
0070
0071 const auto &[elA, surfaceA] = shiftARes.value();
0072 const auto &[elB, surfaceB] = shiftBRes.value();
0073
0074 if (!(surfaceA && surfaceB)) {
0075 return GeoModelConversionError::WrongShapeForConverter;
0076 }
0077
0078 if (surfaceA->bounds().type() != Acts::SurfaceBounds::eTrapezoid ||
0079 surfaceB->bounds().type() != Acts::SurfaceBounds::eTrapezoid) {
0080 return GeoModelConversionError::WrongShapeForConverter;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 const auto vtxsa = surfaceA->polyhedronRepresentation({}, 0).vertices;
0099 const auto vtxsb = surfaceB->polyhedronRepresentation({}, 0).vertices;
0100
0101 if (!trapezoidsAreMergeable(vtxsa, vtxsb)) {
0102 return GeoModelConversionError::WrongShapeForConverter;
0103 }
0104
0105
0106
0107 Acts::Vector3 mpA = vtxsa[3] + 0.5 * (vtxsa[2] - vtxsa[3]);
0108 Acts::Vector3 mpB = vtxsb[0] + 0.5 * (vtxsb[1] - vtxsb[0]);
0109
0110 auto halfLengthY = 0.5 * (mpB - mpA).norm();
0111
0112
0113 const auto &boundsA =
0114 static_cast<const TrapezoidBounds &>(surfaceA->bounds());
0115 const auto &boundsB =
0116 static_cast<const TrapezoidBounds &>(surfaceB->bounds());
0117
0118 const auto gap =
0119 halfLengthY - (boundsA.values()[TrapezoidBounds::eHalfLengthY] +
0120 boundsB.values()[TrapezoidBounds::eHalfLengthY]);
0121
0122 if (gap > gapTolerance) {
0123 return GeoModelConversionError::WrongShapeForConverter;
0124 }
0125
0126
0127 auto hlxny = boundsA.values()[TrapezoidBounds::eHalfLengthXposY];
0128 auto hlxpy = boundsB.values()[TrapezoidBounds::eHalfLengthXnegY];
0129
0130 auto trapezoidBounds =
0131 boundFactory.makeBounds<TrapezoidBounds>(hlxpy, hlxny, halfLengthY);
0132
0133
0134
0135 auto transform = surfaceA->transform({});
0136 transform.translate(Vector3{
0137 0.f, boundsA.values()[TrapezoidBounds::eHalfLengthY] - halfLengthY, 0.f});
0138
0139
0140 if (!sensitive) {
0141 auto surface =
0142 Surface::makeShared<PlaneSurface>(transform, trapezoidBounds);
0143 return std::make_tuple(nullptr, surface);
0144 }
0145
0146
0147 auto detectorElement =
0148 GeoModelDetectorElement::createDetectorElement<PlaneSurface>(
0149 geoPV, trapezoidBounds, transform, elA->thickness());
0150 auto surface = detectorElement->surface().getSharedPtr();
0151
0152 return std::make_tuple(detectorElement, surface);
0153 }
0154
0155 }