File indexing completed on 2025-10-13 08:18:26
0001
0002
0003
0004
0005
0006
0007
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/Material/IMaterialDecorator.hpp"
0029 #include "ActsPython/Utilities/Helpers.hpp"
0030 #include "ActsPython/Utilities/Macros.hpp"
0031
0032 #include <array>
0033 #include <memory>
0034 #include <numbers>
0035 #include <unordered_map>
0036 #include <vector>
0037
0038 #include <boost/algorithm/string/join.hpp>
0039 #include <pybind11/pybind11.h>
0040 #include <pybind11/stl.h>
0041
0042 namespace py = pybind11;
0043 using namespace pybind11::literals;
0044
0045 using namespace Acts;
0046 using namespace Acts::Experimental;
0047 using namespace ActsExamples;
0048
0049 namespace {
0050
0051 struct MaterialSurfaceSelector {
0052 std::vector<const Surface*> surfaces = {};
0053
0054
0055 void operator()(const Surface* surface) {
0056 if (surface->surfaceMaterial() != nullptr &&
0057 !rangeContainsValue(surfaces, surface)) {
0058 surfaces.push_back(surface);
0059 }
0060 }
0061 };
0062
0063 struct IdentifierSurfacesCollector {
0064 std::unordered_map<GeometryIdentifier, const Surface*> surfaces;
0065
0066 void operator()(const Surface* surface) {
0067 surfaces[surface->geometryId()] = surface;
0068 }
0069 };
0070
0071 }
0072
0073 namespace ActsPython {
0074
0075
0076 void addGeometryGen2(py::module_& m) {
0077
0078 py::class_<DetectorVolume, std::shared_ptr<DetectorVolume>>(m,
0079 "DetectorVolume")
0080 .def("surfaces", &DetectorVolume::surfaces)
0081 .def("surfacePtrs", &DetectorVolume::surfacePtrs);
0082
0083
0084 py::class_<Detector, std::shared_ptr<Detector>>(m, "Detector")
0085 .def("volumes", &Detector::volumes)
0086 .def("volumePtrs", &Detector::volumePtrs)
0087 .def("numberVolumes",
0088 [](const Detector& self) { return self.volumes().size(); })
0089 .def("extractMaterialSurfaces",
0090 [](const Detector& self) {
0091 MaterialSurfaceSelector selector;
0092 self.visitSurfaces(selector);
0093 return selector.surfaces;
0094 })
0095 .def("geoIdSurfaceMap",
0096 [](const Detector& self) {
0097 IdentifierSurfacesCollector collector;
0098 self.visitSurfaces(collector);
0099 return collector.surfaces;
0100 })
0101 .def("cylindricalVolumeRepresentation",
0102 [](const Detector& self, const GeometryContext& gctx) {
0103
0104 Extent extent;
0105 for (const auto& volume : self.volumes()) {
0106 extent.extend(volume->extent(gctx));
0107 }
0108 auto bounds = std::make_shared<CylinderVolumeBounds>(
0109 0., extent.max(AxisDirection::AxisR),
0110 extent.max(AxisDirection::AxisZ));
0111
0112 return std::make_shared<Volume>(Transform3::Identity(),
0113 std::move(bounds));
0114 });
0115
0116
0117 py::class_<Experimental::Portal, std::shared_ptr<Experimental::Portal>>(
0118 m, "Portal");
0119
0120 {
0121
0122 using SurfaceHierarchyMap = GeometryHierarchyMap<std::shared_ptr<Surface>>;
0123
0124
0125 m.def("extractVolumeLayerSurfaces", [](const SurfaceHierarchyMap& smap,
0126 bool sensitiveOnly) {
0127 std::map<unsigned int,
0128 std::map<unsigned int, std::vector<std::shared_ptr<Surface>>>>
0129 surfaceVolumeLayerMap;
0130 for (const auto& surface : smap) {
0131 auto gid = surface->geometryId();
0132
0133 if (sensitiveOnly && gid.sensitive() == 0) {
0134 continue;
0135 };
0136 surfaceVolumeLayerMap[gid.volume()][gid.layer()].push_back(surface);
0137 }
0138
0139 return surfaceVolumeLayerMap;
0140 });
0141 }
0142
0143 {
0144
0145 py::class_<Experimental::IInternalStructureBuilder,
0146 std::shared_ptr<Experimental::IInternalStructureBuilder>>(
0147 m, "IInternalStructureBuilder");
0148
0149 auto lsBuilder =
0150 py::class_<LayerStructureBuilder,
0151 Experimental::IInternalStructureBuilder,
0152 std::shared_ptr<LayerStructureBuilder>>(
0153 m, "LayerStructureBuilder")
0154 .def(py::init([](const LayerStructureBuilder::Config& config,
0155 const std::string& name, Logging::Level level) {
0156 return std::make_shared<LayerStructureBuilder>(
0157 config, getDefaultLogger(name, level));
0158 }));
0159
0160 auto lsConfig =
0161 py::class_<LayerStructureBuilder::Config>(lsBuilder, "Config")
0162 .def(py::init<>());
0163 ACTS_PYTHON_STRUCT(lsConfig, surfacesProvider, supports, binnings,
0164 quarterSegments, auxiliary);
0165
0166
0167 py::class_<Experimental::ISurfacesProvider,
0168 std::shared_ptr<Experimental::ISurfacesProvider>>(
0169 m, "ISurfacesProvider");
0170
0171 py::class_<LayerStructureBuilder::SurfacesHolder,
0172 Experimental::ISurfacesProvider,
0173 std::shared_ptr<LayerStructureBuilder::SurfacesHolder>>(
0174 lsBuilder, "SurfacesHolder")
0175 .def(py::init<std::vector<std::shared_ptr<Surface>>>());
0176 }
0177
0178 {
0179 using RangeXDDim1 = RangeXD<1u, double>;
0180 using KdtSurfacesDim1Bin100 = Experimental::KdtSurfaces<1u, 100u>;
0181 using KdtSurfacesProviderDim1Bin100 =
0182 Experimental::KdtSurfacesProvider<1u, 100u>;
0183
0184 py::class_<RangeXDDim1>(m, "RangeXDDim1")
0185 .def(py::init([](const std::array<double, 2u>& irange) {
0186 RangeXDDim1 range;
0187 range[0].shrink(irange[0], irange[1]);
0188 return range;
0189 }));
0190
0191 py::class_<KdtSurfacesDim1Bin100, std::shared_ptr<KdtSurfacesDim1Bin100>>(
0192 m, "KdtSurfacesDim1Bin100")
0193 .def(py::init<const GeometryContext&,
0194 const std::vector<std::shared_ptr<Surface>>&,
0195 const std::array<AxisDirection, 1u>&>())
0196 .def("surfaces", py::overload_cast<const RangeXDDim1&>(
0197 &KdtSurfacesDim1Bin100::surfaces, py::const_));
0198
0199 py::class_<KdtSurfacesProviderDim1Bin100, Experimental::ISurfacesProvider,
0200 std::shared_ptr<KdtSurfacesProviderDim1Bin100>>(
0201 m, "KdtSurfacesProviderDim1Bin100")
0202 .def(py::init<std::shared_ptr<KdtSurfacesDim1Bin100>, const Extent&>());
0203 }
0204
0205 {
0206 using RangeXDDim2 = RangeXD<2u, double>;
0207 using KdtSurfacesDim2Bin100 = Experimental::KdtSurfaces<2u, 100u>;
0208 using KdtSurfacesProviderDim2Bin100 =
0209 Experimental::KdtSurfacesProvider<2u, 100u>;
0210
0211 py::class_<RangeXDDim2>(m, "RangeXDDim2")
0212 .def(py::init([](const std::array<double, 2u>& range0,
0213 const std::array<double, 2u>& range1) {
0214 RangeXDDim2 range;
0215 range[0].shrink(range0[0], range0[1]);
0216 range[1].shrink(range1[0], range1[1]);
0217 return range;
0218 }));
0219
0220 py::class_<KdtSurfacesDim2Bin100, std::shared_ptr<KdtSurfacesDim2Bin100>>(
0221 m, "KdtSurfacesDim2Bin100")
0222 .def(py::init<const GeometryContext&,
0223 const std::vector<std::shared_ptr<Surface>>&,
0224 const std::array<AxisDirection, 2u>&>())
0225 .def("surfaces", py::overload_cast<const RangeXDDim2&>(
0226 &KdtSurfacesDim2Bin100::surfaces, py::const_));
0227
0228 py::class_<KdtSurfacesProviderDim2Bin100, Experimental::ISurfacesProvider,
0229 std::shared_ptr<KdtSurfacesProviderDim2Bin100>>(
0230 m, "KdtSurfacesProviderDim2Bin100")
0231 .def(py::init<std::shared_ptr<KdtSurfacesDim2Bin100>, const Extent&>());
0232 }
0233
0234 {
0235 using RangeXDDim3 = RangeXD<3u, double>;
0236
0237 py::class_<RangeXDDim3>(m, "RangeXDDim3")
0238 .def(py::init([](const std::array<double, 2u>& range0,
0239 const std::array<double, 2u>& range1,
0240 const std::array<double, 2u>& range2) {
0241 RangeXDDim3 range;
0242 range[0].shrink(range0[0], range0[1]);
0243 range[1].shrink(range1[0], range1[1]);
0244 range[2].shrink(range2[0], range2[1]);
0245 return range;
0246 }));
0247 }
0248
0249 {
0250
0251 py::class_<Experimental::IExternalStructureBuilder,
0252 std::shared_ptr<Experimental::IExternalStructureBuilder>>(
0253 m, "IExternalStructureBuilder");
0254
0255 auto vsBuilder =
0256 py::class_<VolumeStructureBuilder,
0257 Experimental::IExternalStructureBuilder,
0258 std::shared_ptr<VolumeStructureBuilder>>(
0259 m, "VolumeStructureBuilder")
0260 .def(py::init([](const VolumeStructureBuilder::Config& config,
0261 const std::string& name, Logging::Level level) {
0262 return std::make_shared<VolumeStructureBuilder>(
0263 config, getDefaultLogger(name, level));
0264 }));
0265
0266 auto vsConfig =
0267 py::class_<VolumeStructureBuilder::Config>(vsBuilder, "Config")
0268 .def(py::init<>());
0269 ACTS_PYTHON_STRUCT(vsConfig, boundsType, boundValues, transform, auxiliary);
0270 }
0271
0272 {
0273 py::class_<Experimental::IGeometryIdGenerator,
0274 std::shared_ptr<Experimental::IGeometryIdGenerator>>(
0275 m, "IGeometryIdGenerator");
0276
0277 auto geoIdGen =
0278 py::class_<Experimental::GeometryIdGenerator,
0279 Experimental::IGeometryIdGenerator,
0280 std::shared_ptr<Experimental::GeometryIdGenerator>>(
0281 m, "GeometryIdGenerator")
0282 .def(py::init([](Experimental::GeometryIdGenerator::Config& config,
0283 const std::string& name, Logging::Level level) {
0284 return std::make_shared<Experimental::GeometryIdGenerator>(
0285 config, getDefaultLogger(name, level));
0286 }));
0287
0288 auto geoIdGenConfig = py::class_<Experimental::GeometryIdGenerator::Config>(
0289 geoIdGen, "Config")
0290 .def(py::init<>());
0291 ACTS_PYTHON_STRUCT(geoIdGenConfig, containerMode, containerId,
0292 resetSubCounters, overrideExistingIds);
0293 }
0294
0295 {
0296
0297 py::class_<Experimental::IDetectorComponentBuilder,
0298 std::shared_ptr<Experimental::IDetectorComponentBuilder>>(
0299 m, "IDetectorComponentBuilder");
0300
0301 auto dvBuilder =
0302 py::class_<DetectorVolumeBuilder,
0303 Experimental::IDetectorComponentBuilder,
0304 std::shared_ptr<DetectorVolumeBuilder>>(
0305 m, "DetectorVolumeBuilder")
0306 .def(py::init([](const DetectorVolumeBuilder::Config& config,
0307 const std::string& name, Logging::Level level) {
0308 return std::make_shared<DetectorVolumeBuilder>(
0309 config, getDefaultLogger(name, level));
0310 }))
0311 .def("construct", &DetectorVolumeBuilder::construct);
0312
0313 auto dvConfig =
0314 py::class_<DetectorVolumeBuilder::Config>(dvBuilder, "Config")
0315 .def(py::init<>());
0316 ACTS_PYTHON_STRUCT(dvConfig, name, internalsBuilder, externalsBuilder,
0317 geoIdGenerator, auxiliary);
0318 }
0319
0320 {
0321
0322 py::class_<Experimental::IRootVolumeFinderBuilder,
0323 std::shared_ptr<Experimental::IRootVolumeFinderBuilder>>(
0324 m, "IRootVolumeFinderBuilder");
0325
0326 auto irvBuilder =
0327 py::class_<
0328 Experimental::IndexedRootVolumeFinderBuilder,
0329 Experimental::IRootVolumeFinderBuilder,
0330 std::shared_ptr<Experimental::IndexedRootVolumeFinderBuilder>>(
0331 m, "IndexedRootVolumeFinderBuilder")
0332 .def(py::init<std::vector<AxisDirection>>());
0333 }
0334
0335 {
0336
0337 auto ccBuilder =
0338 py::class_<CylindricalContainerBuilder,
0339 Experimental::IDetectorComponentBuilder,
0340 std::shared_ptr<CylindricalContainerBuilder>>(
0341 m, "CylindricalContainerBuilder")
0342 .def(py::init([](const CylindricalContainerBuilder::Config& config,
0343 const std::string& name, Logging::Level level) {
0344 return std::make_shared<CylindricalContainerBuilder>(
0345 config, getDefaultLogger(name, level));
0346 }))
0347 .def("construct", &CylindricalContainerBuilder::construct);
0348
0349 auto ccConfig =
0350 py::class_<CylindricalContainerBuilder::Config>(ccBuilder, "Config")
0351 .def(py::init<>());
0352 ACTS_PYTHON_STRUCT(ccConfig, builders, binning, rootVolumeFinderBuilder,
0353 geoIdGenerator, geoIdReverseGen, auxiliary);
0354 }
0355
0356 {
0357
0358 auto ccBuilder =
0359 py::class_<CuboidalContainerBuilder,
0360 Experimental::IDetectorComponentBuilder,
0361 std::shared_ptr<CuboidalContainerBuilder>>(
0362 m, "CuboidalContainerBuilder")
0363 .def(py::init([](const CuboidalContainerBuilder::Config& config,
0364 const std::string& name, Logging::Level level) {
0365 return std::make_shared<CuboidalContainerBuilder>(
0366 config, getDefaultLogger(name, level));
0367 }))
0368 .def("construct", &CuboidalContainerBuilder::construct);
0369
0370 auto ccConfig =
0371 py::class_<CuboidalContainerBuilder::Config>(ccBuilder, "Config")
0372 .def(py::init<>());
0373 ACTS_PYTHON_STRUCT(ccConfig, builders, binning, rootVolumeFinderBuilder,
0374 geoIdGenerator, geoIdReverseGen, auxiliary);
0375 }
0376
0377 {
0378
0379 auto dBuilder =
0380 py::class_<DetectorBuilder, std::shared_ptr<DetectorBuilder>>(
0381 m, "DetectorBuilder")
0382 .def(py::init([](const DetectorBuilder::Config& config,
0383 const std::string& name, Logging::Level level) {
0384 return std::make_shared<DetectorBuilder>(
0385 config, getDefaultLogger(name, level));
0386 }))
0387 .def("construct", &DetectorBuilder::construct);
0388
0389 auto dConfig = py::class_<DetectorBuilder::Config>(dBuilder, "Config")
0390 .def(py::init<>());
0391 ACTS_PYTHON_STRUCT(dConfig, name, builder, geoIdGenerator,
0392 materialDecorator, auxiliary);
0393 }
0394 }
0395
0396 }