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/volumes/PlacedVolume.h>
17
18#include <fairlogger/Logger.h>
19
20namespace
21{
23constexpr std::size_t kMaxChain = 16;
25constexpr int kMaxDepth = 64;
26} // namespace
27
28namespace o2::simsetup
29{
30
31G4VPhysicalVolume* VecGeomG4NavigatorBase::historyFromState(vecgeom::NavigationState const& state)
32{
33 // Collect the Geant4 volumes the state stands for, then keep the levels the history already has
34 // right and rebuild only from the first difference down: NewLevel composes a transform per level.
35 G4VPhysicalVolume* want[kMaxDepth];
36 int n = 0;
37 if (!state.IsOutside()) {
38 const int levels = state.GetCurrentLevel();
39 for (int l = 0; l < levels && n < kMaxDepth; ++l) {
40 auto const* placed = state.At(l);
41 if (placed == nullptr) {
42 break;
43 }
44 unsigned size = 0;
45 auto* const* chain = mMap.chain(placed->id(), size);
46 if (size == 0) {
47 LOG(fatal) << "VecGeom placement " << placed->GetLabel() << " (id " << placed->id() << ") at level " << l
48 << " has no Geant4 counterpart";
49 }
50 for (unsigned c = 0; c < size && n < kMaxDepth; ++c) {
51 want[n++] = chain[c];
52 }
53 }
54 }
55
56 if (n == 0) {
57 // Outside the world. A null first entry is how G4NavigationHistory says so.
58 fHistory.Reset();
59 fHistory.SetFirstEntry(nullptr);
60 return nullptr;
61 }
62
63 const int depth = static_cast<int>(fHistory.GetDepth());
64 int common = 0;
65 while (common <= depth && common < n && fHistory.GetVolume(common) == want[common]) {
66 ++common;
67 }
68 if (common == 0) {
69 fHistory.Reset();
70 fHistory.SetFirstEntry(want[0]);
71 common = 1;
72 } else if (depth >= common) {
73 fHistory.BackLevel(depth - common + 1);
74 }
75 for (int k = common; k < n; ++k) {
76 // The copy number is what TG4StepManager::CurrentVolID and CurrentVolOffID report, so it has to
77 // be filled exactly as the TGeo navigator fills it.
78 fHistory.NewLevel(want[k], kNormal, want[k]->GetCopyNo());
79 }
80 return fHistory.GetTopVolume();
81}
82
83bool VecGeomG4NavigatorBase::stateFromHistory(vecgeom::NavigationState& state) const
84{
85 // A run of levels that ends in a Geant4 volume several placements share is settled by comparing
86 // the run against the placements' recorded chains, which is exact.
87 state.Clear();
88 if (mMap.world() == nullptr || fHistory.GetVolume(0) == nullptr) {
89 return false;
90 }
91 state.Push(mMap.world());
92 const std::size_t depth = fHistory.GetDepth();
93 std::size_t l = mMap.chainSize(mMap.world()->id());
94 while (l <= depth) {
95 G4VPhysicalVolume* run[kMaxChain];
96 vecgeom::VPlacedVolume const* found = nullptr;
97 std::size_t n = 0;
98 for (std::size_t e = l; e <= depth && n < kMaxChain; ++e, ++n) {
99 run[n] = fHistory.GetVolume(e);
100 auto const* candidate = mMap.toVecGeom(run[n]->GetInstanceID());
101 if (candidate == nullptr) {
102 continue; // an assembly level; the chain reaches further down
103 }
104 if (candidate == VecGeomG4Map::ambiguous()) {
105 for (auto const* c : mMap.candidates(run[n]->GetInstanceID())) {
106 if (mMap.chainMatches(c, run, n + 1)) {
107 found = c;
108 break;
109 }
110 }
111 } else if (mMap.chainMatches(candidate, run, n + 1)) {
112 found = candidate;
113 }
114 if (found != nullptr) {
115 break;
116 }
117 }
118 if (found == nullptr) {
119 state.Clear();
120 return false;
121 }
122 state.Push(found);
123 l += mMap.chainSize(found->id());
124 }
125 return true;
126}
127
128} // namespace o2::simsetup
GPUChain * chain
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)
bool stateFromHistory(vecgeom::NavigationState &state) const
GLdouble n
Definition glcorearb.h:1982
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"