source: trunk/source/run/src/G4RunManager.cc @ 1315

Last change on this file since 1315 was 1315, checked in by garnier, 14 years ago

update geant4-09-04-beta-cand-01 interfaces-V09-03-09 vis-V09-03-08

File size: 16.6 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: G4RunManager.cc,v 1.110 2010/06/11 09:02:55 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-04-beta-cand-01 $
29//
30//
31
32// On Sun, to prevent conflict with ObjectSpace, G4Timer.hh has to be
33// loaded *before* globals.hh...
34#include "G4Timer.hh"
35
36#include "G4RunManager.hh"
37#include "G4RunManagerKernel.hh"
38
39#include "G4StateManager.hh"
40#include "G4ApplicationState.hh"
41#include "Randomize.hh"
42#include "G4Run.hh"
43#include "G4RunMessenger.hh"
44#include "G4VUserPhysicsList.hh"
45#include "G4VUserDetectorConstruction.hh"
46#include "G4UserRunAction.hh"
47#include "G4VUserPrimaryGeneratorAction.hh"
48#include "G4VPersistencyManager.hh"
49#include "G4ParticleTable.hh"
50#include "G4ProcessTable.hh"
51#include "G4UnitsTable.hh"
52#include "G4VVisManager.hh"
53#include "G4Material.hh"
54#include "G4SDManager.hh"
55#include "G4UImanager.hh"
56#include "G4ios.hh"
57#include <sstream>
58
59using namespace CLHEP;
60
61G4RunManager* G4RunManager::fRunManager = 0;
62
63G4RunManager* G4RunManager::GetRunManager()
64{ return fRunManager; }
65
66G4RunManager::G4RunManager()
67:userDetector(0),physicsList(0),
68 userRunAction(0),userPrimaryGeneratorAction(0),userEventAction(0),
69 userStackingAction(0),userTrackingAction(0),userSteppingAction(0),
70 geometryInitialized(false),physicsInitialized(false),
71 runAborted(false),initializedAtLeastOnce(false),
72 geometryToBeOptimized(true),runIDCounter(0),verboseLevel(0),DCtable(0),
73 currentRun(0),currentEvent(0),n_perviousEventsToBeStored(0),
74 numberOfEventToBeProcessed(0),storeRandomNumberStatus(false),
75 storeRandomNumberStatusToG4Event(0),
76 currentWorld(0),nParallelWorlds(0)
77{
78  if(fRunManager)
79  { G4Exception("G4RunManager constructed twice."); }
80  fRunManager = this;
81
82  kernel = new G4RunManagerKernel();
83  eventManager = kernel->GetEventManager();
84
85  timer = new G4Timer();
86  runMessenger = new G4RunMessenger(this);
87  previousEvents = new std::vector<G4Event*>;
88  G4ParticleTable::GetParticleTable()->CreateMessenger();
89  G4ProcessTable::GetProcessTable()->CreateMessenger();
90  randomNumberStatusDir = "./";
91  std::ostringstream oss;
92  HepRandom::saveFullState(oss);
93  randomNumberStatusForThisRun = oss.str();
94  randomNumberStatusForThisEvent = oss.str();
95}
96
97G4RunManager::~G4RunManager()
98{
99  if(currentRun) delete currentRun;
100  delete timer;
101  delete runMessenger;
102  G4ParticleTable::GetParticleTable()->DeleteMessenger();
103  G4ProcessTable::GetProcessTable()->DeleteMessenger();
104  delete previousEvents;
105  if(userDetector)
106  {
107    delete userDetector;
108    if(verboseLevel>1) G4cout << "UserDetectorConstruction deleted." << G4endl;
109  }
110  if(physicsList)
111  {
112    delete physicsList;
113    if(verboseLevel>1) G4cout << "UserPhysicsList deleted." << G4endl;
114  }
115  if(userRunAction)
116  {
117    delete userRunAction;
118    if(verboseLevel>1) G4cout << "UserRunAction deleted." << G4endl;
119  }
120  if(userPrimaryGeneratorAction)
121  {
122    delete userPrimaryGeneratorAction;
123    if(verboseLevel>1) G4cout << "UserPrimaryGenerator deleted." << G4endl;
124  }
125
126  delete kernel;
127
128  if(verboseLevel>1) G4cout << "RunManager is deleting." << G4endl;
129  fRunManager = 0;
130}
131
132void G4RunManager::BeamOn(G4int n_event,const char* macroFile,G4int n_select)
133{
134  G4bool cond = ConfirmBeamOnCondition();
135  if(cond)
136  {
137    numberOfEventToBeProcessed = n_event;
138    ConstructScoringWorlds();
139    RunInitialization();
140    if(n_event>0) DoEventLoop(n_event,macroFile,n_select);
141    RunTermination();
142  }
143}
144
145G4bool G4RunManager::ConfirmBeamOnCondition()
146{
147  G4StateManager* stateManager = G4StateManager::GetStateManager();
148
149  G4ApplicationState currentState = stateManager->GetCurrentState();
150  if(currentState!=G4State_PreInit && currentState!=G4State_Idle)
151  {
152    G4cerr << "Illegal application state - BeamOn() ignored." << G4endl;
153    return false;
154  }
155
156  if(!initializedAtLeastOnce)
157  {
158    G4cerr << " Geant4 kernel should be initialized" << G4endl;
159    G4cerr << "before the first BeamOn(). - BeamOn ignored." << G4endl;
160    return false;
161  }
162
163  if(!geometryInitialized || !physicsInitialized)
164  {
165    if(verboseLevel>0)
166    {
167      G4cout << "Start re-initialization because " << G4endl;
168      if(!geometryInitialized) G4cout << "  Geometry" << G4endl;
169      if(!physicsInitialized)  G4cout << "  Physics processes" << G4endl;
170      G4cout << "has been modified since last Run." << G4endl;
171    }
172    Initialize();
173  }
174  return true;
175}
176
177void G4RunManager::RunInitialization()
178{
179  if(!(kernel->RunInitialization())) return;
180  if(currentRun) delete currentRun;
181  currentRun = 0;
182
183  if(userRunAction) currentRun = userRunAction->GenerateRun();
184  if(!currentRun) currentRun = new G4Run();
185
186  currentRun->SetRunID(runIDCounter);
187  currentRun->SetNumberOfEventToBeProcessed(numberOfEventToBeProcessed);
188
189  currentRun->SetDCtable(DCtable);
190  G4SDManager* fSDM = G4SDManager::GetSDMpointerIfExist();
191  if(fSDM)
192  { currentRun->SetHCtable(fSDM->GetHCtable()); }
193 
194  std::ostringstream oss;
195  HepRandom::saveFullState(oss);
196  randomNumberStatusForThisRun = oss.str();
197  currentRun->SetRandomNumberStatus(randomNumberStatusForThisRun);
198 
199  previousEvents->clear();
200  for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
201  { previousEvents->push_back((G4Event*)0); }
202
203  if(userRunAction) userRunAction->BeginOfRunAction(currentRun);
204
205  if(storeRandomNumberStatus) {
206    G4String fileN = randomNumberStatusDir + "currentRun.rndm"; 
207    HepRandom::saveEngineStatus(fileN);
208  }
209
210  runAborted = false;
211
212  if(verboseLevel>0) G4cout << "Start Run processing." << G4endl;
213}
214
215void G4RunManager::DoEventLoop(G4int n_event,const char* macroFile,G4int n_select)
216{
217  if(verboseLevel>0) 
218  { timer->Start(); }
219
220  G4String msg;
221  if(macroFile!=0)
222  { 
223    if(n_select<0) n_select = n_event;
224    msg = "/control/execute ";
225    msg += macroFile;
226  }
227  else
228  { n_select = -1; }
229
230// Event loop
231  G4int i_event;
232  for( i_event=0; i_event<n_event; i_event++ )
233  {
234    currentEvent = GenerateEvent(i_event);
235    eventManager->ProcessOneEvent(currentEvent);
236    AnalyzeEvent(currentEvent);
237    UpdateScoring();
238    if(i_event<n_select) G4UImanager::GetUIpointer()->ApplyCommand(msg);
239    StackPreviousEvent(currentEvent);
240    currentEvent = 0;
241    if(runAborted) break;
242  }
243
244  if(verboseLevel>0)
245  {
246    timer->Stop();
247    G4cout << "Run terminated." << G4endl;
248    G4cout << "Run Summary" << G4endl;
249    if(runAborted)
250    { G4cout << "  Run Aborted after " << i_event + 1 << " events processed." << G4endl; }
251    else
252    { G4cout << "  Number of events processed : " << n_event << G4endl; }
253    G4cout << "  "  << *timer << G4endl;
254  }
255}
256
257G4Event* G4RunManager::GenerateEvent(G4int i_event)
258{
259  if(!userPrimaryGeneratorAction)
260  {
261    G4Exception
262    ("G4RunManager::BeamOn - G4VUserPrimaryGeneratorAction is not defined.");
263  }
264
265  G4Event* anEvent = new G4Event(i_event);
266
267  if(storeRandomNumberStatusToG4Event==1 || storeRandomNumberStatusToG4Event==3)
268  {
269    std::ostringstream oss;
270    HepRandom::saveFullState(oss);
271    randomNumberStatusForThisEvent = oss.str();
272    anEvent->SetRandomNumberStatus(randomNumberStatusForThisEvent);
273  }
274
275  if(storeRandomNumberStatus) {
276    G4String fileN = randomNumberStatusDir + "currentEvent.rndm"; 
277    HepRandom::saveEngineStatus(fileN);
278  } 
279   
280  userPrimaryGeneratorAction->GeneratePrimaries(anEvent);
281  return anEvent;
282}
283
284void G4RunManager::AnalyzeEvent(G4Event* anEvent)
285{
286  G4VPersistencyManager* fPersM = G4VPersistencyManager::GetPersistencyManager();
287  if(fPersM) fPersM->Store(anEvent);
288  currentRun->RecordEvent(anEvent);
289}
290
291void G4RunManager::RunTermination()
292{
293  for(size_t itr=0;itr<previousEvents->size();itr++)
294  {
295    G4Event* prevEv =  (*previousEvents)[itr];
296    if((prevEv) && !(prevEv->ToBeKept())) delete prevEv;
297  }
298  previousEvents->clear();
299  for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
300  { previousEvents->push_back((G4Event*)0); }
301
302  if(userRunAction) userRunAction->EndOfRunAction(currentRun);
303
304  G4VPersistencyManager* fPersM = G4VPersistencyManager::GetPersistencyManager();
305  if(fPersM) fPersM->Store(currentRun);
306  runIDCounter++;
307
308  kernel->RunTermination();
309}
310
311void G4RunManager::StackPreviousEvent(G4Event* anEvent)
312{
313  if(anEvent->ToBeKept()) currentRun->StoreEvent(anEvent);
314  G4Event* evt;
315  if(n_perviousEventsToBeStored==0)
316  { evt = anEvent; }
317  else
318  {
319    previousEvents->insert(previousEvents->begin(),anEvent);
320    evt = previousEvents->back();
321    previousEvents->pop_back();
322  }
323  if(evt && !(evt->ToBeKept())) delete evt;
324}
325
326void G4RunManager::Initialize()
327{
328  G4StateManager* stateManager = G4StateManager::GetStateManager();
329  G4ApplicationState currentState = stateManager->GetCurrentState();
330  if(currentState!=G4State_PreInit && currentState!=G4State_Idle)
331  {
332    G4cerr << "Illegal application state - "
333         << "G4RunManager::Initialize() ignored." << G4endl;
334    return;
335  }
336
337  if(!geometryInitialized) InitializeGeometry();
338  if(!physicsInitialized) InitializePhysics();
339  initializedAtLeastOnce = true;
340}
341
342void G4RunManager::InitializeGeometry()
343{
344  if(!userDetector)
345  {
346    G4Exception
347    ("G4RunManager::InitializeGeometry - G4VUserDetectorConstruction is not defined.");
348  }
349
350  if(verboseLevel>1) G4cout << "userDetector->Construct() start." << G4endl;
351  kernel->DefineWorldVolume(userDetector->Construct(),false);
352  nParallelWorlds = userDetector->ConstructParallelGeometries();
353  kernel->SetNumberOfParallelWorld(nParallelWorlds);
354  geometryInitialized = true;
355}
356
357void G4RunManager::InitializePhysics()
358{
359  if(physicsList)
360  {
361    if(verboseLevel>1) G4cout << "physicsList->Construct() start." << G4endl;
362    kernel->InitializePhysics();
363  }
364  else
365  {
366    G4Exception("G4VUserPhysicsList is not defined");
367  }
368  physicsInitialized = true;
369}
370
371void G4RunManager::AbortRun(G4bool softAbort)
372{
373  // This method is valid only for GeomClosed or EventProc state
374  G4ApplicationState currentState = 
375    G4StateManager::GetStateManager()->GetCurrentState();
376  if(currentState==G4State_GeomClosed || currentState==G4State_EventProc)
377  {
378    runAborted = true;
379    if(currentState==G4State_EventProc && !softAbort)
380    {
381      currentEvent->SetEventAborted();
382      eventManager->AbortCurrentEvent();
383    }
384  }
385  else
386  {
387    G4cerr << "Run is not in progress. AbortRun() ignored." << G4endl;
388  }
389}
390
391void G4RunManager::AbortEvent()
392{
393  // This method is valid only for EventProc state
394  G4ApplicationState currentState = 
395    G4StateManager::GetStateManager()->GetCurrentState();
396  if(currentState==G4State_EventProc)
397  {
398    currentEvent->SetEventAborted();
399    eventManager->AbortCurrentEvent();
400  }
401  else
402  {
403    G4cerr << "Event is not in progress. AbortEevnt() ignored." << G4endl;
404  }
405}
406
407void G4RunManager::DefineWorldVolume(G4VPhysicalVolume* worldVol,
408                                     G4bool topologyIsChanged)
409{
410  kernel->DefineWorldVolume(worldVol,topologyIsChanged);
411}
412
413void G4RunManager::rndmSaveThisRun()
414{
415  G4int runNumber = 0;
416  if(currentRun) runNumber = currentRun->GetRunID();
417  if(!storeRandomNumberStatus) {
418     G4cerr << "Warning from G4RunManager::rndmSaveThisRun():"
419          << " Random number status was not stored prior to this run." 
420          << G4endl << "Command ignored." << G4endl;
421     return;
422  }
423 
424  G4String fileIn  = randomNumberStatusDir + "currentRun.rndm";
425 
426  std::ostringstream os;
427  os << "run" << runNumber << ".rndm" << '\0';
428  G4String fileOut = randomNumberStatusDir + os.str(); 
429
430  G4String copCmd = "/control/shell cp "+fileIn+" "+fileOut;
431  G4UImanager::GetUIpointer()->ApplyCommand(copCmd);
432  if(verboseLevel>0) G4cout << "currentRun.rndm is copied to file: " << fileOut << G4endl;   
433}
434
435void G4RunManager::rndmSaveThisEvent()
436{
437  if(!storeRandomNumberStatus || currentEvent == 0) {
438     G4cerr << "Warning from G4RunManager::rndmSaveThisEvent():"
439          << " there is no currentEvent or its RandomEngineStatus is not available."
440          << G4endl << "Command ignored." << G4endl;
441     return;
442  }
443 
444  G4String fileIn  = randomNumberStatusDir + "currentEvent.rndm";
445
446  std::ostringstream os;
447  os << "run" << currentRun->GetRunID() << "evt" << currentEvent->GetEventID()
448     << ".rndm" << '\0';
449  G4String fileOut = randomNumberStatusDir + os.str();       
450
451  G4String copCmd = "/control/shell cp "+fileIn+" "+fileOut;
452  G4UImanager::GetUIpointer()->ApplyCommand(copCmd);
453  if(verboseLevel>0) G4cout << "currentEvent.rndm is copied to file: " << fileOut << G4endl; 
454}
455 
456void G4RunManager::RestoreRandomNumberStatus(const G4String& fileN)
457{
458  G4String fileNameWithDirectory;
459  if(fileN.index("/")==std::string::npos)
460  { fileNameWithDirectory = randomNumberStatusDir+fileN; }
461  else
462  { fileNameWithDirectory = fileN; }
463 
464  HepRandom::restoreEngineStatus(fileNameWithDirectory);
465  if(verboseLevel>0) G4cout << "RandomNumberEngineStatus restored from file: "
466         << fileNameWithDirectory << G4endl;
467  HepRandom::showEngineStatus();         
468}
469
470void G4RunManager::DumpRegion(const G4String& rname) const
471{
472  kernel->UpdateRegion();
473  kernel->DumpRegion(rname);
474}
475
476void G4RunManager::DumpRegion(G4Region* region) const
477{
478  kernel->UpdateRegion();
479  kernel->DumpRegion(region);
480}
481
482#include "G4ScoringManager.hh"
483#include "G4TransportationManager.hh"
484#include "G4VScoringMesh.hh"
485#include "G4ParticleTable.hh"
486#include "G4ParticleDefinition.hh"
487#include "G4ProcessManager.hh"
488#include "G4ParallelWorldScoringProcess.hh"
489#include "G4HCofThisEvent.hh"
490#include "G4VHitsCollection.hh"
491
492void G4RunManager::ConstructScoringWorlds()
493{
494  G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
495  if(!ScM) return;
496  G4int nPar = ScM->GetNumberOfMesh();
497  if(nPar<1) return;
498
499  G4ParticleTable::G4PTblDicIterator* theParticleIterator
500   = G4ParticleTable::GetParticleTable()->GetIterator();
501  for(G4int iw=0;iw<nPar;iw++)
502  {
503    G4VScoringMesh* mesh = ScM->GetMesh(iw);
504    G4VPhysicalVolume* pWorld
505       = G4TransportationManager::GetTransportationManager()
506         ->IsWorldExisting(ScM->GetWorldName(iw));
507    if(!pWorld)
508    {
509      pWorld = G4TransportationManager::GetTransportationManager()
510         ->GetParallelWorld(ScM->GetWorldName(iw));
511      pWorld->SetName(ScM->GetWorldName(iw));
512
513      G4ParallelWorldScoringProcess* theParallelWorldScoringProcess
514        = new G4ParallelWorldScoringProcess(ScM->GetWorldName(iw));
515      theParallelWorldScoringProcess->SetParallelWorld(ScM->GetWorldName(iw));
516
517      theParticleIterator->reset();
518      while( (*theParticleIterator)() ){
519        G4ParticleDefinition* particle = theParticleIterator->value();
520        G4ProcessManager* pmanager = particle->GetProcessManager();
521        pmanager->AddProcess(theParallelWorldScoringProcess);
522        pmanager->SetProcessOrderingToLast(theParallelWorldScoringProcess, idxAtRest);
523        pmanager->SetProcessOrderingToSecond(theParallelWorldScoringProcess, idxAlongStep);
524        pmanager->SetProcessOrderingToLast(theParallelWorldScoringProcess, idxPostStep);
525      }
526    }
527    mesh->Construct(pWorld);
528  }
529  GeometryHasBeenModified();
530}
531
532void G4RunManager::UpdateScoring()
533{
534  G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
535  if(!ScM) return;
536  G4int nPar = ScM->GetNumberOfMesh();
537  if(nPar<1) return;
538
539  G4HCofThisEvent* HCE = currentEvent->GetHCofThisEvent();
540  if(!HCE) return;
541  G4int nColl = HCE->GetCapacity();
542  for(G4int i=0;i<nColl;i++)
543  {
544    G4VHitsCollection* HC = HCE->GetHC(i);
545    if(HC) ScM->Accumulate(HC);
546  }
547}
548
549
Note: See TracBrowser for help on using the repository browser.