Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Bindings.py
Go to the documentation of this file.
1 # File: GaudiPython/Bindings.py
2 # Author: Pere Mato (pere.mato@cern.ch)
3 
4 """ GaudiPython.Bindings module.
5  This module provides the basic bindings of the main Gaudi
6  components to Python. It is itself based on the PyCintex
7  extersion module provided by LCG/ROOT that provided
8  dynamic bindigns of classes for which LCG dictionaires exists.
9 """
10 
11 __all__ = [ 'gbl','InterfaceCast', 'Interface', 'PropertyEntry',
12  'AppMgr', 'PyAlgorithm', 'CallbackStreamBuf',
13  'iAlgorithm', 'iDataSvc', 'iHistogramSvc','iNTupleSvc','iService', 'iAlgTool', 'Helper',
14  'SUCCESS', 'FAILURE', 'toArray',
15  'ROOT', 'makeNullPointer', 'makeClass', 'setOwnership',
16  'getClass', 'loaddict', 'deprecation' ]
17 
18 import os, sys, string, warnings, re
19 import PyCintex
20 import Pythonizations
21 # Import Configurable from AthenaCommon or GaudiKernel if the first is not
22 # available.
23 from GaudiKernel.Proxy.Configurable import Configurable, getNeededConfigurables
24 
25 #namespaces
26 gbl = PyCintex.makeNamespace('')
27 Gaudi = gbl.Gaudi
28 
29 _gaudi = None
30 
31 #----Useful shortcuts for classes -------------------------------------------------------
32 #Helper = PyCintex.makeClass ('GaudiPython::Helper')
33 Helper = gbl.GaudiPython.Helper
34 StringProperty = gbl.SimpleProperty ('string','BoundedVerifier<string>')
35 StringPropertyRef = gbl.SimplePropertyRef ('string','NullVerifier<string>')
36 GaudiHandleProperty = gbl.GaudiHandleProperty
37 GaudiHandleArrayProperty = gbl.GaudiHandleArrayProperty
38 DataObject = gbl.DataObject
39 SUCCESS = gbl.StatusCode( gbl.StatusCode.SUCCESS, True )
40 FAILURE = gbl.StatusCode( gbl.StatusCode.FAILURE, True )
41 # toIntArray, toShortArray, etc.
42 for l in [ l for l in dir(Helper) if re.match("^to.*Array$",l) ]:
43  exec "%s = Helper.%s"%(l,l)
44  __all__.append(l)
45 
46 # FIXME: (MCl) Hack to handle ROOT 5.18 and ROOT >= 5.20
47 if hasattr(Helper,"toArray"):
48  # This is not backward compatible, but allows to use the same signature
49  # with all the versions of ROOT.
50  toArray = lambda typ: getattr(Helper,"toArray")
51 else:
52  # forward to the actual implementation of GaudiPython::Helper::toArray<T>
53  toArray = lambda typ: getattr(Helper,"toArray<%s>"%typ)
54 
55 #----Convenient accessors to PyROOT functionality ---------------------------------------
56 ROOT = PyCintex.libPyROOT
57 makeNullPointer = PyCintex.libPyROOT.MakeNullPointer
58 makeClass = PyCintex.libPyROOT.MakeRootClass
59 setOwnership = PyCintex.libPyROOT.SetOwnership
60 
61 def deprecation(message):
62  warnings.warn('GaudiPython: '+ message, DeprecationWarning, stacklevel=3)
63 
64 #----InterfaceCast class ----------------------------------------------------------------
65 class InterfaceCast(object) :
66  """ Helper class to obtain the adequate interface from a component
67  by using the Gaudi queryInterface() mechanism """
68  def __init__(self, t ) :
69  if type(t) is str : t = PyCintex.makeClass(t)
70  self.type = t
71  def __call__(self, obj) :
72  if obj :
73  ip = PyCintex.libPyROOT.MakeNullPointer(self.type)
74  try:
75  if obj.queryInterface(self.type.interfaceID(), ip).isSuccess() :
76  return ip
77  else :
78  print "ERROR: queryInterface failed for", obj, "interface:", self.type
79  except Exception, e:
80  print "ERROR: exception", e, "caught when retrieving interface", self.type, "for object", obj
81  import traceback
82  traceback.print_stack()
83  return None
84  cast = __call__
85 #---Interface class (for backward compatibility)-----------------------------------------
87  def __init__(self, t ):
88  deprecation('Use InterfaceCast class instead')
89  InterfaceCast.__init__(self,t)
90  def cast(self, obj) :
91  return self(obj)
92 
93 #----load dictionary function using Gaudi function---------------------------------------
94 def loaddict(dict) :
95  """ Load a LCG dictionary using various mechanisms"""
96  if Helper.loadDynamicLib(dict) == 1 : return
97  else :
98  try:
99  PyCintex.loadDict(dict)
100  except:
101  raise ImportError, 'Error loading dictionary library'
102 
103 #---get a class (by loading modules if needed)--------------------------------------------
104 def getClass( name , libs = [] ) :
105  """
106  Function to retrieve a certain C++ class by name and to load dictionary if requested
107 
108  Usage:
109 
110  from gaudimodule import getClass
111  # one knows that class is already loaded
112  AppMgr = getClass( 'ApplicationMgr' )
113  # one knows where to look for class, if not loaded yet
114  MCParticle = getClass( 'MCParticle' , 'EventDict' )
115  # one knows where to look for class, if not loaded yet
116  Vertex = getClass( 'Vertex' , ['EventDict', 'PhysEventDict'] )
117  """
118  # see if class is already loaded
119  if hasattr( gbl , name ) : return getattr( gbl , name )
120  # try to load dictionaries and look for the required class
121  if type(libs) is not list : libs = [libs]
122  for lib in libs :
123  loaddict( lib )
124  if hasattr( gbl , name ) : return getattr( gbl , name )
125  # return None ( or raise exception? I do not know... )
126  return None
127 
128 #----PropertyEntry class---------------------------------------------------------------------
129 class PropertyEntry(object) :
130  """ holds the value and the documentation string of a property """
131  def __init__(self, prop) :
132  self._type = type(prop).__name__
133  self.__doc__ = " --- Property type is " + self.ptype()
134 
135  if issubclass(type(prop),GaudiHandleProperty) :
136  self._value = prop.value() # do nothing for ATLAS' handles
137  elif issubclass(type(prop),GaudiHandleArrayProperty) :
138  self._value = prop.value() # do nothing for ATLAS' handles
139  else :
140  # for all other types try to extract the native python type
141  try: self._value = eval( prop.toString() , {} , {} )
142  except:
143  if hasattr ( prop , 'value' ) : self._value = prop.value()
144  else : self._value = prop.toString()
145 
146  self.__doc__ += " --- Default value = " + str(self._value) + " --- "
147  if prop.documentation() != 'none':
148  self.__doc__ = prop.documentation() + '\\n' + self.__doc__
149  ## keep the original property
150  self._property = prop # property itself
151  def value(self) :
152  return self._value
153  def ptype(self) :
154  return self._type
155  def property(self):
156  "Return the underlying property itself "
157  return self._property
158  def documentation(self) :
159  return self.__doc__
160  def hasDoc(self):
161  return len(self.__doc__)>0 and self.__doc__ != 'none'
162 
163 #----iProperty class---------------------------------------------------------------------
164 class iProperty(object) :
165  """ Python equivalent to the C++ Property interface """
166  def __init__(self, name, ip = None) :
167  if ip : self.__dict__['_ip'] = InterfaceCast(gbl.IProperty)(ip)
168  else : self.__dict__['_ip'] = None
169  self.__dict__['_svcloc'] = gbl.Gaudi.svcLocator()
170  optsvc = Helper.service(self._svcloc,'JobOptionsSvc')
171  if optsvc : self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(optsvc)
172  else : self.__dict__['_optsvc'] = None
173  self.__dict__['_name'] = name
174  def getInterface(self) :
175  if not self._ip : self.retrieveInterface()
176  return self._ip
177  def retrieveInterface(self) :
178  pass
179  def __call_interface_method__(self,ifname,method,*args):
180  if not getattr(self,ifname) : self.retrieveInterface()
181  return getattr(getattr(self,ifname),method)(*args)
182  def __setattr__(self, name, value):
183  """
184  The method which is used for setting the property from the given value.
185  - In the case of the valid instance it sets the property through IProperty interface
186  - In the case of placeholder the property is added to JobOptionsCatalogue
187  """
188  if hasattr( value, 'toStringProperty' ):
189  # user defined behaviour
190  value = '%s' % value.toStringProperty()
191  ip = self.getInterface()
192  if ip :
193  if not gbl.Gaudi.Utils.hasProperty ( ip , name ) :
194  raise AttributeError, 'property %s does not exist' % name
195  prop = ip.getProperty(name)
196  if not hasattr ( prop , 'value' ) or not type( value ) == type( prop.value() ) :
197  if tuple == type( value ) : value = str(value)
198  elif hasattr ( value , 'toString' ) : value = value.toString()
199  elif not long == type( value ) : value = '%s' % value
200  else : value = '%d' % value
201  if prop.fromString( value ).isFailure() :
202  raise AttributeError, 'property %s could not be set from %s' % (name,value)
203  else :
204  if not prop.setValue( value ) :
205  raise AttributeError, 'property %s could not be set from %s' % (name,value)
206  else :
207  if type(value) == str : value = '"%s"' % value # need double quotes
208  elif type(value) == tuple : value = str(value)
209  elif hasattr( value , 'toString' ) : value = value.toString()
210  elif type(value) == long: value = '%d' % value # prevent pending 'L'
211  sp = StringProperty( name , str(value))
212  self._optsvc.addPropertyToCatalogue( self._name , sp )
213  def __getattr__(self, name ):
214  """
215  The method which returns the value for the given property
216  - In the case of the valid instance it returns the valid property value through IProperty interface
217  - In the case of placeholder the property value is retrieved from JobOptionsCatalogue
218  """
219  ip = self.getInterface()
220  if ip :
221  if not gbl.Gaudi.Utils.hasProperty ( ip , name ) :
222  raise AttributeError, 'property %s does not exist' % name
223  prop = ip.getProperty(name)
224  if StringProperty == type( prop ) : return prop.value()
225  elif StringPropertyRef == type( prop ) : return prop.value()
226  try: return eval( prop.toString(), {}, {} )
227  except : return prop.value()
228  else :
229  props = self._optsvc.getProperties(self._name)
230  for p in props :
231  if not p.name() == name : continue
232  # from JobOptionsSvc we always have only strings
233  try: return eval( p.value(), {}, {} )
234  except: return p.value()
235  raise AttributeError, 'property %s does not exist' % name
236  def properties(self):
237  dct = {}
238  props = None
239  ip = self.getInterface()
240  if ip :
241  props = ip.getProperties()
242  propsFrom = self._name # "interface"
243  else:
244  props = self._optsvc.getProperties( self._name )
245  propsFrom = "jobOptionsSvc"
246  if props:
247  for p in props :
248  try:
249  dct[p.name()] = PropertyEntry(p)
250  except (ValueError,TypeError),e:
251  raise ValueError, "gaudimodule.iProperty.properties(): %s%s processing property %s.%s = %s" % \
252  (e.__class__.__name__, e.args, propsFrom, p.name(), p.value())
253  return dct
254  def name(self) :
255  return self._name
256 
257 #----iService class---------------------------------------------------------------------
259  """ Python equivalent to IProperty interface """
260  def __init__(self, name, isvc = None ) :
261  iProperty.__init__(self, name, isvc )
262  if isvc : self.__dict__['_isvc'] = InterfaceCast(gbl.IService)(isvc)
263  else : self.__dict__['_isvc'] = None
264  def retrieveInterface(self) :
265  isvc = Helper.service(self._svcloc,self._name)
266  if isvc : iService.__init__(self, self._name, isvc)
267  initialize = lambda self : self.__call_interface_method__("_isvc","initialize")
268  start = lambda self : self.__call_interface_method__("_isvc","start")
269  stop = lambda self : self.__call_interface_method__("_isvc","stop")
270  finalize = lambda self : self.__call_interface_method__("_isvc","finalize")
271  reinitialize = lambda self : self.__call_interface_method__("_isvc","reinitialize")
272  restart = lambda self : self.__call_interface_method__("_isvc","restart")
273  def isValid(self) :
274  if self._isvc: return True
275  else : return False
276 
277 #----iAlgorithm class---------------------------------------------------------------------
279  """ Python equivalent to IAlgorithm interface """
280  def __init__(self, name, ialg = None ) :
281  iProperty.__init__(self, name, ialg )
282  if ialg : self.__dict__['_ialg'] = InterfaceCast(gbl.IAlgorithm)(ialg)
283  else : self.__dict__['_ialg'] = None
284  def retrieveInterface(self) :
285  ialg = Helper.algorithm(InterfaceCast(gbl.IAlgManager)(self._svcloc),self._name)
286  if ialg : iAlgorithm.__init__(self, self._name, ialg)
287  initialize = lambda self : self.__call_interface_method__("_ialg","initialize")
288  start = lambda self : self.__call_interface_method__("_ialg","start")
289  execute = lambda self : self.__call_interface_method__("_ialg","execute")
290  stop = lambda self : self.__call_interface_method__("_ialg","stop")
291  finalize = lambda self : self.__call_interface_method__("_ialg","finalize")
292  reinitialize = lambda self : self.__call_interface_method__("_ialg","reinitialize")
293  restart = lambda self : self.__call_interface_method__("_ialg","restart")
294  sysInitialize = lambda self : self.__call_interface_method__("_ialg","sysInitialize")
295  sysStart = lambda self : self.__call_interface_method__("_ialg","sysStart")
296  sysExecute = lambda self : self.__call_interface_method__("_ialg","sysExecute")
297  sysStop = lambda self : self.__call_interface_method__("_ialg","sysStop")
298  sysFinalize = lambda self : self.__call_interface_method__("_ialg","sysFinalize")
299  sysReinitialize = lambda self : self.__call_interface_method__("_ialg","sysReinitialize")
300  sysRestart = lambda self : self.__call_interface_method__("_ialg","sysRestart")
301 
302 #----iAlgTool class---------------------------------------------------------------------
304  """ Python equivalent to IAlgTool interface (not completed yet) """
305  def __init__(self, name, itool = None ) :
306  iProperty.__init__(self, name, itool )
307  if itool : self.__dict__['_itool'] = itool
308  else : self.__dict__['_itool'] = None
309  svc = Helper.service( self._svcloc, 'ToolSvc', True )
310  self.__dict__['_toolsvc']= iToolSvc('ToolSvc', svc)
311  def retrieveInterface(self) :
312  itool = self._toolsvc._retrieve(self._name)
313  if itool : iAlgTool.__init__(self, self._name, itool)
314  start = lambda self : self.__call_interface_method__("_itool","start")
315  stop = lambda self : self.__call_interface_method__("_itool","stop")
316  type = lambda self : self.__call_interface_method__("_itool","type")
317  def name(self) :
318  if self._itool : return self._itool.name()
319  else : return self._name
320 
321 #----iDataSvc class---------------------------------------------------------------------
323  def __init__(self, name, idp) :
324  iService.__init__(self, name, idp )
325  self.__dict__['_idp'] = InterfaceCast(gbl.IDataProviderSvc)(idp)
326  self.__dict__['_idm'] = InterfaceCast(gbl.IDataManagerSvc)(idp)
327  def registerObject(self, path, obj) :
328  if not self._idp : raise AttributeError('C++ service %s does not exist' % self.__dict__['_name'])
329  return self._idp.registerObject(path,obj)
330  def unregisterObject(self, path) :
331  if not self._idp : raise AttributeError('C++ service %s does not exist' % self.__dict__['_name'])
332  return self._idp.unregisterObject(path)
333  def retrieveObject(self, path) :
334  if not self._idp : return None
335  return Helper.dataobject(self._idp, path)
336  ## get object from TES
337  def findObject(self, path) :
338  """
339 
340  Get the existing object in TransientStore for the given location
341 
342  - loading of object from persistency is NOT triggered
343  - 'data-on-demand' action is NOT triggered
344 
345  >>> svc = ... ## get the service
346  >>> path = ... ## get the path in Transient Store
347  >>> data = svc.findObject ( path ) ## use the method
348 
349  """
350  if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
351  return Helper.findobject(self._idp, path)
352 
353  ## get or retrieve object, possible switch-off 'on-demand' actions
354  def getObject ( self , path , *args ) :
355  """
356  Get object from Transient Store for the given location
357 
358  arguments :
359  - path : Location of object in Transient Store
360  - retrieve (bool) True : retrieve versus find
361  - disable on-demand (bool) False : temporary disable 'on-demand' actions
362 
363  >>> svc = ... ## get the service
364  >>> path = ... ## get the path
365 
366  >>> data = svc.getObject ( path , False ) ## find object in Transient Store
367 
368  ## find object in Transient Store
369  # load form tape or use 'on-demand' action for missing objects :
370  >>> data = svc.getObject ( path , True )
371 
372  ## find object in Transient Store
373  # load from tape or for missing objects, disable 'on-demand'-actions
374  >>> data = svc.getObject ( path , True , True )
375 
376  """
377  if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
378  return Helper.getobject(self._idp, path, *args )
379 
380  def __getitem__(self, path) :
381  if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
382  return Helper.dataobject(self._idp, path)
383  def __setitem__(self, path, obj) :
384  if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
385  return self._idp.registerObject(path,obj)
386  def __delitem__(self, path) :
387  if not self._idp : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
388  return self._idp.unregisterObject(path)
389  def leaves(self, node=None) :
390  if not node : node = self.retrieveObject('')
391  ll = gbl.std.vector('IRegistry*')()
392  if type(node) is str : obj = self.retrieveObject(node)
393  else : obj = node
394  if self._idm.objectLeaves(node, ll).isSuccess() : return ll
395  def dump(self, node=None) :
396  if not node :
397  root = self.retrieveObject('')
398  if root : node = root.registry()
399  else : return
400  print node.identifier()
401  if node.object() :
402  for l in self.leaves(node) : self.dump(l)
403  def getList(self, node=None, lst=[], rootFID=None) :
404  if not node :
405  root = self.retrieveObject('')
406  if root :
407  node = root.registry()
408  rootFID = node.address().par()
409  lst = []
410  else :
411  return
412  Helper.dataobject( self._idp, node.identifier() )
413  if node.object() :
414  lst.append( node.identifier() )
415  for l in self.leaves(node) :
416  if l.address() and l.address().par() == rootFID :
417  self.getList(l,lst,rootFID)
418  else :
419  continue
420  return lst
421  def getHistoNames( self, node=None, lst=[] ) :
422  if not node :
423  root = self.retrieveObject('')
424  if root :
425  node = root.registry()
426  # rootFID = node.address().par()
427  lst = []
428  else : return
429  Helper.dataobject( self._idp, node.identifier() )
430  if node.object() :
431  lst.append( node.identifier() )
432  for l in self.leaves(node) :
433  if l.name() : # and l.address().par() == rootFID :
434  self.getHistoNames(l,lst)
435  else :
436  continue
437  return lst
438  def setRoot(self, name, obj):
439  if not self._idm : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
440  return self._idm.setRoot(name,obj)
441  def clearStore(self):
442  if not self._idm : raise IndexError('C++ service %s does not exist' % self.__dict__['_name'])
443  return self._idm.clearStore()
444 
445 
446 #----iHistogramSvc class---------------------------------------------------------------------
448  def __init__(self, name, ihs) :
449  self.__dict__['_ihs'] = InterfaceCast(gbl.IHistogramSvc)(ihs)
450  iDataSvc.__init__(self, name, ihs)
451  def retrieve1D(self, path) :
452  return Helper.histo1D(self._ihs, path)
453  def retrieve2D(self, path) :
454  return Helper.histo2D(self._ihs, path)
455  def retrieve3D(self, path) :
456  return Helper.histo3D(self._ihs, path)
457  def retrieveProfile1D(self, path) :
458  return Helper.profile1D(self._ihs, path)
459  def retrieveProfile2D(self, path) :
460  return Helper.profile2D(self._ihs, path)
461  def retrieve(self,path):
462  """
463  Retrieve AIDA histogram or AIDA profile histogram by path in Histogram Transient Store
464  >>> svc = ...
465  >>> histo = svc.retrieve ( 'path/to/my/histogram' )
466  """
467  h = self.retrieve1D(path)
468  if not h : h = self.retrieve2D(path)
469  if not h : h = self.retrieve3D(path)
470  if not h : h = self.retrieveProfile1D(path)
471  if not h : h = self.retrieveProfile2D(path)
472  return h
473  def book(self, *args) :
474  """
475  Book the histograms(1D,2D&3D) , see IHistogramSvc::book
476  >>> svc = ...
477  >>> histo = svc.book( .... )
478  """
479  return apply(self._ihs.book,args)
480  def bookProf(self, *args) :
481  """
482  Book the profile(1D&2D) histograms, see IHistogramSvc::bookProf
483  >>> svc = ...
484  >>> histo = svc.bookProf( .... )
485  """
486  return apply(self._ihs.bookProf,args)
487  def __getitem__ ( self, path ) :
488  """
489  Retrieve the object from Histogram Transient Store (by path)
490  The reference to AIDA histogram is returned (if possible)
491  >>> svc = ...
492  >>> histo = svc['path/to/my/histogram']
493  """
494  h = self.retrieve ( path )
495  if h : return h
496  return iDataSvc.__getitem__( self , path )
497  def getAsAIDA ( self , path ) :
498  """
499  Retrieve the histogram from Histogram Transient Store (by path)
500  The reference to AIDA histogram is returned (if possible)
501  >>> svc = ...
502  >>> histo = svc.getAsAIDA ( 'path/to/my/histogram' )
503  """
504  return self.__getitem__( path )
505  def getAsROOT ( self , path ) :
506  """
507  Retrieve the histogram from Histogram Transient Store (by path)
508  The Underlying native ROOT object is returned (if possible)
509  >>> svc = ...
510  >>> histo = svc.getAsROOT ( 'path/to/my/histogram' )
511  """
512  fun=gbl.Gaudi.Utils.Aida2ROOT.aida2root
513  return fun( self.getAsAIDA( path ) )
514 
515 #----iNTupleSvc class---------------------------------------------------------------------
517  RowWiseTuple = 42
518  ColumnWiseTuple = 43
519  def __init__(self, name, ints) :
520  self.__dict__['_ints'] = InterfaceCast(gbl.INTupleSvc)(ints)
521  iDataSvc.__init__(self, name, ints)
522  def book(self, *args) :
523  return apply(self._ints.book, args)
524  def defineOutput(self, files, typ="Gaudi::RootCnvSvc"):
525  """ Defines the mapping between logical names and the output file
526  Usage:
527  defineOutput({'LUN1':'MyFile1.root', 'LUN2':'Myfile2.root'}, svc='Gaudi::RootCnvSvc')
528  """
529  import Persistency as prs
530  helper = prs.get(typ)
531  helper.configure(AppMgr())
532  self.Output = [helper.formatOutput(files[lun], lun=lun) for lun in files]
533  if AppMgr().HistogramPersistency == 'NONE':
534  AppMgr().HistogramPersistency = "ROOT"
535  def __getitem__ ( self, path ) :
536  return iDataSvc.__getitem__( self , path )
537 
538 
539 #----iToolSvc class---------------------------------------------------------------------
541  def __init__(self, name, its) :
542  self.__dict__['_its'] = InterfaceCast(gbl.IToolSvc)(its)
543  iService.__init__(self, name, its)
544  def _retrieve(self, name, quiet=True):
545  sol = _gaudi.OutputLevel
546  if quiet : self.OutputLevel = 6
547  if name.rfind('.') == -1 :
548  itool = Helper.tool(self._its, '', name, None, False )
549  elif name[0:8] == 'ToolSvc.' :
550  itool = Helper.tool(self._its, '', name[8:], None, False )
551  elif name.count('.') > 1 :
552  ptool = self._retrieve(name[:name.rfind('.')])
553  itool = Helper.tool(self._its, '', name[name.rfind('.')+1:], ptool, False )
554  elif _gaudi :
555  prop = _gaudi.property(name[:name.rfind('.')])
556  itool = Helper.tool(self._its, '', name[name.rfind('.')+1:], prop._ip, False )
557  if quiet : self.OutputLevel = sol
558  return itool
559  def retrieve(self, name):
560  return iAlgTool(name, self._retrieve(name,quiet=False))
561  def create(self, typ, name=None, parent=None, interface=None) :
562  if not name : name = typ
563  itool = Helper.tool(self._its, typ, name, parent, True )
564  if interface :
565  return InterfaceCast(interface)(itool)
566  else :
567  return iAlgTool(name,itool)
568  def release(self, itool) :
569  if type(itool) is iAlgTool :
570  self._its.releaseTool(itool._itool)
571 
572 #----iJopOptSvc class-------------------------------------------------------------------
574  """
575  Python-image of C++ class IJobOptionsSvc
576  """
577  ## constructor
578  def __init__( self , name , svc ) :
579  """ constructor """
580  self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(svc)
581  return iService.__init__( self , name , svc )
582  def getProperties( self , component ) :
583  """
584  Extract *ALL* properties of the given component
585  Usage :
586  >>> jos = gaudi.optSvc()
587  >>> props = jos.getProperties( 'Name' )
588  """
589  props = self._optsvc.getProperties( component )
590  prps = {}
591  if not props : return prps # RETURN
592  for p in props :
593  prop = p.name().upper()
594  try :
595  value = eval( p.value() , {} , {} )
596  except: value = p.value()
597  prps [ prop ] = value
598 
599  return prps # RETURN
600  def getProperty ( self , component , name ) :
601  """
602  Get a certain property of the certain component
603  Usage:
604  >>> jos = ...
605  >>> extServices = jos.getProperty( 'ApplicationMgr', 'ExtSvc' )
606  """
607  ## get all properties of the component
608  all = self.getProperties ( component )
609  return all.get( name.upper() , None ) # RETURN
610 
611 #----iEventSelector class------------------------------------------------------------------
613  def __init__(self):
614  iService.__init__(self, 'EventSelector', Helper.service(gbl.Gaudi.svcLocator(),'EventSelector'))
615  self.__dict__['g'] = AppMgr()
616  def open(self, stream, typ = 'Gaudi::RootCnvSvc', **kwargs):
617  import Persistency as prs
618  helper = prs.get(typ)
619  helper.configure(self.g)
620  self.Input = helper.formatInput(stream, **kwargs)
621  self.reinitialize()
622  def rewind(self):
623  # It is not possible to reinitialize EventSelector only
624  self.g.service('EventLoopMgr').reinitialize()
625 
626 #----AppMgr class---------------------------------------------------------------------
627 class AppMgr(iService) :
628  def __new__ ( cls, *args, **kwargs ):
629  global _gaudi
630  if not _gaudi :
631  newobj = object.__new__( cls )
632  cls.__init__(newobj, *args, **kwargs)
633  _gaudi = newobj
634  return _gaudi
635  def __reset__(self):
636  global _gaudi
637  # Stop, Finalize and Terminate the current AppMgr
638  self.exit()
639  # release interfaces
640  self._evtpro.release()
641  self._svcloc.release()
642  self._appmgr.release()
643  # Reset the C++ globals
644  gbl.Gaudi.setInstance(makeNullPointer('ISvcLocator'))
645  gbl.Gaudi.setInstance(makeNullPointer('IAppMgrUI'))
646  # Reset the Python global
647  _gaudi = None
648  def __init__(self, outputlevel = -1, joboptions = None, selfoptions = {},
649  dllname = None, factname = None) :
650  global _gaudi
651  if _gaudi : return
652  # Protection against multiple calls to exit() if the finalization fails
653  self.__dict__['_exit_called'] = False
654  # keep the Gaudi namespace around (so it is still available during atexit shutdown)...
655  self.__dict__['_gaudi_ns'] = Gaudi
656  try:
657  from GaudiKernel.Proxy.Configurable import expandvars
658  except ImportError:
659  # pass-through implementation if expandvars is not defined (AthenaCommon)
660  expandvars = lambda data : data
661  if dllname and factname:
662  self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname,factname)
663  elif dllname:
664  self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr(dllname)
665  else:
666  self.__dict__['_appmgr'] = gbl.Gaudi.createApplicationMgr()
667  self.__dict__['_svcloc'] = gbl.Gaudi.svcLocator()
668  self.__dict__['_algmgr'] = InterfaceCast(gbl.IAlgManager)(self._appmgr)
669  self.__dict__['_evtpro'] = InterfaceCast(gbl.IEventProcessor)(self._appmgr)
670  self.__dict__['_svcmgr'] = InterfaceCast(gbl.ISvcManager)(self._appmgr)
671  self.__dict__['pyalgorithms'] = []
672  iService.__init__(self, 'ApplicationMgr', self._appmgr )
673  #------python specific initialization-------------------------------------
674  if self.FSMState() < Gaudi.StateMachine.CONFIGURED : # Not yet configured
675  self.JobOptionsType = 'NONE'
676  if joboptions :
677  from GaudiKernel.ProcessJobOptions import importOptions
678  importOptions(joboptions)
679  # Ensure that the ConfigurableUser instances have been applied
680  import GaudiKernel.Proxy.Configurable
681  if hasattr(GaudiKernel.Proxy.Configurable, "applyConfigurableUsers"):
682  GaudiKernel.Proxy.Configurable.applyConfigurableUsers()
683  # This is the default and could be overridden with "selfopts"
684  self.OutputLevel = 3
685  selfprops = Configurable.allConfigurables.get('ApplicationMgr',{})
686  if selfprops : selfprops = expandvars(selfprops.getValuedProperties())
687  for p,v in selfprops.items() : setattr(self, p, v)
688  for p,v in selfoptions.items() : setattr(self, p, v)
689  # Override job options
690  if outputlevel != -1 : self.OutputLevel = outputlevel
691  self.configure()
692  #---MessageSvc------------------------------------------------------------
693  ms = self.service('MessageSvc')
694  if 'MessageSvc' in Configurable.allConfigurables:
695  msprops = Configurable.allConfigurables['MessageSvc']
696  ms = self.service('MessageSvc')
697  if hasattr(msprops,"getValuedProperties"):
698  msprops = expandvars(msprops.getValuedProperties())
699  for p,v in msprops.items():
700  setattr(ms, p, v)
701  if outputlevel != -1 : ms.OutputLevel = outputlevel
702  #---JobOptions------------------------------------------------------------
703  self.__dict__['_optsvc'] = InterfaceCast(gbl.IJobOptionsSvc)(Helper.service(self._svcloc,'JobOptionsSvc'))
704  #------Configurables initialization (part2)-------------------------------
705  for n in getNeededConfigurables():
706  c = Configurable.allConfigurables[n]
707  if n in ['ApplicationMgr','MessageSvc'] : continue # These are already done---
708  for p, v in c.getValuedProperties().items() :
709  v = expandvars(v)
710  # Note: AthenaCommon.Configurable does not have Configurable.PropertyReference
711  if hasattr(Configurable,"PropertyReference") and type(v) == Configurable.PropertyReference:
712  # this is done in "getFullName", but the exception is ignored,
713  # so we do it again to get it
714  v = v.__resolve__()
715  if type(v) == str : v = '"%s"' % v # need double quotes
716  elif type(v) == long: v = '%d' % v # prevent pending 'L'
717  self._optsvc.addPropertyToCatalogue(n, StringProperty(p,str(v)))
718  if hasattr(Configurable,"_configurationLocked"):
719  Configurable._configurationLocked = True
720 
721  # Ensure that the exit method is called when exiting from Python
722  import atexit
723  atexit.register(self.exit)
724 
725  #---Hack to avoid bad interactions with the ROOT exit handler
726  # Look for an exit handler installed by ROOT
727  root_handler_installed = False
728  for h in atexit._exithandlers:
729  func = h[0]
730  if hasattr(func, "__module__") and func.__module__ == "ROOT":
731  root_handler_installed = True
732  break
733 
734  # If the handler is not yet installed, let's install our private version
735  # that detects that the ROOT exit handler is installed and add our own
736  # after it to ensure it is called before.
737  if not root_handler_installed:
738  orig_register = atexit.register
739  def register(func, *targs, **kargs):
740  orig_register(func, *targs, **kargs)
741  if hasattr(func, "__module__") and func.__module__ == "ROOT":
742  orig_register(self.exit)
743  # we do not need to remove out handler from the list because
744  # it can be safely called more than once
745  register.__doc__ = (orig_register.__doc__ +
746  "\nNote: version hacked by GaudiPython to work " +
747  "around a problem with the ROOT exit handler")
748  atexit.register = register
749 
750  def state(self) : return self._isvc.FSMState()
751  def FSMState(self) : return self._isvc.FSMState()
752  def targetFSMState(self) : return self._isvc.targetFSMState()
753  def loaddict(self, dict) :
754  loaddict(dict)
755  def service(self, name, interface = None) :
756  svc = Helper.service( self._svcloc, name )
757  if interface :
758  return InterfaceCast(interface)(svc)
759  else :
760  return iService(name, svc )
761  def declSvcType(self, svcname, svctype ) :
762  self._svcmgr.declareSvcType(svcname, svctype)
763  def createSvc(self, name ) :
764  return Helper.service( self._svcloc, name, True )
765  def services(self) :
766  l = self._svcloc.getServices()
767  nl = l.__class__(l) # get a copy
768  s = []
769  for i in range(l.size()) :
770  s.append(nl.front().name())
771  nl.pop_front()
772  return s
773  def algorithm(self, name , createIf = False ) :
774  alg = Helper.algorithm( self._algmgr, name , createIf )
775  if not alg : return iAlgorithm ( name , alg )
776  else : return iAlgorithm ( alg.name() , alg )
777  def algorithms(self) :
778  l = self._algmgr.getAlgorithms()
779  nl = l.__class__(l) # get a copy
780  s = []
781  for i in range(l.size()) :
782  s.append(nl.front().name())
783  nl.pop_front()
784  return s
785  def tool(self, name ) :
786  return iAlgTool(name)
787  def property( self , name ) :
788  if name in self.algorithms() : return self.algorithm( name )
789  elif name in self.services() : return self.service(name )
790  else : return iProperty( name )
791  def datasvc(self, name) :
792  if self.state() == Gaudi.StateMachine.CONFIGURED : self.initialize()
793  svc = Helper.service( self._svcloc, name )
794  return iDataSvc(name, svc)
795  def evtsvc(self) :
796  return self.datasvc('EventDataSvc')
797  def detsvc(self) :
798  return self.datasvc('DetectorDataSvc')
799  def filerecordsvc(self) :
800  return self.datasvc('FileRecordDataSvc')
801  def evtsel(self):
802  if self.state() == Gaudi.StateMachine.CONFIGURED : self.initialize()
803  if not hasattr(self,'_evtsel') : self.__dict__['_evtsel'] = iEventSelector()
804  return self._evtsel
805  def histsvc(self, name='HistogramDataSvc') :
806  svc = Helper.service( self._svcloc, name )
807  return iHistogramSvc(name, svc)
808  def ntuplesvc(self, name='NTupleSvc') :
809  if name not in self.ExtSvc : self.ExtSvc += [name]
810 # if self.HistogramPersistency == 'NONE' : self.HistogramPersistency = 'ROOT'
811  svc = Helper.service( self._svcloc, name, True )
812  return iNTupleSvc(name, svc)
813  def partsvc(self ) :
814  if self.FSMState() == Gaudi.StateMachine.CONFIGURED : self.initialize()
815  svc = Helper.service( self._svcloc, 'ParticlePropertySvc' )
816  return InterfaceCast(gbl.IParticlePropertySvc)(svc)
817  def toolsvc(self, name='ToolSvc') :
818  svc = Helper.service( self._svcloc, name, True )
819  return iToolSvc(name, svc)
820  def optSvc (self, name='JobOptionsSvc') :
821  svc = Helper.service( self._svcloc, name, True )
822  return iJobOptSvc(name, svc)
823  def readOptions(self, file) :
824  return self._optsvc.readOptions(file)
825  def addAlgorithm(self, alg) :
826  """ Add an Algorithm to the list of Top algorithms. It can be either a instance of
827  an Algorithm class or it name """
828  if type(alg) is str :
829  self.topAlg += [alg]
830  else :
831  self.pyalgorithms.append(alg)
832  setOwnership(alg,0)
833  if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
834  alg.sysInitialize()
835  if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
836  alg.sysStart()
837  self.topAlg += [alg.name()]
838  def setAlgorithms(self, algs) :
839  """ Set the list of Top Algorithms.
840  It can be an individual of a list of algorithms names or instances """
841  if type(algs) is not list : algs = [algs]
842  names = []
843  for alg in algs :
844  if type(alg) is str : names.append(alg)
845  else :
846  self.pyalgorithms.append(alg)
847  if self.targetFSMState() >= Gaudi.StateMachine.INITIALIZED :
848  alg.sysInitialize()
849  if self.targetFSMState() == Gaudi.StateMachine.RUNNING :
850  alg.sysStart()
851  names.append(alg.name())
852  self.topAlg = names
853  def removeAlgorithm(self, alg) :
854  """ Remove an Algorithm to the list of Top algorithms. It can be either a instance of
855  an Algorithm class or it name """
856  tmp = self.topAlg
857  if type(alg) is str :
858  tmp.remove(alg)
859  else :
860  tmp.remove(alg.name())
861  self.pyalgorithms.remove(alg)
862  setOwnership(alg,1)
863  self.topAlg = tmp
864  def config ( self, **args ):
865  """
866  Simple utility to perform the configuration of Gaudi application.
867  It reads the set of input job-options files, and set few
868  additional parameters 'options' through the usage of temporary *.opts file
869  Usage:
870  gaudi.config( files = [ '$GAUSSOPTS/Gauss.opts' ,
871  '$DECFILESROOT/options/10022_010.0GeV.opts' ] ,
872  options = [ 'EventSelector.PrintFreq = 5 ' ] )
873  """
874  files = args.get('files',[])
875  for file in files :
876  sc = self.readOptions(file)
877  if sc.isFailure() :
878  raise RuntimeError , ' Unable to read file "' + file +'" '
879  options = args.get('options',None)
880  if options :
881  import tempfile
882  tmpfilename = tempfile.mktemp()
883  tmpfile = open( tmpfilename, 'w' )
884  tmpfile.write ( '#pragma print on \n' )
885  tmpfile.write ( '/// File "' + tmpfilename+'" generated by GaudiPython \n\n' )
886  for opt in options :
887  if type(options) is dict :
888  tmpfile.write( ' \t ' + opt + ' = '+ options[opt]+ ' ; // added by GaudiPython \n' )
889  else :
890  tmpfile.write( ' \t ' + opt + ' ; // added by GaudiPython \n' )
891  tmpfile.write ( '/// End of file "' + tmpfilename+'" generated by GaudiPython \n\n' )
892  tmpfile.close()
893  sc = self.readOptions( tmpfilename )
894  if sc.isFailure() :
895  raise RuntimeError , ' Unable to read file "' + tmpfilename +'" '
896  os.remove( tmpfilename )
897  # We need to make sure that the options are taken by the ApplicationMgr
898  if self.FSMState() != Gaudi.StateMachine.OFFLINE : # The state is already configured, so we need to do something....
899 
900  ## get job-options-service, @see class iJobOptSvc
901  jos = self.optSvc()
902 
903  ## list of all libraries
904  _dlls = jos.getProperty ( self.name() , 'DLLs' )
905  ## take care about libraries : APPEND if not done yet
906  if _dlls :
907  libs = [ l for l in _dlls if not l in self.DLLs ]
908  if libs : self.DLLs += libs
909 
910  ## all external services
911  _svcs = jos.getProperty ( self.name() , 'ExtSvc' )
912  ## take care about services : APPEND if not done yet
913  if _svcs :
914  svcs = [ s for s in _svcs if not s in self.ExtSvc ]
915  if svcs : self.ExtSvc += svcs
916 
917  ## get all properties
918  props = jos.getProperties ( self.name() )
919  ## finally treat all other properties (presumably scalar properties)
920  for key in props :
921  if 'DLLS' == key or 'EXTSVC' == key : continue
922  self.__setattr__( key , props[key] )
923  return SUCCESS # RETURN
924  def configure(self) :
925  return self._appmgr.configure()
926  def start(self) :
927  return self._appmgr.start()
928  def run(self, n) :
929  if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
930  sc = self.initialize()
931  if sc.isFailure() or self.ReturnCode != 0:
932  return sc
933  if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
934  sc = self.start()
935  if sc.isFailure() or self.ReturnCode != 0:
936  return sc
937  return self._evtpro.executeRun(n)
938  def executeEvent(self) :
939  return self._evtpro.executeEvent()
940  def execute(self) :
941  return self._evtpro.executeEvent()
942  def runSelectedEvents(self, pfn, events):
943  if self.FSMState() == Gaudi.StateMachine.CONFIGURED :
944  sc = self.initialize()
945  if sc.isFailure(): return sc
946  if self.FSMState() == Gaudi.StateMachine.INITIALIZED :
947  sc = self.start()
948  if sc.isFailure(): return sc
949  #--- Access a number of services ----
950  if not hasattr(self,'_perssvc'): self.__dict__['_perssvc'] = self.service('EventPersistencySvc','IAddressCreator')
951  if not hasattr(self,'_filecat'): self.__dict__['_filecat'] = self.service('FileCatalog','Gaudi::IFileCatalog')
952  if not hasattr(self,'_evtmgr'): self.__dict__['_evtmgr'] = self.service('EventDataSvc','IDataManagerSvc')
953  #--- Get FID from PFN and number of events in file
954  if pfn.find('PFN:') == 0: pfn = pfn[4:]
955  fid, maxevt = _getFIDandEvents(pfn)
956  #--- Add FID into catalog if needed ---
957  if not self._filecat.existsFID(fid) : self._filecat.registerPFN(fid, pfn, '')
958  #--- Loop over events
959  if type(events) is not list : events = (events,)
960  for evt in events :
961  #--- Create POOL Address from Generic Address
962  gadd = gbl.GenericAddress(0x02, 1, fid, '/Event', 0, evt)
963  oadd = makeNullPointer('IOpaqueAddress')
964  self._perssvc.createAddress(gadd.svcType(),gadd.clID(),gadd.par(),gadd.ipar(),oadd)
965  #--- Clear TES, set root and run all algorithms
966  self._evtmgr.clearStore()
967  self._evtmgr.setRoot('/Event',oadd)
968  self._evtpro.executeEvent()
969  def exit(self):
970  # Protection against multiple calls to exit() if the finalization fails
971  if not self._exit_called:
972  self.__dict__['_exit_called'] = True
973  Gaudi = self._gaudi_ns
974  if self.FSMState() == Gaudi.StateMachine.RUNNING:
975  self._appmgr.stop().ignore()
976  if self.FSMState() == Gaudi.StateMachine.INITIALIZED:
977  self._appmgr.finalize().ignore()
978  if self.FSMState() == Gaudi.StateMachine.CONFIGURED:
979  self._appmgr.terminate()
980  return SUCCESS
981  ## Custom destructor to ensure that the application is correctly finalized when exiting from python.
982  def __del__(self):
983  self.exit()
984  evtSvc = evtsvc
985  histSvc = histsvc
986  ntupleSvc = ntuplesvc
987  evtSel = evtsel
988  detSvc = detsvc
989  toolSvc = toolsvc
990  partSvc = partsvc
991 
992 #--------------------------------------------------------------------------------------
993 def _getFIDandEvents( pfn ):
994  tfile = gbl.TFile.Open(pfn)
995  if not tfile : raise 'Cannot open ROOT file ', pfn
996  tree = tfile.Get('##Params')
997  tree.GetEvent(0)
998  text = tree.db_string
999  if 'NAME=FID' in text :
1000  fid = text[text.rfind('VALUE=')+6:-1]
1001  nevt = tfile.Get('_Event').GetEntries()
1002  tfile.Close()
1003  return fid, nevt
1004 
1005 #--------------------------------------------------------------------------------------
1007  """ Get all the properties of a component as a Python dictionary.
1008  The component is instantiated using the component library
1009  """
1010  properties = {}
1011  if name == 'GaudiCoreSvc' :
1012  if Helper.loadDynamicLib(name) != 1 :
1013  raise ImportError, 'Error loading component library '+ name
1014  factorylist = gbl.FactoryTable.instance().getEntries()
1015  factories = _copyFactoriesFromList(factorylist)
1016  g = AppMgr(outputlevel=7)
1017  else :
1018  g = AppMgr(outputlevel=7)
1019  if Helper.loadDynamicLib(name) != 1 :
1020  raise ImportError, 'Error loading component library '+ name
1021  factorylist = gbl.FactoryTable.instance().getEntries()
1022  factories = _copyFactoriesFromList(factorylist)
1023  svcloc = gbl.Gaudi.svcLocator()
1024  dummysvc = gbl.Service('DummySvc',svcloc)
1025  for factory in factories :
1026  if InterfaceCast(gbl.IAlgFactory)(factory) : ctype = 'Algorithm'
1027  elif InterfaceCast(gbl.ISvcFactory)(factory) : ctype = 'Service'
1028  elif InterfaceCast(gbl.IToolFactory)(factory) : ctype = 'AlgTool'
1029  elif factory.ident() == 'ApplicationMgr' : ctype = 'ApplicationMgr'
1030  else : ctype = 'Unknown'
1031  cname = factory.ident().split()[-1]
1032  if ctype in ('Algorithm','Service', 'AlgTool', 'ApplicationMgr') :
1033  try :
1034  if ctype == 'AlgTool' :
1035  obj = factory.instantiate(dummysvc)
1036  else :
1037  obj = factory.instantiate(svcloc)
1038  except RuntimeError, text :
1039  print 'Error instantiating', cname, ' from ', name
1040  print text
1041  continue
1042  prop = iProperty('dummy', obj)
1043  properties[cname] = [ctype, prop.properties()]
1044  try: obj.release()
1045  except: pass
1046  return properties
1047 
1048 def _copyFactoriesFromList(factories) :
1049  result = []
1050  for i in range(factories.size()) :
1051  factory = factories.front()
1052  result.append(factory)
1053  factories.pop_front()
1054  for factory in result :
1055  factories.push_back(factory)
1056  return result
1057 
1058 #----CallbackStreamBuf----------------------------------------------------------------
1059 # Used for redirecting C++ messages to python
1060 _CallbackStreamBufBase = gbl.GaudiPython.CallbackStreamBuf
1062  def __init__(self, callback):
1063  _CallbackStreamBufBase.__init__(self, self)
1064  self.callback = callback
1065  def _sync(self, string = None):
1066  if not string : return 0
1067  self.callback(string)
1068  return 0
1069 
1070 #----PyAlgorithm----------------------------------------------------------------------
1071 # Used to implement Algorithms in Python
1072 _PyAlgorithm = gbl.GaudiPython.PyAlgorithm
1074  def __init__(self, name=None) :
1075  if not name : name = self.__class__.__name__
1076  _PyAlgorithm.__init__(self, self, name)
1077  self._svcloc = gbl.Gaudi.svcLocator()
1078  self._algmgr = InterfaceCast(gbl.IAlgManager)(self._svcloc)
1079  sc = self._algmgr.addAlgorithm(self)
1080  if sc.isFailure() : raise RuntimeError, 'Unable to add Algorithm'
1081  def __del__(self):
1082  sc = self._algmgr.removeAlgorithm(self)
1083  if sc.isFailure() : pass
1084  def initialize(self) : return 1
1085  def start(self) : return 1
1086  def execute(self) : return 1
1087  def stop(self) : return 1
1088  def finalize(self) : return 1
1089  def beginRun(self) : return 1
1090  def endRun(self) : return 1
1091 
1092 #----Enable tab completion------------------------------------------------------------
1093 try:
1094  import rlcompleter, readline
1095  readline.parse_and_bind("tab: complete")
1096 except:
1097  pass

Generated at Wed Dec 4 2013 14:33:10 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004