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