Commits

Anonymous committed 417b990

first import of a set of Gaudi components for use in PyAthena

Comments (0)

Files changed (19)

AthenaPython/AthenaPythonDict.h

+// -*- C++ -*-
+
+// Python includes
+#include "Python.h"
+
+// hack to please gccxml...
+#ifdef PACKAGE_VERSION
+ #undef PACKAGE_VERSION
+#endif
+
+#ifndef PACKAGE_VERSION
+ #define PACKAGE_VERSION "unknown"
+#endif
+
+#include "AthenaPython/PyAthenaAlg.h"
+#include "AthenaPython/PyAthenaSvc.h"
+#include "AthenaPython/PyAthenaTool.h"
+
+#include "AthenaKernel/IProxyDict.h"
+#include "AthenaKernel/IClassIDSvc.h"
+#include "AthenaKernel/IThinningSvc.h"
+
+#include "SGTools/DataProxy.h"
+
+namespace StoreGateDict_dict {
+  struct tmp {
+    SG::DataProxy m_proxy;
+    std::vector<SG::DataProxy*> m_proxies;
+    std::vector<const SG::DataProxy*> m_constProxies;
+  };
+}
+
+// namespace AthenaPythonDict_dict {
+//   struct tmp {
+//     //
+//   };
+// }

AthenaPython/PyAthenaAlg.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyAthenaAlg.h 
+// Header file for class PyAthena::Alg
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef ATHENAPYTHON_PYATHENAALG_H 
+#define ATHENAPYTHON_PYATHENAALG_H 
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/Algorithm.h"
+
+// Forward declaration
+// Python
+struct _object;
+typedef _object PyObject;
+
+namespace PyAthena {
+
+class Alg : public ::Algorithm
+{ 
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /** constructor 
+   *  @param self python objects
+   *  @param name name of algorithm instance 
+   */
+  //Alg( PyObject* self , const std::string& name );
+  Alg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~Alg(); 
+
+  // Assignment operator: 
+  //AlgorithmEx &operator=(const AlgorithmEx &alg); 
+
+  // Framework's Hooks
+  virtual StatusCode initialize();
+  virtual StatusCode reinitialize();
+  virtual StatusCode beginRun();
+  virtual StatusCode execute();
+  virtual StatusCode endRun();
+  virtual StatusCode finalize();
+
+  virtual StatusCode sysInitialize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  Alg();
+
+//   /// Constructor with parameters: 
+//   Alg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Pointer to self (from the python world)
+  PyObject* m_self;
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace PyAthena
+
+#endif //> ATHENAPYTHON_PYATHENAALG_H

AthenaPython/PyAthenaSvc.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyAthenaSvc.h 
+// Header file for class PyAthena::Svc
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef ATHENAPYTHON_PYATHENASVC_H 
+#define ATHENAPYTHON_PYATHENASVC_H 
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/Service.h"
+
+// Forward declaration
+// Python
+struct _object;
+typedef _object PyObject;
+
+namespace PyAthena {
+
+class Svc : public Service
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  Svc( const std::string& name, ISvcLocator* svcLocator );
+
+  /// Destructor: 
+  virtual ~Svc(); 
+
+  /// Gaudi Service Implementation
+  //@{
+  virtual StatusCode initialize();
+  virtual StatusCode reinitialize();
+  virtual StatusCode beginRun();
+  virtual StatusCode endRun();
+  virtual StatusCode finalize();
+  virtual StatusCode queryInterface( const InterfaceID& riid, 
+                                     void** ppvInterface );
+  //@}
+
+  virtual StatusCode sysInitialize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  static const InterfaceID& interfaceID();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  Svc();
+
+  /// Pointer to self (from the python world)
+  PyObject* m_self;
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace PyAthena
+
+#endif //> ATHENAPYTHON_PYATHENASVC_H

AthenaPython/PyAthenaTool.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyAthenaTool.h 
+// Header file for class PyAthena::Tool
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef ATHENAPYTHON_PYATHENATOOL_H 
+#define ATHENAPYTHON_PYATHENATOOL_H 
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/AlgTool.h"
+
+// Forward declaration
+// Python
+struct _object;
+typedef _object PyObject;
+
+namespace PyAthena {
+
+class Tool : public ::AlgTool
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  Tool( const std::string& type,
+	const std::string& name, 
+	const IInterface* parent );
+
+  /// Destructor: 
+  virtual ~Tool(); 
+
+  // Athena tool's Hooks
+  virtual StatusCode  initialize();
+  virtual StatusCode  finalize();
+
+  static const InterfaceID& interfaceID();
+
+  /// python binding
+  void setPyObject( PyObject *self );
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  Tool();
+
+  /// Pointer to self (from the python world)
+  PyObject* m_self;
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace PyAthena
+
+#endif //> ATHENAPYTHON_PYATHENATOOL_H

AthenaPython/selection.xml

+<lcgdict>
+
+  <class name="IProxyDict" />
+  <!-- <class name="SG::DataProxy" /> -->
+  <class name="std::vector<SG::DataProxy*>" />
+  <class name="std::vector<const SG::DataProxy*>" />
+
+  <!-- Framework bindings -->
+  <class name="IClassIDSvc" />
+  <class name="IThinningSvc" />
+
+  <class name="PyAthena::Alg" />
+  <class name="PyAthena::Svc" />
+  <class name="PyAthena::Tool" />
+
+</lcgdict>
+
+2007-11-12  Sebastien Binet  <binet@lblbox>
+
+	* tagging AthenaPython-00-00-00
+	* first import of a set of gaudi components for use in PyAthena
+	
+
+package AthenaPython
+author  Sebastien Binet <binet@cern.ch>
+
+## For Athena policies: it has to be the first use statement
+use AtlasPolicy 	AtlasPolicy-*
+
+## For Gaudi tools, services and objects
+use GaudiInterface 	GaudiInterface-* 	External
+
+## Put here your package dependencies...
+use AtlasPython 	AtlasPython-*  		External
+
+use AthenaKernel 	AthenaKernel-*		Control
+
+use CLIDSvc        	CLIDSvc-*           	Control
+use CLIDComps		CLIDComps-*		Control 
+
+use SGTools 	   	SGTools-*           	Control
+use StoreGate		StoreGate-*		Control
+##
+
+branches AthenaPython src src/components python
+
+library AthenaPython *.cxx components/*.cxx
+#apply_pattern installed_library
+apply_pattern component_library
+
+apply_pattern declare_python_modules files="*.py"
+
+
+#
+# dictionary creation (patterns from Gaudi/SEAL) for bindings
+#
+private
+use AtlasReflex		AtlasReflex-*		External -no_auto_imports
+
+apply_pattern lcgdict dict=AthenaPython selectionfile=selection.xml \
+   headerfiles="../AthenaPython/AthenaPythonDict.h"
+#   extralibfiles="../src/pyext/AthenaPythonPyExt.cxx"
+
+#macro_append AthenaPythonPyExt_pp_cppflags " -I$(Python_inc) "
+#macro_append AthenaPythonDict_shlibflags " $(Python_linkopts)"
+end_private

python/Configurables.py

+# @file: Configurables.py
+# @purpose: a set of Configurables for the PyAthena components
+# @author: Sebastien Binet <binet@cern.ch>
+
+import AthenaCommon.Constants as Lvl
+from AthenaCommon.Configurable import (ConfigurablePyAlgorithm,
+                                       ConfigurableAlgTool,
+                                       ConfigurableService)
+
+### Configurable base class for PyServices ---------------------------------
+class ConfigurablePyService( ConfigurableService ):
+   def __init__( self, name, **kwargs ):
+      super( ConfigurablePyService, self ).__init__( name )
+      self._jobOptName = name
+
+      for n, v in kwargs.items():
+         setattr(self, n, v)
+
+   def getDlls( self ):
+      return None
+
+   def getHandle( self ):
+      return None
+
+### Configurable base class for PyAlgTools ---------------------------------
+class ConfigurablePyAlgTool( ConfigurableAlgTool ):
+   def __init__( self, name, **kwargs ):
+      super( ConfigurablePyAlgTool, self ).__init__( name )
+      self._jobOptName = name
+
+      for n, v in kwargs.items():
+         setattr(self, n, v)
+
+   def getDlls( self ):
+      return None
+
+   def getHandle( self ):
+      return None
+
+class PyComponents(object):
+    instances = {}
+    pass
+
+from AthenaCommon import CfgMgr
+
+### Configurable base class for PyAlgorithms ---------------------------------
+_PyAlg = CfgMgr.PyAthena__Alg
+class CfgPyAlgorithm(_PyAlg):
+    __slots__ = ( '_pyKlass', )
+
+    def __init__(self, name, klass, **kw):
+        # init base class
+        kw['name'] = name
+        super(CfgPyAlgorithm, self).__init__( **kw )
+
+        self._pyKlass = klass
+
+    def setDefaults(cls, handle):
+
+        if not isinstance(handle, CfgPyAlgorithm):
+            return
+
+        print "."*80
+        import PyAthena
+        name = handle.getName()
+        if name in PyComponents.instances:
+            print "???????????"
+            return
+        #PyComponents.instances[name] = "%s/%s" % ( pyKlass, name )
+        exec( 'PyComponents.instances[name] = %s( "%s" )' %
+              (handle._pyKlass, name) )
+        print "."*80
+
+        ## schedule the PyComponentMgr service
+        from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+        if not hasattr(svcMgr, 'PyComponentMgr'):
+            svcMgr += CfgMgr.PyAthena__PyComponentMgr(
+                'PyComponentMgr',
+                OutputLevel = Lvl.VERBOSE )
+            
+        return
+    pass 
+del _PyAlg
+CfgMgr.PyAthena__Alg = CfgPyAlgorithm
+
+### Configurable base class for PyServices ------------------------------------
+_PySvc = CfgMgr.PyAthena__Svc
+class CfgPyService(_PySvc):
+    __slots__ = ( '_pyKlass', )
+
+    def __init__(self, name, klass, **kw):
+        # init base class
+        kw['name'] = name
+        super(CfgPyService, self).__init__( **kw )
+
+        self._pyKlass = klass
+
+    def setDefaults(cls, handle):
+
+        if not isinstance(handle, CfgPyService):
+            return
+
+        print "."*80
+        import PyAthena
+        name = handle.getName()
+        if name in PyComponents.instances:
+            print "???????????"
+            return
+        #PyComponents.instances[name] = "%s/%s" % ( pyKlass, name )
+        exec( 'PyComponents.instances[name] = %s( "%s" )' %
+              (handle._pyKlass, name) )
+        print "."*80
+
+        ## schedule the PyComponentMgr service
+        from AthenaCommon.AppMgr import theApp, ServiceMgr as svcMgr
+        if not hasattr(svcMgr, 'PyComponentMgr'):
+            svcMgr += CfgMgr.PyAthena__PyComponentMgr(
+                'PyComponentMgr',
+                OutputLevel = Lvl.VERBOSE )
+            
+        return
+    pass 
+del _PySvc
+CfgMgr.PyAthena__Svc = CfgPyService
+
+

python/PyAthena.py

+# @file: PyAthena.py
+# @purpose: a set of Python bindings for pyathena
+# @author: Sebastien Binet <binet@cern.ch>
+
+import PyCintex
+
+class StatusCode:
+    Success = 1
+    Failure = 0
+
+import numpy, array
+### PyAthena.Alg --------------------------------------------------------------
+_Alg = PyCintex.makeClass( "PyAthena::Alg" )
+class Alg( _Alg ):
+    """
+    """
+    def __init__(self, name):
+
+        from AthenaCommon.Logging import logging
+        self.msg = logging.getLogger( name )
+        self.msg.error( "__init__ !!")
+
+        from gaudimodule import gbl, Interface
+        svcLoc = gbl.Gaudi.svcLocator()
+        algMgr = Interface(gbl.IAlgManager).cast(svcLoc)
+
+        ## init base class
+        super(Alg, self).__init__(name, svcLoc)
+
+        sc = algMgr.addAlgorithm(self)
+        if sc.isFailure():
+            raise RuntimeError, "Unable to add PyAthena::Alg/%s" % name
+
+        return
+
+    def __del__(self):
+        sc = self._algMgr.removeAlgorithm(self)
+        if sc.isFailure() : pass
+
+    def initialize(self):
+        self.msg.info( "==> initialize..." )
+        self.data = array.array( 'd' )
+        return StatusCode.Success
+    
+    def reinitialize(self):
+        self.msg.info( "==> re-initialize..." )
+        return StatusCode.Success
+    
+    def execute(self):
+        self.msg.info( "==> execute..." )
+        self.data.append( 42 )
+        return StatusCode.Success
+
+    def finalize(self):
+        self.msg.info( "==> finalize..." )
+        self.msg.info( "data: %r", self.data )
+        return StatusCode.Success
+
+    def beginRun(self):
+        self.msg.info( "==> beginRun..." )
+        return StatusCode.Success
+
+    def endRun(self):
+        self.msg.info( "==> endRun..." )
+        return StatusCode.Success
+    
+    pass # PyAthena.Alg
+
+### PyAthena.Svc --------------------------------------------------------------
+_Svc = PyCintex.makeClass( "PyAthena::Svc" )
+class Svc( object ):
+    """
+    """
+    def __init__(self, name):
+
+        from AthenaCommon.Logging import logging
+        self.msg = logging.getLogger( name )
+        self.msg.error( "__init__ !!")
+
+        from gaudimodule import gbl, Interface
+        svcLoc = gbl.Gaudi.svcLocator()
+        svcMgr = Interface(gbl.ISvcManager).cast(svcLoc)
+
+        ## init base class
+        #super(Svc, self).__init__(name, svcLoc)
+
+##         priority = 99999
+##         sc = self._svcMgr.addService(self, priority)
+##         if sc.isFailure():
+##             raise RuntimeError, "Unable to add PyAthena::Svc/%s" % name
+        
+        return
+
+##     def __del__(self):
+##         sc = self._svcMgr.removeService(self)
+##         if sc.isFailure() : pass
+
+    def initialize(self):
+        self.msg.info( "==> initialize..." )
+        return StatusCode.Success
+    
+    def reinitialize(self):
+        self.msg.info( "==> re-initialize..." )
+        return StatusCode.Success
+    
+    def finalize(self):
+        self.msg.info( "==> finalize..." )
+        return StatusCode.Success
+
+    def beginRun(self):
+        self.msg.info( "==> beginRun..." )
+        return StatusCode.Success
+
+    def endRun(self):
+        self.msg.info( "==> endRun..." )
+        return StatusCode.Success
+    
+    pass # PyAthena.Svc
+

python/__init__.py

+# hook for the py-module

src/PyAthenaAlg.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyAthenaAlg.cxx 
+// Implementation file for class PyAthena::Alg
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// Python includes
+#include "Python.h"
+
+// Package includes
+#include "PyAthenaUtils.h"
+#include "AthenaPython/PyAthenaAlg.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaKernel/IPyComponentMgr.h"
+
+namespace PyAthena {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+/*
+Alg::Alg( PyObject* self, const std::string& name ) :
+  ::Algorithm( name, Gaudi::svcLocator() ),
+  m_self     ( self )
+{
+  //
+  // Property declaration
+  // 
+  //declareProperty( "Property", m_nProperty );
+
+  std::cout << "------> " << name << std::endl;
+
+  // The owner of this component is Python (as creator) therefore
+  // it should not be deleted by Gaudi (added an extra addRef()). 
+  addRef();
+  addRef();
+}
+*/
+
+Alg::Alg( const std::string& name, ISvcLocator* svcLocator ) :
+  ::Algorithm( name, svcLocator ),
+  m_self     ( 0 )
+{
+  std::cout << "------> " << name << std::endl;
+}
+
+// Destructor
+///////////////
+Alg::~Alg()
+{ 
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::DEBUG << "Calling destructor" << endreq;
+  std::cout << "-----> PyAthena::Alg::~Alg()..." << std::endl;
+  Py_XDECREF( m_self );
+}
+
+// Framework's Hooks
+////////////////////////////
+StatusCode 
+Alg::initialize()
+{
+  std::cout << "-----> PyAthena::Alg::initialize()..." << std::endl;
+  MsgStream msg( msgSvc(), name() );
+
+  msg << MSG::INFO 
+      << "Initializing " << name() << "..." 
+      << endreq;
+
+  if ( !::Algorithm::initialize().isSuccess() ) {
+    msg << MSG::ERROR
+	<< "Could not initialize Algorithm base class !!"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  return PyAthena::call_python_method( m_self, "initialize" );
+}
+
+StatusCode 
+Alg::reinitialize()
+{
+  MsgStream msg( msgSvc(), name() );
+
+  msg << MSG::INFO 
+      << "Re-Initializing " << name() << "..." 
+      << endreq;
+
+  if ( !::Algorithm::reinitialize().isSuccess() ) {
+    msg << MSG::ERROR
+	<< "Could not Re-initialize Algorithm base class !!"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  return PyAthena::call_python_method( m_self, "reinitialize" );
+}
+
+StatusCode 
+Alg::beginRun()
+{ 
+  return PyAthena::call_python_method( m_self, "beginRun" );
+}
+
+StatusCode 
+Alg::endRun()
+{
+  return PyAthena::call_python_method( m_self, "endRun" );
+}
+
+StatusCode 
+Alg::finalize()
+{
+  std::cout << "-----> PyAthena::Alg::finalize()..." << std::endl;
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::INFO 
+      << "Finalizing " << name() << "..." 
+      << endreq;
+
+  return PyAthena::call_python_method( m_self, "finalize" );
+}
+
+StatusCode 
+Alg::execute()
+{  
+  std::cout << "-----> PyAthena::Alg::execute()..." << std::endl;
+//   m_msg << MSG::DEBUG << "Executing " << name() << "..." 
+// 	<< endreq;
+
+  return PyAthena::call_python_method( m_self, "execute" );
+}
+
+StatusCode
+Alg::sysInitialize()
+{
+  std::cout << "-----> PyAthena::Alg::sysInitialize()..." << std::endl;
+
+  ServiceHandle<IPyComponentMgr> pyMgr( "PyComponentMgr", name() );
+  if ( !pyMgr.retrieve().isSuccess() ) {
+    MsgStream msg( msgSvc(), name() );
+    msg << MSG::ERROR
+	<< "Could not retrieve service [" << pyMgr.typeAndName() << "] !!"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  // first retrieve our python object cousin...
+  m_self = pyMgr->pyObject( name() );
+
+  if ( m_self == Py_None ) {
+    MsgStream msg( msgSvc(), name() );
+    msg << MSG::ERROR
+	<< "Wrapped PyObject is NONE !"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  // re-route to usual sysInit...
+  return ::Algorithm::sysInitialize();
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace PyAthena

src/PyAthenaSvc.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyAthenaSvc.cxx 
+// Implementation file for class PyAthena::Svc
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// Python includes
+#include "Python.h"
+
+// Package includes
+#include "PyAthenaUtils.h"
+#include "AthenaPython/PyAthenaSvc.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaKernel/IPyComponentMgr.h"
+
+namespace PyAthena {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+//   Svc::Svc( PyObject* self, const std::string& name ) : 
+//   ::Service( name, Gaudi::svcLocator() ),
+//   m_self   ( self )
+// {
+//   //
+//   // Property declaration
+//   // 
+//   //declareProperty( "Property", m_nProperty );
+
+//   // The owner of this component Algorithm is Python (as creator) therefore
+//   // it should not be deleted by Gaudi (added an extra addRef()). 
+//   addRef();
+//   addRef();
+// }
+
+Svc::Svc( const std::string& name, ISvcLocator* svcLocator ) :
+  ::Service( name, svcLocator ),
+  m_self   ( 0 )
+{}
+
+// Destructor
+///////////////
+Svc::~Svc()
+{ 
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::DEBUG << "Calling destructor" << endreq;
+  Py_XDECREF( m_self );
+}
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode 
+Svc::initialize()
+{
+  MsgStream msg( msgSvc(), name() );
+
+  msg << MSG::INFO 
+      << "Initializing " << name() << "..." 
+      << endreq;
+
+  if ( !Service::initialize().isSuccess() ) {
+    msg << MSG::ERROR
+	<< "Could not initialize Service base class !!"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  return PyAthena::call_python_method( m_self, "initialize" );
+}
+
+StatusCode 
+Svc::reinitialize()
+{
+  MsgStream msg( msgSvc(), name() );
+
+  msg << MSG::INFO 
+      << "Re-Initializing " << name() << "..." 
+      << endreq;
+
+  if ( !Service::reinitialize().isSuccess() ) {
+    msg << MSG::ERROR
+	<< "Could not Re-initialize Service base class !!"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  return PyAthena::call_python_method( m_self, "reinitialize" );
+}
+
+StatusCode 
+Svc::finalize()
+{
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::INFO 
+      << "Finalizing " << name() << "..." 
+      << endreq;
+
+  return PyAthena::call_python_method( m_self, "finalize" );
+}
+
+StatusCode 
+Svc::beginRun()
+{
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::INFO 
+      << "beginRun " << name() << "..." 
+      << endreq;
+
+  return PyAthena::call_python_method( m_self, "beginRun" );
+}
+
+StatusCode 
+Svc::endRun()
+{
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::INFO 
+      << "endRun " << name() << "..." 
+      << endreq;
+
+  return PyAthena::call_python_method( m_self, "endRun" );
+}
+
+// Query the interfaces.
+//   Input: riid, Requested interface ID
+//          ppvInterface, Pointer to requested interface
+//   Return: StatusCode indicating SUCCESS or FAILURE.
+// N.B. Don't forget to release the interface after use!!!
+StatusCode 
+Svc::queryInterface(const InterfaceID& riid, void** ppvInterface) 
+{
+  if ( interfaceID().versionMatch(riid) )    {
+    *ppvInterface = static_cast<PyAthena::Svc*>(this);
+  } else  {
+    // Interface is not directly available: try out a base class
+    return ::Service::queryInterface(riid, ppvInterface);
+  }
+  addRef();
+  return StatusCode::SUCCESS;
+}
+
+const InterfaceID& 
+Svc::interfaceID() { 
+  static const InterfaceID _IID("PyAthena::Svc", 1, 0);
+  return _IID; 
+}
+
+StatusCode
+Svc::sysInitialize()
+{
+  std::cout << "-----> PyAthena::Svc::sysInitialize()..." << std::endl;
+
+  ServiceHandle<IPyComponentMgr> pyMgr( "PyComponentMgr", name() );
+  if ( !pyMgr.retrieve().isSuccess() ) {
+    MsgStream msg( msgSvc(), name() );
+    msg << MSG::ERROR
+	<< "Could not retrieve service [" << pyMgr.typeAndName() << "] !!"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  // first retrieve our python object cousin...
+  m_self = pyMgr->pyObject( name() );
+
+  if ( m_self == Py_None ) {
+    MsgStream msg( msgSvc(), name() );
+    msg << MSG::ERROR
+	<< "Wrapped PyObject is NONE !"
+	<< endreq;
+    return StatusCode::FAILURE;
+  }
+
+  // re-route to usual sysInit...
+  return ::Service::sysInitialize();
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace AthenaPython
+

src/PyAthenaTool.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// Tool.cxx 
+// Implementation file for class Tool
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// Python includes
+#include "Python.h"
+
+// Package includes
+#include "AthenaPython/PyAthenaTool.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Property.h"
+
+namespace PyAthena {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+Tool::Tool( const std::string& type, 
+	    const std::string& name, 
+	    const IInterface* parent ) : 
+  ::AlgTool( type, name, parent ),
+  m_self   ( 0 )
+{
+  //
+  // Property declaration
+  // 
+  //declareProperty( "Property", m_nProperty );
+
+}
+
+// Destructor
+///////////////
+Tool::~Tool()
+{ 
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::DEBUG << "Calling destructor" << endreq;
+
+  Py_XDECREF( m_self );
+}
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode Tool::initialize()
+{
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::INFO 
+      << "Initializing " << name() << "..." 
+      << endreq;
+
+  return ::AlgTool::initialize();
+}
+
+StatusCode Tool::finalize()
+{
+  MsgStream msg( msgSvc(), name() );
+  msg << MSG::INFO 
+      << "Finalizing " << name() << "..." 
+      << endreq;
+
+  return ::AlgTool::finalize();
+}
+
+const InterfaceID& 
+Tool::interfaceID() { 
+  static const InterfaceID _IID("PyAthena::Tool", 1, 0);
+  return _IID; 
+}
+
+void Tool::setPyObject( PyObject *self )
+{ m_self = self; }  
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace Package

src/PyAthenaUtils.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyAthenaUtils.cxx 
+// Implementation file for various PyAthena helpers
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// Python includes
+#include "Python.h"
+
+// Package includes
+#include "PyAthenaUtils.h"
+
+StatusCode 
+PyAthena::call_python_method( PyObject* self, const char* methodName )
+{
+  // that's a bit ugly...
+  char* method = const_cast<char*>(methodName);
+
+  StatusCode sc = StatusCode::FAILURE;
+  // check arguments 
+  if ( 0 == self || 0 == method ) { return StatusCode::FAILURE; }
+  
+  // call Python 
+  PyObject* r = PyObject_CallMethod( self, method, const_cast<char*>("") );
+  
+  if ( 0 == r ) { 
+    PyErr_Print();
+    return sc; 
+  }
+  
+  if ( PyInt_Check( r ) ) {
+    sc = PyInt_AS_LONG( r );
+    Py_DECREF( r );
+    return sc;
+  }
+  
+  // look for the method getCode with the signature: 
+  //  ' int getCode() '
+  PyObject* c = PyObject_CallMethod( r, 
+				     const_cast<char*>("getCode"), 
+				     const_cast<char*>("") );
+  
+  if        ( 0 == c            ) { PyErr_Print();
+  } else if ( PyLong_Check( c ) ) { sc = PyLong_AsLong( c );
+  } else {
+    
+    std::string msg( " call_python_method unexpected type from '" );
+    msg += method;
+    msg += "().getCode()' ";
+    PyErr_SetString( PyExc_TypeError, msg.c_str() );
+    PyErr_Print();
+  }
+
+  // release used objects 
+  Py_XDECREF( c );
+  Py_XDECREF( r );
+
+  return sc;
+}
+

src/PyAthenaUtils.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyAthenaUtils.h 
+// Header file for various PyAthena helpers and utils
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef ATHENAPYTHON_PYATHENAUTILS_H 
+#define ATHENAPYTHON_PYATHENAUTILS_H 
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/StatusCode.h"
+
+// Forward declaration
+// Python
+struct _object;
+typedef _object PyObject;
+
+namespace PyAthena {
+
+  /// call the python method
+  StatusCode call_python_method ( PyObject* self , const char* method ) ;
+
+}
+
+#endif // ATHENAPYTHON_PYATHENAUTILS_H 

src/PyComponentMgr.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyComponentMgr.cxx 
+// Implementation file for class PyComponentMgr
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// Python includes
+#include "Python.h"
+
+// AthenaPython includes
+#include "PyComponentMgr.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/SvcFactory.h"
+
+using namespace PyAthena;
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+PyComponentMgr::PyComponentMgr( const std::string& name, 
+				ISvcLocator* pSvcLocator ) : 
+  Service ( name,     pSvcLocator ),
+  m_msg   ( msgSvc(),        name ),
+  m_module( 0 ),
+  m_dict  ( 0 )
+{
+  //
+  // Property declaration
+  // 
+  //declareProperty( "Property", m_nProperty, "descr" );
+
+}
+
+// Destructor
+///////////////
+PyComponentMgr::~PyComponentMgr()
+{ 
+  m_msg << MSG::DEBUG << "Calling destructor" << endreq;
+
+  // we own the module
+  Py_XDECREF( m_module );
+}
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode 
+PyComponentMgr::initialize()
+{
+  // initialize MsgStream
+  m_msg.setLevel( m_outputLevel.value() );
+
+  m_msg << MSG::INFO 
+      << "Initializing " << name() << "..." 
+      << endreq;
+
+  m_msg << MSG::DEBUG << "Initializing base class..." << endreq;
+  if ( Service::initialize().isFailure() ) {
+    m_msg << MSG::ERROR
+        << "Could not intialize base class !!"
+        << endreq;
+    return StatusCode::FAILURE;
+  } else {
+    m_msg << MSG::VERBOSE << "Base class initialized" << endreq;
+  }
+
+  const std::string pyModuleName = "AthenaPython.Configurables";
+
+  // import the module holding the dictionary of component instances
+  m_msg << MSG::DEBUG << "Importing module [" << pyModuleName << "]..."
+	<< endreq;
+  m_module = PyImport_ImportModule( const_cast<char*>(pyModuleName.c_str()) );
+  if ( !m_module || !PyModule_Check( m_module ) ) {
+    PyErr_Clear();
+    m_msg << MSG::ERROR
+	  << "Could not import [" << pyModuleName << "] !!"
+	  << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  const std::string pyClassName = "PyComponents";
+  PyObject* pyClass = 0;
+  pyClass = PyDict_GetItemString( PyModule_GetDict( m_module ),
+				  const_cast<char*>( pyClassName.c_str() ) );
+  
+  // borrowed ref. so ->increment
+  Py_XINCREF( pyClass );
+
+  if ( !pyClass ) {
+    PyErr_Clear();
+    m_msg << MSG::ERROR
+	  << "Could not retrieve class [" << pyClassName << "] from module ["
+	  << pyModuleName << "] !!"
+	  << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  m_dict = PyObject_GetAttrString( pyClass,
+				   const_cast<char*>( "instances" ) );
+  if ( !m_dict || !PyDict_Check( m_dict ) ) {
+    m_msg << MSG::ERROR
+	  << "Could not retrieve attribute [instances] from class ["
+	  << pyClassName << "] !!"
+	  << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode 
+PyComponentMgr::finalize()
+{
+  m_msg << MSG::INFO 
+      << "Finalizing " << name() << "..." 
+      << endreq;
+
+  return StatusCode::SUCCESS;
+}
+
+// Query the interfaces.
+//   Input: riid, Requested interface ID
+//          ppvInterface, Pointer to requested interface
+//   Return: StatusCode indicating SUCCESS or FAILURE.
+// N.B. Don't forget to release the interface after use!!!
+StatusCode 
+PyComponentMgr::queryInterface(const InterfaceID& riid, void** ppvInterface) 
+{
+  if ( IPyComponentMgr::interfaceID().versionMatch(riid) ) {
+    *ppvInterface = dynamic_cast<IPyComponentMgr*>(this);
+  } else {
+    // Interface is not directly available : try out a base class
+    return Service::queryInterface(riid, ppvInterface);
+  }
+  addRef();
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+PyObject*
+PyComponentMgr::pyObject( const std::string& name )
+{
+  // Check we have a valid dict.
+  if ( !m_dict || !PyDict_Check(m_dict) ) {
+    m_msg << MSG::ERROR
+	  << "Invalid repository of Python components !!"
+	  << endreq;
+    Py_INCREF( Py_None );
+    return Py_None;
+  }
+  
+  PyObject* o = PyDict_GetItemString( m_dict, 
+				      const_cast<char*>(name.c_str()) );
+  // borrowed ref -> incr
+  Py_XINCREF( o );
+
+  if ( !o ) {
+    PyErr_Clear();
+    m_msg << MSG::ERROR
+	  << "No such python component [" << name << "] !!"
+	  << endreq;
+    Py_XDECREF( o ); // <============ ??? FIXME: do we do that ???
+    Py_INCREF( Py_None );
+    return Py_None;
+  }
+
+  return o;
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 

src/PyComponentMgr.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// PyComponentMgr.h 
+// Header file for class PyAthena::PyComponentMgr
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef PERFMONCOMPS_PYCOMPONENTMGR_H 
+#define PERFMONCOMPS_PYCOMPONENTMGR_H 
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/MsgStream.h"
+
+// AthenaKernel includes
+#include "AthenaKernel/IPyComponentMgr.h"
+
+// Forward declaration
+class ISvcLocator;
+template <class TYPE> class SvcFactory;
+
+namespace PyAthena {
+
+class PyComponentMgr : virtual public IPyComponentMgr,
+		               public Service
+{ 
+  friend class SvcFactory<PyAthena::PyComponentMgr>;
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  PyComponentMgr( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~PyComponentMgr(); 
+
+  /// Gaudi Service Implementation
+  //@{
+  StatusCode initialize();
+  StatusCode finalize();
+  virtual StatusCode queryInterface( const InterfaceID& riid, 
+                                     void** ppvInterface );
+  //@}
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  static const InterfaceID& interfaceID();
+
+  /**
+   * Retrieve a python object from the python world
+   */
+  PyObject* pyObject( const std::string& name );
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private methods: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  PyComponentMgr();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// MsgStream for talking with the outside world
+  MsgStream m_msg;
+
+  /// The module holding all python component instances
+  PyObject* m_module;
+
+  /// The dictionary of python objects (created from the Python prompt)
+  PyObject* m_dict;
+}; 
+
+/// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+/// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+inline const InterfaceID& PyComponentMgr::interfaceID() 
+{ 
+   return IPyComponentMgr::interfaceID(); 
+}
+
+} //> namespace PyAthena
+
+#endif //> ATHENAPYTHON_PYATHENA_PYCOMPONENTMGR_H

src/components/AthenaPython_entries.cxx

+#include "AthenaPython/PyAthenaAlg.h"
+#include "AthenaPython/PyAthenaSvc.h"
+#include "AthenaPython/PyAthenaTool.h"
+#include "../PyComponentMgr.h"
+
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+// DECLARE_NAMESPACE_TOOL_FACTORY( PyAthena, Tool )
+DECLARE_NAMESPACE_SERVICE_FACTORY( PyAthena, Svc )
+DECLARE_NAMESPACE_ALGORITHM_FACTORY( PyAthena, Alg )
+
+DECLARE_NAMESPACE_SERVICE_FACTORY( PyAthena, PyComponentMgr )
+
+DECLARE_FACTORY_ENTRIES( AthenaPython ) {
+
+//   DECLARE_NAMESPACE_TOOL( PyAthena, Tool )
+  DECLARE_NAMESPACE_SERVICE( PyAthena, Svc )
+  DECLARE_NAMESPACE_ALGORITHM( PyAthena, Alg )
+
+  DECLARE_NAMESPACE_SERVICE( PyAthena, PyComponentMgr )
+}

src/components/AthenaPython_load.cxx

+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES( Package )