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

Last change on this file since 1058 was 1058, checked in by garnier, 15 years ago

file release beta

File size: 16.9 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.108 2007/11/09 13:57:39 asaim Exp $
28// GEANT4 tag $Name: geant4-09-02-ref-02 $
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    printf("G4RunManager::BeamOn before INIT\n");
140    RunInitialization();
141    printf("G4RunManager::BeamOn after INIT\n");
142    if(n_event>0) DoEventLoop(n_event,macroFile,n_select);
143    printf("G4RunManager::BeamOn before END\n");
144    RunTermination();
145    printf("G4RunManager::BeamOn after END\n");
146  }
147}
148
149G4bool G4RunManager::ConfirmBeamOnCondition()
150{
151  G4StateManager* stateManager = G4StateManager::GetStateManager();
152
153  G4ApplicationState currentState = stateManager->GetCurrentState();
154  if(currentState!=G4State_PreInit && currentState!=G4State_Idle)
155  {
156    G4cerr << "Illegal application state - BeamOn() ignored." << G4endl;
157    return false;
158  }
159
160  if(!initializedAtLeastOnce)
161  {
162    G4cerr << " Geant4 kernel should be initialized" << G4endl;
163    G4cerr << "before the first BeamOn(). - BeamOn ignored." << G4endl;
164    return false;
165  }
166
167  if(!geometryInitialized || !physicsInitialized)
168  {
169    if(verboseLevel>0)
170    {
171      G4cout << "Start re-initialization because " << G4endl;
172      if(!geometryInitialized) G4cout << "  Geometry" << G4endl;
173      if(!physicsInitialized)  G4cout << "  Physics processes" << G4endl;
174      G4cout << "has been modified since last Run." << G4endl;
175    }
176    Initialize();
177  }
178  return true;
179}
180
181void G4RunManager::RunInitialization()
182{
183  if(!(kernel->RunInitialization())) return;
184  if(currentRun) delete currentRun;
185  currentRun = 0;
186
187  if(userRunAction) currentRun = userRunAction->GenerateRun();
188  if(!currentRun) currentRun = new G4Run();
189
190  currentRun->SetRunID(runIDCounter);
191  currentRun->SetNumberOfEventToBeProcessed(numberOfEventToBeProcessed);
192
193  currentRun->SetDCtable(DCtable);
194  G4SDManager* fSDM = G4SDManager::GetSDMpointerIfExist();
195  if(fSDM)
196  { currentRun->SetHCtable(fSDM->GetHCtable()); }
197 
198  std::ostringstream oss;
199  HepRandom::saveFullState(oss);
200  randomNumberStatusForThisRun = oss.str();
201  currentRun->SetRandomNumberStatus(randomNumberStatusForThisRun);
202 
203  previousEvents->clear();
204  for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
205  { previousEvents->push_back((G4Event*)0); }
206
207  if(userRunAction) userRunAction->BeginOfRunAction(currentRun);
208
209  if(storeRandomNumberStatus) {
210    G4String fileN = randomNumberStatusDir + "currentRun.rndm"; 
211    HepRandom::saveEngineStatus(fileN);
212  }
213
214  runAborted = false;
215
216  if(verboseLevel>0) G4cout << "Start Run processing." << G4endl;
217}
218
219void G4RunManager::DoEventLoop(G4int n_event,const char* macroFile,G4int n_select)
220{
221  if(verboseLevel>0) 
222  { timer->Start(); }
223
224  G4String msg;
225  if(macroFile!=0)
226  { 
227    if(n_select<0) n_select = n_event;
228    msg = "/control/execute ";
229    msg += macroFile;
230  }
231  else
232  { n_select = -1; }
233
234// Event loop
235  G4int i_event;
236  for( i_event=0; i_event<n_event; i_event++ )
237  {
238    printf("1\n");
239    currentEvent = GenerateEvent(i_event);
240    printf("2\n");
241    eventManager->ProcessOneEvent(currentEvent);
242    printf("3\n");
243    AnalyzeEvent(currentEvent);
244    printf("4\n");
245    UpdateScoring();
246    printf("5\n");
247    if(i_event<n_select) G4UImanager::GetUIpointer()->ApplyCommand(msg);
248    printf("6\n");
249    StackPreviousEvent(currentEvent);
250    printf("7\n");
251    currentEvent = 0;
252    printf("8\n");
253    if(runAborted) break;
254    printf("9\n");
255  }
256
257  if(verboseLevel>0)
258  {
259    timer->Stop();
260    G4cout << "Run terminated." << G4endl;
261    G4cout << "Run Summary" << G4endl;
262    if(runAborted)
263    { G4cout << "  Run Aborted after " << i_event << " events processed." << G4endl; }
264    else
265    { G4cout << "  Number of events processed : " << n_event << G4endl; }
266    G4cout << "  "  << *timer << G4endl;
267  }
268}
269
270G4Event* G4RunManager::GenerateEvent(G4int i_event)
271{
272  if(!userPrimaryGeneratorAction)
273  {
274    G4Exception
275    ("G4RunManager::BeamOn - G4VUserPrimaryGeneratorAction is not defined.");
276  }
277
278  G4Event* anEvent = new G4Event(i_event);
279
280  if(storeRandomNumberStatusToG4Event==1 || storeRandomNumberStatusToG4Event==3)
281  {
282    std::ostringstream oss;
283    HepRandom::saveFullState(oss);
284    randomNumberStatusForThisEvent = oss.str();
285    anEvent->SetRandomNumberStatus(randomNumberStatusForThisEvent);
286  }
287
288  if(storeRandomNumberStatus) {
289    G4String fileN = randomNumberStatusDir + "currentEvent.rndm"; 
290    HepRandom::saveEngineStatus(fileN);
291  } 
292   
293  userPrimaryGeneratorAction->GeneratePrimaries(anEvent);
294  return anEvent;
295}
296
297void G4RunManager::AnalyzeEvent(G4Event* anEvent)
298{
299  G4VPersistencyManager* fPersM = G4VPersistencyManager::GetPersistencyManager();
300  if(fPersM) fPersM->Store(anEvent);
301  currentRun->RecordEvent(anEvent);
302}
303
304void G4RunManager::RunTermination()
305{
306  for(size_t itr=0;itr<previousEvents->size();itr++)
307  {
308    G4Event* prevEv =  (*previousEvents)[itr];
309    if((prevEv) && !(prevEv->ToBeKept())) delete prevEv;
310  }
311  previousEvents->clear();
312  for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
313  { previousEvents->push_back((G4Event*)0); }
314
315  if(userRunAction) userRunAction->EndOfRunAction(currentRun);
316
317  G4VPersistencyManager* fPersM = G4VPersistencyManager::GetPersistencyManager();
318  if(fPersM) fPersM->Store(currentRun);
319  runIDCounter++;
320
321  kernel->RunTermination();
322}
323
324void G4RunManager::StackPreviousEvent(G4Event* anEvent)
325{
326  if(anEvent->ToBeKept()) currentRun->StoreEvent(anEvent);
327  G4Event* evt;
328  if(n_perviousEventsToBeStored==0)
329  { evt = anEvent; }
330  else
331  {
332    previousEvents->insert(previousEvents->begin(),anEvent);
333    evt = previousEvents->back();
334    previousEvents->pop_back();
335  }
336  if(evt && !(evt->ToBeKept())) delete evt;
337}
338
339void G4RunManager::Initialize()
340{
341  G4StateManager* stateManager = G4StateManager::GetStateManager();
342  G4ApplicationState currentState = stateManager->GetCurrentState();
343  if(currentState!=G4State_PreInit && currentState!=G4State_Idle)
344  {
345    G4cerr << "Illegal application state - "
346         << "G4RunManager::Initialize() ignored." << G4endl;
347    return;
348  }
349
350  if(!geometryInitialized) InitializeGeometry();
351  if(!physicsInitialized) InitializePhysics();
352  initializedAtLeastOnce = true;
353}
354
355void G4RunManager::InitializeGeometry()
356{
357  if(!userDetector)
358  {
359    G4Exception
360    ("G4RunManager::InitializeGeometry - G4VUserDetectorConstruction is not defined.");
361  }
362
363  if(verboseLevel>1) G4cout << "userDetector->Construct() start." << G4endl;
364  kernel->DefineWorldVolume(userDetector->Construct(),false);
365  nParallelWorlds = userDetector->ConstructParallelGeometries();
366  kernel->SetNumberOfParallelWorld(nParallelWorlds);
367  geometryInitialized = true;
368}
369
370void G4RunManager::InitializePhysics()
371{
372  if(physicsList)
373  {
374    if(verboseLevel>1) G4cout << "physicsList->Construct() start." << G4endl;
375    kernel->InitializePhysics();
376  }
377  else
378  {
379    G4Exception("G4VUserPhysicsList is not defined");
380  }
381  physicsInitialized = true;
382}
383
384void G4RunManager::AbortRun(G4bool softAbort)
385{
386  // This method is valid only for GeomClosed or EventProc state
387  G4ApplicationState currentState = 
388    G4StateManager::GetStateManager()->GetCurrentState();
389  if(currentState==G4State_GeomClosed || currentState==G4State_EventProc)
390  {
391    runAborted = true;
392    if(currentState==G4State_EventProc && !softAbort)
393    {
394      currentEvent->SetEventAborted();
395      eventManager->AbortCurrentEvent();
396    }
397  }
398  else
399  {
400    G4cerr << "Run is not in progress. AbortRun() ignored." << G4endl;
401  }
402}
403
404void G4RunManager::AbortEvent()
405{
406  // This method is valid only for EventProc state
407  G4ApplicationState currentState = 
408    G4StateManager::GetStateManager()->GetCurrentState();
409  if(currentState==G4State_EventProc)
410  {
411    currentEvent->SetEventAborted();
412    eventManager->AbortCurrentEvent();
413  }
414  else
415  {
416    G4cerr << "Event is not in progress. AbortEevnt() ignored." << G4endl;
417  }
418}
419
420void G4RunManager::DefineWorldVolume(G4VPhysicalVolume* worldVol,
421                                     G4bool topologyIsChanged)
422{
423  kernel->DefineWorldVolume(worldVol,topologyIsChanged);
424}
425
426void G4RunManager::rndmSaveThisRun()
427{
428  G4int runNumber = 0;
429  if(currentRun) runNumber = currentRun->GetRunID();
430  if(!storeRandomNumberStatus) {
431     G4cerr << "Warning from G4RunManager::rndmSaveThisRun():"
432          << " Random number status was not stored prior to this run." 
433          << G4endl << "Command ignored." << G4endl;
434     return;
435  }
436 
437  G4String fileIn  = randomNumberStatusDir + "currentRun.rndm";
438 
439  std::ostringstream os;
440  os << "run" << runNumber << ".rndm" << '\0';
441  G4String fileOut = randomNumberStatusDir + os.str(); 
442
443  G4String copCmd = "/control/shell cp "+fileIn+" "+fileOut;
444  G4UImanager::GetUIpointer()->ApplyCommand(copCmd);
445  if(verboseLevel>0) G4cout << "currentRun.rndm is copied to file: " << fileOut << G4endl;   
446}
447
448void G4RunManager::rndmSaveThisEvent()
449{
450  if(!storeRandomNumberStatus || currentEvent == 0) {
451     G4cerr << "Warning from G4RunManager::rndmSaveThisEvent():"
452          << " there is no currentEvent or its RandomEngineStatus is not available."
453          << G4endl << "Command ignored." << G4endl;
454     return;
455  }
456 
457  G4String fileIn  = randomNumberStatusDir + "currentEvent.rndm";
458
459  std::ostringstream os;
460  os << "run" << currentRun->GetRunID() << "evt" << currentEvent->GetEventID()
461     << ".rndm" << '\0';
462  G4String fileOut = randomNumberStatusDir + os.str();       
463
464  G4String copCmd = "/control/shell cp "+fileIn+" "+fileOut;
465  G4UImanager::GetUIpointer()->ApplyCommand(copCmd);
466  if(verboseLevel>0) G4cout << "currentEvent.rndm is copied to file: " << fileOut << G4endl; 
467}
468 
469void G4RunManager::RestoreRandomNumberStatus(G4String fileN)
470{
471  G4String fileNameWithDirectory;
472  if(fileN.index("/")==std::string::npos)
473  { fileNameWithDirectory = randomNumberStatusDir+fileN; }
474  else
475  { fileNameWithDirectory = fileN; }
476 
477  HepRandom::restoreEngineStatus(fileNameWithDirectory);
478  if(verboseLevel>0) G4cout << "RandomNumberEngineStatus restored from file: "
479         << fileNameWithDirectory << G4endl;
480  HepRandom::showEngineStatus();         
481}
482
483void G4RunManager::DumpRegion(G4String rname) const
484{
485  kernel->UpdateRegion();
486  kernel->DumpRegion(rname);
487}
488
489void G4RunManager::DumpRegion(G4Region* region) const
490{
491  kernel->UpdateRegion();
492  kernel->DumpRegion(region);
493}
494
495#include "G4ScoringManager.hh"
496#include "G4TransportationManager.hh"
497#include "G4VScoringMesh.hh"
498#include "G4ParticleTable.hh"
499#include "G4ParticleDefinition.hh"
500#include "G4ProcessManager.hh"
501#include "G4ParallelWorldScoringProcess.hh"
502#include "G4HCofThisEvent.hh"
503#include "G4VHitsCollection.hh"
504
505void G4RunManager::ConstructScoringWorlds()
506{
507  G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
508  if(!ScM) return;
509  G4int nPar = ScM->GetNumberOfMesh();
510  if(nPar<1) return;
511
512  G4ParticleTable::G4PTblDicIterator* theParticleIterator
513   = G4ParticleTable::GetParticleTable()->GetIterator();
514  for(G4int iw=0;iw<nPar;iw++)
515  {
516    G4VScoringMesh* mesh = ScM->GetMesh(iw);
517    G4VPhysicalVolume* pWorld
518       = G4TransportationManager::GetTransportationManager()
519         ->IsWorldExisting(ScM->GetWorldName(iw));
520    if(!pWorld)
521    {
522      pWorld = G4TransportationManager::GetTransportationManager()
523         ->GetParallelWorld(ScM->GetWorldName(iw));
524      pWorld->SetName(ScM->GetWorldName(iw));
525
526      G4ParallelWorldScoringProcess* theParallelWorldScoringProcess
527        = new G4ParallelWorldScoringProcess(ScM->GetWorldName(iw));
528      theParallelWorldScoringProcess->SetParallelWorld(ScM->GetWorldName(iw));
529
530      theParticleIterator->reset();
531      while( (*theParticleIterator)() ){
532        G4ParticleDefinition* particle = theParticleIterator->value();
533        G4ProcessManager* pmanager = particle->GetProcessManager();
534        pmanager->AddProcess(theParallelWorldScoringProcess);
535        pmanager->SetProcessOrderingToLast(theParallelWorldScoringProcess, idxAtRest);
536        pmanager->SetProcessOrderingToSecond(theParallelWorldScoringProcess, idxAlongStep);
537        pmanager->SetProcessOrderingToLast(theParallelWorldScoringProcess, idxPostStep);
538      }
539    }
540    mesh->Construct(pWorld);
541  }
542  GeometryHasBeenModified();
543}
544
545void G4RunManager::UpdateScoring()
546{
547  G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
548  if(!ScM) return;
549  G4int nPar = ScM->GetNumberOfMesh();
550  if(nPar<1) return;
551
552  G4HCofThisEvent* HCE = currentEvent->GetHCofThisEvent();
553  if(!HCE) return;
554  G4int nColl = HCE->GetCapacity();
555  for(G4int i=0;i<nColl;i++)
556  {
557    G4VHitsCollection* HC = HCE->GetHC(i);
558    if(HC) ScM->Accumulate(HC);
559  }
560}
561
562
Note: See TracBrowser for help on using the repository browser.