Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-13 08:18:26

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/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   /// @param surface is the test surface
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   /// @param surface is the test surface
0066   void operator()(const Surface* surface) {
0067     surfaces[surface->geometryId()] = surface;
0068   }
0069 };
0070 
0071 }  // namespace
0072 
0073 namespace ActsPython {
0074 /// This adds the geometry building bindings for the Gen2 geometry
0075 /// @param m the module to add the bindings to
0076 void addGeometryGen2(py::module_& m) {
0077   // Detector volume definition
0078   py::class_<DetectorVolume, std::shared_ptr<DetectorVolume>>(m,
0079                                                               "DetectorVolume")
0080       .def("surfaces", &DetectorVolume::surfaces)
0081       .def("surfacePtrs", &DetectorVolume::surfacePtrs);
0082 
0083   // Detector definition
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              // Loop over the volumes and gather the extent
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   // Portal definition
0117   py::class_<Experimental::Portal, std::shared_ptr<Experimental::Portal>>(
0118       m, "Portal");
0119 
0120   {
0121     // The surface hierarchy map
0122     using SurfaceHierarchyMap = GeometryHierarchyMap<std::shared_ptr<Surface>>;
0123 
0124     // Extract volume / layer surfaces
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         // Exclusion criteria
0133         if (sensitiveOnly && gid.sensitive() == 0) {
0134           continue;
0135         };
0136         surfaceVolumeLayerMap[gid.volume()][gid.layer()].push_back(surface);
0137       }
0138       // Return the surface volume map
0139       return surfaceVolumeLayerMap;
0140     });
0141   }
0142 
0143   {
0144     // The internal layer structure builder
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     // The internal layer structure builder
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     // The external volume structure builder
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     // Put them together to a detector volume
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     // The external volume structure builder
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     // Cylindrical container builder
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     // Cuboidal container builder
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     // Detector builder
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 }  // namespace ActsPython