00001
00002
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
00022
00023 from GaudiKernel.Proxy.Configurable import Configurable, getNeededConfigurables
00024
00025
00026 gbl = PyCintex.makeNamespace('')
00027 Gaudi = gbl.Gaudi
00028
00029 _gaudi = None
00030
00031
00032
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
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
00047 if hasattr(Helper,"toArray"):
00048
00049
00050 toArray = lambda typ: getattr(Helper,"toArray")
00051 else:
00052
00053 toArray = lambda typ: getattr(Helper,"toArray<%s>"%typ)
00054
00055
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
00065 class InterfaceCast(object) :
00066 """ Helper class to obtain the adequate 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 try:
00075 if obj.queryInterface(self.type.interfaceID(), ip).isSuccess() :
00076 return ip
00077 else :
00078 print "ERROR: queryInterface failed for", obj, "interface:", self.type
00079 except Exception, e:
00080 print "ERROR: exception", e, "caught when retrieving interface", self.type, "for object", obj
00081 import traceback
00082 traceback.print_stack()
00083 return None
00084 cast = __call__
00085
00086 class Interface(InterfaceCast) :
00087 def __init__(self, t ):
00088 deprecation('Use InterfaceCast class instead')
00089 InterfaceCast.__init__(self,t)
00090 def cast(self, obj) :
00091 return self(obj)
00092
00093
00094 def loaddict(dict) :
00095 """ Load a LCG dictionary using various mechanisms"""
00096 if Helper.loadDynamicLib(dict) == 1 : return
00097 else :
00098 try:
00099 PyCintex.loadDict(dict)
00100 except:
00101 raise ImportError, 'Error loading dictionary library'
00102
00103
00104 def getClass( name , libs = [] ) :
00105 """
00106 Function to retrieve a certain C++ class by name and to load dictionary if requested
00107
00108 Usage:
00109
00110 from gaudimodule import getClass
00111 # one knows that class is already loaded
00112 AppMgr = getClass( 'ApplicationMgr' )
00113 # one knows where to look for class, if not loaded yet
00114 MCParticle = getClass( 'MCParticle' , 'EventDict' )
00115 # one knows where to look for class, if not loaded yet
00116 Vertex = getClass( 'Vertex' , ['EventDict', 'PhysEventDict'] )
00117 """
00118
00119 if hasattr( gbl , name ) : return getattr( gbl , name )
00120
00121 if type(libs) is not list : libs = [libs]
00122 for lib in libs :
00123 loaddict( lib )
00124 if hasattr( gbl , name ) : return getattr( gbl , name )
00125
00126 return None
00127
00128
00129 class PropertyEntry(object) :
00130 """ holds the value and the documentation string of a property """
00131 def __init__(self, prop) :
00132 self._type = type(prop).__name__
00133 self.__doc__ = " --- Property type is " + self.ptype()
00134
00135 if issubclass(type(prop),GaudiHandleProperty) :
00136 self._value = prop.value()
00137 elif issubclass(type(prop),GaudiHandleArrayProperty) :
00138 self._value = prop.value()
00139 else :
00140
00141 try: self._value = eval( prop.toString() , {} , {} )
00142 except:
00143 if hasattr ( prop , 'value' ) : self._value = prop.value()
00144 else : self._value = prop.toString()
00145
00146 self.__doc__ += " --- Default value = " + str(self._value) + " --- "
00147 if prop.documentation() != 'none':
00148 self.__doc__ = prop.documentation() + '\\n' + self.__doc__
00149
00150 self._property = prop
00151 def value(self) :
00152 return self._value
00153 def ptype(self) :
00154 return self._type
00155 def property(self):
00156 "Return the underlying property itself "
00157 return self._property
00158 def documentation(self) :
00159 return self.__doc__
00160 def hasDoc(self):
00161 return len(self.__doc__)>0 and self.__doc__ != 'none'
00162
00163
00164 class iProperty(object) :
00165 """ Python equivalent to the C++ Property interface """
00166 def __init__(self, name, ip = None) :
00167 if ip : self.__dict__['_ip'] = InterfaceCast(gbl.IProperty)(ip)
00168 else : self.__dict__['_ip'] = None
00169 self.__dict__['_svcloc'] = gbl.Gaudi.svcLocator()
00170 optsvc = Helper.service(self._svcloc,'JobOptionsSvc')
00171 if optsvc : self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(optsvc)
00172 else : self.__dict__['_optsvc'] = None
00173 self.__dict__['_name'] = name
00174 def getInterface(self) :
00175 if not self._ip : self.retrieveInterface()
00176 return self._ip
00177 def retrieveInterface(self) :
00178 pass
00179 def __call_interface_method__(self,ifname,method,*args):
00180 if not getattr(self,ifname) : self.retrieveInterface()
00181 return getattr(getattr(self,ifname),method)(*args)
00182 def __setattr__(self, name, value):
00183 """
00184 The method which is used for setting the property from the given value.
00185 - In the case of the valid instance it sets the property through IProperty interface
00186 - In the case of placeholder the property is added to JobOptionsCatalogue
00187 """
00188 if hasattr( value, 'toStringProperty' ):
00189
00190 value = '%s' % value.toStringProperty()
00191 ip = self.getInterface()
00192 if ip :
00193 if not gbl.Gaudi.Utils.hasProperty ( ip , name ) :
00194 raise AttributeError, 'property %s does not exist' % name
00195 prop = ip.getProperty(name)
00196 if not hasattr ( prop , 'value' ) or not type( value ) == type( prop.value() ) :
00197 if tuple == type( value ) : value = str(value)
00198 elif hasattr ( value , 'toString' ) : value = value.toString()
00199 elif not long == type( value ) : value = '%s' % value
00200 else : value = '%d' % value
00201 if prop.fromString( value ).isFailure() :
00202 raise AttributeError, 'property %s could not be set from %s' % (name,value)
00203 else :
00204 if not prop.setValue( value ) :
00205 raise AttributeError, 'property %s could not be set from %s' % (name,value)
00206 else :
00207 if type(value) == str : value = '"%s"' % value
00208 elif type(value) == tuple : value = str(value)
00209 elif hasattr( value , 'toString' ) : value = value.toString()
00210 elif type(value) == long: value = '%d' % value
00211 sp = StringProperty( name , str(value))
00212 self._optsvc.addPropertyToCatalogue( self._name , sp )
00213 def __getattr__(self, name ):
00214 """
00215 The method which returns the value for the given property
00216 - In the case of the valid instance it returns the valid property value through IProperty interface
00217 - In the case of placeholder the property value is retrieved from JobOptionsCatalogue
00218 """
00219 ip = self.getInterface()
00220 if ip :
00221 if not gbl.Gaudi.Utils.hasProperty ( ip , name ) :
00222 raise AttributeError, 'property %s does not exist' % name
00223 prop = ip.getProperty(name)
00224 if StringProperty == type( prop ) : return prop.value()
00225 elif StringPropertyRef == type( prop ) : return prop.value()
00226 try: return eval( prop.toString(), {}, {} )
00227 except : return prop.value()
00228 else :
00229 props = self._optsvc.getProperties(self._name)
00230 for p in props :
00231 if not p.name() == name : continue
00232
00233 try: return eval( p.value(), {}, {} )
00234 except: return p.value()
00235 raise AttributeError, 'property %s does not exist' % name
00236 def properties(self):
00237 dct = {}
00238 props = None
00239 ip = self.getInterface()
00240 if ip :
00241 props = ip.getProperties()
00242 propsFrom = self._name
00243 else:
00244 props = self._optsvc.getProperties( self._name )
00245 propsFrom = "jobOptionsSvc"
00246 if props:
00247 for p in props :
00248 try:
00249 dct[p.name()] = PropertyEntry(p)
00250 except (ValueError,TypeError),e:
00251 raise ValueError, "gaudimodule.iProperty.properties(): %s%s processing property %s.%s = %s" % \
00252 (e.__class__.__name__, e.args, propsFrom, p.name(), p.value())
00253 return dct
00254 def name(self) :
00255 return self._name
00256
00257
00258 class iService(iProperty) :
00259 """ Python equivalent to IProperty interface """
00260 def __init__(self, name, isvc = None ) :
00261 iProperty.__init__(self, name, isvc )
00262 if isvc : self.__dict__['_isvc'] = InterfaceCast(gbl.IService)(isvc)
00263 else : self.__dict__['_isvc'] = None
00264 def retrieveInterface(self) :
00265 isvc = Helper.service(self._svcloc,self._name)
00266 if isvc : iService.__init__(self, self._name, isvc)
00267 initialize = lambda self : self.__call_interface_method__("_isvc","initialize")
00268 start = lambda self : self.__call_interface_method__("_isvc","start")
00269 stop = lambda self : self.__call_interface_method__("_isvc","stop")
00270 finalize = lambda self : self.__call_interface_method__("_isvc","finalize")
00271 reinitialize = lambda self : self.__call_interface_method__("_isvc","reinitialize")
00272 restart = lambda self : self.__call_interface_method__("_isvc","restart")
00273 def isValid(self) :
00274 if self._isvc: return True
00275 else : return False
00276
00277
00278 class iAlgorithm(iProperty) :
00279 """ Python equivalent to IAlgorithm interface """
00280 def __init__(self, name, ialg = None ) :
00281 iProperty.__init__(self, name, ialg )
00282 if ialg : self.__dict__['_ialg'] = InterfaceCast(gbl.IAlgorithm)(ialg)
00283 else : self.__dict__['_ialg'] = None
00284 def retrieveInterface(self) :
00285 ialg = Helper.algorithm(InterfaceCast(gbl.IAlgManager)(self._svcloc),self._name)
00286 if ialg : iAlgorithm.__init__(self, self._name, ialg)
00287 initialize = lambda self : self.__call_interface_method__("_ialg","initialize")
00288 start = lambda self : self.__call_interface_method__("_ialg","start")
00289 execute = lambda self : self.__call_interface_method__("_ialg","execute")
00290 stop = lambda self : self.__call_interface_method__("_ialg","stop")
00291 finalize = lambda self : self.__call_interface_method__("_ialg","finalize")
00292 reinitialize = lambda self : self.__call_interface_method__("_ialg","reinitialize")
00293 restart = lambda self : self.__call_interface_method__("_ialg","restart")
00294 sysInitialize = lambda self : self.__call_interface_method__("_ialg","sysInitialize")
00295 sysStart = lambda self : self.__call_interface_method__("_ialg","sysStart")
00296 sysExecute = lambda self : self.__call_interface_method__("_ialg","sysExecute")
00297 sysStop = lambda self : self.__call_interface_method__("_ialg","sysStop")
00298 sysFinalize = lambda self : self.__call_interface_method__("_ialg","sysFinalize")
00299 sysReinitialize = lambda self : self.__call_interface_method__("_ialg","sysReinitialize")
00300 sysRestart = lambda self : self.__call_interface_method__("_ialg","sysRestart")
00301
00302
00303 class iAlgTool(iProperty) :
00304 """ Python equivalent to IAlgTool interface (not completed yet) """
00305 def __init__(self, name, itool = None ) :
00306 iProperty.__init__(self, name, itool )
00307 if itool : self.__dict__['_itool'] = itool
00308 else : self.__dict__['_itool'] = None
00309 svc = Helper.service( self._svcloc, 'ToolSvc', True )
00310 self.__dict__['_toolsvc']= iToolSvc('ToolSvc', svc)
00311 def retrieveInterface(self) :
00312 itool = self._toolsvc._retrieve(self._name)
00313 if itool : iAlgTool.__init__(self, self._name, itool)
00314 start = lambda self : self.__call_interface_method__("_itool","start")
00315 stop = lambda self : self.__call_interface_method__("_itool","stop")
00316 type = lambda self : self.__call_interface_method__("_itool","type")
00317 def name(self) :
00318 if self._itool : return self._itool.name()
00319 else : return self._name
00320
00321
00322 class iDataSvc(iService) :
00323 def __init__(self, name, idp) :
00324 iService.__init__(self, name, idp )
00325 self.__dict__['_idp'] = InterfaceCast(gbl.IDataProviderSvc)(idp)
00326 self.__dict__['_idm'] = InterfaceCast(gbl.IDataManagerSvc)(idp)
00327 def registerObject(self, path, obj) :
00328 if not self._idp : raise AttributeError('C++ service %s does not exist' % self.__dict__['_name'])
00329 return self._idp.registerObject(path,obj)
00330 def unregisterObject(self, path) :
00331 if not self._idp : raise AttributeError('C++ service %s does not exist' % self.__dict__['_name'])
00332 return self._idp.unregisterObject(path)
00333 def retrieveObject(self, path) :
00334 if not self._idp : return None
00335 return Helper.dataobject(self._idp, path)
00336
00337 def findObject(self, path) :
00338 """
00339
00340 Get the existing object in TransientStore for the given location
00341
00342 - loading of object from persistency is NOT triggered
00343 - 'data-on-demand' action is NOT triggered
00344
00345 >>> svc = ... ## get the service
00346 >>> path = ... ## get the path in Transient Store
00347 >>> data = svc.findObject ( path ) ## use the method
00348
00349 """
00350 if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
00351 return Helper.findobject(self._idp, path)
00352
00353
00354 def getObject ( self , path , *args ) :
00355 """
00356 Get object from Transient Store for the given location
00357
00358 arguments :
00359 - path : Location of object in Transient Store
00360 - retrieve (bool) True : retrieve versus find
00361 - disable on-demand (bool) False : temporary disable 'on-demand' actions
00362
00363 >>> svc = ... ## get the service
00364 >>> path = ... ## get the path
00365
00366 >>> data = svc.getObject ( path , False ) ## find object in Transient Store
00367
00368 ## find object in Transient Store
00369 # load form tape or use 'on-demand' action for missing objects :
00370 >>> data = svc.getObject ( path , True )
00371
00372 ## find object in Transient Store
00373 # load from tape or for missing objects, disable 'on-demand'-actions
00374 >>> data = svc.getObject ( path , True , True )
00375
00376 """
00377 if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
00378 return Helper.getobject(self._idp, path, *args )
00379
00380 def __getitem__(self, path) :
00381 if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
00382 return Helper.dataobject(self._idp, path)
00383 def __setitem__(self, path, obj) :
00384 if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
00385 return self._idp.registerObject(path,obj)
00386 def __delitem__(self, path) :
00387 if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
00388 return self._idp.unregisterObject(path)
00389 def leaves(self, node=None) :
00390 if not node : node = self.retrieveObject('')
00391 ll = gbl.std.vector('IRegistry*')()
00392 if type(node) is str : obj = self.retrieveObject(node)
00393 else : obj = node
00394 if self._idm.objectLeaves(node, ll).isSuccess() : return ll
00395 def dump(self, node=None) :
00396 if not node :
00397 root = self.retrieveObject('')
00398 if root : node = root.registry()
00399 else : return
00400 print node.identifier()
00401 if node.object() :
00402 for l in self.leaves(node) : self.dump(l)
00403 def getList(self, node=None, lst=[], rootFID=None) :
00404 if not node :
00405 root = self.retrieveObject('')
00406 if root :
00407 node = root.registry()
00408 rootFID = node.address().par()
00409 lst = []
00410 else :
00411 return
00412 Helper.dataobject( self._idp, node.identifier() )
00413 if node.object() :
00414 lst.append( node.identifier() )
00415 for l in self.leaves(node) :
00416 if l.address() and l.address().par() == rootFID :
00417 self.getList(l,lst,rootFID)
00418 else :
00419 continue
00420 return lst
00421 def getHistoNames( self, node=None, lst=[] ) :
00422 if not node :
00423 root = self.retrieveObject('')
00424 if root :
00425 node = root.registry()
00426
00427 lst = []
00428 else : return
00429 Helper.dataobject( self._idp, node.identifier() )
00430 if node.object() :
00431 lst.append( node.identifier() )
00432 for l in self.leaves(node) :
00433 if l.name() :
00434 self.getHistoNames(l,lst)
00435 else :
00436 continue
00437 return lst
00438 def setRoot(self, name, obj):
00439 if not self._idm : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
00440 return self._idm.setRoot(name,obj)
00441 def clearStore(self):
00442 if not self._idm : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
00443 return self._idm.clearStore()
00444
00445
00446
00447 class iHistogramSvc(iDataSvc) :
00448 def __init__(self, name, ihs) :
00449 self.__dict__['_ihs'] = InterfaceCast(gbl.IHistogramSvc)(ihs)
00450 iDataSvc.__init__(self, name, ihs)
00451 def retrieve1D(self, path) :
00452 return Helper.histo1D(self._ihs, path)
00453 def retrieve2D(self, path) :
00454 return Helper.histo2D(self._ihs, path)
00455 def retrieve3D(self, path) :
00456 return Helper.histo3D(self._ihs, path)
00457 def retrieveProfile1D(self, path) :
00458 return Helper.profile1D(self._ihs, path)
00459 def retrieveProfile2D(self, path) :
00460 return Helper.profile2D(self._ihs, path)
00461 def retrieve(self,path):
00462 """
00463 Retrieve AIDA histogram or AIDA profile histogram by path in Histogram Transient Store
00464 >>> svc = ...
00465 >>> histo = svc.retrieve ( 'path/to/my/histogram' )
00466 """
00467 h = self.retrieve1D(path)
00468 if not h : h = self.retrieve2D(path)
00469 if not h : h = self.retrieve3D(path)
00470 if not h : h = self.retrieveProfile1D(path)
00471 if not h : h = self.retrieveProfile2D(path)
00472 return h
00473 def book(self, *args) :
00474 """
00475 Book the histograms(1D,2D&3D) , see IHistogramSvc::book
00476 >>> svc = ...
00477 >>> histo = svc.book( .... )
00478 """
00479 return apply(self._ihs.book,args)
00480 def bookProf(self, *args) :
00481 """
00482 Book the profile(1D&2D) histograms, see IHistogramSvc::bookProf
00483 >>> svc = ...
00484 >>> histo = svc.bookProf( .... )
00485 """
00486 return apply(self._ihs.bookProf,args)
00487 def __getitem__ ( self, path ) :
00488 """
00489 Retrieve the object from Histogram Transient Store (by path)
00490 The reference to AIDA histogram is returned (if possible)
00491 >>> svc = ...
00492 >>> histo = svc['path/to/my/histogram']
00493 """
00494 h = self.retrieve ( path )
00495 if h : return h
00496 return iDataSvc.__getitem__( self , path )
00497 def getAsAIDA ( self , path ) :
00498 """
00499 Retrieve the histogram from Histogram Transient Store (by path)
00500 The reference to AIDA histogram is returned (if possible)
00501 >>> svc = ...
00502 >>> histo = svc.getAsAIDA ( 'path/to/my/histogram' )
00503 """
00504 return self.__getitem__( path )
00505 def getAsROOT ( self , path ) :
00506 """
00507 Retrieve the histogram from Histogram Transient Store (by path)
00508 The Underlying native ROOT object is returned (if possible)
00509 >>> svc = ...
00510 >>> histo = svc.getAsROOT ( 'path/to/my/histogram' )
00511 """
00512 fun=gbl.Gaudi.Utils.Aida2ROOT.aida2root
00513 return fun( self.getAsAIDA( path ) )
00514
00515
00516 class iNTupleSvc(iDataSvc) :
00517 RowWiseTuple = 42
00518 ColumnWiseTuple = 43
00519 def __init__(self, name, ints) :
00520 self.__dict__['_ints'] = InterfaceCast(gbl.INTupleSvc)(ints)
00521 iDataSvc.__init__(self, name, ints)
00522 def book(self, *args) :
00523 return apply(self._ints.book, args)
00524 def defineOutput(self, files, typ='ROOT') :
00525 """ Defines dthe mapping between logical names and the output file
00526 Usage:
00527 defineOutput({'LUN1':'MyFile1.root', 'LUN2':'Myfile2.root'}, typ='ROOT')
00528 """
00529 out = []
00530 for o in files :
00531 out.append( "%s DATAFILE='%s' OPT='RECREATE' TYP='%s'" % ( o, files[o], typ ) )
00532 self.Output = out
00533 if AppMgr().HistogramPersistency == 'NONE' : AppMgr().HistogramPersistency = typ
00534 def __getitem__ ( self, path ) :
00535 return iDataSvc.__getitem__( self , path )
00536
00537
00538
00539 class iToolSvc(iService) :
00540 def __init__(self, name, its) :
00541 self.__dict__['_its'] = InterfaceCast(gbl.IToolSvc)(its)
00542 iService.__init__(self, name, its)
00543 def _retrieve(self, name, quiet=True):
00544 sol = _gaudi.OutputLevel
00545 if quiet : self.OutputLevel = 6
00546 if name.rfind('.') == -1 :
00547 itool = Helper.tool(self._its, '', name, None, False )
00548 elif name[0:8] == 'ToolSvc.' :
00549 itool = Helper.tool(self._its, '', name[8:], None, False )
00550 elif name.count('.') > 1 :
00551 ptool = self._retrieve(name[:name.rfind('.')])
00552 itool = Helper.tool(self._its, '', name[name.rfind('.')+1:], ptool, False )
00553 elif _gaudi :
00554 prop = _gaudi.property(name[:name.rfind('.')])
00555 itool = Helper.tool(self._its, '', name[name.rfind('.')+1:], prop._ip, False )
00556 if quiet : self.OutputLevel = sol
00557 return itool
00558 def retrieve(self, name):
00559 return iAlgTool(name, self._retrieve(name,quiet=False))
00560 def create(self, typ, name=None, parent=None, interface=None) :
00561 if not name : name = typ
00562 itool = Helper.tool(self._its, typ, name, parent, True )
00563 if interface :
00564 return InterfaceCast(interface)(itool)
00565 else :
00566 return iAlgTool(name,itool)
00567 def release(self, itool) :
00568 if type(itool) is iAlgTool :
00569 self._its.releaseTool(itool._itool)
00570
00571
00572 class iJobOptSvc(iService) :
00573 """
00574 Python-image of C++ class IJobOptionsSvc
00575 """
00576
00577 def __init__( self , name , svc ) :
00578 """ constructor """
00579 self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(svc)
00580 return iService.__init__( self , name , svc )
00581 def getProperties( self , component ) :
00582 """
00583 Extract *ALL* properties of the given component
00584 Usage :
00585 >>> jos = gaudi.optSvc()
00586 >>> props = jos.getProperties( 'Name' )
00587 """
00588 props = self._optsvc.getProperties( component )
00589 prps = {}
00590 if not props : return prps
00591 for p in props :
00592 prop = p.name().upper()
00593 try :
00594 value = eval( p.value() , {} , {} )
00595 except: value = p.value()
00596 prps [ prop ] = value
00597
00598 return prps
00599 def getProperty ( self , component , name ) :
00600 """
00601 Get a certain property of the certain component
00602 Usage:
00603 >>> jos = ...
00604 >>> extServices = jos.getProperty( 'ApplicationMgr', 'ExtSvc' )
00605 """
00606
00607 all = self.getProperties ( component )
00608 return all.get( name.upper() , None )
00609
00610
00611 class iEventSelector(iService):
00612 def __init__(self):
00613 iService.__init__(self, 'EventSelector', Helper.service(gbl.Gaudi.svcLocator(),'EventSelector'))
00614 self.__dict__['g'] = AppMgr()
00615 def open(self, stream, typ = 'POOL_ROOT', opt = 'READ', sel = None, fun = None, collection = None ):
00616 if typ == 'ROOT' :
00617 self.g.declSvcType('RootEvtCnvSvc','DbEventCnvSvc')
00618 self.g.service('RootEvtCnvSvc').DbType = 'ROOT'
00619 self.g.createSvc('RootEvtCnvSvc')
00620 self.g.service('EventPersistencySvc').CnvServices = ['RootEvtCnvSvc']
00621 elif typ == 'POOL_ROOT':
00622 cacsvc = self.g.service('PoolDbCacheSvc')
00623 if hasattr(cacsvc, 'Dlls') : cacsvc.Dlls += ['lcg_RootStorageSvc', 'lcg_XMLCatalog']
00624 else : cacsvc.Dlls = ['lcg_RootStorageSvc', 'lcg_XMLCatalog']
00625 cacsvc.OutputLevel = 4
00626 cacsvc.DomainOpts = [ 'Domain[ROOT_All].CLASS_VERSION=2 TYP=int',
00627 'Domain[ROOT_Key].CLASS_VERSION=2 TYP=int',
00628 'Domain[ROOT_Tree].CLASS_VERSION=2 TYP=int' ]
00629 cacsvc.DatabaseOpts = ['']
00630 cacsvc.ContainerOpts = ['']
00631 self.g.createSvc('PoolDbCacheSvc')
00632 cnvSvcs = [('PoolRootEvtCnvSvc', 'POOL_ROOT'),
00633 ('PoolRootTreeEvtCnvSvc', 'POOL_ROOTTREE'),
00634 ('PoolRootKeyEvtCnvSvc', 'POOL_ROOTKEY')]
00635 for svc in cnvSvcs :
00636 self.g.declSvcType(svc[0], 'PoolDbCnvSvc')
00637 cnvsvc = self.g.service(svc[0])
00638 cnvsvc.DbType = svc[1]
00639 self.g.service('EventPersistencySvc').CnvServices = [ svc[0] for svc in cnvSvcs ]
00640 for svc in cnvSvcs :
00641 self.g.createSvc(svc[0])
00642 self.g.service('EventDataSvc').RootCLID = 1
00643 if type(stream) != list : stream = [stream]
00644 fixpart = "TYP=\'%s\' OPT=\'%s\'" % ( typ, opt )
00645 if sel : fixpart += " SEL=\'%s\'" % sel
00646 if fun : fixpart += " FUN=\'%s\'" % fun
00647 if collection : fixpart += " COLLECTION=\'%s\'" % collection
00648 cstream = ["DATAFILE=\'%s\' %s" % ( s, fixpart) for s in stream]
00649 self.Input = cstream
00650 self.reinitialize()
00651 def rewind(self):
00652
00653 self.g.service('EventLoopMgr').reinitialize()
00654
00655
00656 class AppMgr(iService) :
00657 def __new__ ( cls, *args, **kwargs ):
00658 global _gaudi
00659 if not _gaudi :
00660 newobj = object.__new__( cls, *args, **kwargs )
00661 cls.__init__(newobj, *args, **kwargs)
00662 _gaudi = newobj
00663 return _gaudi
00664 def __reset__(self):
00665 global _gaudi
00666
00667 self.exit()
00668
00669 self._evtpro.release()
00670 self._svcloc.release()
00671 self._appmgr.release()
00672
00673 gbl.Gaudi.setInstance(makeNullPointer('ISvcLocator'))
00674 gbl.Gaudi.setInstance(makeNullPointer('IAppMgrUI'))
00675
00676 _gaudi = None
00677 def __init__(self, outputlevel = -1, joboptions = None, selfoptions = {},
00678 dllname = None, factname = None) :
00679 global _gaudi
00680 if _gaudi : return
00681
00682 self.__dict__['_exit_called'] = False
00683 try:
00684 from GaudiKernel.Proxy.Configurable import expandvars
00685 except ImportError:
00686
00687 expandvars = lambda data : data
00688 if dllname and factname:
00689 self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname,factname)
00690 elif dllname:
00691 self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname)
00692 else:
00693 self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr()
00694 self.__dict__['_svcloc'] = gbl.Gaudi.svcLocator()
00695 self.__dict__['_algmgr'] = InterfaceCast(gbl.IAlgManager)(self._appmgr)
00696 self.__dict__['_evtpro'] = InterfaceCast(gbl.IEventProcessor)(self._appmgr)
00697 self.__dict__['_svcmgr'] = InterfaceCast(gbl.ISvcManager)(self._appmgr)
00698 self.__dict__['pyalgorithms'] = []
00699 iService.__init__(self, 'ApplicationMgr', self._appmgr )
00700
00701 if self.FSMState() < Gaudi.StateMachine.CONFIGURED :
00702 self.JobOptionsType = 'NONE'
00703 if joboptions :
00704 from GaudiKernel.ProcessJobOptions import importOptions
00705 importOptions(joboptions)
00706
00707 import GaudiKernel.Proxy.Configurable
00708 if hasattr(GaudiKernel.Proxy.Configurable, "applyConfigurableUsers"):
00709 GaudiKernel.Proxy.Configurable.applyConfigurableUsers()
00710
00711 self.OutputLevel = 3
00712 selfprops = Configurable.allConfigurables.get('ApplicationMgr',{})
00713 if selfprops : selfprops = expandvars(selfprops.getValuedProperties())
00714 for p,v in selfprops.items() : setattr(self, p, v)
00715 for p,v in selfoptions.items() : setattr(self, p, v)
00716
00717 if outputlevel != -1 : self.OutputLevel = outputlevel
00718 self.configure()
00719
00720 ms = self.service('MessageSvc')
00721 if 'MessageSvc' in Configurable.allConfigurables:
00722 msprops = Configurable.allConfigurables['MessageSvc']
00723 ms = self.service('MessageSvc')
00724 if hasattr(msprops,"getValuedProperties"):
00725 msprops = expandvars(msprops.getValuedProperties())
00726 for p,v in msprops.items():
00727 setattr(ms, p, v)
00728 if outputlevel != -1 : ms.OutputLevel = outputlevel
00729
00730 self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(Helper.service(self._svcloc,'JobOptionsSvc'))
00731
00732 for n in getNeededConfigurables():
00733 c = Configurable.allConfigurables[n]
00734 if n in ['ApplicationMgr','MessageSvc'] : continue
00735 for p, v in c.getValuedProperties().items() :
00736 v = expandvars(v)
00737
00738 if hasattr(Configurable,"PropertyReference") and type(v) == Configurable.PropertyReference:
00739
00740
00741 v = v.__resolve__()
00742 if type(v) == str : v = '"%s"' % v
00743 elif type(v) == long: v = '%d' % v
00744 self._optsvc.addPropertyToCatalogue(n, StringProperty(p,str(v)))
00745 if hasattr(Configurable,"_configurationLocked"):
00746 Configurable._configurationLocked = True
00747 def state(self) : return self._isvc.FSMState()
00748 def FSMState(self) : return self._isvc.FSMState()
00749 def targetFSMState(self) : return self._isvc.targetFSMState()
00750 def loaddict(self, dict) :
00751 loaddict(dict)
00752 def service(self, name, interface = None) :
00753 svc = Helper.service( self._svcloc, name )
00754 if interface :
00755 return InterfaceCast(interface)(svc)
00756 else :
00757 return iService(name, svc )
00758 def declSvcType(self, svcname, svctype ) :
00759 self._svcmgr.declareSvcType(svcname, svctype)
00760 def createSvc(self, name ) :
00761 return Helper.service( self._svcloc, name, True )
00762 def services(self) :
00763 l = self._svcloc.getServices()
00764 nl = l.__class__(l)
00765 s = []
00766 for i in range(l.size()) :
00767 s.append(nl.front().name())
00768 nl.pop_front()
00769 return s
00770 def algorithm(self, name ) :
00771 alg = Helper.algorithm( self._algmgr, name )
00772 return iAlgorithm(name, alg )
00773 def algorithms(self) :
00774 l = self._algmgr.getAlgorithms()
00775 nl = l.__class__(l)
00776 s = []
00777 for i in range(l.size()) :
00778 s.append(nl.front().name())
00779 nl.pop_front()
00780 return s
00781 def tool(self, name ) :
00782 return iAlgTool(name)
00783 def property( self , name ) :
00784 if name in self.algorithms() : return self.algorithm( name )
00785 elif name in self.services() : return self.service(name )
00786 else : return iProperty( name )
00787 def datasvc(self, name) :
00788 if self.state() == Gaudi.StateMachine.CONFIGURED : self.initialize()
00789 svc = Helper.service( self._svcloc, name )
00790 return iDataSvc(name, svc)
00791 def evtsvc(self) :
00792 return self.datasvc('EventDataSvc')
00793 def detsvc(self) :
00794 return self.datasvc('DetectorDataSvc')
00795 def filerecordsvc(self) :
00796 return self.datasvc('FileRecordDataSvc')
00797 def evtsel(self):
00798 if self.state() == Gaudi.StateMachine.CONFIGURED : self.initialize()
00799 if not hasattr(self,'_evtsel') : self.__dict__['_evtsel'] = iEventSelector()
00800 return self._evtsel
00801 def histsvc(self, name='HistogramDataSvc') :
00802 svc = Helper.service( self._svcloc, name )
00803 return iHistogramSvc(name, svc)
00804 def ntuplesvc(self, name='NTupleSvc') :
00805 if name not in self.ExtSvc : self.ExtSvc += [name]
00806
00807 svc = Helper.service( self._svcloc, name, True )
00808 return iNTupleSvc(name, svc)
00809 def partsvc(self ) :
00810 if self.FSMState() == Gaudi.StateMachine.CONFIGURED : self.initialize()
00811 svc = Helper.service( self._svcloc, 'ParticlePropertySvc' )
00812 return InterfaceCast(gbl.IParticlePropertySvc)(svc)
00813 def toolsvc(self, name='ToolSvc') :
00814 svc = Helper.service( self._svcloc, name, True )
00815 return iToolSvc(name, svc)
00816 def optSvc (self, name='JobOptionsSvc') :
00817 svc = Helper.service( self._svcloc, name, True )
00818 return iJobOptSvc(name, svc)
00819 def readOptions(self, file) :
00820 return self._optsvc.readOptions(file)
00821 def addAlgorithm(self, alg) :
00822 """ Add an Algorithm to the list of Top algorithms. It can be either a instance of
00823 an Algorithm class or it name """
00824 if type(alg) is str :
00825 self.topAlg += [alg]
00826 else :
00827 self.pyalgorithms.append(alg)
00828 setOwnership(alg,0)
00829 if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
00830 alg.sysInitialize()
00831 if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
00832 alg.sysStart()
00833 self.topAlg += [alg.name()]
00834 def setAlgorithms(self, algs) :
00835 """ Set the list of Top Algorithms.
00836 It can be an individual of a list of algorithms names or instances """
00837 if type(algs) is not list : algs = [algs]
00838 names = []
00839 for alg in algs :
00840 if type(alg) is str : names.append(alg)
00841 else :
00842 self.pyalgorithms.append(alg)
00843 if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
00844 alg.sysInitialize()
00845 if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
00846 alg.sysStart()
00847 names.append(alg.name())
00848 self.topAlg = names
00849 def removeAlgorithm(self, alg) :
00850 """ Remove an Algorithm to the list of Top algorithms. It can be either a instance of
00851 an Algorithm class or it name """
00852 tmp = self.topAlg
00853 if type(alg) is str :
00854 tmp.remove(alg)
00855 else :
00856 tmp.remove(alg.name())
00857 self.pyalgorithms.remove(alg)
00858 setOwnership(alg,1)
00859 self.topAlg = tmp
00860 def config ( self, **args ):
00861 """
00862 Simple utility to perform the configuration of Gaudi application.
00863 It reads the set of input job-options files, and set few
00864 additional parameters 'options' through the usage of temporary *.opts file
00865 Usage:
00866 gaudi.config( files = [ '$GAUSSOPTS/Gauss.opts' ,
00867 '$DECFILESROOT/options/10022_010.0GeV.opts' ] ,
00868 options = [ 'EventSelector.PrintFreq = 5 ' ] )
00869 """
00870 files = args.get('files',[])
00871 for file in files :
00872 sc = self.readOptions(file)
00873 if sc.isFailure() :
00874 raise RuntimeError , ' Unable to read file "' + file +'" '
00875 options = args.get('options',None)
00876 if options :
00877 import tempfile
00878 tmpfilename = tempfile.mktemp()
00879 tmpfile = open( tmpfilename, 'w' )
00880 tmpfile.write ( '#pragma print on \n' )
00881 tmpfile.write ( '/// File "' + tmpfilename+'" generated by GaudiPython \n\n' )
00882 for opt in options :
00883 if type(options) is dict :
00884 tmpfile.write( ' \t ' + opt + ' = '+ options[opt]+ ' ; // added by GaudiPython \n' )
00885 else :
00886 tmpfile.write( ' \t ' + opt + ' ; // added by GaudiPython \n' )
00887 tmpfile.write ( '/// End of file "' + tmpfilename+'" generated by GaudiPython \n\n' )
00888 tmpfile.close()
00889 sc = self.readOptions( tmpfilename )
00890 if sc.isFailure() :
00891 raise RuntimeError , ' Unable to read file "' + tmpfilename +'" '
00892 os.remove( tmpfilename )
00893
00894 if self.FSMState() != Gaudi.StateMachine.OFFLINE :
00895
00896
00897 jos = self.optSvc()
00898
00899
00900 _dlls = jos.getProperty ( self.name() , 'DLLs' )
00901
00902 if _dlls :
00903 libs = [ l for l in _dlls if not l in self.DLLs ]
00904 if libs : self.DLLs += libs
00905
00906
00907 _svcs = jos.getProperty ( self.name() , 'ExtSvc' )
00908
00909 if _svcs :
00910 svcs = [ s for s in _svcs if not s in self.ExtSvc ]
00911 if svcs : self.ExtSvc += svcs
00912
00913
00914 props = jos.getProperties ( self.name() )
00915
00916 for key in props :
00917 if 'DLLS' == key or 'EXTSVC' == key : continue
00918 self.__setattr__( key , props[key] )
00919 return SUCCESS
00920 def configure(self) :
00921 return self._appmgr.configure()
00922 def start(self) :
00923 return self._appmgr.start()
00924 def run(self, n) :
00925 if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
00926 sc = self.initialize()
00927 if sc.isFailure(): return sc
00928 if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
00929 sc = self.start()
00930 if sc.isFailure(): return sc
00931 return self._evtpro.executeRun(n)
00932 def executeEvent(self) :
00933 return self._evtpro.executeEvent()
00934 def execute(self) :
00935 return self._evtpro.executeEvent()
00936 def runSelectedEvents(self, pfn, events):
00937 if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
00938 sc = self.initialize()
00939 if sc.isFailure(): return sc
00940 if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
00941 sc = self.start()
00942 if sc.isFailure(): return sc
00943
00944 if not hasattr(self,'_perssvc'): self.__dict__['_perssvc'] = self.service('EventPersistencySvc','IAddressCreator')
00945 if not hasattr(self,'_filecat'): self.__dict__['_filecat'] = self.service('FileCatalog','Gaudi::IFileCatalog')
00946 if not hasattr(self,'_evtmgr'): self.__dict__['_evtmgr'] = self.service('EventDataSvc','IDataManagerSvc')
00947
00948 if pfn.find('PFN:') == 0: pfn = pfn[4:]
00949 fid, maxevt = _getFIDandEvents(pfn)
00950
00951 if not self._filecat.existsFID(fid) : self._filecat.registerPFN(fid, pfn, '')
00952
00953 if type(events) is not list : events = (events,)
00954 for evt in events :
00955
00956 gadd = gbl.GenericAddress(0x202, 1, fid, '/Event', 0, evt)
00957 oadd = makeNullPointer('IOpaqueAddress')
00958 self._perssvc.createAddress(gadd.svcType(),gadd.clID(),gadd.par(),gadd.ipar(),oadd)
00959
00960 self._evtmgr.clearStore()
00961 self._evtmgr.setRoot('/Event',oadd)
00962 self._evtpro.executeEvent()
00963 def exit(self):
00964
00965 if not self._exit_called:
00966 self.__dict__['_exit_called'] = True
00967 if self.FSMState() == Gaudi.StateMachine.RUNNING:
00968 self._appmgr.stop().ignore()
00969 if self.FSMState() == Gaudi.StateMachine.INITIALIZED:
00970 self._appmgr.finalize().ignore()
00971 if self.FSMState() == Gaudi.StateMachine.CONFIGURED:
00972 self._appmgr.terminate()
00973 return SUCCESS
00974
00975 def __del__(self):
00976 self.exit()
00977 evtSvc = evtsvc
00978 histSvc = histsvc
00979 ntupleSvc = ntuplesvc
00980 evtSel = evtsel
00981 detSvc = detsvc
00982 toolSvc = toolsvc
00983 partSvc = partsvc
00984
00985
00986 def _getFIDandEvents( pfn ):
00987 tfile = gbl.TFile.Open(pfn)
00988 if not tfile : raise 'Cannot open ROOT file ', pfn
00989 tree = tfile.Get('##Params')
00990 tree.GetEvent(0)
00991 text = tree.db_string
00992 if 'NAME=FID' in text :
00993 fid = text[text.rfind('VALUE=')+6:-1]
00994 nevt = tfile.Get('_Event').GetEntries()
00995 tfile.Close()
00996 return fid, nevt
00997
00998
00999 def getComponentProperties( name ):
01000 """ Get all the properties of a component as a Python dictionary.
01001 The component is instantiated using the component library
01002 """
01003 properties = {}
01004 if name == 'GaudiSvc' :
01005 if Helper.loadDynamicLib(name) != 1 :
01006 raise ImportError, 'Error loading component library '+ name
01007 factorylist = gbl.FactoryTable.instance().getEntries()
01008 factories = _copyFactoriesFromList(factorylist)
01009 g = AppMgr(outputlevel=7)
01010 else :
01011 g = AppMgr(outputlevel=7)
01012 if Helper.loadDynamicLib(name) != 1 :
01013 raise ImportError, 'Error loading component library '+ name
01014 factorylist = gbl.FactoryTable.instance().getEntries()
01015 factories = _copyFactoriesFromList(factorylist)
01016 svcloc = gbl.Gaudi.svcLocator()
01017 dummysvc = gbl.Service('DummySvc',svcloc)
01018 for factory in factories :
01019 if InterfaceCast(gbl.IAlgFactory)(factory) : ctype = 'Algorithm'
01020 elif InterfaceCast(gbl.ISvcFactory)(factory) : ctype = 'Service'
01021 elif InterfaceCast(gbl.IToolFactory)(factory) : ctype = 'AlgTool'
01022 elif factory.ident() == 'ApplicationMgr' : ctype = 'ApplicationMgr'
01023 else : ctype = 'Unknown'
01024 cname = factory.ident().split()[-1]
01025 if ctype in ('Algorithm','Service', 'AlgTool', 'ApplicationMgr') :
01026 try :
01027 if ctype == 'AlgTool' :
01028 obj = factory.instantiate(dummysvc)
01029 else :
01030 obj = factory.instantiate(svcloc)
01031 except RuntimeError, text :
01032 print 'Error instantiating', cname, ' from ', name
01033 print text
01034 continue
01035 prop = iProperty('dummy', obj)
01036 properties[cname] = [ctype, prop.properties()]
01037 try: obj.release()
01038 except: pass
01039 return properties
01040
01041 def _copyFactoriesFromList(factories) :
01042 result = []
01043 for i in range(factories.size()) :
01044 factory = factories.front()
01045 result.append(factory)
01046 factories.pop_front()
01047 for factory in result :
01048 factories.push_back(factory)
01049 return result
01050
01051
01052
01053 _CallbackStreamBufBase = gbl.GaudiPython.CallbackStreamBuf
01054 class CallbackStreamBuf (_CallbackStreamBufBase):
01055 def __init__(self, callback):
01056 _CallbackStreamBufBase.__init__(self, self)
01057 self.callback = callback
01058 def _sync(self, string = None):
01059 if not string : return 0
01060 self.callback(string)
01061 return 0
01062
01063
01064
01065 _PyAlgorithm = gbl.GaudiPython.PyAlgorithm
01066 class PyAlgorithm (_PyAlgorithm) :
01067 def __init__(self, name=None) :
01068 if not name : name = self.__class__.__name__
01069 _PyAlgorithm.__init__(self, self, name)
01070 self._svcloc = gbl.Gaudi.svcLocator()
01071 self._algmgr = InterfaceCast(gbl.IAlgManager)(self._svcloc)
01072 sc = self._algmgr.addAlgorithm(self)
01073 if sc.isFailure() : raise RuntimeError, 'Unable to add Algorithm'
01074 def __del__(self):
01075 sc = self._algmgr.removeAlgorithm(self)
01076 if sc.isFailure() : pass
01077 def initialize(self) : return 1
01078 def start(self) : return 1
01079 def execute(self) : return 1
01080 def stop(self) : return 1
01081 def finalize(self) : return 1
01082 def beginRun(self) : return 1
01083 def endRun(self) : return 1
01084
01085
01086 try:
01087 import rlcompleter,readline
01088 readline.parse_and_bind("tab: complete")
01089 except:
01090 pass