The Gaudi Framework  v36r0 (4abb4d13)
Configurable.py
Go to the documentation of this file.
1 
14 from __future__ import absolute_import
15 
16 import copy
17 import string
18 import types
19 import os
20 import sys
21 from inspect import isclass
22 import six
23 import GaudiKernel.ConfigurableMeta as ConfigurableMeta
24 from GaudiKernel.Constants import error_explanation, \
25  VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL
26 from GaudiKernel.PropertyProxy import PropertyProxy
27 from GaudiKernel.GaudiHandles import *
28 from GaudiKernel.DataHandle import *
29 
30 from GaudiConfig.ControlFlow import (OrNode, AndNode, OrderedNode, ignore,
31  InvertNode, ControlFlowLeaf,
32  ControlFlowNode, CFTrue, CFFalse)
33 
34 # data ---------------------------------------------------------------------
35 __all__ = [
36  'Configurable', 'ConfigurableAlgorithm', 'ConfigurableAlgTool',
37  'ConfigurableAuditor', 'ConfigurableService', 'ConfigurableUser',
38  'VERBOSE', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'FATAL',
39  'appendPostConfigAction', 'removePostConfigAction'
40 ]
41 
42 # for messaging
43 import logging
44 log = logging.getLogger('Configurable')
45 
46 
47 def expandvars(data):
48  """
49  Expand environment variables "data".
50  Data can be string, list, tuple and dictionary. For collection, all the
51  contained strings will be manipulated (recursively).
52  """
53  import os.path
54  typ = type(data)
55  if typ is str:
56  return os.path.expandvars(data)
57  elif typ in [list, tuple]:
58  collect = []
59  for i in data:
60  collect.append(expandvars(i))
61  return typ(collect)
62  elif typ is dict:
63  collect = {}
64  for k in data:
65  collect[expandvars(k)] = expandvars(data[k])
66  return collect
67  return data
68 
69 
70 class Error(RuntimeError):
71  """
72  Error occurred in the configuration process.
73  """
74  pass
75 
76 
77 # Allow references to options as in old style
78 
79 
80 class PropertyReference(object):
81  def __init__(self, propname):
82  self.name = propname
83 
84  def __str__(self):
85  return "@%s" % self.name
86 
87  def __resolve__(self):
88  # late binding for property references
89  retval = None
90  refname, refprop = self.name.rsplit('.', 1)
91  if refname in Configurable.allConfigurables:
92  conf = Configurable.allConfigurables[refname]
93  retval = getattr(conf, refprop)
94  if hasattr(retval, "getFullName"):
95  retval = retval.getFullName()
96  else:
97  raise NameError(
98  "name '%s' not found resolving '%s'" % (refname, self))
99  return retval
100 
101  def getFullName(self):
102  """This function allow transparent integration with
103  Configurable.getValuedProperties.
104  """
105  try:
106  return self.__resolve__()
107  except NameError:
108  # ignore the error if we cannot resolve the name yet
109  return self
110  except AttributeError:
111  # ignore the error if we cannot resolve the attribute yet
112  return self
113 
114 
115 # base class for configurable Gaudi algorithms/services/algtools/etc. ======
116 
117 
119  six.with_metaclass(ConfigurableMeta.ConfigurableMeta, object)):
120  """Base class for Gaudi components that implement the IProperty interface.
121  Provides most of the boilerplate code, but the actual useful classes
122  are its derived ConfigurableAlgorithm, ConfigurableService, and
123  ConfigurableAlgTool."""
124 
125  # for detecting the default name
126  class DefaultName:
127  pass
128 
129  propertyNoValue = '<no value>'
130  indentUnit = '| '
131  printHeaderWidth = 100
132  printHeaderPre = 5
133 
134  __slots__ = (
135  '__children', # controlled components, e.g. private AlgTools
136  '__tools', # private AlgTools (#PM-->)
137  '_name', # the (unqualified) component name
138  '_inSetDefaults', # currently setting default values
139  '_initok', # used to enforce base class init
140  '_setupok', # for debugging purposes (temporary)
141  '_unpickling', # flag for actions done during unpickling
142  )
143 
144  allConfigurables = {
145  } # just names would do, but currently refs to the actual
146  configurableServices = {
147  } # just names would do, but currently refs to the actual
148  # configurables is needed for (temporary) backwards
149  # compatibility; will change in the future
150  _configurationLocked = False
151 
152  def __new__(cls, *args, **kwargs):
153  """To Gaudi, any object with the same type/name is the same object. Hence,
154  this is mimicked in the configuration: instantiating a new Configurable
155  of a type with the same name will return the same instance."""
156 
157  global log
158  func_code = six.get_function_code(cls.__init__)
159  func_defaults = six.get_function_defaults(cls.__init__)
160  # try to get the name of the Configurable (having a name is compulsory)
161  if 'name' in kwargs:
162  # simple keyword (by far the easiest)
163  name = kwargs['name']
164  elif 'name' in func_code.co_varnames:
165  # either positional in args, or default
166  index = list(func_code.co_varnames).index('name')
167  try:
168  # var names index is offset by one as __init__ is to be called with self
169  name = args[index - 1]
170  except IndexError:
171  # retrieve default value, then
172  name = func_defaults[index - (len(args) + 1)]
173  else:
174  # positional index is assumed (will work most of the time)
175  try:
176  name = args[1] # '0' is for self
177  except (IndexError, TypeError):
178  raise TypeError('no "name" argument while instantiating "%s"' %
179  cls.__name__)
180 
181  argname = name
182  if name == Configurable.DefaultName:
183  if hasattr(cls, 'DefaultedName'):
184  name = cls.DefaultedName
185  else:
186  name = cls.getType()
187  elif not name or type(name) != str:
188  # unnamed, highly specialized user code, etc. ... unacceptable
189  raise TypeError(
190  'could not retrieve name from %s.__init__ arguments' %
191  cls.__name__)
192 
193  # Handle the case of global tools to prepend ToolSvc in the name.
194  # This is needed for compatibility with old JobOptions files being read
195  if issubclass(cls, ConfigurableAlgTool) and '.' not in name:
196  name = 'ToolSvc.' + name
197 
198  # close backdoor access to otherwise private subalgs/tools
199  # PM if 0 <= name.find( '.' ):
200  # PM # temp protection for old style types
201  # PM from OldStyleConfig import GenericConfigurable
202  # PM if not issubclass( cls, GenericConfigurable ): # except raised for new types only
203  # PM raise NameError( '"%s": backdoor access to private configurables not allowed' % name )
204 
205  # ordinary recycle case
206  if name in cls.configurables:
207  conf = cls.configurables[name]
208  if name != argname: # special case: user derived <-> real ... make same
209  cls.configurables[conf.getType()] = conf
210  # ---PM: Initialize additional properties
211  for n, v in kwargs.items():
212  if n != "name": # it should not be confused with a normal property
213  setattr(conf, n, v)
214  if not cls._configurationLocked and not "_enabled" in kwargs and isinstance(
215  conf, ConfigurableUser):
216  # Ensure that the ConfigurableUser gets enabled if nothing is
217  # specified in the constructor.
218  setattr(conf, "_enabled", True)
219  return conf
220 
221  # a couple of special cases (note that these cases don't mix)
222  spos = name.find('/')
223  ti_name = None
224  if spos < 0:
225  ti_name = "%s/%s" % (name, name)
226  if ti_name in cls.configurables:
227  # support for old-style name as type/name lookup where name==type
228  return cls.configurables[ti_name]
229 
230  i_name = None
231  if spos > 0:
232  i_name = name[:spos]
233  if i_name == name[spos + 1:] and i_name in cls.configurables:
234  # this is the opposite of the above special case
235  return cls.configurables[i_name]
236 
237  # the following is purely for debugging support and should realistically bomb
238  conf = cls.allConfigurables.get(name, None) or\
239  (spos < 0 and cls.allConfigurables.get(ti_name, None)) or\
240  (spos > 0 and i_name == name[spos + 1:]
241  and cls.allConfigurables.get(i_name, None))
242  if conf: # wrong type used?
243  if conf.__class__ is ConfigurableGeneric:
244  # If the instance found is ConfigurableGeneric then
245  # we create a new one with the proper type and fill with
246  # the contents of the generic one
247  newconf = object.__new__(cls)
248  cls.__init__(newconf, *args, **kwargs)
249  # initialize with the properties of generic configurable
250  # (we map the names of the properties to lowercase versions because
251  # old options are not case sensitive)
252  names = {}
253  for n in newconf.__slots__:
254  names[n.lower()] = n
255  for n in conf._properties:
256  if names[n.lower()] != n:
257  log.warning(
258  "Option '%s' was used for %s, but the correct spelling is '%s'"
259  % (n, name, names[n.lower()]))
260  setattr(newconf, names[n.lower()], getattr(conf, n))
261  for n, v in kwargs.items():
262  setattr(newconf, n, v)
263  cls.configurables[name] = newconf
264  cls.allConfigurables[name] = newconf
265  return newconf
266  else:
267  # will be an actual error in the future (now only report as such)
268  log.error(
269  'attempt to redefine type of "%s" (was: %s, new: %s)%s',
270  name, conf.__class__.__name__, cls.__name__,
271  error_explanation)
272  # in the future:
273  # return None # will bomb on use (or go unharmed on non-use)
274  # for now, allow use through allConfigurables lookup
275  # ---PM: Initialize additional properties
276  for n, v in kwargs.items():
277  setattr(conf, n, v)
278  return conf
279 
280  # still here: create a new instance and initialize it
281  conf = object.__new__(cls)
282  cls.__init__(conf, *args, **kwargs)
283 
284  # update normal, per-class cache
285  cls.configurables[name] = conf
286 
287  for base in cls.__bases__:
288  if base.__name__ == 'ConfigurableService':
289  cls.configurableServices[name] = conf
290 
291  # update generics super-cache, if needed
292  cls.allConfigurables[name] = conf
293  # -->PM#if hasattr( cls, 'getType' ) and name.find('/') < 0:
294  # -->PM# cls.allConfigurables[ cls.getType() + '/' + name ] = conf
295 
296  return conf
297 
298  def __init__(self, name=DefaultName):
299  # check class readiness, all required overloads should be there now
300  klass = self.__class__
301 
302  # this is an abstract class
303  if klass == Configurable:
304  raise TypeError(
305  "%s is an ABC and can not be instantiated" % str(Configurable))
306 
307  # the following methods require overloading
308  # NOT YET meths = { 'getServices' : 1, # retrieve list of services to configure
309  meths = {
310  'getDlls': 1, # provide list of Dlls to load
311  'getGaudiType': 1, # return string describing component class
312  'getHandle': 1
313  } # provide access to C++ side component instance
314  # 'getType' : 1 } # return the type of the actual C++ component
315 
316  for meth, nArgs in meths.items():
317  try:
318  f = six.get_unbound_function(getattr(klass, meth))
319  except AttributeError:
320  raise NotImplementedError(
321  "%s is missing in class %s" % (meth, str(klass)))
322 
323  # in addition, verify the number of arguments w/o defaults
324  nargcount = six.get_function_code(f).co_argcount
325  fdefaults = six.get_function_defaults(f)
326  ndefaults = fdefaults and len(fdefaults) or 0
327  if not nargcount - ndefaults <= nArgs <= nargcount:
328  raise TypeError("%s.%s requires exactly %d arguments" %
329  (klass, meth, nArgs))
330 
331  # for using this Configurable as a (Gaudi) sequence
332  self.__children = []
333  self.__tools = {}
334 
335  # know who we are
336  if name == Configurable.DefaultName:
337  if hasattr(self.__class__, 'DefaultedName'):
338  self._name = self.__class__.DefaultedName
339  else:
340  self._name = self.getType()
341  else:
342  self._name = name
343 
344  # set to True when collecting defaults, False otherwise
345  self._inSetDefaults = False
346 
347  # for later, in case __init__ itself is overridden
348  self._initok = True
349 
350  # for debugging purposes (temporary)
351  self._setupok = False
352 
353  # used to prevent spurious deprecation warnings when unpickling
354  self._unpickling = False
355 
356  # pickle support
357  def __getstate__(self):
358  dict = {}
359  for name, proxy in self._properties.items():
360  try:
361  dict[name] = proxy.__get__(self)
362  except AttributeError:
363  pass
364 
365  dict['_Configurable__children'] = self.__children
366  dict['_Configurable__tools'] = self.__tools
367  dict['_name'] = self._name
368  return dict
369 
370  def __getnewargs__(self):
371  return (self._name, )
372 
373  def __setstate__(self, dict):
374  self._initok = True
375  from contextlib import contextmanager
376 
377  @contextmanager
378  def unpickling():
379  try:
380  self._unpickling = True
381  yield
382  finally:
383  self._unpickling = False
384 
385  with unpickling():
386  for n, v in dict.items():
387  setattr(self, n, v)
388 
389  # to allow a few basic sanity checks, as well as nice syntax
390  def __len__(self):
391  return len(self.__children)
392 
393  def __iter__(self):
394  return iter(self.__children)
395 
396  # ownership rules of self through copying
397  def __deepcopy__(self, memo):
398  newconf = object.__new__(self.__class__)
399  self.__class__.__init__(newconf, self.getName())
400 
401  for proxy in self._properties.values():
402  try:
403  proxy.__set__(newconf, proxy.__get__(self))
404  except AttributeError:
405  pass # means property was not set for self
406 
407  for c in self.__children:
408  newconf += c # processes proper copy semantics
409 
410  return newconf
411 
412  # hierarchy building, and ownership rules of children
413  def __iadd__(self, configs, descr=None):
414  if not type(configs) in (list, tuple):
415  configs = (configs, )
416 
417  joname = self.getJobOptName()
418 
419  for cfg in configs:
420  # prevent type mismatches
421  if not isinstance(cfg, Configurable):
422  raise TypeError("'%s' is not a Configurable" % str(cfg))
423 
424  cc = self.copyChildAndSetParent(cfg, joname)
425 
426  # filters dupes; usually "ok" (backdoor should catch them)
427  ccjo = cc.getJobOptName()
428  for c in self.__children:
429  if c.getJobOptName() == ccjo:
430  log.error('attempt to add a duplicate ... dupe ignored%s',
431  error_explanation)
432  break
433  else:
434  self.__children.append(cc)
435 
436  try:
437  if descr: # support for tool properties
438  descr.__set__(self, cc)
439  else:
440  setattr(self, cc.getName(), cc)
441  except AttributeError:
442  pass # to allow free addition of tools/subalgorithms
443 
444  return self
445 
446  def __getattr__(self, attr): # until ToolProperties exist ...
447 
448  if attr in self.__tools:
449  return self.__tools[attr]
450 
451  if attr in self._properties:
452  if isinstance(self._properties[attr].__get__(self), DataHandle):
453  return self._properties[attr].__get__(self)
454 
455  for c in self.__children:
456  if c.getName() == attr:
457  return c
458 
459  raise AttributeError(
460  "'%s' object has no attribute '%s'" % (self.__class__, attr))
461 
462  def __setattr__(self, name, value):
463  if self._configurationLocked:
464  raise RuntimeError(
465  "%s: Configuration cannot be modified after the ApplicationMgr has been started."
466  % self.name())
467  try:
468  super(Configurable, self).__setattr__(name, value)
469  except AttributeError:
470  raise AttributeError(
471  "Configurable '%s' does not have property '%s'." %
472  (self.__class__.__name__, name))
473 
474  def __delattr__(self, attr):
475  # remove as property, otherwise try as child
476  try:
477  # remove history etc., then reset to default (in case set before)
478  prop = self._properties[attr]
479  prop.__delete__(self)
480  prop.__set__(self, prop.default)
481  return # reaches here? was property: done now
482  except KeyError:
483  pass
484  # otherwise, remove the private tool
485  if attr in self.__tools:
486  del self.__tools[attr]
487 
488  # otherwise, remove child, if one is so named
489  for c in self.__children:
490  if c.getName() == attr:
491  self.__children.remove(c)
492 
493  # potentially, there are left over caches (certain user derived classes)
494  try:
495  del self.__dict__[attr]
496  except (AttributeError, KeyError):
497  pass
498 
499  def __bool__(self):
500  return True
501 
502  # Python 2 compatibility
503  __nonzero__ = __bool__
504 
505  def remove(self, items):
506  if type(items) != list and type(items) != tuple:
507  items = [items]
508 
509  self.__children = [e for e in self.__children if not e in items]
510 
511  def removeAll(self):
512  self.remove(self.__children)
513 
514  # called by __iadd__; determines child copy semantics
515  def copyChild(self, child):
516  return copy.deepcopy(child)
517 
518  def setParent(self, parentName):
519  pass
520 
521  def getParent(self):
522  return ""
523 
524  def hasParent(self, parent):
525  return False
526 
527  def copyChildAndSetParent(self, cfg, parent):
528  cc = self.copyChild(cfg)
529 
530  if hasattr(cc, 'setParent') and parent:
531  try:
532  cc.setParent(parent)
533  except RuntimeError as e:
534  # temporary backdoor resolution for compatibility
535  log.error(str(e) + '%s', error_explanation)
536  ccbd = cc.configurables[cc.getJobOptName()]
537 
538  # merge properties, new over pre-existing
539  for proxy in self._properties.values():
540  if cc in proxy.history:
541  proxy.__set__(ccbd, proxy.__get__(cc))
542 
543  # consolidate
544  cc = ccbd
545  return cc
546 
547  def getChildren(self):
548  return self.__children[:] # read only
549 
550  def getTools(self):
551  return self.__tools.values() # read only
552 
553  def children(self):
554  log.error(
555  "children() is deprecated, use getChildren() instead for consistency"
556  )
557  log.error(
558  "getChildren() returns a copy; to add a child, use 'parent += child'%s",
559  error_explanation)
560  return self.__children # by ref, for compatibility
561 
562  def getAllChildren(self):
563  """Get all (private) configurable children, both explicit ones (added with +=)
564  and the ones in the private GaudiHandle properties"""
565  childs = []
566  # add private configurable properties (also inside handles)
567  for proxy in self._properties.values():
568  try:
569  c = proxy.__get__(self)
570  except AttributeError:
571  pass
572  else:
573  if isinstance(c, Configurable) and not c.isPublic():
574  childs.append(c)
575  elif isinstance(c, GaudiHandle):
576  try:
577  conf = c.configurable
578  except AttributeError:
579  pass
580  else:
581  if not conf.isPublic():
582  childs.append(conf)
583  elif isinstance(c, GaudiHandleArray):
584  # only setup private arrays
585  if not c.isPublic():
586  for ci in c:
587  if isinstance(ci, Configurable):
588  childs.append(ci)
589  else:
590  try:
591  conf = ci.configurable
592  except AttributeError:
593  pass
594  else:
595  childs.append(conf)
596 
597  # add explicit children
598  childs += self.__children
599  return childs
600 
601  def getSequence(self):
602  elems = []
603  for c in self.__children:
604  elems.append(c.getFullName())
605  return elems
606 
607  def setup(self):
608  # make sure base class init has been called
609  if not hasattr(self, '_initok') or not self._initok:
610  # could check more, but this is the only explanation
611  raise TypeError("Configurable.__init__ not called in %s override" %
612  self.__class__.__name__)
613 
614 # log.debug("calling setup() on " + self.getFullJobOptName())
615 
616 # setup self: this collects all values on the python side
617  self.__setupServices()
618  self.__setupDlls()
619  self.__setupDefaults()
620 
621  # setup children
622  for c in self.getAllChildren():
623  c.setup()
624 
625  # now get handle to work with for moving properties into the catalogue
626  handle = self.getHandle()
627  if not handle:
628  log.debug('no handle for %s: not transporting properties',
629  self._name)
630  return # allowed, done early
631 
632  # pass final set of properties on to handle on the C++ side or JobOptSvc
633  for name in self._properties.keys():
634  if hasattr(self,
635  name): # means property has python-side value/default
636  setattr(handle, name, getattr(self, name))
637 
638  # for debugging purposes
639  self._setupok = True
640 
641  def getProperties(self):
642  props = {}
643  for name, proxy in self._properties.items():
644  try:
645  props[name] = proxy.__get__(self)
646  except AttributeError:
647  props[name] = Configurable.propertyNoValue
648 
649  return props
650 
652  """Get all properties with their description string as { name : (value, desc) }."""
653  props = {}
654  for name, proxy in self._properties.items():
655  try:
656  props[name] = (proxy.__get__(self), proxy.__doc__)
657  except AttributeError:
658  props[name] = (Configurable.propertyNoValue, proxy.__doc__)
659  return props
660 
662  props = {}
663  for name, proxy in self._properties.items():
664  if self.isPropertySet(name):
665  value = proxy.__get__(self)
666  if hasattr(value, 'getFullName'):
667  value = value.getFullName()
668  elif type(value) in [list, tuple]:
669  new_value = []
670  for i in value:
671  if hasattr(i, 'getFullName'):
672  new_value.append(i.getFullName())
673  else:
674  new_value.append(i)
675  value = type(value)(new_value)
676  elif type(value) is dict:
677  new_value = {}
678  for i in value:
679  if hasattr(value[i], 'getFullName'):
680  new_value[i] = value[i].getFullName()
681  else:
682  new_value[i] = value[i]
683  value = new_value
684  props[name] = value
685 
686  return props
687 
688  def properties(self):
689  return self.getProperties() # compatibility
690 
691  @classmethod
693  class collector:
694  pass
695 
696  # user provided defaults
697  c = collector()
698  cls.setDefaults(c)
699 
700  # defaults from C++
701  for k, v in cls._properties.items():
702  if not k in c.__dict__ and hasattr(v, 'default'):
703  c.__dict__[k] = v.default
704 
705  return c.__dict__
706 
707  @classmethod
708  def getDefaultProperty(cls, name):
709  class collector:
710  pass
711 
712  # user provided defaults
713  c = collector()
714  cls.setDefaults(c)
715 
716  if name in c.__dict__:
717  return c.__dict__[name]
718 
719  # defaults from C++
720  try:
721  v = cls._properties[name]
722  if hasattr(v, 'default'):
723  return v.default
724  except KeyError:
725  pass
726 
727  return None
728 
729  def getProp(self, name):
730  """Returns the value of the given property.
731  """
732  if hasattr(self, name):
733  return getattr(self, name)
734  else:
735  return self.getDefaultProperties()[name]
736 
737  def setProp(self, name, value):
738  """Set the value of a given property
739  """
740  return setattr(self, name, value)
741 
742  def isPropertySet(self, name):
743  """Tell if the property 'name' has been set or not.
744 
745  Because of a problem with list and dictionary properties, in those cases
746  if the value is equal to the default, the property is considered as not
747  set.
748  """
749  if not hasattr(self, name):
750  return False
751  default = self.getDefaultProperty(name)
752  if isinstance(default, (list, dict, DataHandle)):
753  value = getattr(self, name)
754  return value != default
755  return True
756 
757  def getType(cls):
758  return cls.__name__
759 
760  def getName(self):
761  return self._name
762 
763  def name(self):
764  return self.getName()
765 
766  def getJobOptName(self): # full hierachical name
767  return self.getName()
768 
769  def isPublic(self):
770  return True
771 
772  # for a couple of existing uses out there
773  def jobOptName(self):
774  log.error(
775  "jobOptName() is deprecated, use getJobOptName() instead for consistency%s",
776  error_explanation)
777  return self.getJobOptName() # compatibility
778 
779  def getFullName(self):
780  return str(self.getType() + '/' + self.getName())
781 
782  def getFullJobOptName(self):
783  return "%s/%s" % (self.getType(), self.getJobOptName()
784  or self.getName())
785 
786  def getPrintTitle(self):
787  return self.getGaudiType() + ' ' + self.getTitleName()
788 
789  def getTitleName(self):
790  if log.isEnabledFor(logging.DEBUG):
791  return self.getFullJobOptName()
792  else:
793  return self.getFullName()
794 
795  def setDefaults(cls, handle):
796  pass
797 
798  def clone(self, name=None, **kwargs):
799  if not name:
800  if hasattr(self, 'DefaultedName'):
801  name = self.DefaultedName
802  else:
803  name = self.getType()
804 
805  newconf = Configurable.__new__(self.__class__, name)
806  self.__class__.__init__(newconf, name)
807 
808  for proxy in self._properties.values():
809  try:
810  value = proxy.__get__(self)
811  if type(value) in [str, list, dict, tuple]:
812  # clone the values of the properties for basic types
813  value = type(value)(value)
814  proxy.__set__(newconf, value)
815  except AttributeError:
816  pass
817 
818  for c in self.__children:
819  newconf += c # processes proper copy semantics
820 
821  for n, t in self.__tools.items():
822  newconf.addTool(t, n)
823 
824  for name, value in kwargs.items():
825  setattr(newconf, name, value)
826 
827  return newconf
828 
829  def splitName(self):
830  fullname = self.getName()
831  dot = fullname.find('.')
832  if dot != -1:
833  parentname = fullname[:dot]
834  longname = fullname[dot + 1:]
835  else:
836  parentname = ''
837  longname = fullname
838  dot = longname.find('.')
839  if dot != -1:
840  name = longname[:dot]
841  else:
842  name = longname
843  return parentname, name, longname
844 
845  def addTool(self, tool, name=None):
846  if isclass(tool) and issubclass(tool, ConfigurableAlgTool):
847  if name is None:
848  name = tool.__name__
849  priv_tool = tool(self.getName() + '.' + name)
850  elif isinstance(tool, ConfigurableAlgTool):
851  if name is None:
852  name = tool.splitName()[1]
853  priv_tool = tool.clone(self.getName() + '.' + name)
854  else:
855  if isclass(tool):
856  classname = tool.__name__
857  else:
858  classname = type(tool).__name__
859  raise TypeError(
860  "addTool requires AlgTool configurable. Got %s type" %
861  classname)
862  self.__tools[name] = priv_tool
863  if name in self.__slots__:
864  # this is to avoid that the property hides the tool
865  setattr(self, name, self.__tools[name])
866  return self.__tools[name]
867 
868  def _isInSetDefaults(self):
869  return self._inSetDefaults
870 
871  def __setupServices(self):
872  #svcs = self.getServices()
873  # if not svcs:
874  svcs = []
875  # elif type(svcs) == types.StringType:
876  # svcs = [ svcs ]
877 
878  import __main__
879  for svc in svcs:
880  handle = __main__.Service(svc)
881  # services should be configurables as well, but aren't for now
882  # handle.setup()
883 
884  # allow Configurable to make some changes
885  if hasattr(self, 'configure' + svc):
886  eval('self.configure' + svc + '( handle )')
887 
888  def __setupDlls(self):
889  dlls = self.getDlls()
890  if not dlls:
891  dlls = []
892  elif type(dlls) == types.StringType:
893  dlls = [dlls]
894 
895  from __main__ import theApp
896  dlls = filter(lambda d: d not in theApp.Dlls, dlls)
897  if dlls:
898  theApp.Dlls += dlls
899 
900  def __setupDefaults(self):
901  # set handle defaults flags to inform __setattr__ that it is being
902  # called during setDefaults of the concrete Configurable
903  self._inSetDefaults = True
904  self.setDefaults(self)
905  self._inSetDefaults = False
906 
907  @staticmethod
908  def _printHeader(indentStr, title):
909  preLen = Configurable.printHeaderPre
910  postLen = Configurable.printHeaderWidth - \
911  preLen - 3 - len(title) # - len(indentStr)
912  postLen = max(preLen, postLen)
913  return indentStr + '/%s %s %s' % (preLen * '*', title, postLen * '*')
914 
915  @staticmethod
916  def _printFooter(indentStr, title):
917  preLen = Configurable.printHeaderPre
918  postLen = Configurable.printHeaderWidth - \
919  preLen - 12 - len(title) # - len(indentStr)
920  postLen = max(preLen, postLen)
921  return indentStr + '\\%s (End of %s) %s' % (preLen * '-', title,
922  postLen * '-')
923 
924  def __repr__(self):
925  return '{0}({1!r})'.format(self.__class__.__name__, self.name())
926 
927  def __str__(self, indent=0, headerLastIndentUnit=indentUnit):
928  global log # to print some info depending on output level
929  indentStr = indent * Configurable.indentUnit
930  # print header
931  title = self.getPrintTitle()
932  # print line to easily see start-of-configurable
933  if indent > 0:
934  headerIndent = (indent - 1) * \
935  Configurable.indentUnit + headerLastIndentUnit
936  else:
937  headerIndent = ''
938  rep = Configurable._printHeader(headerIndent, title)
939  rep += os.linesep
940  # print own properties
941  props = self.getProperties()
942  defs = self.getDefaultProperties()
943  if not props:
944  rep += indentStr + '|-<no properties>' + os.linesep
945  else:
946  # get property name with
947  nameWidth = 0
948  for p in props.keys():
949  nameWidth = max(nameWidth, len(p))
950  for p, v in props.items():
951  # start with indent and property name
952  prefix = indentStr + '|-%-*s' % (nameWidth, p)
953  # add memory address for debugging (not for defaults)
954  if log.isEnabledFor(logging.DEBUG):
955  if v != Configurable.propertyNoValue:
956  address = ' @%11s' % hex(id(v))
957  else:
958  address = 13 * ' '
959  prefix += address
960  # add value and default
961  default = defs.get(p)
962  if v == Configurable.propertyNoValue:
963  # show default value as value, and no extra 'default'
964  strVal = repr(default)
965  strDef = None
966  else:
967  # convert configurable to handle
968  if hasattr(v, "getGaudiHandle"):
969  vv = v.getGaudiHandle()
970  else:
971  vv = v
972  if isinstance(vv,
973  (GaudiHandle, GaudiHandleArray, DataHandle)):
974  strVal = repr(vv)
975  # the default may not be a GaudiHandle (?)
976  if hasattr(default, "toStringProperty"):
977  strDef = repr(default.toStringProperty())
978  else:
979  strDef = repr(default)
980  if strDef == repr(vv.toStringProperty()):
981  strDef = None
982  else:
983  strVal = repr(vv)
984  strDef = repr(default)
985  # add the value
986  line = prefix + ' = ' + strVal
987  # add default if present
988  if strDef is not None:
989  # put default on new line if too big
990  if len(line) + len(strDef) > Configurable.printHeaderWidth:
991  line += os.linesep + indentStr + '| ' + \
992  (len(prefix) - len(indentStr) - 3) * ' '
993  line += ' (default: %s)' % (strDef, )
994  # add the line to the total string
995  rep += line + os.linesep
996  # print out full private configurables
997 # if isinstance(v,Configurable) and not v.isPublic():
998 
1003 
1004 # print configurables + their properties, or loop over sequence
1005 # for cfg in self.__children:
1006  for cfg in self.getAllChildren():
1007  rep += cfg.__str__(indent + 1, '|=') + os.linesep
1008 
1009  # print line to easily see end-of-configurable. Note: No linesep!
1010  rep += Configurable._printFooter(indentStr, title)
1011  return rep
1012 
1013  def isApplicable(self):
1014  '''
1015  Return True is the instance can be "applied".
1016  Always False for plain Configurable instances
1017  (i.e. not ConfigurableUser).
1018  '''
1019  return False
1020 
1021 
1022 # classes for generic Gaudi component ===========
1023 
1024 
1025 class DummyDescriptor(object):
1026  def __init__(self, name):
1027  self.__name__ = name # conventional
1028 
1029  def __get__(self, obj, type=None):
1030  return getattr(obj, self.__name__)
1031 
1032  def __set__(self, obj, value):
1033  object.__setattr__(obj, self.__name__, value)
1034 
1035 
1037  #__slots__ = { }
1038 
1039  def __init__(self, name=Configurable.DefaultName):
1040  Configurable.__init__(self, name)
1041  self._name = name
1042  self._properties = {}
1043 
1044  def __deepcopy__(self, memo):
1045  return self # algorithms are always shared
1046 
1047  @classmethod
1048  def getGaudiType(cls):
1049  return 'GenericComponent'
1050 
1051  def getDlls(self):
1052  pass
1053 
1054  def getHandle(self):
1055  pass
1056 
1057  def __setattr__(self, name, value):
1058  # filter private (user) variables
1059  if name[0] == '_':
1060  super(ConfigurableGeneric, self).__setattr__(name, value)
1061  return
1062 
1063  # filter configurable types
1064  if isinstance(value, Configurable):
1065  self.__dict__[name] = value
1066  return
1067 
1068  # assume all the rest are properties
1069  if not name in self._properties:
1070  self._properties[name] = PropertyProxy(DummyDescriptor(name))
1071  self._properties[name].__set__(self, value)
1072 
1073  def getJobOptName(self):
1074  return None
1075 
1076 
1077 # base classes for individual Gaudi algorithms/services/algtools ===========
1079  __slots__ = {
1080  '_jobOptName': 0,
1081  'OutputLevel': 0,
1082  'Enable': 1,
1083  'ErrorMax': 1,
1084  'ErrorCount': 0,
1085  'AuditAlgorithms': 0,
1086  'AuditInitialize': 0,
1087  'AuditReinitialize': 0,
1088  'AuditExecute': 0,
1089  'AuditFinalize': 0
1090  }
1091 
1092  def __init__(self, name=Configurable.DefaultName):
1093  super(ConfigurableAlgorithm, self).__init__(name)
1094  name = self.getName()
1095  self._jobOptName = name[name.find('/') + 1:] # strips class
1096 
1097  def __deepcopy__(self, memo):
1098  return self # algorithms are always shared
1099 
1100  def getHandle(self):
1101  return iAlgorithm(self.getJobOptName())
1102 
1103  @classmethod
1104  def getGaudiType(cls):
1105  return 'Algorithm'
1106 
1107  def getJobOptName(self):
1108  return self._jobOptName
1109 
1110  # mimick the ControlFlowLeaf interface
1111  def __and__(self, rhs):
1112  if rhs is CFTrue:
1113  return self
1114  elif rhs is CFFalse:
1115  return CFFalse
1116  return AndNode(self, rhs)
1117 
1118  def __or__(self, rhs):
1119  if rhs is CFFalse:
1120  return self
1121  elif rhs is CFTrue:
1122  return CFTrue
1123  return OrNode(self, rhs)
1124 
1125  def __invert__(self):
1126  return InvertNode(self)
1127 
1128  def __rshift__(self, rhs):
1129  return OrderedNode(self, rhs)
1130 
1131  def visitNode(self, visitor):
1132  visitor.enter(self)
1133  self._visitSubNodes(visitor)
1134  visitor.leave(self)
1135 
1136  def _visitSubNodes(self, visitor):
1137  pass
1138 
1139  def __eq__(self, other):
1140  return (repr(self) == repr(other))
1141 
1142  def __hash__(self):
1143  """Return a unique identifier for this object.
1144 
1145  As we use the `repr` of this object to check for equality, we use it
1146  here to define uniqueness.
1147  """
1148  # The hash of the 1-tuple containing the repr of this object
1149  return hash((repr(self), ))
1150 
1151 
1153  __slots__ = {
1154  'OutputLevel': 0,
1155  'AuditServices': 0,
1156  'AuditInitialize': 0,
1157  'AuditFinalize': 0
1158  }
1159 
1160  def __deepcopy__(self, memo):
1161  return self # services are always shared
1162 
1163  def copyChild(self, child):
1164  return child # full sharing
1165 
1166  def getHandle(self):
1167  return iService(self._name)
1168 
1169  @classmethod
1170  def getGaudiType(cls):
1171  return 'Service'
1172 
1173  def getGaudiHandle(self):
1174  return ServiceHandle(self.toStringProperty())
1175 
1176  def toStringProperty(self):
1177  # called on conversion to a string property for the jocat
1178  return self.getName()
1179 
1180 
1182  __slots__ = {
1183  '_jobOptName': '',
1184  'OutputLevel': 0,
1185  'AuditTools': 0,
1186  'AuditInitialize': 0,
1187  'AuditFinalize': 0
1188  }
1189 
1190  def __init__(self, name=Configurable.DefaultName):
1191  super(ConfigurableAlgTool, self).__init__(name)
1192  if '.' not in self._name:
1193  # Public tools must have ToolSvc as parent
1194  self._name = "ToolSvc." + self._name
1195  name = self.getName()
1196  name = name[name.find('/') + 1:] # strips class, if any
1197  self._jobOptName = name
1198 
1199  def getHandle(self):
1200  # iAlgTool isn't useful, unless one knows for sure that the tool exists
1201  return iProperty(self.getJobOptName())
1202 
1203  @classmethod
1204  def getGaudiType(cls):
1205  return 'AlgTool'
1206 
1207  def getGaudiHandle(self):
1208  if self.isPublic():
1209  return PublicToolHandle(self.toStringProperty())
1210  else:
1211  return PrivateToolHandle(self.toStringProperty())
1212 
1213  def getPrintTitle(self):
1214  if self.isPublic():
1215  pop = 'Public '
1216  else:
1217  pop = 'Private '
1218  return pop + Configurable.getPrintTitle(self)
1219 
1220  def setParent(self, parentName):
1221  # print "ConfigurableAlgTool.setParent(%s@%x,%r)" % (self.getName(),id(self),parentName)
1222  # print "Calling stack:"
1223  # import traceback
1224  # traceback.print_stack()
1225  # propagate parent to AlgTools in children
1226  for c in self.getAllChildren():
1227  if isinstance(c, ConfigurableAlgTool):
1228  c.setParent(parentName)
1229 
1230  # update my own parent
1231  name = self.getName()
1232  name = name[name.rfind('.') + 1:] # Name of the instance
1233  self._jobOptName = self._name = parentName + '.' + name
1234 
1235  def getParent(self):
1236  dot = self._jobOptName.rfind('.')
1237  if dot != -1:
1238  return self._jobOptName[:dot]
1239  else:
1240  return ""
1241 
1242  def hasParent(self, parent):
1243  return self._jobOptName.startswith(parent + '.')
1244 
1245  def getJobOptName(self):
1246  return self._jobOptName
1247 
1248  def isPublic(self):
1249  return self.isInToolSvc()
1250 
1251  def isInToolSvc(self):
1252  return self._jobOptName.startswith('ToolSvc.')
1253 
1254  def toStringProperty(self):
1255  # called on conversion to a string property for the jocat
1256  return self.getFullName()
1257 
1258  def getFullName(self):
1259  # for Tools, the "full name" means "Type/LocalName",
1260  # without the names of the parents
1261  name = self.getName()
1262  # strip off everything before the last '.'
1263  name = name[name.rfind('.') + 1:]
1264  return str(self.getType() + '/' + name)
1265 
1266 
1267 # FIXME: this is just a placeholder, waiting for a real implementation
1268 # It is sufficient to get us going... (and import a PkgConf which
1269 # happens to contain an Auditor...)
1271  __slots__ = {'_jobOptName': 0, 'OutputLevel': 0, 'Enable': 1}
1272 
1273  def __init__(self, name=Configurable.DefaultName):
1274  super(ConfigurableAuditor, self).__init__(name)
1275  name = self.getName()
1276  name = name[name.find('/') + 1:] # strips class, if any
1277  self._jobOptName = name
1278 
1279  def getHandle(self):
1280  # iAlgTool isn't useful, unless one knows for sure that the tool exists
1281  return iProperty(self.getJobOptName())
1282 
1283  @classmethod
1284  def getGaudiType(cls):
1285  return 'Auditor'
1286 
1287  def getJobOptName(self):
1288  return self._jobOptName
1289 
1290  def toStringProperty(self):
1291  # called on conversion to a string property for the jocat
1292  return self.getType() + '/' + self.getName()
1293 
1294 
1296  __slots__ = {
1297  "__users__": [],
1298  "__used_instances__": [],
1299  "_enabled": True,
1300  "_applied": False
1301  }
1302  # list of ConfigurableUser classes this one is going to modify in the
1303  # __apply_configuration__ method.
1304  # The list may contain class objects, strings representing class objects or
1305  # tuples with the class object (or a string) as first element and the instance
1306  # name as second element.
1307  # If the instance name is None or not present, the function _instanceName()
1308  # is used to determine the name of the instance (the default implementation
1309  # returns "<this name>_<other name>".
1310  __used_configurables__ = []
1311  # list of ConfigurableUser classes this one is going to query in the
1312  # __apply_configuration__ method
1313  __queried_configurables__ = []
1314 
1315  def __init__(self, name=Configurable.DefaultName, _enabled=True, **kwargs):
1316  super(ConfigurableUser, self).__init__(name)
1317  for n, v in kwargs.items():
1318  setattr(self, n, v)
1319  self._enabled = _enabled
1320  self.__users__ = []
1321  self._applied = False
1322 
1323  # Needed to retrieve the actual class if the declaration in __used_configurables__
1324  # and __queried_configurables__ is done with strings.
1325  from GaudiKernel.ConfigurableDb import getConfigurable as confDbGetConfigurable
1326 
1327  # Set the list of users of the used configurables
1328  #
1330  for used in self.__used_configurables__:
1331  # By default we want to use the default name of the instances
1332  # for the used configurables
1333  used_name = Configurable.DefaultName
1334  # If the entry in the list is a tuple, we need a named instance
1335  if type(used) is tuple:
1336  used, used_name = used # we re-set used to re-use the code below
1337  if not used_name:
1338  used_name = self._instanceName(used)
1339  # Check is 'used' is a string or not
1340  if type(used) is str:
1341  used_class = confDbGetConfigurable(used)
1342  else:
1343  used_class = used
1344  # Instantiate the configurable that we are going to use
1345  try:
1346  inst = used_class(name=used_name, _enabled=False)
1347  except AttributeError:
1348  # This cover the case where the used configurable is not a
1349  # ConfigurableUser instance, i.e. id doesn't have the attribute
1350  # '_enabled'.
1351  inst = used_class(name=used_name)
1352  self.__addActiveUseOf(inst)
1353  for queried in self.__queried_configurables__:
1354  try:
1355  if type(queried) is str:
1356  queried = confDbGetConfigurable(used)
1357  inst = queried(_enabled=False)
1358  except AttributeError:
1359  inst = queried()
1360  self.__addPassiveUseOf(inst)
1361 
1362  def __addActiveUseOf(self, other):
1363  """
1364  Declare that we are going to modify the Configurable 'other' in our
1365  __apply_configuration__.
1366  """
1367  self.__used_instances__.append(other)
1368  if hasattr(other, "__users__"): # allow usage of plain Configurables
1369  other.__users__.append(self)
1370 
1371  def __addPassiveUseOf(self, other):
1372  """
1373  Declare that we are going to retrieve property values from the
1374  ConfigurableUser 'other' in our __apply_configuration__.
1375  """
1376  if not isinstance(other, ConfigurableUser):
1377  raise Error(
1378  "'%s': Cannot make passive use of '%s', it is not a ConfigurableUser"
1379  % (self.name(), other.name()))
1380  other.__addActiveUseOf(self)
1381 
1382  @classmethod
1383  def getGaudiType(cls):
1384  return 'User'
1385 
1386  def getDlls(self):
1387  return None
1388 
1389  def getHandle(self):
1390  return None
1391 
1392  def __detach_used__(self):
1393  """
1394  Remove this ConfigurableUser instance from the users list of the used
1395  instances.
1396  """
1397  for used in self.__used_instances__:
1398  if hasattr(used,
1399  "__users__"): # allow usage of plain Configurables
1400  used.__users__.remove(self)
1401 
1402  def propagateProperty(self, name, others=None, force=True):
1403  """
1404  Propagate the property 'name' (if set) to other configurables (if possible).
1405  'others' can be:
1406  None:
1407  propagate to all the entries in __used_configurables__
1408  a configurable instance:
1409  propagate only to it
1410  list of configurable instances:
1411  propagate to all of them.
1412 
1413 
1414  The logic is:
1415  - if the local property is set, the other property will be overwritten
1416  - local property not set and other set => keep other
1417  - local property not set and other not set => overwrite the default for
1418  ConfigurableUser instances and set the property for Configurables
1419  """
1420  # transform 'others' to a list of configurable instances
1421  if others is None:
1422  others = self.__used_instances__
1423  elif type(others) not in [list, tuple]:
1424  others = [others]
1425  # these can be computed before the loop
1426  local_is_set = self.isPropertySet(name)
1427  value = self.getProp(name)
1428  # loop over the others that do have 'name' in their slots
1429  for other in [o for o in others if name in o.__slots__]:
1430  # If self property is set, use it
1431  if local_is_set:
1432  if other.isPropertySet(name):
1433  log.warning(
1434  "Property '%(prop)s' is set in both '%(self)s' and '%(other)s', using '%(self)s.%(prop)s'"
1435  % {
1436  "self": self.name(),
1437  "other": other.name(),
1438  "prop": name
1439  })
1440  other.setProp(name, value)
1441  # If not, and other property also not set, propagate the default
1442  elif not other.isPropertySet(name):
1443  if isinstance(other, ConfigurableUser):
1444  otherType = type(other._properties[name].getDefault())
1445  other._properties[name].setDefault(value)
1446  if otherType in [list, dict]:
1447  # Special case for list and dictionaries:
1448  # also set the property to the same value of the default (copy)
1449  other.setProp(name, otherType(value))
1450  else:
1451  other.setProp(name, value)
1452  # If not set and other set, do nothing
1453 
1454  def propagateProperties(self, names=None, others=None, force=True):
1455  """
1456  Call propagateProperty for each property listed in 'names'.
1457  If 'names' is None, all the properties are propagated.
1458  """
1459  if names is None:
1460  # use all the non-private slots
1461  names = [p for p in self.__slots__ if not p.startswith("_")]
1462  for n in names:
1463  self.propagateProperty(n, others, force)
1464 
1466  """
1467  Function to be overridden to convert the high level configuration into a
1468  low level one.
1469  The default implementation calls applyConf, which is the method defined
1470  in some ConfigurableUser implementations.
1471  """
1472  return self.applyConf()
1473 
1474  def applyConf(self):
1475  """
1476  Function to be overridden to convert the high level configuration into a
1477  low level one.
1478  """
1479  pass
1480 
1481  def _instanceName(self, cls):
1482  """
1483  Function used to define the name of the private instance of a given class
1484  name.
1485  This method is used when the __used_configurables_property__ declares the
1486  need of a private used configurable without specifying the name.
1487  """
1488  if type(cls) is str:
1489  clName = cls
1490  else:
1491  clName = cls.__name__
1492  return "%s_%s" % (self.name(), clName)
1493 
1494  def getUsedInstance(self, name):
1495  """
1496  Return the used instance with a given name.
1497  """
1498  for i in self.__used_instances__:
1499  if i.name() == name:
1500  if hasattr(i, "_enabled"):
1501  # ensure that the instances retrieved through the method are
1502  # enabled
1503  i._enabled = True
1504  return i
1505  raise KeyError(name)
1506 
1507  def isApplicable(self):
1508  '''
1509  Return True is the instance can be "applied".
1510  '''
1511  return (not self.__users__) and (not self._applied)
1512 
1513 
1514 # list of callables to be called after all the __apply_configuration__ are called.
1515 postConfigActions = []
1516 
1517 
1519  """
1520  Add a new callable ('function') to the list of post-configuration actions.
1521  If the callable is already in the list, it is moved to the end of the list.
1522  The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1523  """
1524  try:
1525  postConfigActions.remove(function)
1526  except:
1527  pass
1528  postConfigActions.append(function)
1529 
1530 
1532  """
1533  Remove a callable from the list of post-config actions.
1534  The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1535  """
1536  postConfigActions.remove(function)
1537 
1538 
1539 _appliedConfigurableUsers_ = False
1540 
1541 
1543  """
1544  Call the apply method of all the ConfigurableUser instances respecting the
1545  dependencies. First the C.U.s that are not used by anybody, then the used
1546  ones, when they are not used anymore.
1547  """
1548  # Avoid double calls
1549  global _appliedConfigurableUsers_, postConfigActions
1550  if _appliedConfigurableUsers_:
1551  return
1552  _appliedConfigurableUsers_ = True
1553 
1554  def applicableConfUsers():
1555  '''
1556  Generator returning all the configurables that can be applied in the
1557  order in which they can be applied.
1558  '''
1559  # This is tricky...
1560  # We keep on looking for the first configurable that can be applied.
1561  # When we cannot find any, 'next()' raises a StopIteration that is
1562  # propagated outside of the infinite loop and the function, then handled
1563  # correctly from outside (it is the exception that is raised when you
1564  # exit from a generator).
1565  # Checking every time the full list is inefficient, but it is the
1566  # easiest way to fix bug #103803.
1567  # <https://savannah.cern.ch/bugs/?103803>
1568  while True:
1569  try:
1570  yield next(c for c in Configurable.allConfigurables.values()
1571  if c.isApplicable())
1572  except StopIteration:
1573  break
1574 
1575  debugApplyOrder = 'GAUDI_DUBUG_CONF_USER' in os.environ
1576  for c in applicableConfUsers():
1577  if c._enabled:
1578  log.info("applying configuration of %s", c.name())
1579  if debugApplyOrder:
1580  sys.stderr.write('applying %r' % c)
1581  c.__apply_configuration__()
1582  log.info(c)
1583  else:
1584  log.info("skipping configuration of %s", c.name())
1585  c._applied = True # flag the instance as already applied
1586  if hasattr(c, "__detach_used__"):
1587  # tells the used configurables that they are not needed anymore
1588  c.__detach_used__()
1589 
1590  # check for dependency loops
1591  leftConfUsers = [
1592  c for c in Configurable.allConfigurables.values() if
1593  hasattr(c, '__apply_configuration__') and c._enabled and not c._applied
1594  ]
1595  # if an enabled configurable has not been applied, there must be a dependency loop
1596  if leftConfUsers:
1597  raise Error("Detected loop in the ConfigurableUser"
1598  " dependencies: %r" % [c.name() for c in leftConfUsers])
1599  # ensure that all the Handles have been triggered
1600  known = set()
1601  unknown = set(Configurable.allConfigurables)
1602  while unknown:
1603  for k in unknown:
1604  if not known: # do not print during the first iteration
1605  log.debug('new configurable created automatically: %s', k)
1606  # this trigger the instantiation from handles
1607  Configurable.allConfigurables[k].properties()
1608  known.add(k)
1609  unknown -= known
1610  # Call post-config actions
1611  for action in postConfigActions:
1612  action()
1613 
1614 
1616  """
1617  Obsolete (buggy) implementation of applyConfigurableUsers(), kept to provide
1618  backward compatibility for configurations that where relying (implicitly) on
1619  bug #103803, or on a specific (non guaranteed) order of execution.
1620 
1621  @see applyConfigurableUsers()
1622  """
1623  # Avoid double calls
1624  global _appliedConfigurableUsers_, postConfigActions
1625  if _appliedConfigurableUsers_:
1626  return
1627  _appliedConfigurableUsers_ = True
1628 
1629  debugApplyOrder = 'GAUDI_DUBUG_CONF_USER' in os.environ
1630  confUsers = [
1631  c for c in Configurable.allConfigurables.values()
1632  if hasattr(c, "__apply_configuration__")
1633  ]
1634  applied = True # needed to detect dependency loops
1635  while applied and confUsers:
1636  newConfUsers = [] # list of conf users that cannot be applied yet
1637  applied = False
1638  for c in confUsers:
1639  if hasattr(c, "__users__") and c.__users__:
1640  newConfUsers.append(c) # cannot use this one yet
1641  else: # it does not have users or the list is empty
1642  applied = True
1643  # the ConfigurableUser is enabled if it doesn't have an _enabled
1644  # property or its value is True
1645  enabled = (not hasattr(c, "_enabled")) or c._enabled
1646  if enabled:
1647  log.info("applying configuration of %s", c.name())
1648  if debugApplyOrder:
1649  sys.stderr.write('applying %r' % c)
1650  c.__apply_configuration__()
1651  log.info(c)
1652  else:
1653  log.info("skipping configuration of %s", c.name())
1654  if hasattr(c, "__detach_used__"):
1655  # tells the used configurables that they are not needed anymore
1656  c.__detach_used__()
1657  confUsers = newConfUsers # list of C.U.s still to go
1658  if confUsers:
1659  # this means that some C.U.s could not be applied because of a dependency loop
1660  raise Error("Detected loop in the ConfigurableUser "
1661  " dependencies: %r" % [c.name() for c in confUsers])
1662  # ensure that all the Handles have been triggered
1663  known = set()
1664  unknown = set(Configurable.allConfigurables)
1665  while unknown:
1666  for k in unknown:
1667  if not known: # do not print during the first iteration
1668  log.debug('new configurable created automatically: %s', k)
1669  # this trigger the instantiation from handles
1670  Configurable.allConfigurables[k].properties()
1671  known.add(k)
1672  unknown -= known
1673  # Call post-config actions
1674  for action in postConfigActions:
1675  action()
1676 
1677 
1679  """
1680  Function to select all and only the configurables that have to be used in
1681  GaudiPython.AppMgr constructor.
1682  This is needed because in Athena the implementation have to be different (the
1683  configuration is used in a different moment).
1684  """
1685  return sorted(
1686  k for k, v in Configurable.allConfigurables.items()
1687  if v.getGaudiType() != "User") # Exclude ConfigurableUser instances
1688 
1689 
1690 def purge():
1691  """
1692  Clean up all configurations and configurables.
1693  """
1694  for c in Configurable.allConfigurables.values():
1695  c.__class__.configurables.clear()
1696  Configurable.allConfigurables.clear()
1697  # FIXME: (MCl) this is needed because instances of ConfigurableGeneric are not
1698  # migrated to the correct class when this is known.
1699  ConfigurableGeneric.configurables.clear()
1700  from .ProcessJobOptions import _included_files
1701  import os.path
1702  import sys
1703  for file in _included_files:
1704  dirname, basname = os.path.split(file)
1705  basname, ext = os.path.splitext(basname)
1706  if basname in sys.modules:
1707  del sys.modules[basname]
1708  _included_files.clear()
1709 
1710 
1712  def __init__(self):
1713  self.stack = []
1714 
1715  @property
1716  def sequence(self):
1717  return self.stack[-1]
1718 
1719  def enter(self, visitee):
1720  pass
1721 
1722  def _getUniqueName(self, prefix):
1723  from Gaudi.Configuration import allConfigurables
1724  cnt = 0
1725  name = prefix + str(cnt)
1726  while name in allConfigurables:
1727  cnt += 1
1728  name = prefix + str(cnt)
1729  return name
1730 
1731  def _newSeq(self, prefix='seq_', **kwargs):
1732  from Configurables import GaudiSequencer
1733  return GaudiSequencer(self._getUniqueName('seq_'), **kwargs)
1734 
1735  def leave(self, visitee):
1736  stack = self.stack
1737  if visitee in (CFTrue, CFFalse):
1738  stack.append(self._newSeq(Invert=visitee is CFFalse))
1739  elif isinstance(visitee, (ControlFlowLeaf, ConfigurableAlgorithm)):
1740  stack.append(visitee)
1741  elif isinstance(visitee, (OrNode, AndNode, OrderedNode)):
1742  b = stack.pop()
1743  a = stack.pop()
1744  seq = self._newSeq(
1745  Members=[a, b],
1746  ModeOR=isinstance(visitee, OrNode),
1747  ShortCircuit=not isinstance(visitee, OrderedNode),
1748  MeasureTime=True)
1749  stack.append(seq)
1750  elif isinstance(visitee, ignore):
1751  if hasattr(stack[-1], 'IgnoreFilterPassed'):
1752  stack[-1].IgnoreFilterPassed = True
1753  else:
1754  stack.append(
1755  self._newSeq(
1756  Members=[stack.pop()], IgnoreFilterPassed=True))
1757  elif isinstance(visitee, InvertNode):
1758  if hasattr(stack[-1], 'Invert'):
1759  stack[-1].Invert = True
1760  else:
1761  stack.append(self._newSeq(Members=[stack.pop()], Invert=True))
1762 
1763 
1764 def makeSequences(expression):
1765  '''
1766  Convert a control flow expression to nested GaudiSequencers.
1767  '''
1768  if not isinstance(expression, ControlFlowNode):
1769  raise ValueError('ControlFlowNode instance expected, got %s' %
1770  type(expression).__name__)
1771  visitor = CreateSequencesVisitor()
1772  expression.visitNode(visitor)
1773  return visitor.sequence
1774 
1775 
1777  '''
1778  Helper class to use a ControlFlowNode as an algorithm configurable
1779  instance.
1780  '''
1781 
1782  def __new__(cls, name=None, **kwargs):
1783  if name is None:
1784  name = cls.__name__
1785  if name in Configurable.allConfigurables:
1786  instance = Configurable.allConfigurables[name]
1787  assert type(instance) is cls, \
1788  ('trying to reuse {0!r} as name of a {1} instance while it''s '
1789  'already used for an instance of {2}').format(
1790  name,
1791  cls.__name__,
1792  type(instance).__name__)
1793  return instance
1794  else:
1795  instance = super(SuperAlgorithm, cls).__new__(cls)
1796  Configurable.allConfigurables[name] = instance
1797  return instance
1798 
1799  def __init__(self, name=None, **kwargs):
1800  self._name = name or self.getType()
1801  self.graph = self._initGraph()
1802  for key in kwargs:
1803  setattr(self, key, kwargs[key])
1804 
1805  @property
1806  def name(self): # name is a read only property
1807  return self._name
1808 
1809  @classmethod
1810  def getType(cls):
1811  return cls.__name__
1812 
1813  # required to be registered in allConfigurables
1814  def properties(self):
1815  pass
1816 
1817  # required to be registered in allConfigurables
1818  def isApplicable(self):
1819  return False
1820 
1821  # required to be registered in allConfigurables
1822  @classmethod
1823  def getGaudiType(cls):
1824  return 'User'
1825 
1826  def _makeAlg(self, typ, **kwargs):
1827  '''
1828  Instantiate and algorithm of type 'typ' with a name suitable for use
1829  inside a SuperAlgorithm.
1830  '''
1831  name = '{0}_{1}'.format(self.name, kwargs.pop('name', typ.getType()))
1832  return typ(name, **kwargs)
1833 
1834  def _initGraph(self):
1835  raise NotImplementedError()
1836 
1837  def __repr__(self):
1838  return '{0}({1!r})'.format(self.getType(), self.name)
1839 
1840  def _visitSubNodes(self, visitor):
1841  if self.graph:
1842  self.graph.visitNode(visitor)
1843 
1844  def __setattr__(self, name, value):
1845  super(SuperAlgorithm, self).__setattr__(name, value)
1846  if name in ('_name', 'graph'):
1847  # do not propagate internal data members
1848  return
1849 
1850  class PropSetter(object):
1851  def enter(self, node):
1852  try:
1853  setattr(node, name, value)
1854  except (ValueError, AttributeError):
1855  # ignore type and name mismatch
1856  pass
1857 
1858  def leave(self, node):
1859  pass
1860 
1861  self._visitSubNodes(PropSetter())
GaudiKernel.Configurable.ConfigurableGeneric
Definition: Configurable.py:1036
GaudiKernel.Configurable.SuperAlgorithm.__repr__
def __repr__(self)
Definition: Configurable.py:1837
GaudiKernel.Configurable.Configurable.getSequence
def getSequence(self)
Definition: Configurable.py:601
GaudiKernel.Configurable.ConfigurableUser
Definition: Configurable.py:1295
GaudiKernel.Configurable.ConfigurableGeneric.getDlls
def getDlls(self)
Definition: Configurable.py:1051
GaudiKernel.Configurable.Configurable.children
def children(self)
Definition: Configurable.py:553
GaudiKernel.Configurable.Configurable.getDefaultProperties
def getDefaultProperties(cls)
Definition: Configurable.py:692
GaudiKernel.Configurable.ConfigurableAlgTool.getJobOptName
def getJobOptName(self)
Definition: Configurable.py:1245
GaudiKernel.Configurable.ConfigurableService.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1170
GaudiKernel.Configurable.ConfigurableUser.__used_instances__
__used_instances__
Definition: Configurable.py:1329
MSG::hex
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:281
GaudiKernel.Configurable.SuperAlgorithm.graph
graph
Definition: Configurable.py:1801
GaudiKernel.Configurable.ConfigurableAlgorithm.__init__
def __init__(self, name=Configurable.DefaultName)
Definition: Configurable.py:1092
GaudiKernel.Configurable.ConfigurableAlgTool.getFullName
def getFullName(self)
Definition: Configurable.py:1258
GaudiKernel.Configurable.ConfigurableUser._instanceName
def _instanceName(self, cls)
Definition: Configurable.py:1481
GaudiKernel.Configurable.Configurable.__setupDefaults
def __setupDefaults(self)
Definition: Configurable.py:900
GaudiKernel.Configurable.ConfigurableGeneric.__deepcopy__
def __deepcopy__(self, memo)
Definition: Configurable.py:1044
GaudiKernel.Configurable.ConfigurableUser.applyConf
def applyConf(self)
Definition: Configurable.py:1474
GaudiKernel.Configurable.Configurable.isPropertySet
def isPropertySet(self, name)
Definition: Configurable.py:742
GaudiKernel.Configurable.Configurable.getParent
def getParent(self)
Definition: Configurable.py:521
GaudiConfig.ControlFlow.OrderedNode
Definition: ControlFlow.py:107
GaudiKernel.Configurable.Configurable._initok
_initok
Definition: Configurable.py:348
GaudiConfig.ControlFlow
Definition: ControlFlow.py:1
GaudiKernel.Configurable.ConfigurableAlgorithm.__or__
def __or__(self, rhs)
Definition: Configurable.py:1118
GaudiKernel.Configurable.SuperAlgorithm
Definition: Configurable.py:1776
GaudiKernel.Configurable.Configurable.setProp
def setProp(self, name, value)
Definition: Configurable.py:737
GaudiKernel.Configurable.ConfigurableService.getHandle
def getHandle(self)
Definition: Configurable.py:1166
GaudiKernel.Configurable.ConfigurableGeneric.getHandle
def getHandle(self)
Definition: Configurable.py:1054
GaudiKernel.Configurable.CreateSequencesVisitor
Definition: Configurable.py:1711
GaudiKernel.Configurable.SuperAlgorithm.__setattr__
def __setattr__(self, name, value)
Definition: Configurable.py:1844
GaudiKernel.Configurable.CreateSequencesVisitor.leave
def leave(self, visitee)
Definition: Configurable.py:1735
GaudiKernel.Configurable.Configurable.hasParent
def hasParent(self, parent)
Definition: Configurable.py:524
GaudiKernel.Configurable.DummyDescriptor.__name__
__name__
Definition: Configurable.py:1027
GaudiKernel.Configurable.ConfigurableUser.propagateProperty
def propagateProperty(self, name, others=None, force=True)
Definition: Configurable.py:1402
GaudiKernel.Configurable.ConfigurableUser.propagateProperties
def propagateProperties(self, names=None, others=None, force=True)
Definition: Configurable.py:1454
GaudiKernel.Configurable.Configurable.__iter__
def __iter__(self)
Definition: Configurable.py:393
GaudiKernel.Configurable.ConfigurableGeneric.getJobOptName
def getJobOptName(self)
Definition: Configurable.py:1073
GaudiKernel.Configurable.ConfigurableAlgTool.isPublic
def isPublic(self)
Definition: Configurable.py:1248
GaudiKernel.Configurable.Configurable.getProp
def getProp(self, name)
Definition: Configurable.py:729
GaudiKernel.Configurable.ConfigurableAlgorithm._jobOptName
_jobOptName
Definition: Configurable.py:1095
GaudiKernel.Configurable.ConfigurableAlgTool.__init__
def __init__(self, name=Configurable.DefaultName)
Definition: Configurable.py:1190
GaudiKernel.Configurable.ConfigurableUser.getHandle
def getHandle(self)
Definition: Configurable.py:1389
GaudiKernel.Configurable.Configurable._isInSetDefaults
def _isInSetDefaults(self)
Definition: Configurable.py:868
GaudiKernel.Configurable.Configurable.__bool__
def __bool__(self)
Definition: Configurable.py:499
GaudiKernel.Configurable.Configurable.configurableServices
dictionary configurableServices
Definition: Configurable.py:146
GaudiKernel.Configurable.Configurable.getAllChildren
def getAllChildren(self)
Definition: Configurable.py:562
GaudiKernel.Configurable.Configurable.getTools
def getTools(self)
Definition: Configurable.py:550
GaudiKernel.Configurable.SuperAlgorithm.name
def name(self)
Definition: Configurable.py:1806
GaudiKernel.Configurable.Configurable.__iadd__
def __iadd__(self, configs, descr=None)
Definition: Configurable.py:413
GaudiKernel.Configurable.Configurable.allConfigurables
dictionary allConfigurables
Definition: Configurable.py:144
GaudiKernel.Configurable.Configurable.jobOptName
def jobOptName(self)
Definition: Configurable.py:773
GaudiKernel.Configurable.ConfigurableAlgTool._jobOptName
_jobOptName
Definition: Configurable.py:1197
GaudiKernel.Configurable.Error
Definition: Configurable.py:70
GaudiKernel.Configurable.DummyDescriptor.__init__
def __init__(self, name)
Definition: Configurable.py:1026
GaudiKernel.ConfigurableMeta
Definition: ConfigurableMeta.py:1
GaudiKernel.Configurable.ConfigurableUser.__init__
def __init__(self, name=Configurable.DefaultName, _enabled=True, **kwargs)
Definition: Configurable.py:1315
GaudiKernel.ConfigurableMeta.ConfigurableMeta.properties
dictionary properties
Definition: ConfigurableMeta.py:48
GaudiKernel.Configurable.Configurable._name
_name
Definition: Configurable.py:338
GaudiKernel.Configurable.PropertyReference.__str__
def __str__(self)
Definition: Configurable.py:84
GaudiKernel.Configurable.ConfigurableAlgorithm.__deepcopy__
def __deepcopy__(self, memo)
Definition: Configurable.py:1097
GaudiKernel.Configurable.Configurable.__repr__
def __repr__(self)
Definition: Configurable.py:924
GaudiKernel.Configurable.Configurable._configurationLocked
bool _configurationLocked
Definition: Configurable.py:150
GaudiKernel.Configurable.Configurable.isPublic
def isPublic(self)
Definition: Configurable.py:769
max
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:225
GaudiKernel.Configurable.Configurable.removeAll
def removeAll(self)
Definition: Configurable.py:511
GaudiKernel.Configurable.Configurable.getFullName
def getFullName(self)
Definition: Configurable.py:779
GaudiKernel.Configurable.ConfigurableAlgorithm._visitSubNodes
def _visitSubNodes(self, visitor)
Definition: Configurable.py:1136
GaudiKernel.Configurable.DummyDescriptor.__set__
def __set__(self, obj, value)
Definition: Configurable.py:1032
GaudiKernel.Configurable.ConfigurableAlgTool.hasParent
def hasParent(self, parent)
Definition: Configurable.py:1242
GaudiKernel.Constants
Definition: Constants.py:1
GaudiKernel.Configurable.ConfigurableAlgorithm.__invert__
def __invert__(self)
Definition: Configurable.py:1125
GaudiKernel.Configurable.ConfigurableUser.getDlls
def getDlls(self)
Definition: Configurable.py:1386
GaudiKernel.Configurable.Configurable.__setupDlls
def __setupDlls(self)
Definition: Configurable.py:888
GaudiKernel.Configurable.ConfigurableUser.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1383
GaudiConfig.ControlFlow.OrNode
Definition: ControlFlow.py:141
GaudiKernel.Configurable.Configurable.name
def name(self)
Definition: Configurable.py:763
GaudiPython.GaudiAlgs.iAlgorithm
iAlgorithm
Definition: GaudiAlgs.py:65
GaudiKernel.DataHandle
Definition: DataHandle.py:1
GaudiKernel.Configurable.Configurable.getType
def getType(cls)
Definition: Configurable.py:757
GaudiKernel.Configurable.ConfigurableAlgorithm.getHandle
def getHandle(self)
Definition: Configurable.py:1100
GaudiKernel.Configurable.Configurable._unpickling
_unpickling
Definition: Configurable.py:354
GaudiKernel.Configurable.PropertyReference.__resolve__
def __resolve__(self)
Definition: Configurable.py:87
GaudiKernel.Configurable.SuperAlgorithm.__init__
def __init__(self, name=None, **kwargs)
Definition: Configurable.py:1799
GaudiKernel.Configurable.Configurable._printFooter
def _printFooter(indentStr, title)
Definition: Configurable.py:916
GaudiKernel.Configurable.Configurable.getProperties
def getProperties(self)
Definition: Configurable.py:641
GaudiKernel.Configurable.CreateSequencesVisitor.enter
def enter(self, visitee)
Definition: Configurable.py:1719
GaudiKernel.Configurable.ConfigurableAuditor.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1284
GaudiKernel.Configurable.ConfigurableAlgTool.getParent
def getParent(self)
Definition: Configurable.py:1235
GaudiKernel.Configurable.applyConfigurableUsers_old
def applyConfigurableUsers_old()
Definition: Configurable.py:1615
GaudiKernel.Configurable.Configurable.getPropertiesWithDescription
def getPropertiesWithDescription(self)
Definition: Configurable.py:651
GaudiKernel.Configurable.CreateSequencesVisitor.sequence
def sequence(self)
Definition: Configurable.py:1716
GaudiKernel.Configurable.SuperAlgorithm.isApplicable
def isApplicable(self)
Definition: Configurable.py:1818
GaudiKernel.Configurable.makeSequences
def makeSequences(expression)
Definition: Configurable.py:1764
GaudiKernel.Configurable.Configurable.__tools
__tools
Definition: Configurable.py:333
GaudiKernel.Configurable.Configurable.getName
def getName(self)
Definition: Configurable.py:760
GaudiKernel.Configurable.ConfigurableAlgTool.toStringProperty
def toStringProperty(self)
Definition: Configurable.py:1254
GaudiKernel.Configurable.Configurable.__getnewargs__
def __getnewargs__(self)
Definition: Configurable.py:370
GaudiKernel.Configurable.DummyDescriptor.__get__
def __get__(self, obj, type=None)
Definition: Configurable.py:1029
GaudiKernel.Configurable.appendPostConfigAction
def appendPostConfigAction(function)
Definition: Configurable.py:1518
bug_34121.tool
tool
Definition: bug_34121.py:17
GaudiKernel.Configurable.ConfigurableUser._applied
_applied
Definition: Configurable.py:1321
Gaudi::Functional::details::get
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
Definition: FunctionalDetails.h:391
GaudiKernel.Configurable.Configurable.clone
def clone(self, name=None, **kwargs)
Definition: Configurable.py:798
GaudiKernel.Configurable.ConfigurableAlgTool.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1204
GaudiKernel.Configurable.Configurable.copyChild
def copyChild(self, child)
Definition: Configurable.py:515
GaudiKernel.Configurable.ConfigurableAuditor._jobOptName
_jobOptName
Definition: Configurable.py:1277
GaudiKernel.Configurable.ConfigurableService.getGaudiHandle
def getGaudiHandle(self)
Definition: Configurable.py:1173
GaudiKernel.Configurable.Configurable.DefaultName
Definition: Configurable.py:126
GaudiKernel.ConfigurableMeta.ConfigurableMeta.configurables
configurables
Definition: ConfigurableMeta.py:45
GaudiKernel.Configurable.SuperAlgorithm.__new__
def __new__(cls, name=None, **kwargs)
Definition: Configurable.py:1782
GaudiKernel.Configurable.ConfigurableUser.__used_configurables__
list __used_configurables__
Definition: Configurable.py:1310
GaudiKernel.PropertyProxy.PropertyProxy
Definition: PropertyProxy.py:80
Gaudi.Configuration
Definition: Configuration.py:1
GaudiKernel.Configurable.Configurable._setupok
_setupok
Definition: Configurable.py:351
GaudiKernel.Configurable.ConfigurableAlgorithm
Definition: Configurable.py:1078
GaudiKernel.Configurable.DummyDescriptor
Definition: Configurable.py:1025
GaudiKernel.Configurable.Configurable.getChildren
def getChildren(self)
Definition: Configurable.py:547
GaudiKernel.Configurable.Configurable.setDefaults
def setDefaults(cls, handle)
Definition: Configurable.py:795
GaudiKernel.Configurable.PropertyReference.__init__
def __init__(self, propname)
Definition: Configurable.py:81
GaudiKernel.Configurable.Configurable.__len__
def __len__(self)
Definition: Configurable.py:390
GaudiKernel.Configurable.Configurable.__init__
def __init__(self, name=DefaultName)
Definition: Configurable.py:298
GaudiKernel.Configurable.ConfigurableAuditor.toStringProperty
def toStringProperty(self)
Definition: Configurable.py:1290
GaudiKernel.Configurable.ConfigurableGeneric.__init__
def __init__(self, name=Configurable.DefaultName)
Definition: Configurable.py:1039
GaudiKernel.Configurable.Configurable.getTitleName
def getTitleName(self)
Definition: Configurable.py:789
GaudiKernel.Configurable.CreateSequencesVisitor._newSeq
def _newSeq(self, prefix='seq_', **kwargs)
Definition: Configurable.py:1731
GaudiKernel.Configurable.ConfigurableService.copyChild
def copyChild(self, child)
Definition: Configurable.py:1163
GaudiKernel.Configurable.SuperAlgorithm._initGraph
def _initGraph(self)
Definition: Configurable.py:1834
GaudiKernel.Configurable.ConfigurableUser.isApplicable
def isApplicable(self)
Definition: Configurable.py:1507
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
GaudiKernel.Configurable.SuperAlgorithm._makeAlg
def _makeAlg(self, typ, **kwargs)
Definition: Configurable.py:1826
GaudiKernel.Configurable.Configurable.splitName
def splitName(self)
Definition: Configurable.py:829
GaudiKernel.GaudiHandles.ServiceHandle
Definition: GaudiHandles.py:107
GaudiKernel.Configurable.Configurable.__delattr__
def __delattr__(self, attr)
Definition: Configurable.py:474
GaudiKernel.Configurable.ConfigurableAlgTool.isInToolSvc
def isInToolSvc(self)
Definition: Configurable.py:1251
GaudiKernel.PropertyProxy
Definition: PropertyProxy.py:1
GaudiKernel.Configurable.ConfigurableAuditor.__init__
def __init__(self, name=Configurable.DefaultName)
Definition: Configurable.py:1273
GaudiKernel.Configurable.Configurable.getPrintTitle
def getPrintTitle(self)
Definition: Configurable.py:786
GaudiKernel.Configurable.isApplicable
def isApplicable(self)
rep += v.__str__( indent + 1 ) + os.linesep elif isinstance(v,GaudiHandleArray): for vi in v: if isin...
Definition: Configurable.py:1013
GaudiKernel.Configurable.PropertyReference.name
name
Definition: Configurable.py:82
GaudiKernel.Configurable.ConfigurableAlgorithm.__eq__
def __eq__(self, other)
Definition: Configurable.py:1139
GaudiKernel.Configurable.ConfigurableUser._enabled
_enabled
Definition: Configurable.py:1319
GaudiKernel.Configurable.ConfigurableGeneric.__setattr__
def __setattr__(self, name, value)
Definition: Configurable.py:1057
GaudiKernel.Configurable.Configurable.setup
def setup(self)
Definition: Configurable.py:607
gaudiComponentHelp.properties
properties
Definition: gaudiComponentHelp.py:62
GaudiKernel.Configurable.PropertyReference.getFullName
def getFullName(self)
Definition: Configurable.py:101
GaudiKernel.Configurable.Configurable.getValuedProperties
def getValuedProperties(self)
Definition: Configurable.py:661
GaudiKernel.Configurable.ConfigurableAlgorithm.visitNode
def visitNode(self, visitor)
Definition: Configurable.py:1131
GaudiKernel.Configurable.ConfigurableUser.__addActiveUseOf
def __addActiveUseOf(self, other)
Definition: Configurable.py:1362
GaudiConfig.ControlFlow.ControlFlowNode.visitNode
def visitNode(self, visitor)
Definition: ControlFlow.py:44
GaudiKernel.Configurable.ConfigurableAuditor.getJobOptName
def getJobOptName(self)
Definition: Configurable.py:1287
GaudiKernel.Configurable.Configurable._printHeader
def _printHeader(indentStr, title)
Definition: Configurable.py:908
GaudiKernel.Configurable.ConfigurableAlgTool.getGaudiHandle
def getGaudiHandle(self)
Definition: Configurable.py:1207
GaudiConfig.ControlFlow.InvertNode
Definition: ControlFlow.py:158
gaudirun.type
type
Definition: gaudirun.py:154
GaudiKernel.Configurable.ConfigurableGeneric.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1048
GaudiKernel.Configurable.removePostConfigAction
def removePostConfigAction(function)
Definition: Configurable.py:1531
GaudiSequencer
Definition: GaudiSequencer.h:38
GaudiKernel.Configurable.ConfigurableService.toStringProperty
def toStringProperty(self)
Definition: Configurable.py:1176
GaudiKernel.Configurable.SuperAlgorithm._visitSubNodes
def _visitSubNodes(self, visitor)
Definition: Configurable.py:1840
GaudiKernel.Configurable.ConfigurableUser.getUsedInstance
def getUsedInstance(self, name)
Definition: Configurable.py:1494
GaudiKernel.Configurable.Configurable.__children
__children
Definition: Configurable.py:332
GaudiKernel.Configurable.getNeededConfigurables
def getNeededConfigurables()
Definition: Configurable.py:1678
GaudiKernel.Configurable.Configurable.addTool
def addTool(self, tool, name=None)
Definition: Configurable.py:845
GaudiKernel.Configurable.ConfigurableAlgorithm.getJobOptName
def getJobOptName(self)
Definition: Configurable.py:1107
GaudiKernel.Configurable.Configurable.__getattr__
def __getattr__(self, attr)
Definition: Configurable.py:446
GaudiKernel.Configurable.Configurable.__getstate__
def __getstate__(self)
Definition: Configurable.py:357
GaudiKernel.Configurable.ConfigurableAlgTool.getHandle
def getHandle(self)
Definition: Configurable.py:1199
GaudiKernel.Configurable.ConfigurableUser.__apply_configuration__
def __apply_configuration__(self)
Definition: Configurable.py:1465
GaudiKernel.Configurable.SuperAlgorithm._name
_name
Definition: Configurable.py:1800
GaudiKernel.Configurable.Configurable._inSetDefaults
_inSetDefaults
Definition: Configurable.py:345
GaudiKernel.Configurable.ConfigurableUser.__users__
__users__
Definition: Configurable.py:1320
GaudiKernel.Configurable.ConfigurableService
Definition: Configurable.py:1152
GaudiConfig.ControlFlow.ControlFlowNode
Definition: ControlFlow.py:19
GaudiKernel.Configurable.Configurable.getJobOptName
def getJobOptName(self)
Definition: Configurable.py:766
GaudiKernel.Configurable.ConfigurableAlgTool.setParent
def setParent(self, parentName)
Definition: Configurable.py:1220
GaudiKernel.Configurable.Configurable.copyChildAndSetParent
def copyChildAndSetParent(self, cfg, parent)
Definition: Configurable.py:527
GaudiKernel.Configurable.ConfigurableUser.__queried_configurables__
list __queried_configurables__
Definition: Configurable.py:1313
GaudiKernel.Configurable.ConfigurableAlgorithm.__rshift__
def __rshift__(self, rhs)
Definition: Configurable.py:1128
GaudiKernel.GaudiHandles.PrivateToolHandle
Definition: GaudiHandles.py:98
GaudiKernel.Configurable.Configurable.__setattr__
def __setattr__(self, name, value)
Definition: Configurable.py:462
GaudiKernel.Configurable.ConfigurableUser.__detach_used__
def __detach_used__(self)
Definition: Configurable.py:1392
GaudiKernel.Configurable.ConfigurableAlgorithm.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1104
GaudiKernel.Configurable.Configurable.__setstate__
def __setstate__(self, dict)
Definition: Configurable.py:373
GaudiKernel.Configurable.Configurable.__new__
def __new__(cls, *args, **kwargs)
Definition: Configurable.py:152
GaudiKernel.Configurable.Configurable.__deepcopy__
def __deepcopy__(self, memo)
Definition: Configurable.py:397
GaudiKernel.Configurable.SuperAlgorithm.getType
def getType(cls)
Definition: Configurable.py:1810
GaudiKernel.Configurable.SuperAlgorithm.properties
def properties(self)
Definition: Configurable.py:1814
GaudiKernel.ConfigurableMeta.ConfigurableMeta._properties
_properties
Definition: ConfigurableMeta.py:74
GaudiKernel.Configurable.Configurable.getFullJobOptName
def getFullJobOptName(self)
Definition: Configurable.py:782
GaudiKernel.Configurable.ConfigurableAlgorithm.__hash__
def __hash__(self)
Definition: Configurable.py:1142
GaudiKernel.Configurable.CreateSequencesVisitor._getUniqueName
def _getUniqueName(self, prefix)
Definition: Configurable.py:1722
GaudiKernel.Configurable.ConfigurableAuditor
Definition: Configurable.py:1270
gaudirun.action
action
Definition: gaudirun.py:148
GaudiKernel.Configurable.SuperAlgorithm.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1823
GaudiKernel.ConfigurableMeta.ConfigurableMeta
Definition: ConfigurableMeta.py:25
GaudiKernel.Configurable.purge
def purge()
Definition: Configurable.py:1690
GaudiKernel.Configurable.ConfigurableAlgorithm.__and__
def __and__(self, rhs)
Definition: Configurable.py:1111
GaudiKernel.Configurable.ConfigurableGeneric._properties
_properties
Definition: Configurable.py:1042
GaudiKernel.Configurable.Configurable
Definition: Configurable.py:119
GaudiKernel.Configurable.CreateSequencesVisitor.__init__
def __init__(self)
Definition: Configurable.py:1712
GaudiKernel.GaudiHandles
Definition: GaudiHandles.py:1
GaudiKernel.Configurable.ConfigurableAlgTool
Definition: Configurable.py:1181
GaudiKernel.Configurable.ConfigurableUser.__addPassiveUseOf
def __addPassiveUseOf(self, other)
Definition: Configurable.py:1371
GaudiKernel.Configurable.ConfigurableService.__deepcopy__
def __deepcopy__(self, memo)
Definition: Configurable.py:1160
GaudiKernel.Configurable.Configurable.__slots__
tuple __slots__
Definition: Configurable.py:134
GaudiKernel.Configurable.Configurable.__str__
def __str__(self, indent=0, headerLastIndentUnit=indentUnit)
Definition: Configurable.py:927
GaudiKernel.ConfigurableDb
Definition: ConfigurableDb.py:1
GaudiKernel.Configurable.ConfigurableAlgTool.getPrintTitle
def getPrintTitle(self)
Definition: Configurable.py:1213
GaudiKernel.Configurable.Configurable.getDefaultProperty
def getDefaultProperty(cls, name)
Definition: Configurable.py:708
GaudiKernel.Configurable.Configurable.setParent
def setParent(self, parentName)
Definition: Configurable.py:518
GaudiKernel.Configurable.expandvars
def expandvars(data)
Definition: Configurable.py:47
GaudiKernel.Configurable.ConfigurableAuditor.getHandle
def getHandle(self)
Definition: Configurable.py:1279
GaudiKernel.GaudiHandles.PublicToolHandle
Definition: GaudiHandles.py:89
GaudiKernel.Configurable.Configurable.remove
def remove(self, items)
Definition: Configurable.py:505
GaudiKernel.Configurable.Configurable.__setupServices
def __setupServices(self)
Definition: Configurable.py:871
StringKeyEx.keys
list keys
Definition: StringKeyEx.py:67
GaudiKernel.Configurable.CreateSequencesVisitor.stack
stack
Definition: Configurable.py:1713
GaudiPython.Pythonizations.items
items
Definition: Pythonizations.py:526
GaudiKernel.Configurable.applyConfigurableUsers
def applyConfigurableUsers()
Definition: Configurable.py:1542
GaudiConfig.ControlFlow.AndNode
Definition: ControlFlow.py:124