GGS(GenericGEANT4Simulation)Software  2.99.0
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Macros
GGSWorkerRunManager.cpp
1 /*
2  * GGSWorkerRunManager.cpp
3  *
4  * Created on: 4 Nov 2020
5  * Author: Nicola Mori
6  */
7 
9 
10 #include "G4MTRunManager.hh"
11 #include "G4Run.hh"
12 #include "G4TiMemory.hh"
13 #include "G4UImanager.hh"
14 
15 void GGSWorkerRunManager::DoEventLoop(G4int n_event, const char *macroFile, G4int n_select) {
16  // Implementation copy-pasted from G4 10.06.p02 with no modification, to just allow for binding the call to
17  // ProcessOneEvent to the override defined in this class.
18  TIMEMORY_AUTO_TIMER("");
19  if (!userPrimaryGeneratorAction) {
20  G4Exception("G4RunManager::GenerateEvent()", "Run0032", FatalException,
21  "G4VUserPrimaryGeneratorAction is not defined!");
22  }
23 
24  // This is the same as in the sequential case, just the for-loop indexes are
25  // different
26  InitializeEventLoop(n_event, macroFile, n_select);
27 
28  // Reset random number seeds queue
29  while (seedsQueue.size() > 0) {
30  seedsQueue.pop();
31  }
32  // for each run, worker should receive at least one set of random number seeds.
33  runIsSeeded = false;
34 
35  // Event loop
36  eventLoopOnGoing = true;
38  G4int i_event = -1;
39  nevModulo = -1;
40  currEvID = -1;
41 
42  while (eventLoopOnGoing) {
43  ProcessOneEvent(i_event);
44  if (eventLoopOnGoing) {
45  TerminateOneEvent();
46  if (runAborted) {
47  eventLoopOnGoing = false;
48  }
54  }
55  }
56 
57  TerminateEventLoop();
58 }
59 
61 
62  TIMEMORY_AUTO_TIMER("");
63  currentEvent = _SetupRandomNumbers(i_event);
64  // _SetupRandomNumbers will set eventLoopOnGoing to false and return nullptr if the event loop is already finished, so
65  // check before going on.
66  if (eventLoopOnGoing) {
68  userPrimaryGeneratorAction->GeneratePrimaries(currentEvent);
69  DumpStatus(currentEvent->GetEventID());
70  bool resim = true;
71  while (resim) {
73  eventManager->ProcessOneEvent(currentEvent);
74  resim = IsKilledAndToBeSimulatedAgain(currentEvent);
75  if (resim) {
76  // Create a new G4Event for this event
77  G4Event *newEvent = new G4Event(currentEvent->GetEventID());
78  delete currentEvent;
79  currentEvent = newEvent;
80  userPrimaryGeneratorAction->GeneratePrimaries(currentEvent);
81  }
82  }
83  AnalyzeEvent(currentEvent);
84  UpdateScoring();
85  if (currentEvent->GetEventID() < n_select_msg)
86  G4UImanager::GetUIpointer()->ApplyCommand(msgText);
87  }
88 }
89 
90 G4Event *GGSWorkerRunManager::_SetupRandomNumbers(G4int i_event) {
91  // Implementation copy-pasted from G4WorkerRunManager::GenerateEvent in G4 10.06.p02, with these modifications:
92  // 1. don't generate of the event at the end.
93  // 2. offload the handling of seeds files to GGSRunManagerExtensions::HandleEventRngStateFile
94 
95  TIMEMORY_AUTO_TIMER("");
96  G4Event *anEvent = new G4Event(i_event);
97  long s1 = 0;
98  long s2 = 0;
99  long s3 = 0;
100  G4bool eventHasToBeSeeded = true;
101  if (G4MTRunManager::SeedOncePerCommunication() == 1 && runIsSeeded) {
102  eventHasToBeSeeded = false;
103  }
104 
105  if (i_event < 0) {
106  G4int nevM = G4MTRunManager::GetMasterRunManager()->GetEventModulo();
107  if (nevM == 1) {
108  eventLoopOnGoing = G4MTRunManager::GetMasterRunManager()->SetUpAnEvent(anEvent, s1, s2, s3, eventHasToBeSeeded);
109  runIsSeeded = true;
110  } else {
111  if (nevModulo <= 0) {
112  G4int nevToDo = G4MTRunManager::GetMasterRunManager()->SetUpNEvents(anEvent, &seedsQueue, eventHasToBeSeeded);
113  if (nevToDo == 0) {
114  eventLoopOnGoing = false;
115  } else {
116  currEvID = anEvent->GetEventID();
117  nevModulo = nevToDo - 1;
118  }
119  } else {
120  if (G4MTRunManager::SeedOncePerCommunication() > 0)
121  eventHasToBeSeeded = false;
122  anEvent->SetEventID(++currEvID);
123  nevModulo--;
124  }
125  if (eventLoopOnGoing && eventHasToBeSeeded) {
126  s1 = seedsQueue.front();
127  seedsQueue.pop();
128  s2 = seedsQueue.front();
129  seedsQueue.pop();
130  }
131  }
132 
133  if (!eventLoopOnGoing) {
134  delete anEvent;
135  return 0;
136  }
137  } else if (eventHasToBeSeeded) {
138  // Need to reseed random number generator
139  G4RNGHelper *helper = G4RNGHelper::GetInstance();
140  s1 = helper->GetSeed(i_event * 2);
141  s2 = helper->GetSeed(i_event * 2 + 1);
142  }
143 
144  if (eventHasToBeSeeded) {
145  long seeds[3] = {s1, s2, 0};
146  G4Random::setTheSeeds(seeds, luxury);
147  runIsSeeded = true;
149  }
150 
151  HandleEventRngStateFile(currentRun->GetRunID(), anEvent->GetEventID());
152 
153  if (storeRandomNumberStatusToG4Event == 1 || storeRandomNumberStatusToG4Event == 3) {
154  std::ostringstream oss;
155  G4Random::saveFullState(oss);
156  randomNumberStatusForThisEvent = oss.str();
157  anEvent->SetRandomNumberStatus(randomNumberStatusForThisEvent);
158  }
159 
160  if (printModulo > 0 && anEvent->GetEventID() % printModulo == 0) {
161  G4cout << "--> Event " << anEvent->GetEventID() << " starts";
162  if (eventHasToBeSeeded) {
163  G4cout << " with initial seeds (" << s1 << "," << s2 << ")";
164  }
165  G4cout << "." << G4endl;
166  }
167 
168  return anEvent;
169 }
void DoEventLoop(G4int n_event, const char *macroFile=0, G4int n_select=-1) override
Run the event loop.
bool IsKilledAndToBeSimulatedAgain(const G4Event *ev)
Checks if the event has been killed and has to be re-simulated.
void HandleEventRngStateFile(int runID, int eventID)
Handles the read/write operations to/from the random generator state file for each event...
void DumpStatus(G4int eventID)
Prints the status of the random number generator.
void ProcessOneEvent(G4int i_event) override
Process a single event.
void BeginOfEventSimulation()
Reset the internal flags at the beginning of event simulation.
void BeginOfEventProcessing()
Method for storing the random engine state and resetting the internal flags at the beginning event ge...