| # Gaudi Framework, version v20r4
Generated: 8 Jan 2009

# Bindings.py

Go to the documentation of this file.

    00001 # File: GaudiPython/Bindings.py
    00002 # Author: Pere Mato (pere.mato@cern.ch)
    00003
    00004 """ GaudiPython.Bindings module.
    00005     This module provides the basic bindings of the main Gaudi
    00006     components to Python. It is itself based on the PyCintex
    00007     extersion module provided by LCG/ROOT that provided
    00008     dynamic bindigns of classes for which LCG dictionaires exists.
    00009 """
    00010
    00011 __all__ = [ 'gbl','InterfaceCast', 'Interface', 'PropertyEntry',
    00012             'AppMgr', 'PyAlgorithm', 'CallbackStreamBuf',
    00013             'iAlgorithm', 'iDataSvc', 'iHistogramSvc','iNTupleSvc','iService', 'iAlgTool', 'Helper',
    00014             'SUCCESS', 'FAILURE', 'toArray',
    00015             'ROOT', 'makeNullPointer', 'makeClass', 'setOwnership',
    00016             'getClass', 'loaddict', 'deprecation' ]
    00017
    00018 import os, sys, string, warnings, re
    00019 import PyCintex
    00020 import Pythonizations
    00021 # Import Configurable from AthenaCommon or GaudiKernel if the first is not
    00022 # available.
    00023 from GaudiKernel.Proxy.Configurable import Configurable, getNeededConfigurables
    00024
    00025 #namespaces
    00026 gbl    = PyCintex.makeNamespace('')
    00027 Gaudi = gbl.Gaudi
    00028
    00029 _gaudi = None
    00030
    00031 #----Useful shortcuts for classes -------------------------------------------------------
    00032 #Helper              = PyCintex.makeClass     ('GaudiPython::Helper')
    00033 Helper              = gbl.GaudiPython.Helper
    00034 StringProperty      = gbl.SimpleProperty     ('string','BoundedVerifier<string>')
    00035 StringPropertyRef   = gbl.SimplePropertyRef  ('string','NullVerifier<string>')
    00036 GaudiHandleProperty = gbl.GaudiHandleProperty
    00037 GaudiHandleArrayProperty = gbl.GaudiHandleArrayProperty
    00038 DataObject          = gbl.DataObject
    00039 SUCCESS             = gbl.StatusCode( gbl.StatusCode.SUCCESS, True )
    00040 FAILURE             = gbl.StatusCode( gbl.StatusCode.FAILURE, True )
    00041 # toIntArray, toShortArray, etc.
    00042 for l in [ l for l in dir(Helper) if re.match("^to.*Array$",l) ]:
    00043     exec "%s = Helper.%s"%(l,l)
    00044     __all__.append(l)
    00045
    00046 # FIXME: (MCl) Hack to handle ROOT 5.18 and ROOT >= 5.20
    00047 if hasattr(Helper,"toArray"):
    00048     # This is not backward compatible, but allows to use the same signature
    00049     # with all the versions of ROOT.
    00050     toArray = lambda typ: getattr(Helper,"toArray")
    00051 else:
    00052     # forward to the actual implementation of GaudiPython::Helper::toArray<T>
    00053     toArray = lambda typ: getattr(Helper,"toArray<%s>"%typ)
    00054
    00055 #----Convenient accessors to PyROOT functionality ---------------------------------------
    00056 ROOT            = PyCintex.libPyROOT
    00057 makeNullPointer = PyCintex.libPyROOT.MakeNullPointer
    00058 makeClass       = PyCintex.libPyROOT.MakeRootClass
    00059 setOwnership    = PyCintex.libPyROOT.SetOwnership
    00060
    00061 def deprecation(message):
    00062   warnings.warn('GaudiPython: '+ message, DeprecationWarning, stacklevel=3)
    00063
    00064 #----InterfaceCast class ----------------------------------------------------------------
    00065 class InterfaceCast(object) :
    00066   """ Helper class to obtain the adequeste interface from a component
    00067       by using the Gaudi queryInterface() mechanism """
    00068   def __init__(self, t ) :
    00069     if type(t) is str : t = PyCintex.makeClass(t)
    00070     self.type = t
    00071   def __call__(self, obj) :
    00072     if obj :
    00073       ip = PyCintex.libPyROOT.MakeNullPointer(self.type)
    00074       if obj.queryInterface(self.type.interfaceID(), ip).isSuccess() :
    00075         return ip
    00076     return None
    00077   cast = __call__
    00078 #---Interface class (for backward compatibility)-----------------------------------------
    00079 class Interface(InterfaceCast) :
    00080   def __init__(self, t ):
    00081     deprecation('Use InterfaceCast class instead')
    00082     InterfaceCast.__init__(self,t)
    00083   def cast(self, obj) :
    00084     return self(obj)
    00085
    00086 #----load dictionary function using Gaudi function---------------------------------------
    00087 def loaddict(dict) :
    00088   """ Load a LCG dictionary using various mechanisms"""
    00089   if Helper.loadDynamicLib(dict) == 1 : return
    00090   else :
    00091     try:
    00092       PyCintex.loadDict(dict)
    00093     except:
    00094       raise ImportError, 'Error loading dictionary library'
    00095
    00096 #---get a class (by loading modules if needed)--------------------------------------------
    00097 def getClass( name , libs = [] ) :
    00098     """
    00099     Function to retrieve a certain C++ class by name and to load dictionary if requested
    00100
    00101     Usage:
    00102
    00103     from gaudimodule import getClass
    00104     # one knows that class is already loaded
    00105     AppMgr     = getClass( 'ApplicationMgr'           )
    00106     # one knows where to look for class, if not loaded yet
    00107     MCParticle = getClass( 'MCParticle' , 'EventDict' )
    00108     # one knows where to look for class, if not loaded yet
    00109     Vertex     = getClass( 'Vertex' , ['EventDict', 'PhysEventDict'] )
    00110     """
    00111     # see if class is already loaded
    00112     if hasattr( gbl , name )  : return getattr( gbl , name )
    00113     # try to load dictionaries and  look for the required class
    00114     if type(libs) is not list : libs = [libs]
    00115     for lib in libs :
    00116       loaddict( lib )
    00117       if hasattr( gbl , name ) : return getattr( gbl , name )
    00118     # return None ( or raise exception? I do not know...  )
    00119     return None
    00120
    00121 #----PropertyEntry class---------------------------------------------------------------------
    00122 class PropertyEntry(object) :
    00123   """ holds the value and the documentation string of a property """
    00124   def __init__(self, prop) :
    00125     self._type = type(prop).__name__
    00126     self.__doc__ = " --- Property type is " + self.ptype()
    00127
    00128     if   issubclass(type(prop),GaudiHandleProperty) :
    00129       self._value = prop.value()   # do nothing for ATLAS' handles
    00130     elif issubclass(type(prop),GaudiHandleArrayProperty) :
    00131       self._value = prop.value()   # do nothing for ATLAS' handles
    00132     else :
    00133       # for all other types try to extract the native python type
    00134       try:    self._value = eval( prop.toString() , {} , {} )
    00135       except: self._value = prop.value()
    00136
    00137     self.__doc__ += " --- Default value = " + str(self._value) + " --- "
    00138     if prop.documentation() != 'none':
    00139       self.__doc__ = prop.documentation() + '\\n' + self.__doc__
    00140     ## keep the original property
    00141     self._property = prop # property itself
    00142   def value(self) :
    00143     return self._value
    00144   def ptype(self) :
    00145     return self._type
    00146   def property(self):
    00147     "Return the underlying  property itself "
    00148     return self._property
    00149   def documentation(self) :
    00150     return self.__doc__
    00151   def hasDoc(self):
    00152     return len(self.__doc__)>0 and self.__doc__ != 'none'
    00153
    00154 #----iProperty class---------------------------------------------------------------------
    00155 class iProperty(object) :
    00156   """ Python equivalent to the C++ Property interface """
    00157   def __init__(self, name, ip = None) :
    00158     if ip : self.__dict__['_ip'] = InterfaceCast(gbl.IProperty)(ip)
    00159     else  : self.__dict__['_ip'] = None
    00160     self.__dict__['_svcloc'] = gbl.Gaudi.svcLocator()
    00161     optsvc = Helper.service(self._svcloc,'JobOptionsSvc')
    00162     if optsvc : self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(optsvc)
    00163     else      : self.__dict__['_optsvc'] = None
    00164     self.__dict__['_name'] = name
    00165   def getInterface(self) :
    00166     if not self._ip : self.retrieveInterface()
    00167     return self._ip
    00168   def retrieveInterface(self) :
    00169     pass
    00170   def __call_interface_method__(self,ifname,method,*args):
    00171     if not getattr(self,ifname) : self.retrieveInterface()
    00172     return getattr(getattr(self,ifname),method)(*args)
    00173   def __setattr__(self, name, value):
    00174     """
    00175     The method which is used for setting the property from the given value.
    00176     - In the case of the valid instance it sets the property through IProperty interface
    00177     - In the case of placeholder the property is added to JobOptionsCatalogue
    00178     """
    00179     if hasattr( value, 'toStringProperty' ):
    00180       # user defined behaviour
    00181       value = '%s' % value.toStringProperty()
    00182     ip = self.getInterface()
    00183     if ip :
    00184       if not gbl.Gaudi.Utils.hasProperty ( ip , name ) :
    00185         raise AttributeError, 'property %s does not exist' % name
    00186       prop = ip.getProperty(name)
    00187       if not type( value ) == type( prop.value() ) :
    00188         if not long  == type( value ) : value = '%s' % value
    00189         else                          : value = '%d' % value
    00190         if prop.fromString( value ).isFailure() :
    00191           raise AttributeError, 'property %s could not be set from %s' % (name,value)
    00192       else :
    00193         if not prop.setValue( value ) :
    00194           raise AttributeError, 'property %s could not be set from %s' % (name,value)
    00195     else :
    00196         if   type(value) == str : value = '"%s"' % value # need double quotes
    00197         elif type(value) == long: value = '%d'   % value # prevent pending 'L'
    00198         sp = StringProperty( name , str(value))
    00199         self._optsvc.addPropertyToCatalogue( self._name , sp )
    00200   def __getattr__(self, name ):
    00201     """
    00202     The method which returns the value for the given property
    00203     - In the case of the valid instance it returns the valid property value through IProperty interface
    00204     - In the case of placeholder the property value is retrieevd from JobOptionsCatalogue
    00205     """
    00206     ip = self.getInterface()
    00207     if ip :
    00208       if not gbl.Gaudi.Utils.hasProperty ( ip , name ) :
    00209         raise AttributeError, 'property %s does not exist' % name
    00210       prop = ip.getProperty(name)
    00211       if   StringProperty    == type( prop )   : return prop.value()
    00212       elif StringPropertyRef == type( prop )   : return prop.value()
    00213       try:     return eval( prop.toString(), {}, {} )
    00214       except : return p.value()
    00215     else :
    00216       props = self._optsvc.getProperties(self._name)
    00217       for p in props :
    00218         if not p.name() == name : continue
    00219         # from JobOptionsSvc we always have only strings
    00220         try:    return eval( p.value(), {}, {} )
    00221         except: return p.value()
    00222       raise AttributeError, 'property %s does not exist' % name
    00223   def properties(self):
    00224     dct = {}
    00225     props = None
    00226     ip = self.getInterface()
    00227     if ip :
    00228       props = ip.getProperties()
    00229       propsFrom = self._name # "interface"
    00230     else:
    00231       props = self._optsvc.getProperties( self._name )
    00232       propsFrom = "jobOptionsSvc"
    00233     if props:
    00234       for p in props :
    00235         try:
    00236           dct[p.name()] = PropertyEntry(p)
    00237         except (ValueError,TypeError),e:
    00238           raise ValueError, "gaudimodule.iProperty.properties(): %s%s processing property %s.%s = %s" % \
    00239                 (e.__class__.__name__, e.args, propsFrom, p.name(), p.value())
    00240     return dct
    00241   def name(self) :
    00242     return self._name
    00243
    00244 #----iService class---------------------------------------------------------------------
    00245 class iService(iProperty) :
    00246   """ Python equivalent to IProperty interface """
    00247   def __init__(self, name, isvc = None ) :
    00248     iProperty.__init__(self, name, isvc )
    00249     if isvc : self.__dict__['_isvc'] = InterfaceCast(gbl.IService)(isvc)
    00250     else    : self.__dict__['_isvc'] = None
    00251   def retrieveInterface(self) :
    00252     isvc = Helper.service(self._svcloc,self._name)
    00253     if isvc : iService.__init__(self, self._name, isvc)
    00254   initialize   = lambda self : self.__call_interface_method__("_isvc","initialize")
    00255   start        = lambda self : self.__call_interface_method__("_isvc","start")
    00256   stop         = lambda self : self.__call_interface_method__("_isvc","stop")
    00257   finalize     = lambda self : self.__call_interface_method__("_isvc","finalize")
    00258   reinitialize = lambda self : self.__call_interface_method__("_isvc","reinitialize")
    00259   restart      = lambda self : self.__call_interface_method__("_isvc","restart")
    00260   def isValid(self) :
    00261     if self._isvc: return True
    00262     else :         return False
    00263
    00264 #----iAlgorithm class---------------------------------------------------------------------
    00265 class iAlgorithm(iProperty) :
    00266   """ Python equivalent to IAlgorithm interface """
    00267   def __init__(self, name, ialg = None ) :
    00268     iProperty.__init__(self, name, ialg )
    00269     if ialg : self.__dict__['_ialg'] = InterfaceCast(gbl.IAlgorithm)(ialg)
    00270     else    : self.__dict__['_ialg'] = None
    00271   def retrieveInterface(self) :
    00272     ialg = Helper.algorithm(InterfaceCast(gbl.IAlgManager)(self._svcloc),self._name)
    00273     if ialg : iAlgorithm.__init__(self, self._name, ialg)
    00274   initialize   = lambda self : self.__call_interface_method__("_ialg","initialize")
    00275   start        = lambda self : self.__call_interface_method__("_ialg","start")
    00276   execute      = lambda self : self.__call_interface_method__("_ialg","execute")
    00277   stop         = lambda self : self.__call_interface_method__("_ialg","stop")
    00278   finalize     = lambda self : self.__call_interface_method__("_ialg","finalize")
    00279   reinitialize = lambda self : self.__call_interface_method__("_ialg","reinitialize")
    00280   restart      = lambda self : self.__call_interface_method__("_ialg","restart")
    00281   sysInitialize   = lambda self : self.__call_interface_method__("_ialg","sysInitialize")
    00282   sysStart        = lambda self : self.__call_interface_method__("_ialg","sysStart")
    00283   sysExecute      = lambda self : self.__call_interface_method__("_ialg","sysExecute")
    00284   sysStop         = lambda self : self.__call_interface_method__("_ialg","sysStop")
    00285   sysFinalize     = lambda self : self.__call_interface_method__("_ialg","sysFinalize")
    00286   sysReinitialize = lambda self : self.__call_interface_method__("_ialg","sysReinitialize")
    00287   sysRestart      = lambda self : self.__call_interface_method__("_ialg","sysRestart")
    00288
    00289 #----iAlgTool class---------------------------------------------------------------------
    00290 class iAlgTool(iProperty) :
    00291   """ Python equivalent to IAlgTool interface (not completed yet) """
    00292   def __init__(self, name, itool = None ) :
    00293     iProperty.__init__(self, name, itool )
    00294     if itool : self.__dict__['_itool'] = itool
    00295     else     : self.__dict__['_itool'] = None
    00296     svc = Helper.service( self._svcloc, 'ToolSvc', True )
    00297     self.__dict__['_toolsvc']= iToolSvc('ToolSvc', svc)
    00298   def retrieveInterface(self) :
    00299     itool = self._toolsvc._retrieve(self._name)
    00300     if itool : iAlgTool.__init__(self, self._name, itool)
    00301   start = lambda self : self.__call_interface_method__("_itool","start")
    00302   stop  = lambda self : self.__call_interface_method__("_itool","stop")
    00303   type  = lambda self : self.__call_interface_method__("_itool","type")
    00304   def name(self) :
    00305     if self._itool : return self._itool.name()
    00306     else : return self._name
    00307
    00308 #----iDataSvc class---------------------------------------------------------------------
    00309 class iDataSvc(iService) :
    00310   def __init__(self, name, idp) :
    00311     iService.__init__(self, name, idp )
    00312     self.__dict__['_idp'] = InterfaceCast(gbl.IDataProviderSvc)(idp)
    00313     self.__dict__['_idm'] = InterfaceCast(gbl.IDataManagerSvc)(idp)
    00314   def registerObject(self, path, obj) :
    00315     if not self._idp : raise AttributeError('C++ service %s does not exist' % self.__dict__['_name'])
    00316     return self._idp.registerObject(path,obj)
    00317   def unregisterObject(self, path) :
    00318     if not self._idp : raise AttributeError('C++ service %s does not exist' % self.__dict__['_name'])
    00319     return self._idp.unregisterObject(path)
    00320   def retrieveObject(self, path) :
    00321     if not self._idp : return  None
    00322     return Helper.dataobject(self._idp, path)
    00323   def __getitem__(self, path) :
    00324     if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
    00325     return Helper.dataobject(self._idp, path)
    00326   def __setitem__(self, path, obj) :
    00327     if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
    00328     return self._idp.registerObject(path,obj)
    00329   def __delitem__(self, path) :
    00330     if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
    00331     return self._idp.unregisterObject(path)
    00332   def leaves(self, node=None) :
    00333     if not node : node = self.retrieveObject('')
    00334     ll = gbl.std.vector('IRegistry*')()
    00335     if type(node) is str : obj = self.retrieveObject(node)
    00336     else                 : obj = node
    00337     if self._idm.objectLeaves(node, ll).isSuccess() : return ll
    00338   def dump(self, node=None) :
    00339     if not node :
    00340       root = self.retrieveObject('')
    00341       if root : node = root.registry()
    00342       else : return
    00343     print node.identifier()
    00344     if node.object() :
    00345       for l in self.leaves(node) : self.dump(l)
    00346   def setRoot(self, name, obj):
    00347     if not self._idm : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
    00348     return self._idm.setRoot(name,obj)
    00349   def clearStore(self):
    00350     if not self._idm : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
    00351     return self._idm.clearStore()
    00352
    00353
    00354 #----iHistogramSvc class---------------------------------------------------------------------
    00355 class iHistogramSvc(iDataSvc) :
    00356   def __init__(self, name, ihs) :
    00357     self.__dict__['_ihs'] = InterfaceCast(gbl.IHistogramSvc)(ihs)
    00358     iDataSvc.__init__(self, name, ihs)
    00359   def retrieve1D(self, path) :
    00360     return Helper.histo1D(self._ihs, path)
    00361   def retrieve2D(self, path) :
    00362     return Helper.histo2D(self._ihs, path)
    00363   def retrieve3D(self, path) :
    00364     return Helper.histo3D(self._ihs, path)
    00365   def retrieveProfile1D(self, path) :
    00366     return Helper.profile1D(self._ihs, path)
    00367   def retrieveProfile2D(self, path) :
    00368     return Helper.profile2D(self._ihs, path)
    00369   def retrieve(self,path):
    00370     """
    00371     Retrieve AIDA histogram or AIDA profile histogram by path in Histogram Transient Store
    00372     >>> svc = ...
    00373     >>> histo = svc.retrieve ( 'path/to/my/histogram' )
    00374     """
    00375     h = self.retrieve1D(path)
    00376     if not h : h = self.retrieve2D(path)
    00377     if not h : h = self.retrieve3D(path)
    00378     if not h : h = self.retrieveProfile1D(path)
    00379     if not h : h = self.retrieveProfile2D(path)
    00380     return h
    00381   def book(self, *args) :
    00382     """
    00383     Book the histograms(1D,2D&3D) , see IHistogramSvc::book
    00384     >>> svc = ...
    00385     >>> histo = svc.book( .... )
    00386     """
    00387     return apply(self._ihs.book,args)
    00388   def bookProf(self, *args) :
    00389     """
    00390     Book the profile(1D&2D) histograms, see IHistogramSvc::bookProf
    00391     >>> svc = ...
    00392     >>> histo = svc.bookProf( .... )
    00393     """
    00394     return apply(self._ihs.bookProf,args)
    00395   def __getitem__ ( self, path ) :
    00396     """
    00397     Retrieve the object from  Histogram Transient Store (by path)
    00398     The reference to AIDA historam is returned (if possible)
    00399     >>> svc = ...
    00400     >>> histo = svc['path/to/my/histogram']
    00401     """
    00402     h = self.retrieve ( path )
    00403     if h : return h
    00404     return iDataSvc.__getitem__( self , path )
    00405   def getAsAIDA ( self , path ) :
    00406     """
    00407     Retrieve the histogram from  Histogram Transient Store (by path)
    00408     The reference to AIDA historam is returned (if possible)
    00409     >>> svc = ...
    00410     >>> histo = svc.getAsAIDA ( 'path/to/my/histogram' )
    00411     """
    00412     return self.__getitem__( path )
    00413   def getAsROOT ( self , path ) :
    00414     """
    00415     Retrieve the histogram from  Histogram Transient Store (by path)
    00416     The Underlying native ROOT object is returned (if possible)
    00417     >>> svc = ...
    00418     >>> histo = svc.getAsROOT ( 'path/to/my/histogram' )
    00419     """
    00420     fun=gbl.Gaudi.Utils.Aida2ROOT.aida2root
    00421     return fun( self.getAsAIDA( path ) )
    00422
    00423 #----iNTupleSvc class---------------------------------------------------------------------
    00424 class iNTupleSvc(iDataSvc) :
    00425   RowWiseTuple    = 42
    00426   ColumnWiseTuple = 43
    00427   def __init__(self, name, ints) :
    00428     self.__dict__['_ints'] = InterfaceCast(gbl.INTupleSvc)(ints)
    00429     iDataSvc.__init__(self, name, ints)
    00430   def book(self, *args) :
    00431     return apply(self._ints.book, args)
    00432   def defineOutput(self, files, typ='ROOT') :
    00433     """ Defines dthe mapping between logical names and the output file
    00434         Usage:
    00435           defineOutput({'LUN1':'MyFile1.root', 'LUN2':'Myfile2.root'}, typ='ROOT')
    00436     """
    00437     out = []
    00438     for o in files :
    00439       out.append( "%s DATAFILE='%s' OPT='RECREATE' TYP='%s'" % ( o, files[o], typ ) )
    00440     self.Output = out
    00441     if AppMgr().HistogramPersistency == 'NONE' : AppMgr().HistogramPersistency = typ
    00442   def __getitem__ ( self, path ) :
    00443     return iDataSvc.__getitem__( self , path )
    00444
    00445
    00446 #----iToolSvc class---------------------------------------------------------------------
    00447 class iToolSvc(iService) :
    00448   def __init__(self, name, its) :
    00449     self.__dict__['_its'] = InterfaceCast(gbl.IToolSvc)(its)
    00450     iService.__init__(self, name, its)
    00451   def _retrieve(self, name, quiet=True):
    00452     sol = _gaudi.OutputLevel
    00453     if quiet : self.OutputLevel = 6
    00454     if name.rfind('.') == -1 :
    00455       itool = Helper.tool(self._its, '', name, None, False )
    00456     elif name[0:8] == 'ToolSvc.' :
    00457       itool = Helper.tool(self._its, '', name[8:], None, False )
    00458     elif name.count('.') > 1 :
    00459       ptool = self._retrieve(name[:name.rfind('.')])
    00460       itool = Helper.tool(self._its, '', name[name.rfind('.')+1:], ptool, False )
    00461     elif _gaudi :
    00462       prop = _gaudi.property(name[:name.rfind('.')])
    00463       itool = Helper.tool(self._its, '', name[name.rfind('.')+1:], prop._ip, False )
    00464     if quiet : self.OutputLevel = sol
    00465     return itool
    00466   def retrieve(self, name):
    00467     return iAlgTool(name, self._retrieve(name,quiet=False))
    00468   def create(self, typ, name=None, parent=None, interface=None) :
    00469     if not name : name = typ
    00470     itool = Helper.tool(self._its, typ, name, parent, True )
    00471     if interface :
    00472       return InterfaceCast(interface)(itool)
    00473     else :
    00474       return iAlgTool(name,itool)
    00475   def release(self, itool) :
    00476     if type(itool) is iAlgTool :
    00477       self._its.releaseTool(itool._itool)
    00478
    00479 #----iJopOptSvc class-------------------------------------------------------------------
    00480 class iJobOptSvc(iService) :
    00481   """
    00482   Python-image of C++ class IJobOptionsSvc
    00483   """
    00484   ## constructor
    00485   def __init__( self , name , svc ) :
    00486     """ constructor """
    00487     self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(svc)
    00488     return iService.__init__( self , name , svc )
    00489   def getProperties( self , component ) :
    00490     """
    00491     Extract *ALL* properties of the given component
    00492     Usage :
    00493     >>> jos   = gaudi.optSvc()
    00494     >>> props = jos.getProperties( 'Name' )
    00495     """
    00496     props = self._optsvc.getProperties( component )
    00497     prps = {}
    00498     if not props : return  prps              # RETURN
    00499     for p in props :
    00500       prop  = p.name().upper()
    00501       try :
    00502         value = eval( p.value() , {} , {} )
    00503       except: value = p.value()
    00504       prps [ prop ] = value
    00505
    00506     return prps                               # RETURN
    00507   def getProperty ( self , component , name ) :
    00508     """
    00509     Get a certain property of the certain component
    00510     Usage:
    00511     >>> jos  = ...
    00512     >>> extServices = jos.getProperty( 'ApplicationMgr', 'ExtSvc' )
    00513     """
    00514     ## get all properties of the component
    00515     all = self.getProperties ( component )
    00516     return all.get( name.upper() , None )     # RETURN
    00517
    00518 #----iEventSelector class------------------------------------------------------------------
    00519 class iEventSelector(iService):
    00520   def __init__(self):
    00521     iService.__init__(self, 'EventSelector', Helper.service(gbl.Gaudi.svcLocator(),'EventSelector'))
    00522     self.__dict__['g'] = AppMgr()
    00523   def open(self, stream, typ = 'POOL_ROOT', opt = 'READ', sel = None, fun = None, collection = None ):
    00524     if typ == 'ROOT' :
    00525       self.g.declSvcType('RootEvtCnvSvc','DbEventCnvSvc')
    00526       self.g.service('RootEvtCnvSvc').DbType  = 'ROOT'
    00527       self.g.createSvc('RootEvtCnvSvc')
    00528       self.g.service('EventPersistencySvc').CnvServices = ['RootEvtCnvSvc']
    00529     elif typ == 'POOL_ROOT':
    00530       cacsvc = self.g.service('PoolDbCacheSvc')
    00531       if hasattr(cacsvc, 'Dlls') : cacsvc.Dlls += ['lcg_RootStorageSvc', 'lcg_XMLCatalog']
    00532       else :                       cacsvc.Dlls = ['lcg_RootStorageSvc', 'lcg_XMLCatalog']
    00533       cacsvc.OutputLevel = 4
    00534       cacsvc.DomainOpts    = [ 'Domain[ROOT_All].CLASS_VERSION=2 TYP=int',
    00535                                'Domain[ROOT_Key].CLASS_VERSION=2 TYP=int',
    00536                                'Domain[ROOT_Tree].CLASS_VERSION=2 TYP=int' ]
    00537       cacsvc.DatabaseOpts  = ['']
    00538       cacsvc.ContainerOpts = ['']
    00539       self.g.createSvc('PoolDbCacheSvc')
    00540       cnvSvcs = [('PoolRootEvtCnvSvc',     'POOL_ROOT'),
    00541                  ('PoolRootTreeEvtCnvSvc', 'POOL_ROOTTREE'),
    00542                  ('PoolRootKeyEvtCnvSvc',  'POOL_ROOTKEY')]
    00543       for svc in cnvSvcs :
    00544         self.g.declSvcType(svc[0], 'PoolDbCnvSvc')
    00545         cnvsvc = self.g.service(svc[0])
    00546         cnvsvc.DbType = svc[1]
    00547       self.g.service('EventPersistencySvc').CnvServices = [ svc[0] for svc in cnvSvcs ]
    00548       for svc in cnvSvcs :
    00549         self.g.createSvc(svc[0])
    00550     self.g.service('EventDataSvc').RootCLID = 1
    00551     if type(stream) != list : stream = [stream]
    00552     fixpart = "TYP=\'%s\' OPT=\'%s\'" % ( typ, opt )
    00553     if sel        : fixpart += " SEL=\'%s\'" % sel
    00554     if fun        : fixpart += " FUN=\'%s\'" % fun
    00555     if collection : fixpart += " COLLECTION=\'%s\'" % collection
    00556     cstream = ["DATAFILE=\'%s\' %s" % ( s, fixpart) for s in stream]
    00557     self.Input = cstream
    00558     self.reinitialize()
    00559   def rewind(self):
    00560     # It is not possible to reinitialze EventSelector only
    00561     self.g.service('EventLoopMgr').reinitialize()
    00562
    00563 #----AppMgr class---------------------------------------------------------------------
    00564 class AppMgr(iService) :
    00565   def __new__ ( cls, *args, **kwargs ):
    00566     global _gaudi
    00567     if not _gaudi :
    00568       newobj = object.__new__( cls, *args, **kwargs )
    00569       cls.__init__(newobj, *args, **kwargs)
    00570       _gaudi = newobj
    00571     return _gaudi
    00572   def __init__(self, outputlevel = -1, joboptions = None, selfoptions = {},
    00573                dllname = None, factname = None) :
    00574     global _gaudi
    00575     if _gaudi : return
    00576     try:
    00577         from GaudiKernel.Proxy.Configurable import expandvars
    00578     except ImportError:
    00579         # pass-through implementation if expandvars is not defined (AthenaCommon)
    00580         expandvars = lambda data : data
    00581     if dllname and factname:
    00582       self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname,factname)
    00583     elif dllname:
    00584       self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname)
    00585     else:
    00586       self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr()
    00587     self.__dict__['_svcloc'] = gbl.Gaudi.svcLocator()
    00588     self.__dict__['_algmgr'] = InterfaceCast(gbl.IAlgManager)(self._appmgr)
    00589     self.__dict__['_evtpro'] = InterfaceCast(gbl.IEventProcessor)(self._appmgr)
    00590     self.__dict__['_svcmgr'] = InterfaceCast(gbl.ISvcManager)(self._appmgr)
    00591     self.__dict__['pyalgorithms'] = []
    00592     iService.__init__(self, 'ApplicationMgr', self._appmgr )
    00593     #------python specific initialization-------------------------------------
    00594     if self.FSMState() < Gaudi.StateMachine.CONFIGURED :  # Not yet configured
    00595       self.JobOptionsType = 'NONE'
    00596       if joboptions :
    00597           from GaudiKernel.ProcessJobOptions import importOptions
    00598           importOptions(joboptions)
    00599       # Ensure that the ConfigurableUser instances have been applied
    00600       import GaudiKernel.Proxy.Configurable
    00601       if hasattr(GaudiKernel.Proxy.Configurable, "applyConfigurableUsers"):
    00602           GaudiKernel.Proxy.Configurable.applyConfigurableUsers()
    00603       # This is the default and could be overridden with "selfopts"
    00604       self.OutputLevel = 3
    00605       selfprops = Configurable.allConfigurables.get('ApplicationMgr',{})
    00606       if selfprops : selfprops = expandvars(selfprops.getValuedProperties())
    00607       for p,v in selfprops.items()   : setattr(self, p, v)
    00608       for p,v in selfoptions.items() : setattr(self, p, v)
    00609       # Override job options
    00610       if outputlevel != -1 : self.OutputLevel = outputlevel
    00611       self.configure()
    00612     #---MessageSvc------------------------------------------------------------
    00613     ms = self.service('MessageSvc')
    00614     if 'MessageSvc' in Configurable.allConfigurables:
    00615         msprops = Configurable.allConfigurables['MessageSvc']
    00616         ms = self.service('MessageSvc')
    00617         if hasattr(msprops,"getValuedProperties"):
    00618             msprops = expandvars(msprops.getValuedProperties())
    00619         for p,v in msprops.items():
    00620             setattr(ms, p, v)
    00621     if outputlevel != -1 : ms.OutputLevel = outputlevel
    00622     #---JobOptions------------------------------------------------------------
    00623     self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(Helper.service(self._svcloc,'JobOptionsSvc'))
    00624     #------Configurables initialization (part2)-------------------------------
    00625     for n in getNeededConfigurables():
    00626       c = Configurable.allConfigurables[n]
    00627       if n in ['ApplicationMgr','MessageSvc'] : continue # These are already done---
    00628       for p, v in  c.getValuedProperties().items() :
    00629         v = expandvars(v)
    00630         # Note: AthenaCommon.Configurable does not have Configurable.PropertyReference
    00631         if hasattr(Configurable,"PropertyReference") and type(v) == Configurable.PropertyReference:
    00632             # this is done in "getFullName", but the exception is ignored,
    00633             # so we do it again to get it
    00634             v = v.__resolve__()
    00635         if   type(v) == str : v = '"%s"' % v # need double quotes
    00636         elif type(v) == long: v = '%d'   % v # prevent pending 'L'
    00637         self._optsvc.addPropertyToCatalogue(n, StringProperty(p,str(v)))
    00638     if hasattr(Configurable,"_configurationLocked"):
    00639         Configurable._configurationLocked = True
    00640   def state(self) : return self._isvc.FSMState()
    00641   def FSMState(self) : return self._isvc.FSMState()
    00642   def targetFSMState(self) : return self._isvc.targetFSMState()
    00643   def loaddict(self, dict) :
    00644     loaddict(dict)
    00645   def service(self, name, interface = None) :
    00646     svc = Helper.service( self._svcloc, name )
    00647     if interface :
    00648       return InterfaceCast(interface)(svc)
    00649     else :
    00650       return iService(name, svc )
    00651   def declSvcType(self, svcname, svctype ) :
    00652     self._svcmgr.declareSvcType(svcname, svctype)
    00653   def createSvc(self, name ) :
    00654     return Helper.service( self._svcloc, name, True )
    00655   def services(self) :
    00656     l = self._svcloc.getServices()
    00657     nl = l.__class__(l)  # get a copy
    00658     s = []
    00659     for i in range(l.size()) :
    00660       s.append(nl.front().name())
    00661       nl.pop_front()
    00662     return s
    00663   def algorithm(self, name ) :
    00664     alg = Helper.algorithm( self._algmgr, name )
    00665     return iAlgorithm(name, alg )
    00666   def algorithms(self) :
    00667     l = self._algmgr.getAlgorithms()
    00668     nl = l.__class__(l)  # get a copy
    00669     s = []
    00670     for i in range(l.size()) :
    00671       s.append(nl.front().name())
    00672       nl.pop_front()
    00673     return s
    00674   def tool(self, name ) :
    00675     return iAlgTool(name)
    00676   def property( self , name ) :
    00677     if name in self.algorithms() : return self.algorithm( name )
    00678     elif name in self.services() : return self.service(name )
    00679     else :                         return iProperty( name )
    00680   def datasvc(self, name) :
    00681     if self.state() == Gaudi.StateMachine.CONFIGURED :  self.initialize()
    00682     svc = Helper.service( self._svcloc, name )
    00683     return iDataSvc(name, svc)
    00684   def evtsvc(self) :
    00685     return self.datasvc('EventDataSvc')
    00686   def detsvc(self) :
    00687     return self.datasvc('DetectorDataSvc')
    00688   def evtsel(self):
    00689     if self.state() == Gaudi.StateMachine.CONFIGURED :  self.initialize()
    00690     if not hasattr(self,'_evtsel') : self.__dict__['_evtsel'] = iEventSelector()
    00691     return self._evtsel
    00692   def histsvc(self, name='HistogramDataSvc') :
    00693     svc = Helper.service( self._svcloc, name )
    00694     return iHistogramSvc(name, svc)
    00695   def ntuplesvc(self, name='NTupleSvc') :
    00696     if name not in self.ExtSvc : self.ExtSvc += [name]
    00697 #    if self.HistogramPersistency == 'NONE' : self.HistogramPersistency = 'ROOT'
    00698     svc = Helper.service( self._svcloc, name, True )
    00699     return iNTupleSvc(name, svc)
    00700   def partsvc(self ) :
    00701     if self.FSMState() == Gaudi.StateMachine.CONFIGURED :  self.initialize()
    00702     svc = Helper.service( self._svcloc, 'ParticlePropertySvc' )
    00703     return InterfaceCast(gbl.IParticlePropertySvc)(svc)
    00704   def toolsvc(self, name='ToolSvc') :
    00705     svc = Helper.service( self._svcloc, name, True )
    00706     return iToolSvc(name, svc)
    00707   def optSvc (self, name='JobOptionsSvc') :
    00708     svc = Helper.service( self._svcloc, name, True )
    00709     return iJobOptSvc(name, svc)
    00710   def readOptions(self, file) :
    00711     return self._optsvc.readOptions(file)
    00712   def addAlgorithm(self, alg) :
    00713     """ Add an Algorithm to the list of Top algorithms. It can be either a instance of
    00714         an Algorithm class or it name """
    00715     if type(alg) is  str :
    00716       self.topAlg += [alg]
    00717     else :
    00718       self.pyalgorithms.append(alg)
    00719       setOwnership(alg,0)
    00720       if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
    00721           alg.sysInitialize()
    00722           if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
    00723               alg.sysStart()
    00724       self.topAlg += [alg.name()]
    00725   def setAlgorithms(self, algs) :
    00726     """ Set the list of Top Algorithms.
    00727         It can be an individual of a list of algorithms names or instances """
    00728     if type(algs) is not list : algs = [algs]
    00729     names = []
    00730     for alg in algs :
    00731       if type(alg) is str : names.append(alg)
    00732       else :
    00733         self.pyalgorithms.append(alg)
    00734         if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
    00735             alg.sysInitialize()
    00736             if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
    00737                 alg.sysStart()
    00738         names.append(alg.name())
    00739     self.topAlg = names
    00740   def removeAlgorithm(self, alg) :
    00741     """ Remove an Algorithm to the list of Top algorithms. It can be either a instance of
    00742         an Algorithm class or it name """
    00743     tmp = self.topAlg
    00744     if type(alg) is  str :
    00745       tmp.remove(alg)
    00746     else :
    00747       tmp.remove(alg.name())
    00748       self.pyalgorithms.remove(alg)
    00749       setOwnership(alg,1)
    00750     self.topAlg = tmp
    00751   def config ( self, **args ):
    00752     """
    00753     Simple utility to perform the configuration of Gaudi application.
    00754     It reads the set of input job-options files, and set few
    00755     additional parameters 'options' through the usage of temporary *.opts file
    00756     Usage:
    00757     gaudi.config( files   = [ '$GAUSSOPTS/Gauss.opts'                     ,
    00758                               '$DECFILESROOT/options/10022_010.0GeV.opts' ] ,
    00759                   options = [ 'EventSelector.PrintFreq   =   5  '         ] )
    00760     """
    00761     files  = args.get('files',[])
    00762     for file in files :
    00763       sc = self.readOptions(file)
    00764       if sc.isFailure() :
    00765         raise RuntimeError , ' Unable to read file "' + file +'" '
    00766     options  = args.get('options',None)
    00767     if options :
    00768       import tempfile
    00769       tmpfilename = tempfile.mktemp()
    00770       tmpfile     = open( tmpfilename, 'w' )
    00771       tmpfile.write ( '#pragma print on  \n' )
    00772       tmpfile.write ( '/// File         "' + tmpfilename+'" generated by GaudiPython \n\n' )
    00773       for opt in options :
    00774         if type(options) is dict :
    00775           tmpfile.write( ' \t ' + opt + ' = '+ options[opt]+ ' ;  // added by GaudiPython \n' )
    00776         else :
    00777           tmpfile.write( ' \t ' + opt + ' ;  // added by GaudiPython \n' )
    00778       tmpfile.write ( '/// End of  file "' + tmpfilename+'" generated by GaudiPython \n\n' )
    00779       tmpfile.close()
    00780       sc = self.readOptions( tmpfilename )
    00781       if sc.isFailure() :
    00782         raise RuntimeError , ' Unable to read file "' + tmpfilename +'" '
    00783       os.remove( tmpfilename )
    00784     # We need to make sure that the options are taken by the ApplicationMgr
    00785     if self.FSMState() != Gaudi.StateMachine.OFFLINE : # The state is already configured, so we need to do something....
    00786
    00787       ## get job-options-service, @see class iJobOptSvc
    00788       jos   = self.optSvc()
    00789
    00790       ## list of all libraries
    00791       _dlls = jos.getProperty   ( self.name() , 'DLLs'   )
    00792       ## take care about libraries : APPEND if not done yet
    00793       if _dlls :
    00794         libs = [ l for l in _dlls if not l in self.DLLs ]
    00795         if libs : self.DLLs  += libs
    00796
    00797       ## all external services
    00798       _svcs = jos.getProperty   ( self.name() , 'ExtSvc' )
    00799       ## take care about services : APPEND  if not done yet
    00800       if _svcs :
    00801         svcs = [ s for s in _svcs if not s in self.ExtSvc ]
    00802         if svcs : self.ExtSvc += svcs
    00803
    00804       ## get all properties
    00805       props = jos.getProperties ( self.name() )
    00806       ## finally treat all other properties (presumably scalar properties)
    00807       for key in props :
    00808         if 'DLLS' == key or 'EXTSVC' == key : continue
    00809         self.__setattr__( key , props[key] )
    00810     return SUCCESS                                           # RETURN
    00811   def configure(self) :
    00812     return self._appmgr.configure()
    00813   def start(self) :
    00814     return self._appmgr.start()
    00815   def run(self, n) :
    00816     if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
    00817       sc = self.initialize()
    00818       if sc.isFailure(): return sc
    00819     if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
    00820       sc = self.start()
    00821       if sc.isFailure(): return sc
    00822     return self._evtpro.executeRun(n)
    00823   def executeEvent(self) :
    00824     return self._evtpro.executeEvent()
    00825   def execute(self) :
    00826     return self._evtpro.executeEvent()
    00827   def exit(self) :
    00828     if self.FSMState() == Gaudi.StateMachine.RUNNING: self._appmgr.stop().ignore()
    00829     if self.FSMState() == Gaudi.StateMachine.INITIALIZED: self._appmgr.finalize().ignore()
    00830     return self._appmgr.terminate()
    00831   evtSvc  = evtsvc
    00832   histSvc = histsvc
    00833   ntupleSvc = ntuplesvc
    00834   evtSel  = evtsel
    00835   detSvc  = detsvc
    00836   toolSvc = toolsvc
    00837   partSvc = partsvc
    00838
    00839 #--------------------------------------------------------------------------------------
    00840 def getComponentProperties( name ):
    00841   """ Get all the properties of a component as a Python dictionary.
    00842       The component is instantiated using the component library
    00843   """
    00844   properties = {}
    00845   if name == 'GaudiSvc' :
    00846     if Helper.loadDynamicLib(name) != 1 :
    00847       raise ImportError,  'Error loading component library '+ name
    00848     factorylist = gbl.FactoryTable.instance().getEntries()
    00849     factories = _copyFactoriesFromList(factorylist)
    00850     g = AppMgr(outputlevel=7)
    00851   else :
    00852     g = AppMgr(outputlevel=7)
    00853     if Helper.loadDynamicLib(name) != 1 :
    00854       raise ImportError,  'Error loading component library '+ name
    00855     factorylist = gbl.FactoryTable.instance().getEntries()
    00856     factories = _copyFactoriesFromList(factorylist)
    00857   svcloc    = gbl.Gaudi.svcLocator()
    00858   dummysvc  = gbl.Service('DummySvc',svcloc)
    00859   for factory in factories :
    00860     if    InterfaceCast(gbl.IAlgFactory)(factory) : ctype = 'Algorithm'
    00861     elif  InterfaceCast(gbl.ISvcFactory)(factory) : ctype = 'Service'
    00862     elif  InterfaceCast(gbl.IToolFactory)(factory) : ctype = 'AlgTool'
    00863     elif  factory.ident() == 'ApplicationMgr' :  ctype = 'ApplicationMgr'
    00864     else :  ctype = 'Unknown'
    00865     cname = factory.ident().split()[-1]
    00866     if ctype in ('Algorithm','Service', 'AlgTool', 'ApplicationMgr') :
    00867       try :
    00868         if ctype == 'AlgTool' :
    00869           obj = factory.instantiate(dummysvc)
    00870         else :
    00871           obj = factory.instantiate(svcloc)
    00872       except RuntimeError, text :
    00873         print 'Error instantiating', cname, ' from ', name
    00874         print text
    00875         continue
    00876       prop = iProperty('dummy', obj)
    00877       properties[cname] = [ctype, prop.properties()]
    00878       try:  obj.release()
    00879       except: pass
    00880   return properties
    00881
    00882 def _copyFactoriesFromList(factories) :
    00883   result = []
    00884   for i in range(factories.size()) :
    00885     factory = factories.front()
    00886     result.append(factory)
    00887     factories.pop_front()
    00888   for factory in result :
    00889     factories.push_back(factory)
    00890   return result
    00891
    00892 #----CallbackStreamBuf----------------------------------------------------------------
    00893 #    Used for redirecting C++ messages to python
    00894 _CallbackStreamBufBase = gbl.GaudiPython.CallbackStreamBuf
    00895 class CallbackStreamBuf (_CallbackStreamBufBase):
    00896   def __init__(self, callback):
    00897     _CallbackStreamBufBase.__init__(self, self)
    00898     self.callback = callback
    00899   def _sync(self, string = None):
    00900     if not string : return 0
    00901     self.callback(string)
    00902     return 0
    00903
    00904 #----PyAlgorithm----------------------------------------------------------------------
    00905 # Used for implemenating Algorithms in Python
    00906 _PyAlgorithm = gbl.GaudiPython.PyAlgorithm
    00907 class PyAlgorithm (_PyAlgorithm) :
    00908   def __init__(self, name=None) :
    00909     if not name : name = self.__class__.__name__
    00910     _PyAlgorithm.__init__(self, self, name)
    00911     self._svcloc = gbl.Gaudi.svcLocator()
    00912     self._algmgr = InterfaceCast(gbl.IAlgManager)(self._svcloc)
    00913     sc = self._algmgr.addAlgorithm(self)
    00914     if sc.isFailure() : raise RuntimeError, 'Unable to add Algorithm'
    00915   def __del__(self):
    00916     sc = self._algmgr.removeAlgorithm(self)
    00917     if sc.isFailure() : pass
    00918   def initialize(self) : return 1
    00919   def start(self) : return 1
    00920   def execute(self) : return 1
    00921   def stop(self) : return 1
    00922   def finalize(self) : return 1
    00923   def beginRun(self) : return 1
    00924   def endRun(self) : return 1
    00925
    00926
    00927
    00928 #----Install exit handler-------------------------------------------------------------
    00929 import atexit
    00930 def _atexit_() :
    00931   if _gaudi :
    00932     state = _gaudi.FSMState()
    00933     if state in [ Gaudi.StateMachine.CONFIGURED, Gaudi.StateMachine.INITIALIZED,
    00934                   Gaudi.StateMachine.RUNNING ]:
    00935         _gaudi.exit()
    00936 atexit.register( _atexit_ )
    00937
    00938 #----Enable tab completion------------------------------------------------------------
    00939 try:
    00940   import rlcompleter,readline
    00941   readline.parse_and_bind("tab: complete")
    00942 except:
    00943   pass
    00944