Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SensitiveSurfaceMapper.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SensitiveSurfaceMapper.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
14 #include "Acts/Geometry/Layer.hpp"
18 
19 #include <algorithm>
20 #include <ostream>
21 #include <stdexcept>
22 #include <utility>
23 
24 #include <G4LogicalVolume.hh>
25 #include <G4Material.hh>
26 #include <G4VPhysicalVolume.hh>
27 
29  const Config& cfg, std::unique_ptr<const Acts::Logger> logger)
30  : m_cfg(cfg), m_logger(std::move(logger)) {
31  if (m_cfg.trackingGeometry == nullptr) {
32  throw std::invalid_argument("No Acts::TrackingGeometry provided.");
33  }
34 }
35 
37  G4VPhysicalVolume* g4PhysicalVolume,
38  const Acts::Transform3& motherTransform, int& sCounter) const {
39  constexpr double convertLength = CLHEP::mm / Acts::UnitConstants::mm;
40 
41  auto g4LogicalVolume = g4PhysicalVolume->GetLogicalVolume();
42  auto g4SensitiveDetector = g4LogicalVolume->GetSensitiveDetector();
43 
44  // Get the transform of the G4 object
45  auto g4Translation = g4PhysicalVolume->GetTranslation();
46  auto g4Rotation = g4PhysicalVolume->GetRotation();
47  Acts::Vector3 g4RelPosition(g4Translation[0] * convertLength,
48  g4Translation[1] * convertLength,
49  g4Translation[2] * convertLength);
50  Acts::Translation3 translation(g4RelPosition);
52  if (g4Rotation == nullptr) {
53  transform = motherTransform * translation;
54  } else {
55  Acts::RotationMatrix3 rotation;
56  rotation << g4Rotation->xx(), g4Rotation->yx(), g4Rotation->zx(),
57  g4Rotation->xy(), g4Rotation->yy(), g4Rotation->zy(), g4Rotation->xz(),
58  g4Rotation->yz(), g4Rotation->zz();
59  transform = motherTransform * (translation * rotation);
60  }
61  Acts::Vector3 g4AbsPosition = transform * Acts::Vector3::Zero();
62 
63  if (G4int nDaughters = g4LogicalVolume->GetNoDaughters(); nDaughters > 0) {
64  // Step down to all daughters
65  for (G4int id = 0; id < nDaughters; ++id) {
66  remapSensitiveNames(g4LogicalVolume->GetDaughter(id), transform,
67  sCounter);
68  }
69  return;
70  }
71 
72  std::string volumeName = g4LogicalVolume->GetName();
73  std::string volumeMaterialName = g4LogicalVolume->GetMaterial()->GetName();
74  if (g4SensitiveDetector == nullptr or
75  std::find(m_cfg.materialMappings.begin(), m_cfg.materialMappings.end(),
76  volumeMaterialName) != m_cfg.materialMappings.end() or
77  std::find(m_cfg.volumeMappings.begin(), m_cfg.volumeMappings.end(),
78  volumeName) != m_cfg.volumeMappings.end()) {
79  // Find the associated ACTS object
80  auto actsLayer = m_cfg.trackingGeometry->associatedLayer(
81  Acts::GeometryContext(), g4AbsPosition);
82 
83  // Prepare the mapped surface
84  const Acts::Surface* mappedSurface = nullptr;
85 
86  if (actsLayer != nullptr and actsLayer->surfaceArray() != nullptr) {
87  auto actsSurfaces = actsLayer->surfaceArray()->at(g4AbsPosition);
88  if (not actsSurfaces.empty()) {
89  // Fast matching: search
90  for (const auto& as : actsSurfaces) {
91  if (as->center(Acts::GeometryContext()).isApprox(g4AbsPosition)) {
92  mappedSurface = as;
93  break;
94  }
95  }
96  }
97  if (mappedSurface == nullptr) {
98  // Slow matching: Fallback, loop over all layer surfaces
99  for (const auto& as : actsLayer->surfaceArray()->surfaces()) {
100  if (as->center(Acts::GeometryContext()).isApprox(g4AbsPosition)) {
101  mappedSurface = as;
102  break;
103  }
104  }
105  }
106  }
107  // A mapped surface was found, a new name will be set that
108  // contains the GeometryID/
109  if (mappedSurface != nullptr) {
110  ++sCounter;
112  mappedVolumeName += std::to_string(mappedSurface->geometryId().value());
113  ACTS_VERBOSE("Found matching surface " << mappedSurface->geometryId()
114  << " at position "
115  << g4RelPosition.transpose());
116  ACTS_VERBOSE("Remap: " << g4PhysicalVolume->GetName() << " -> "
117  << mappedVolumeName);
118  g4PhysicalVolume->SetName(mappedVolumeName.c_str());
119  } else {
120  ACTS_VERBOSE("No mapping found for '"
121  << volumeName << "' with material '" << volumeMaterialName
122  << "' at position " << g4RelPosition.transpose());
123  }
124  } else {
125  ACTS_VERBOSE("Did not try mapping '"
126  << g4PhysicalVolume->GetName() << "' at "
127  << g4RelPosition.transpose()
128  << " because g4SensitiveDetector (=" << g4SensitiveDetector
129  << ") is null and volume name (=" << volumeName
130  << ") and material name (=" << volumeMaterialName
131  << ") were not found");
132  }
133 }