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