ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Simulation
G4Atlas
G4AtlasTools
src
G4CaloTransportTool.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
G4CaloTransportTool.h
"
6
7
#include <memory>
8
9
// Geant4 includes for for particle extrapolation
10
#include "G4FieldTrack.hh"
11
#include "G4FieldTrackUpdator.hh"
12
#include "G4LogicalVolumeStore.hh"
13
#include "G4Navigator.hh"
14
#include "G4PVPlacement.hh"
15
#include "G4PathFinder.hh"
16
#include "G4TransportationManager.hh"
17
18
thread_local
std::unique_ptr<G4PropagatorInField, G4CaloTransportTool::Deleter>
G4CaloTransportTool::s_propagator
;
19
20
void
G4CaloTransportTool::Deleter::operator()
(G4PropagatorInField* ptr)
const
{
21
delete
ptr->GetNavigatorForPropagating();
22
delete
ptr;
23
}
24
25
G4CaloTransportTool::G4CaloTransportTool
(
const
std::string&
type
,
26
const
std::string& name,
27
const
IInterface* parent)
28
: base_class(
type
, name, parent) {}
29
30
StatusCode
G4CaloTransportTool::finalize
() {
31
32
// Delete the world volume if we created it
33
if
(
m_useSimplifiedGeo
)
34
delete
m_worldVolume
;
35
36
return
StatusCode::SUCCESS;
37
}
38
39
StatusCode
G4CaloTransportTool::initializePropagator
() {
40
ATH_MSG_INFO
(
"Initializing G4PropagatorInField for thread "
41
<< G4Threading::G4GetThreadId());
42
43
if
(!
m_worldVolume
) {
44
// If not set, get either the simplified or full world volume
45
m_worldVolume
=
getWorldVolume
();
46
47
if
(!
m_worldVolume
) {
48
G4Exception(
"G4CaloTransportTool"
,
"FailedToGetWorldVolume"
,
49
FatalException,
50
"G4CaloTransportTool: Failed to get world volume."
);
51
abort();
52
}
53
ATH_MSG_INFO
(
"Using world volume: "
<<
m_worldVolume
->GetName());
54
ATH_MSG_INFO
(
"Transport will be stopped at volume: "
55
<<
m_transportLimitVolume
.value());
56
ATH_MSG_INFO
(
"Maximum allowed number of steps in particle transport: "
57
<<
m_maxSteps
.value());
58
}
59
60
// Check if we already have propagator set up for the current thread
61
// If not, we create one
62
if
(!
s_propagator
) {
63
s_propagator
= std::unique_ptr<G4PropagatorInField, Deleter>(
makePropagator
());
64
}
else
{
65
ATH_MSG_ERROR
(
66
"G4CaloTransportTool::initializePropagator() Propagator already "
67
"initialized!"
);
68
}
69
70
return
StatusCode::SUCCESS;
71
}
72
73
G4VPhysicalVolume*
G4CaloTransportTool::getWorldVolume
() {
74
75
if
(
m_useSimplifiedGeo
) {
76
77
ATH_MSG_INFO
(
"Creating simplified world volume for particle transport"
);
78
// Get the logical world volume of the simplified geometry by name
79
G4LogicalVolume* logVol = G4LogicalVolumeStore::GetInstance()->GetVolume(
80
m_simplifiedWorldLogName
.value());
81
82
// Create the physical volume of the simplified world
83
return
new
G4PVPlacement(
84
nullptr
,
// no rotation
85
G4ThreeVector(0, 0, 0),
// world centre at (0,0,0)
86
logVol,
// logical volume
87
"simplifiedWorldPhysVol"
,
// name of physical volume
88
nullptr
,
// mother volume
89
false
,
// not used
90
999,
// copy number
91
false
);
// overlap check
92
93
}
else
{
94
ATH_MSG_INFO
(
"Using full geometry for particle transport"
);
95
return
G4TransportationManager::GetTransportationManager()
96
->GetNavigatorForTracking()
97
->GetWorldVolume();
98
}
99
}
100
101
G4PropagatorInField*
G4CaloTransportTool::makePropagator
() {
102
// Create a new navigator
103
G4Navigator* navigator =
new
G4Navigator();
104
// Set world volume in which the navigator will operate
105
navigator->SetWorldVolume(
m_worldVolume
);
106
// Get the global field manager
107
G4FieldManager* fieldMgr =
108
G4TransportationManager::GetTransportationManager()->GetFieldManager();
109
// Create a new magnetic field propagator
110
G4PropagatorInField* propagator =
111
new
G4PropagatorInField(navigator, fieldMgr);
112
return
propagator;
113
}
114
115
void
G4CaloTransportTool::doStep
(G4FieldTrack& fieldTrack) {
116
117
// Get the propagator and navigator for the current thread
118
auto
navigator =
s_propagator
->GetNavigatorForPropagating();
119
120
G4double retSafety = -1.0;
121
G4double currentMinimumStep = 10.0 * CLHEP::m;
122
123
G4VPhysicalVolume* currentPhysVol =
124
navigator->LocateGlobalPointAndSetup(fieldTrack.GetPosition(),
nullptr
);
125
126
G4ThreeVector direction = fieldTrack.GetMomentumDirection();
127
// Must be called before calling the computeStep method
128
navigator->LocateGlobalPointAndSetup(fieldTrack.GetPosition(), &direction);
129
130
if
(fieldTrack.GetCharge() == 0) {
131
/* Neutral particles: transport with navigator */
132
133
// Compute the step length
134
G4double stepLength = navigator->ComputeStep(
135
fieldTrack.GetPosition(), fieldTrack.GetMomentumDirection(),
136
currentMinimumStep, retSafety);
137
138
// Update the position of the track from the computed step length
139
fieldTrack.SetPosition(fieldTrack.GetPosition() +
140
stepLength *
141
fieldTrack.GetMomentumDirection().unit());
142
143
}
else
{
144
/* Charged particles: transport with magnetic field propagator */
145
s_propagator
->ComputeStep(fieldTrack, currentMinimumStep, retSafety,
146
currentPhysVol);
147
}
148
149
return
;
150
}
151
152
std::vector<G4FieldTrack>
G4CaloTransportTool::transport
(
153
const
G4Track& G4InputTrack) {
154
155
// Get the PDG ID of the particle
156
int
pdgId = G4InputTrack.GetDefinition()->GetPDGEncoding();
157
158
// Get the navigator for the current thread
159
auto
navigator =
s_propagator
->GetNavigatorForPropagating();
160
161
// Create a vector to store the output steps
162
std::vector<G4FieldTrack> outputStepVector;
163
164
// Initialize the tmpFieldTrack with the input track
165
G4FieldTrack tmpFieldTrack(
'0'
);
166
G4FieldTrackUpdator::Update(&tmpFieldTrack, &G4InputTrack);
167
// Fill with the initial particle position
168
outputStepVector.push_back(tmpFieldTrack);
169
170
// Iterate until we reach the maximum number of steps or the requested volume
171
for
(
unsigned
int
iStep = 0; iStep <
m_maxSteps
; iStep++) {
172
// Save preStep information
173
G4ThreeVector preStepPos = tmpFieldTrack.GetPosition();
174
G4ThreeVector preStepMom = tmpFieldTrack.GetMomentum();
175
176
// Perform a single Geant4 step
177
doStep
(tmpFieldTrack);
178
179
// Fill the output vector with the updated track
180
outputStepVector.push_back(tmpFieldTrack);
181
182
// Get the name of the volume in which the particle is located
183
auto
volume = navigator->LocateGlobalPointAndSetup(
184
tmpFieldTrack.GetPosition(),
nullptr
);
185
186
if
(volume !=
nullptr
) {
187
// Get the name of the current volume
188
std::string volName = volume->GetName();
189
190
// We stop the track navigation once we have reached the provided volume
191
if
(volName.find(
m_transportLimitVolume
) != std::string::npos) {
192
break
;
193
}
194
}
else
{
195
G4ExceptionDescription
description
;
196
description
197
<<
"Transport failure for particle PID: "
<< pdgId <<
" at step "
198
<< iStep <<
"/"
<<
m_maxSteps
<< G4endl
199
<<
" - PreStep position: "
<< preStepPos << G4endl
200
<<
" - PreStep momentum: "
<< preStepMom << G4endl
201
<<
" - PostStep position: "
<< tmpFieldTrack.GetPosition() << G4endl
202
<<
" - PostStep momentum: "
<< tmpFieldTrack.GetMomentum() << G4endl
203
<<
"Possible cause: The transport is likely outside the world volume."
204
<< G4endl
205
<<
"Check if an envelope volume is defined and properly set up."
206
<< G4endl <<
"This issue should not occur during normal operation."
;
207
G4Exception(
"G4CaloTransportTool::transport"
,
208
"LocateGlobalPointAndSetup failed: Particle may be "
209
"transported outside the world volume."
,
210
JustWarning,
description
);
211
break
;
212
}
213
}
214
215
return
outputStepVector;
216
}
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition
AthMsgStreamMacros.h:33
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition
AthMsgStreamMacros.h:31
G4CaloTransportTool.h
G4CaloTransportTool::doStep
void doStep(G4FieldTrack &fieldTrack)
Definition
G4CaloTransportTool.cxx:115
G4CaloTransportTool::initializePropagator
StatusCode initializePropagator() override final
Definition
G4CaloTransportTool.cxx:39
G4CaloTransportTool::m_useSimplifiedGeo
Gaudi::Property< bool > m_useSimplifiedGeo
Definition
G4CaloTransportTool.h:54
G4CaloTransportTool::s_propagator
static std::unique_ptr< G4PropagatorInField, Deleter > s_propagator
Definition
G4CaloTransportTool.h:62
G4CaloTransportTool::m_transportLimitVolume
Gaudi::Property< std::string > m_transportLimitVolume
Definition
G4CaloTransportTool.h:58
G4CaloTransportTool::finalize
virtual StatusCode finalize() override final
Definition
G4CaloTransportTool.cxx:30
G4CaloTransportTool::m_worldVolume
G4VPhysicalVolume * m_worldVolume
Definition
G4CaloTransportTool.h:51
G4CaloTransportTool::m_simplifiedWorldLogName
Gaudi::Property< std::string > m_simplifiedWorldLogName
Definition
G4CaloTransportTool.h:56
G4CaloTransportTool::transport
virtual std::vector< G4FieldTrack > transport(const G4Track &G4InputTrack) override final
Definition
G4CaloTransportTool.cxx:152
G4CaloTransportTool::getWorldVolume
G4VPhysicalVolume * getWorldVolume()
Definition
G4CaloTransportTool.cxx:73
G4CaloTransportTool::G4CaloTransportTool
G4CaloTransportTool(const std::string &, const std::string &, const IInterface *)
Definition
G4CaloTransportTool.cxx:25
G4CaloTransportTool::m_maxSteps
Gaudi::Property< unsigned int > m_maxSteps
Definition
G4CaloTransportTool.h:60
G4CaloTransportTool::makePropagator
G4PropagatorInField * makePropagator()
Definition
G4CaloTransportTool.cxx:101
description
std::string description
glabal timer - how long have I taken so far?
Definition
hcg.cxx:93
G4CaloTransportTool::Deleter::operator()
void operator()(G4PropagatorInField *) const
Definition
G4CaloTransportTool.cxx:20
type
Generated on
for ATLAS Offline Software by
1.17.0