Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4TransportationManager.cc
Go to the documentation of this file.
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 //
27 // $Id$
28 //
29 //
30 // G4TransportationManager
31 //
32 // Created : J.Apostolakis, 1997
33 // Reviewed: G.Cosmo, 2006
34 // 10.04.07 V.Ivanchenko Use unique G4SafetyHelper
35 //
36 // --------------------------------------------------------------------
37 
39 
40 #include <algorithm>
41 
42 #include "G4GeometryMessenger.hh"
43 #include "G4PropagatorInField.hh"
44 #include "G4FieldManager.hh"
45 #include "G4LogicalVolume.hh"
46 #include "G4PVPlacement.hh"
47 
48 // Initialise the static instance of the singleton
49 //
50 G4TransportationManager* G4TransportationManager::fTransportationManager=0;
51 
52 // ----------------------------------------------------------------------------
53 // Constructor
54 //
56 {
57  if (fTransportationManager)
58  {
59  G4Exception("G4TransportationManager::G4TransportationManager()",
60  "GeomNav0002", FatalException,
61  "Only ONE instance of G4TransportationManager is allowed!");
62  }
63 
64  // Create the navigator for tracking and activate it; add to collections
65  //
66  G4Navigator* trackingNavigator = new G4Navigator();
67  trackingNavigator->Activate(true);
68  fNavigators.push_back(trackingNavigator);
69  fActiveNavigators.push_back(trackingNavigator);
70  fWorlds.push_back(trackingNavigator->GetWorldVolume()); // NULL registered
71 
72  fGeomMessenger = new G4GeometryMessenger(this);
73  fFieldManager = new G4FieldManager();
74  fPropagatorInField= new G4PropagatorInField(trackingNavigator,fFieldManager);
75  fSafetyHelper = new G4SafetyHelper();
76 }
77 
78 // ----------------------------------------------------------------------------
79 // Destructor
80 //
82 {
83  delete fFieldManager;
84  delete fPropagatorInField;
85  ClearNavigators();
86  delete fGeomMessenger;
87  delete fSafetyHelper;
88 }
89 
90 // ----------------------------------------------------------------------------
91 // GetTransportationManager()
92 //
93 // Retrieve the static instance of the singleton
94 //
96 {
97  static G4TransportationManager theInstance;
98  if (!fTransportationManager)
99  fTransportationManager = &theInstance;
100 
101  return fTransportationManager;
102 }
103 
104 // ----------------------------------------------------------------------------
105 // SetFieldManager()
106 //
107 // Set the associated field manager.
108 //
110 {
111  fFieldManager = newFieldManager;
112 
113  // Message the PropagatorInField,
114  // which also maintains this information (to be reviewed)
115  //
116  if( fPropagatorInField )
117  {
118  fPropagatorInField -> SetDetectorFieldManager( newFieldManager );
119  }
120 }
121 
122 // ----------------------------------------------------------------------------
123 // ClearNavigators()
124 //
125 // Clear collection of navigators and delete allocated objects.
126 // Called only by the class destructor.
127 //
128 void G4TransportationManager::ClearNavigators()
129 {
130  std::vector<G4Navigator*>::iterator pNav;
131  for (pNav=fNavigators.begin(); pNav!=fNavigators.end(); pNav++)
132  {
133  delete *pNav;
134  }
135  fNavigators.clear();
136  fActiveNavigators.clear();
137  fWorlds.clear();
138 }
139 
140 // ----------------------------------------------------------------------------
141 // GetParallelWorld()
142 //
143 // Provided the name of a world volume, returns the associated world pointer.
144 // If not existing, create (allocate) and register it in the collection.
145 //
148 {
149  G4VPhysicalVolume* wPV = IsWorldExisting(worldName);
150  if (!wPV)
151  {
153  G4LogicalVolume* wLV = wPV->GetLogicalVolume();
154  wLV = new G4LogicalVolume(wLV->GetSolid(), 0,
155  worldName);
156  wPV = new G4PVPlacement (wPV->GetRotation(),
157  wPV->GetTranslation(),
158  wLV, worldName, 0, false, 0);
159  RegisterWorld(wPV);
160  }
161  return wPV;
162 }
163 
164 // ----------------------------------------------------------------------------
165 // GetNavigator()
166 //
167 // Provided the name of a world volume, returns the associated navigator.
168 // If not existing, create it and register it in the collection, throw an
169 // exception if the associated parallel world does not exist.
170 //
172 {
173  // If already existing, return the stored pointer to the navigator
174  //
175  std::vector<G4Navigator*>::iterator pNav;
176  for (pNav=fNavigators.begin(); pNav!=fNavigators.end(); pNav++)
177  {
178  if ((*pNav)->GetWorldVolume()->GetName() == worldName) { return *pNav; }
179  }
180 
181  // Check if world of that name already exists,
182  // create a navigator and register it
183  //
184  G4Navigator* aNavigator = 0;
185  G4VPhysicalVolume* aWorld = IsWorldExisting(worldName);
186  if(aWorld)
187  {
188  aNavigator = new G4Navigator();
189  aNavigator->SetWorldVolume(aWorld);
190  fNavigators.push_back(aNavigator);
191  }
192  else
193  {
194  G4String message
195  = "World volume with name -" + worldName
196  + "- does not exist. Create it first by GetParallelWorld() method!";
197  G4Exception("G4TransportationManager::GetNavigator(name)",
198  "GeomNav0002", FatalException, message);
199  }
200 
201  return aNavigator;
202 }
203 
204 // ----------------------------------------------------------------------------
205 // GetNavigator()
206 //
207 // Provided a pointer to a world volume, returns the associated navigator.
208 // Create it in case not existing and add it to the collection.
209 // If world volume not existing, issue an exception.
210 //
212 {
213  std::vector<G4Navigator*>::iterator pNav;
214  for (pNav=fNavigators.begin(); pNav!=fNavigators.end(); pNav++)
215  {
216  if ((*pNav)->GetWorldVolume() == aWorld) { return *pNav; }
217  }
218  G4Navigator* aNavigator = 0;
219  std::vector<G4VPhysicalVolume*>::iterator pWorld =
220  std::find(fWorlds.begin(), fWorlds.end(), aWorld);
221  if (pWorld != fWorlds.end())
222  {
223  aNavigator = new G4Navigator();
224  aNavigator->SetWorldVolume(aWorld);
225  fNavigators.push_back(aNavigator);
226  }
227  else
228  {
229  G4String message
230  = "World volume with name -" + aWorld->GetName()
231  + "- does not exist. Create it first by GetParallelWorld() method!";
232  G4Exception("G4TransportationManager::GetNavigator(pointer)",
233  "GeomNav0002", FatalException, message);
234  }
235 
236  return aNavigator;
237 }
238 
239 // ----------------------------------------------------------------------------
240 // DeRegisterNavigator()
241 //
242 // Provided a pointer to an already allocated navigator object, removes the
243 // associated entry in the navigators collection (remove pair) but does not
244 // delete the actual pointed object, which is still owned by the caller.
245 // The navigator for tracking -cannot- be deregistered.
246 //
248 {
249  if (aNavigator == fNavigators[0])
250  {
251  G4Exception("G4TransportationManager::DeRegisterNavigator()",
252  "GeomNav0003", FatalException,
253  "The navigator for tracking CANNOT be deregistered!");
254  }
255  std::vector<G4Navigator*>::iterator pNav =
256  std::find(fNavigators.begin(), fNavigators.end(), aNavigator);
257  if (pNav != fNavigators.end())
258  {
259  // Deregister associated world volume
260  //
261  DeRegisterWorld((*pNav)->GetWorldVolume());
262 
263  // Deregister the navigator
264  //
265  fNavigators.erase(pNav);
266  }
267  else
268  {
269  G4String message
270  = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
271  + "- not found in memory!";
272  G4Exception("G4TransportationManager::DeRegisterNavigator()",
273  "GeomNav1002", JustWarning, message);
274  }
275 }
276 
277 // ----------------------------------------------------------------------------
278 // ActivateNavigator()
279 //
280 // Provided a pointer to an already allocated navigator object, set to 'true'
281 // the associated activation flag for the navigator in the collection.
282 // If the provided navigator is not already registered, issue a warning
283 // Return the index of the activated navigator. This index should be used for
284 // ComputeStep() method of G4PathFinder.
285 //
287 {
288  std::vector<G4Navigator*>::iterator pNav =
289  std::find(fNavigators.begin(), fNavigators.end(), aNavigator);
290  if (pNav == fNavigators.end())
291  {
292  G4String message
293  = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
294  + "- not found in memory!";
295  G4Exception("G4TransportationManager::ActivateNavigator()",
296  "GeomNav1002", JustWarning, message);
297  return -1;
298  }
299 
300  aNavigator->Activate(true);
301  G4int id = 0;
302  std::vector<G4Navigator*>::iterator pActiveNav;
303  for(pActiveNav=fActiveNavigators.begin();
304  pActiveNav!=fActiveNavigators.end(); pActiveNav++)
305  {
306  if (*pActiveNav == aNavigator) { return id; }
307  id++;
308  }
309 
310  fActiveNavigators.push_back(aNavigator);
311  return id;
312 }
313 
314 // ----------------------------------------------------------------------------
315 // DeActivateNavigator()
316 //
317 // Provided a pointer to an already allocated navigator object, set to 'false'
318 // the associated activation flag in the navigators collection.
319 // If the provided navigator is not already registered, issue a warning.
320 //
322 {
323  std::vector<G4Navigator*>::iterator pNav =
324  std::find(fNavigators.begin(), fNavigators.end(), aNavigator);
325  if (pNav != fNavigators.end())
326  {
327  (*pNav)->Activate(false);
328  }
329  else
330  {
331  G4String message
332  = "Navigator for volume -" + aNavigator->GetWorldVolume()->GetName()
333  + "- not found in memory!";
334  G4Exception("G4TransportationManager::DeActivateNavigator()",
335  "GeomNav1002", JustWarning, message);
336  }
337 
338  std::vector<G4Navigator*>::iterator pActiveNav =
339  std::find(fActiveNavigators.begin(), fActiveNavigators.end(), aNavigator);
340  if (pActiveNav != fActiveNavigators.end())
341  {
342  fActiveNavigators.erase(pActiveNav);
343  }
344 }
345 
346 // ----------------------------------------------------------------------------
347 // InactivateAll()
348 //
349 // Inactivate all the navigators except for the tracking one, and clear the
350 // store of active navigators.
351 //
353 {
354  std::vector<G4Navigator*>::iterator pNav;
355  for (pNav=fActiveNavigators.begin(); pNav!=fActiveNavigators.end(); pNav++)
356  {
357  (*pNav)->Activate(false);
358  }
359  fActiveNavigators.clear();
360 
361  // Restore status for the navigator for tracking
362  //
363  fNavigators[0]->Activate(true);
364  fActiveNavigators.push_back(fNavigators[0]);
365 }
366 
367 // ----------------------------------------------------------------------------
368 // IsWorldExisting()
369 //
370 // Verify existance or not of an istance of the world volume with
371 // same name in the collection. Return the world pointer if existing.
372 //
375 {
376  std::vector<G4VPhysicalVolume*>::iterator pWorld = fWorlds.begin();
377  if (*pWorld==0) { *pWorld=fNavigators[0]->GetWorldVolume(); }
378 
379  for (pWorld=fWorlds.begin(); pWorld!=fWorlds.end(); pWorld++)
380  {
381  if ((*pWorld)->GetName() == name ) { return *pWorld; }
382  }
383  return 0;
384 }
385 
386 // ----------------------------------------------------------------------------
387 // RegisterWorld()
388 //
389 // Provided a pointer to an already allocated world object, check and add the
390 // associated entry in the worlds collection. Return 'true' if registration
391 // succeeds and the new entry is created.
392 //
393 G4bool G4TransportationManager::RegisterWorld( G4VPhysicalVolume* aWorld )
394 {
395  G4bool done = false;
396 
397  std::vector<G4VPhysicalVolume*>::iterator pWorld =
398  std::find(fWorlds.begin(), fWorlds.end(), aWorld);
399  if (pWorld == fWorlds.end())
400  {
401  fWorlds.push_back(aWorld);
402  done = true;
403  }
404  return done;
405 }
406 
407 // ----------------------------------------------------------------------------
408 // DeRegisterWorld()
409 //
410 // Provided a pointer to an already allocated world object, removes the
411 // associated entry in the worlds collection but does not delete the actual
412 // pointed object, which is still owned by the caller.
413 //
414 void G4TransportationManager::DeRegisterWorld( G4VPhysicalVolume* aWorld )
415 {
416  std::vector<G4VPhysicalVolume*>::iterator pWorld =
417  std::find(fWorlds.begin(), fWorlds.end(), aWorld);
418  if (pWorld != fWorlds.end())
419  {
420  fWorlds.erase(pWorld);
421  }
422  else
423  {
424  G4String message
425  = "World volume -" + aWorld->GetName() + "- not found in memory!";
426  G4Exception("G4TransportationManager::DeRegisterWorld()",
427  "GeomNav1002", JustWarning, message);
428  }
429 }