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