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 )
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
00748
00749 import atexit
00750 atexit.register(self.exit)
00751
00752
00753
00754 root_handler_installed = False
00755 for h in atexit._exithandlers:
00756 func = h[0]
00757 if hasattr(func, "__module__") and func.__module__ == "ROOT":
00758 root_handler_installed = True
00759 break
00760
00761
00762
00763
00764 if not root_handler_installed:
00765 orig_register = atexit.register
00766 def register(func, *targs, **kargs):
00767 orig_register(func, *targs, **kargs)
00768 if hasattr(func, "__module__") and func.__module__ == "ROOT":
00769 orig_register(self.exit)
00770
00771
00772 register.__doc__ = (orig_register.__doc__ +
00773 "\nNote: version hacked by GaudiPython to work " +
00774 "around a problem with the ROOT exit handler")
00775 atexit.register = register
00776
00777 def state(self) : return self._isvc.FSMState()
00778 def FSMState(self) : return self._isvc.FSMState()
00779 def targetFSMState(self) : return self._isvc.targetFSMState()
00780 def loaddict(self, dict) :
00781 loaddict(dict)
00782 def service(self, name, interface = None) :
00783 svc = Helper.service( self._svcloc, name )
00784 if interface :
00785 return InterfaceCast(interface)(svc)
00786 else :
00787 return iService(name, svc )
00788 def declSvcType(self, svcname, svctype ) :
00789 self._svcmgr.declareSvcType(svcname, svctype)
00790 def createSvc(self, name ) :
00791 return Helper.service( self._svcloc, name, True )
00792 def services(self) :
00793 l = self._svcloc.getServices()
00794 nl = l.__class__(l)
00795 s = []
00796 for i in range(l.size()) :
00797 s.append(nl.front().name())
00798 nl.pop_front()
00799 return s
00800 def algorithm(self, name , createIf = False ) :
00801 alg = Helper.algorithm( self._algmgr, name , createIf )
00802 if not alg : return iAlgorithm ( name , alg )
00803 else : return iAlgorithm ( alg.name() , alg )
00804 def algorithms(self) :
00805 l = self._algmgr.getAlgorithms()
00806 nl = l.__class__(l)
00807 s = []
00808 for i in range(l.size()) :
00809 s.append(nl.front().name())
00810 nl.pop_front()
00811 return s
00812 def tool(self, name ) :
00813 return iAlgTool(name)
00814 def property( self , name ) :
00815 if name in self.algorithms() : return self.algorithm( name )
00816 elif name in self.services() : return self.service(name )
00817 else : return iProperty( name )
00818 def datasvc(self, name) :
00819 if self.state() == Gaudi.StateMachine.CONFIGURED : self.initialize()
00820 svc = Helper.service( self._svcloc, name )
00821 return iDataSvc(name, svc)
00822 def evtsvc(self) :
00823 return self.datasvc('EventDataSvc')
00824 def detsvc(self) :
00825 return self.datasvc('DetectorDataSvc')
00826 def filerecordsvc(self) :
00827 return self.datasvc('FileRecordDataSvc')
00828 def evtsel(self):
00829 if self.state() == Gaudi.StateMachine.CONFIGURED : self.initialize()
00830 if not hasattr(self,'_evtsel') : self.__dict__['_evtsel'] = iEventSelector()
00831 return self._evtsel
00832 def histsvc(self, name='HistogramDataSvc') :
00833 svc = Helper.service( self._svcloc, name )
00834 return iHistogramSvc(name, svc)
00835 def ntuplesvc(self, name='NTupleSvc') :
00836 if name not in self.ExtSvc : self.ExtSvc += [name]
00837
00838 svc = Helper.service( self._svcloc, name, True )
00839 return iNTupleSvc(name, svc)
00840 def partsvc(self ) :
00841 if self.FSMState() == Gaudi.StateMachine.CONFIGURED : self.initialize()
00842 svc = Helper.service( self._svcloc, 'ParticlePropertySvc' )
00843 return InterfaceCast(gbl.IParticlePropertySvc)(svc)
00844 def toolsvc(self, name='ToolSvc') :
00845 svc = Helper.service( self._svcloc, name, True )
00846 return iToolSvc(name, svc)
00847 def optSvc (self, name='JobOptionsSvc') :
00848 svc = Helper.service( self._svcloc, name, True )
00849 return iJobOptSvc(name, svc)
00850 def readOptions(self, file) :
00851 return self._optsvc.readOptions(file)
00852 def addAlgorithm(self, alg) :
00853 """ Add an Algorithm to the list of Top algorithms. It can be either a instance of
00854 an Algorithm class or it name """
00855 if type(alg) is str :
00856 self.topAlg += [alg]
00857 else :
00858 self.pyalgorithms.append(alg)
00859 setOwnership(alg,0)
00860 if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
00861 alg.sysInitialize()
00862 if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
00863 alg.sysStart()
00864 self.topAlg += [alg.name()]
00865 def setAlgorithms(self, algs) :
00866 """ Set the list of Top Algorithms.
00867 It can be an individual of a list of algorithms names or instances """
00868 if type(algs) is not list : algs = [algs]
00869 names = []
00870 for alg in algs :
00871 if type(alg) is str : names.append(alg)
00872 else :
00873 self.pyalgorithms.append(alg)
00874 if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
00875 alg.sysInitialize()
00876 if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
00877 alg.sysStart()
00878 names.append(alg.name())
00879 self.topAlg = names
00880 def removeAlgorithm(self, alg) :
00881 """ Remove an Algorithm to the list of Top algorithms. It can be either a instance of
00882 an Algorithm class or it name """
00883 tmp = self.topAlg
00884 if type(alg) is str :
00885 tmp.remove(alg)
00886 else :
00887 tmp.remove(alg.name())
00888 self.pyalgorithms.remove(alg)
00889 setOwnership(alg,1)
00890 self.topAlg = tmp
00891 def config ( self, **args ):
00892 """
00893 Simple utility to perform the configuration of Gaudi application.
00894 It reads the set of input job-options files, and set few
00895 additional parameters 'options' through the usage of temporary *.opts file
00896 Usage:
00897 gaudi.config( files = [ '$GAUSSOPTS/Gauss.opts' ,
00898 '$DECFILESROOT/options/10022_010.0GeV.opts' ] ,
00899 options = [ 'EventSelector.PrintFreq = 5 ' ] )
00900 """
00901 files = args.get('files',[])
00902 for file in files :
00903 sc = self.readOptions(file)
00904 if sc.isFailure() :
00905 raise RuntimeError , ' Unable to read file "' + file +'" '
00906 options = args.get('options',None)
00907 if options :
00908 import tempfile
00909 tmpfilename = tempfile.mktemp()
00910 tmpfile = open( tmpfilename, 'w' )
00911 tmpfile.write ( '#pragma print on \n' )
00912 tmpfile.write ( '/// File "' + tmpfilename+'" generated by GaudiPython \n\n' )
00913 for opt in options :
00914 if type(options) is dict :
00915 tmpfile.write( ' \t ' + opt + ' = '+ options[opt]+ ' ; // added by GaudiPython \n' )
00916 else :
00917 tmpfile.write( ' \t ' + opt + ' ; // added by GaudiPython \n' )
00918 tmpfile.write ( '/// End of file "' + tmpfilename+'" generated by GaudiPython \n\n' )
00919 tmpfile.close()
00920 sc = self.readOptions( tmpfilename )
00921 if sc.isFailure() :
00922 raise RuntimeError , ' Unable to read file "' + tmpfilename +'" '
00923 os.remove( tmpfilename )
00924
00925 if self.FSMState() != Gaudi.StateMachine.OFFLINE :
00926
00927
00928 jos = self.optSvc()
00929
00930
00931 _dlls = jos.getProperty ( self.name() , 'DLLs' )
00932
00933 if _dlls :
00934 libs = [ l for l in _dlls if not l in self.DLLs ]
00935 if libs : self.DLLs += libs
00936
00937
00938 _svcs = jos.getProperty ( self.name() , 'ExtSvc' )
00939
00940 if _svcs :
00941 svcs = [ s for s in _svcs if not s in self.ExtSvc ]
00942 if svcs : self.ExtSvc += svcs
00943
00944
00945 props = jos.getProperties ( self.name() )
00946
00947 for key in props :
00948 if 'DLLS' == key or 'EXTSVC' == key : continue
00949 self.__setattr__( key , props[key] )
00950 return SUCCESS
00951 def configure(self) :
00952 return self._appmgr.configure()
00953 def start(self) :
00954 return self._appmgr.start()
00955 def run(self, n) :
00956 if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
00957 sc = self.initialize()
00958 if sc.isFailure(): return sc
00959 if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
00960 sc = self.start()
00961 if sc.isFailure(): return sc
00962 return self._evtpro.executeRun(n)
00963 def executeEvent(self) :
00964 return self._evtpro.executeEvent()
00965 def execute(self) :
00966 return self._evtpro.executeEvent()
00967 def runSelectedEvents(self, pfn, events):
00968 if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
00969 sc = self.initialize()
00970 if sc.isFailure(): return sc
00971 if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
00972 sc = self.start()
00973 if sc.isFailure(): return sc
00974
00975 if not hasattr(self,'_perssvc'): self.__dict__['_perssvc'] = self.service('EventPersistencySvc','IAddressCreator')
00976 if not hasattr(self,'_filecat'): self.__dict__['_filecat'] = self.service('FileCatalog','Gaudi::IFileCatalog')
00977 if not hasattr(self,'_evtmgr'): self.__dict__['_evtmgr'] = self.service('EventDataSvc','IDataManagerSvc')
00978
00979 if pfn.find('PFN:') == 0: pfn = pfn[4:]
00980 fid, maxevt = _getFIDandEvents(pfn)
00981
00982 if not self._filecat.existsFID(fid) : self._filecat.registerPFN(fid, pfn, '')
00983
00984 if type(events) is not list : events = (events,)
00985 for evt in events :
00986
00987 gadd = gbl.GenericAddress(0x202, 1, fid, '/Event', 0, evt)
00988 oadd = makeNullPointer('IOpaqueAddress')
00989 self._perssvc.createAddress(gadd.svcType(),gadd.clID(),gadd.par(),gadd.ipar(),oadd)
00990
00991 self._evtmgr.clearStore()
00992 self._evtmgr.setRoot('/Event',oadd)
00993 self._evtpro.executeEvent()
00994 def exit(self):
00995
00996 if not self._exit_called:
00997 self.__dict__['_exit_called'] = True
00998 if self.FSMState() == Gaudi.StateMachine.RUNNING:
00999 self._appmgr.stop().ignore()
01000 if self.FSMState() == Gaudi.StateMachine.INITIALIZED:
01001 self._appmgr.finalize().ignore()
01002 if self.FSMState() == Gaudi.StateMachine.CONFIGURED:
01003 self._appmgr.terminate()
01004 return SUCCESS
01005
01006 def __del__(self):
01007 self.exit()
01008 evtSvc = evtsvc
01009 histSvc = histsvc
01010 ntupleSvc = ntuplesvc
01011 evtSel = evtsel
01012 detSvc = detsvc
01013 toolSvc = toolsvc
01014 partSvc = partsvc
01015
01016
01017 def _getFIDandEvents( pfn ):
01018 tfile = gbl.TFile.Open(pfn)
01019 if not tfile : raise 'Cannot open ROOT file ', pfn
01020 tree = tfile.Get('##Params')
01021 tree.GetEvent(0)
01022 text = tree.db_string
01023 if 'NAME=FID' in text :
01024 fid = text[text.rfind('VALUE=')+6:-1]
01025 nevt = tfile.Get('_Event').GetEntries()
01026 tfile.Close()
01027 return fid, nevt
01028
01029
01030 def getComponentProperties( name ):
01031 """ Get all the properties of a component as a Python dictionary.
01032 The component is instantiated using the component library
01033 """
01034 properties = {}
01035 if name == 'GaudiSvc' :
01036 if Helper.loadDynamicLib(name) != 1 :
01037 raise ImportError, 'Error loading component library '+ name
01038 factorylist = gbl.FactoryTable.instance().getEntries()
01039 factories = _copyFactoriesFromList(factorylist)
01040 g = AppMgr(outputlevel=7)
01041 else :
01042 g = AppMgr(outputlevel=7)
01043 if Helper.loadDynamicLib(name) != 1 :
01044 raise ImportError, 'Error loading component library '+ name
01045 factorylist = gbl.FactoryTable.instance().getEntries()
01046 factories = _copyFactoriesFromList(factorylist)
01047 svcloc = gbl.Gaudi.svcLocator()
01048 dummysvc = gbl.Service('DummySvc',svcloc)
01049 for factory in factories :
01050 if InterfaceCast(gbl.IAlgFactory)(factory) : ctype = 'Algorithm'
01051 elif InterfaceCast(gbl.ISvcFactory)(factory) : ctype = 'Service'
01052 elif InterfaceCast(gbl.IToolFactory)(factory) : ctype = 'AlgTool'
01053 elif factory.ident() == 'ApplicationMgr' : ctype = 'ApplicationMgr'
01054 else : ctype = 'Unknown'
01055 cname = factory.ident().split()[-1]
01056 if ctype in ('Algorithm','Service', 'AlgTool', 'ApplicationMgr') :
01057 try :
01058 if ctype == 'AlgTool' :
01059 obj = factory.instantiate(dummysvc)
01060 else :
01061 obj = factory.instantiate(svcloc)
01062 except RuntimeError, text :
01063 print 'Error instantiating', cname, ' from ', name
01064 print text
01065 continue
01066 prop = iProperty('dummy', obj)
01067 properties[cname] = [ctype, prop.properties()]
01068 try: obj.release()
01069 except: pass
01070 return properties
01071
01072 def _copyFactoriesFromList(factories) :
01073 result = []
01074 for i in range(factories.size()) :
01075 factory = factories.front()
01076 result.append(factory)
01077 factories.pop_front()
01078 for factory in result :
01079 factories.push_back(factory)
01080 return result
01081
01082
01083
01084 _CallbackStreamBufBase = gbl.GaudiPython.CallbackStreamBuf
01085 class CallbackStreamBuf (_CallbackStreamBufBase):
01086 def __init__(self, callback):
01087 _CallbackStreamBufBase.__init__(self, self)
01088 self.callback = callback
01089 def _sync(self, string = None):
01090 if not string : return 0
01091 self.callback(string)
01092 return 0
01093
01094
01095
01096 _PyAlgorithm = gbl.GaudiPython.PyAlgorithm
01097 class PyAlgorithm (_PyAlgorithm) :
01098 def __init__(self, name=None) :
01099 if not name : name = self.__class__.__name__
01100 _PyAlgorithm.__init__(self, self, name)
01101 self._svcloc = gbl.Gaudi.svcLocator()
01102 self._algmgr = InterfaceCast(gbl.IAlgManager)(self._svcloc)
01103 sc = self._algmgr.addAlgorithm(self)
01104 if sc.isFailure() : raise RuntimeError, 'Unable to add Algorithm'
01105 def __del__(self):
01106 sc = self._algmgr.removeAlgorithm(self)
01107 if sc.isFailure() : pass
01108 def initialize(self) : return 1
01109 def start(self) : return 1
01110 def execute(self) : return 1
01111 def stop(self) : return 1
01112 def finalize(self) : return 1
01113 def beginRun(self) : return 1
01114 def endRun(self) : return 1
01115
01116
01117 try:
01118 import rlcompleter, readline
01119 readline.parse_and_bind("tab: complete")
01120 except:
01121 pass