ATLAS Offline Software
UserActionSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <mutex>
6 
7 // Framework includes
8 
9 // Geant4 includes
10 #include "G4RunManager.hh"
11 
12 // Local includes
13 #include "UserActionSvc.h"
14 
15 namespace G4UA
16 {
17 
18  //---------------------------------------------------------------------------
19  // Constructor
20  // I was using private tool handle arrays, but the OutputLevels weren't
21  // getting set correctly (in mig1), so I will just make them all public.
22  //---------------------------------------------------------------------------
23  UserActionSvc::UserActionSvc(const std::string& name,
24  ISvcLocator* pSvcLocator)
25  : base_class(name, pSvcLocator)
26  , m_userActionTools(this)
27  {
28  declareProperty("UserActionTools", m_userActionTools);
29  }
30 
31  //---------------------------------------------------------------------------
32  // Initialize the service
33  //---------------------------------------------------------------------------
35  {
36  ATH_MSG_INFO("Initializing " << m_userActionTools.size() << " user action tools.");
37 
38  for(const auto& action : m_userActionTools) {
39  ATH_MSG_INFO( " -> " << action.name() );
40  }
41 
42  ATH_CHECK( m_userActionTools.retrieve() );
43 
44  return StatusCode::SUCCESS;
45  }
46  StatusCode UserActionSvc::addActionTool(const ToolHandle<IUserActionTool>& service_tool){
47 
48  if (!service_tool.isPublic()){
49  ATH_MSG_FATAL("Only public tools are allowed");
50  return StatusCode::FAILURE;
51  }
52  if (service_tool.empty()) {
53  ATH_MSG_FATAL("NO point in adding empty tool handles here.");
54  return StatusCode::FAILURE;
55  }
56  ATH_MSG_INFO(" Add new tool "<<service_tool.name());
57  m_userActionTools.push_back(service_tool);
58  return StatusCode::SUCCESS;
59  }
60 
61  //---------------------------------------------------------------------------
62  // Initialize the user actions for the current thread.
63  // In this code, "action" refers to the G4 action classes, and "plugin"
64  // refers to the custom action objects that get assigned to the G4 action.
65  // TODO: this prototype could be cleaner
66  //---------------------------------------------------------------------------
68  {
69  // This method is called concurrently in AthenaMT during initialization.
70  // We conservatively just lock the whole thing to protect MsgStream and
71  // downstream code.
72  static std::mutex userActionMutex;
73  std::lock_guard<std::mutex> userActionLock(userActionMutex);
74 
75  ATH_MSG_DEBUG("initializeActions");
76 
77  // sanity check: this is to make sure there are no other instances of this
78  // svc that have been already initialized, or that nobody else in some other
79  // code has already been registering actions to the run manager, which would
80  // be a major error in the configuration checking the run action is probably
81  // enough fo multiple instances of this service, since all roles are usually
82  // set at the same time. but other code may as well have registered just one
83  // role, so it is safer to do all checks here.
84 
85  if( G4RunManager::GetRunManager()->GetUserRunAction() ||
86  G4RunManager::GetRunManager()->GetUserEventAction() ||
87  G4RunManager::GetRunManager()->GetUserStackingAction() ||
88  G4RunManager::GetRunManager()->GetUserTrackingAction() ||
89  G4RunManager::GetRunManager()->GetUserSteppingAction() )
90  {
91  ATH_MSG_FATAL("UserActionSvc has found that actions were already " <<
92  "registered to the G4RunManager. Check your code/configuration");
93  return StatusCode::FAILURE;
94  }
95 
96  // Retrieve the new user actions
97  G4AtlasUserActions actions;
98  for(auto& tool : m_userActionTools) {
99  ATH_CHECK( tool->fillUserAction(actions) );
100  }
101 
102  // Initialize the ATLAS run action.
103  if(m_runActions.get()) {
104  ATH_MSG_ERROR("Run action already exists for current thread!");
105  return StatusCode::FAILURE;
106  }
107  auto runAction = std::make_unique<G4AtlasRunAction>();
108  // Assign run plugins
109  for(auto* action : actions.runActions)
110  runAction->addRunAction(action);
111  G4RunManager::GetRunManager()->SetUserAction( runAction.get() );
112  m_runActions.set( std::move(runAction) );
113 
114  // Initialize the ATLAS event action.
115  if(m_eventActions.get()) {
116  ATH_MSG_ERROR("Event action already exists for current thread!");
117  return StatusCode::FAILURE;
118  }
119  auto eventAction = std::make_unique<G4AtlasEventAction>();
120  // Assign event plugins
121  for(auto* action : actions.eventActions) {
122  eventAction->addEventAction(action);
123  // set the event manager
124  action->SetEventManager( G4EventManager::GetEventManager() );
125  }
126  G4RunManager::GetRunManager()->SetUserAction( eventAction.get() );
127  m_eventActions.set( std::move(eventAction) );
128 
129  // Initialize the ATLAS stacking action.
130  if(m_stackingActions.get()) {
131  ATH_MSG_ERROR("Stacking action already exists for current thread!");
132  return StatusCode::FAILURE;
133  }
134  auto stackAction = std::make_unique<G4AtlasStackingAction>();
135  // Assign stacking plugins
136  for(auto* action : actions.stackingActions) {
137  stackAction->addAction(action);
138  // set the stack manager
139  action->SetStackManager( G4EventManager::GetEventManager()->GetStackManager() );
140  }
141  G4RunManager::GetRunManager()->SetUserAction( stackAction.get() );
142  m_stackingActions.set( std::move(stackAction) );
143 
144  // Initialize the ATLAS tracking action.
145  if(m_trackingActions.get()) {
146  ATH_MSG_ERROR("Tracking action already exists for current thread!");
147  return StatusCode::FAILURE;
148  }
149  auto trackAction = std::make_unique<G4AtlasTrackingAction>();
150  // Assign tracking plugins
151  for(auto* action : actions.trackingActions) {
152  trackAction->addTrackAction(action);
153  // set the tracking manager
154  action->SetTrackingManagerPointer ( G4EventManager::GetEventManager()->GetTrackingManager() );
155  }
156  G4RunManager::GetRunManager()->SetUserAction( trackAction.get() );
157  m_trackingActions.set( std::move(trackAction) );
158 
159  // Initialize the ATLAS stepping action.
160  if(m_steppingActions.get()) {
161  ATH_MSG_ERROR("Stepping action already exists for current thread!");
162  return StatusCode::FAILURE;
163  }
164  auto stepAction = std::make_unique<G4AtlasSteppingAction>();
165  // Assign stepping plugins
166  for(auto* action : actions.steppingActions) {
167  stepAction->addAction(action);
168  // set the stepping manager
169  action->SetSteppingManagerPointer( G4EventManager::GetEventManager()->GetTrackingManager()->GetSteppingManager() );
170  }
171  G4RunManager::GetRunManager()->SetUserAction( stepAction.get() );
172  m_steppingActions.set( std::move(stepAction) );
173 
174  return StatusCode::SUCCESS;
175  }
176 
177  // For ISF, get UserActions that could have stored secondary particles
178  StatusCode UserActionSvc::getSecondaryActions( std::vector< G4UserSteppingAction* >& actions ) {
179 
180  // Only stepping actions can return secondaries? Maybe turn this into a templated method
181  actions = m_steppingActions.get()->getActions();
182 
183  return StatusCode::SUCCESS;
184  }
185 } // namespace G4UA
G4UA::UserActionSvc::m_userActionTools
ToolHandleArray< IUserActionTool > m_userActionTools
User action tools.
Definition: UserActionSvc.h:58
G4UA::G4AtlasUserActions
Struct for passing around user actions.
Definition: IUserActionTool.h:32
G4UA::UserActionSvc::m_stackingActions
ThreadActionHolder< G4AtlasStackingAction > m_stackingActions
Thread-local stacking action.
Definition: UserActionSvc.h:70
G4UA::UserActionSvc::m_runActions
ThreadActionHolder< G4AtlasRunAction > m_runActions
Thread-local run action.
Definition: UserActionSvc.h:66
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
G4UA::UserActionSvc::m_eventActions
ThreadActionHolder< G4AtlasEventAction > m_eventActions
Thread-local event action.
Definition: UserActionSvc.h:68
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
G4UA
for nSW
Definition: CalibrationDefaultProcessing.h:19
G4UA::UserActionSvc::initializeActions
StatusCode initializeActions() override final
Initialize the user actions for the current thread.
Definition: UserActionSvc.cxx:67
G4UA::G4AtlasUserActions::trackingActions
std::vector< G4UserTrackingAction * > trackingActions
Definition: IUserActionTool.h:35
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
G4UA::UserActionSvc::initialize
StatusCode initialize() override
Initialize the service.
Definition: UserActionSvc.cxx:34
UserActionSvc.h
G4UA::UserActionSvc::addActionTool
StatusCode addActionTool(const ToolHandle< IUserActionTool > &service_tool) override final
Definition: UserActionSvc.cxx:46
G4UA::UserActionSvc::getSecondaryActions
StatusCode getSecondaryActions(std::vector< G4UserSteppingAction * > &actions) override final
Definition: UserActionSvc.cxx:178
G4UA::UserActionSvc::UserActionSvc
UserActionSvc(const std::string &name, ISvcLocator *pSvcLocator)
Standard constructor.
Definition: UserActionSvc.cxx:23
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
G4UA::G4AtlasUserActions::runActions
std::vector< G4UserRunAction * > runActions
Definition: IUserActionTool.h:33
G4UA::G4AtlasUserActions::stackingActions
std::vector< G4UserStackingAction * > stackingActions
Definition: IUserActionTool.h:37
python.CaloScaleNoiseConfig.action
action
Definition: CaloScaleNoiseConfig.py:77
G4UA::G4AtlasUserActions::eventActions
std::vector< G4UserEventAction * > eventActions
Definition: IUserActionTool.h:34
G4UA::UserActionSvc::m_trackingActions
ThreadActionHolder< G4AtlasTrackingAction > m_trackingActions
Thread-local tracking action.
Definition: UserActionSvc.h:72
G4UA::G4AtlasUserActions::steppingActions
std::vector< G4UserSteppingAction * > steppingActions
Definition: IUserActionTool.h:36
G4UA::UserActionSvc::m_steppingActions
ThreadActionHolder< G4AtlasSteppingAction > m_steppingActions
Thread-local stepping action.
Definition: UserActionSvc.h:74