Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 09:35:01

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 <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         // y axis in ACTS is z axis in geomodel
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     // Go down the left side (opA) of the subtraction until we reach a normal
0105     // shape
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     // Go down the left side (opA) of the subtraction until we reach a normal
0112     // shape
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     // Will change in future, get bounding box for now
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   // type conversion from GeoModelSensitiveSurface to Surface
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 }  // namespace Acts::GeoModel