Project
Loading...
Searching...
No Matches
VecGeomNavigation.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 <fairlogger/Logger.h>
15#include <sstream>
16#include <string>
17
18#ifdef O2_WITH_VECGEOM
19
20// The O2 headers come first on purpose: VecGeom's build interface defines a VECGEOM macro,
21// which would otherwise eat the VECGEOM enumerator of MatbudGeomBackend.
24#include "SimConfig/G4Params.h"
25
26#include "VecGeomChecks.h"
27#include "VecGeomG4Map.h"
28#include "VecGeomG4Navigator.h"
30
31#include "TG4RootDetectorConstruction.h"
32#include "TG4RootNavMgr.h"
33
34#include "G4EventManager.hh"
35#include "G4FieldManager.hh"
36#include "G4PropagatorInField.hh"
37#include "G4SteppingManager.hh"
38#include "G4TrackingManager.hh"
39#include "G4TransportationManager.hh"
40
41#include "TMCManager.h"
42#include "TStopwatch.h"
43
44#endif
45
46namespace o2::simsetup
47{
48
49#ifdef O2_WITH_VECGEOM
50
51bool isVecGeomNavigationAvailable() { return true; }
52
54{
55 auto const& g4Params = o2::conf::G4Params::Instance();
56
57 if (TMCManager::Instance() != nullptr) {
58 LOG(fatal) << "G4.navmode=kVecGeom cannot be used with the multi-engine TMCManager: restoring a "
59 "geometry state across engines goes through the TGeo navigator";
60 }
61 if (o2::GeometryManagerParam::Instance().useParallelWorld) {
62 LOG(fatal) << "G4.navmode=kVecGeom cannot be used with GeometryManagerParam.useParallelWorld: VecGeom "
63 "has no equivalent of the TGeo priority world";
64 }
65 auto* navMgr = TG4RootNavMgr::GetInstance();
66 if (navMgr == nullptr || navMgr->GetDetConstruction() == nullptr) {
67 LOG(fatal) << "G4.navmode=kVecGeom needs the Geant4 geometry built from TGeo by g4root, which is what "
68 "the geomRoot option provides; no TG4RootNavMgr was found";
69 }
70 auto* detConstruction = navMgr->GetDetConstruction();
71 if (!detConstruction->IsConstructed()) {
72 LOG(fatal) << "The Geant4 geometry has not been built yet; installVecGeomNavigator must be called after "
73 "the TGeant4 engine has been created";
74 }
75
76 if (!g4Params.vecgeomFlattenAssemblies && g4Params.vecgeomNavigator == o2::conf::EVecGeomNav::kRelocating) {
77 LOG(fatal) << "G4.vecgeomNavigator=kRelocating needs G4.vecgeomFlattenAssemblies=true: it enters a daughter by "
78 "locating inside it, which an assembly cannot answer";
79 }
80
81 TStopwatch timer;
82 timer.Start();
83 o2::base::GeometryManager::buildVecGeomGeometry(g4Params.vecgeomFlattenAssemblies);
84 timer.Stop();
85 LOG(info) << "VecGeom geometry built in " << timer.RealTime() << " s";
86
87 timer.Start();
88 // Owned here for the lifetime of the process; the navigator keeps a reference to it.
89 static VecGeomG4Map map;
90 map.build(*detConstruction, g4Params.vecgeomFlattenAssemblies);
91 timer.Stop();
92 LOG(info) << "VecGeom to Geant4 map built in " << timer.RealTime() << " s";
93
94 if (!g4Params.vecgeomCheckVolumes.empty()) {
95 std::stringstream names(g4Params.vecgeomCheckVolumes);
96 std::string one;
97 while (std::getline(names, one, ',')) {
98 checkVecGeomVolume(one.c_str(), 20, 200);
99 }
100 }
101 if (g4Params.vecgeomCheckRays > 0) {
102 checkVecGeomRays(static_cast<std::size_t>(g4Params.vecgeomCheckRays));
103 }
104 if (g4Params.vecgeomCheckLocation > 0) {
105 checkVecGeomLocation(static_cast<std::size_t>(g4Params.vecgeomCheckLocation));
106 }
107
108 G4Navigator* navigator = nullptr;
109 if (g4Params.vecgeomNavigator == o2::conf::EVecGeomNav::kPropagated) {
110 LOG(info) << "VecGeom navigation: propagating navigator";
111 navigator = new VecGeomG4PropagatingNavigator(map, g4Params.vecgeomZeroSafety);
112 } else {
113 navigator = new VecGeomG4Navigator(map, g4Params.vecgeomPushDepth, g4Params.vecgeomZeroSafety);
114 }
115 navigator->SetWorldVolume(detConstruction->GetTopPV());
116
117 // Same sequence TG4RootNavMgr::SetNavigator uses, run here because by the time the engine
118 // exists the navigator manager considers itself connected and refuses to swap.
119 auto* trMgr = G4TransportationManager::GetTransportationManager();
120 trMgr->SetNavigatorForTracking(navigator);
121 auto* fieldMgr = trMgr->GetPropagatorInField()->GetCurrentFieldManager();
122 delete trMgr->GetPropagatorInField();
123 trMgr->SetPropagatorInField(new G4PropagatorInField(navigator, fieldMgr));
124 trMgr->ActivateNavigator(navigator);
125 if (auto* evtMgr = G4EventManager::GetEventManager()) {
126 evtMgr->GetTrackingManager()->GetSteppingManager()->SetNavigator(navigator);
127 }
128
129 LOG(info) << "VecGeom navigator registered with the Geant4 transportation manager";
130}
131
132#else
133
134bool isVecGeomNavigationAvailable() { return false; }
135
137{
138 LOG(fatal) << "G4.navmode=kVecGeom needs O2 built against TGeo2VecGeom and a VecGeom with the BVH navigator of "
139 "the VNavigator family (BVHNavigatorV), which were not found at configure time";
140}
141
142#endif
143
144} // namespace o2::simsetup
Definition of the GeometryManager class.
uint32_t one
Definition RawData.h:4
void checkVecGeomRays(std::size_t rays)
bool isVecGeomNavigationAvailable()
std::size_t checkVecGeomLocation(std::size_t samples)
std::size_t checkVecGeomVolume(const char *name, std::size_t perPlacement, std::size_t maxPlacements)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"