Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-22 07:52:56

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsPlugins/Geant4/Geant4DetectorSurfaceFactory.hpp"
0010 
0011 #include "Acts/Surfaces/Surface.hpp"
0012 #include "Acts/Utilities/StringHelpers.hpp"
0013 #include "ActsPlugins/Geant4/Geant4Converters.hpp"
0014 #include "ActsPlugins/Geant4/Geant4PhysicalVolumeSelectors.hpp"
0015 
0016 #include <utility>
0017 
0018 #include "G4LogicalVolume.hh"
0019 #include "G4Transform3D.hh"
0020 #include "G4VPhysicalVolume.hh"
0021 
0022 using namespace Acts;
0023 
0024 void ActsPlugins::Geant4DetectorSurfaceFactory::construct(
0025     Cache& cache, const G4Transform3D& g4ToGlobal,
0026     const G4VPhysicalVolume& g4PhysVol, const Options& option) {
0027   // Get Rotation and translation
0028   auto g4Translation = g4PhysVol.GetTranslation();
0029   auto g4Rotation = g4PhysVol.GetRotation();
0030 
0031   auto newTranslation =
0032       g4ToGlobal.getTranslation() + g4ToGlobal.getRotation() * g4Translation;
0033   auto newRotation = (g4Rotation == nullptr)
0034                          ? g4ToGlobal.getRotation() * CLHEP::HepRotation()
0035                          : g4ToGlobal.getRotation() * g4Rotation->inverse();
0036 
0037   G4Transform3D newToGlobal(newRotation, newTranslation);
0038 
0039   // Get the logical volume
0040   auto g4LogicalVolume = g4PhysVol.GetLogicalVolume();
0041   std::size_t nDaughters = g4LogicalVolume->GetNoDaughters();
0042   ACTS_DEBUG("Processing Geant4 physical volume " << g4PhysVol.GetName()
0043                                                   << " did yield " << nDaughters
0044                                                   << " daughters.");
0045   for (std::size_t d = 0; d < nDaughters; ++d) {
0046     auto daughter = g4LogicalVolume->GetDaughter(d);
0047     construct(cache, newToGlobal, *daughter, option);
0048   }
0049 
0050   // Check if the volume is accepted by a sensitive or passive selector
0051   bool sensitive = option.sensitiveSurfaceSelector != nullptr &&
0052                    option.sensitiveSurfaceSelector->select(g4PhysVol);
0053   bool passive = option.passiveSurfaceSelector != nullptr &&
0054                  option.passiveSurfaceSelector->select(g4PhysVol);
0055 
0056   if (sensitive || passive) {
0057     // Conversion and selection code
0058     ++cache.matchedG4Volumes;
0059     ACTS_VERBOSE("Matched Geant4 physical volume "
0060                  << g4PhysVol.GetName() << " with "
0061                  << (sensitive ? "sensitive " : "")
0062                  << (passive ? "passive " : "") << "surface selector.");
0063     // Attempt the conversion
0064     auto surface = Geant4PhysicalVolumeConverter{}.surface(
0065         g4PhysVol, Geant4AlgebraConverter{}.transform(newToGlobal),
0066         option.convertMaterial, option.convertedMaterialThickness);
0067 
0068     if (surface != nullptr) {
0069       ++cache.convertedSurfaces;
0070       // Count the material conversion
0071       if (surface->surfaceMaterial() != nullptr) {
0072         ++cache.convertedMaterials;
0073       }
0074 
0075       if (sensitive) {
0076         // empty geometry context is fine as the transform was just passed down
0077         // without context before
0078         auto detectorElement = m_config.detectorElementFactory(
0079             surface, g4PhysVol, Geant4AlgebraConverter{}.transform(newToGlobal),
0080             option.convertedMaterialThickness);
0081         cache.sensitiveSurfaces.push_back(
0082             {std::move(detectorElement), std::move(surface)});
0083       } else {
0084         cache.passiveSurfaces.push_back(std::move(surface));
0085       }
0086     }
0087   }
0088 }