ATLAS Offline Software
PyAthenaEventLoopMgr.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //===================================================================
6 // PyAthenaEventLoopMgr.cxx
7 //--------------------------------------------------------------------
8 //
9 // Package : AthenaServices
10 //
11 // Description: implementation of the Application's interactive mode
12 // handler
13 //
14 // Author : Wim Lavrijsen
15 // History :
16 // +---------+----------------------------------------------+---------
17 // | Date | Comment | Who
18 // +---------+----------------------------------------------+---------
19 // | 01/12/05| Initial version | WL
20 // +---------+----------------------------------------------+---------
21 //
22 //====================================================================
23 
25 ATLAS_NO_CHECK_FILE_THREAD_SAFETY; // non-MT EventLoopMgr
26 
27 // Python
28 #include "Python.h"
29 
30 // Gaudi
31 #include "GaudiKernel/MsgStream.h"
32 #include "GaudiKernel/Bootstrap.h"
33 #include "GaudiKernel/IConversionSvc.h"
34 #include "GaudiKernel/ISvcLocator.h"
35 #include "GaudiKernel/IAlgorithm.h"
36 #include "GaudiKernel/DataSvc.h"
37 
38 // AthenaServices
39 #include "PyAthenaEventLoopMgr.h"
40 
42 
43 
44 //- data ------------------------------------------------------------------
45 namespace {
46 
47  char* execalgs = const_cast< char* >( "executeAlgorithms" );
48 
49 } // unnamed namespace
50 
51 
52 //=========================================================================
53 // Outside access to the event loop manager
54 //=========================================================================
56 
57  SmartIF<IEventProcessor> ep{Gaudi::svcLocator()->service( "PyAthenaEventLoopMgr", /*createIf*/false )};
58  if ( ep ) {
59  ep->addRef();
60  return dynamic_cast< PyAthenaEventLoopMgr* >( ep.get() );
61  }
62 
63  return nullptr;
64 }
65 
66 
67 //=========================================================================
68 // Standard Constructor
69 //=========================================================================
71  ISvcLocator* svcLoc )
72  : AthenaEventLoopMgr( name, svcLoc ), m_manager( nullptr )
73 {
78  AthenaEventLoopMgr::m_clearStorePolicy.set( "BeginEvent" );
79 }
80 
81 
82 //=========================================================================
83 // Python side manager set/get
84 //=========================================================================
86 {
88  if ( ! PyObject_HasAttrString( mgr, execalgs ) )
89  {
90  PyErr_SetString( PyExc_TypeError, "given object is not a manager" );
91  return nullptr;
92  }
93 
94 // set on ourselves
96  Py_INCREF( mgr );
97  m_manager = mgr;
98 
99 // set onto the module as a module global (this may replace the old one, so
100 // users are best served to only access this through the module)
101  PyObject* pyelm = PyImport_AddModule( const_cast< char* >( "AthenaServices.PyAthenaEventLoopMgr" ) );
102  if ( pyelm ) {
103  Py_INCREF( mgr );
104  if (PyModule_AddObject( pyelm, const_cast< char* >( "EventLoopMgr" ), mgr ) < 0) {
105  Py_DECREF( mgr );
106  }
107  }
108 
109 // hand the python side its interfaces
110  PyObject* pyself = PyCapsule_New( (void*)static_cast< IEventSeek* >( this ), nullptr, nullptr );
111 #if PY_MAJOR_VERSION < 3
112  PyObject* method = PyString_FromString( "_installServices" );
113 #else
114  PyObject* method = PyUnicode_FromString( "_installServices" );
115 #endif
116  PyObject* result = PyObject_CallMethodObjArgs( mgr, method, pyself, 0 );
117  Py_DECREF( method );
118  Py_DECREF( pyself );
119 
120  if ( ! result )
121  return nullptr;
122 
123 // return old value (with its refcount), if set previously; or None
124  if ( old != nullptr )
125  return old;
126 
127  Py_INCREF( Py_None );
128  return Py_None;
129 }
130 
132 {
134  if ( ! m_manager )
135  {
136  Py_INCREF( Py_None );
137  return Py_None;
138  }
139 
140  Py_INCREF( m_manager );
141  return m_manager;
142 }
143 
144 
145 //=========================================================================
146 // Implementation of IAppMgrUI::initialize
147 //=========================================================================
149 {
151 // get the PyAthenaEventLoopMgr python-side class
152  PyObject* modpyelm = PyImport_ImportModule( const_cast< char* >( "AthenaServices.PyAthenaEventLoopMgr" ) );
153  if ( modpyelm ) {
154 
155  PyObject* pyelm = PyObject_GetAttrString( modpyelm, const_cast< char* >( "PyAthenaEventLoopMgr" ) );
156  Py_DECREF( modpyelm );
157 
158  if ( pyelm ) {
159  PyObject* args = PyTuple_New( 0 );
160  PyObject* self = PyObject_Call( pyelm, args, nullptr );
161  Py_DECREF( args );
162  Py_DECREF( pyelm );
163 
164  if ( self ) {
165  // initialize base class, which then allows queryInterface as appropriate
167 
168  // set the interfaces on the python-side manager
169  PyObject* result = setManager( self );
170  Py_DECREF( self );
171 
172  if ( ! result ) {
173  PyErr_Print();
174  sc.ignore();
175  return StatusCode::FAILURE;
176  }
177 
178  return sc;
179  }
180 
181  }
182 
183  }
184 
185  PyErr_Print();
186  return StatusCode::FAILURE;
187 }
188 
189 
190 //=========================================================================
191 // Run the algorithms for the current event
192 //=========================================================================
194 {
196 // forward to call to the python-side object
197  if ( m_manager != nullptr )
198  {
199  // forward call, if python side manager available
200  PyObject* pycontext = PyCapsule_New ( const_cast<EventContext*>(&ctx), nullptr, nullptr);
201  PyObject* result = PyObject_CallMethod( m_manager, execalgs,
202  (char*)"O", pycontext);
203  Py_DECREF (pycontext);
204 
205  if ( ! result )
206  {
207  PyErr_Print(); // should use MessageSvc instead
208  return StatusCode::FAILURE;
209  }
210 
211 #if PY_MAJOR_VERSION < 3
212  if ( PyInt_Check( result ) || PyLong_Check( result ) )
213  {
214  StatusCode sc = StatusCode( (int) PyInt_AS_LONG( result ) );
215  Py_DECREF( result );
216  return sc;
217  }
218 #else
219  if ( PyLong_Check( result ) )
220  {
221  StatusCode sc = StatusCode( (int) PyLong_AS_LONG( result ) );
222  Py_DECREF( result );
223  return sc;
224  }
225 #endif
226 
227  // FIXME: allow python result to be a statuscode
228  MsgStream log( msgSvc(), name() );
229  log << MSG::ERROR
230  << "result from python event loop manager has unexpected type."
231  << endmsg;
232  Py_DECREF( result );
233  return StatusCode::FAILURE;
234  }
235 
236 // otherwise, let base class handle it
238 }
239 
240 
241 //=========================================================================
242 // Implementation of IAppMgrUI::finalize
243 //=========================================================================
245 {
247  Py_XDECREF( m_manager );
248 
249  return this->AthenaEventLoopMgr::finalize();
250 }
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
AthenaEventLoopMgr
The default ATLAS batch event loop manager.
Definition: AthenaEventLoopMgr.h:66
get_generator_info.result
result
Definition: get_generator_info.py:21
AthenaEventLoopMgr::name
virtual const std::string & name() const
Definition: AthenaEventLoopMgr.h:188
PyAthenaEventLoopMgr::pointer
static PyAthenaEventLoopMgr * pointer()
outside access
Definition: PyAthenaEventLoopMgr.cxx:55
AthenaEventLoopMgr::initialize
virtual StatusCode initialize()
implementation of IAppMgrUI::initalize
Definition: AthenaEventLoopMgr.cxx:130
PyAthenaEventLoopMgr::executeAlgorithms
virtual StatusCode executeAlgorithms(const EventContext &)
Run the algorithms for the current event.
Definition: PyAthenaEventLoopMgr.cxx:193
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
PyAthenaEventLoopMgr::PyAthenaEventLoopMgr
PyAthenaEventLoopMgr()
Unimplemented features to keep Reflex happy.
PyAthenaEventLoopMgr::initialize
virtual StatusCode initialize()
implementation of IAppMgrUI::initalize
Definition: PyAthenaEventLoopMgr.cxx:148
RootUtils::PyGILStateEnsure
Definition: PyAthenaGILStateEnsure.h:20
PyAthenaEventLoopMgr::getManager
PyObject * getManager()
Definition: PyAthenaEventLoopMgr.cxx:131
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
PyAthenaEventLoopMgr.h
Implementation of the AthenaEventLoopMgr that allows selective and specific overrides in python....
AthenaEventLoopMgr::finalize
virtual StatusCode finalize()
implementation of IAppMgrUI::finalize
Definition: AthenaEventLoopMgr.cxx:372
PyAthenaEventLoopMgr
Implementation of the AthenaEventLoopMgr that allows selective and specific overrides in python....
Definition: PyAthenaEventLoopMgr.h:36
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
AthenaEventLoopMgr::m_clearStorePolicy
StringProperty m_clearStorePolicy
Definition: AthenaEventLoopMgr.h:139
CSV_InDetExporter.old
old
Definition: CSV_InDetExporter.py:145
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
PyAthenaGILStateEnsure.h
IEventSeek
Abstract interface for seeking within an event stream.
Definition: IEventSeek.h:27
PyAthenaEventLoopMgr::setManager
PyObject * setManager(PyObject *)
actual manager object
Definition: PyAthenaEventLoopMgr.cxx:85
checker_macros.h
Define macros for attributes used to control the static checker.
PyObject
_object PyObject
Definition: IPyComponent.h:26
AthenaEventLoopMgr::executeAlgorithms
virtual StatusCode executeAlgorithms(const EventContext &)
Run the algorithms for the current event.
Definition: AthenaEventLoopMgr.cxx:519
PyAthenaEventLoopMgr::m_manager
PyObject * m_manager
Definition: PyAthenaEventLoopMgr.h:62
python.CaloScaleNoiseConfig.args
args
Definition: CaloScaleNoiseConfig.py:80
PyAthenaEventLoopMgr::finalize
virtual StatusCode finalize()
implementation of IAppMgrUI::finalize
Definition: PyAthenaEventLoopMgr.cxx:244
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Definition: PyAthenaEventLoopMgr.cxx:25