Allow registration of multiple user actions in Geant4. Currently only a single instance of user action object of a certain type can be registered in `G4EventManager` (`G4UserEventAction`, `G4UserStackingAction`, `G4UserTrackingAction`, `G4UserSteppingAction`). This approach is rather confusing. From perspective of Object-Oriented Programming, application developer should be able to override basic user event actions and register multiple instances of custom user actions. For example, it is convenient to address optical effects in say `OpticalEventAction:G4UserEventAction` and have another class `EnergyEventAction:G4UserEventAction` for saving energy deposition in solids.
While you cannot define multiple PrimaryGeneratorAction or StackingAction (they do not make sense), you can define multiple RunActions, EventActions, TrackingActions and/or SteppingActions. In addition, you may define SteppingActions per geometry region if you want.
Hi, thanks for your reply. I have recently tested registration of two user `G4UserEventAction` actions. Only the last EventAction fires up. Here is a sample code where we register two event actions: void ActionInitialization::Build() const { FirstEventAction* eventAction1 = new FirstEventAction(); SetUserAction(eventAction1); SecondEventAction* eventAction2 = new SecondEventAction(); SetUserAction(eventAction2); } Unfortunately methods `BeginOfEventAction` and `EndOfEventAction` are only called on the `eventAction2` object (the last registered). Let me explain why. G4EventManager stores a single instance of G4UserEventAction (G4EventManager.hh, line 179): class G4EventManager { // ... G4UserEventAction* userEventAction = nullptr; } When registering new Event action, only last registered cation is saved in `G4EventManager` (G4EventManager.cc, line 307): void G4EventManager::SetUserAction(G4UserEventAction* userAction) { userEventAction = userAction; // ... } Finally, when Geant4 processes the event, it calls (G4EventManager.cc, lines 131 and 262): void G4EventManager::DoProcessing(G4Event* anEvent){ // ... if(userEventAction) userEventAction->BeginOfEventAction(currentEvent); // ... if(userEventAction) userEventAction->EndOfEventAction(currentEvent); } Looking at the above code it is clear that methods `BeginOfEventAction` and `EndOfEventAction` are called for the class mamber `userEventAction` (that corresponds to the last registered object in `SetUserAction(...)`. To my understanding, instead of storing a single member of `userEventAction` inside `G4EventManager` there must be a std::vector<G4UserEventAction*> and `Begin/EndOfEventAction` needs to be called for every object in that vector. Please correct me if I'm wrong. Looking forward to hearing from you.
Sorry for incomplete reply. For example of EventAction, use G4MultiEventAction here you may register as many EventActions as you need. By the way, "OpticalEventAction" or "EnergyEventAction" does not make much sense to me. Would you like to consider using G4MultiFunctionalDetector and scorers / filters? You can assign them to individual volume. Let me close this report. For further discussions, please use the user forum.
Thank you so much for explaining the workflow. Next time will go to the forum!