ATLAS Offline Software
Loading...
Searching...
No Matches
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
37
39
40
41//- data ------------------------------------------------------------------
42namespace {
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{
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
92 PyObject* old = m_manager;
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
159 StatusCode sc = this->AthenaEventLoopMgr::initialize();
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//=========================================================================
186StatusCode PyAthenaEventLoopMgr::executeAlgorithms(const EventContext& ctx)
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}
#define endmsg
_object PyObject
static Double_t sc
Implementation of the AthenaEventLoopMgr that allows selective and specific overrides in python.
virtual StatusCode initialize() override
implementation of IAppMgrUI::initalize
virtual StatusCode finalize() override
implementation of IAppMgrUI::finalize
StringProperty m_clearStorePolicy
virtual const std::string & name() const override
AthenaEventLoopMgr(const std::string &nam, ISvcLocator *svcLoc)
Standard Constructor.
virtual StatusCode executeAlgorithms(const EventContext &)
Run the algorithms for the current event.
Abstract interface for seeking within an event stream.
Definition IEventSeek.h:27
virtual StatusCode initialize()
implementation of IAppMgrUI::initalize
PyObject * setManager(PyObject *)
actual manager object
static PyAthenaEventLoopMgr * pointer()
outside access
PyAthenaEventLoopMgr(const std::string &name, ISvcLocator *svcLoc)
Standard Constructor.
virtual StatusCode executeAlgorithms(const EventContext &)
Run the algorithms for the current event.
virtual StatusCode finalize()
implementation of IAppMgrUI::finalize
PyAthenaEventLoopMgr()
Unimplemented features to keep Reflex happy.