11 #include <geometry/modules/overlapchecker/OverlapCheckerModule.h>
12 #include <geometry/GeometryManager.h>
13 #include <framework/gearbox/Unit.h>
15 #include "G4VPhysicalVolume.hh"
16 #include "G4LogicalVolume.hh"
17 #include "G4UnitsTable.hh"
18 #include "G4VExceptionHandler.hh"
19 #include "G4StateManager.hh"
20 #include "G4AffineTransform.hh"
21 #include "G4VSolid.hh"
32 class OverlapHandler:
public G4VExceptionHandler {
35 explicit OverlapHandler(std::function<
void(
const std::string&)> callback): m_callback(std::move(callback)) {}
37 bool Notify(
const char*,
const char*, G4ExceptionSeverity,
const char* description)
override
39 m_callback(description);
44 std::function<void(
const std::string&)> m_callback;
55 Number of test points we will generate on randomly on the surface of each geometry volume and then check for all of them that
57 1. The points are inside the mother volume
58 2. The points are not inside any neighbor volume
60 The higher the number the more precise the check for overlaps becomes, and the slower it gets.
61 See also https://questions.belle2.org/question/7264/ )DOC",
79 G4UnitDefinition::BuildUnitsTable();
82 B2ERROR(
"No geometry found. => Add the Geometry module to the path before the OverlapChecker module.");
89 G4VExceptionHandler* old = G4StateManager::GetStateManager()->GetExceptionHandler();
91 OverlapHandler handler([&](
const std::string & message) {
handleOverlap(message); });
92 G4StateManager::GetStateManager()->SetExceptionHandler(&handler);
96 G4StateManager::GetStateManager()->SetExceptionHandler(old);
100 B2ERROR(
"Overlaps detected for " << m_overlap);
107 G4VPhysicalVolume* volume =
m_nav.GetTopVolume();
109 B2ERROR(geant4Message);
110 std::regex r(R
"((mother)?\s*local point \(([-+0-9eE.]+),([-+0-9eE.]+),([-+0-9eE.]+)\))");
112 if (std::regex_search(geant4Message, m, r)) {
113 G4ThreeVector posLocal(std::atof(m[2].str().c_str()), std::atof(m[3].str().c_str()), std::atof(m[4].str().c_str()));
114 if (m[1].length() == 0) {
121 G4AffineTransform trans_volume(volume->GetRotation(), volume->GetTranslation());
122 trans_volume.Invert();
124 G4VSolid* solid = volume->GetLogicalVolume()->GetSolid();
126 std::regex nameRegex(
"with (.*) volume's");
127 std::smatch nameMatch;
129 if (std::regex_search(geant4Message, nameMatch, nameRegex)) {
130 const std::string& name = nameMatch[1].str();
132 for (
int i = 0; i < volume->GetMotherLogical()->GetNoDaughters(); ++i) {
133 G4VPhysicalVolume* sister = volume->GetMotherLogical()->GetDaughter(i);
135 if (name != sister->GetName())
continue;
137 G4AffineTransform trans_sister(sister->GetRotation(), sister->GetTranslation());
138 G4ThreeVector posMother = trans_sister.TransformPoint(posLocal);
139 G4ThreeVector posSister = trans_volume.TransformPoint(posMother);
141 if (solid->Inside(posSister) != kOutside) {
143 B2INFO(
"Found intersecting volume " << sister->GetName() <<
"." << sister->GetCopyNo());
145 G4AffineTransform t =
m_nav.GetTopTransform().Inverse();
146 G4ThreeVector global = t.TransformPoint(posMother);
151 B2ERROR(
"Could not find name of intersecting volume");
155 G4AffineTransform t =
m_nav.GetTopTransform().Inverse();
156 G4ThreeVector global = t.TransformPoint(posLocal);
160 m_nav.NewLevel(volume);
168 m_nav.NewLevel(volume);
170 std::string volumePath = path +
"/" + volume->GetName();
181 G4LogicalVolume* logicalVolume = volume->GetLogicalVolume();
182 for (
int iDaughter = 0; iDaughter < logicalVolume->GetNoDaughters(); iDaughter++) {
183 G4VPhysicalVolume* daughter = logicalVolume->GetDaughter(iDaughter);
185 auto it =
m_seen.insert(daughter);
186 if (!it.second)
continue;
187 result |=
checkVolume(daughter, volumePath, depth + 1);