File indexing completed on 2025-02-22 09:35:01
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 <GeoModelKernel/GeoBox.h>
0024 #include <GeoModelKernel/GeoPcon.h>
0025 #include <GeoModelKernel/GeoShapeShift.h>
0026 #include <GeoModelKernel/GeoShapeSubtraction.h>
0027 #include <GeoModelKernel/GeoShapeUnion.h>
0028 #include <GeoModelKernel/GeoSimplePolygonBrep.h>
0029 #include <GeoModelKernel/GeoTrd.h>
0030 #include <GeoModelKernel/GeoTube.h>
0031 #include <GeoModelKernel/GeoTubs.h>
0032
0033 namespace Acts::GeoModel {
0034 Volume convertVolume(const Transform3& trf, const GeoShape& shape) {
0035 std::shared_ptr<VolumeBounds> bounds;
0036 GeoTrf::Transform3D newTrf = trf;
0037 if (shape.typeID() == GeoTube::getClassTypeID()) {
0038 const GeoTube* tube = dynamic_cast<const GeoTube*>(&shape);
0039 bounds = std::make_shared<CylinderVolumeBounds>(
0040 tube->getRMin(), tube->getRMax(), tube->getZHalfLength());
0041 } else if (shape.typeID() == GeoTubs::getClassTypeID()) {
0042 const GeoTubs* tubs = dynamic_cast<const GeoTubs*>(&shape);
0043 bounds = std::make_shared<CylinderVolumeBounds>(
0044 tubs->getRMin(), tubs->getRMax(), tubs->getZHalfLength(),
0045 tubs->getDPhi() / 2);
0046 newTrf = trf * GeoTrf::RotateZ3D(tubs->getSPhi() + 0.5 * tubs->getDPhi());
0047 } else if (shape.typeID() == GeoBox::getClassTypeID()) {
0048 const GeoBox* box = dynamic_cast<const GeoBox*>(&shape);
0049 bounds = std::make_shared<CuboidVolumeBounds>(
0050 box->getXHalfLength(), box->getYHalfLength(), box->getZHalfLength());
0051 } else if (shape.typeID() == GeoSimplePolygonBrep::getClassTypeID()) {
0052 const GeoSimplePolygonBrep* brep =
0053 dynamic_cast<const GeoSimplePolygonBrep*>(&shape);
0054 double xmin{0}, xmax{0}, ymin{0}, ymax{0}, zmin{0}, zmax{0};
0055 brep->extent(xmin, ymin, zmin, xmax, ymax, zmax);
0056 bounds = std::make_shared<CuboidVolumeBounds>(
0057 (xmax - xmin) / 2, (ymax - ymin) / 2, (zmax - zmin) / 2);
0058 } else if (shape.typeID() == GeoTrd::getClassTypeID()) {
0059 const GeoTrd* trd = dynamic_cast<const GeoTrd*>(&shape);
0060 double x1 = trd->getXHalfLength1();
0061 double x2 = trd->getXHalfLength2();
0062 double y1 = trd->getYHalfLength1();
0063 double y2 = trd->getYHalfLength2();
0064 double z = trd->getZHalfLength();
0065
0066 if (y1 == y2) {
0067 if (x1 <= x2) {
0068
0069 bounds = std::make_shared<TrapezoidVolumeBounds>(x1, x2, z, y1);
0070 constexpr double rotationAngle = std::numbers::pi / 2.;
0071 newTrf = trf * GeoTrf::RotateX3D(rotationAngle);
0072 } else {
0073 bounds = std::make_shared<TrapezoidVolumeBounds>(x2, x1, z, y1);
0074 constexpr double rotationAngle = std::numbers::pi;
0075 newTrf = trf * GeoTrf::RotateY3D(rotationAngle) *
0076 GeoTrf::RotateZ3D(rotationAngle);
0077 }
0078 } else if (x1 == x2) {
0079 if (y1 < y2) {
0080 bounds = std::make_shared<TrapezoidVolumeBounds>(y1, y2, z, x1);
0081 auto rotationAngle = std::numbers::pi / 2.;
0082 newTrf = trf * GeoTrf::RotateZ3D(rotationAngle) *
0083 GeoTrf::RotateX3D(rotationAngle);
0084 } else {
0085 bounds = std::make_shared<TrapezoidVolumeBounds>(y2, y1, z, x1);
0086 auto rotationAngle = std::numbers::pi;
0087 newTrf = trf * GeoTrf::RotateX3D(rotationAngle) *
0088 GeoTrf::RotateZ3D(rotationAngle / 2) *
0089 GeoTrf::RotateX3D(rotationAngle / 2);
0090 }
0091 } else {
0092 throw std::runtime_error("FATAL: Translating GeoTrd to ACTS failed");
0093 }
0094 }
0095
0096 else if (shape.typeID() == GeoShapeUnion::getClassTypeID()) {
0097 const GeoShapeUnion* unionShape =
0098 dynamic_cast<const GeoShapeUnion*>(&shape);
0099 double xmin{0}, xmax{0}, ymin{0}, ymax{0}, zmin{0}, zmax{0};
0100 unionShape->extent(xmin, ymin, zmin, xmax, ymax, zmax);
0101 bounds = std::make_shared<CuboidVolumeBounds>(
0102 (xmax - xmin) / 2, (ymax - ymin) / 2, (zmax - zmin) / 2);
0103 } else if (shape.typeID() == GeoShapeSubtraction::getClassTypeID()) {
0104
0105
0106 const GeoShapeSubtraction* subtractionShape =
0107 dynamic_cast<const GeoShapeSubtraction*>(&shape);
0108 const GeoShape* shapeA = subtractionShape->getOpA();
0109 return convertVolume(trf, *shapeA);
0110 } else if (shape.typeID() == GeoShapeSubtraction::getClassTypeID()) {
0111
0112
0113 const GeoShapeSubtraction* subtractionShape =
0114 dynamic_cast<const GeoShapeSubtraction*>(&shape);
0115 const GeoShape* shapeA = subtractionShape->getOpA();
0116 return convertVolume(trf, *shapeA);
0117 } else if (shape.typeID() == GeoPcon::getClassTypeID()) {
0118
0119 double xmin{0}, xmax{0}, ymin{0}, ymax{0}, zmin{0}, zmax{0};
0120 const GeoPcon* pcon = dynamic_cast<const GeoPcon*>(&shape);
0121 pcon->extent(xmin, ymin, zmin, xmax, ymax, zmax);
0122 bounds = std::make_shared<CuboidVolumeBounds>(
0123 (xmax - xmin) / 2, (ymax - ymin) / 2, (zmax - zmin) / 2);
0124 } else if (shape.typeID() == GeoShapeShift::getClassTypeID()) {
0125 const GeoShapeShift* shiftShape =
0126 dynamic_cast<const GeoShapeShift*>(&shape);
0127 const GeoShape* shapeOp = shiftShape->getOp();
0128 newTrf = trf * shiftShape->getX();
0129 return convertVolume(newTrf, *shapeOp);
0130 } else {
0131 throw std::runtime_error("FATAL: Unsupported GeoModel shape: " +
0132 shape.type());
0133 }
0134 return Volume(newTrf, bounds);
0135 }
0136
0137 std::shared_ptr<Experimental::DetectorVolume> convertDetectorVolume(
0138 const GeometryContext& context, const GeoShape& shape,
0139 const std::string& name, const GeoTrf::Transform3D& transform,
0140 const std::vector<GeoModelSensitiveSurface>& sensitives) {
0141
0142 std::vector<std::shared_ptr<Surface>> sensSurfaces(sensitives.size());
0143 std::transform(sensitives.begin(), sensitives.end(), sensSurfaces.begin(),
0144 [](const std::tuple<std::shared_ptr<GeoModelDetectorElement>,
0145 std::shared_ptr<Surface>>& t) {
0146 return std::get<1>(t);
0147 });
0148 auto portalGenerator = Experimental::defaultPortalAndSubPortalGenerator();
0149 Volume vol = convertVolume(transform, shape);
0150 return Experimental::DetectorVolumeFactory::construct(
0151 portalGenerator, context, name, vol.transform(), vol.volumeBoundsPtr(),
0152 sensSurfaces,
0153 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>{},
0154 Experimental::tryNoVolumes(), Experimental::tryAllPortalsAndSurfaces());
0155 }
0156
0157 }