Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 #if PY_MAJOR_VERSION < 3
109  PyObject* method = PyString_FromString( "_installServices" );
110 #else
111  PyObject* method = PyUnicode_FromString( "_installServices" );
112 #endif
113  PyObject* result = PyObject_CallMethodObjArgs( mgr, method, pyself, 0 );
114  Py_DECREF( method );
115  Py_DECREF( pyself );
116 
117  if ( ! result )
118  return nullptr;
119 
120 // return old value (with its refcount), if set previously; or None
121  if ( old != nullptr )
122  return old;
123 
124  Py_INCREF( Py_None );
125  return Py_None;
126 }
127 
129 {
131  if ( ! m_manager )
132  {
133  Py_INCREF( Py_None );
134  return Py_None;
135  }
136 
137  Py_INCREF( m_manager );
138  return m_manager;
139 }
140 
141 
142 //=========================================================================
143 // Implementation of IAppMgrUI::initialize
144 //=========================================================================
146 {
148 // get the PyAthenaEventLoopMgr python-side class
149  PyObject* modpyelm = PyImport_ImportModule( const_cast< char* >( "AthenaServices.PyAthenaEventLoopMgr" ) );
150  if ( modpyelm ) {
151 
152  PyObject* pyelm = PyObject_GetAttrString( modpyelm, const_cast< char* >( "PyAthenaEventLoopMgr" ) );
153  Py_DECREF( modpyelm );
154 
155  if ( pyelm ) {
156  PyObject* args = PyTuple_New( 0 );
157  PyObject* self = PyObject_Call( pyelm, args, nullptr );
158  Py_DECREF( args );
159  Py_DECREF( pyelm );
160 
161  if ( self ) {
162  // initialize base class, which then allows queryInterface as appropriate
164 
165  // set the interfaces on the python-side manager
166  PyObject* result = setManager( self );
167  Py_DECREF( self );
168 
169  if ( ! result ) {
170  PyErr_Print();
171  sc.ignore();
172  return StatusCode::FAILURE;
173  }
174 
175  return sc;
176  }
177 
178  }
179 
180  }
181 
182  PyErr_Print();
183  return StatusCode::FAILURE;
184 }
185 
186 
187 //=========================================================================
188 // Run the algorithms for the current event
189 //=========================================================================
191 {
193 // forward to call to the python-side object
194  if ( m_manager != nullptr )
195  {
196  // forward call, if python side manager available
197  PyObject* pycontext = PyCapsule_New ( const_cast<EventContext*>(&ctx), nullptr, nullptr);
198  PyObject* result = PyObject_CallMethod( m_manager, execalgs,
199  (char*)"O", pycontext);
200  Py_DECREF (pycontext);
201 
202  if ( ! result )
203  {
204  PyErr_Print(); // should use MessageSvc instead
205  return StatusCode::FAILURE;
206  }
207 
208 #if PY_MAJOR_VERSION < 3
209  if ( PyInt_Check( result ) || PyLong_Check( result ) )
210  {
211  StatusCode sc = StatusCode( (int) PyInt_AS_LONG( result ) );
212  Py_DECREF( result );
213  return sc;
214  }
215 #else
216  if ( PyLong_Check( result ) )
217  {
218  StatusCode sc = StatusCode( (int) PyLong_AS_LONG( result ) );
219  Py_DECREF( result );
220  return sc;
221  }
222 #endif
223 
224  // FIXME: allow python result to be a statuscode
225  MsgStream log( msgSvc(), name() );
226  log << MSG::ERROR
227  << "result from python event loop manager has unexpected type."
228  << endmsg;
229  Py_DECREF( result );
230  return StatusCode::FAILURE;
231  }
232 
233 // otherwise, let base class handle it
235 }
236 
237 
238 //=========================================================================
239 // Implementation of IAppMgrUI::finalize
240 //=========================================================================
242 {
244  Py_XDECREF( m_manager );
245 
246  return this->AthenaEventLoopMgr::finalize();
247 }
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:45
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:190
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:145
RootUtils::PyGILStateEnsure
Definition: PyAthenaGILStateEnsure.h:20
PyAthenaEventLoopMgr::getManager
PyObject * getManager()
Definition: PyAthenaEventLoopMgr.cxx:128
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:228
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:241