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

Last change on this file since 1031 was 850, checked in by garnier, 17 years ago

geant4.8.2 beta

File size: 16.5 KB
RevLine 
[828]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 $
[850]28// GEANT4 tag $Name: HEAD $
[828]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 << " 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(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(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.