Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:42

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 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 #pragma once
0010 
0011 #include "Acts/Detector/KdtSurfacesProvider.hpp"
0012 #include "Acts/Detector/interface/ISurfacesProvider.hpp"
0013 #include "Acts/Plugins/Geant4/Geant4DetectorSurfaceFactory.hpp"
0014 
0015 #include "G4GDMLParser.hh"
0016 #include "G4LogicalVolume.hh"
0017 #include "G4VPhysicalVolume.hh"
0018 
0019 namespace Acts::Experimental {
0020 
0021 /// @brief A surface provider that extracts surfaces from a gdml file
0022 ///
0023 /// This provider extracts volumes from a gdml file based on
0024 /// the preselection criteria and converts them to surfaces.
0025 /// By default, all the volumes are converted.
0026 ///
0027 /// Optionally, it can be configured to return a range-based
0028 /// subset of all the preselected surfaces. This is done
0029 /// by setting the range and binning values in the kdtOptions
0030 ///
0031 /// @note if the KDTree selection is not needed, the
0032 /// template parameters can be left to their default values
0033 /// as they will not affect the result.
0034 ///
0035 /// @tparam kDim The number of dimensions for the KDTree
0036 /// @tparam bSize The maximum number of surfaces per KDTree leaf
0037 /// @tparam reference_generator The reference generator for the KDTree
0038 template <std::size_t kDim = 2u, std::size_t bSize = 100u,
0039           typename reference_generator =
0040               detail::PolyhedronReferenceGenerator<1u, false>>
0041 class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider {
0042  public:
0043   /// Nested configuration struct
0044   struct Config {
0045     /// Pointer to the g4World volume
0046     const G4VPhysicalVolume* g4World = nullptr;
0047 
0048     /// Convert the length scale
0049     ActsScalar scaleConversion = 1.;
0050 
0051     /// Convert the material
0052     bool convertMaterial = true;
0053 
0054     /// Converted material thickness (< 0 indicates keeping original thickness)
0055     ActsScalar convertedMaterialThickness = -1;
0056 
0057     /// Transformation to apply to the
0058     /// G4World volume
0059     G4Transform3D worldTransform = G4Transform3D();
0060 
0061     /// A selector for passive surfaces
0062     std::shared_ptr<IGeant4PhysicalVolumeSelector> surfacePreselector =
0063         std::make_shared<Acts::Geant4PhysicalVolumeSelectors::AllSelector>();
0064   };
0065 
0066   /// Optional configuration for the KDTree
0067   struct kdtOptions {
0068     /// A set of ranges to separate the surfaces
0069     Acts::RangeXD<kDim, Acts::ActsScalar> range;
0070 
0071     /// A set of binning values to perform the separation
0072     std::array<Acts::BinningValue, kDim> binningValues;
0073 
0074     /// The maximum number of surfaces per leaf
0075     std::size_t leafSize = bSize;
0076 
0077     /// The reference generator for the KDTree
0078     reference_generator rgen;
0079 
0080     /// Initialize range to be degenerate by default
0081     kdtOptions() {
0082       for (std::size_t i = 0; i < kDim; ++i) {
0083         range[i].set(1, -1);
0084       }
0085     }
0086   };
0087 
0088   /// Constructor
0089   /// @param config The configuration struct
0090   /// @param options The optional configuration for KDTree
0091   Geant4SurfaceProvider(const Config& config,
0092                         const kdtOptions& options = kdtOptions()) {
0093     if (config.g4World == nullptr) {
0094       throw std::invalid_argument(
0095           "Geant4SurfaceProvider: No World volume provided");
0096     }
0097     if (config.surfacePreselector == nullptr) {
0098       throw std::invalid_argument(
0099           "Geant4SurfaceProvider: no preselection criteria provided");
0100     }
0101 
0102     m_cfg = config;
0103     m_kdtOptions = options;
0104     m_g4World = m_cfg.g4World;
0105     m_g4ToWorld = m_cfg.worldTransform;
0106   };
0107 
0108   /// Destructor
0109   ~Geant4SurfaceProvider() override = default;
0110 
0111   std::vector<std::shared_ptr<Acts::Surface>> surfaces(
0112       [[maybe_unused]] const Acts::GeometryContext& gctx) const override {
0113     /// Surface factory options
0114     Acts::Geant4DetectorSurfaceFactory::Options g4SurfaceOptions;
0115 
0116     /// Copy the configuration
0117     /// This is done to avoid checking nullptrs
0118     /// in the factory
0119     g4SurfaceOptions.scaleConversion = m_cfg.scaleConversion;
0120     g4SurfaceOptions.convertMaterial = m_cfg.convertMaterial;
0121     g4SurfaceOptions.convertedMaterialThickness =
0122         m_cfg.convertedMaterialThickness;
0123     g4SurfaceOptions.passiveSurfaceSelector = m_cfg.surfacePreselector;
0124 
0125     /// Generate the surface cache
0126     Acts::Geant4DetectorSurfaceFactory::Cache g4SurfaceCache;
0127 
0128     /// Find and store surfaces in the cache object
0129     auto g4ToWorldConsistent = G4Transform3D(
0130         m_g4ToWorld.getRotation().inverse(), m_g4ToWorld.getTranslation());
0131     Acts::Geant4DetectorSurfaceFactory{}.construct(
0132         g4SurfaceCache, g4ToWorldConsistent, *m_g4World, g4SurfaceOptions);
0133 
0134     auto surfaces = g4SurfaceCache.passiveSurfaces;
0135 
0136     /// If range is degenerate, return all surfaces
0137     if (m_kdtOptions.range.degenerate()) {
0138       return surfaces;
0139     }
0140 
0141     /// Otherwise, select the surfaces based on the range
0142     auto kdtSurfaces =
0143         Acts::Experimental::KdtSurfaces<kDim, bSize, reference_generator>(
0144             gctx, surfaces, m_kdtOptions.binningValues);
0145 
0146     return kdtSurfaces.surfaces(m_kdtOptions.range);
0147   };
0148 
0149  private:
0150   Config m_cfg;
0151 
0152   kdtOptions m_kdtOptions;
0153 
0154   const G4VPhysicalVolume* m_g4World;
0155 
0156   G4Transform3D m_g4ToWorld;
0157 };
0158 
0159 }  // namespace Acts::Experimental