| Summary: | Allow registration of multiple user actions | ||
|---|---|---|---|
| Product: | Geant4 | Reporter: | Petr Stepanov <stepanovps> |
| Component: | run | Assignee: | asai |
| Status: | RESOLVED INVALID | ||
| Severity: | minor | ||
| Priority: | P4 | ||
| Version: | 10.7 | ||
| Hardware: | All | ||
| OS: | All | ||
|
Description
Petr Stepanov
2021-04-13 02:26:30 CEST
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! |