Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:10:05

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2021 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Definitions/Algebra.hpp"
0010 #include "Acts/Detector/CuboidalContainerBuilder.hpp"
0011 #include "Acts/Detector/CylindricalContainerBuilder.hpp"
0012 #include "Acts/Detector/Detector.hpp"
0013 #include "Acts/Detector/DetectorBuilder.hpp"
0014 #include "Acts/Detector/DetectorVolume.hpp"
0015 #include "Acts/Detector/DetectorVolumeBuilder.hpp"
0016 #include "Acts/Detector/GeometryIdGenerator.hpp"
0017 #include "Acts/Detector/IndexedRootVolumeFinderBuilder.hpp"
0018 #include "Acts/Detector/KdtSurfacesProvider.hpp"
0019 #include "Acts/Detector/LayerStructureBuilder.hpp"
0020 #include "Acts/Detector/VolumeStructureBuilder.hpp"
0021 #include "Acts/Detector/interface/IDetectorBuilder.hpp"
0022 #include "Acts/Detector/interface/IDetectorComponentBuilder.hpp"
0023 #include "Acts/Detector/interface/IExternalStructureBuilder.hpp"
0024 #include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
0025 #include "Acts/Detector/interface/IInternalStructureBuilder.hpp"
0026 #include "Acts/Detector/interface/IRootVolumeFinderBuilder.hpp"
0027 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0028 #include "Acts/Geometry/Extent.hpp"
0029 #include "Acts/Geometry/GeometryContext.hpp"
0030 #include "Acts/Geometry/GeometryHierarchyMap.hpp"
0031 #include "Acts/Geometry/GeometryIdentifier.hpp"
0032 #include "Acts/Geometry/TrackingGeometry.hpp"
0033 #include "Acts/Geometry/Volume.hpp"
0034 #include "Acts/Geometry/VolumeBounds.hpp"
0035 #include "Acts/Plugins/Python/Utilities.hpp"
0036 #include "Acts/Surfaces/Surface.hpp"
0037 #include "Acts/Surfaces/SurfaceArray.hpp"
0038 #include "Acts/Utilities/RangeXD.hpp"
0039 #include "ActsExamples/Geometry/VolumeAssociationTest.hpp"
0040 
0041 #include <array>
0042 #include <memory>
0043 #include <vector>
0044 
0045 #include <pybind11/pybind11.h>
0046 #include <pybind11/stl.h>
0047 
0048 namespace py = pybind11;
0049 using namespace pybind11::literals;
0050 
0051 namespace {
0052 struct GeometryIdentifierHookBinding : public Acts::GeometryIdentifierHook {
0053   py::object callable;
0054 
0055   Acts::GeometryIdentifier decorateIdentifier(
0056       Acts::GeometryIdentifier identifier,
0057       const Acts::Surface& surface) const override {
0058     return callable(identifier, surface.getSharedPtr())
0059         .cast<Acts::GeometryIdentifier>();
0060   }
0061 };
0062 
0063 struct MaterialSurfaceSelector {
0064   std::vector<const Acts::Surface*> surfaces = {};
0065 
0066   /// @param surface is the test surface
0067   void operator()(const Acts::Surface* surface) {
0068     if (surface->surfaceMaterial() != nullptr) {
0069       if (std::find(surfaces.begin(), surfaces.end(), surface) ==
0070           surfaces.end()) {
0071         surfaces.push_back(surface);
0072       }
0073     }
0074   }
0075 };
0076 
0077 }  // namespace
0078 
0079 namespace Acts::Python {
0080 void addGeometry(Context& ctx) {
0081   auto m = ctx.get("main");
0082 
0083   {
0084     py::class_<Acts::GeometryIdentifier>(m, "GeometryIdentifier")
0085         .def(py::init<>())
0086         .def(py::init<Acts::GeometryIdentifier::Value>())
0087         .def("setVolume", &Acts::GeometryIdentifier::setVolume)
0088         .def("setLayer", &Acts::GeometryIdentifier::setLayer)
0089         .def("setBoundary", &Acts::GeometryIdentifier::setBoundary)
0090         .def("setApproach", &Acts::GeometryIdentifier::setApproach)
0091         .def("setSensitive", &Acts::GeometryIdentifier::setSensitive)
0092         .def("setExtra", &Acts::GeometryIdentifier::setExtra)
0093         .def("volume", &Acts::GeometryIdentifier::volume)
0094         .def("layer", &Acts::GeometryIdentifier::layer)
0095         .def("boundary", &Acts::GeometryIdentifier::boundary)
0096         .def("approach", &Acts::GeometryIdentifier::approach)
0097         .def("sensitive", &Acts::GeometryIdentifier::sensitive)
0098         .def("extra", &Acts::GeometryIdentifier::extra)
0099         .def("value", &Acts::GeometryIdentifier::value);
0100   }
0101 
0102   {
0103     py::class_<Acts::Surface, std::shared_ptr<Acts::Surface>>(m, "Surface")
0104         .def("geometryId",
0105              [](Acts::Surface& self) { return self.geometryId(); })
0106         .def("center",
0107              [](Acts::Surface& self) {
0108                return self.center(Acts::GeometryContext{});
0109              })
0110         .def("type", [](Acts::Surface& self) { return self.type(); });
0111   }
0112 
0113   {
0114     py::enum_<Acts::Surface::SurfaceType>(m, "SurfaceType")
0115         .value("Cone", Acts::Surface::SurfaceType::Cone)
0116         .value("Cylinder", Acts::Surface::SurfaceType::Cylinder)
0117         .value("Disc", Acts::Surface::SurfaceType::Disc)
0118         .value("Perigee", Acts::Surface::SurfaceType::Perigee)
0119         .value("Plane", Acts::Surface::SurfaceType::Plane)
0120         .value("Straw", Acts::Surface::SurfaceType::Straw)
0121         .value("Curvilinear", Acts::Surface::SurfaceType::Curvilinear)
0122         .value("Other", Acts::Surface::SurfaceType::Other);
0123   }
0124 
0125   {
0126     py::enum_<Acts::VolumeBounds::BoundsType>(m, "VolumeBoundsType")
0127         .value("Cone", Acts::VolumeBounds::BoundsType::eCone)
0128         .value("Cuboid", Acts::VolumeBounds::BoundsType::eCuboid)
0129         .value("CutoutCylinder",
0130                Acts::VolumeBounds::BoundsType::eCutoutCylinder)
0131         .value("Cylinder", Acts::VolumeBounds::BoundsType::eCylinder)
0132         .value("GenericCuboid", Acts::VolumeBounds::BoundsType::eGenericCuboid)
0133         .value("Trapezoid", Acts::VolumeBounds::BoundsType::eTrapezoid)
0134         .value("Other", Acts::VolumeBounds::BoundsType::eOther);
0135   }
0136 
0137   {
0138     py::class_<Acts::TrackingGeometry, std::shared_ptr<Acts::TrackingGeometry>>(
0139         m, "TrackingGeometry")
0140         .def("visitSurfaces",
0141              [](Acts::TrackingGeometry& self, py::function& func) {
0142                self.visitSurfaces(func);
0143              })
0144         .def("extractMaterialSurfaces",
0145              [](Acts::TrackingGeometry& self) {
0146                MaterialSurfaceSelector selector;
0147                self.visitSurfaces(selector, false);
0148                return selector.surfaces;
0149              })
0150         .def_property_readonly(
0151             "worldVolume",
0152             &Acts::TrackingGeometry::highestTrackingVolumeShared);
0153   }
0154 
0155   {
0156     py::class_<Acts::Volume, std::shared_ptr<Acts::Volume>>(m, "Volume")
0157         .def_static(
0158             "makeCylinderVolume",
0159             [](double r, double halfZ) {
0160               auto bounds =
0161                   std::make_shared<Acts::CylinderVolumeBounds>(0, r, halfZ);
0162               return std::make_shared<Acts::Volume>(Transform3::Identity(),
0163                                                     bounds);
0164             },
0165             "r"_a, "halfZ"_a);
0166   }
0167 
0168   {
0169     py::class_<Acts::TrackingVolume, Acts::Volume,
0170                std::shared_ptr<Acts::TrackingVolume>>(m, "TrackingVolume");
0171   }
0172 
0173   {
0174     py::class_<Acts::GeometryIdentifierHook,
0175                std::shared_ptr<Acts::GeometryIdentifierHook>>(
0176         m, "GeometryIdentifierHook")
0177         .def(py::init([](py::object callable) {
0178           auto hook = std::make_shared<GeometryIdentifierHookBinding>();
0179           hook->callable = callable;
0180           return hook;
0181         }));
0182   }
0183 
0184   {
0185     py::class_<Acts::Extent>(m, "Extent")
0186         .def(py::init(
0187             [](const std::vector<std::tuple<Acts::BinningValue,
0188                                             std::array<Acts::ActsScalar, 2u>>>&
0189                    franges) {
0190               Acts::Extent extent;
0191               for (const auto& [bval, frange] : franges) {
0192                 extent.set(bval, frange[0], frange[1]);
0193               }
0194               return extent;
0195             }))
0196         .def("range", [](const Acts::Extent& self, Acts::BinningValue bval) {
0197           return std::array<Acts::ActsScalar, 2u>{self.min(bval),
0198                                                   self.max(bval)};
0199         });
0200   }
0201 }
0202 
0203 void addExperimentalGeometry(Context& ctx) {
0204   auto [m, mex] = ctx.get("main", "examples");
0205 
0206   using namespace Acts::Experimental;
0207 
0208   // Detector volume definition
0209   py::class_<DetectorVolume, std::shared_ptr<DetectorVolume>>(m,
0210                                                               "DetectorVolume");
0211 
0212   // Detector definition
0213   py::class_<Detector, std::shared_ptr<Detector>>(m, "Detector")
0214       .def("numberVolumes",
0215            [](Detector& self) { return self.volumes().size(); })
0216       .def("extractMaterialSurfaces", [](Detector& self) {
0217         MaterialSurfaceSelector selector;
0218         self.visitSurfaces(selector);
0219         return selector.surfaces;
0220       });
0221 
0222   // Portal definition
0223   py::class_<Portal, std::shared_ptr<Portal>>(m, "Portal");
0224 
0225   {
0226     // The surface hierarchy map
0227     using SurfaceHierarchyMap =
0228         Acts::GeometryHierarchyMap<std::shared_ptr<Surface>>;
0229 
0230     py::class_<SurfaceHierarchyMap, std::shared_ptr<SurfaceHierarchyMap>>(
0231         m, "SurfaceHierarchyMap");
0232 
0233     // Extract volume / layer surfaces
0234     mex.def("extractVolumeLayerSurfaces", [](const SurfaceHierarchyMap& smap,
0235                                              bool sensitiveOnly) {
0236       std::map<unsigned int,
0237                std::map<unsigned int, std::vector<std::shared_ptr<Surface>>>>
0238           surfaceVolumeLayerMap;
0239       for (const auto& surface : smap) {
0240         auto gid = surface->geometryId();
0241         // Exclusion criteria
0242         if (sensitiveOnly and gid.sensitive() == 0) {
0243           continue;
0244         };
0245         surfaceVolumeLayerMap[gid.volume()][gid.layer()].push_back(surface);
0246       }
0247       // Return the surface volume map
0248       return surfaceVolumeLayerMap;
0249     });
0250   }
0251 
0252   {
0253     // Be able to construct a proto binning
0254     py::class_<ProtoBinning>(m, "ProtoBinning")
0255         .def(py::init<Acts::BinningValue, Acts::detail::AxisBoundaryType,
0256                       const std::vector<Acts::ActsScalar>&, std::size_t>())
0257         .def(py::init<Acts::BinningValue, Acts::detail::AxisBoundaryType,
0258                       Acts::ActsScalar, Acts::ActsScalar, std::size_t,
0259                       std::size_t>());
0260   }
0261 
0262   {
0263     // The internal layer structure builder
0264     py::class_<Acts::Experimental::IInternalStructureBuilder,
0265                std::shared_ptr<Acts::Experimental::IInternalStructureBuilder>>(
0266         m, "IInternalStructureBuilder");
0267 
0268     auto lsBuilder =
0269         py::class_<LayerStructureBuilder,
0270                    Acts::Experimental::IInternalStructureBuilder,
0271                    std::shared_ptr<LayerStructureBuilder>>(
0272             m, "LayerStructureBuilder")
0273             .def(py::init([](const LayerStructureBuilder::Config& config,
0274                              const std::string& name,
0275                              Acts::Logging::Level level) {
0276               return std::make_shared<LayerStructureBuilder>(
0277                   config, getDefaultLogger(name, level));
0278             }));
0279 
0280     auto lsConfig =
0281         py::class_<LayerStructureBuilder::Config>(lsBuilder, "Config")
0282             .def(py::init<>());
0283 
0284     ACTS_PYTHON_STRUCT_BEGIN(lsConfig, LayerStructureBuilder::Config);
0285     ACTS_PYTHON_MEMBER(surfacesProvider);
0286     ACTS_PYTHON_MEMBER(supports);
0287     ACTS_PYTHON_MEMBER(binnings);
0288     ACTS_PYTHON_MEMBER(nSegments);
0289     ACTS_PYTHON_MEMBER(auxiliary);
0290     ACTS_PYTHON_STRUCT_END();
0291 
0292     // The internal layer structure builder
0293     py::class_<Acts::Experimental::ISurfacesProvider,
0294                std::shared_ptr<Acts::Experimental::ISurfacesProvider>>(
0295         m, "ISurfacesProvider");
0296 
0297     py::class_<LayerStructureBuilder::SurfacesHolder,
0298                Acts::Experimental::ISurfacesProvider,
0299                std::shared_ptr<LayerStructureBuilder::SurfacesHolder>>(
0300         lsBuilder, "SurfacesHolder")
0301         .def(py::init<std::vector<std::shared_ptr<Surface>>>());
0302   }
0303 
0304   {
0305     using RangeXDDim1 = Acts::RangeXD<1u, Acts::ActsScalar>;
0306     using KdtSurfacesDim1Bin100 = Acts::Experimental::KdtSurfaces<1u, 100u>;
0307     using KdtSurfacesProviderDim1Bin100 =
0308         Acts::Experimental::KdtSurfacesProvider<1u, 100u>;
0309 
0310     py::class_<RangeXDDim1>(m, "RangeXDDim1")
0311         .def(py::init([](const std::array<Acts::ActsScalar, 2u>& irange) {
0312           RangeXDDim1 range;
0313           range[0].shrink(irange[0], irange[1]);
0314           return range;
0315         }));
0316 
0317     py::class_<KdtSurfacesDim1Bin100, std::shared_ptr<KdtSurfacesDim1Bin100>>(
0318         m, "KdtSurfacesDim1Bin100")
0319         .def(py::init<const GeometryContext&,
0320                       const std::vector<std::shared_ptr<Acts::Surface>>&,
0321                       const std::array<Acts::BinningValue, 1u>&>())
0322         .def("surfaces", py::overload_cast<const RangeXDDim1&>(
0323                              &KdtSurfacesDim1Bin100::surfaces, py::const_));
0324 
0325     py::class_<KdtSurfacesProviderDim1Bin100,
0326                Acts::Experimental::ISurfacesProvider,
0327                std::shared_ptr<KdtSurfacesProviderDim1Bin100>>(
0328         m, "KdtSurfacesProviderDim1Bin100")
0329         .def(py::init<std::shared_ptr<KdtSurfacesDim1Bin100>, const Extent&>());
0330   }
0331 
0332   {
0333     using RangeXDDim2 = Acts::RangeXD<2u, Acts::ActsScalar>;
0334     using KdtSurfacesDim2Bin100 = Acts::Experimental::KdtSurfaces<2u, 100u>;
0335     using KdtSurfacesProviderDim2Bin100 =
0336         Acts::Experimental::KdtSurfacesProvider<2u, 100u>;
0337 
0338     py::class_<RangeXDDim2>(m, "RangeXDDim2")
0339         .def(py::init([](const std::array<Acts::ActsScalar, 2u>& range0,
0340                          const std::array<Acts::ActsScalar, 2u>& range1) {
0341           RangeXDDim2 range;
0342           range[0].shrink(range0[0], range0[1]);
0343           range[1].shrink(range1[0], range1[1]);
0344           return range;
0345         }));
0346 
0347     py::class_<KdtSurfacesDim2Bin100, std::shared_ptr<KdtSurfacesDim2Bin100>>(
0348         m, "KdtSurfacesDim2Bin100")
0349         .def(py::init<const GeometryContext&,
0350                       const std::vector<std::shared_ptr<Acts::Surface>>&,
0351                       const std::array<Acts::BinningValue, 2u>&>())
0352         .def("surfaces", py::overload_cast<const RangeXDDim2&>(
0353                              &KdtSurfacesDim2Bin100::surfaces, py::const_));
0354 
0355     py::class_<KdtSurfacesProviderDim2Bin100,
0356                Acts::Experimental::ISurfacesProvider,
0357                std::shared_ptr<KdtSurfacesProviderDim2Bin100>>(
0358         m, "KdtSurfacesProviderDim2Bin100")
0359         .def(py::init<std::shared_ptr<KdtSurfacesDim2Bin100>, const Extent&>());
0360   }
0361 
0362   {
0363     // The external volume structure builder
0364     py::class_<Acts::Experimental::IExternalStructureBuilder,
0365                std::shared_ptr<Acts::Experimental::IExternalStructureBuilder>>(
0366         m, "IExternalStructureBuilder");
0367 
0368     auto vsBuilder =
0369         py::class_<VolumeStructureBuilder,
0370                    Acts::Experimental::IExternalStructureBuilder,
0371                    std::shared_ptr<VolumeStructureBuilder>>(
0372             m, "VolumeStructureBuilder")
0373             .def(py::init([](const VolumeStructureBuilder::Config& config,
0374                              const std::string& name,
0375                              Acts::Logging::Level level) {
0376               return std::make_shared<VolumeStructureBuilder>(
0377                   config, getDefaultLogger(name, level));
0378             }));
0379 
0380     auto vsConfig =
0381         py::class_<VolumeStructureBuilder::Config>(vsBuilder, "Config")
0382             .def(py::init<>());
0383 
0384     ACTS_PYTHON_STRUCT_BEGIN(vsConfig, VolumeStructureBuilder::Config);
0385     ACTS_PYTHON_MEMBER(boundsType);
0386     ACTS_PYTHON_MEMBER(boundValues);
0387     ACTS_PYTHON_MEMBER(transform);
0388     ACTS_PYTHON_MEMBER(auxiliary);
0389     ACTS_PYTHON_STRUCT_END();
0390   }
0391 
0392   {
0393     py::class_<Acts::Experimental::IGeometryIdGenerator,
0394                std::shared_ptr<Acts::Experimental::IGeometryIdGenerator>>(
0395         m, "IGeometryIdGenerator");
0396 
0397     auto geoIdGen =
0398         py::class_<Acts::Experimental::GeometryIdGenerator,
0399                    Acts::Experimental::IGeometryIdGenerator,
0400                    std::shared_ptr<Acts::Experimental::GeometryIdGenerator>>(
0401             m, "GeometryIdGenerator")
0402             .def(py::init([](Acts::Experimental::GeometryIdGenerator::Config&
0403                                  config,
0404                              const std::string& name,
0405                              Acts::Logging::Level level) {
0406               return std::make_shared<Acts::Experimental::GeometryIdGenerator>(
0407                   config, getDefaultLogger(name, level));
0408             }));
0409 
0410     auto geoIdGenConfig =
0411         py::class_<Acts::Experimental::GeometryIdGenerator::Config>(geoIdGen,
0412                                                                     "Config")
0413             .def(py::init<>());
0414 
0415     ACTS_PYTHON_STRUCT_BEGIN(geoIdGenConfig,
0416                              Acts::Experimental::GeometryIdGenerator::Config);
0417     ACTS_PYTHON_MEMBER(containerMode);
0418     ACTS_PYTHON_MEMBER(containerId);
0419     ACTS_PYTHON_MEMBER(resetSubCounters);
0420     ACTS_PYTHON_MEMBER(overrideExistingIds);
0421     ACTS_PYTHON_STRUCT_END();
0422   }
0423 
0424   {
0425     // Put them together to a detector volume
0426     py::class_<Acts::Experimental::IDetectorComponentBuilder,
0427                std::shared_ptr<Acts::Experimental::IDetectorComponentBuilder>>(
0428         m, "IDetectorComponentBuilder");
0429 
0430     auto dvBuilder =
0431         py::class_<DetectorVolumeBuilder,
0432                    Acts::Experimental::IDetectorComponentBuilder,
0433                    std::shared_ptr<DetectorVolumeBuilder>>(
0434             m, "DetectorVolumeBuilder")
0435             .def(py::init([](const DetectorVolumeBuilder::Config& config,
0436                              const std::string& name,
0437                              Acts::Logging::Level level) {
0438               return std::make_shared<DetectorVolumeBuilder>(
0439                   config, getDefaultLogger(name, level));
0440             }))
0441             .def("construct", &DetectorVolumeBuilder::construct);
0442 
0443     auto dvConfig =
0444         py::class_<DetectorVolumeBuilder::Config>(dvBuilder, "Config")
0445             .def(py::init<>());
0446 
0447     ACTS_PYTHON_STRUCT_BEGIN(dvConfig, DetectorVolumeBuilder::Config);
0448     ACTS_PYTHON_MEMBER(name);
0449     ACTS_PYTHON_MEMBER(internalsBuilder);
0450     ACTS_PYTHON_MEMBER(externalsBuilder);
0451     ACTS_PYTHON_MEMBER(geoIdGenerator);
0452     ACTS_PYTHON_MEMBER(auxiliary);
0453     ACTS_PYTHON_STRUCT_END();
0454   }
0455 
0456   {
0457     // The external volume structure builder
0458     py::class_<Acts::Experimental::IRootVolumeFinderBuilder,
0459                std::shared_ptr<Acts::Experimental::IRootVolumeFinderBuilder>>(
0460         m, "IRootVolumeFinderBuilder");
0461 
0462     auto irvBuilder =
0463         py::class_<Acts::Experimental::IndexedRootVolumeFinderBuilder,
0464                    Acts::Experimental::IRootVolumeFinderBuilder,
0465                    std::shared_ptr<
0466                        Acts::Experimental::IndexedRootVolumeFinderBuilder>>(
0467             m, "IndexedRootVolumeFinderBuilder")
0468             .def(py::init<std::vector<Acts::BinningValue>>());
0469   }
0470 
0471   {
0472     // Cylindrical container builder
0473     auto ccBuilder =
0474         py::class_<CylindricalContainerBuilder,
0475                    Acts::Experimental::IDetectorComponentBuilder,
0476                    std::shared_ptr<CylindricalContainerBuilder>>(
0477             m, "CylindricalContainerBuilder")
0478             .def(py::init([](const CylindricalContainerBuilder::Config& config,
0479                              const std::string& name,
0480                              Acts::Logging::Level level) {
0481               return std::make_shared<CylindricalContainerBuilder>(
0482                   config, getDefaultLogger(name, level));
0483             }))
0484             .def("construct", &CylindricalContainerBuilder::construct);
0485 
0486     auto ccConfig =
0487         py::class_<CylindricalContainerBuilder::Config>(ccBuilder, "Config")
0488             .def(py::init<>());
0489 
0490     ACTS_PYTHON_STRUCT_BEGIN(ccConfig, CylindricalContainerBuilder::Config);
0491     ACTS_PYTHON_MEMBER(builders);
0492     ACTS_PYTHON_MEMBER(binning);
0493     ACTS_PYTHON_MEMBER(rootVolumeFinderBuilder);
0494     ACTS_PYTHON_MEMBER(geoIdGenerator);
0495     ACTS_PYTHON_MEMBER(geoIdReverseGen);
0496     ACTS_PYTHON_MEMBER(auxiliary);
0497     ACTS_PYTHON_STRUCT_END();
0498   }
0499 
0500   {
0501     // Cuboidal container builder
0502     auto ccBuilder =
0503         py::class_<CuboidalContainerBuilder,
0504                    Acts::Experimental::IDetectorComponentBuilder,
0505                    std::shared_ptr<CuboidalContainerBuilder>>(
0506             m, "CuboidalContainerBuilder")
0507             .def(py::init([](const CuboidalContainerBuilder::Config& config,
0508                              const std::string& name,
0509                              Acts::Logging::Level level) {
0510               return std::make_shared<CuboidalContainerBuilder>(
0511                   config, getDefaultLogger(name, level));
0512             }))
0513             .def("construct", &CuboidalContainerBuilder::construct);
0514 
0515     auto ccConfig =
0516         py::class_<CuboidalContainerBuilder::Config>(ccBuilder, "Config")
0517             .def(py::init<>());
0518 
0519     ACTS_PYTHON_STRUCT_BEGIN(ccConfig, CuboidalContainerBuilder::Config);
0520     ACTS_PYTHON_MEMBER(builders);
0521     ACTS_PYTHON_MEMBER(binning);
0522     ACTS_PYTHON_MEMBER(rootVolumeFinderBuilder);
0523     ACTS_PYTHON_MEMBER(geoIdGenerator);
0524     ACTS_PYTHON_MEMBER(geoIdReverseGen);
0525     ACTS_PYTHON_MEMBER(auxiliary);
0526     ACTS_PYTHON_STRUCT_END();
0527   }
0528 
0529   {
0530     // Detector builder
0531     auto dBuilder =
0532         py::class_<DetectorBuilder, std::shared_ptr<DetectorBuilder>>(
0533             m, "DetectorBuilder")
0534             .def(py::init([](const DetectorBuilder::Config& config,
0535                              const std::string& name,
0536                              Acts::Logging::Level level) {
0537               return std::make_shared<DetectorBuilder>(
0538                   config, getDefaultLogger(name, level));
0539             }))
0540             .def("construct", &DetectorBuilder::construct);
0541 
0542     auto dConfig = py::class_<DetectorBuilder::Config>(dBuilder, "Config")
0543                        .def(py::init<>());
0544 
0545     ACTS_PYTHON_STRUCT_BEGIN(dConfig, DetectorBuilder::Config);
0546     ACTS_PYTHON_MEMBER(name);
0547     ACTS_PYTHON_MEMBER(builder);
0548     ACTS_PYTHON_MEMBER(geoIdGenerator);
0549     ACTS_PYTHON_MEMBER(auxiliary);
0550     ACTS_PYTHON_STRUCT_END();
0551   }
0552 
0553   ACTS_PYTHON_DECLARE_ALGORITHM(ActsExamples::VolumeAssociationTest, mex,
0554                                 "VolumeAssociationTest", name, ntests,
0555                                 randomNumbers, randomRange, detector);
0556 }
0557 
0558 }  // namespace Acts::Python