Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:51

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2022-2023 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 http://mozilla.org/MPL/2.0/.
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   // Surface array creator
0064   auto surfaceArrayCreator = std::make_shared<const Acts::SurfaceArrayCreator>(
0065       Acts::SurfaceArrayCreator::Config(), logger.clone("SurfaceArrayCreator"));
0066   // Layer Creator
0067   Acts::LayerCreator::Config lcConfig;
0068   lcConfig.surfaceArrayCreator = surfaceArrayCreator;
0069   auto layerCreator = std::make_shared<Acts::LayerCreator>(
0070       lcConfig, logger.clone("LayerCreator"));
0071   // Layer array creator
0072   Acts::LayerArrayCreator::Config lacConfig;
0073   auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>(
0074       lacConfig, logger.clone("LayerArrayCreator"));
0075   // Tracking volume array creator
0076   Acts::TrackingVolumeArrayCreator::Config tvacConfig;
0077   auto tVolumeArrayCreator =
0078       std::make_shared<const Acts::TrackingVolumeArrayCreator>(
0079           tvacConfig, logger.clone("TrackingVolumeArrayCreator"));
0080   // configure the cylinder volume helper
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   // Configure the tracking geometry builder, copy the surfaces in
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   // The KDT tracking geometry builder
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   // Generate the surface cache
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   // Reserve the right amount of surfaces
0130   surfaces.reserve(g4SurfaceCache.sensitiveSurfaces.size() +
0131                    g4SurfaceCache.passiveSurfaces.size());
0132   elements.reserve(g4SurfaceCache.sensitiveSurfaces.size());
0133 
0134   // Add the sensitive surfaces
0135   for (const auto& [e, s] : g4SurfaceCache.sensitiveSurfaces) {
0136     elements.push_back(e);
0137     surfaces.push_back(s);
0138   }
0139   // Add the passive surfaces
0140   surfaces.insert(surfaces.end(), g4SurfaceCache.passiveSurfaces.begin(),
0141                   g4SurfaceCache.passiveSurfaces.end());
0142 
0143   return std::tie(surfaces, elements);
0144 }