| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

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 __reset__(self):
00566     '''Allow for a full reset.  Calling this lets a new Gaudi
00567     AppMgr to be freshly created in the same executable image.
00568     https://lists.bnl.gov/pipermail/gaudi-talk/2009-July/000443.html
00569     '''
00570 
00571     global _gaudi
00572     # Stop, Finalize and Terminate the current AppMgr
00573     self.exit()
00574     # release interfaces
00575     self._evtpro.release()
00576     self._svcloc.release()
00577     self._appmgr.release()
00578     # Reset the C++ globals
00579     gbl.Gaudi.setInstance(makeNullPointer('ISvcLocator'))
00580     gbl.Gaudi.setInstance(makeNullPointer('IAppMgrUI'))
00581     # Reset the Python global
00582     _gaudi = None
00583     return
00584   def __new__ ( cls, *args, **kwargs ):
00585     global _gaudi
00586     if not _gaudi :
00587       newobj = object.__new__( cls, *args, **kwargs )
00588       cls.__init__(newobj, *args, **kwargs)
00589       _gaudi = newobj
00590     return _gaudi
00591   def __init__(self, outputlevel = -1, joboptions = None, selfoptions = {},
00592                dllname = None, factname = None) :
00593     global _gaudi
00594     if _gaudi : return
00595     try:
00596         from GaudiKernel.Proxy.Configurable import expandvars
00597     except ImportError:
00598         # pass-through implementation if expandvars is not defined (AthenaCommon)
00599         expandvars = lambda data : data
00600     if dllname and factname:
00601       self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname,factname)
00602     elif dllname:
00603       self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname)
00604     else:
00605       self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr()
00606     self.__dict__['_svcloc'] = gbl.Gaudi.svcLocator()
00607     self.__dict__['_algmgr'] = InterfaceCast(gbl.IAlgManager)(self._appmgr)
00608     self.__dict__['_evtpro'] = InterfaceCast(gbl.IEventProcessor)(self._appmgr)
00609     self.__dict__['_svcmgr'] = InterfaceCast(gbl.ISvcManager)(self._appmgr)
00610     self.__dict__['pyalgorithms'] = []
00611     iService.__init__(self, 'ApplicationMgr', self._appmgr )
00612     #------python specific initialization-------------------------------------
00613     if self.FSMState() < Gaudi.StateMachine.CONFIGURED :  # Not yet configured
00614       self.JobOptionsType = 'NONE'
00615       if joboptions :
00616           from GaudiKernel.ProcessJobOptions import importOptions
00617           importOptions(joboptions)
00618       # Ensure that the ConfigurableUser instances have been applied
00619       import GaudiKernel.Proxy.Configurable
00620       if hasattr(GaudiKernel.Proxy.Configurable, "applyConfigurableUsers"):
00621           GaudiKernel.Proxy.Configurable.applyConfigurableUsers()
00622       # This is the default and could be overridden with "selfopts"
00623       self.OutputLevel = 3
00624       selfprops = Configurable.allConfigurables.get('ApplicationMgr',{})
00625       if selfprops : selfprops = expandvars(selfprops.getValuedProperties())
00626       for p,v in selfprops.items()   : setattr(self, p, v)
00627       for p,v in selfoptions.items() : setattr(self, p, v)
00628       # Override job options
00629       if outputlevel != -1 : self.OutputLevel = outputlevel
00630       self.configure()
00631     #---MessageSvc------------------------------------------------------------
00632     ms = self.service('MessageSvc')
00633     if 'MessageSvc' in Configurable.allConfigurables:
00634         msprops = Configurable.allConfigurables['MessageSvc']
00635         ms = self.service('MessageSvc')
00636         if hasattr(msprops,"getValuedProperties"):
00637             msprops = expandvars(msprops.getValuedProperties())
00638         for p,v in msprops.items():
00639             setattr(ms, p, v)
00640     if outputlevel != -1 : ms.OutputLevel = outputlevel
00641     #---JobOptions------------------------------------------------------------
00642     self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(Helper.service(self._svcloc,'JobOptionsSvc'))
00643     #------Configurables initialization (part2)-------------------------------
00644     for n in getNeededConfigurables():
00645       c = Configurable.allConfigurables[n]
00646       if n in ['ApplicationMgr','MessageSvc'] : continue # These are already done---
00647       for p, v in  c.getValuedProperties().items() :
00648         v = expandvars(v)
00649         # Note: AthenaCommon.Configurable does not have Configurable.PropertyReference
00650         if hasattr(Configurable,"PropertyReference") and type(v) == Configurable.PropertyReference:
00651             # this is done in "getFullName", but the exception is ignored,
00652             # so we do it again to get it 
00653             v = v.__resolve__()
00654         if   type(v) == str : v = '"%s"' % v # need double quotes
00655         elif type(v) == long: v = '%d'   % v # prevent pending 'L'
00656         self._optsvc.addPropertyToCatalogue(n, StringProperty(p,str(v)))
00657     if hasattr(Configurable,"_configurationLocked"):
00658         Configurable._configurationLocked = True
00659   def state(self) : return self._isvc.FSMState()
00660   def FSMState(self) : return self._isvc.FSMState()
00661   def targetFSMState(self) : return self._isvc.targetFSMState()
00662   def loaddict(self, dict) :
00663     loaddict(dict)
00664   def service(self, name, interface = None) :
00665     svc = Helper.service( self._svcloc, name )
00666     if interface :
00667       return InterfaceCast(interface)(svc)
00668     else :
00669       return iService(name, svc )
00670   def declSvcType(self, svcname, svctype ) :
00671     self._svcmgr.declareSvcType(svcname, svctype)
00672   def createSvc(self, name ) :
00673     return Helper.service( self._svcloc, name, True )
00674   def services(self) :
00675     l = self._svcloc.getServices()
00676     nl = l.__class__(l)  # get a copy
00677     s = []
00678     for i in range(l.size()) :
00679       s.append(nl.front().name())
00680       nl.pop_front()
00681     return s
00682   def algorithm(self, name ) :
00683     alg = Helper.algorithm( self._algmgr, name )
00684     return iAlgorithm(name, alg )
00685   def algorithms(self) :
00686     l = self._algmgr.getAlgorithms()
00687     nl = l.__class__(l)  # get a copy
00688     s = []
00689     for i in range(l.size()) :
00690       s.append(nl.front().name())
00691       nl.pop_front()
00692     return s
00693   def tool(self, name ) :
00694     return iAlgTool(name)
00695   def property( self , name ) :
00696     if name in self.algorithms() : return self.algorithm( name )
00697     elif name in self.services() : return self.service(name )
00698     else :                         return iProperty( name )
00699   def datasvc(self, name) :
00700     if self.state() == Gaudi.StateMachine.CONFIGURED :  self.initialize()
00701     svc = Helper.service( self._svcloc, name )
00702     return iDataSvc(name, svc)
00703   def evtsvc(self) :
00704     return self.datasvc('EventDataSvc')
00705   def detsvc(self) :
00706     return self.datasvc('DetectorDataSvc')
00707   def evtsel(self):
00708     if self.state() == Gaudi.StateMachine.CONFIGURED :  self.initialize()
00709     if not hasattr(self,'_evtsel') : self.__dict__['_evtsel'] = iEventSelector()
00710     return self._evtsel
00711   def histsvc(self, name='HistogramDataSvc') :
00712     svc = Helper.service( self._svcloc, name )
00713     return iHistogramSvc(name, svc)
00714   def ntuplesvc(self, name='NTupleSvc') :
00715     if name not in self.ExtSvc : self.ExtSvc += [name]
00716 #    if self.HistogramPersistency == 'NONE' : self.HistogramPersistency = 'ROOT'
00717     svc = Helper.service( self._svcloc, name, True )
00718     return iNTupleSvc(name, svc)
00719   def partsvc(self ) :
00720     if self.FSMState() == Gaudi.StateMachine.CONFIGURED :  self.initialize()
00721     svc = Helper.service( self._svcloc, 'ParticlePropertySvc' )
00722     return InterfaceCast(gbl.IParticlePropertySvc)(svc)
00723   def toolsvc(self, name='ToolSvc') :
00724     svc = Helper.service( self._svcloc, name, True )
00725     return iToolSvc(name, svc)
00726   def optSvc (self, name='JobOptionsSvc') :
00727     svc = Helper.service( self._svcloc, name, True )
00728     return iJobOptSvc(name, svc)    
00729   def readOptions(self, file) :
00730     return self._optsvc.readOptions(file)
00731   def addAlgorithm(self, alg) :
00732     """ Add an Algorithm to the list of Top algorithms. It can be either a instance of
00733         an Algorithm class or it name """
00734     if type(alg) is  str :
00735       self.topAlg += [alg]
00736     else :
00737       self.pyalgorithms.append(alg)
00738       setOwnership(alg,0)
00739       if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
00740           alg.sysInitialize()
00741           if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
00742               alg.sysStart()
00743       self.topAlg += [alg.name()]
00744   def setAlgorithms(self, algs) :
00745     """ Set the list of Top Algorithms. 
00746         It can be an individual of a list of algorithms names or instances """
00747     if type(algs) is not list : algs = [algs]
00748     names = []
00749     for alg in algs :
00750       if type(alg) is str : names.append(alg)
00751       else :
00752         self.pyalgorithms.append(alg)
00753         if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
00754             alg.sysInitialize()
00755             if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
00756                 alg.sysStart()
00757         names.append(alg.name()) 
00758     self.topAlg = names
00759   def removeAlgorithm(self, alg) :
00760     """ Remove an Algorithm to the list of Top algorithms. It can be either a instance of
00761         an Algorithm class or it name """
00762     tmp = self.topAlg    
00763     if type(alg) is  str :
00764       tmp.remove(alg)
00765     else :
00766       tmp.remove(alg.name())
00767       self.pyalgorithms.remove(alg)
00768       setOwnership(alg,1)
00769     self.topAlg = tmp
00770   def config ( self, **args ):
00771     """  
00772     Simple utility to perform the configuration of Gaudi application.
00773     It reads the set of input job-options files, and set few
00774     additional parameters 'options' through the usage of temporary *.opts file
00775     Usage:
00776     gaudi.config( files   = [ '$GAUSSOPTS/Gauss.opts'                     ,
00777                               '$DECFILESROOT/options/10022_010.0GeV.opts' ] ,
00778                   options = [ 'EventSelector.PrintFreq   =   5  '         ] )
00779     """
00780     files  = args.get('files',[])
00781     for file in files :
00782       sc = self.readOptions(file)
00783       if sc.isFailure() :
00784         raise RuntimeError , ' Unable to read file "' + file +'" '
00785     options  = args.get('options',None)
00786     if options :
00787       import tempfile
00788       tmpfilename = tempfile.mktemp()
00789       tmpfile     = open( tmpfilename, 'w' )
00790       tmpfile.write ( '#pragma print on  \n' ) 
00791       tmpfile.write ( '/// File         "' + tmpfilename+'" generated by GaudiPython \n\n' ) 
00792       for opt in options :
00793         if type(options) is dict :
00794           tmpfile.write( ' \t ' + opt + ' = '+ options[opt]+ ' ;  // added by GaudiPython \n' )
00795         else :
00796           tmpfile.write( ' \t ' + opt + ' ;  // added by GaudiPython \n' )
00797       tmpfile.write ( '/// End of  file "' + tmpfilename+'" generated by GaudiPython \n\n' ) 
00798       tmpfile.close() 
00799       sc = self.readOptions( tmpfilename )
00800       if sc.isFailure() :
00801         raise RuntimeError , ' Unable to read file "' + tmpfilename +'" '
00802       os.remove( tmpfilename )
00803     # We need to make sure that the options are taken by the ApplicationMgr
00804     if self.FSMState() != Gaudi.StateMachine.OFFLINE : # The state is already configured, so we need to do something....
00805 
00806       ## get job-options-service, @see class iJobOptSvc 
00807       jos   = self.optSvc()
00808       
00809       ## list of all libraries 
00810       _dlls = jos.getProperty   ( self.name() , 'DLLs'   )
00811       ## take care about libraries : APPEND if not done yet 
00812       if _dlls :
00813         libs = [ l for l in _dlls if not l in self.DLLs ] 
00814         if libs : self.DLLs  += libs
00815       
00816       ## all external services 
00817       _svcs = jos.getProperty   ( self.name() , 'ExtSvc' )
00818       ## take care about services : APPEND  if not done yet 
00819       if _svcs :
00820         svcs = [ s for s in _svcs if not s in self.ExtSvc ]
00821         if svcs : self.ExtSvc += svcs
00822         
00823       ## get all properties 
00824       props = jos.getProperties ( self.name() )
00825       ## finally treat all other properties (presumably scalar properties)
00826       for key in props :
00827         if 'DLLS' == key or 'EXTSVC' == key : continue
00828         self.__setattr__( key , props[key] )
00829     return SUCCESS                                           # RETURN 
00830   def configure(self) :
00831     return self._appmgr.configure()
00832   def start(self) :
00833     return self._appmgr.start()
00834   def run(self, n) :
00835     if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
00836       sc = self.initialize()
00837       if sc.isFailure(): return sc
00838     if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
00839       sc = self.start()
00840       if sc.isFailure(): return sc
00841     return self._evtpro.executeRun(n)
00842   def executeEvent(self) :
00843     return self._evtpro.executeEvent()
00844   def execute(self) :
00845     return self._evtpro.executeEvent()
00846   def exit(self) :
00847     if self.FSMState() == Gaudi.StateMachine.RUNNING: self._appmgr.stop().ignore()
00848     if self.FSMState() == Gaudi.StateMachine.INITIALIZED: self._appmgr.finalize().ignore()
00849     return self._appmgr.terminate()
00850   evtSvc  = evtsvc
00851   histSvc = histsvc
00852   ntupleSvc = ntuplesvc
00853   evtSel  = evtsel
00854   detSvc  = detsvc
00855   toolSvc = toolsvc
00856   partSvc = partsvc
00857 
00858 #--------------------------------------------------------------------------------------
00859 def getComponentProperties( name ):
00860   """ Get all the properties of a component as a Python dictionary. 
00861       The component is instantiated using the component library
00862   """
00863   properties = {}
00864   if name == 'GaudiSvc' :
00865     if Helper.loadDynamicLib(name) != 1 :
00866       raise ImportError,  'Error loading component library '+ name
00867     factorylist = gbl.FactoryTable.instance().getEntries()
00868     factories = _copyFactoriesFromList(factorylist)
00869     g = AppMgr(outputlevel=7)     
00870   else :
00871     g = AppMgr(outputlevel=7) 
00872     if Helper.loadDynamicLib(name) != 1 :
00873       raise ImportError,  'Error loading component library '+ name
00874     factorylist = gbl.FactoryTable.instance().getEntries()
00875     factories = _copyFactoriesFromList(factorylist)
00876   svcloc    = gbl.Gaudi.svcLocator()
00877   dummysvc  = gbl.Service('DummySvc',svcloc)
00878   for factory in factories :
00879     if    InterfaceCast(gbl.IAlgFactory)(factory) : ctype = 'Algorithm'
00880     elif  InterfaceCast(gbl.ISvcFactory)(factory) : ctype = 'Service'
00881     elif  InterfaceCast(gbl.IToolFactory)(factory) : ctype = 'AlgTool'
00882     elif  factory.ident() == 'ApplicationMgr' :  ctype = 'ApplicationMgr'
00883     else :  ctype = 'Unknown'
00884     cname = factory.ident().split()[-1]
00885     if ctype in ('Algorithm','Service', 'AlgTool', 'ApplicationMgr') :
00886       try :
00887         if ctype == 'AlgTool' :
00888           obj = factory.instantiate(dummysvc)
00889         else :
00890           obj = factory.instantiate(svcloc)
00891       except RuntimeError, text :
00892         print 'Error instantiating', cname, ' from ', name
00893         print text
00894         continue
00895       prop = iProperty('dummy', obj)
00896       properties[cname] = [ctype, prop.properties()]
00897       try:  obj.release()
00898       except: pass
00899   return properties
00900 
00901 def _copyFactoriesFromList(factories) :
00902   result = []
00903   for i in range(factories.size()) :
00904     factory = factories.front()
00905     result.append(factory)
00906     factories.pop_front()
00907   for factory in result :
00908     factories.push_back(factory)
00909   return result
00910 
00911 #----CallbackStreamBuf----------------------------------------------------------------
00912 #    Used for redirecting C++ messages to python
00913 _CallbackStreamBufBase = gbl.GaudiPython.CallbackStreamBuf
00914 class CallbackStreamBuf (_CallbackStreamBufBase):
00915   def __init__(self, callback):
00916     _CallbackStreamBufBase.__init__(self, self)
00917     self.callback = callback
00918   def _sync(self, string = None):
00919     if not string : return 0
00920     self.callback(string)
00921     return 0
00922 
00923 #----PyAlgorithm----------------------------------------------------------------------
00924 # Used for implemenating Algorithms in Python
00925 _PyAlgorithm = gbl.GaudiPython.PyAlgorithm
00926 class PyAlgorithm (_PyAlgorithm) :
00927   def __init__(self, name=None) :
00928     if not name : name = self.__class__.__name__
00929     _PyAlgorithm.__init__(self, self, name)
00930     self._svcloc = gbl.Gaudi.svcLocator()
00931     self._algmgr = InterfaceCast(gbl.IAlgManager)(self._svcloc)
00932     sc = self._algmgr.addAlgorithm(self)
00933     if sc.isFailure() : raise RuntimeError, 'Unable to add Algorithm'
00934   def __del__(self):
00935     sc = self._algmgr.removeAlgorithm(self)
00936     if sc.isFailure() : pass
00937   def initialize(self) : return 1
00938   def start(self) : return 1
00939   def execute(self) : return 1
00940   def stop(self) : return 1
00941   def finalize(self) : return 1
00942   def beginRun(self) : return 1
00943   def endRun(self) : return 1
00944 
00945 
00946 
00947 #----Install exit handler-------------------------------------------------------------
00948 import atexit
00949 def _atexit_() :
00950   if _gaudi :
00951     state = _gaudi.FSMState()
00952     if state in [ Gaudi.StateMachine.CONFIGURED, Gaudi.StateMachine.INITIALIZED,
00953                   Gaudi.StateMachine.RUNNING ]:
00954         _gaudi.exit()
00955 atexit.register( _atexit_ )
00956   
00957 #----Enable tab completion------------------------------------------------------------
00958 try:
00959   import rlcompleter,readline    
00960   readline.parse_and_bind("tab: complete")
00961 except:
00962   pass
00963 
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 19:58:56 2011 for GaudiPython by doxygen 1.4.7