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  IEventProcessor* ep = nullptr;
57 
58  static const bool CREATEIF( false );
59  if ( ( Gaudi::svcLocator()->service( "PyAthenaEventLoopMgr", ep, CREATEIF ) ).isSuccess() ) {
60  ep->addRef();
61  return dynamic_cast< PyAthenaEventLoopMgr* >( ep );
62  }
63 
64  return nullptr;
65 }
66 
67 
68 //=========================================================================
69 // Standard Constructor
70 //=========================================================================
72  ISvcLocator* svcLoc )
73  : AthenaEventLoopMgr( name, svcLoc ), m_manager( nullptr )
74 {
79  AthenaEventLoopMgr::m_clearStorePolicy.set( "BeginEvent" );
80 }
81 
82 
83 //=========================================================================
84 // Python side manager set/get
85 //=========================================================================
87 {
89  if ( ! PyObject_HasAttrString( mgr, execalgs ) )
90  {
91  PyErr_SetString( PyExc_TypeError, "given object is not a manager" );
92  return nullptr;
93  }
94 
95 // set on ourselves
97  Py_INCREF( mgr );
98  m_manager = mgr;
99 
100 // set onto the module as a module global (this may replace the old one, so
101 // users are best served to only access this through the module)
102  PyObject* pyelm = PyImport_AddModule( const_cast< char* >( "AthenaServices.PyAthenaEventLoopMgr" ) );
103  if ( pyelm ) {
104  Py_INCREF( mgr );
105  if (PyModule_AddObject( pyelm, const_cast< char* >( "EventLoopMgr" ), mgr ) < 0) {
106  Py_DECREF( mgr );
107  }
108  }
109 
110 // hand the python side its interfaces
111  PyObject* pyself = PyCapsule_New( (void*)static_cast< IEventSeek* >( this ), nullptr, nullptr );
112 #if PY_MAJOR_VERSION < 3
113  PyObject* method = PyString_FromString( "_installServices" );
114 #else
115  PyObject* method = PyUnicode_FromString( "_installServices" );
116 #endif
117  PyObject* result = PyObject_CallMethodObjArgs( mgr, method, pyself, 0 );
118  Py_DECREF( method );
119  Py_DECREF( pyself );
120 
121  if ( ! result )
122  return nullptr;
123 
124 // return old value (with its refcount), if set previously; or None
125  if ( old != nullptr )
126  return old;
127 
128  Py_INCREF( Py_None );
129  return Py_None;
130 }
131 
133 {
135  if ( ! m_manager )
136  {
137  Py_INCREF( Py_None );
138  return Py_None;
139  }
140 
141  Py_INCREF( m_manager );
142  return m_manager;
143 }
144 
145 
146 //=========================================================================
147 // Implementation of IAppMgrUI::initialize
148 //=========================================================================
150 {
152 // get the PyAthenaEventLoopMgr python-side class
153  PyObject* modpyelm = PyImport_ImportModule( const_cast< char* >( "AthenaServices.PyAthenaEventLoopMgr" ) );
154  if ( modpyelm ) {
155 
156  PyObject* pyelm = PyObject_GetAttrString( modpyelm, const_cast< char* >( "PyAthenaEventLoopMgr" ) );
157  Py_DECREF( modpyelm );
158 
159  if ( pyelm ) {
160  PyObject* args = PyTuple_New( 0 );
161  PyObject* self = PyObject_Call( pyelm, args, nullptr );
162  Py_DECREF( args );
163  Py_DECREF( pyelm );
164 
165  if ( self ) {
166  // initialize base class, which then allows queryInterface as appropriate
168 
169  // set the interfaces on the python-side manager
170  PyObject* result = setManager( self );
171  Py_DECREF( self );
172 
173  if ( ! result ) {
174  PyErr_Print();
175  sc.ignore();
176  return StatusCode::FAILURE;
177  }
178 
179  return sc;
180  }
181 
182  }
183 
184  }
185 
186  PyErr_Print();
187  return StatusCode::FAILURE;
188 }
189 
190 
191 //=========================================================================
192 // Run the algorithms for the current event
193 //=========================================================================
195 {
197 // forward to call to the python-side object
198  if ( m_manager != nullptr )
199  {
200  // forward call, if python side manager available
201  PyObject* pycontext = PyCapsule_New ( const_cast<EventContext*>(&ctx), nullptr, nullptr);
202  PyObject* result = PyObject_CallMethod( m_manager, execalgs,
203  (char*)"O", pycontext);
204  Py_DECREF (pycontext);
205 
206  if ( ! result )
207  {
208  PyErr_Print(); // should use MessageSvc instead
209  return StatusCode::FAILURE;
210  }
211 
212 #if PY_MAJOR_VERSION < 3
213  if ( PyInt_Check( result ) || PyLong_Check( result ) )
214  {
215  StatusCode sc = StatusCode( (int) PyInt_AS_LONG( result ) );
216  Py_DECREF( result );
217  return sc;
218  }
219 #else
220  if ( PyLong_Check( result ) )
221  {
222  StatusCode sc = StatusCode( (int) PyLong_AS_LONG( result ) );
223  Py_DECREF( result );
224  return sc;
225  }
226 #endif
227 
228  // FIXME: allow python result to be a statuscode
229  MsgStream log( msgSvc(), name() );
230  log << MSG::ERROR
231  << "result from python event loop manager has unexpected type."
232  << endmsg;
233  Py_DECREF( result );
234  return StatusCode::FAILURE;
235  }
236 
237 // otherwise, let base class handle it
239 }
240 
241 
242 //=========================================================================
243 // Implementation of IAppMgrUI::finalize
244 //=========================================================================
246 {
248  Py_XDECREF( m_manager );
249 
250  return this->AthenaEventLoopMgr::finalize();
251 }
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
AthenaEventLoopMgr
The default ATLAS batch event loop manager.
Definition: AthenaEventLoopMgr.h:69
get_generator_info.result
result
Definition: get_generator_info.py:21
AthenaEventLoopMgr::name
virtual const std::string & name() const
Definition: AthenaEventLoopMgr.h:195
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:194
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:149
RootUtils::PyGILStateEnsure
Definition: PyAthenaGILStateEnsure.h:20
PyAthenaEventLoopMgr::getManager
PyObject * getManager()
Definition: PyAthenaEventLoopMgr.cxx:132
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:383
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:142
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:86
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:530
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:245
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Definition: PyAthenaEventLoopMgr.cxx:25