Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:53:39

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