Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:03

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/Geometry/CylinderVolumeBounds.hpp"
0010 #include "Acts/Geometry/NavigationPolicyFactory.hpp"
0011 #include "Acts/Geometry/TrackingVolume.hpp"
0012 #include "Acts/Navigation/SurfaceArrayNavigationPolicy.hpp"
0013 #include "Acts/Navigation/TryAllNavigationPolicy.hpp"
0014 #include "Acts/Plugins/Python/Utilities.hpp"
0015 #include "Acts/Surfaces/CylinderBounds.hpp"
0016 #include "Acts/Surfaces/CylinderSurface.hpp"
0017 #include "Acts/Utilities/Logger.hpp"
0018 #include "Acts/Utilities/TypeTag.hpp"
0019 
0020 #include <memory>
0021 #include <stdexcept>
0022 #include <utility>
0023 
0024 #include <boost/core/demangle.hpp>
0025 #include <pybind11/pybind11.h>
0026 #include <pybind11/stl.h>
0027 
0028 namespace py = pybind11;
0029 using namespace pybind11::literals;
0030 
0031 namespace Acts::Python {
0032 
0033 struct AnyNavigationPolicyFactory : public Acts::NavigationPolicyFactory {
0034   virtual std::unique_ptr<AnyNavigationPolicyFactory> add(
0035       TypeTag<TryAllNavigationPolicy> /*type*/) = 0;
0036 
0037   virtual std::unique_ptr<AnyNavigationPolicyFactory> add(
0038       TypeTag<SurfaceArrayNavigationPolicy> /*type*/,
0039       SurfaceArrayNavigationPolicy::Config config) = 0;
0040 
0041   virtual std::unique_ptr<AnyNavigationPolicyFactory> add(
0042       TypeTag<TryAllNavigationPolicy> /*type*/,
0043       TryAllNavigationPolicy::Config config) = 0;
0044 };
0045 
0046 template <typename Factory = detail::NavigationPolicyFactoryImpl<>,
0047           typename... Policies>
0048 struct NavigationPolicyFactoryT : public AnyNavigationPolicyFactory {
0049   explicit NavigationPolicyFactoryT(Factory impl)
0050     requires(sizeof...(Policies) > 0)
0051       : m_impl(std::move(impl)) {}
0052 
0053   NavigationPolicyFactoryT()
0054     requires(sizeof...(Policies) == 0)
0055       : m_impl{} {}
0056 
0057   std::unique_ptr<AnyNavigationPolicyFactory> add(
0058       TypeTag<TryAllNavigationPolicy> /*type*/) override {
0059     return add<TryAllNavigationPolicy>();
0060   }
0061 
0062   std::unique_ptr<AnyNavigationPolicyFactory> add(
0063       TypeTag<SurfaceArrayNavigationPolicy> /*type*/,
0064       SurfaceArrayNavigationPolicy::Config config) override {
0065     return add<SurfaceArrayNavigationPolicy>(std::move(config));
0066   }
0067 
0068   std::unique_ptr<AnyNavigationPolicyFactory> add(
0069       TypeTag<TryAllNavigationPolicy> /*type*/,
0070       TryAllNavigationPolicy::Config config) override {
0071     return add<TryAllNavigationPolicy>(config);
0072   }
0073 
0074   std::unique_ptr<INavigationPolicy> build(
0075       const GeometryContext& gctx, const TrackingVolume& volume,
0076       const Logger& logger) const override {
0077     if constexpr (sizeof...(Policies) > 0) {
0078       return m_impl.build(gctx, volume, logger);
0079     } else {
0080       throw std::runtime_error("No policies added to the factory");
0081     }
0082   }
0083 
0084  private:
0085   template <typename T, typename... Args>
0086   std::unique_ptr<AnyNavigationPolicyFactory> add(Args&&... args) {
0087     if constexpr (!(std::is_same_v<T, Policies> || ...)) {
0088       auto impl =
0089           std::move(m_impl).template add<T>(std::forward<Args>(args)...);
0090       return std::make_unique<
0091           NavigationPolicyFactoryT<decltype(impl), Policies..., T>>(
0092           std::move(impl));
0093     } else {
0094       throw std::invalid_argument("Policy already added to the factory");
0095     }
0096   }
0097 
0098   Factory m_impl;
0099 };
0100 
0101 class NavigationPolicyFactory : public Acts::NavigationPolicyFactory {
0102  public:
0103   // This overload is for all the navigation policies that don't have extra
0104   // arguments
0105   NavigationPolicyFactory& addNoArguments(const py::object& cls) {
0106     auto m = py::module_::import("acts");
0107     if (py::object o = m.attr("TryAllNavigationPolicy"); cls.is(o)) {
0108       m_impl = m_impl->add(Type<TryAllNavigationPolicy>);
0109     }
0110     // Add other policies here
0111     return *this;
0112   }
0113 
0114   NavigationPolicyFactory& addSurfaceArray(
0115       const py::object& /*cls*/,
0116       const SurfaceArrayNavigationPolicy::Config& config) {
0117     m_impl = m_impl->add(Type<SurfaceArrayNavigationPolicy>, config);
0118     return *this;
0119   }
0120 
0121   NavigationPolicyFactory& addTryAll(
0122       const py::object& /*cls*/, const TryAllNavigationPolicy::Config& config) {
0123     m_impl = m_impl->add(Type<TryAllNavigationPolicy>, config);
0124     return *this;
0125   }
0126 
0127   std::unique_ptr<INavigationPolicy> build(
0128       const GeometryContext& gctx, const TrackingVolume& volume,
0129       const Logger& logger) const override {
0130     return m_impl->build(gctx, volume, logger);
0131   }
0132 
0133  private:
0134   std::unique_ptr<AnyNavigationPolicyFactory> m_impl =
0135       std::make_unique<NavigationPolicyFactoryT<>>();
0136 };
0137 
0138 namespace Test {
0139 class DetectorElementStub : public DetectorElementBase {
0140  public:
0141   DetectorElementStub() : DetectorElementBase() {}
0142 
0143   const Transform3& transform(const GeometryContext&) const override {
0144     return m_transform;
0145   }
0146 
0147   /// Return surface representation - const return pattern
0148   const Surface& surface() const override {
0149     throw std::runtime_error("Not implemented");
0150   }
0151 
0152   /// Non-const return pattern
0153   Surface& surface() override { throw std::runtime_error("Not implemented"); }
0154 
0155   /// Returns the thickness of the module
0156   /// @return double that indicates the thickness of the module
0157   double thickness() const override { return 0; }
0158 
0159  private:
0160   Transform3 m_transform;
0161 };
0162 
0163 }  // namespace Test
0164 
0165 void addNavigation(Context& ctx) {
0166   auto m = ctx.get("main");
0167 
0168   py::class_<Acts::NavigationPolicyFactory,
0169              std::shared_ptr<Acts::NavigationPolicyFactory>>(
0170       m, "_NavigationPolicyFactory");
0171 
0172   {
0173     auto tryAll =
0174         py::class_<TryAllNavigationPolicy>(m, "TryAllNavigationPolicy");
0175     using Config = TryAllNavigationPolicy::Config;
0176     auto c = py::class_<Config>(tryAll, "Config").def(py::init<>());
0177     ACTS_PYTHON_STRUCT_BEGIN(c, Config);
0178     ACTS_PYTHON_MEMBER(portals);
0179     ACTS_PYTHON_MEMBER(sensitives);
0180     ACTS_PYTHON_STRUCT_END();
0181   }
0182 
0183   py::class_<NavigationPolicyFactory, Acts::NavigationPolicyFactory,
0184              std::shared_ptr<NavigationPolicyFactory>>(
0185       m, "NavigationPolicyFactory")
0186       // only to mirror the C++ API
0187       .def_static("make", []() { return NavigationPolicyFactory{}; })
0188       .def("add", &NavigationPolicyFactory::addNoArguments)
0189       .def("add", &NavigationPolicyFactory::addSurfaceArray)
0190       .def("add", &NavigationPolicyFactory::addTryAll)
0191       .def("_buildTest", [](NavigationPolicyFactory& self) {
0192         auto vol1 = std::make_shared<TrackingVolume>(
0193             Transform3::Identity(),
0194             std::make_shared<CylinderVolumeBounds>(30, 40, 100));
0195         vol1->setVolumeName("TestVolume");
0196 
0197         auto detElem = std::make_unique<Test::DetectorElementStub>();
0198 
0199         auto surface = Surface::makeShared<CylinderSurface>(
0200             Transform3::Identity(), std::make_shared<CylinderBounds>(30, 40));
0201         surface->assignDetectorElement(*detElem);
0202 
0203         vol1->addSurface(std::move(surface));
0204 
0205         std::unique_ptr<INavigationPolicy> result =
0206             self.build(GeometryContext{}, *vol1,
0207                        *getDefaultLogger("Test", Logging::VERBOSE));
0208       });
0209 
0210   {
0211     auto saPolicy = py::class_<SurfaceArrayNavigationPolicy>(
0212         m, "SurfaceArrayNavigationPolicy");
0213 
0214     using LayerType = SurfaceArrayNavigationPolicy::LayerType;
0215     py::enum_<LayerType>(saPolicy, "LayerType")
0216         .value("Cylinder", LayerType::Cylinder)
0217         .value("Disc", LayerType::Disc)
0218         .value("Plane", LayerType::Plane);
0219 
0220     using Config = SurfaceArrayNavigationPolicy::Config;
0221     auto c = py::class_<Config>(saPolicy, "Config").def(py::init<>());
0222     ACTS_PYTHON_STRUCT_BEGIN(c, Config);
0223     ACTS_PYTHON_MEMBER(layerType);
0224     ACTS_PYTHON_MEMBER(bins);
0225     ACTS_PYTHON_STRUCT_END();
0226   }
0227 }
0228 
0229 }  // namespace Acts::Python