Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-08 08:11:07

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 
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              /// Union is converted into box. Revise in the future
0059              id == GeoShapeUnion::getClassTypeID() ||
0060              /// Will change in future, get bounding box for now
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         // y axis in ACTS is z axis in geomodel
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 }  // namespace Acts::GeoModel