GGS(GenericGEANT4Simulation)Software  2.99.0
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Macros
GGSUserActionInitialization.cpp
1 /*
2  * GGSUserActionInitialization.cpp
3  *
4  * Created on: 22 Oct 2020
5  * Author: Nicola Mori
6  */
7 
12 #include "utils/GGSFactory.h"
13 #include "utils/GGSSmartLog.h"
14 
15 #include "G4Exception.hh"
16 #include "G4UIcmdWithAString.hh"
17 #include "G4UIcommand.hh"
18 #include "G4UImanager.hh"
19 
20 #include <memory>
21 
22 // Thread-local global variables
23 namespace {
24 G4ThreadLocal GGSMultiUserAction *muAction = nullptr;
25 G4ThreadLocal GGSMultiUserAction *muActionForMaster = nullptr;
26 } // namespace
27 
28 void GGSUserActionInitialization::BuildForMaster() const {
29  const std::string routineName("GGSUserActionInitialization::BuildForMaster");
30  GGSCOUT(DEBUG) << "Setting the run actions for the master thread." << GGSENDL;
31 
32  /* ***** Build user action creation commands for master thread. ***** */
33  // User action build commands are created for worker threads in Build(). During the creation process they are
34  // also automatically registered in the UI manager for master thread by G4UImanager::AddWorkerCommand that is called
35  // in G4UImanager::AddNewCommand. In this way the commands are recognized during the parsing of the data card by the
36  // master thread and no error is generated. However, build commands create user actions that might create additional
37  // commands in their constructors: these would not be registered for master thread, since a build command added to the
38  // master UI manager from a worker thread is flagged as workerThreadOnly, so it is recognized but not executed by the
39  // master thread; a subsequent action-created command would therefore be not registered in master UI and an error
40  // would occur. The only solution seems to register all the build commands directly in the master thread, so that they
41  // will be executed by master, all the user action configuration commands will be created and no error will occur
42  // while parsing the data card. The master actions should not be executed during the simulation, so SetUserAction is
43  // not called for the master malt-action.
44  muActionForMaster = new GGSMultiUserAction; // Thread-local
45 }
46 
47 void GGSUserActionInitialization::Build() const {
48  const std::string routineName("GGSUserActionInitialization::Build");
49 
50  if (G4Threading::IsMultithreadedApplication()) {
51  GGSCOUT(DEBUG) << "Setting the user actions for worker thread " << G4Threading::G4GetThreadId() << GGSENDL;
52  } else {
53  GGSCOUT(DEBUG) << "Setting the user actions" << GGSENDL;
54  }
55  delete muAction;
56  muAction = new GGSMultiUserAction; // Thread-local
57  SetUserAction((G4UserSteppingAction *)muAction);
58  SetUserAction((G4UserTrackingAction *)muAction);
59  SetUserAction((G4UserEventAction *)muAction);
60  SetUserAction((G4UserRunAction *)muAction);
61  SetUserAction((G4UserStackingAction *)muAction);
62 
63  // Add a dummy event generator for the MT dry run. Will be replaced by a real generator built with a datacard command.
64  class DummyGenAction : public GGSGeneratorAction {
65  public:
66  void GeneratePrimaries(G4Event *){};
67  };
68  SetUserAction(new DummyGenAction);
69 }
Base class for GGS generator actions.
#define GGSENDL
Definition: GGSSmartLog.h:131
A multiplexer container for user actions.