ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4TransportationManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4TransportationManager.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // Class G4TransportationManager implementation
27 //
28 // Created : J.Apostolakis, 1997
29 // Reviewed: G.Cosmo, 2006
30 // --------------------------------------------------------------------
31 
33 
34 #include <algorithm>
35 
36 #include "G4GeometryMessenger.hh"
37 #include "G4PropagatorInField.hh"
38 #include "G4FieldManager.hh"
39 #include "G4LogicalVolume.hh"
40 #include "G4PVPlacement.hh"
41 
42 // Initialise the static instance of the singleton
43 //
46 
47 // The first registered navigator -- expect this to be the master thread's navigator
48 // If it has an external sub-navigator, it will be cloned for each worker thread.
50 
51 // ----------------------------------------------------------------------------
52 // Constructor
53 //
55 {
57  {
58  G4Exception("G4TransportationManager::G4TransportationManager()",
59  "GeomNav0002", FatalException,
60  "Only ONE instance of G4TransportationManager is allowed!");
61  }
62 
63  // Create the navigator for tracking and activate it; add to collections
64  //
65  G4Navigator* trackingNavigator= nullptr;
67  {
68  trackingNavigator = fFirstTrackingNavigator->Clone();
69  }
70  else
71  {
72  trackingNavigator = new G4Navigator();
73  if( fFirstTrackingNavigator == nullptr )
74  fFirstTrackingNavigator = trackingNavigator;
75  }
76  trackingNavigator->Activate(true);
77  fNavigators.push_back(trackingNavigator);
78  fActiveNavigators.push_back(trackingNavigator);
79  fWorlds.push_back(trackingNavigator->GetWorldVolume()); // NULL registered
80 
82  fFieldManager = new G4FieldManager(); // deleted by G4FieldManagerStore
85 }
86 
87 // ----------------------------------------------------------------------------
88 // Destructor
89 //
91 {
92  delete fSafetyHelper;
93  delete fPropagatorInField;
94  delete fGeomMessenger;
96  fTransportationManager = nullptr;
97 }
98 
99 // ----------------------------------------------------------------------------
100 // GetTransportationManager()
101 //
102 // Retrieve the static instance of the singleton and create it if not existing
103 //
105 {
106  if (fTransportationManager == nullptr)
107  {
109  }
110  return fTransportationManager;
111 }
112 
113 // ----------------------------------------------------------------------------
114 // GetInstanceIfExist()
115 //
116 // Retrieve the static instance pointer of the singleton
117 //
119 {
120  return fTransportationManager;
121 }
122 
123 // ----------------------------------------------------------------------------
124 // SetFieldManager()
125 //
126 // Set the associated field manager.
127 //
129 {
130  fFieldManager = newFieldManager;
131 
132  // Message the PropagatorInField,
133  // which also maintains this information (to be reviewed)
134  //
135  if( fPropagatorInField )
136  {
137  fPropagatorInField -> SetDetectorFieldManager( newFieldManager );
138  }
139 }
140 
141 // ----------------------------------------------------------------------------
142 // SetNavigatorForTracking()
143 //
144 // Set the active navigator for tracking, always
145 // the first in the collection of registered navigators.
146 //
148 {
149  fNavigators[0] = newNavigator;
150  fActiveNavigators[0] = newNavigator;
152 }
153 
154 // ----------------------------------------------------------------------------
155 // ClearNavigators()
156 //
157 // Clear collection of navigators and delete allocated objects.
158 // Called only by the class destructor.
159 //
161 {
162  for (auto pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
163  {
164  delete *pNav;
165  }
166  fNavigators.clear();
167  fActiveNavigators.clear();
168  fWorlds.clear();
169 }
170 
171 // ----------------------------------------------------------------------------
172 // GetParallelWorld()
173 //
174 // Provided the name of a world volume, returns the associated world pointer.
175 // If not existing, create (allocate) and register it in the collection.
176 //
179 {
180  G4VPhysicalVolume* wPV = IsWorldExisting(worldName);
181  if (wPV == nullptr)
182  {
184  G4LogicalVolume* wLV = wPV->GetLogicalVolume();
185  wLV = new G4LogicalVolume(wLV->GetSolid(), nullptr,
186  worldName);
187  wPV = new G4PVPlacement (wPV->GetRotation(),
188  wPV->GetTranslation(),
189  wLV, worldName, nullptr, false, 0);
190  RegisterWorld(wPV);
191  }
192  return wPV;
193 }
194 
195 // ----------------------------------------------------------------------------
196 // GetNavigator()
197 //
198 // Provided the name of a world volume, returns the associated navigator.
199 // If not existing, create it and register it in the collection, throw an
200 // exception if the associated parallel world does not exist.
201 //
203 {
204  // If already existing, return the stored pointer to the navigator
205  //
206  for (auto pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
207  {
208  if ((*pNav)->GetWorldVolume()->GetName() == worldName) { return *pNav; }
209  }
210 
211  // Check if world of that name already exists,
212  // create a navigator and register it
213  //
214  G4Navigator* aNavigator = nullptr;
215  G4VPhysicalVolume* aWorld = IsWorldExisting(worldName);
216  if(aWorld != nullptr)
217  {
218  aNavigator = new G4Navigator();
219  aNavigator->SetWorldVolume(aWorld);
220  fNavigators.push_back(aNavigator);
221  }
222  else
223  {
225  = "World volume with name -" + worldName
226  + "- does not exist. Create it first by GetParallelWorld() method!";
227  G4Exception("G4TransportationManager::GetNavigator(name)",
228  "GeomNav0002", FatalException, message);
229  }
230 
231  return aNavigator;
232 }
233 
234 // ----------------------------------------------------------------------------
235 // GetNavigator()
236 //
237 // Provided a pointer to a world volume, returns the associated navigator.
238 // Create it in case not existing and add it to the collection.
239 // If world volume not existing, issue an exception.
240 //
242 {
243  for (auto pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
244  {
245  if ((*pNav)->GetWorldVolume() == aWorld) { return *pNav; }
246  }
247  G4Navigator* aNavigator = nullptr;
248  auto pWorld = std::find(fWorlds.cbegin(), fWorlds.cend(), aWorld);
249  if (pWorld != fWorlds.cend())
250  {
251  aNavigator = new G4Navigator();
252  aNavigator->SetWorldVolume(aWorld);
253  fNavigators.push_back(aNavigator);
254  }
255  else
256  {
258  = "World volume with name -" + aWorld->GetName()
259  + "- does not exist. Create it first by GetParallelWorld() method!";
260  G4Exception("G4TransportationManager::GetNavigator(pointer)",
261  "GeomNav0002", FatalException, message);
262  }
263 
264  return aNavigator;
265 }
266 
267 // ----------------------------------------------------------------------------
268 // DeRegisterNavigator()
269 //
270 // Provided a pointer to an already allocated navigator object, removes the
271 // associated entry in the navigators collection (remove pair) but does not
272 // delete the actual pointed object, which is still owned by the caller.
273 // The navigator for tracking -cannot- be deregistered.
274 //
276 {
277  if (aNavigator == fNavigators[0])
278  {
279  G4Exception("G4TransportationManager::DeRegisterNavigator()",
280  "GeomNav0003", FatalException,
281  "The navigator for tracking CANNOT be deregistered!");
282  }
283  auto pNav = std::find(fNavigators.cbegin(), fNavigators.cend(), aNavigator);
284  if (pNav != fNavigators.cend())
285  {
286  // Deregister associated world volume
287  //
288  DeRegisterWorld((*pNav)->GetWorldVolume());
289 
290  // Deregister the navigator
291  //
292  fNavigators.erase(pNav);
293  }
294  else
295  {
297  = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
298  + "- not found in memory!";
299  G4Exception("G4TransportationManager::DeRegisterNavigator()",
300  "GeomNav1002", JustWarning, message);
301  }
302 }
303 
304 // ----------------------------------------------------------------------------
305 // ActivateNavigator()
306 //
307 // Provided a pointer to an already allocated navigator object, set to 'true'
308 // the associated activation flag for the navigator in the collection.
309 // If the provided navigator is not already registered, issue a warning
310 // Return the index of the activated navigator. This index should be used for
311 // ComputeStep() method of G4PathFinder.
312 //
314 {
315  auto pNav = std::find(fNavigators.cbegin(), fNavigators.cend(), aNavigator);
316  if (pNav == fNavigators.cend())
317  {
319  = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
320  + "- not found in memory!";
321  G4Exception("G4TransportationManager::ActivateNavigator()",
322  "GeomNav1002", FatalException, message);
323  return -1;
324  }
325 
326  aNavigator->Activate(true);
327  G4int id = 0;
328  for(auto pActiveNav=fActiveNavigators.cbegin();
329  pActiveNav!=fActiveNavigators.cend(); ++pActiveNav)
330  {
331  if (*pActiveNav == aNavigator) { return id; }
332  ++id;
333  }
334 
335  fActiveNavigators.push_back(aNavigator);
336  return id;
337 }
338 
339 // ----------------------------------------------------------------------------
340 // DeActivateNavigator()
341 //
342 // Provided a pointer to an already allocated navigator object, set to 'false'
343 // the associated activation flag in the navigators collection.
344 // If the provided navigator is not already registered, issue a warning.
345 //
347 {
348  auto pNav = std::find(fNavigators.cbegin(), fNavigators.cend(), aNavigator);
349  if (pNav != fNavigators.cend())
350  {
351  (*pNav)->Activate(false);
352  }
353  else
354  {
356  = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
357  + "- not found in memory!";
358  G4Exception("G4TransportationManager::DeActivateNavigator()",
359  "GeomNav1002", JustWarning, message);
360  }
361 
362  auto pActiveNav = std::find(fActiveNavigators.cbegin(),
363  fActiveNavigators.cend(), aNavigator);
364  if (pActiveNav != fActiveNavigators.cend())
365  {
366  fActiveNavigators.erase(pActiveNav);
367  }
368 }
369 
370 // ----------------------------------------------------------------------------
371 // InactivateAll()
372 //
373 // Inactivate all the navigators except for the tracking one, and clear the
374 // store of active navigators.
375 //
377 {
378  for (auto pNav=fActiveNavigators.cbegin();
379  pNav!=fActiveNavigators.cend(); ++pNav)
380  {
381  (*pNav)->Activate(false);
382  }
383  fActiveNavigators.clear();
384 
385  // Restore status for the navigator for tracking
386  //
387  fNavigators[0]->Activate(true);
388  fActiveNavigators.push_back(fNavigators[0]);
389 }
390 
391 // ----------------------------------------------------------------------------
392 // IsWorldExisting()
393 //
394 // Verify existance or not of an istance of the world volume with
395 // same name in the collection. Return the world pointer if existing.
396 //
399 {
400  auto pWorld = fWorlds.begin();
401  if ( *pWorld==nullptr ) { *pWorld=fNavigators[0]->GetWorldVolume(); }
402 
403  for (auto cpWorld=fWorlds.cbegin(); cpWorld!=fWorlds.cend(); ++cpWorld)
404  {
405  if ((*cpWorld)->GetName() == name ) { return *cpWorld; }
406  }
407  return 0;
408 }
409 
410 // ----------------------------------------------------------------------------
411 // RegisterWorld()
412 //
413 // Provided a pointer to an already allocated world object, check and add the
414 // associated entry in the worlds collection. Return 'true' if registration
415 // succeeds and the new entry is created.
416 //
418 {
419  G4bool done = false;
420 
421  auto pWorld = std::find(fWorlds.cbegin(), fWorlds.cend(), aWorld);
422  if (pWorld == fWorlds.cend())
423  {
424  fWorlds.push_back(aWorld);
425  done = true;
426  }
427  return done;
428 }
429 
430 // ----------------------------------------------------------------------------
431 // DeRegisterWorld()
432 //
433 // Provided a pointer to an already allocated world object, removes the
434 // associated entry in the worlds collection but does not delete the actual
435 // pointed object, which is still owned by the caller.
436 //
438 {
439  auto pWorld = std::find(fWorlds.cbegin(), fWorlds.cend(), aWorld);
440  if (pWorld != fWorlds.cend())
441  {
442  fWorlds.erase(pWorld);
443  }
444  else
445  {
447  = "World volume -" + aWorld->GetName() + "- not found in memory!";
448  G4Exception("G4TransportationManager::DeRegisterWorld()",
449  "GeomNav1002", JustWarning, message);
450  }
451 }
452 
453 // ----------------------------------------------------------------------------
454 // ClearParallelWorlds()
455 //
456 // Clear collection of navigators and delete allocated objects associated with
457 // parallel worlds.
458 // Called only by the RunManager when the entire geometry is rebuilt from
459 // scratch.
460 //
462 {
463  auto pNav = fNavigators.cbegin();
464  G4Navigator* trackingNavigator = *pNav;
465  for (pNav=fNavigators.cbegin(); pNav!=fNavigators.cend(); ++pNav)
466  {
467  if (*pNav != trackingNavigator) { delete *pNav; }
468  }
469  fNavigators.clear();
470  fActiveNavigators.clear();
471  fWorlds.clear();
472 
473  fNavigators.push_back(trackingNavigator);
474  fActiveNavigators.push_back(trackingNavigator);
475  fWorlds.push_back(0); // NULL registered
476 }
477 
478 // ----------------------------------------------------------------------------
479 // GetFirstTrackingNavigator()
480 //
481 // Get pointer to the first tracking Navigator created
482 //
484 {
486 }
487 
488 // ----------------------------------------------------------------------------
489 // GetFirstTrackingNavigator()
490 //
491 // Get pointer to the first tracking Navigator created
492 
494 {
496 }