File indexing completed on 2025-07-08 08:11:07
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/GeoModel/GeoModelToDetectorVolume.hpp"
0010
0011 #include "Acts/Detector/GeometryIdGenerator.hpp"
0012 #include "Acts/Detector/PortalGenerators.hpp"
0013 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0014 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0016 #include "Acts/Geometry/GeometryIdentifier.hpp"
0017 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0018 #include "Acts/Navigation/DetectorVolumeFinders.hpp"
0019 #include "Acts/Navigation/InternalNavigation.hpp"
0020
0021 #include <numbers>
0022
0023 #include <GeoModelHelpers/GeoShapeUtils.h>
0024 #include <GeoModelKernel/GeoBox.h>
0025 #include <GeoModelKernel/GeoPcon.h>
0026 #include <GeoModelKernel/GeoShapeShift.h>
0027 #include <GeoModelKernel/GeoShapeSubtraction.h>
0028 #include <GeoModelKernel/GeoShapeUnion.h>
0029 #include <GeoModelKernel/GeoSimplePolygonBrep.h>
0030 #include <GeoModelKernel/GeoTrd.h>
0031 #include <GeoModelKernel/GeoTube.h>
0032 #include <GeoModelKernel/GeoTubs.h>
0033
0034 namespace Acts::GeoModel {
0035
0036 std::shared_ptr<Volume> convertVolume(const Transform3& trf,
0037 const GeoShape* shape,
0038 VolumeBoundFactory& boundFactory) {
0039 assert(shape);
0040 std::shared_ptr<VolumeBounds> bounds{};
0041 GeoTrf::Transform3D newTrf = trf;
0042 const ShapeType id = shape->typeID();
0043 if (id == GeoTube::getClassTypeID()) {
0044 const auto* tube = dynamic_cast<const GeoTube*>(shape);
0045 bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0046 tube->getRMin(), tube->getRMax(), tube->getZHalfLength());
0047 } else if (id == GeoTubs::getClassTypeID()) {
0048 const auto* tubs = dynamic_cast<const GeoTubs*>(shape);
0049 bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0050 tubs->getRMin(), tubs->getRMax(), tubs->getZHalfLength(),
0051 tubs->getDPhi() / 2);
0052 newTrf = trf * GeoTrf::RotateZ3D(tubs->getSPhi() + 0.5 * tubs->getDPhi());
0053 } else if (id == GeoBox::getClassTypeID()) {
0054 const auto* box = dynamic_cast<const GeoBox*>(shape);
0055 bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0056 box->getXHalfLength(), box->getYHalfLength(), box->getZHalfLength());
0057 } else if (id == GeoSimplePolygonBrep::getClassTypeID() ||
0058
0059 id == GeoShapeUnion::getClassTypeID() ||
0060
0061 id == GeoPcon::getClassTypeID()) {
0062 double xmin{0}, xmax{0}, ymin{0}, ymax{0}, zmin{0}, zmax{0};
0063 shape->extent(xmin, ymin, zmin, xmax, ymax, zmax);
0064 bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0065 (xmax - xmin) / 2, (ymax - ymin) / 2, (zmax - zmin) / 2);
0066 } else if (id == GeoTrd::getClassTypeID()) {
0067 const auto* trd = dynamic_cast<const GeoTrd*>(shape);
0068 double x1 = trd->getXHalfLength1();
0069 double x2 = trd->getXHalfLength2();
0070 double y1 = trd->getYHalfLength1();
0071 double y2 = trd->getYHalfLength2();
0072 double z = trd->getZHalfLength();
0073 if (y1 == y2) {
0074 if (x1 <= x2) {
0075
0076 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x1, x2, z, y1);
0077 constexpr double rotationAngle = std::numbers::pi / 2.;
0078 newTrf = trf * GeoTrf::RotateX3D(rotationAngle);
0079 } else {
0080 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x2, x1, z, y1);
0081 constexpr double rotationAngle = std::numbers::pi;
0082 newTrf = trf * GeoTrf::RotateY3D(rotationAngle) *
0083 GeoTrf::RotateZ3D(rotationAngle);
0084 }
0085 } else if (x1 == x2) {
0086 if (y1 < y2) {
0087 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y1, y2, z, x1);
0088 auto rotationAngle = std::numbers::pi / 2.;
0089 newTrf = trf * GeoTrf::RotateZ3D(rotationAngle) *
0090 GeoTrf::RotateX3D(rotationAngle);
0091 } else {
0092 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y2, y1, z, x1);
0093 auto rotationAngle = std::numbers::pi;
0094 newTrf = trf * GeoTrf::RotateX3D(rotationAngle) *
0095 GeoTrf::RotateZ3D(rotationAngle / 2) *
0096 GeoTrf::RotateX3D(rotationAngle / 2);
0097 }
0098 } else {
0099 throw std::runtime_error("convertVolume() - Translating the GeoTrd " +
0100 printGeoShape(shape) + " to ACTS failed");
0101 }
0102
0103 } else if (id == GeoShapeSubtraction::getClassTypeID()) {
0104 return convertVolume(newTrf, getOps(shape).first, boundFactory);
0105 } else if (id == GeoShapeShift::getClassTypeID()) {
0106 auto compressed = compressShift(shape);
0107 if (compressed->typeID() != GeoShapeShift::getClassTypeID()) {
0108 return convertVolume(newTrf, compressed, boundFactory);
0109 }
0110 const auto shiftShape =
0111 dynamic_pointer_cast<const GeoShapeShift>(compressed);
0112 const GeoShape* shapeOp = shiftShape->getOp();
0113 return convertVolume(newTrf * shiftShape->getX(), shapeOp, boundFactory);
0114 } else {
0115 throw std::runtime_error("Cannot convert " + printGeoShape(shape));
0116 }
0117 return std::make_shared<Volume>(newTrf, bounds);
0118 }
0119
0120 std::shared_ptr<Experimental::DetectorVolume> convertDetectorVolume(
0121 const GeometryContext& context, Volume& vol, const std::string& name,
0122 const std::vector<std::shared_ptr<Surface>>& sensitives) {
0123 auto portalGenerator = Experimental::defaultPortalAndSubPortalGenerator();
0124 return Experimental::DetectorVolumeFactory::construct(
0125 portalGenerator, context, name, vol.transform(), vol.volumeBoundsPtr(),
0126 sensitives,
0127 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>{},
0128 Experimental::tryNoVolumes(), Experimental::tryAllPortalsAndSurfaces());
0129 }
0130
0131 }