Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-19 09:12:20

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2022 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 "Acts/Plugins/Geant4/Geant4DetectorSurfaceFactory.hpp"
0010 
0011 #include "Acts/Plugins/Geant4/Geant4Converters.hpp"
0012 #include "Acts/Plugins/Geant4/Geant4DetectorElement.hpp"
0013 #include "Acts/Plugins/Geant4/Geant4PhysicalVolumeSelectors.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/StringHelpers.hpp"
0016 
0017 #include <utility>
0018 
0019 #include "G4LogicalVolume.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   for (std::size_t d = 0; d < nDaughters; ++d) {
0041     auto daughter = g4LogicalVolume->GetDaughter(d);
0042     construct(cache, newToGlobal, *daughter, option);
0043   }
0044 
0045   // Check if the volume is accepted by a sensitive or passive selector
0046   bool sensitive = option.sensitiveSurfaceSelector != nullptr &&
0047                    option.sensitiveSurfaceSelector->select(g4PhysVol);
0048   bool passive = option.passiveSurfaceSelector != nullptr &&
0049                  option.passiveSurfaceSelector->select(g4PhysVol);
0050 
0051   if (sensitive || passive) {
0052     // Conversion and selection code
0053     ++cache.matchedG4Volumes;
0054 
0055     // Attempt the conversion
0056     auto surface = Acts::Geant4PhysicalVolumeConverter{}.surface(
0057         g4PhysVol, Geant4AlgebraConverter{}.transform(newToGlobal),
0058         option.convertMaterial, option.convertedMaterialThickness);
0059 
0060     if (surface != nullptr) {
0061       ++cache.convertedSurfaces;
0062       // Count the material conversion
0063       if (surface->surfaceMaterial() != nullptr) {
0064         ++cache.convertedMaterials;
0065       }
0066 
0067       if (sensitive) {
0068         // empty geometry context is fine as the transform was just passed down
0069         // without context before
0070         auto detectorElement = std::make_shared<Acts::Geant4DetectorElement>(
0071             surface, g4PhysVol, surface->transform({}), 0.1);
0072         surface->assignDetectorElement(*detectorElement);
0073 
0074         cache.sensitiveSurfaces.push_back(
0075             {std::move(detectorElement), std::move(surface)});
0076       } else {
0077         cache.passiveSurfaces.push_back(std::move(surface));
0078       }
0079     }
0080   }
0081 }