File indexing completed on 2025-01-18 09:12:03
0001
0002
0003
0004
0005
0006
0007
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> ) = 0;
0036
0037 virtual std::unique_ptr<AnyNavigationPolicyFactory> add(
0038 TypeTag<SurfaceArrayNavigationPolicy> ,
0039 SurfaceArrayNavigationPolicy::Config config) = 0;
0040
0041 virtual std::unique_ptr<AnyNavigationPolicyFactory> add(
0042 TypeTag<TryAllNavigationPolicy> ,
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> ) override {
0059 return add<TryAllNavigationPolicy>();
0060 }
0061
0062 std::unique_ptr<AnyNavigationPolicyFactory> add(
0063 TypeTag<SurfaceArrayNavigationPolicy> ,
0064 SurfaceArrayNavigationPolicy::Config config) override {
0065 return add<SurfaceArrayNavigationPolicy>(std::move(config));
0066 }
0067
0068 std::unique_ptr<AnyNavigationPolicyFactory> add(
0069 TypeTag<TryAllNavigationPolicy> ,
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
0104
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
0111 return *this;
0112 }
0113
0114 NavigationPolicyFactory& addSurfaceArray(
0115 const py::object& ,
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& , 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
0148 const Surface& surface() const override {
0149 throw std::runtime_error("Not implemented");
0150 }
0151
0152
0153 Surface& surface() override { throw std::runtime_error("Not implemented"); }
0154
0155
0156
0157 double thickness() const override { return 0; }
0158
0159 private:
0160 Transform3 m_transform;
0161 };
0162
0163 }
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
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 }