ATLAS Offline Software
PyAthenaEventLoopMgr.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 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 
24 // Python
25 #include "Python.h"
26 
27 // Gaudi
28 #include "GaudiKernel/MsgStream.h"
29 #include "GaudiKernel/Bootstrap.h"
30 #include "GaudiKernel/IConversionSvc.h"
31 #include "GaudiKernel/ISvcLocator.h"
32 #include "GaudiKernel/IAlgorithm.h"
33 #include "GaudiKernel/DataSvc.h"
34 
35 // AthenaServices
36 #include "PyAthenaEventLoopMgr.h"
37 
39 
40 
41 //- data ------------------------------------------------------------------
42 namespace {
43 
44  char* execalgs = const_cast< char* >( "executeAlgorithms" );
45 
46 } // unnamed namespace
47 
48 
49 //=========================================================================
50 // Outside access to the event loop manager
51 //=========================================================================
53 
54  SmartIF<IEventProcessor> ep{Gaudi::svcLocator()->service( "PyAthenaEventLoopMgr", /*createIf*/false )};
55  if ( ep ) {
56  ep->addRef();
57  return dynamic_cast< PyAthenaEventLoopMgr* >( ep.get() );
58  }
59 
60  return nullptr;
61 }
62 
63 
64 //=========================================================================
65 // Standard Constructor
66 //=========================================================================
68  ISvcLocator* svcLoc )
69  : AthenaEventLoopMgr( name, svcLoc ), m_manager( nullptr )
70 {
75  AthenaEventLoopMgr::m_clearStorePolicy.set( "BeginEvent" );
76 }
77 
78 
79 //=========================================================================
80 // Python side manager set/get
81 //=========================================================================
83 {
85  if ( ! PyObject_HasAttrString( mgr, execalgs ) )
86  {
87  PyErr_SetString( PyExc_TypeError, "given object is not a manager" );
88  return nullptr;
89  }
90 
91 // set on ourselves
93  Py_INCREF( mgr );
94  m_manager = mgr;
95 
96 // set onto the module as a module global (this may replace the old one, so
97 // users are best served to only access this through the module)
98  PyObject* pyelm = PyImport_AddModule( const_cast< char* >( "AthenaServices.PyAthenaEventLoopMgr" ) );
99  if ( pyelm ) {
100  Py_INCREF( mgr );
101  if (PyModule_AddObject( pyelm, const_cast< char* >( "EventLoopMgr" ), mgr ) < 0) {
102  Py_DECREF( mgr );
103  }
104  }
105 
106 // hand the python side its interfaces
107  PyObject* pyself = PyCapsule_New( (void*)static_cast< IEventSeek* >( this ), nullptr, nullptr );
108  PyObject* method = PyUnicode_FromString( "_installServices" );
109  PyObject* result = PyObject_CallMethodObjArgs( mgr, method, pyself, 0 );
110  Py_DECREF( method );
111  Py_DECREF( pyself );
112 
113  if ( ! result )
114  return nullptr;
115 
116 // return old value (with its refcount), if set previously; or None
117  if ( old != nullptr )
118  return old;
119 
120  Py_INCREF( Py_None );
121  return Py_None;
122 }
123 
125 {
127  if ( ! m_manager )
128  {
129  Py_INCREF( Py_None );
130  return Py_None;
131  }
132 
133  Py_INCREF( m_manager );
134  return m_manager;
135 }
136 
137 
138 //=========================================================================
139 // Implementation of IAppMgrUI::initialize
140 //=========================================================================
142 {
144 // get the PyAthenaEventLoopMgr python-side class
145  PyObject* modpyelm = PyImport_ImportModule( const_cast< char* >( "AthenaServices.PyAthenaEventLoopMgr" ) );
146  if ( modpyelm ) {
147 
148  PyObject* pyelm = PyObject_GetAttrString( modpyelm, const_cast< char* >( "PyAthenaEventLoopMgr" ) );
149  Py_DECREF( modpyelm );
150 
151  if ( pyelm ) {
152  PyObject* args = PyTuple_New( 0 );
153  PyObject* self = PyObject_Call( pyelm, args, nullptr );
154  Py_DECREF( args );
155  Py_DECREF( pyelm );
156 
157  if ( self ) {
158  // initialize base class, which then allows queryInterface as appropriate
160 
161  // set the interfaces on the python-side manager
162  PyObject* result = setManager( self );
163  Py_DECREF( self );
164 
165  if ( ! result ) {
166  PyErr_Print();
167  sc.ignore();
168  return StatusCode::FAILURE;
169  }
170 
171  return sc;
172  }
173 
174  }
175 
176  }
177 
178  PyErr_Print();
179  return StatusCode::FAILURE;
180 }
181 
182 
183 //=========================================================================
184 // Run the algorithms for the current event
185 //=========================================================================
187 {
189 // forward to call to the python-side object
190  if ( m_manager != nullptr )
191  {
192  // forward call, if python side manager available
193  PyObject* pycontext = PyCapsule_New ( const_cast<EventContext*>(&ctx), nullptr, nullptr);
194  PyObject* result = PyObject_CallMethod( m_manager, execalgs,
195  (char*)"O", pycontext);
196  Py_DECREF (pycontext);
197 
198  if ( ! result )
199  {
200  PyErr_Print(); // should use MessageSvc instead
201  return StatusCode::FAILURE;
202  }
203 
204  if ( PyLong_Check( result ) )
205  {
206  StatusCode sc = StatusCode( (int) PyLong_AS_LONG( result ) );
207  Py_DECREF( result );
208  return sc;
209  }
210 
211  // FIXME: allow python result to be a statuscode
212  MsgStream log( msgSvc(), name() );
213  log << MSG::ERROR
214  << "result from python event loop manager has unexpected type."
215  << endmsg;
216  Py_DECREF( result );
217  return StatusCode::FAILURE;
218  }
219 
220 // otherwise, let base class handle it
222 }
223 
224 
225 //=========================================================================
226 // Implementation of IAppMgrUI::finalize
227 //=========================================================================
229 {
231  Py_XDECREF( m_manager );
232 
233  return this->AthenaEventLoopMgr::finalize();
234 }
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
AthenaEventLoopMgr
The default ATLAS batch event loop manager.
Definition: AthenaEventLoopMgr.h:63
get_generator_info.result
result
Definition: get_generator_info.py:21
python.CaloAddPedShiftConfig.args
args
Definition: CaloAddPedShiftConfig.py:47
AthenaEventLoopMgr::name
virtual const std::string & name() const
Definition: AthenaEventLoopMgr.h:185
PyAthenaEventLoopMgr::pointer
static PyAthenaEventLoopMgr * pointer()
outside access
Definition: PyAthenaEventLoopMgr.cxx:52
AthenaEventLoopMgr::initialize
virtual StatusCode initialize()
implementation of IAppMgrUI::initalize
Definition: AthenaEventLoopMgr.cxx:127
PyAthenaEventLoopMgr::executeAlgorithms
virtual StatusCode executeAlgorithms(const EventContext &)
Run the algorithms for the current event.
Definition: PyAthenaEventLoopMgr.cxx:186
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:141
RootUtils::PyGILStateEnsure
Definition: PyAthenaGILStateEnsure.h:20
PyAthenaEventLoopMgr::getManager
PyObject * getManager()
Definition: PyAthenaEventLoopMgr.cxx:124
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:369
PyAthenaEventLoopMgr
Implementation of the AthenaEventLoopMgr that allows selective and specific overrides in python....
Definition: PyAthenaEventLoopMgr.h:34
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
AthenaEventLoopMgr::m_clearStorePolicy
StringProperty m_clearStorePolicy
Definition: AthenaEventLoopMgr.h:136
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:82
PyObject
_object PyObject
Definition: IPyComponent.h:26
AthenaEventLoopMgr::executeAlgorithms
virtual StatusCode executeAlgorithms(const EventContext &)
Run the algorithms for the current event.
Definition: AthenaEventLoopMgr.cxx:516
PyAthenaEventLoopMgr::m_manager
PyObject * m_manager
Definition: PyAthenaEventLoopMgr.h:60
PyAthenaEventLoopMgr::finalize
virtual StatusCode finalize()
implementation of IAppMgrUI::finalize
Definition: PyAthenaEventLoopMgr.cxx:228