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