Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Geant4Component.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Geant4Component.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
28 
29 #include <array>
30 #include <memory>
31 #include <optional>
32 #include <string>
33 #include <tuple>
34 #include <unordered_map>
35 #include <utility>
36 #include <vector>
37 
38 #include <G4RunManager.hh>
39 #include <G4Transform3D.hh>
40 #include <G4UserEventAction.hh>
41 #include <G4UserRunAction.hh>
42 #include <pybind11/pybind11.h>
43 #include <pybind11/stl.h>
44 
45 class G4UserSteppingAction;
46 class G4VUserPhysicsList;
47 namespace Acts {
49 class TrackingGeometry;
50 class Volume;
51 } // namespace Acts
52 namespace ActsExamples {
53 class RandomNumbers;
54 } // namespace ActsExamples
55 
56 namespace py = pybind11;
57 using namespace pybind11::literals;
58 
59 using namespace ActsExamples;
60 using namespace Acts;
61 using namespace Acts::Python;
62 
63 namespace Acts::Python {
64 void addGeant4HepMC3(Context& ctx);
65 }
66 
67 PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) {
68  py::class_<DetectorConstructionFactory,
69  std::shared_ptr<DetectorConstructionFactory>>(
70  mod, "DetectorConstructionFactory");
71 
72  py::class_<Geant4Manager, std::unique_ptr<Geant4Manager, py::nodelete>>(
73  mod, "Geant4Manager")
74  .def_static("instance", &Geant4Manager::instance,
75  py::return_value_policy::reference)
76  .def("currentHandle", &Geant4Manager::currentHandle);
77 
78  py::class_<Geant4Handle, std::shared_ptr<Geant4Handle>>(mod, "Geant4Handle")
79  .def("tweakLogging", &Geant4Handle::tweakLogging);
80 
81  {
82  using Algorithm = Geant4SimulationBase;
83  using Config = Algorithm::Config;
84  auto alg =
85  py::class_<Algorithm, IAlgorithm, std::shared_ptr<Algorithm>>(
86  mod, "Geant4SimulationBase")
87  .def_property_readonly("geant4Handle", &Algorithm::geant4Handle);
88 
89  auto c1 = py::class_<Config, std::shared_ptr<Config>>(alg, "Config")
90  .def(py::init<>());
95  ACTS_PYTHON_MEMBER(geant4Handle);
97  }
98 
99  {
100  using Algorithm = Geant4Simulation;
101  using Config = Algorithm::Config;
102  auto alg =
103  py::class_<Algorithm, Geant4SimulationBase, std::shared_ptr<Algorithm>>(
104  mod, "Geant4Simulation")
105  .def(py::init<const Config&, Acts::Logging::Level>(),
106  py::arg("config"), py::arg("level"))
107  .def_property_readonly("config", &Algorithm::config);
108 
109  auto c1 = py::class_<Config, Geant4SimulationBase::Config,
110  std::shared_ptr<Config>>(alg, "Config")
111  .def(py::init<>());
112  ACTS_PYTHON_STRUCT_BEGIN(c1, Config);
118  ACTS_PYTHON_MEMBER(physicsList);
119  ACTS_PYTHON_MEMBER(volumeMappings);
120  ACTS_PYTHON_MEMBER(materialMappings);
124  ACTS_PYTHON_MEMBER(recordHitsOfSecondaries);
125  ACTS_PYTHON_MEMBER(keepParticlesWithoutHits);
127  }
128 
129  {
130  using Algorithm = Geant4MaterialRecording;
131  using Config = Algorithm::Config;
132  auto alg =
133  py::class_<Algorithm, Geant4SimulationBase, std::shared_ptr<Algorithm>>(
134  mod, "Geant4MaterialRecording")
135  .def(py::init<const Config&, Acts::Logging::Level>(),
136  py::arg("config"), py::arg("level"))
137  .def_property_readonly("config", &Algorithm::config);
138 
139  auto c = py::class_<Config, Geant4SimulationBase::Config,
140  std::shared_ptr<Config>>(alg, "Config")
141  .def(py::init<>());
142  ACTS_PYTHON_STRUCT_BEGIN(c, Config);
143  ACTS_PYTHON_MEMBER(outputMaterialTracks);
145  }
146 
147  {
148  py::class_<GdmlDetectorConstructionFactory, DetectorConstructionFactory,
149  std::shared_ptr<GdmlDetectorConstructionFactory>>(
150  mod, "GdmlDetectorConstructionFactory")
151  .def(py::init<std::string>());
152  }
153 
154  {
155  py::class_<
157  DetectorConstructionFactory,
158  std::shared_ptr<Telescope::TelescopeG4DetectorConstructionFactory>>(
159  mod, "TelescopeG4DetectorConstructionFactory")
160  .def(py::init<const Telescope::TelescopeDetector::Config&>());
161  }
162 
163  {
164  using ISelector = Acts::IGeant4PhysicalVolumeSelector;
165  auto is = py::class_<ISelector, std::shared_ptr<ISelector>>(
166  mod, "IVolumeSelector");
167 
169  auto ns = py::class_<NameSelector, std::shared_ptr<NameSelector>>(
170  mod, "VolumeNameSelector", is)
171  .def(py::init<const std::vector<std::string>&, bool>());
172 
174  auto o = py::class_<Factory::Options>(mod, "SurfaceFactoryOptions")
175  .def(py::init<>());
176  ACTS_PYTHON_STRUCT_BEGIN(o, Factory::Options);
177  ACTS_PYTHON_MEMBER(scaleConversion);
178  ACTS_PYTHON_MEMBER(convertMaterial);
179  ACTS_PYTHON_MEMBER(convertedMaterialThickness);
180  ACTS_PYTHON_MEMBER(sensitiveSurfaceSelector);
181  ACTS_PYTHON_MEMBER(passiveSurfaceSelector);
183  }
184 
185  {
186  py::class_<Acts::Geant4DetectorElement,
187  std::shared_ptr<Acts::Geant4DetectorElement>>(
188  mod, "Geant4DetectorElement");
189 
190  using Geant4Detector = Geant4::Geant4Detector;
191 
192  auto g =
193  py::class_<Geant4Detector, std::shared_ptr<Geant4Detector>>(
194  mod, "Geant4Detector")
195  .def(py::init<>())
196  .def(
197  "constructDetector",
198  [](Geant4Detector& self, const Geant4Detector::Config& cfg,
200  auto logger = getDefaultLogger("Geant4Detector", logLevel);
201  return self.constructDetector(cfg, *logger);
202  },
203  py::arg("cfg"), py::arg("logLevel") = Logging::INFO)
204  .def(
205  "constructTrackingGeometry",
206  [](Geant4Detector& self, const Geant4Detector::Config& cfg,
207  Logging::Level logLevel) {
208  auto logger = getDefaultLogger("Geant4Detector", logLevel);
209  return self.constructTrackingGeometry(cfg, *logger);
210  },
211  py::arg("cfg"), py::arg("logLevel") = Logging::INFO);
212 
213  auto c = py::class_<Geant4Detector::Config>(g, "Config").def(py::init<>());
216  ACTS_PYTHON_MEMBER(g4World);
217  ACTS_PYTHON_MEMBER(g4SurfaceOptions);
218  ACTS_PYTHON_MEMBER(protoDetector);
219  ACTS_PYTHON_MEMBER(geometryIdentifierHook);
220  ACTS_PYTHON_MEMBER(logLevel);
222  }
223 
224  {
230  mod.def("convertSurfaces", [](const std::string& gdmlFileName,
231  const std::vector<std::string>&
232  sensitiveMatches,
233  const std::vector<std::string>&
234  passiveMatches) {
235  // Initiate the detector construction & retrieve world
236  ActsExamples::GdmlDetectorConstruction gdmlContruction(gdmlFileName);
237  const auto* world = gdmlContruction.Construct();
238 
239  // Create the selectors
240  auto sensitiveSelectors =
241  std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
242  sensitiveMatches, false);
243  auto passiveSelectors =
244  std::make_shared<Acts::Geant4PhysicalVolumeSelectors::NameSelector>(
245  passiveMatches, false);
246 
249  options.sensitiveSurfaceSelector = sensitiveSelectors;
250  options.passiveSurfaceSelector = passiveSelectors;
251 
252  G4Transform3D nominal;
254  factory.construct(cache, nominal, *world, options);
255 
256  // Capture the sensitive elements and the surfaces
257  using Elements =
258  std::vector<std::shared_ptr<Acts::Geant4DetectorElement>>;
259  Elements detectorElements;
260  detectorElements.reserve(cache.sensitiveSurfaces.size());
261  using Surfaces = std::vector<std::shared_ptr<Acts::Surface>>;
262  Surfaces surfaces;
263  surfaces.reserve(cache.sensitiveSurfaces.size());
264  std::for_each(cache.sensitiveSurfaces.begin(),
265  cache.sensitiveSurfaces.end(), [&](const auto& sensitive) {
266  detectorElements.push_back(std::get<0>(sensitive));
267  surfaces.push_back(std::get<1>(sensitive));
268  });
269 
270  // Capture the passive surfaces
271  Surfaces passiveSurfaces;
272  passiveSurfaces.reserve(cache.passiveSurfaces.size());
273  for (const auto& passive : cache.passiveSurfaces) {
274  passiveSurfaces.push_back(passive);
275  }
276 
277  // Return a convenient tuple for drawing
278  return std::tuple<Elements, Surfaces, Surfaces>(
279  std::move(detectorElements), std::move(surfaces),
280  std::move(passiveSurfaces));
281  });
282  }
283 
284  {
287  using ChamberConfig = MockupSectorBuilder::ChamberConfig;
288 
289  auto ms =
290  py::class_<MockupSectorBuilder, std::shared_ptr<MockupSectorBuilder>>(
291  mod, "MockupSectorBuilder")
292  .def(py::init<const Config&>())
293  .def("buildChamber", &MockupSectorBuilder::buildChamber)
294  .def("buildSector", &MockupSectorBuilder::buildSector)
295  .def("drawSector", &MockupSectorBuilder::drawSector);
296 
297  auto c = py::class_<Config>(ms, "Config").def(py::init<>());
299  ACTS_PYTHON_MEMBER(gdmlPath);
300  ACTS_PYTHON_MEMBER(NumberOfSectors);
301  ACTS_PYTHON_MEMBER(toleranceOverlap);
303 
304  auto cch = py::class_<ChamberConfig>(ms, "ChamberConfig").def(py::init<>());
305  ACTS_PYTHON_STRUCT_BEGIN(cch, ChamberConfig);
307  ACTS_PYTHON_MEMBER(SensitiveNames);
308  ACTS_PYTHON_MEMBER(PassiveNames);
310  }
311 
313  ctx.modules["geant4"] = mod;
314 
315  addGeant4HepMC3(ctx);
316 }