Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/src/G4RunMessenger.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 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // G4RunMessenger implementation
 27 //
 28 // Original author: M.Asai, 1997
 29 // --------------------------------------------------------------------
 30 
 31 #include "G4RunMessenger.hh"
 32 
 33 #include "G4MTRunManager.hh"
 34 #include "G4ProductionCutsTable.hh"
 35 #include "G4RunManager.hh"
 36 #include "G4Tokenizer.hh"
 37 #include "G4UIcmdWithABool.hh"
 38 #include "G4UIcmdWithAString.hh"
 39 #include "G4UIcmdWithAnInteger.hh"
 40 #include "G4UIcmdWithoutParameter.hh"
 41 #include "G4UIcommand.hh"
 42 #include "G4UIdirectory.hh"
 43 #include "G4UImanager.hh"
 44 #include "G4UIparameter.hh"
 45 #include "G4ios.hh"
 46 #include "Randomize.hh"
 47 
 48 #include <sstream>
 49 
 50 G4RunMessenger::G4RunMessenger(G4RunManager* runMgr) : runManager(runMgr)
 51 {
 52   runDirectory = new G4UIdirectory("/run/");
 53   runDirectory->SetGuidance("Run control commands.");
 54 
 55   initCmd = new G4UIcmdWithoutParameter("/run/initialize", this);
 56   initCmd->SetGuidance("Initialize G4 kernel.");
 57   initCmd->AvailableForStates(G4State_PreInit, G4State_Idle),
 58 
 59     beamOnCmd = new G4UIcommand("/run/beamOn", this);
 60   beamOnCmd->SetGuidance("Start a Run.");
 61   beamOnCmd->SetGuidance("If G4 kernel is not initialized, it will be initialized.");
 62   beamOnCmd->SetGuidance("Default number of events to be processed is 1.");
 63   beamOnCmd->SetGuidance("The second and third arguments can be used for");
 64   beamOnCmd->SetGuidance("executing a macro file at the end of each event.");
 65   beamOnCmd->SetGuidance("If the second argument, i.e. name of the macro");
 66   beamOnCmd->SetGuidance("file, is given but the third argument is not,");
 67   beamOnCmd->SetGuidance("the macro file will be executed for all of the");
 68   beamOnCmd->SetGuidance("event.");
 69   beamOnCmd->SetGuidance("If the third argument (nSelect) is given, the");
 70   beamOnCmd->SetGuidance("macro file will be executed only for the first");
 71   beamOnCmd->SetGuidance("nSelect events.");
 72   beamOnCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
 73   beamOnCmd->SetToBeBroadcasted(false);
 74   auto p1 = new G4UIparameter("numberOfEvent", 'i', true);
 75   p1->SetDefaultValue(1);
 76   p1->SetParameterRange("numberOfEvent >= 0");
 77   beamOnCmd->SetParameter(p1);
 78   auto p2 = new G4UIparameter("macroFile", 's', true);
 79   p2->SetDefaultValue("***NULL***");
 80   beamOnCmd->SetParameter(p2);
 81   auto p3 = new G4UIparameter("nSelect", 'i', true);
 82   p3->SetDefaultValue(-1);
 83   p3->SetParameterRange("nSelect>=-1");
 84   beamOnCmd->SetParameter(p3);
 85   // beamOnCmd->SetToBeBroadcasted(false);
 86 
 87   verboseCmd = new G4UIcmdWithAnInteger("/run/verbose", this);
 88   verboseCmd->SetGuidance("Set the Verbose level of G4RunManager.");
 89   verboseCmd->SetGuidance(" 0 : Silent (default)");
 90   verboseCmd->SetGuidance(" 1 : Display main topics");
 91   verboseCmd->SetGuidance(" 2 : Display main topics and run summary");
 92   verboseCmd->SetParameterName("level", true);
 93   verboseCmd->SetDefaultValue(0);
 94   verboseCmd->SetRange("level >=0 && level <=2");
 95 
 96   printProgCmd = new G4UIcmdWithAnInteger("/run/printProgress", this);
 97   printProgCmd->SetGuidance("Display begin_of_event information at given frequency.");
 98   printProgCmd->SetGuidance("If it is set to zero, only the begin_of_run is shown.");
 99   printProgCmd->SetGuidance("If it is set to -1, no print-out is shown.");
100   printProgCmd->SetParameterName("mod", true);
101   printProgCmd->SetDefaultValue(-1);
102   printProgCmd->SetRange("mod>=-1");
103 
104   nThreadsCmd = new G4UIcmdWithAnInteger("/run/numberOfThreads", this);
105   nThreadsCmd->SetGuidance("Set the number of threads to be used.");
106   nThreadsCmd->SetGuidance("This command works only in PreInit state.");
107   nThreadsCmd->SetGuidance("This command is valid only for multi-threaded mode.");
108   nThreadsCmd->SetGuidance("The command is ignored if it is issued in sequential mode.");
109   nThreadsCmd->SetParameterName("nThreads", true);
110   nThreadsCmd->SetDefaultValue(2);
111   nThreadsCmd->SetRange("nThreads >0");
112   nThreadsCmd->SetToBeBroadcasted(false);
113   nThreadsCmd->AvailableForStates(G4State_PreInit);
114 
115   maxThreadsCmd = new G4UIcmdWithoutParameter("/run/useMaximumLogicalCores", this);
116   maxThreadsCmd->SetGuidance(
117     "Set the number of threads to be the number of available logical cores.");
118   maxThreadsCmd->SetGuidance("This command works only in PreInit state.");
119   maxThreadsCmd->SetGuidance("This command is valid only for multi-threaded mode.");
120   maxThreadsCmd->SetGuidance("The command is ignored if it is issued in sequential mode.");
121   maxThreadsCmd->SetToBeBroadcasted(false);
122   maxThreadsCmd->AvailableForStates(G4State_PreInit);
123 
124   pinAffinityCmd = new G4UIcmdWithAnInteger("/run/pinAffinity", this);
125   pinAffinityCmd->SetGuidance(
126     "Locks each thread to a specific logical core. Workers "
127     "are locked in round robin to logical cores.");
128   pinAffinityCmd->SetGuidance("This command is valid only for multi-threaded mode.");
129   pinAffinityCmd->SetGuidance("This command works only in PreInit state.");
130   pinAffinityCmd->SetGuidance("This command is ignored if it is issued in sequential mode.");
131   pinAffinityCmd->SetGuidance(
132     "If a value n>0 is provided it starts setting affinity "
133     "from the n-th CPU (note: counting from 1).");
134   pinAffinityCmd->SetGuidance(
135     "E.g. /run/pinAffinity 3 locks first thread on "
136     "third logical CPU (number 2).");
137   pinAffinityCmd->SetGuidance("If a value n<0 is provided never locks on n-th CPU.");
138   pinAffinityCmd->SetParameterName("pinAffinity", true);
139   pinAffinityCmd->SetDefaultValue(1);
140   pinAffinityCmd->SetToBeBroadcasted(false);
141   pinAffinityCmd->SetRange("pinAffinity > 0 || pinAffinity < 0");
142   pinAffinityCmd->AvailableForStates(G4State_PreInit);
143 
144   evModCmd = new G4UIcommand("/run/eventModulo", this);
145   evModCmd->SetGuidance("Set the event modulo for dispatching events to worker threads");
146   evModCmd->SetGuidance("i.e. each worker thread is ordered to simulate N events and then");
147   evModCmd->SetGuidance("comes back to G4MTRunManager for next set.");
148   evModCmd->SetGuidance("If it is set to zero (default value), N is roughly given by this.");
149   evModCmd->SetGuidance("   N = int( sqrt( number_of_events / number_of_threads ) )");
150   evModCmd->SetGuidance("The value N may affect on the computing performance in particular");
151   evModCmd->SetGuidance("if N is too small compared to the total number of events.");
152   evModCmd->SetGuidance("The second parameter seedOnce specifies how frequently each worker");
153   evModCmd->SetGuidance("thread is seeded by the random number sequence centrally managed");
154   evModCmd->SetGuidance("by the master G4MTRunManager.");
155   evModCmd->SetGuidance(" - If seedOnce is set to 0 (default), seeds that are centrally managed");
156   evModCmd->SetGuidance("   by G4MTRunManager are set for every event of every worker thread.");
157   evModCmd->SetGuidance("   This option guarantees event reproducibility regardless of number");
158   evModCmd->SetGuidance("   of threads.");
159   evModCmd->SetGuidance(" - If seedOnce is set to 1, seeds are set only once for the first");
160   evModCmd->SetGuidance("   event of each run of each worker thread. Event reproducibility is");
161   evModCmd->SetGuidance("   guaranteed only if the same number of worker threads are used.");
162   evModCmd->SetGuidance("   On the other hand, this option offers better computing performance");
163   evModCmd->SetGuidance("   in particular for applications with relatively small primary");
164   evModCmd->SetGuidance("   particle energy and large number of events.");
165   evModCmd->SetGuidance(" - If seedOnce is set to 2, seeds are set only for the first event of");
166   evModCmd->SetGuidance("   group of N events. This option is reserved for the future use when");
167   evModCmd->SetGuidance("   Geant4 allows number of threads to be dynamically changed during an");
168   evModCmd->SetGuidance("   event loop.");
169   evModCmd->SetGuidance("This command is valid only for multi-threaded mode.");
170   evModCmd->SetGuidance("This command is ignored if it is issued in sequential mode.");
171   auto emp1 = new G4UIparameter("N", 'i', true);
172   emp1->SetDefaultValue(0);
173   emp1->SetParameterRange("N >= 0");
174   evModCmd->SetParameter(emp1);
175   auto emp2 = new G4UIparameter("seedOnce", 'i', true);
176   emp2->SetDefaultValue(0);
177   emp2->SetParameterRange("seedOnce >= 0 && seedOnce <=2");
178   evModCmd->SetParameter(emp2);
179   evModCmd->SetToBeBroadcasted(false);
180   evModCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
181 
182   dumpRegCmd = new G4UIcmdWithAString("/run/dumpRegion", this);
183   dumpRegCmd->SetGuidance("Dump region information.");
184   dumpRegCmd->SetGuidance("In case name of a region is not given, all regions will be displayed.");
185   dumpRegCmd->SetParameterName("regionName", true);
186   dumpRegCmd->SetDefaultValue("**ALL**");
187   dumpRegCmd->AvailableForStates(G4State_Idle);
188 
189   dumpCoupleCmd = new G4UIcmdWithoutParameter("/run/dumpCouples", this);
190   dumpCoupleCmd->SetGuidance("Dump material-cuts-couple information.");
191   dumpCoupleCmd->SetGuidance("Note that material-cuts-couple information is updated");
192   dumpCoupleCmd->SetGuidance("after BeamOn has started.");
193   dumpCoupleCmd->AvailableForStates(G4State_Idle);
194 
195   optCmd = new G4UIcmdWithABool("/run/optimizeGeometry", this);
196   optCmd->SetGuidance("Set the optimization flag for geometry.");
197   optCmd->SetGuidance("If it is set to TRUE, G4GeometryManager will optimize");
198   optCmd->SetGuidance("the geometry definitions.");
199   optCmd->SetGuidance("GEANT4 is initialized with this flag as TRUE.");
200   optCmd->SetParameterName("optimizeFlag", true);
201   optCmd->SetDefaultValue(true);
202   optCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
203 
204   brkBoECmd = new G4UIcmdWithABool("/run/breakAtBeginOfEvent", this);
205   brkBoECmd->SetGuidance("Set a break point at the beginning of every event.");
206   brkBoECmd->SetParameterName("flag", true);
207   brkBoECmd->SetDefaultValue(true);
208 
209   brkEoECmd = new G4UIcmdWithABool("/run/breakAtEndOfEvent", this);
210   brkEoECmd->SetGuidance("Set a break point at the end of every event.");
211   brkEoECmd->SetParameterName("flag", true);
212   brkEoECmd->SetDefaultValue(true);
213 
214   abortCmd = new G4UIcmdWithABool("/run/abort", this);
215   abortCmd->SetGuidance("Abort current run processing.");
216   abortCmd->SetGuidance(
217     "If softAbort is false (default), currently processing event "
218     "will be immediately aborted,");
219   abortCmd->SetGuidance(
220     "while softAbort is true, abortion occurs after "
221     "processing the current event.");
222   abortCmd->AvailableForStates(G4State_GeomClosed, G4State_EventProc);
223   abortCmd->SetParameterName("softAbort", true);
224   abortCmd->SetDefaultValue(false);
225 
226   abortEventCmd = new G4UIcmdWithoutParameter("/run/abortCurrentEvent", this);
227   abortEventCmd->SetGuidance("Abort currently processing event.");
228   abortEventCmd->AvailableForStates(G4State_EventProc);
229 
230   geomCmd = new G4UIcmdWithoutParameter("/run/geometryModified", this);
231   geomCmd->SetGuidance("Force geometry to be closed (re-voxellized) again.");
232   geomCmd->SetGuidance("This command must be applied if geometry has been modified");
233   geomCmd->SetGuidance(" after the first initialization (or BeamOn).");
234   geomCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
235 
236   geomRebCmd = new G4UIcmdWithABool("/run/reinitializeGeometry", this);
237   geomRebCmd->SetGuidance("Force geometry to be rebuilt once again.");
238   geomRebCmd->SetGuidance("This command must be applied if the user needs his/her");
239   geomRebCmd->SetGuidance(" detector construction to be reinvoked.");
240   geomRebCmd->SetGuidance("/run/geometryModified is automatically issued with this command.");
241   geomRebCmd->SetParameterName("destroyFirst", true);
242   geomRebCmd->SetDefaultValue(false);
243   geomRebCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
244 
245   physCmd = new G4UIcmdWithoutParameter("/run/physicsModified", this);
246   physCmd->SetGuidance("Force all physics tables recalculated again.");
247   physCmd->SetGuidance("This command must be applied");
248   physCmd->SetGuidance(" if physics process has been modified after the");
249   physCmd->SetGuidance(" first initialization (or BeamOn).");
250   physCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
251 
252   constScoreCmd = new G4UIcmdWithoutParameter("/run/constructScoringWorlds", this);
253   constScoreCmd->SetGuidance("Construct scoring parallel world(s) if defined.");
254   constScoreCmd->SetGuidance(
255     "This command is not mandatory, but automatically "
256     "called when a run starts.");
257   constScoreCmd->SetGuidance(
258     "But the user may use this to visualize the scoring "
259     "world(s) before a run to start.");
260   constScoreCmd->AvailableForStates(G4State_Idle);
261 
262   randomDirectory = new G4UIdirectory("/random/");
263   randomDirectory->SetGuidance("Random number status control commands.");
264 
265   seedCmd = new G4UIcmdWithAString("/random/setSeeds", this);
266   seedCmd->SetGuidance("Initialize the random number generator with integer seed stream.");
267   seedCmd->SetGuidance("Number of integers should be more than 1.");
268   seedCmd->SetGuidance(
269     "Actual number of integers to be used depends on the individual "
270     "random number engine.");
271 #ifdef G4MULTITHREADED
272   seedCmd->SetGuidance("This command sets the seeds for the master thread.");
273 #endif
274   seedCmd->SetParameterName("IntArray", false);
275   seedCmd->AvailableForStates(G4State_PreInit, G4State_Idle, G4State_GeomClosed);
276   seedCmd->SetToBeBroadcasted(false);
277 
278   randDirCmd = new G4UIcmdWithAString("/random/setDirectoryName", this);
279   randDirCmd->SetGuidance("Define the directory name of the rndm status files.");
280   randDirCmd->SetGuidance("Directory will be created if it does not exist.");
281   randDirCmd->SetParameterName("fileName", true);
282   randDirCmd->SetDefaultValue("./");
283   randDirCmd->AvailableForStates(G4State_PreInit, G4State_Idle, G4State_GeomClosed);
284 
285   savingFlagCmd = new G4UIcmdWithABool("/random/setSavingFlag", this);
286   savingFlagCmd->SetGuidance("The randomNumberStatus will be saved at :");
287   savingFlagCmd->SetGuidance(
288     "beginning of run (currentRun.rndm) and "
289     "beginning of event (currentEvent.rndm) ");
290   savingFlagCmd->SetParameterName("flag", true);
291   savingFlagCmd->SetDefaultValue(true);
292 
293   saveThisRunCmd = new G4UIcmdWithoutParameter("/random/saveThisRun", this);
294   saveThisRunCmd->SetGuidance("copy currentRun.rndm to runXXX.rndm");
295   saveThisRunCmd->AvailableForStates(G4State_Idle, G4State_GeomClosed, G4State_EventProc);
296 
297   saveThisEventCmd = new G4UIcmdWithoutParameter("/random/saveThisEvent", this);
298   saveThisEventCmd->SetGuidance("copy currentEvent.rndm to runXXXevtYYY.rndm");
299   saveThisEventCmd->AvailableForStates(G4State_EventProc);
300 
301   restoreRandCmd = new G4UIcmdWithAString("/random/resetEngineFrom", this);
302   restoreRandCmd->SetGuidance("Reset the status of the rndm engine from a file.");
303   restoreRandCmd->SetGuidance("See CLHEP manual for detail.");
304   restoreRandCmd->SetGuidance("The engine status must be stored beforehand.");
305   restoreRandCmd->SetGuidance(
306     "Directory of the status file should be set by"
307     " /random/setDirectoryName.");
308   restoreRandCmd->SetParameterName("fileName", true);
309   restoreRandCmd->SetDefaultValue("currentRun.rndm");
310   restoreRandCmd->AvailableForStates(G4State_PreInit, G4State_Idle, G4State_GeomClosed);
311   restoreRandCmd->SetToBeBroadcasted(false);
312 
313   restoreRandCmdMT = new G4UIcmdWithABool("/random/resetEngineFromEachEvent", this);
314   restoreRandCmdMT->SetGuidance("Reset the status of the rndm engine from a file at each event.");
315   restoreRandCmdMT->SetGuidance("Note that the file must follow the following naming convention:");
316   restoreRandCmdMT->SetGuidance(
317     "run{#1}evt{#2}.rndm ; where #1 is the run "
318     "number and #2 is the event number.");
319   restoreRandCmdMT->SetGuidance(
320     "For example to re-seed the first event of the first "
321     "run the file should be called run0evt0.rndm.");
322   restoreRandCmdMT->SetGuidance(
323     "If for a specific run/event the file is not found, "
324     "the standard re-seeding strategy is used.");
325   restoreRandCmdMT->SetGuidance(
326     "This command has meaning only in MT mode for "
327     "strong reproducibility studies.");
328   restoreRandCmdMT->SetGuidance(
329     "Directory of the status file should be set by"
330     " /random/setDirectoryName.");
331   restoreRandCmdMT->SetDefaultValue(false);
332   restoreRandCmdMT->AvailableForStates(G4State_PreInit, G4State_Idle, G4State_GeomClosed);
333 
334   saveEachEventCmd = new G4UIcmdWithABool("/random/saveEachEventFlag", this);
335   saveEachEventCmd->SetGuidance("Save random number status at beginning of each event.");
336   saveEachEventCmd->SetGuidance("File name contains run and event numbers: runXXXevtYYY.rndm");
337   saveEachEventCmd->SetParameterName("flag", true);
338   saveEachEventCmd->SetDefaultValue(true);
339 
340   randEvtCmd = new G4UIcmdWithAnInteger("/run/storeRndmStatToEvent", this);
341   randEvtCmd->SetGuidance("Flag to store rndm status to G4Event object.");
342   randEvtCmd->SetGuidance(" flag = 0 : not store (default)");
343   randEvtCmd->SetGuidance(" flag = 1 : status before primary particle generation is stored");
344   randEvtCmd->SetGuidance(
345     " flag = 2 : status before event processing (after primary "
346     "particle generation) is stored");
347   randEvtCmd->SetGuidance(" flag = 3 : both are stored");
348   randEvtCmd->SetGuidance(
349     "Note: Some performance overhead may be seen by storing rndm "
350     "status, in particular");
351   randEvtCmd->SetGuidance(
352     "for the case of simplest geometry and small number of tracks per event.");
353   randEvtCmd->SetParameterName("flag", true);
354   randEvtCmd->SetDefaultValue(0);
355   randEvtCmd->SetRange("flag>=0 && flag<=3");
356   randEvtCmd->AvailableForStates(G4State_PreInit, G4State_Idle);
357 
358   procUICmds = new G4UIcmdWithoutParameter("/run/workersProcessCmds", this);
359   procUICmds->SetToBeBroadcasted(false);
360   procUICmds->SetGuidance("Force workers to process current stack of UI commands.");
361   procUICmds->SetGuidance("This commands is meaningful only in MT mode.");
362   procUICmds->AvailableForStates(G4State_PreInit, G4State_Idle, G4State_GeomClosed);
363 }
364 
365 // --------------------------------------------------------------------
366 G4RunMessenger::~G4RunMessenger()
367 {
368   delete beamOnCmd;
369   delete verboseCmd;
370   delete printProgCmd;
371   delete nThreadsCmd;
372   delete maxThreadsCmd;
373   delete pinAffinityCmd;
374   delete evModCmd;
375   delete optCmd;
376   delete dumpRegCmd;
377   delete dumpCoupleCmd;
378   delete brkBoECmd;
379   delete brkEoECmd;
380   delete abortCmd;
381   delete abortEventCmd;
382   delete initCmd;
383   delete geomCmd;
384   delete geomRebCmd;
385   delete physCmd;
386   delete randEvtCmd;
387   delete constScoreCmd;
388   delete procUICmds;
389 
390   delete seedCmd;
391   delete savingFlagCmd;
392   delete saveThisRunCmd;
393   delete saveThisEventCmd;
394   delete restoreRandCmd;
395   delete randomDirectory;
396   delete saveEachEventCmd;
397 
398   delete randDirCmd;
399   delete runDirectory;
400 
401   delete restoreRandCmdMT;
402 }
403 
404 // --------------------------------------------------------------------
405 void G4RunMessenger::SetNewValue(G4UIcommand* command, G4String newValue)
406 {
407   if (command == beamOnCmd) {
408     G4int nev;
409     G4int nst;
410     const auto nv = (const char*)newValue;
411     std::istringstream is(nv);
412     is >> nev >> macroFileName >> nst;
413     if (macroFileName == "***NULL***") {
414       runManager->BeamOn(nev);
415     }
416     else {
417       runManager->BeamOn(nev, macroFileName, nst);
418     }
419   }
420   else if (command == verboseCmd) {
421     runManager->SetVerboseLevel(verboseCmd->GetNewIntValue(newValue));
422   }
423   else if (command == printProgCmd) {
424     runManager->SetPrintProgress(printProgCmd->GetNewIntValue(newValue));
425   }
426   else if (command == nThreadsCmd) {
427     G4RunManager::RMType rmType = runManager->GetRunManagerType();
428     if (rmType == G4RunManager::masterRM) {
429       static_cast<G4MTRunManager*>(runManager)
430         ->SetNumberOfThreads(nThreadsCmd->GetNewIntValue(newValue));
431     }
432     else if (rmType == G4RunManager::sequentialRM) {
433       G4cout << "*** /run/numberOfThreads command is issued in sequential mode."
434              << "\nCommand is ignored." << G4endl;
435     }
436     else {
437       G4Exception("G4RunMessenger::ApplyNewCommand", "Run0901", FatalException,
438                   "/run/numberOfThreads command is issued to local thread.");
439     }
440   }
441   else if (command == maxThreadsCmd) {
442     G4RunManager::RMType rmType = runManager->GetRunManagerType();
443     if (rmType == G4RunManager::masterRM) {
444       static_cast<G4MTRunManager*>(runManager)
445         ->SetNumberOfThreads(G4Threading::G4GetNumberOfCores());
446     }
447     else if (rmType == G4RunManager::sequentialRM) {
448       G4cout << "*** /run/useMaximumLogicalCores command is issued in "
449                 "sequential mode."
450              << "\nCommand is ignored." << G4endl;
451     }
452     else {
453       G4Exception("G4RunMessenger::ApplyNewCommand", "Run0901", FatalException,
454                   "/run/useMaximumLogicalCores command is issued to local thread.");
455     }
456   }
457   else if (command == pinAffinityCmd) {
458     G4RunManager::RMType rmType = runManager->GetRunManagerType();
459     if (rmType == G4RunManager::masterRM) {
460       static_cast<G4MTRunManager*>(runManager)
461         ->SetPinAffinity(pinAffinityCmd->GetNewIntValue(newValue));
462     }
463     else if (rmType == G4RunManager::sequentialRM) {
464       G4cout << "*** /run/pinAffinity command is issued in sequential mode."
465              << "\nCommand is ignored." << G4endl;
466     }
467     else {
468       G4Exception("G4RunMessenger::ApplyNewCommand", "Run0901", FatalException,
469                   "/run/pinAffinity command is issued to local thread.");
470     }
471   }
472   else if (command == evModCmd) {
473     G4RunManager::RMType rmType = runManager->GetRunManagerType();
474     if (rmType == G4RunManager::masterRM) {
475       G4int nevMod = 0;
476       G4int sOnce = 0;
477       const auto nv = (const char*)newValue;
478       std::istringstream is(nv);
479       is >> nevMod >> sOnce;
480       static_cast<G4MTRunManager*>(runManager)->SetEventModulo(nevMod);
481       G4MTRunManager::SetSeedOncePerCommunication(sOnce);
482     }
483     else if (rmType == G4RunManager::sequentialRM) {
484       G4cout << "*** /run/eventModulo command is issued in sequential mode."
485              << "\nCommand is ignored." << G4endl;
486     }
487     else {
488       G4Exception("G4RunMessenger::ApplyNewCommand", "Run0902", FatalException,
489                   "/run/eventModulo command is issued to local thread.");
490     }
491   }
492   else if (command == dumpRegCmd) {
493     if (newValue == "**ALL**") {
494       runManager->DumpRegion();
495     }
496     else {
497       runManager->DumpRegion(newValue);
498     }
499   }
500   else if (command == dumpCoupleCmd) {
501     G4ProductionCutsTable::GetProductionCutsTable()->DumpCouples();
502   }
503   else if (command == optCmd) {
504     runManager->SetGeometryToBeOptimized(optCmd->GetNewBoolValue(newValue));
505   }
506   else if (command == brkBoECmd) {
507     G4UImanager::GetUIpointer()->SetPauseAtBeginOfEvent(brkBoECmd->GetNewBoolValue(newValue));
508   }
509   else if (command == brkEoECmd) {
510     G4UImanager::GetUIpointer()->SetPauseAtEndOfEvent(brkEoECmd->GetNewBoolValue(newValue));
511   }
512   else if (command == abortCmd) {
513     runManager->AbortRun(abortCmd->GetNewBoolValue(newValue));
514   }
515   else if (command == abortEventCmd) {
516     runManager->AbortEvent();
517   }
518   else if (command == initCmd) {
519     runManager->Initialize();
520   }
521   else if (command == geomCmd) {
522     runManager->GeometryHasBeenModified(false);
523   }
524   else if (command == geomRebCmd) {
525     runManager->ReinitializeGeometry(geomRebCmd->GetNewBoolValue(newValue), false);
526   }
527   else if (command == physCmd) {
528     runManager->PhysicsHasBeenModified();
529   }
530   else if (command == seedCmd) {
531     G4Tokenizer next(newValue);
532     G4int idx = 0;
533     G4long seeds[100];
534     G4String vl;
535     while (!(vl = next()).empty()) {
536       seeds[idx] = StoL(vl);
537       ++idx;
538     }
539     if (idx < 2) {
540       G4cerr << "/random/setSeeds should have at least two values. "
541                 "Command ignored."
542              << G4endl;
543     }
544     else {
545       seeds[idx] = 0;
546       G4Random::setTheSeeds(seeds);
547     }
548   }
549   else if (command == randDirCmd) {
550     runManager->SetRandomNumberStoreDir(newValue);
551   }
552   else if (command == savingFlagCmd) {
553     runManager->SetRandomNumberStore(savingFlagCmd->GetNewBoolValue(newValue));
554   }
555   else if (command == saveThisRunCmd) {
556     runManager->rndmSaveThisRun();
557   }
558   else if (command == saveThisEventCmd) {
559     runManager->rndmSaveThisEvent();
560   }
561   else if (command == restoreRandCmd) {
562     runManager->RestoreRandomNumberStatus(newValue);
563   }
564   else if (command == randEvtCmd) {
565     runManager->StoreRandomNumberStatusToG4Event(randEvtCmd->GetNewIntValue(newValue));
566   }
567   else if (command == saveEachEventCmd) {
568     runManager->SetRandomNumberStorePerEvent(saveEachEventCmd->GetNewBoolValue(newValue));
569   }
570   else if (command == constScoreCmd) {
571     runManager->ConstructScoringWorlds();
572   }
573   else if (command == restoreRandCmdMT) {
574     runManager->RestoreRndmEachEvent(restoreRandCmdMT->GetNewBoolValue(newValue));
575   }
576   else if (command == procUICmds) {
577     G4RunManager::RMType rmType = runManager->GetRunManagerType();
578     if (rmType == G4RunManager::masterRM) {
579       auto rm = dynamic_cast<G4MTRunManager*>(runManager);
580       if (rm != nullptr) {
581         rm->RequestWorkersProcessCommandsStack();
582       }
583       else {
584         G4Exception("G4RunManager::ApplyNewCommand", "Run0128", FatalException,
585                     "/run/workersProcessCmds command issued on a "
586                     "non-G4MTRunManager class instance.");
587       }
588     }
589     else if (rmType == G4RunManager::sequentialRM) {
590       G4cout << "*** /run/workersProcessCmds command is issued in sequential mode."
591              << "\nCommand is ignored." << G4endl;
592     }
593     else {
594       G4Exception("G4RunMessenger::ApplyNewCommand", "Run0129", FatalException,
595                   "/run/workersProcessCmds command is issued to local thread.");
596     }
597   }
598 }
599 
600 // --------------------------------------------------------------------
601 G4String G4RunMessenger::GetCurrentValue(G4UIcommand* command)
602 {
603   G4String cv;
604 
605   if (command == verboseCmd) {
606     cv = verboseCmd->ConvertToString(runManager->GetVerboseLevel());
607   }
608   else if (command == printProgCmd) {
609     cv = printProgCmd->ConvertToString(runManager->GetPrintProgress());
610   }
611   else if (command == randDirCmd) {
612     cv = runManager->GetRandomNumberStoreDir();
613   }
614   else if (command == randEvtCmd) {
615     cv = randEvtCmd->ConvertToString(runManager->GetFlagRandomNumberStatusToG4Event());
616   }
617   else if (command == nThreadsCmd) {
618     G4RunManager::RMType rmType = runManager->GetRunManagerType();
619     if (rmType == G4RunManager::masterRM) {
620       cv = nThreadsCmd->ConvertToString(
621         static_cast<G4MTRunManager*>(runManager)->GetNumberOfThreads());
622     }
623     else if (rmType == G4RunManager::sequentialRM) {
624       cv = "0";
625     }
626   }
627   else if (command == evModCmd) {
628     G4RunManager::RMType rmType = runManager->GetRunManagerType();
629     if (rmType == G4RunManager::masterRM) {
630       cv = evModCmd->ConvertToString(static_cast<G4MTRunManager*>(runManager)->GetEventModulo())
631            + " " + evModCmd->ConvertToString(G4MTRunManager::SeedOncePerCommunication());
632     }
633     else if (rmType == G4RunManager::sequentialRM) {
634       G4cout << "*** /run/eventModulo command is valid only in MT mode." << G4endl;
635     }
636   }
637 
638   return cv;
639 }
640