File indexing completed on 2025-08-05 08:10:05
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Definitions/Algebra.hpp"
0010 #include "Acts/Detector/Detector.hpp"
0011 #include "Acts/Geometry/TrackingGeometry.hpp"
0012 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0013 #include "Acts/Plugins/Geant4/Geant4DetectorElement.hpp"
0014 #include "Acts/Plugins/Geant4/Geant4DetectorSurfaceFactory.hpp"
0015 #include "Acts/Plugins/Geant4/Geant4PhysicalVolumeSelectors.hpp"
0016 #include "Acts/Plugins/Python/Utilities.hpp"
0017 #include "Acts/Utilities/Logger.hpp"
0018 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0019 #include "ActsExamples/Framework/IContextDecorator.hpp"
0020 #include "ActsExamples/Geant4/DetectorConstructionFactory.hpp"
0021 #include "ActsExamples/Geant4/GdmlDetectorConstruction.hpp"
0022 #include "ActsExamples/Geant4/Geant4Manager.hpp"
0023 #include "ActsExamples/Geant4/Geant4Simulation.hpp"
0024 #include "ActsExamples/Geant4/RegionCreator.hpp"
0025 #include "ActsExamples/Geant4Detector/Geant4Detector.hpp"
0026 #include "ActsExamples/MuonSpectrometerMockupDetector/MockupSectorBuilder.hpp"
0027 #include "ActsExamples/TelescopeDetector/TelescopeDetector.hpp"
0028 #include "ActsExamples/TelescopeDetector/TelescopeG4DetectorConstruction.hpp"
0029
0030 #include <array>
0031 #include <memory>
0032 #include <optional>
0033 #include <string>
0034 #include <tuple>
0035 #include <unordered_map>
0036 #include <utility>
0037 #include <vector>
0038
0039 #include <G4RunManager.hh>
0040 #include <G4Transform3D.hh>
0041 #include <G4UserEventAction.hh>
0042 #include <G4UserRunAction.hh>
0043 #include <pybind11/pybind11.h>
0044 #include <pybind11/stl.h>
0045
0046 class G4UserSteppingAction;
0047 class G4VUserPhysicsList;
0048 namespace Acts {
0049 class MagneticFieldProvider;
0050 class TrackingGeometry;
0051 class Volume;
0052 }
0053 namespace ActsExamples {
0054 class RandomNumbers;
0055 }
0056
0057 namespace py = pybind11;
0058 using namespace pybind11::literals;
0059
0060 using namespace ActsExamples;
0061 using namespace Acts;
0062 using namespace Acts::Python;
0063
0064 namespace Acts::Python {
0065 void addGeant4HepMC3(Context& ctx);
0066 }
0067
0068 PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) {
0069 py::class_<DetectorConstructionFactory,
0070 std::shared_ptr<DetectorConstructionFactory>>(
0071 mod, "DetectorConstructionFactory");
0072
0073 py::class_<Geant4Manager, std::unique_ptr<Geant4Manager, py::nodelete>>(
0074 mod, "Geant4Manager")
0075 .def_static("instance", &Geant4Manager::instance,
0076 py::return_value_policy::reference)
0077 .def("currentHandle", &Geant4Manager::currentHandle);
0078
0079 py::class_<Geant4Handle, std::shared_ptr<Geant4Handle>>(mod, "Geant4Handle")
0080 .def("tweakLogging", &Geant4Handle::tweakLogging);
0081
0082 {
0083 using Algorithm = Geant4SimulationBase;
0084 using Config = Algorithm::Config;
0085 auto alg =
0086 py::class_<Algorithm, IAlgorithm, std::shared_ptr<Algorithm>>(
0087 mod, "Geant4SimulationBase")
0088 .def_property_readonly("geant4Handle", &Algorithm::geant4Handle);
0089
0090 auto c1 = py::class_<Config, std::shared_ptr<Config>>(alg, "Config")
0091 .def(py::init<>());
0092 ACTS_PYTHON_STRUCT_BEGIN(c1, Config);
0093 ACTS_PYTHON_MEMBER(inputParticles);
0094 ACTS_PYTHON_MEMBER(randomNumbers);
0095 ACTS_PYTHON_MEMBER(detectorConstructionFactory);
0096 ACTS_PYTHON_MEMBER(geant4Handle);
0097 ACTS_PYTHON_STRUCT_END();
0098 }
0099
0100 {
0101 using Algorithm = Geant4Simulation;
0102 using Config = Algorithm::Config;
0103 auto alg =
0104 py::class_<Algorithm, Geant4SimulationBase, std::shared_ptr<Algorithm>>(
0105 mod, "Geant4Simulation")
0106 .def(py::init<const Config&, Acts::Logging::Level>(),
0107 py::arg("config"), py::arg("level"))
0108 .def_property_readonly("config", &Algorithm::config);
0109
0110 auto c1 = py::class_<Config, Geant4SimulationBase::Config,
0111 std::shared_ptr<Config>>(alg, "Config")
0112 .def(py::init<>());
0113 ACTS_PYTHON_STRUCT_BEGIN(c1, Config);
0114 ACTS_PYTHON_MEMBER(outputSimHits);
0115 ACTS_PYTHON_MEMBER(outputParticlesInitial);
0116 ACTS_PYTHON_MEMBER(outputParticlesFinal);
0117 ACTS_PYTHON_MEMBER(trackingGeometry);
0118 ACTS_PYTHON_MEMBER(magneticField);
0119 ACTS_PYTHON_MEMBER(physicsList);
0120 ACTS_PYTHON_MEMBER(volumeMappings);
0121 ACTS_PYTHON_MEMBER(materialMappings);
0122 ACTS_PYTHON_MEMBER(killVolume);
0123 ACTS_PYTHON_MEMBER(killAfterTime);
0124 ACTS_PYTHON_MEMBER(killSecondaries);
0125 ACTS_PYTHON_MEMBER(recordHitsOfSecondaries);
0126 ACTS_PYTHON_MEMBER(keepParticlesWithoutHits);
0127 ACTS_PYTHON_STRUCT_END();
0128 }
0129
0130 {
0131 using Algorithm = Geant4MaterialRecording;
0132 using Config = Algorithm::Config;
0133 auto alg =
0134 py::class_<Algorithm, Geant4SimulationBase, std::shared_ptr<Algorithm>>(
0135 mod, "Geant4MaterialRecording")
0136 .def(py::init<const Config&, Acts::Logging::Level>(),
0137 py::arg("config"), py::arg("level"))
0138 .def_property_readonly("config", &Algorithm::config);
0139
0140 auto c = py::class_<Config, Geant4SimulationBase::Config,
0141 std::shared_ptr<Config>>(alg, "Config")
0142 .def(py::init<>());
0143 ACTS_PYTHON_STRUCT_BEGIN(c, Config);
0144 ACTS_PYTHON_MEMBER(outputMaterialTracks);
0145 ACTS_PYTHON_MEMBER(excludeMaterials);
0146 ACTS_PYTHON_STRUCT_END();
0147 }
0148
0149 {
0150 py::class_<GdmlDetectorConstructionFactory, DetectorConstructionFactory,
0151 std::shared_ptr<GdmlDetectorConstructionFactory>>(
0152 mod, "GdmlDetectorConstructionFactory")
0153 .def(py::init<std::string,
0154 std::vector<std::shared_ptr<RegionCreator>>>(),
0155 py::arg("path"),
0156 py::arg("regionCreators") =
0157 std::vector<std::shared_ptr<RegionCreator>>());
0158 }
0159
0160 {
0161 py::class_<
0162 Telescope::TelescopeG4DetectorConstructionFactory,
0163 DetectorConstructionFactory,
0164 std::shared_ptr<Telescope::TelescopeG4DetectorConstructionFactory>>(
0165 mod, "TelescopeG4DetectorConstructionFactory")
0166 .def(py::init<const Telescope::TelescopeDetector::Config&,
0167 std::vector<std::shared_ptr<RegionCreator>>>(),
0168 py::arg("cfg"),
0169 py::arg("regionCreators") =
0170 std::vector<std::shared_ptr<RegionCreator>>());
0171 }
0172
0173 {
0174 using ISelector = Acts::IGeant4PhysicalVolumeSelector;
0175 auto is = py::class_<ISelector, std::shared_ptr<ISelector>>(
0176 mod, "IVolumeSelector");
0177
0178 using NameSelector = Acts::Geant4PhysicalVolumeSelectors::NameSelector;
0179 auto ns = py::class_<NameSelector, std::shared_ptr<NameSelector>>(
0180 mod, "VolumeNameSelector", is)
0181 .def(py::init<const std::vector<std::string>&, bool>());
0182
0183 using Factory = Acts::Geant4DetectorSurfaceFactory;
0184 auto o = py::class_<Factory::Options>(mod, "SurfaceFactoryOptions")
0185 .def(py::init<>());
0186 ACTS_PYTHON_STRUCT_BEGIN(o, Factory::Options);
0187 ACTS_PYTHON_MEMBER(scaleConversion);
0188 ACTS_PYTHON_MEMBER(convertMaterial);
0189 ACTS_PYTHON_MEMBER(convertedMaterialThickness);
0190 ACTS_PYTHON_MEMBER(sensitiveSurfaceSelector);
0191 ACTS_PYTHON_MEMBER(passiveSurfaceSelector);
0192 ACTS_PYTHON_STRUCT_END();
0193 }
0194
0195 {
0196 py::class_<Acts::Geant4DetectorElement,
0197 std::shared_ptr<Acts::Geant4DetectorElement>>(
0198 mod, "Geant4DetectorElement");
0199
0200 using Geant4Detector = Geant4::Geant4Detector;
0201
0202 auto g =
0203 py::class_<Geant4Detector, std::shared_ptr<Geant4Detector>>(
0204 mod, "Geant4Detector")
0205 .def(py::init<>())
0206 .def(
0207 "constructDetector",
0208 [](Geant4Detector& self, const Geant4Detector::Config& cfg,
0209 Logging::Level logLevel) {
0210 auto logger = getDefaultLogger("Geant4Detector", logLevel);
0211 return self.constructDetector(cfg, *logger);
0212 },
0213 py::arg("cfg"), py::arg("logLevel") = Logging::INFO)
0214 .def(
0215 "constructTrackingGeometry",
0216 [](Geant4Detector& self, const Geant4Detector::Config& cfg,
0217 Logging::Level logLevel) {
0218 auto logger = getDefaultLogger("Geant4Detector", logLevel);
0219 return self.constructTrackingGeometry(cfg, *logger);
0220 },
0221 py::arg("cfg"), py::arg("logLevel") = Logging::INFO);
0222
0223 auto c = py::class_<Geant4Detector::Config>(g, "Config").def(py::init<>());
0224 ACTS_PYTHON_STRUCT_BEGIN(c, Geant4Detector::Config);
0225 ACTS_PYTHON_MEMBER(name);
0226 ACTS_PYTHON_MEMBER(g4World);
0227 ACTS_PYTHON_MEMBER(g4SurfaceOptions);
0228 ACTS_PYTHON_MEMBER(protoDetector);
0229 ACTS_PYTHON_MEMBER(geometryIdentifierHook);
0230 ACTS_PYTHON_MEMBER(logLevel);
0231 ACTS_PYTHON_STRUCT_END();
0232 }
0233
0234 {
0235
0236
0237
0238
0239
0240 mod.def("convertSurfaces", [](const std::string& gdmlFileName,
0241 const std::vector<std::string>&
0242 sensitiveMatches,
0243 const std::vector<std::string>&
0244 passiveMatches) {
0245
0246 ActsExamples::GdmlDetectorConstruction gdmlContruction(gdmlFileName);
0247 const auto* world = gdmlContruction.Construct();
0248
0249
0250 auto sensitiveSelectors =
0251 std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
0252 sensitiveMatches, false);
0253 auto passiveSelectors =
0254 std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
0255 passiveMatches, false);
0256
0257 Acts::Geant4DetectorSurfaceFactory::Cache cache;
0258 Acts::Geant4DetectorSurfaceFactory::Options options;
0259 options.sensitiveSurfaceSelector = sensitiveSelectors;
0260 options.passiveSurfaceSelector = passiveSelectors;
0261
0262 G4Transform3D nominal;
0263 Acts::Geant4DetectorSurfaceFactory factory;
0264 factory.construct(cache, nominal, *world, options);
0265
0266
0267 using Elements =
0268 std::vector<std::shared_ptr<Acts::Geant4DetectorElement>>;
0269 Elements detectorElements;
0270 detectorElements.reserve(cache.sensitiveSurfaces.size());
0271 using Surfaces = std::vector<std::shared_ptr<Acts::Surface>>;
0272 Surfaces surfaces;
0273 surfaces.reserve(cache.sensitiveSurfaces.size());
0274 std::for_each(cache.sensitiveSurfaces.begin(),
0275 cache.sensitiveSurfaces.end(), [&](const auto& sensitive) {
0276 detectorElements.push_back(std::get<0>(sensitive));
0277 surfaces.push_back(std::get<1>(sensitive));
0278 });
0279
0280
0281 Surfaces passiveSurfaces;
0282 passiveSurfaces.reserve(cache.passiveSurfaces.size());
0283 for (const auto& passive : cache.passiveSurfaces) {
0284 passiveSurfaces.push_back(passive);
0285 }
0286
0287
0288 return std::tuple<Elements, Surfaces, Surfaces>(
0289 std::move(detectorElements), std::move(surfaces),
0290 std::move(passiveSurfaces));
0291 });
0292 }
0293
0294 {
0295 using MockupSectorBuilder = MockupSectorBuilder;
0296 using Config = MockupSectorBuilder::Config;
0297 using ChamberConfig = MockupSectorBuilder::ChamberConfig;
0298
0299 auto ms =
0300 py::class_<MockupSectorBuilder, std::shared_ptr<MockupSectorBuilder>>(
0301 mod, "MockupSectorBuilder")
0302 .def(py::init<const Config&>())
0303 .def("buildChamber", &MockupSectorBuilder::buildChamber)
0304 .def("buildSector", &MockupSectorBuilder::buildSector)
0305 .def("drawSector", &MockupSectorBuilder::drawSector);
0306
0307 auto c = py::class_<Config>(ms, "Config").def(py::init<>());
0308 ACTS_PYTHON_STRUCT_BEGIN(c, Config);
0309 ACTS_PYTHON_MEMBER(gdmlPath);
0310 ACTS_PYTHON_MEMBER(NumberOfSectors);
0311 ACTS_PYTHON_MEMBER(toleranceOverlap);
0312 ACTS_PYTHON_STRUCT_END();
0313
0314 auto cch = py::class_<ChamberConfig>(ms, "ChamberConfig").def(py::init<>());
0315 ACTS_PYTHON_STRUCT_BEGIN(cch, ChamberConfig);
0316 ACTS_PYTHON_MEMBER(name);
0317 ACTS_PYTHON_MEMBER(SensitiveNames);
0318 ACTS_PYTHON_MEMBER(PassiveNames);
0319 ACTS_PYTHON_STRUCT_END();
0320 }
0321
0322 {
0323 using Tool = RegionCreator;
0324 using Config = Tool::Config;
0325 auto tool = py::class_<Tool, std::shared_ptr<Tool>>(mod, "RegionCreator")
0326 .def(py::init<const Config&, std::string, Logging::Level>(),
0327 py::arg("config"), py::arg("name"),
0328 py::arg("logLevel") = Logging::INFO)
0329 .def_property_readonly("config", &Tool::config);
0330
0331 auto c = py::class_<Config>(tool, "Config").def(py::init<>());
0332 ACTS_PYTHON_STRUCT_BEGIN(c, Config);
0333 ACTS_PYTHON_MEMBER(gammaCut);
0334 ACTS_PYTHON_MEMBER(electronCut);
0335 ACTS_PYTHON_MEMBER(positronCut);
0336 ACTS_PYTHON_MEMBER(protonCut);
0337 ACTS_PYTHON_MEMBER(volumes);
0338 ACTS_PYTHON_STRUCT_END();
0339 }
0340
0341 Acts::Python::Context ctx;
0342 ctx.modules["geant4"] = mod;
0343
0344 addGeant4HepMC3(ctx);
0345 }