source: trunk/source/geometry/navigation/src/G4TransportationManager.cc @ 1347

Last change on this file since 1347 was 1347, checked in by garnier, 13 years ago

geant4 tag 9.4

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