Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/src/G4WorkerRunManager.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /run/src/G4WorkerRunManager.cc (Version 11.3.0) and /run/src/G4WorkerRunManager.cc (Version 10.3.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4WorkerRunManager implementation           << 
 27 //                                                 26 //
 28 // Original authors: X.Dong, A.Dotti - 2013    << 
 29 // ------------------------------------------- << 
 30                                                    27 
 31 #include "G4WorkerRunManager.hh"                   28 #include "G4WorkerRunManager.hh"
 32                                                <<  29 #include "G4WorkerRunManagerKernel.hh"
 33 #include "G4AutoLock.hh"                       <<  30 #include "G4UImanager.hh"
 34 #include "G4CopyRandomState.hh"                <<  31 #include "G4VUserDetectorConstruction.hh"
 35 #include "G4MTRunManager.hh"                       32 #include "G4MTRunManager.hh"
 36 #include "G4ParallelWorldProcess.hh"           << 
 37 #include "G4ParallelWorldProcessStore.hh"      << 
 38 #include "G4RNGHelper.hh"                      << 
 39 #include "G4Run.hh"                            << 
 40 #include "G4SDManager.hh"                      << 
 41 #include "G4ScoringManager.hh"                     33 #include "G4ScoringManager.hh"
 42 #include "G4Timer.hh"                          << 
 43 #include "G4TransportationManager.hh"              34 #include "G4TransportationManager.hh"
 44 #include "G4UImanager.hh"                      <<  35 #include "G4ParallelWorldProcess.hh"
 45 #include "G4UserRunAction.hh"                  <<  36 #include "G4WorkerThread.hh"
                                                   >>  37 #include "G4VUserPhysicsList.hh"
                                                   >>  38 #include "G4VUserActionInitialization.hh"
 46 #include "G4UserWorkerInitialization.hh"           39 #include "G4UserWorkerInitialization.hh"
 47 #include "G4UserWorkerThreadInitialization.hh"     40 #include "G4UserWorkerThreadInitialization.hh"
 48 #include "G4VScoreNtupleWriter.hh"             <<  41 #include "G4UserRunAction.hh"
 49 #include "G4VScoringMesh.hh"                   <<  42 #include "G4RNGHelper.hh"
 50 #include "G4VUserActionInitialization.hh"      <<  43 #include "G4Run.hh"
 51 #include "G4VUserDetectorConstruction.hh"      << 
 52 #include "G4VUserPhysicsList.hh"               << 
 53 #include "G4VUserPrimaryGeneratorAction.hh"        44 #include "G4VUserPrimaryGeneratorAction.hh"
 54 #include "G4VVisManager.hh"                        45 #include "G4VVisManager.hh"
 55 #include "G4WorkerRunManagerKernel.hh"         <<  46 #include "G4SDManager.hh"
 56 #include "G4WorkerThread.hh"                   <<  47 #include "G4VScoringMesh.hh"
 57                                                <<  48 #include "G4Timer.hh"
 58 #include "G4GeometryManager.hh"   // For paral << 
 59                                                << 
 60 #include <fstream>                             << 
 61 #include <sstream>                                 49 #include <sstream>
                                                   >>  50 #include <fstream>
 62                                                    51 
 63 // ------------------------------------------- << 
 64 G4WorkerRunManager* G4WorkerRunManager::GetWor     52 G4WorkerRunManager* G4WorkerRunManager::GetWorkerRunManager()
 65 {                                              <<  53 { return static_cast<G4WorkerRunManager*>(G4RunManager::GetRunManager()); }
 66   return static_cast<G4WorkerRunManager*>(G4Ru << 
 67 }                                              << 
 68                                                    54 
 69 // ------------------------------------------- << 
 70 G4WorkerRunManagerKernel* G4WorkerRunManager::     55 G4WorkerRunManagerKernel* G4WorkerRunManager::GetWorkerRunManagerKernel()
 71 {                                              <<  56 { return static_cast<G4WorkerRunManagerKernel*>(GetWorkerRunManager()->kernel); }
 72   return static_cast<G4WorkerRunManagerKernel* << 
 73 }                                              << 
 74                                                << 
 75 // ------------------------------------------- << 
 76 G4WorkerRunManager::G4WorkerRunManager() : G4R << 
 77 {                                              << 
 78   // This constructor should never be called i << 
 79                                                    57 
                                                   >>  58 G4WorkerRunManager::G4WorkerRunManager() : G4RunManager(workerRM) {
                                                   >>  59     //This constructor should never be called in non-multithreaded mode
 80 #ifndef G4MULTITHREADED                            60 #ifndef G4MULTITHREADED
 81   G4ExceptionDescription msg;                  <<  61     G4ExceptionDescription msg;
 82   msg << "Geant4 code is compiled without mult <<  62     msg<<"Geant4 code is compiled without multi-threading support (-DG4MULTITHREADED is set to off).";
 83          "(-DG4MULTITHREADED "                 <<  63     msg<<" This type of RunManager can only be used in mult-threaded applications.";
 84          "is set to off).";                    <<  64     G4Exception("G4WorkerRunManager::G4WorkerRunManager()","Run0103",FatalException,msg);
 85   msg << " This type of RunManager can only be << 
 86          "applications.";                      << 
 87   G4Exception("G4WorkerRunManager::G4WorkerRun << 
 88 #endif                                             65 #endif
 89   // G4ParticleTable::GetParticleTable()->Work <<  66     G4ParticleTable::GetParticleTable()->WorkerG4ParticleTable();
 90      // WorkerG4ParticleTable() would be perfo <<  67     G4ScoringManager* masterScM = G4MTRunManager::GetMasterScoringManager();
 91      // as it is called already from G4Particl <<  68     if(masterScM) G4ScoringManager::GetScoringManager(); //TLS instance for a worker
 92      // which is called beforehand by other Ge <<  69 
 93   G4ScoringManager* masterScM = G4MTRunManager <<  70     eventLoopOnGoing = false;
 94   if (masterScM != nullptr) G4ScoringManager:: <<  71     runIsSeeded = false;
 95                                                <<  72     nevModulo = -1;
 96   // Properly initialise luxury level for Ranl <<  73     currEvID = -1;
 97   //                                           <<  74     workerContext = 0;
 98   if (dynamic_cast<const CLHEP::Ranlux64Engine <<  75     readStatusFromFile = false;
 99     const auto theEngine = dynamic_cast<const  << 
100     luxury = theEngine->getLuxury();           << 
101   }                                            << 
102   else if (dynamic_cast<const CLHEP::RanluxEng << 
103     const auto theEngine = dynamic_cast<const  << 
104     luxury = theEngine->getLuxury();           << 
105   }                                            << 
106                                                    76 
107   G4UImanager::GetUIpointer()->SetIgnoreCmdNot <<  77     G4UImanager::GetUIpointer()->SetIgnoreCmdNotFound(true);
108                                                    78 
109 #ifdef G4MULTITHREADED                             79 #ifdef G4MULTITHREADED
110   G4VVisManager* pVVis = G4VVisManager::GetCon <<  80     G4VVisManager* pVVis = G4VVisManager::GetConcreteInstance();
111   if (pVVis != nullptr) {                      <<  81     if(pVVis)
112     pVVis->SetUpForAThread();                  <<  82     {
113     visIsSetUp = true;                         <<  83       pVVis->SetUpForAThread();
114   }                                            <<  84       visIsSetUp = true;
                                                   >>  85     }
                                                   >>  86     else
                                                   >>  87     { visIsSetUp = false; }
115 #endif                                             88 #endif
116 }                                                  89 }
117                                                    90 
118 // ------------------------------------------- <<  91 #include "G4MTRunManager.hh"
119 G4WorkerRunManager::~G4WorkerRunManager()      <<  92 
120 {                                              <<  93 G4WorkerRunManager::~G4WorkerRunManager() {
121   CleanUpPreviousEvents();                     <<  94     // Delete thread-local process manager objects
122   // Put these pointers to zero: owned by mast <<  95     physicsList->RemoveProcessManager();
123   // If not to zero, the base class destructor <<  96 
124   // delete them                               <<  97     //Put these pointers to zero: owned by master thread
125   userDetector = nullptr;                      <<  98     //If not to zero, the base class destructor will attempt to
126   userWorkerInitialization = nullptr;          <<  99     //delete them
127   userWorkerThreadInitialization = nullptr;    << 100     userDetector = 0;
128   userActionInitialization = nullptr;          << 101     userWorkerInitialization = 0;
129   physicsList->TerminateWorker();              << 102     userWorkerThreadInitialization = 0;
130   physicsList = nullptr;                       << 103     userActionInitialization = 0;
131   if (verboseLevel > 1) G4cout << "Destroying  << 104     physicsList = 0;
132 }                                              << 105     if(verboseLevel>0) G4cout<<"Destroying WorkerRunManager ("<<this<<")"<<G4endl;
133                                                << 
134 // ------------------------------------------- << 
135 void G4WorkerRunManager::InitializeGeometry()  << 
136 {                                              << 
137   if (userDetector == nullptr) {               << 
138     G4Exception("G4RunManager::InitializeGeome << 
139                 "G4VUserDetectorConstruction i << 
140     return;                                    << 
141   }                                            << 
142                                                << 
143   if (fGeometryHasBeenDestroyed) {             << 
144     G4TransportationManager::GetTransportation << 
145   }                                            << 
146                                                << 
147   // Step 0: Contribute to the voxelisation of << 
148   G4GeometryManager* geomManager = G4GeometryM << 
149   if( geomManager->IsParallelOptimisationConfi << 
150     G4cout << "G4RunManager::InitializeGeometr << 
151            << G4endl;  // TODO - suppress / de << 
152     geomManager->UndertakeOptimisation();      << 
153   }                                            << 
154   //  A barrier must ensure that all that all  << 
155   //  Currently we rely on the (later) barrier << 
156                                                << 
157   // Step1: Get pointer to the physiWorld (not << 
158   // pointer, i.e. the one shared by all threa << 
159   G4RunManagerKernel* masterKernel = G4MTRunMa << 
160   G4VPhysicalVolume* worldVol = masterKernel-> << 
161   // Step2:, Call a new "WorkerDefineWorldVolu << 
162   kernel->WorkerDefineWorldVolume(worldVol, fa << 
163   kernel->SetNumberOfParallelWorld(masterKerne << 
164   // Step3: Call user's ConstructSDandField()  << 
165   userDetector->ConstructSDandField();         << 
166   userDetector->ConstructParallelSD();         << 
167   geometryInitialized = true;                  << 
168 }                                                 106 }
169                                                   107 
170 // ------------------------------------------- << 108 
                                                   >> 109 void G4WorkerRunManager::InitializeGeometry() {
                                                   >> 110     if(!userDetector)
                                                   >> 111     {
                                                   >> 112         G4Exception("G4RunManager::InitializeGeometry", "Run0033",
                                                   >> 113                     FatalException, "G4VUserDetectorConstruction is not defined!");
                                                   >> 114         return;
                                                   >> 115     }
                                                   >> 116     if(fGeometryHasBeenDestroyed) 
                                                   >> 117     { G4TransportationManager::GetTransportationManager()->ClearParallelWorlds(); }
                                                   >> 118 
                                                   >> 119     //Step1: Get pointer to the physiWorld (note: needs to get the "super pointer, i.e. the one shared by all threads"
                                                   >> 120     G4RunManagerKernel* masterKernel = G4MTRunManager::GetMasterRunManagerKernel();
                                                   >> 121     G4VPhysicalVolume* worldVol = masterKernel->GetCurrentWorld();
                                                   >> 122     //Step2:, Call a new "WorkerDefineWorldVolume( pointer from 2-, false); 
                                                   >> 123     kernel->WorkerDefineWorldVolume(worldVol,false);
                                                   >> 124     kernel->SetNumberOfParallelWorld(masterKernel->GetNumberOfParallelWorld());
                                                   >> 125     //Step3: Call user's ConstructSDandField()
                                                   >> 126     userDetector->ConstructSDandField();
                                                   >> 127     userDetector->ConstructParallelSD();
                                                   >> 128     geometryInitialized = true;
                                                   >> 129 }
                                                   >> 130 
                                                   >> 131 #include "G4ParallelWorldProcessStore.hh"
                                                   >> 132 
171 void G4WorkerRunManager::RunInitialization()      133 void G4WorkerRunManager::RunInitialization()
172 {                                                 134 {
173 #ifdef G4MULTITHREADED                            135 #ifdef G4MULTITHREADED
174   if (!visIsSetUp) {                           << 136   if(!visIsSetUp)
                                                   >> 137   {
175     G4VVisManager* pVVis = G4VVisManager::GetC    138     G4VVisManager* pVVis = G4VVisManager::GetConcreteInstance();
176     if (pVVis != nullptr) {                    << 139     if(pVVis)
                                                   >> 140     {
177       pVVis->SetUpForAThread();                   141       pVVis->SetUpForAThread();
178       visIsSetUp = true;                          142       visIsSetUp = true;
179     }                                             143     }
180   }                                               144   }
181 #endif                                            145 #endif
182                                                   146 
183   if (!(kernel->RunInitialization(fakeRun))) r << 147   if(!(kernel->RunInitialization(fakeRun))) return;
184                                                   148 
185   // Signal this thread can start event loop.  << 149   //Signal this thread can start event loop.
186   // Note this will return only when all threa << 150   //Note this will return only when all threads reach this point
187   G4MTRunManager::GetMasterRunManager()->ThisW    151   G4MTRunManager::GetMasterRunManager()->ThisWorkerReady();
188   if (fakeRun) return;                         << 152   if(fakeRun) return;
189                                                   153 
190   const G4UserWorkerInitialization* uwi =      << 154   const G4UserWorkerInitialization* uwi
191     G4MTRunManager::GetMasterRunManager()->Get << 155        = G4MTRunManager::GetMasterRunManager()->GetUserWorkerInitialization();
192   CleanUpPreviousEvents();                        156   CleanUpPreviousEvents();
193   delete currentRun;                           << 157   if(currentRun) delete currentRun;
194   currentRun = nullptr;                        << 158   currentRun = 0;
195                                                   159 
196   if (fGeometryHasBeenDestroyed) G4ParallelWor << 160   if(fGeometryHasBeenDestroyed) G4ParallelWorldProcessStore::GetInstance()->UpdateWorlds();
197   // Call a user hook: this is guaranteed all  << 161   //Call a user hook: this is guaranteed all threads are "synchronized"
198   if (uwi != nullptr) uwi->WorkerRunStart();   << 162   if(uwi) uwi->WorkerRunStart();
199                                                   163 
200   if (userRunAction != nullptr) currentRun = u << 164   if(userRunAction) currentRun = userRunAction->GenerateRun();
201   if (currentRun == nullptr) currentRun = new  << 165   if(!currentRun) currentRun = new G4Run();
202                                                   166 
203   currentRun->SetRunID(runIDCounter);             167   currentRun->SetRunID(runIDCounter);
204   currentRun->SetNumberOfEventToBeProcessed(nu    168   currentRun->SetNumberOfEventToBeProcessed(numberOfEventToBeProcessed);
205                                                   169 
206   currentRun->SetDCtable(DCtable);                170   currentRun->SetDCtable(DCtable);
207   G4SDManager* fSDM = G4SDManager::GetSDMpoint    171   G4SDManager* fSDM = G4SDManager::GetSDMpointerIfExist();
208   if (fSDM != nullptr) {                       << 172   if(fSDM)
209     currentRun->SetHCtable(fSDM->GetHCtable()) << 173   { currentRun->SetHCtable(fSDM->GetHCtable()); }
210   }                                            << 
211                                                << 
212   if (G4VScoreNtupleWriter::Instance() != null << 
213     auto hce = (fSDM != nullptr) ? fSDM->Prepa << 
214     isScoreNtupleWriter = G4VScoreNtupleWriter << 
215     delete hce;                                << 
216   }                                            << 
217                                                   174 
218   std::ostringstream oss;                         175   std::ostringstream oss;
219   G4Random::saveFullState(oss);                << 176     G4Random::saveFullState(oss);
220   randomNumberStatusForThisRun = oss.str();       177   randomNumberStatusForThisRun = oss.str();
221   currentRun->SetRandomNumberStatus(randomNumb    178   currentRun->SetRandomNumberStatus(randomNumberStatusForThisRun);
222                                                   179 
223   for (G4int i_prev = 0; i_prev < n_perviousEv << 180   for(G4int i_prev=0;i_prev<n_perviousEventsToBeStored;i_prev++)
224     previousEvents->push_back(nullptr);        << 181   { previousEvents->push_back((G4Event*)0); }
225   }                                            << 
226                                                   182 
227   if (printModulo > 0 || verboseLevel > 0) {   << 183   if(printModulo>0 || verboseLevel>0)
                                                   >> 184   {
228     G4cout << "### Run " << currentRun->GetRun    185     G4cout << "### Run " << currentRun->GetRunID() << " starts on worker thread "
229            << G4Threading::G4GetThreadId() <<     186            << G4Threading::G4GetThreadId() << "." << G4endl;
230   }                                               187   }
231   if (userRunAction != nullptr) userRunAction- << 188   if(userRunAction) userRunAction->BeginOfRunAction(currentRun);
232                                                   189 
233   if (isScoreNtupleWriter) {                   << 190   if(storeRandomNumberStatus) {
234     G4VScoreNtupleWriter::Instance()->OpenFile << 191       G4String fileN = "currentRun";
235   }                                            << 192       if ( rngStatusEventsFlag ) {
236                                                << 193           std::ostringstream os;
237   if (storeRandomNumberStatus) {               << 194           os << "run" << currentRun->GetRunID();
238     G4String fileN = "currentRun";             << 195           fileN = os.str();
239     if (rngStatusEventsFlag) {                 << 196       }
240       std::ostringstream os;                   << 197       StoreRNGStatus(fileN);
241       os << "run" << currentRun->GetRunID();   << 
242       fileN = os.str();                        << 
243     }                                          << 
244     StoreRNGStatus(fileN);                     << 
245   }                                               198   }
246                                                   199 
247   runAborted = false;                             200   runAborted = false;
248   numberOfEventProcessed = 0;                     201   numberOfEventProcessed = 0;
249 }                                                 202 }
250                                                   203 
251 // ------------------------------------------- << 204 void G4WorkerRunManager::DoEventLoop(G4int n_event, const char* macroFile , G4int n_select)
252 void G4WorkerRunManager::DoEventLoop(G4int n_e << 
253 {                                                 205 {
254   if (userPrimaryGeneratorAction == nullptr) { << 206     if(!userPrimaryGeneratorAction)
255     G4Exception("G4RunManager::GenerateEvent() << 207     {
                                                   >> 208       G4Exception("G4RunManager::GenerateEvent()", "Run0032", FatalException,
256                 "G4VUserPrimaryGeneratorAction    209                 "G4VUserPrimaryGeneratorAction is not defined!");
257   }                                            << 210     }
258                                                << 
259   // This is the same as in the sequential cas << 
260   // different                                 << 
261   InitializeEventLoop(n_event, macroFile, n_se << 
262                                                << 
263   // Reset random number seeds queue           << 
264   while (!seedsQueue.empty()) {                << 
265     seedsQueue.pop();                          << 
266   }                                            << 
267   // for each run, worker should receive at le << 
268   // seeds.                                    << 
269   runIsSeeded = false;                         << 
270                                                   211 
271   // Event loop                                << 212     //This is the same as in the sequential case, just the for-loop indexes are
272   eventLoopOnGoing = true;                     << 213     //different
273   ///////    G4int i_event = workerContext->Ge << 214     InitializeEventLoop(n_event,macroFile,n_select);
274   G4int i_event = -1;                          << 215 
275   nevModulo = -1;                              << 216     // Reset random number seeds queue
276   currEvID = -1;                               << 217     while(seedsQueue.size()>0)
                                                   >> 218     { seedsQueue.pop(); }
                                                   >> 219     // for each run, worker should receive at least one set of random number seeds.
                                                   >> 220     runIsSeeded = false; 
                                                   >> 221 
                                                   >> 222     // Event loop
                                                   >> 223     eventLoopOnGoing = true;
                                                   >> 224 ///////    G4int i_event = workerContext->GetThreadId();
                                                   >> 225     G4int i_event = -1;
                                                   >> 226     nevModulo = -1;
                                                   >> 227     currEvID = -1;
277                                                   228 
278   while (eventLoopOnGoing) {                   << 229     while(eventLoopOnGoing)
279     ProcessOneEvent(i_event);                  << 230     {
280     if (eventLoopOnGoing) {                    << 231       ProcessOneEvent(i_event);
281       TerminateOneEvent();                     << 232       if(eventLoopOnGoing)
282       if (runAborted) {                        << 233       {
283         eventLoopOnGoing = false;              << 234         TerminateOneEvent();
                                                   >> 235         if(runAborted)
                                                   >> 236         { eventLoopOnGoing = false; }
                                                   >> 237 //////        else
                                                   >> 238 //////        {
                                                   >> 239 //////          i_event += workerContext->GetNumberThreads();
                                                   >> 240 //////          eventLoopOnGoing = i_event<n_event;
                                                   >> 241 //////        }
284       }                                           242       }
285     }                                             243     }
286   }                                            << 244      
287                                                << 245     TerminateEventLoop();
288   TerminateEventLoop();                        << 
289 }                                                 246 }
290                                                   247 
291 // ------------------------------------------- << 
292 void G4WorkerRunManager::ProcessOneEvent(G4int    248 void G4WorkerRunManager::ProcessOneEvent(G4int i_event)
293 {                                                 249 {
294   currentEvent = GenerateEvent(i_event);          250   currentEvent = GenerateEvent(i_event);
295   if (eventLoopOnGoing) {                      << 251   if(eventLoopOnGoing)
                                                   >> 252   {  
296     eventManager->ProcessOneEvent(currentEvent    253     eventManager->ProcessOneEvent(currentEvent);
297     AnalyzeEvent(currentEvent);                   254     AnalyzeEvent(currentEvent);
298     UpdateScoring();                              255     UpdateScoring();
299     if (currentEvent->GetEventID() < n_select_ << 256     if(currentEvent->GetEventID()<n_select_msg) G4UImanager::GetUIpointer()->ApplyCommand(msgText);
300       G4UImanager::GetUIpointer()->ApplyComman << 
301   }                                               257   }
302 }                                                 258 }
303                                                   259 
304 // ------------------------------------------- << 
305 G4Event* G4WorkerRunManager::GenerateEvent(G4i    260 G4Event* G4WorkerRunManager::GenerateEvent(G4int i_event)
306 {                                                 261 {
307   auto anEvent = new G4Event(i_event);         << 262   G4Event* anEvent = new G4Event(i_event);
308   G4long s1 = 0;                               << 263   long s1 = 0;
309   G4long s2 = 0;                               << 264   long s2 = 0;
310   G4long s3 = 0;                               << 265   long s3 = 0;
311   G4bool eventHasToBeSeeded = true;               266   G4bool eventHasToBeSeeded = true;
312   if (G4MTRunManager::SeedOncePerCommunication << 267   if(G4MTRunManager::SeedOncePerCommunication()==1 && runIsSeeded)
313     eventHasToBeSeeded = false;                << 268   { eventHasToBeSeeded = false; }
314   }                                            << 
315                                                   269 
316   if (i_event < 0) {                           << 270   if(i_event<0)
                                                   >> 271   {
317     G4int nevM = G4MTRunManager::GetMasterRunM    272     G4int nevM = G4MTRunManager::GetMasterRunManager()->GetEventModulo();
318     if (nevM == 1) {                           << 273     if(nevM==1)
319       eventLoopOnGoing = G4MTRunManager::GetMa << 274     {
320                                                << 275       eventLoopOnGoing = G4MTRunManager::GetMasterRunManager()
                                                   >> 276                        ->SetUpAnEvent(anEvent,s1,s2,s3,eventHasToBeSeeded);
321       runIsSeeded = true;                         277       runIsSeeded = true;
322     }                                             278     }
323     else {                                     << 279     else
324       if (nevModulo <= 0) {                    << 280     {
325         G4int nevToDo = G4MTRunManager::GetMas << 281       if(nevModulo<=0)
326                                                << 282       {
327         if (nevToDo == 0) {                    << 283         G4int nevToDo = G4MTRunManager::GetMasterRunManager()
328           eventLoopOnGoing = false;            << 284                          ->SetUpNEvents(anEvent,&seedsQueue,eventHasToBeSeeded);
329         }                                      << 285         if(nevToDo==0)
330         else {                                 << 286         { eventLoopOnGoing = false; }
                                                   >> 287         else
                                                   >> 288         {
331           currEvID = anEvent->GetEventID();       289           currEvID = anEvent->GetEventID();
332           nevModulo = nevToDo - 1;                290           nevModulo = nevToDo - 1;
333         }                                         291         }
334       }                                           292       }
335       else {                                   << 293       else
336         if (G4MTRunManager::SeedOncePerCommuni << 294       {
                                                   >> 295         if(G4MTRunManager::SeedOncePerCommunication()>0) eventHasToBeSeeded = false;
337         anEvent->SetEventID(++currEvID);          296         anEvent->SetEventID(++currEvID);
338         --nevModulo;                           << 297         nevModulo--;
339       }                                           298       }
340       if (eventLoopOnGoing && eventHasToBeSeed << 299       if(eventLoopOnGoing && eventHasToBeSeeded)
341         s1 = seedsQueue.front();               << 300       {
342         seedsQueue.pop();                      << 301         s1 = seedsQueue.front(); seedsQueue.pop();
343         s2 = seedsQueue.front();               << 302         s2 = seedsQueue.front(); seedsQueue.pop();
344         seedsQueue.pop();                      << 
345       }                                           303       }
346     }                                             304     }
347                                                   305 
348     if (!eventLoopOnGoing) {                   << 306     if(!eventLoopOnGoing)
                                                   >> 307     {
349       delete anEvent;                             308       delete anEvent;
350       return nullptr;                          << 309       return 0;
351     }                                             310     }
352   }                                               311   }
353   else if (eventHasToBeSeeded) {               << 312   else if(eventHasToBeSeeded)
354     // Need to reseed random number generator  << 313   {
                                                   >> 314     //Need to reseed random number generator
355     G4RNGHelper* helper = G4RNGHelper::GetInst    315     G4RNGHelper* helper = G4RNGHelper::GetInstance();
356     s1 = helper->GetSeed(i_event * 2);         << 316     s1 = helper->GetSeed(i_event*2);
357     s2 = helper->GetSeed(i_event * 2 + 1);     << 317     s2 = helper->GetSeed(i_event*2+1);
358   }                                               318   }
359                                                   319 
360   if (eventHasToBeSeeded) {                    << 320   if(eventHasToBeSeeded) 
361     G4long seeds[3] = {s1, s2, 0};             << 321   {
362     G4Random::setTheSeeds(seeds, luxury);      << 322     long seeds[3] = { s1, s2, 0 };
                                                   >> 323     G4Random::setTheSeeds(seeds,-1);
363     runIsSeeded = true;                           324     runIsSeeded = true;
                                                   >> 325 ////G4cout<<"Event "<<currEvID<<" is seeded with { "<<s1<<", "<<s2<<" }"<<G4endl;
364   }                                               326   }
365                                                   327 
366   // Read from file seed.                      << 328   //Read from file seed.
367   // Andrea Dotti 4 November 2015              << 329   //Andrea Dotti 4 November 2015
368   // This is required for strong-reproducibili << 330   //This is required for strong-reproducibility, in MT mode we have that each
369   // thread produces, for each event a status  << 331   //thread produces, for each event a status file, we want to do that.
370   // Search a random file with the format run{ << 332   //Search a random file with the format run{%d}evt{%d}.rndm
371                                                   333 
372   // This is the filename base constructed fro << 334   //This is the filename base constructed from run and event
373   const auto filename = [&] {                     335   const auto filename = [&] {
374     std::ostringstream os;                     << 336     std::ostringstream os;
375     os << "run" << currentRun->GetRunID() << " << 337     os << "run"<<currentRun->GetRunID() << "evt" << anEvent->GetEventID();
376     return os.str();                           << 338     return os.str();
377   };                                              339   };
378                                                   340 
379   G4bool RNGstatusReadFromFile = false;           341   G4bool RNGstatusReadFromFile = false;
380   if (readStatusFromFile) {                    << 342  if ( readStatusFromFile ) {
381     // Build full path of RNG status file for  << 343    //Build full path of RNG status file for this event
382     std::ostringstream os;                     << 344    std::ostringstream os;
383     os << filename() << ".rndm";               << 345    os << filename() << ".rndm";
384     const G4String& randomStatusFile = os.str( << 346    const G4String& randomStatusFile = os.str();
385     std::ifstream ifile(randomStatusFile.c_str << 347    std::ifstream ifile(randomStatusFile.c_str());
386     if (ifile) {  // File valid and readable   << 348    if ( ifile ) { //File valid and readable
387       RNGstatusReadFromFile = true;            << 349      RNGstatusReadFromFile = true;
388       G4Random::restoreEngineStatus(randomStat << 350      G4Random::restoreEngineStatus(randomStatusFile.c_str());
389     }                                          << 351    }
390   }                                            << 352  }
391                                                   353 
392   if (storeRandomNumberStatusToG4Event == 1 || << 354 
                                                   >> 355   if(storeRandomNumberStatusToG4Event==1 || storeRandomNumberStatusToG4Event==3)
                                                   >> 356   {
393     std::ostringstream oss;                       357     std::ostringstream oss;
394     G4Random::saveFullState(oss);                 358     G4Random::saveFullState(oss);
395     randomNumberStatusForThisEvent = oss.str()    359     randomNumberStatusForThisEvent = oss.str();
396     anEvent->SetRandomNumberStatus(randomNumbe    360     anEvent->SetRandomNumberStatus(randomNumberStatusForThisEvent);
397   }                                               361   }
398                                                   362 
399   if (storeRandomNumberStatus && !RNGstatusRea << 363   if(storeRandomNumberStatus && ! RNGstatusReadFromFile ) { //If reading from file, avoid to rewrite the same
400   {  // If reading from file, avoid to rewrite << 364       G4String fileN = "currentEvent";
401     G4String fileN = "currentEvent";           << 365       if ( rngStatusEventsFlag ) {
402     if (rngStatusEventsFlag) {                 << 366         fileN = filename();
403       fileN = filename();                      << 367       }
404     }                                          << 368       StoreRNGStatus(fileN);
405     StoreRNGStatus(fileN);                     << 
406   }                                               369   }
407                                                   370 
408   if (printModulo > 0 && anEvent->GetEventID() << 371   if(printModulo > 0 && anEvent->GetEventID()%printModulo == 0 )
                                                   >> 372   {
409     G4cout << "--> Event " << anEvent->GetEven    373     G4cout << "--> Event " << anEvent->GetEventID() << " starts";
410     if (eventHasToBeSeeded) {                  << 374     if(eventHasToBeSeeded)
411       G4cout << " with initial seeds (" << s1  << 375     { G4cout << " with initial seeds (" << s1 << "," << s2 << ")"; }
412     }                                          << 
413     G4cout << "." << G4endl;                      376     G4cout << "." << G4endl;
414   }                                               377   }
415   userPrimaryGeneratorAction->GeneratePrimarie    378   userPrimaryGeneratorAction->GeneratePrimaries(anEvent);
416   return anEvent;                                 379   return anEvent;
417 }                                                 380 }
418                                                   381 
419 // ------------------------------------------- << 382 void G4WorkerRunManager::MergePartialResults()
420 void G4WorkerRunManager::MergePartialResults(G << 
421 {                                                 383 {
422   // Merge partial results into global run     << 384     //Merge partial results into global run
423   G4MTRunManager* mtRM = G4MTRunManager::GetMa << 385     G4MTRunManager* mtRM = G4MTRunManager::GetMasterRunManager();
424   G4ScoringManager* ScM = G4ScoringManager::Ge << 386     G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
425   if (ScM != nullptr) mtRM->MergeScores(ScM);  << 387     if(ScM) mtRM->MergeScores(ScM);
426 #ifdef G4VERBOSE                               << 388     mtRM->MergeRun(currentRun);
427   if(mergeEvents && verboseLevel>3) {          << 
428     auto eventVector = currentRun->GetEventVec << 
429     if(eventVector!=nullptr || !(eventVector-> << 
430       G4cout<<"G4WorkerRunManager::MergePartia << 
431             <<eventVector->size()<<" events."< << 
432     }                                          << 
433   }                                            << 
434 #endif                                         << 
435   if(mergeEvents) mtRM->MergeRun(currentRun);  << 
436 }                                                 389 }
437                                                   390 
438 // ------------------------------------------- << 
439 void G4WorkerRunManager::RunTermination()         391 void G4WorkerRunManager::RunTermination()
440 {                                                 392 {
441   if (!fakeRun) {                              << 393   if(!fakeRun)
                                                   >> 394   {
442     MergePartialResults();                        395     MergePartialResults();
443                                                << 396     
444     // Call a user hook: note this is before t << 397     //Call a user hook: note this is before the next barrier
445     // so threads execute this method asyncrho << 398     //so threads execute this method asyncrhonouzly
446     //(TerminateRun allows for synch via G4Run    399     //(TerminateRun allows for synch via G4RunAction::EndOfRun)
447     const G4UserWorkerInitialization* uwi =    << 400     const G4UserWorkerInitialization* uwi
448       G4MTRunManager::GetMasterRunManager()->G << 401        = G4MTRunManager::GetMasterRunManager()->GetUserWorkerInitialization();
449     if (uwi != nullptr) uwi->WorkerRunEnd();   << 402     if(uwi) uwi->WorkerRunEnd();
450   }                                               403   }
451                                                   404 
452   G4RunManager::RunTermination();                 405   G4RunManager::RunTermination();
453   // Signal this thread has finished envent-lo << 406   //Signal this thread has finished envent-loop.
454   // Note this will return only whan all threa << 407   //Note this will return only whan all threads reach this point
455   G4MTRunManager::GetMasterRunManager()->ThisW    408   G4MTRunManager::GetMasterRunManager()->ThisWorkerEndEventLoop();
                                                   >> 409 
456 }                                                 410 }
457                                                   411 
458 // ------------------------------------------- << 
459 void G4WorkerRunManager::TerminateEventLoop()     412 void G4WorkerRunManager::TerminateEventLoop()
460 {                                                 413 {
461   if (verboseLevel > 0 && !fakeRun) {          << 414     if(verboseLevel>0 && !fakeRun)
462     timer->Stop();                             << 415     {
463     G4cout << "Thread-local run terminated." < << 416         timer->Stop();
464     G4cout << "Run Summary" << G4endl;         << 417         G4cout << "Thread-local run terminated." << G4endl;
465     if (runAborted) {                          << 418         G4cout << "Run Summary" << G4endl;
466       G4cout << "  Run Aborted after " << numb << 419         if(runAborted)
467     }                                          << 420         { G4cout << "  Run Aborted after " << numberOfEventProcessed << " events processed." << G4endl; }
468     else {                                     << 421         else
469       G4cout << "  Number of events processed  << 422         { G4cout << "  Number of events processed : " << numberOfEventProcessed << G4endl; }
                                                   >> 423         G4cout << "  "  << *timer << G4endl;
470     }                                             424     }
471     G4cout << "  " << *timer << G4endl;        << 
472   }                                            << 
473 }                                                 425 }
474                                                   426 
475 // ------------------------------------------- << 427 /****************************
476 namespace                                      << 428 void G4WorkerRunManager::BeamOn(G4int n_event,const char* macroFile,G4int n_select)
477 {                                              << 429 { 
478 G4Mutex ConstructScoringWorldsMutex = G4MUTEX_ << 430   if(n_event>0) 
                                                   >> 431   { G4RunManager::BeamOn(n_event,macroFile,n_select); }
                                                   >> 432   else
                                                   >> 433   {
                                                   >> 434     // fake BeamOn.
                                                   >> 435     G4MTRunManager::GetMasterRunManager()->ThisWorkerReady();
                                                   >> 436     G4MTRunManager::GetMasterRunManager()->ThisWorkerEndEventLoop();
                                                   >> 437   }
479 }                                                 438 }
                                                   >> 439 ******************************/
480                                                   440 
481 // ------------------------------------------- << 441 #include "G4AutoLock.hh"
                                                   >> 442 namespace { G4Mutex ConstructScoringWorldsMutex = G4MUTEX_INITIALIZER; }
482 void G4WorkerRunManager::ConstructScoringWorld    443 void G4WorkerRunManager::ConstructScoringWorlds()
483 {                                                 444 {
484   using MeshShape = G4VScoringMesh::MeshShape; << 445     // Return if unnecessary
485                                                << 446     G4ScoringManager* ScM = G4ScoringManager::GetScoringManagerIfExist();
486   // Return if unnecessary                     << 447     if(!ScM) return;
487   G4ScoringManager* ScM = G4ScoringManager::Ge << 448     G4int nPar = ScM->GetNumberOfMesh();
488   if (ScM == nullptr) return;                  << 449     if(nPar<1) return;
489   auto nPar = (G4int)ScM->GetNumberOfMesh();   << 450 
490   if (nPar < 1) return;                        << 451     // Update thread-local G4TransportationManager of all the world volumes
491                                                << 452     kernel->WorkerUpdateWorldVolume();
492   // Update thread-local G4TransportationManag << 453 
493   kernel->WorkerUpdateWorldVolume();           << 454     G4ScoringManager* masterScM = G4MTRunManager::GetMasterScoringManager();
494                                                << 455     assert( masterScM != NULL );
495   G4ScoringManager* masterScM = G4MTRunManager << 456     
496                                                << 457     G4ParticleTable::G4PTblDicIterator* particleIterator
497   auto particleIterator = G4ParticleTable::Get << 458      = G4ParticleTable::GetParticleTable()->GetIterator();
498                                                << 459     
499   for (G4int iw = 0; iw < nPar; ++iw) {        << 460     for(G4int iw=0;iw<nPar;iw++)
500     G4VScoringMesh* mesh = ScM->GetMesh(iw);   << 461     {
501     if (fGeometryHasBeenDestroyed) mesh->Geome << 462       G4VScoringMesh* mesh = ScM->GetMesh(iw);
502     G4VPhysicalVolume* pWorld = nullptr;       << 463       if(fGeometryHasBeenDestroyed) mesh->GeometryHasBeenDestroyed();
503     if (mesh->GetShape() != MeshShape::realWor << 464       G4VPhysicalVolume* pWorld
504       pWorld =                                 << 465        = G4TransportationManager::GetTransportationManager()
505         G4TransportationManager::GetTransporta << 466          ->IsWorldExisting(ScM->GetWorldName(iw));
506       if (pWorld == nullptr) {                 << 467       if(!pWorld)
                                                   >> 468       {
507         G4ExceptionDescription ed;                469         G4ExceptionDescription ed;
508         ed << "Mesh name <" << ScM->GetWorldNa << 470         ed<<"Mesh name <"<<ScM->GetWorldName(iw)<<"> is not found in the master thread.";
509         G4Exception("G4WorkerRunManager::Const << 471         G4Exception("G4WorkerRunManager::ConstructScoringWorlds()","RUN79001",
510       }                                        << 472                       FatalException,ed);
511     }                                          << 473       }
512     if ((mesh->GetMeshElementLogical()) == nul << 474       if(!(mesh->GetMeshElementLogical()))
513       G4AutoLock l(&ConstructScoringWorldsMute << 475       {
514       G4VScoringMesh* masterMesh = masterScM-> << 476         G4AutoLock l(&ConstructScoringWorldsMutex);
515       mesh->SetMeshElementLogical(masterMesh-> << 477         G4VScoringMesh* masterMesh = masterScM->GetMesh(iw);
516       l.unlock();                              << 478         mesh->SetMeshElementLogical(masterMesh->GetMeshElementLogical());
517                                                << 479         l.unlock();
518       if (mesh->GetShape() != MeshShape::realW << 480         
519         G4ParallelWorldProcess* theParallelWor    481         G4ParallelWorldProcess* theParallelWorldProcess = mesh->GetParallelWorldProcess();
520         if (theParallelWorldProcess != nullptr << 482         if(theParallelWorldProcess)
521           theParallelWorldProcess->SetParallel << 483         { theParallelWorldProcess->SetParallelWorld(ScM->GetWorldName(iw)); }
522         }                                      << 484         else
523         else {                                 << 485         {
524           theParallelWorldProcess = new G4Para    486           theParallelWorldProcess = new G4ParallelWorldProcess(ScM->GetWorldName(iw));
525           mesh->SetParallelWorldProcess(thePar    487           mesh->SetParallelWorldProcess(theParallelWorldProcess);
526           theParallelWorldProcess->SetParallel    488           theParallelWorldProcess->SetParallelWorld(ScM->GetWorldName(iw));
527                                                   489 
528           particleIterator->reset();              490           particleIterator->reset();
529           while ((*particleIterator)()) {      << 491           while( (*particleIterator)() ){
530             G4ParticleDefinition* particle = p    492             G4ParticleDefinition* particle = particleIterator->value();
531             G4ProcessManager* pmanager = parti    493             G4ProcessManager* pmanager = particle->GetProcessManager();
532             if (pmanager != nullptr) {         << 494             if(pmanager)
                                                   >> 495             {
533               pmanager->AddProcess(theParallel    496               pmanager->AddProcess(theParallelWorldProcess);
534               if (theParallelWorldProcess->IsA << 497               if(theParallelWorldProcess->IsAtRestRequired(particle))
535                 pmanager->SetProcessOrdering(t << 498               { pmanager->SetProcessOrdering(theParallelWorldProcess, idxAtRest, 9900); }
536               }                                << 
537               pmanager->SetProcessOrderingToSe    499               pmanager->SetProcessOrderingToSecond(theParallelWorldProcess, idxAlongStep);
538               pmanager->SetProcessOrdering(the    500               pmanager->SetProcessOrdering(theParallelWorldProcess, idxPostStep, 9900);
539             }  // if(pmanager)                 << 501             } //if(pmanager)
540           }  // while                          << 502           }//while
541         }                                         503         }
542         theParallelWorldProcess->SetLayeredMat << 
543       }                                           504       }
                                                   >> 505       mesh->WorkerConstruct(pWorld);
544     }                                             506     }
545     mesh->WorkerConstruct(pWorld);             << 
546   }                                            << 
547 }                                                 507 }
548                                                   508 
549 // ------------------------------------------- << 
550 void G4WorkerRunManager::SetUserInitialization    509 void G4WorkerRunManager::SetUserInitialization(G4UserWorkerInitialization*)
551 {                                                 510 {
552   G4Exception("G4RunManager::SetUserInitializa << 511     G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerInitialization*)", "Run0118",
553               FatalException, "This method sho << 512                 FatalException, "This method should be used only with an instance of G4MTRunManager");
554 }                                                 513 }
555                                                   514 
556 // ------------------------------------------- << 
557 void G4WorkerRunManager::SetUserInitialization    515 void G4WorkerRunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)
558 {                                                 516 {
559   G4Exception("G4RunManager::SetUserInitializa << 517     G4Exception("G4RunManager::SetUserInitialization(G4UserWorkerThreadInitialization*)", "Run0119",
560               FatalException, "This method sho << 518                 FatalException, "This method should be used only with an instance of G4MTRunManager");
561 }                                                 519 }
562                                                   520 
563 // ------------------------------------------- << 
564 void G4WorkerRunManager::SetUserInitialization    521 void G4WorkerRunManager::SetUserInitialization(G4VUserActionInitialization*)
565 {                                                 522 {
566   G4Exception("G4RunManager::SetUserInitializa << 523     G4Exception("G4RunManager::SetUserInitialization(G4VUserActionInitialization*)", "Run0120",
567               FatalException, "This method sho << 524                 FatalException, "This method should be used only with an instance of G4MTRunManager");
568 }                                                 525 }
569                                                   526 
570 // ------------------------------------------- << 
571 void G4WorkerRunManager::SetUserInitialization    527 void G4WorkerRunManager::SetUserInitialization(G4VUserDetectorConstruction*)
572 {                                                 528 {
573   G4Exception("G4RunManager::SetUserInitializa << 529     G4Exception("G4RunManager::SetUserInitialization(G4VUserDetectorConstruction*)", "Run0121",
574               FatalException, "This method sho << 530                 FatalException, "This method should be used only with an instance of G4MTRunManager");
575 }                                                 531 }
576                                                   532 
577 // ------------------------------------------- << 
578 void G4WorkerRunManager::SetUserInitialization    533 void G4WorkerRunManager::SetUserInitialization(G4VUserPhysicsList* pl)
579 {                                                 534 {
580   pl->InitializeWorker();                      << 535     pl->InitializeWorker();
581   G4RunManager::SetUserInitialization(pl);     << 536     G4RunManager::SetUserInitialization(pl);
582 }                                                 537 }
583                                                   538 
584 // ------------------------------------------- << 
585 void G4WorkerRunManager::SetUserAction(G4UserR    539 void G4WorkerRunManager::SetUserAction(G4UserRunAction* userAction)
586 {                                                 540 {
587   G4RunManager::SetUserAction(userAction);     << 541     G4RunManager::SetUserAction(userAction);
588   if (userAction != nullptr) userAction->SetMa << 542     userAction->SetMaster(false);
589 }                                                 543 }
590                                                   544 
591 // ------------------------------------------- << 
592 void G4WorkerRunManager::SetupDefaultRNGEngine    545 void G4WorkerRunManager::SetupDefaultRNGEngine()
593 {                                                 546 {
594   const CLHEP::HepRandomEngine* mrnge =        << 547     const CLHEP::HepRandomEngine* mrnge = G4MTRunManager::GetMasterRunManager()->getMasterRandomEngine();
595     G4MTRunManager::GetMasterRunManager()->get << 548     assert(mrnge);//Master has created RNG
596   const G4UserWorkerThreadInitialization* uwti << 549     const G4UserWorkerThreadInitialization* uwti
597     G4MTRunManager::GetMasterRunManager()->Get << 550       =G4MTRunManager::GetMasterRunManager()->GetUserWorkerThreadInitialization();
598   uwti->SetupRNGEngine(mrnge);                 << 551     uwti->SetupRNGEngine(mrnge);
599 }                                                 552 }
600                                                   553 
601 // Forward calls (avoid GCC compilation warnin << 
602                                                   554 
603 // ------------------------------------------- << 555 //Forward calls (avoid GCC compilation warnings)
604 void G4WorkerRunManager::SetUserAction(G4UserE    556 void G4WorkerRunManager::SetUserAction(G4UserEventAction* ua)
605 {                                                 557 {
606   G4RunManager::SetUserAction(ua);             << 558     G4RunManager::SetUserAction(ua);
607 }                                                 559 }
608                                                   560 
609 // ------------------------------------------- << 
610 void G4WorkerRunManager::SetUserAction(G4VUser    561 void G4WorkerRunManager::SetUserAction(G4VUserPrimaryGeneratorAction* ua)
611 {                                                 562 {
612   G4RunManager::SetUserAction(ua);             << 563     G4RunManager::SetUserAction(ua);
613 }                                                 564 }
614                                                   565 
615 // ------------------------------------------- << 
616 void G4WorkerRunManager::SetUserAction(G4UserS    566 void G4WorkerRunManager::SetUserAction(G4UserStackingAction* ua)
617 {                                                 567 {
618   G4RunManager::SetUserAction(ua);             << 568     G4RunManager::SetUserAction(ua);
619 }                                                 569 }
620                                                   570 
621 // ------------------------------------------- << 
622 void G4WorkerRunManager::SetUserAction(G4UserT    571 void G4WorkerRunManager::SetUserAction(G4UserTrackingAction* ua)
623 {                                                 572 {
624   G4RunManager::SetUserAction(ua);             << 573     G4RunManager::SetUserAction(ua);
625 }                                                 574 }
626                                                   575 
627 // ------------------------------------------- << 
628 void G4WorkerRunManager::SetUserAction(G4UserS    576 void G4WorkerRunManager::SetUserAction(G4UserSteppingAction* ua)
629 {                                                 577 {
630   G4RunManager::SetUserAction(ua);             << 578     G4RunManager::SetUserAction(ua);
631 }                                              << 
632                                                << 
633 // ------------------------------------------- << 
634 void G4WorkerRunManager::StoreRNGStatus(const  << 
635 {                                              << 
636   std::ostringstream os;                       << 
637   os << randomNumberStatusDir << "G4Worker" << << 
638   G4Random::saveEngineStatus(os.str().c_str()) << 
639 }                                              << 
640                                                << 
641 // ------------------------------------------- << 
642 void G4WorkerRunManager::rndmSaveThisRun()     << 
643 {                                              << 
644   G4int runNumber = 0;                         << 
645   if (currentRun != nullptr) runNumber = curre << 
646   if (!storeRandomNumberStatus) {              << 
647     G4cerr << "Warning from G4RunManager::rndm << 
648            << " Random number status was not s << 
649            << "/random/setSavingFlag command m << 
650            << "Command ignored." << G4endl;    << 
651     return;                                    << 
652   }                                            << 
653                                                << 
654   std::ostringstream oos;                      << 
655   oos << "G4Worker" << workerContext->GetThrea << 
656       << "currentRun.rndm"                     << 
657       << "\0";                                 << 
658   G4fs::path fileIn = randomNumberStatusDir +  << 
659                                                << 
660   std::ostringstream os;                       << 
661   os << "run" << runNumber << ".rndm" << '\0'; << 
662   G4fs::path fileOut = randomNumberStatusDir + << 
663                                                << 
664   if (G4CopyRandomState(fileIn, fileOut, "G4Wo << 
665       && verboseLevel > 0)                     << 
666   {                                            << 
667     G4cout << fileIn << " is copied to " << fi << 
668   }                                            << 
669 }                                                 579 }
670                                                   580 
671 // ------------------------------------------- << 581 void G4WorkerRunManager::StoreRNGStatus(const G4String& fn )
672 void G4WorkerRunManager::rndmSaveThisEvent()   << 
673 {                                                 582 {
674   if (currentEvent == nullptr) {               << 583     std::ostringstream os;
675     G4cerr << "Warning from G4RunManager::rndm << 584     os << randomNumberStatusDir << "G4Worker"<<workerContext->GetThreadId()<<"_"<<fn <<".rndm";
676            << " there is no currentEvent avail << 585     G4Random::saveEngineStatus(os.str().c_str());
677     return;                                    << 
678   }                                            << 
679                                                << 
680   if (!storeRandomNumberStatus) {              << 
681     G4cerr << "Warning from G4RunManager::rndm << 
682            << " Random number engine status is << 
683            << "/random/setSavingFlag command m << 
684            << "prior to the start of the run.  << 
685     return;                                    << 
686   }                                            << 
687                                                << 
688   std::ostringstream oos;                      << 
689   oos << "G4Worker" << workerContext->GetThrea << 
690       << "currentEvent.rndm"                   << 
691       << "\0";                                 << 
692   G4fs::path fileIn = randomNumberStatusDir +  << 
693                                                << 
694   std::ostringstream os;                       << 
695   os << "run" << currentRun->GetRunID() << "ev << 
696   G4fs::path fileOut = randomNumberStatusDir + << 
697                                                << 
698   if (G4CopyRandomState(fileIn, fileOut, "G4Wo << 
699       && verboseLevel > 0)                     << 
700   {                                            << 
701     G4cout << fileIn << " is copied to " << fi << 
702   }                                            << 
703 }                                                 586 }
704                                                   587 
705 // ------------------------------------------- << 
706 void G4WorkerRunManager::DoWork()                 588 void G4WorkerRunManager::DoWork()
707 {                                                 589 {
708   G4MTRunManager* mrm = G4MTRunManager::GetMas    590   G4MTRunManager* mrm = G4MTRunManager::GetMasterRunManager();
709   G4MTRunManager::WorkerActionRequest nextActi    591   G4MTRunManager::WorkerActionRequest nextAction = mrm->ThisWorkerWaitForNextAction();
710   while (nextAction != G4MTRunManager::WorkerA << 592   while( nextAction != G4MTRunManager::WorkerActionRequest::ENDWORKER )
711     if (nextAction == G4MTRunManager::WorkerAc << 593   {
712                                                << 594     if( nextAction == G4MTRunManager::WorkerActionRequest::NEXTITERATION ) // start the next run
713     {                                             595     {
714       // The following code deals with changin << 596       //The following code deals with changing materials between runs
715       static G4ThreadLocal G4bool skipInitiali    597       static G4ThreadLocal G4bool skipInitialization = true;
716       if (skipInitialization) {                << 598       if(skipInitialization)
                                                   >> 599       {
717         // re-initialization is not necessary     600         // re-initialization is not necessary for the first run
718         skipInitialization = false;               601         skipInitialization = false;
719       }                                           602       }
720       else {                                   << 603       else
721         //        ReinitializeGeometry();      << 604       {
722         workerContext->UpdateGeometryAndPhysic << 605 //        ReinitializeGeometry();
                                                   >> 606           workerContext->UpdateGeometryAndPhysicsVectorFromMaster();
723       }                                           607       }
724                                                   608 
725       // Execute UI commands stored in the mas    609       // Execute UI commands stored in the master UI manager
726       std::vector<G4String> cmds = mrm->GetCom    610       std::vector<G4String> cmds = mrm->GetCommandStack();
727       G4UImanager* uimgr = G4UImanager::GetUIp << 611       G4UImanager* uimgr = G4UImanager::GetUIpointer(); //TLS instance
728       for (const auto& cmd : cmds) {           << 612       std::vector<G4String>::const_iterator it = cmds.begin();
729         uimgr->ApplyCommand(cmd);              << 613       for(;it!=cmds.end();it++)
730       }                                        << 614       { uimgr->ApplyCommand(*it); }
731       // Start this run                        << 615       //Start this run
732       G4int numevents = mrm->GetNumberOfEvents    616       G4int numevents = mrm->GetNumberOfEventsToBeProcessed();
733       G4String macroFile = mrm->GetSelectMacro    617       G4String macroFile = mrm->GetSelectMacro();
734       G4int numSelect = mrm->GetNumberOfSelect    618       G4int numSelect = mrm->GetNumberOfSelectEvents();
735       if (macroFile.empty() || macroFile == "  << 619       if ( macroFile == "" || macroFile == " " )
736         this->BeamOn(numevents);               << 620       {
737       }                                        << 621           this->BeamOn(numevents);
738       else {                                   << 622       }
739         this->BeamOn(numevents, macroFile, num << 623       else
740       }                                        << 624       {
                                                   >> 625           this->BeamOn(numevents,macroFile,numSelect);
                                                   >> 626       }
                                                   >> 627     }
                                                   >> 628     else if (nextAction == G4MTRunManager::WorkerActionRequest::PROCESSUI ) {
                                                   >> 629         std::vector<G4String> cmds = mrm->GetCommandStack();
                                                   >> 630         G4UImanager* uimgr = G4UImanager::GetUIpointer(); //TLS instance
                                                   >> 631         std::vector<G4String>::const_iterator it = cmds.begin();
                                                   >> 632         for(;it!=cmds.end();it++)
                                                   >> 633         { uimgr->ApplyCommand(*it); }
                                                   >> 634         mrm->ThisWorkerProcessCommandsStackDone();
741     }                                             635     }
742     else if (nextAction == G4MTRunManager::Wor << 636     else
743       std::vector<G4String> cmds = mrm->GetCom << 637     {
744       G4UImanager* uimgr = G4UImanager::GetUIp << 
745       for (const auto& cmd : cmds) {           << 
746         uimgr->ApplyCommand(cmd);              << 
747       }                                        << 
748       mrm->ThisWorkerProcessCommandsStackDone( << 
749     }                                          << 
750     else {                                     << 
751       G4ExceptionDescription d;                   638       G4ExceptionDescription d;
752       d << "Cannot continue, this worker has b << 639       d<<"Cannot continue, this worker has been requested an unknwon action: "
753         << static_cast<std::underlying_type<G4 << 640        <<static_cast<std::underlying_type<G4MTRunManager::WorkerActionRequest>::type>(nextAction);
754       G4Exception("G4WorkerRunManager::DoWork" << 641       G4Exception("G4WorkerRunManager::DoWork","Run0104",FatalException,d);
755     }                                             642     }
756                                                   643 
757     // Now wait for master thread to signal ne << 644     //Now wait for master thread to signal new action to be performed
758     nextAction = mrm->ThisWorkerWaitForNextAct    645     nextAction = mrm->ThisWorkerWaitForNextAction();
759   }  // No more actions to perform             << 646   } //No more actions to perform
760                                                   647 
761   return;                                         648   return;
762 }                                                 649 }
763                                                   650