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 Geant4 main thread.
63  //---------------------------------------------------------------------------
65  {
66  // Retrieve the new user actions
67  G4AtlasUserActions actions;
68  for(auto& tool : m_userActionTools) {
69  ATH_CHECK( tool->fillUserAction(actions) );
70  }
71  auto runAction = std::make_unique<G4AtlasRunAction>();
72  // Assign run plugins
73  for(auto* action : actions.runActionsMaster)
74  {
75  runAction->addRunAction(action);
76  }
77  G4RunManager::GetRunManager()->SetUserAction( runAction.release() );
78  return StatusCode::SUCCESS;
79  }
80 
81  //---------------------------------------------------------------------------
82  // Initialize the user actions for the current thread.
83  // In this code, "action" refers to the G4 action classes, and "plugin"
84  // refers to the custom action objects that get assigned to the G4 action.
85  // TODO: this prototype could be cleaner
86  //---------------------------------------------------------------------------
88  {
89  // This method is called concurrently in AthenaMT during initialization.
90  // We conservatively just lock the whole thing to protect MsgStream and
91  // downstream code.
92  static std::mutex userActionMutex;
93  std::lock_guard<std::mutex> userActionLock(userActionMutex);
94 
95  ATH_MSG_DEBUG("initializeActions");
96 
97  // sanity check: this is to make sure there are no other instances of this
98  // svc that have been already initialized, or that nobody else in some other
99  // code has already been registering actions to the run manager, which would
100  // be a major error in the configuration checking the run action is probably
101  // enough fo multiple instances of this service, since all roles are usually
102  // set at the same time. but other code may as well have registered just one
103  // role, so it is safer to do all checks here.
104 
105  if( G4RunManager::GetRunManager()->GetUserRunAction() ||
106  G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction() ||
107  G4RunManager::GetRunManager()->GetUserEventAction() ||
108  G4RunManager::GetRunManager()->GetUserStackingAction() ||
109  G4RunManager::GetRunManager()->GetUserTrackingAction() ||
110  G4RunManager::GetRunManager()->GetUserSteppingAction() )
111  {
112  ATH_MSG_FATAL("UserActionSvc has found that actions were already " <<
113  "registered to the G4RunManager. Check your code/configuration");
114  return StatusCode::FAILURE;
115  }
116 
117  // Retrieve the new user actions
118  G4AtlasUserActions actions;
119  for(auto& tool : m_userActionTools) {
120  ATH_CHECK( tool->fillUserAction(actions) );
121  }
122 
123  // Initialize the ATLAS run action.
124  if(m_runActions.get()) {
125  ATH_MSG_ERROR("Run action already exists for current thread!");
126  return StatusCode::FAILURE;
127  }
128  auto runAction = std::make_unique<G4AtlasRunAction>();
129  // Assign run plugins
130  for(auto* action : actions.runActions)
131  runAction->addRunAction(action);
132  G4RunManager::GetRunManager()->SetUserAction( runAction.get() );
133  m_runActions.set( std::move(runAction) );
134 
135  // Initialize the ATLAS primary generator action.
136  if(m_primaryGeneratorActions.get()) {
137  ATH_MSG_ERROR("Primary generator action already exists for current thread!");
138  return StatusCode::FAILURE;
139  }
140  auto primaryGeneratorAction = std::make_unique<G4AtlasPrimaryGeneratorAction>();
141  // Assign run plugins
142  for(auto* action : actions.primaryGeneratorActions)
143  primaryGeneratorAction->addPrimaryGeneratorAction(action);
144  G4RunManager::GetRunManager()->SetUserAction( primaryGeneratorAction.get() );
145  m_primaryGeneratorActions.set( std::move(primaryGeneratorAction) );
146 
147  // Initialize the ATLAS event action.
148  if(m_eventActions.get()) {
149  ATH_MSG_ERROR("Event action already exists for current thread!");
150  return StatusCode::FAILURE;
151  }
152  auto eventAction = std::make_unique<G4AtlasEventAction>();
153  // Assign event plugins
154  for(auto* action : actions.eventActions) {
155  eventAction->addEventAction(action);
156  // set the event manager
157  action->SetEventManager( G4EventManager::GetEventManager() );
158  }
159  G4RunManager::GetRunManager()->SetUserAction( eventAction.get() );
160  m_eventActions.set( std::move(eventAction) );
161 
162  // Initialize the ATLAS stacking action.
163  if(m_stackingActions.get()) {
164  ATH_MSG_ERROR("Stacking action already exists for current thread!");
165  return StatusCode::FAILURE;
166  }
167  auto stackAction = std::make_unique<G4AtlasStackingAction>();
168  // Assign stacking plugins
169  for(auto* action : actions.stackingActions) {
170  stackAction->addAction(action);
171  // set the stack manager
172  action->SetStackManager( G4EventManager::GetEventManager()->GetStackManager() );
173  }
174  G4RunManager::GetRunManager()->SetUserAction( stackAction.get() );
175  m_stackingActions.set( std::move(stackAction) );
176 
177  // Initialize the ATLAS tracking action.
178  if(m_trackingActions.get()) {
179  ATH_MSG_ERROR("Tracking action already exists for current thread!");
180  return StatusCode::FAILURE;
181  }
182  auto trackAction = std::make_unique<G4AtlasTrackingAction>();
183  // Assign tracking plugins
184  for(auto* action : actions.trackingActions) {
185  trackAction->addTrackAction(action);
186  // set the tracking manager
187  action->SetTrackingManagerPointer ( G4EventManager::GetEventManager()->GetTrackingManager() );
188  }
189  G4RunManager::GetRunManager()->SetUserAction( trackAction.get() );
190  m_trackingActions.set( std::move(trackAction) );
191 
192  // Initialize the ATLAS stepping action.
193  if(m_steppingActions.get()) {
194  ATH_MSG_ERROR("Stepping action already exists for current thread!");
195  return StatusCode::FAILURE;
196  }
197  auto stepAction = std::make_unique<G4AtlasSteppingAction>();
198  // Assign stepping plugins
199  for(auto* action : actions.steppingActions) {
200  stepAction->addAction(action);
201  // set the stepping manager
202  action->SetSteppingManagerPointer( G4EventManager::GetEventManager()->GetTrackingManager()->GetSteppingManager() );
203  }
204  G4RunManager::GetRunManager()->SetUserAction( stepAction.get() );
205  m_steppingActions.set( std::move(stepAction) );
206 
207  return StatusCode::SUCCESS;
208  }
209 
210  // For ISF, get UserActions that could have stored secondary particles
211  StatusCode UserActionSvc::getSecondaryActions( std::vector< G4UserSteppingAction* >& actions ) {
212 
213  // Only stepping actions can return secondaries? Maybe turn this into a templated method
214  actions = m_steppingActions.get()->getActions();
215 
216  return StatusCode::SUCCESS;
217  }
218 } // namespace G4UA
G4UA::UserActionSvc::m_userActionTools
ToolHandleArray< IUserActionTool > m_userActionTools
User action tools.
Definition: UserActionSvc.h:62
G4UA::G4AtlasUserActions
Struct for passing around user actions.
Definition: IUserActionTool.h:33
G4UA::UserActionSvc::m_stackingActions
ThreadActionHolder< G4AtlasStackingAction > m_stackingActions
Thread-local stacking action.
Definition: UserActionSvc.h:76
G4UA::UserActionSvc::m_runActions
ThreadActionHolder< G4AtlasRunAction > m_runActions
Thread-local run action.
Definition: UserActionSvc.h:70
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:74
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
G4UA
for nSW
Definition: CalibrationDefaultProcessing.h:19
G4UA::G4AtlasUserActions::runActionsMaster
std::vector< G4UserRunAction * > runActionsMaster
Definition: IUserActionTool.h:35
G4UA::UserActionSvc::initializeActions
StatusCode initializeActions() override final
Initialize the user actions for the current thread.
Definition: UserActionSvc.cxx:87
G4UA::G4AtlasUserActions::trackingActions
std::vector< G4UserTrackingAction * > trackingActions
Definition: IUserActionTool.h:38
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:211
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
G4UA::UserActionSvc::initializeActionsMaster
StatusCode initializeActionsMaster() override final
Initialize the user run actions for the main thread.
Definition: UserActionSvc.cxx:64
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:452
G4UA::G4AtlasUserActions::runActions
std::vector< G4UserRunAction * > runActions
Definition: IUserActionTool.h:34
G4UA::UserActionSvc::m_primaryGeneratorActions
ThreadActionHolder< G4AtlasPrimaryGeneratorAction > m_primaryGeneratorActions
Thread-local primary generator action.
Definition: UserActionSvc.h:72
G4UA::G4AtlasUserActions::primaryGeneratorActions
std::vector< G4VUserPrimaryGeneratorAction * > primaryGeneratorActions
Definition: IUserActionTool.h:36
G4UA::G4AtlasUserActions::stackingActions
std::vector< G4UserStackingAction * > stackingActions
Definition: IUserActionTool.h:40
python.CaloScaleNoiseConfig.action
action
Definition: CaloScaleNoiseConfig.py:77
G4UA::G4AtlasUserActions::eventActions
std::vector< G4UserEventAction * > eventActions
Definition: IUserActionTool.h:37
G4UA::UserActionSvc::m_trackingActions
ThreadActionHolder< G4AtlasTrackingAction > m_trackingActions
Thread-local tracking action.
Definition: UserActionSvc.h:78
G4UA::G4AtlasUserActions::steppingActions
std::vector< G4UserSteppingAction * > steppingActions
Definition: IUserActionTool.h:39
G4UA::UserActionSvc::m_steppingActions
ThreadActionHolder< G4AtlasSteppingAction > m_steppingActions
Thread-local stepping action.
Definition: UserActionSvc.h:80