Project
Loading...
Searching...
No Matches
VecGeomG4NavigatorBase.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
14#include "G4VPhysicalVolume.hh"
15
16#include <VecGeom/management/BVHManager.h>
17#include <VecGeom/navigation/BVHNavigator.h>
18#include <VecGeom/navigation/BVHSafetyEstimator.h>
19#include <VecGeom/navigation/VSafetyEstimator.h>
20#include <VecGeom/volumes/LogicalVolume.h>
21#include <VecGeom/volumes/PlacedVolume.h>
22
23#include <fairlogger/Logger.h>
24
25#include <algorithm>
26
27namespace
28{
30constexpr std::size_t kMaxChain = 16;
32constexpr int kMaxDepth = 64;
33} // namespace
34
35namespace o2::simsetup
36{
37
38double VecGeomG4NavigatorBase::boundedSafety(vecgeom::NavigationState const& state, const G4ThreeVector& point,
39 double limit)
40{
41 auto const* pvol = state.Top();
42 auto const* lvol = pvol->GetLogicalVolume();
43 auto const* estimator = lvol->GetSafetyEstimator();
44 if (estimator == nullptr) {
45 return 0.;
46 }
47 if (limit < kInfinity && estimator == vecgeom::BVHSafetyEstimator::Instance() && lvol->GetDaughters().size() > 0) {
48 // The BVH estimator's own computation, with the search limited.
49 vecgeom::Transformation3D m;
50 state.TopMatrix(m);
51 const V3 local = m.Transform(toVG(point));
52 double safety = pvol->SafetyToOut(local);
53 if (safety > 0.) {
54 safety = vecgeom::BVHNavigator::ComputeBVHSafety<vecgeom::BVHSafetyEstimator>(
55 *vecgeom::BVHManager::GetBVH(lvol), local, safety, std::min(safety, limit * kG4ToVG));
56 }
57 return safety * kVGToG4;
58 }
59 return estimator->ComputeSafety(toVG(point), state) * kVGToG4;
60}
61
62G4VPhysicalVolume* VecGeomG4NavigatorBase::historyFromState(vecgeom::NavigationState const& state)
63{
64 // Collect the Geant4 volumes the state stands for, then keep the levels the history already has
65 // right and rebuild only from the first difference down: NewLevel composes a transform per level.
66 G4VPhysicalVolume* want[kMaxDepth];
67 int n = 0;
68 if (!state.IsOutside()) {
69 const int levels = state.GetCurrentLevel();
70 for (int l = 0; l < levels && n < kMaxDepth; ++l) {
71 auto const* placed = state.At(l);
72 if (placed == nullptr) {
73 break;
74 }
75 unsigned size = 0;
76 auto* const* chain = mMap.chain(placed->id(), size);
77 if (size == 0) {
78 LOG(fatal) << "VecGeom placement " << placed->GetLabel() << " (id " << placed->id() << ") at level " << l
79 << " has no Geant4 counterpart";
80 }
81 for (unsigned c = 0; c < size && n < kMaxDepth; ++c) {
82 want[n++] = chain[c];
83 }
84 }
85 }
86
87 if (n == 0) {
88 // Outside the world. A null first entry is how G4NavigationHistory says so.
89 fHistory.Reset();
90 fHistory.SetFirstEntry(nullptr);
91 return nullptr;
92 }
93
94 const int depth = static_cast<int>(fHistory.GetDepth());
95 int common = 0;
96 while (common <= depth && common < n && fHistory.GetVolume(common) == want[common]) {
97 ++common;
98 }
99 if (common == 0) {
100 fHistory.Reset();
101 fHistory.SetFirstEntry(want[0]);
102 common = 1;
103 } else if (depth >= common) {
104 fHistory.BackLevel(depth - common + 1);
105 }
106 for (int k = common; k < n; ++k) {
107 // The copy number is what TG4StepManager::CurrentVolID and CurrentVolOffID report, so it has to
108 // be filled exactly as the TGeo navigator fills it.
109 fHistory.NewLevel(want[k], kNormal, want[k]->GetCopyNo());
110 }
111 return fHistory.GetTopVolume();
112}
113
114bool VecGeomG4NavigatorBase::stateFromHistory(vecgeom::NavigationState& state) const
115{
116 // A run of levels that ends in a Geant4 volume several placements share is settled by comparing
117 // the run against the placements' recorded chains, which is exact.
118 state.Clear();
119 if (mMap.world() == nullptr || fHistory.GetVolume(0) == nullptr) {
120 return false;
121 }
122 state.Push(mMap.world());
123 const std::size_t depth = fHistory.GetDepth();
124 std::size_t l = mMap.chainSize(mMap.world()->id());
125 while (l <= depth) {
126 G4VPhysicalVolume* run[kMaxChain];
127 vecgeom::VPlacedVolume const* found = nullptr;
128 std::size_t n = 0;
129 for (std::size_t e = l; e <= depth && n < kMaxChain; ++e, ++n) {
130 run[n] = fHistory.GetVolume(e);
131 auto const* candidate = mMap.toVecGeom(run[n]->GetInstanceID());
132 if (candidate == nullptr) {
133 continue; // an assembly level; the chain reaches further down
134 }
135 if (candidate == VecGeomG4Map::ambiguous()) {
136 for (auto const* c : mMap.candidates(run[n]->GetInstanceID())) {
137 if (mMap.chainMatches(c, run, n + 1)) {
138 found = c;
139 break;
140 }
141 }
142 } else if (mMap.chainMatches(candidate, run, n + 1)) {
143 found = candidate;
144 }
145 if (found != nullptr) {
146 break;
147 }
148 }
149 if (found == nullptr) {
150 state.Clear();
151 return false;
152 }
153 state.Push(found);
154 l += mMap.chainSize(found->id());
155 }
156 return true;
157}
158
159} // namespace o2::simsetup
GPUChain * chain
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
SurfaceTrackState state
uint32_t c
Definition RawData.h:2
G4VPhysicalVolume *const * chain(int vgId, unsigned &size) const
static vecgeom::VPlacedVolume const * ambiguous()
Marks a Geant4 volume that several VecGeom placements reach.
std::vector< vecgeom::VPlacedVolume const * > const & candidates(int g4Id) const
The placements that share an ambiguous Geant4 volume, to be told apart by their chains.
unsigned chainSize(int vgId) const
How many Geant4 levels a VecGeom placement accounts for.
vecgeom::VPlacedVolume const * toVecGeom(int g4Id) const
bool chainMatches(vecgeom::VPlacedVolume const *pv, G4VPhysicalVolume *const *first, std::size_t n) const
Whether a placement's chain is exactly the given run of Geant4 volumes.
vecgeom::VPlacedVolume const * world() const
The outermost placement, standing for the Geant4 world volume.
G4VPhysicalVolume * historyFromState(vecgeom::NavigationState const &state)
static V3 toVG(const G4ThreeVector &p)
bool stateFromHistory(vecgeom::NavigationState &state) const
static double boundedSafety(vecgeom::NavigationState const &state, const G4ThreeVector &point, double limit)
GLdouble n
Definition glcorearb.h:1982
const GLfloat * m
Definition glcorearb.h:4066
GLsizeiptr size
Definition glcorearb.h:659
GLsizei levels
Definition glcorearb.h:2198
GLint GLint GLsizei GLsizei GLsizei depth
Definition glcorearb.h:470
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"