Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-12 08:13:59

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 "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 #include <GeoModelKernel/GeoVFullPhysVol.h>
0034 
0035 namespace Acts::GeoModel {
0036 
0037 Acts::Transform3 volumePosInSpace(const PVConstLink& physVol) {
0038   if (auto fullPhys = dynamic_pointer_cast<const GeoVFullPhysVol>(physVol);
0039       fullPhys != nullptr) {
0040     return fullPhys->getAbsoluteTransform();
0041   }
0042   /// @brief GeoNodePositioning is the class which handles
0043   ///        the absolute placement of a GeoVPhysVol. Its constructor
0044   ///        is protected though -> create helper class to make it public
0045   class GeoVolumePositioner : public GeoNodePositioning {
0046    public:
0047     explicit GeoVolumePositioner(const GeoVPhysVol* physVol)
0048         : GeoNodePositioning{physVol} {}
0049   };
0050 
0051   GeoVolumePositioner positioner{physVol};
0052   return positioner.getAbsoluteTransform();
0053 }
0054 std::shared_ptr<Volume> convertVolume(const Transform3& trf,
0055                                       const GeoShape* shape,
0056                                       VolumeBoundFactory& boundFactory) {
0057   assert(shape);
0058   std::shared_ptr<VolumeBounds> bounds{};
0059   GeoTrf::Transform3D newTrf = trf;
0060   const ShapeType id = shape->typeID();
0061   if (id == GeoTube::getClassTypeID()) {
0062     const auto* tube = dynamic_cast<const GeoTube*>(shape);
0063     bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0064         tube->getRMin(), tube->getRMax(), tube->getZHalfLength());
0065   } else if (id == GeoTubs::getClassTypeID()) {
0066     const auto* tubs = dynamic_cast<const GeoTubs*>(shape);
0067     bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0068         tubs->getRMin(), tubs->getRMax(), tubs->getZHalfLength(),
0069         tubs->getDPhi() / 2);
0070     newTrf = trf * GeoTrf::RotateZ3D(tubs->getSPhi() + 0.5 * tubs->getDPhi());
0071   } else if (id == GeoBox::getClassTypeID()) {
0072     const auto* box = dynamic_cast<const GeoBox*>(shape);
0073     bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0074         box->getXHalfLength(), box->getYHalfLength(), box->getZHalfLength());
0075   } else if (id == GeoSimplePolygonBrep::getClassTypeID() ||
0076              /// Union is converted into box. Revise in the future
0077              id == GeoShapeUnion::getClassTypeID() ||
0078              /// Will change in future, get bounding box for now
0079              id == GeoPcon::getClassTypeID()) {
0080     double xmin{0}, xmax{0}, ymin{0}, ymax{0}, zmin{0}, zmax{0};
0081     shape->extent(xmin, ymin, zmin, xmax, ymax, zmax);
0082     bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0083         (xmax - xmin) / 2, (ymax - ymin) / 2, (zmax - zmin) / 2);
0084   } else if (id == GeoTrd::getClassTypeID()) {
0085     const auto* trd = dynamic_cast<const GeoTrd*>(shape);
0086     double x1 = trd->getXHalfLength1();
0087     double x2 = trd->getXHalfLength2();
0088     double y1 = trd->getYHalfLength1();
0089     double y2 = trd->getYHalfLength2();
0090     double z = trd->getZHalfLength();
0091     if (y1 == y2) {
0092       if (x1 <= x2) {
0093         // y axis in ACTS is z axis in geomodel
0094         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x1, x2, z, y1);
0095         constexpr double rotationAngle = std::numbers::pi / 2.;
0096         newTrf = trf * GeoTrf::RotateX3D(rotationAngle);
0097       } else {
0098         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x2, x1, z, y1);
0099         constexpr double rotationAngle = std::numbers::pi;
0100         newTrf = trf * GeoTrf::RotateY3D(rotationAngle) *
0101                  GeoTrf::RotateZ3D(rotationAngle);
0102       }
0103     } else if (x1 == x2) {
0104       if (y1 < y2) {
0105         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y1, y2, z, x1);
0106         auto rotationAngle = std::numbers::pi / 2.;
0107         newTrf = trf * GeoTrf::RotateZ3D(rotationAngle) *
0108                  GeoTrf::RotateX3D(rotationAngle);
0109       } else {
0110         bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y2, y1, z, x1);
0111         auto rotationAngle = std::numbers::pi;
0112         newTrf = trf * GeoTrf::RotateX3D(rotationAngle) *
0113                  GeoTrf::RotateZ3D(rotationAngle / 2) *
0114                  GeoTrf::RotateX3D(rotationAngle / 2);
0115       }
0116     } else {
0117       throw std::runtime_error("convertVolume() - Translating the GeoTrd " +
0118                                printGeoShape(shape) + " to ACTS failed");
0119     }
0120 
0121   } else if (id == GeoShapeSubtraction::getClassTypeID()) {
0122     return convertVolume(newTrf, getOps(shape).first, boundFactory);
0123   } else if (id == GeoShapeShift::getClassTypeID()) {
0124     auto compressed = compressShift(shape);
0125     if (compressed->typeID() != GeoShapeShift::getClassTypeID()) {
0126       return convertVolume(newTrf, compressed, boundFactory);
0127     }
0128     const auto shiftShape =
0129         dynamic_pointer_cast<const GeoShapeShift>(compressed);
0130     const GeoShape* shapeOp = shiftShape->getOp();
0131     return convertVolume(newTrf * shiftShape->getX(), shapeOp, boundFactory);
0132   } else {
0133     throw std::runtime_error("Cannot convert " + printGeoShape(shape));
0134   }
0135   return std::make_shared<Volume>(newTrf, bounds);
0136 }
0137 
0138 std::shared_ptr<Experimental::DetectorVolume> convertDetectorVolume(
0139     const GeometryContext& context, Volume& vol, const std::string& name,
0140     const std::vector<std::shared_ptr<Surface>>& sensitives) {
0141   auto portalGenerator = Experimental::defaultPortalAndSubPortalGenerator();
0142   return Experimental::DetectorVolumeFactory::construct(
0143       portalGenerator, context, name, vol.transform(), vol.volumeBoundsPtr(),
0144       sensitives,
0145       std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>{},
0146       Experimental::tryNoVolumes(), Experimental::tryAllPortalsAndSurfaces());
0147 }
0148 
0149 }  // namespace Acts::GeoModel