00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "G4Timer.hh"
00034
00035 #include "G4RunManager.hh"
00036 #include "G4RunManagerKernel.hh"
00037
00038 #include "G4StateManager.hh"
00039 #include "G4ApplicationState.hh"
00040 #include "Randomize.hh"
00041 #include "G4Run.hh"
00042 #include "G4RunMessenger.hh"
00043 #include "G4VUserPhysicsList.hh"
00044 #include "G4VUserDetectorConstruction.hh"
00045 #include "G4UserRunAction.hh"
00046 #include "G4VUserPrimaryGeneratorAction.hh"
00047 #include "G4VPersistencyManager.hh"
00048 #include "G4ParticleTable.hh"
00049 #include "G4ProcessTable.hh"
00050 #include "G4UnitsTable.hh"
00051 #include "G4VVisManager.hh"
00052 #include "G4Material.hh"
00053 #include "G4SDManager.hh"
00054 #include "G4UImanager.hh"
00055 #include "G4ios.hh"
00056 #include <sstream>
00057
00058 using namespace CLHEP;
00059
00060 G4RunManager* G4RunManager::fRunManager = 0;
00061
00062 G4RunManager* G4RunManager::GetRunManager()
00063 { return fRunManager; }
00064
00065 G4RunManager::G4RunManager()
00066 :userDetector(0),physicsList(0),
00067 userRunAction(0),userPrimaryGeneratorAction(0),userEventAction(0),
00068 userStackingAction(0),userTrackingAction(0),userSteppingAction(0),
00069 geometryInitialized(false),physicsInitialized(false),
00070 runAborted(false),initializedAtLeastOnce(false),
00071 geometryToBeOptimized(true),runIDCounter(0),verboseLevel(0),DCtable(0),
00072 currentRun(0),currentEvent(0),n_perviousEventsToBeStored(0),
00073 numberOfEventToBeProcessed(0),storeRandomNumberStatus(false),
00074 storeRandomNumberStatusToG4Event(0),
00075 currentWorld(0),nParallelWorlds(0),msgText(" "),n_select_msg(-1),
00076 numberOfEventProcessed(0)
00077 {
00078 if(fRunManager)
00079 {
00080 G4Exception("G4RunManager::G4RunManager()", "Run0031",
00081 FatalException, "G4RunManager constructed twice.");
00082 }
00083 fRunManager = this;
00084
00085 kernel = new G4RunManagerKernel();
00086 eventManager = kernel->GetEventManager();
00087
00088 timer = new G4Timer();
00089 runMessenger = new G4RunMessenger(this);
00090 previousEvents = new std::vector<G4Event*>;
00091 G4ParticleTable::GetParticleTable()->CreateMessenger();
00092 G4ProcessTable::GetProcessTable()->CreateMessenger();
00093 randomNumberStatusDir = "./";
00094 std::ostringstream oss;
00095 HepRandom::saveFullState(oss);
00096 randomNumberStatusForThisRun = oss.str();
00097 randomNumberStatusForThisEvent = oss.str();
00098 }
00099
00100 G4RunManager::~G4RunManager()
00101 {
00102 G4StateManager* pStateManager = G4StateManager::GetStateManager();
00103
00104 if(pStateManager->GetCurrentState()!=G4State_Quit)
00105 {
00106 if(verboseLevel>0) G4cout << "G4 kernel has come to Quit state." << G4endl;
00107 pStateManager->SetNewState(G4State_Quit);
00108 }
00109
00110 if(currentRun) delete currentRun;
00111 delete timer;
00112 delete runMessenger;
00113 G4ParticleTable::GetParticleTable()->DeleteMessenger();
00114 G4ProcessTable::GetProcessTable()->DeleteMessenger();
00115 delete previousEvents;
00116 if(userDetector)
00117 {
00118 delete userDetector;
00119 userDetector = 0;
00120 if(verboseLevel>1) G4cout << "UserDetectorConstruction deleted." << G4endl;
00121 }
00122 if(physicsList)
00123 {
00124 delete physicsList;
00125 physicsList = 0;
00126 if(verboseLevel>1) G4cout << "UserPhysicsList deleted." << G4endl;
00127 }
00128 if(userRunAction)
00129 {
00130 delete userRunAction;
00131 userRunAction = 0;
00132 if(verboseLevel>1) G4cout << "UserRunAction deleted." << G4endl;
00133 }
00134 if(userPrimaryGeneratorAction)
00135 {
00136 delete userPrimaryGeneratorAction;
00137 userPrimaryGeneratorAction = 0;
00138 if(verboseLevel>1) G4cout << "UserPrimaryGenerator deleted." << G4endl;
00139 }
00140
00141 delete kernel;
00142
00143 if(verboseLevel>1) G4cout << "RunManager is deleted." << G4endl;
00144 fRunManager = 0;
00145 }
00146
00147 void G4RunManager::BeamOn(G4int n_event,const char* macroFile,G4int n_select)
00148 {
00149 G4bool cond = ConfirmBeamOnCondition();
00150 if(cond)
00151 {
00152 numberOfEventToBeProcessed = n_event;
00153 ConstructScoringWorlds();
00154 RunInitialization();
00155 if(n_event>0) DoEventLoop(n_event,macroFile,n_select);
00156 RunTermination();
00157 }
00158 }
00159
00160 G4bool G4RunManager::ConfirmBeamOnCondition()
00161 {
00162 G4StateManager* stateManager = G4StateManager::GetStateManager();
00163
00164 G4ApplicationState currentState = stateManager->GetCurrentState();
00165 if(currentState!=G4State_PreInit && currentState!=G4State_Idle)
00166 {
00167 G4cerr << "Illegal application state - BeamOn() ignored." << G4endl;
00168 return false;
00169 }
00170
00171 if(!initializedAtLeastOnce)
00172 {
00173 G4cerr << " Geant4 kernel should be initialized" << G4endl;
00174 G4cerr << "before the first BeamOn(). - BeamOn ignored." << G4endl;
00175 return false;
00176 }
00177
00178 if(!geometryInitialized || !physicsInitialized)
00179 {
00180 if(verboseLevel>0)
00181 {
00182 G4cout << "Start re-initialization because " << G4endl;
00183 if(!geometryInitialized) G4cout << " Geometry" << G4endl;
00184 if(!physicsInitialized) G4cout << " Physics processes" << G4endl;
00185 G4cout << "has been modified since last Run." << G4endl;
00186 }
00187 Initialize();
00188 }
00189 return true;
00190 }
00191
00192 void G4RunManager::RunInitialization()
00193 {
00194 if(!(kernel->RunInitialization())) return;
00195 if(currentRun) delete currentRun;
00196 currentRun = 0;
00197
00198 if(userRunAction) currentRun = userRunAction->GenerateRun();
00199 if(!currentRun) currentRun = new G4Run();
00200
00201 currentRun->SetRunID(runIDCounter);
00202 currentRun->SetNumberOfEventToBeProcessed(numberOfEventToBeProcessed);
00203
00204 currentRun->SetDCtable(DCtable);
00205 G4SDManager* fSDM = G4SDManager::GetSDMpointerIfExist();
00206 if(fSDM)
00207 { currentRun->SetHCtable(fSDM->GetHCtable()); }
00208
00209 std::ostringstream oss;
00210 HepRandom::saveFullState(oss);
00211 randomNumberStatusForThisRun = oss.str();
00212 currentRun->SetRandomNumberStatus(randomNumberStatusForThisRun);
00213
00214 previousEvents->clear();
00215 for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
00216 { previousEvents->push_back((G4Event*)0); }
00217
00218 if(userRunAction) userRunAction->BeginOfRunAction(currentRun);
00219
00220 if(storeRandomNumberStatus) {
00221 G4String fileN = randomNumberStatusDir + "currentRun.rndm";
00222 HepRandom::saveEngineStatus(fileN);
00223 }
00224
00225 runAborted = false;
00226 numberOfEventProcessed = 0;
00227 if(verboseLevel>0) G4cout << "Start Run processing." << G4endl;
00228 }
00229
00230 void G4RunManager::DoEventLoop(G4int n_event,const char* macroFile,G4int n_select)
00231 {
00232 InitializeEventLoop(n_event,macroFile,n_select);
00233
00234
00235 for(G4int i_event=0; i_event<n_event; i_event++ )
00236 {
00237 ProcessOneEvent(i_event);
00238 TerminateOneEvent();
00239 if(runAborted) break;
00240 }
00241
00242 TerminateEventLoop();
00243 }
00244
00245 void G4RunManager::InitializeEventLoop(G4int n_event,const char* macroFile,G4int n_select)
00246 {
00247 if(verboseLevel>0)
00248 { timer->Start(); }
00249
00250 n_select_msg = n_select;
00251 if(macroFile!=0)
00252 {
00253 if(n_select_msg<0) n_select_msg = n_event;
00254 msgText = "/control/execute ";
00255 msgText += macroFile;
00256 }
00257 else
00258 { n_select_msg = -1; }
00259 }
00260
00261 void G4RunManager::ProcessOneEvent(G4int i_event)
00262 {
00263 currentEvent = GenerateEvent(i_event);
00264 eventManager->ProcessOneEvent(currentEvent);
00265 AnalyzeEvent(currentEvent);
00266 UpdateScoring();
00267 if(i_event<n_select_msg) G4UImanager::GetUIpointer()->ApplyCommand(msgText);
00268 }
00269
00270 void G4RunManager::TerminateOneEvent()
00271 {
00272 StackPreviousEvent(currentEvent);
00273 currentEvent = 0;
00274 numberOfEventProcessed++;
00275 }
00276
00277 void G4RunManager::TerminateEventLoop()
00278 {
00279 if(verboseLevel>0)
00280 {
00281 timer->Stop();
00282 G4cout << "Run terminated." << G4endl;
00283 G4cout << "Run Summary" << G4endl;
00284 if(runAborted)
00285 { G4cout << " Run Aborted after " << numberOfEventProcessed << " events processed." << G4endl; }
00286 else
00287 { G4cout << " Number of events processed : " << numberOfEventProcessed << G4endl; }
00288 G4cout << " " << *timer << G4endl;
00289 }
00290 }
00291
00292 G4Event* G4RunManager::GenerateEvent(G4int i_event)
00293 {
00294 if(!userPrimaryGeneratorAction)
00295 {
00296 G4Exception("G4RunManager::GenerateEvent()", "Run0032", FatalException,
00297 "G4VUserPrimaryGeneratorAction is not defined!");
00298 return 0;
00299 }
00300
00301 G4Event* anEvent = new G4Event(i_event);
00302
00303 if(storeRandomNumberStatusToG4Event==1 || storeRandomNumberStatusToG4Event==3)
00304 {
00305 std::ostringstream oss;
00306 HepRandom::saveFullState(oss);
00307 randomNumberStatusForThisEvent = oss.str();
00308 anEvent->SetRandomNumberStatus(randomNumberStatusForThisEvent);
00309 }
00310
00311 if(storeRandomNumberStatus) {
00312 G4String fileN = randomNumberStatusDir + "currentEvent.rndm";
00313 HepRandom::saveEngineStatus(fileN);
00314 }
00315
00316 userPrimaryGeneratorAction->GeneratePrimaries(anEvent);
00317 return anEvent;
00318 }
00319
00320 void G4RunManager::AnalyzeEvent(G4Event* anEvent)
00321 {
00322 G4VPersistencyManager* fPersM = G4VPersistencyManager::GetPersistencyManager();
00323 if(fPersM) fPersM->Store(anEvent);
00324 currentRun->RecordEvent(anEvent);
00325 }
00326
00327 void G4RunManager::RunTermination()
00328 {
00329 for(size_t itr=0;itr<previousEvents->size();itr++)
00330 {
00331 G4Event* prevEv = (*previousEvents)[itr];
00332 if((prevEv) && !(prevEv->ToBeKept())) delete prevEv;
00333 }
00334 previousEvents->clear();
00335 for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
00336 { previousEvents->push_back((G4Event*)0); }
00337
00338 if(userRunAction) userRunAction->EndOfRunAction(currentRun);
00339
00340 G4VPersistencyManager* fPersM = G4VPersistencyManager::GetPersistencyManager();
00341 if(fPersM) fPersM->Store(currentRun);
00342 runIDCounter++;
00343
00344 kernel->RunTermination();
00345 }
00346
00347 void G4RunManager::StackPreviousEvent(G4Event* anEvent)
00348 {
00349 if(anEvent->ToBeKept()) currentRun->StoreEvent(anEvent);
00350 G4Event* evt;
00351 if(n_perviousEventsToBeStored==0)
00352 { evt = anEvent; }
00353 else
00354 {
00355 previousEvents->insert(previousEvents->begin(),anEvent);
00356 evt = previousEvents->back();
00357 previousEvents->pop_back();
00358 }
00359 if(evt && !(evt->ToBeKept())) delete evt;
00360 }
00361
00362 void G4RunManager::Initialize()
00363 {
00364 G4StateManager* stateManager = G4StateManager::GetStateManager();
00365 G4ApplicationState currentState = stateManager->GetCurrentState();
00366 if(currentState!=G4State_PreInit && currentState!=G4State_Idle)
00367 {
00368 G4cerr << "Illegal application state - "
00369 << "G4RunManager::Initialize() ignored." << G4endl;
00370 return;
00371 }
00372
00373 if(!geometryInitialized) InitializeGeometry();
00374 if(!physicsInitialized) InitializePhysics();
00375 initializedAtLeastOnce = true;
00376 }
00377
00378 void G4RunManager::InitializeGeometry()
00379 {
00380 if(!userDetector)
00381 {
00382 G4Exception("G4RunManager::InitializeGeometry", "Run0033",
00383 FatalException, "G4VUserDetectorConstruction is not defined!");
00384 return;
00385 }
00386
00387 if(verboseLevel>1) G4cout << "userDetector->Construct() start." << G4endl;
00388 kernel->DefineWorldVolume(userDetector->Construct(),false);
00389 nParallelWorlds = userDetector->ConstructParallelGeometries();
00390 kernel->SetNumberOfParallelWorld(nParallelWorlds);
00391 geometryInitialized = true;
00392 }
00393
00394 void G4RunManager::InitializePhysics()
00395 {
00396 if(physicsList)
00397 {
00398 if(verboseLevel>1) G4cout << "physicsList->Construct() start." << G4endl;
00399 kernel->InitializePhysics();
00400 }
00401 else
00402 {
00403 G4Exception("G4RunManager::InitializePhysics()", "Run0034",
00404 FatalException, "G4VUserPhysicsList is not defined!");
00405 }
00406 physicsInitialized = true;
00407 }
00408
00409 void G4RunManager::AbortRun(G4bool softAbort)
00410 {
00411
00412 G4ApplicationState currentState =
00413 G4StateManager::GetStateManager()->GetCurrentState();
00414 if(currentState==G4State_GeomClosed || currentState==G4State_EventProc)
00415 {
00416 runAborted = true;
00417 if(currentState==G4State_EventProc && !softAbort)
00418 {
00419 currentEvent->SetEventAborted();
00420 eventManager->AbortCurrentEvent();
00421 }
00422 }
00423 else
00424 {
00425 G4cerr << "Run is not in progress. AbortRun() ignored." << G4endl;
00426 }
00427 }
00428
00429 void G4RunManager::AbortEvent()
00430 {
00431
00432 G4ApplicationState currentState =
00433 G4StateManager::GetStateManager()->GetCurrentState();
00434 if(currentState==G4State_EventProc)
00435 {
00436 currentEvent->SetEventAborted();
00437 eventManager->AbortCurrentEvent();
00438 }
00439 else
00440 {
00441 G4cerr << "Event is not in progress. AbortEevnt() ignored." << G4endl;
00442 }
00443 }
00444
00445 void G4RunManager::DefineWorldVolume(G4VPhysicalVolume* worldVol,
00446 G4bool topologyIsChanged)
00447 {
00448 kernel->DefineWorldVolume(worldVol,topologyIsChanged);
00449 }
00450
00451 void G4RunManager::rndmSaveThisRun()
00452 {
00453 G4int runNumber = 0;
00454 if(currentRun) runNumber = currentRun->GetRunID();
00455 if(!storeRandomNumberStatus) {
00456 G4cerr << "Warning from G4RunManager::rndmSaveThisRun():"
00457 << " Random number status was not stored prior to this run."
00458 << G4endl << "Command ignored." << G4endl;
00459 return;
00460 }
00461
00462 G4String fileIn = randomNumberStatusDir + "currentRun.rndm";
00463
00464 std::ostringstream os;
00465 os << "run" << runNumber << ".rndm" << '\0';
00466 G4String fileOut = randomNumberStatusDir + os.str();
00467
00468 G4String copCmd = "/control/shell cp "+fileIn+" "+fileOut;
00469 G4UImanager::GetUIpointer()->ApplyCommand(copCmd);
00470 if(verboseLevel>0) G4cout << "currentRun.rndm is copied to file: " << fileOut << G4endl;
00471 }
00472
00473 void G4RunManager::rndmSaveThisEvent()
00474 {
00475 if(!storeRandomNumberStatus || currentEvent == 0) {
00476 G4cerr << "Warning from G4RunManager::rndmSaveThisEvent():"
00477 << " there is no currentEvent or its RandomEngineStatus is not available."
00478 << G4endl << "Command ignored." << G4endl;
00479 return;
00480 }
00481
00482 G4String fileIn = randomNumberStatusDir + "currentEvent.rndm";
00483
00484 std::ostringstream os;
00485 os << "run" << currentRun->GetRunID() << "evt" << currentEvent->GetEventID()
00486 << ".rndm" << '\0';
00487 G4String fileOut = randomNumberStatusDir + os.str();
00488
00489 G4String copCmd = "/control/shell cp "+fileIn+" "+fileOut;
00490 G4UImanager::GetUIpointer()->ApplyCommand(copCmd);
00491 if(verboseLevel>0) G4cout << "currentEvent.rndm is copied to file: " << fileOut << G4endl;
00492 }
00493
00494 void G4RunManager::RestoreRandomNumberStatus(const G4String& fileN)
00495 {
00496 G4String fileNameWithDirectory;
00497 if(fileN.index("/")==std::string::npos)
00498 { fileNameWithDirectory = randomNumberStatusDir+fileN; }
00499 else
00500 { fileNameWithDirectory = fileN; }
00501
00502 HepRandom::restoreEngineStatus(fileNameWithDirectory);
00503 if(verboseLevel>0) G4cout << "RandomNumberEngineStatus restored from file: "
00504 << fileNameWithDirectory << G4endl;
00505 HepRandom::showEngineStatus();
00506 }
00507
00508 void G4RunManager::DumpRegion(const G4String& rname) const
00509 {
00510
00511 kernel->DumpRegion(rname);
00512 }
00513
00514 void G4RunManager::DumpRegion(G4Region* region) const
00515 {
00516
00517 kernel->DumpRegion(region);
00518 }
00519
00520 #include "G4ScoringManager.hh"
00521 #include "G4TransportationManager.hh"
00522 #include "G4VScoringMesh.hh"
00523 #include "G4ParticleTable.hh"
00524 #include "G4ParticleDefinition.hh"
00525 #include "G4ProcessManager.hh"
00526 #include "G4ParallelWorldScoringProcess.hh"
00527 #include "G4HCofThisEvent.hh"
00528 #include "G4VHitsCollection.hh"
00529
00530 void G4RunManager::ConstructScoringWorlds()
00531 {
00532 G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
00533 if(!ScM) return;
00534 G4int nPar = ScM->GetNumberOfMesh();
00535 if(nPar<1) return;
00536
00537 G4ParticleTable::G4PTblDicIterator* theParticleIterator
00538 = G4ParticleTable::GetParticleTable()->GetIterator();
00539 for(G4int iw=0;iw<nPar;iw++)
00540 {
00541 G4VScoringMesh* mesh = ScM->GetMesh(iw);
00542 G4VPhysicalVolume* pWorld
00543 = G4TransportationManager::GetTransportationManager()
00544 ->IsWorldExisting(ScM->GetWorldName(iw));
00545 if(!pWorld)
00546 {
00547 pWorld = G4TransportationManager::GetTransportationManager()
00548 ->GetParallelWorld(ScM->GetWorldName(iw));
00549 pWorld->SetName(ScM->GetWorldName(iw));
00550
00551 G4ParallelWorldScoringProcess* theParallelWorldScoringProcess
00552 = new G4ParallelWorldScoringProcess(ScM->GetWorldName(iw));
00553 theParallelWorldScoringProcess->SetParallelWorld(ScM->GetWorldName(iw));
00554
00555 theParticleIterator->reset();
00556 while( (*theParticleIterator)() ){
00557 G4ParticleDefinition* particle = theParticleIterator->value();
00558 G4ProcessManager* pmanager = particle->GetProcessManager();
00559 if(pmanager)
00560 {
00561 pmanager->AddProcess(theParallelWorldScoringProcess);
00562 if(theParallelWorldScoringProcess->IsAtRestRequired(particle))
00563 { pmanager->SetProcessOrdering(theParallelWorldScoringProcess, idxAtRest, 9999); }
00564 pmanager->SetProcessOrderingToSecond(theParallelWorldScoringProcess, idxAlongStep);
00565 pmanager->SetProcessOrdering(theParallelWorldScoringProcess, idxPostStep, 9999);
00566 }
00567 }
00568 }
00569 mesh->Construct(pWorld);
00570 }
00571 GeometryHasBeenModified();
00572 }
00573
00574 void G4RunManager::UpdateScoring()
00575 {
00576 G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
00577 if(!ScM) return;
00578 G4int nPar = ScM->GetNumberOfMesh();
00579 if(nPar<1) return;
00580
00581 G4HCofThisEvent* HCE = currentEvent->GetHCofThisEvent();
00582 if(!HCE) return;
00583 G4int nColl = HCE->GetCapacity();
00584 for(G4int i=0;i<nColl;i++)
00585 {
00586 G4VHitsCollection* HC = HCE->GetHC(i);
00587 if(HC) ScM->Accumulate(HC);
00588 }
00589 }
00590
00591 #include "G4VPhysicalVolume.hh"
00592 #include "G4LogicalVolume.hh"
00593 #include "G4SmartVoxelHeader.hh"
00594
00595 void G4RunManager::ReOptimizeMotherOf(G4VPhysicalVolume* pPhys)
00596 {
00597 G4LogicalVolume* pMotherL = pPhys->GetMotherLogical();
00598 if(pMotherL) ReOptimize(pMotherL);
00599 }
00600
00601 void G4RunManager::ReOptimize(G4LogicalVolume* pLog)
00602 {
00603 G4SmartVoxelHeader* header = pLog->GetVoxelHeader();
00604 delete header;
00605 header = new G4SmartVoxelHeader(pLog);
00606 pLog->SetVoxelHeader(header);
00607 }
00608