Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:24:24

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsPlugins/GeoModel/GeoModelToDetectorVolume.hpp"
0010 
0011 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0012 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
0013 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0014 #include "Acts/Geometry/GeometryIdentifier.hpp"
0015 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0016 
0017 #include <numbers>
0018 
0019 #include <GeoModelHelpers/GeoShapeUtils.h>
0020 #include <GeoModelKernel/GeoBox.h>
0021 #include <GeoModelKernel/GeoPcon.h>
0022 #include <GeoModelKernel/GeoShapeShift.h>
0023 #include <GeoModelKernel/GeoShapeSubtraction.h>
0024 #include <GeoModelKernel/GeoShapeUnion.h>
0025 #include <GeoModelKernel/GeoSimplePolygonBrep.h>
0026 #include <GeoModelKernel/GeoTrd.h>
0027 #include <GeoModelKernel/GeoTube.h>
0028 #include <GeoModelKernel/GeoTubs.h>
0029 #include <GeoModelKernel/GeoVFullPhysVol.h>
0030 
0031 using namespace Acts;
0032 
0033 namespace ActsPlugins::GeoModel {
0034 
0035 Transform3 volumePosInSpace(const PVConstLink& physVol) {
0036   if (auto fullPhys = dynamic_pointer_cast<const GeoVFullPhysVol>(physVol);
0037       fullPhys != nullptr) {
0038     return fullPhys->getAbsoluteTransform();
0039   }
0040   /// @brief GeoNodePositioning is the class which handles
0041   ///        the absolute placement of a GeoVPhysVol. Its constructor
0042   ///        is protected though -> create helper class to make it public
0043   class GeoVolumePositioner : public GeoNodePositioning {
0044    public:
0045     explicit GeoVolumePositioner(const GeoVPhysVol* physVol)
0046         : GeoNodePositioning{physVol} {}
0047   };
0048 
0049   GeoVolumePositioner positioner{physVol};
0050   return positioner.getAbsoluteTransform();
0051 }
0052 std::shared_ptr<Volume> convertVolume(const Transform3& trf,
0053                                       const GeoShape* shape,
0054                                       VolumeBoundFactory& boundFactory) {
0055   assert(shape);
0056   std::shared_ptr<VolumeBounds> bounds{};
0057   GeoTrf::Transform3D newTrf = trf;
0058   const ShapeType id = shape->typeID();
0059   if (id == GeoTube::getClassTypeID()) {
0060     const auto* tube = dynamic_cast<const GeoTube*>(shape);
0061     bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0062         tube->getRMin(), tube->getRMax(), tube->getZHalfLength());
0063   } else if (id == GeoTubs::getClassTypeID()) {
0064     const auto* tubs = dynamic_cast<const GeoTubs*>(shape);
0065     bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0066         tubs->getRMin(), tubs->getRMax(), tubs->getZHalfLength(),
0067         tubs->getDPhi() / 2);
0068     newTrf = trf * GeoTrf::RotateZ3D(tubs->getSPhi() + 0.5 * tubs->getDPhi());
0069   } else if (id == GeoBox::getClassTypeID()) {
0070     const auto* box = dynamic_cast<const GeoBox*>(shape);
0071     bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0072         box->getXHalfLength(), box->getYHalfLength(), box->getZHalfLength());
0073   } else if (id == GeoSimplePolygonBrep::getClassTypeID() ||
0074              /// Union is converted into box. Revise in the future
0075              id == GeoShapeUnion::getClassTypeID() ||
0076              /// Will change in future, get bounding box for now
0077              id == GeoPcon::getClassTypeID()) {
0078     double xmin{0}, xmax{0}, ymin{0}, ymax{0}, zmin{0}, zmax{0};
0079     shape->extent(xmin, ymin, zmin, xmax, ymax, zmax);
0080     bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0081         (xmax - xmin) / 2, (ymax - ymin) / 2, (zmax - zmin) / 2);
0082   } else if (id == GeoTrd::getClassTypeID()) {
0083     const auto* trd = dynamic_cast<const GeoTrd*>(shape);
0084     double x1 = trd->getXHalfLength1();
0085     double x2 = trd->getXHalfLength2();
0086     double y1 = trd->getYHalfLength1();
0087     double y2 = trd->getYHalfLength2();
0088     double z = trd->getZHalfLength();
0089     if (y1 == y2) {
0090       if (x1 <= x2) {
0091         // y axis in ACTS is z axis in geomodel
0092         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x1, x2, z, y1);
0093         constexpr double rotationAngle = std::numbers::pi / 2.;
0094         newTrf = trf * GeoTrf::RotateX3D(rotationAngle);
0095       } else {
0096         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x2, x1, z, y1);
0097         constexpr double rotationAngle = std::numbers::pi;
0098         newTrf = trf * GeoTrf::RotateY3D(rotationAngle) *
0099                  GeoTrf::RotateZ3D(rotationAngle);
0100       }
0101     } else if (x1 == x2) {
0102       if (y1 < y2) {
0103         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y1, y2, z, x1);
0104         auto rotationAngle = std::numbers::pi / 2.;
0105         newTrf = trf * GeoTrf::RotateZ3D(rotationAngle) *
0106                  GeoTrf::RotateX3D(rotationAngle);
0107       } else {
0108         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y2, y1, z, x1);
0109         auto rotationAngle = std::numbers::pi;
0110         newTrf = trf * GeoTrf::RotateX3D(rotationAngle) *
0111                  GeoTrf::RotateZ3D(rotationAngle / 2) *
0112                  GeoTrf::RotateX3D(rotationAngle / 2);
0113       }
0114     } else {
0115       throw std::runtime_error("convertVolume() - Translating the GeoTrd " +
0116                                printGeoShape(shape) + " to ACTS failed");
0117     }
0118 
0119   } else if (id == GeoShapeSubtraction::getClassTypeID()) {
0120     return convertVolume(newTrf, getOps(shape).first, boundFactory);
0121   } else if (id == GeoShapeShift::getClassTypeID()) {
0122     auto compressed = compressShift(shape);
0123     if (compressed->typeID() != GeoShapeShift::getClassTypeID()) {
0124       return convertVolume(newTrf, compressed, boundFactory);
0125     }
0126     const auto shiftShape =
0127         dynamic_pointer_cast<const GeoShapeShift>(compressed);
0128     const GeoShape* shapeOp = shiftShape->getOp();
0129     return convertVolume(newTrf * shiftShape->getX(), shapeOp, boundFactory);
0130   } else {
0131     throw std::runtime_error("Cannot convert " + printGeoShape(shape));
0132   }
0133   return std::make_shared<Volume>(newTrf, bounds);
0134 }
0135 
0136 }  // namespace ActsPlugins::GeoModel