File indexing completed on 2025-08-05 08:09:51
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Geant4Detector/Geant4Detector.hpp"
0010
0011 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Geometry/KDTreeTrackingGeometryBuilder.hpp"
0014 #include "Acts/Geometry/LayerArrayCreator.hpp"
0015 #include "Acts/Geometry/LayerCreator.hpp"
0016 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0017 #include "Acts/Geometry/TrackingGeometry.hpp"
0018 #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp"
0019
0020 #include <ostream>
0021 #include <stdexcept>
0022
0023 #include "G4VPhysicalVolume.hh"
0024
0025 auto ActsExamples::Geant4::Geant4Detector::constructDetector(
0026 const ActsExamples::Geant4::Geant4Detector::Config& cfg,
0027 const Acts::Logger& logger)
0028 -> std::tuple<DetectorPtr, ContextDecorators, DetectorElements> {
0029 if (cfg.g4World == nullptr) {
0030 throw std::invalid_argument(
0031 "Geant4Detector: no world Geant4 volume provided");
0032 }
0033
0034 ACTS_INFO("Building an Acts::Detector called '"
0035 << cfg.name << "' from the Geant4PhysVolume '"
0036 << cfg.g4World->GetName() << "'");
0037
0038 DetectorPtr detector = nullptr;
0039 ContextDecorators decorators = {};
0040
0041 auto [surfaces, elements] = convertGeant4Volumes(cfg, logger);
0042
0043 return std::tie(detector, decorators, elements);
0044 }
0045
0046 auto ActsExamples::Geant4::Geant4Detector::constructTrackingGeometry(
0047 const ActsExamples::Geant4::Geant4Detector::Config& cfg,
0048 const Acts::Logger& logger)
0049 -> std::tuple<TrackingGeometryPtr, ContextDecorators, DetectorElements> {
0050 if (cfg.g4World == nullptr) {
0051 throw std::invalid_argument(
0052 "Geant4Detector: no world Geant4 volume provided");
0053 }
0054
0055 ACTS_INFO("Building an Acts::TrackingGeometry called '"
0056 << cfg.name << "' from the Geant4PhysVolume '"
0057 << cfg.g4World->GetName() << "'");
0058
0059 ContextDecorators decorators = {};
0060
0061 auto [surfaces, elements] = convertGeant4Volumes(cfg, logger);
0062
0063
0064 auto surfaceArrayCreator = std::make_shared<const Acts::SurfaceArrayCreator>(
0065 Acts::SurfaceArrayCreator::Config(), logger.clone("SurfaceArrayCreator"));
0066
0067 Acts::LayerCreator::Config lcConfig;
0068 lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0069 auto layerCreator = std::make_shared<Acts::LayerCreator>(
0070 lcConfig, logger.clone("LayerCreator"));
0071
0072 Acts::LayerArrayCreator::Config lacConfig;
0073 auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
0074 lacConfig, logger.clone("LayerArrayCreator"));
0075
0076 Acts::TrackingVolumeArrayCreator::Config tvacConfig;
0077 auto tVolumeArrayCreator =
0078 std::make_shared<const Acts::TrackingVolumeArrayCreator>(
0079 tvacConfig, logger.clone("TrackingVolumeArrayCreator"));
0080
0081 Acts::CylinderVolumeHelper::Config cvhConfig;
0082 cvhConfig.layerArrayCreator = layerArrayCreator;
0083 cvhConfig.trackingVolumeArrayCreator = tVolumeArrayCreator;
0084 auto cylinderVolumeHelper =
0085 std::make_shared<const Acts::CylinderVolumeHelper>(
0086 cvhConfig, logger.clone("CylinderVolumeHelper"));
0087
0088
0089 Acts::KDTreeTrackingGeometryBuilder::Config kdtCfg;
0090 kdtCfg.surfaces = surfaces;
0091 kdtCfg.layerCreator = layerCreator;
0092 kdtCfg.trackingVolumeHelper = cylinderVolumeHelper;
0093 kdtCfg.protoDetector = cfg.protoDetector;
0094 kdtCfg.geometryIdentifierHook = cfg.geometryIdentifierHook;
0095
0096
0097 auto kdtBuilder = Acts::KDTreeTrackingGeometryBuilder(
0098 kdtCfg, logger.clone("KDTreeTrackingGeometryBuilder"));
0099
0100 Acts::GeometryContext tContext;
0101 TrackingGeometryPtr trackingGeometry = kdtBuilder.trackingGeometry(tContext);
0102
0103 return std::tie(trackingGeometry, decorators, elements);
0104 }
0105
0106 auto ActsExamples::Geant4::Geant4Detector::convertGeant4Volumes(
0107 const Geant4Detector::Config& cfg, const Acts::Logger& logger) const
0108 -> std::tuple<ActsExamples::Geant4::Geant4Detector::Surfaces,
0109 ActsExamples::Geant4::Geant4Detector::DetectorElements> {
0110
0111 Acts::Geant4DetectorSurfaceFactory::Cache g4SurfaceCache;
0112 G4Transform3D g4ToWorld;
0113
0114 Acts::Geant4DetectorSurfaceFactory{}.construct(
0115 g4SurfaceCache, g4ToWorld, *cfg.g4World, cfg.g4SurfaceOptions);
0116
0117 ACTS_INFO("Found " << g4SurfaceCache.matchedG4Volumes
0118 << " matching Geant4 Physical volumes.");
0119 ACTS_INFO("Found " << g4SurfaceCache.sensitiveSurfaces.size()
0120 << " converted sensitive Geant4 Physical volumes.");
0121 ACTS_INFO("Found " << g4SurfaceCache.passiveSurfaces.size()
0122 << " converted passive Geant4 Physical volumes.");
0123 ACTS_INFO("Found " << g4SurfaceCache.convertedMaterials
0124 << " converted Geant4 Material slabs.");
0125
0126 Surfaces surfaces = {};
0127 DetectorElements elements = {};
0128
0129
0130 surfaces.reserve(g4SurfaceCache.sensitiveSurfaces.size() +
0131 g4SurfaceCache.passiveSurfaces.size());
0132 elements.reserve(g4SurfaceCache.sensitiveSurfaces.size());
0133
0134
0135 for (const auto& [e, s] : g4SurfaceCache.sensitiveSurfaces) {
0136 elements.push_back(e);
0137 surfaces.push_back(s);
0138 }
0139
0140 surfaces.insert(surfaces.end(), g4SurfaceCache.passiveSurfaces.begin(),
0141 g4SurfaceCache.passiveSurfaces.end());
0142
0143 return std::tie(surfaces, elements);
0144 }