The Gaudi Framework  v36r1 (3e2fb5a8)
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  (parent, child) = self._jobOptName.rsplit('.', 1)
1253  return parent == 'ToolSvc'
1254 
1255  def toStringProperty(self):
1256  # called on conversion to a string property for the jocat
1257  return self.getFullName()
1258 
1259  def getFullName(self):
1260  # for Tools, the "full name" means "Type/LocalName",
1261  # without the names of the parents
1262  name = self.getName()
1263  # strip off everything before the last '.'
1264  name = name[name.rfind('.') + 1:]
1265  return str(self.getType() + '/' + name)
1266 
1267 
1268 # FIXME: this is just a placeholder, waiting for a real implementation
1269 # It is sufficient to get us going... (and import a PkgConf which
1270 # happens to contain an Auditor...)
1272  __slots__ = {'_jobOptName': 0, 'OutputLevel': 0, 'Enable': 1}
1273 
1274  def __init__(self, name=Configurable.DefaultName):
1275  super(ConfigurableAuditor, self).__init__(name)
1276  name = self.getName()
1277  name = name[name.find('/') + 1:] # strips class, if any
1278  self._jobOptName = name
1279 
1280  def getHandle(self):
1281  # iAlgTool isn't useful, unless one knows for sure that the tool exists
1282  return iProperty(self.getJobOptName())
1283 
1284  @classmethod
1285  def getGaudiType(cls):
1286  return 'Auditor'
1287 
1288  def getJobOptName(self):
1289  return self._jobOptName
1290 
1291  def toStringProperty(self):
1292  # called on conversion to a string property for the jocat
1293  return self.getType() + '/' + self.getName()
1294 
1295 
1297  __slots__ = {
1298  "__users__": [],
1299  "__used_instances__": [],
1300  "_enabled": True,
1301  "_applied": False
1302  }
1303  # list of ConfigurableUser classes this one is going to modify in the
1304  # __apply_configuration__ method.
1305  # The list may contain class objects, strings representing class objects or
1306  # tuples with the class object (or a string) as first element and the instance
1307  # name as second element.
1308  # If the instance name is None or not present, the function _instanceName()
1309  # is used to determine the name of the instance (the default implementation
1310  # returns "<this name>_<other name>".
1311  __used_configurables__ = []
1312  # list of ConfigurableUser classes this one is going to query in the
1313  # __apply_configuration__ method
1314  __queried_configurables__ = []
1315 
1316  def __init__(self, name=Configurable.DefaultName, _enabled=True, **kwargs):
1317  super(ConfigurableUser, self).__init__(name)
1318  for n, v in kwargs.items():
1319  setattr(self, n, v)
1320  self._enabled = _enabled
1321  self.__users__ = []
1322  self._applied = False
1323 
1324  # Needed to retrieve the actual class if the declaration in __used_configurables__
1325  # and __queried_configurables__ is done with strings.
1326  from GaudiKernel.ConfigurableDb import getConfigurable as confDbGetConfigurable
1327 
1328  # Set the list of users of the used configurables
1329  #
1331  for used in self.__used_configurables__:
1332  # By default we want to use the default name of the instances
1333  # for the used configurables
1334  used_name = Configurable.DefaultName
1335  # If the entry in the list is a tuple, we need a named instance
1336  if type(used) is tuple:
1337  used, used_name = used # we re-set used to re-use the code below
1338  if not used_name:
1339  used_name = self._instanceName(used)
1340  # Check is 'used' is a string or not
1341  if type(used) is str:
1342  used_class = confDbGetConfigurable(used)
1343  else:
1344  used_class = used
1345  # Instantiate the configurable that we are going to use
1346  try:
1347  inst = used_class(name=used_name, _enabled=False)
1348  except AttributeError:
1349  # This cover the case where the used configurable is not a
1350  # ConfigurableUser instance, i.e. id doesn't have the attribute
1351  # '_enabled'.
1352  inst = used_class(name=used_name)
1353  self.__addActiveUseOf(inst)
1354  for queried in self.__queried_configurables__:
1355  try:
1356  if type(queried) is str:
1357  queried = confDbGetConfigurable(used)
1358  inst = queried(_enabled=False)
1359  except AttributeError:
1360  inst = queried()
1361  self.__addPassiveUseOf(inst)
1362 
1363  def __addActiveUseOf(self, other):
1364  """
1365  Declare that we are going to modify the Configurable 'other' in our
1366  __apply_configuration__.
1367  """
1368  self.__used_instances__.append(other)
1369  if hasattr(other, "__users__"): # allow usage of plain Configurables
1370  other.__users__.append(self)
1371 
1372  def __addPassiveUseOf(self, other):
1373  """
1374  Declare that we are going to retrieve property values from the
1375  ConfigurableUser 'other' in our __apply_configuration__.
1376  """
1377  if not isinstance(other, ConfigurableUser):
1378  raise Error(
1379  "'%s': Cannot make passive use of '%s', it is not a ConfigurableUser"
1380  % (self.name(), other.name()))
1381  other.__addActiveUseOf(self)
1382 
1383  @classmethod
1384  def getGaudiType(cls):
1385  return 'User'
1386 
1387  def getDlls(self):
1388  return None
1389 
1390  def getHandle(self):
1391  return None
1392 
1393  def __detach_used__(self):
1394  """
1395  Remove this ConfigurableUser instance from the users list of the used
1396  instances.
1397  """
1398  for used in self.__used_instances__:
1399  if hasattr(used,
1400  "__users__"): # allow usage of plain Configurables
1401  used.__users__.remove(self)
1402 
1403  def propagateProperty(self, name, others=None, force=True):
1404  """
1405  Propagate the property 'name' (if set) to other configurables (if possible).
1406  'others' can be:
1407  None:
1408  propagate to all the entries in __used_configurables__
1409  a configurable instance:
1410  propagate only to it
1411  list of configurable instances:
1412  propagate to all of them.
1413 
1414 
1415  The logic is:
1416  - if the local property is set, the other property will be overwritten
1417  - local property not set and other set => keep other
1418  - local property not set and other not set => overwrite the default for
1419  ConfigurableUser instances and set the property for Configurables
1420  """
1421  # transform 'others' to a list of configurable instances
1422  if others is None:
1423  others = self.__used_instances__
1424  elif type(others) not in [list, tuple]:
1425  others = [others]
1426  # these can be computed before the loop
1427  local_is_set = self.isPropertySet(name)
1428  value = self.getProp(name)
1429  # loop over the others that do have 'name' in their slots
1430  for other in [o for o in others if name in o.__slots__]:
1431  # If self property is set, use it
1432  if local_is_set:
1433  if other.isPropertySet(name):
1434  log.warning(
1435  "Property '%(prop)s' is set in both '%(self)s' and '%(other)s', using '%(self)s.%(prop)s'"
1436  % {
1437  "self": self.name(),
1438  "other": other.name(),
1439  "prop": name
1440  })
1441  other.setProp(name, value)
1442  # If not, and other property also not set, propagate the default
1443  elif not other.isPropertySet(name):
1444  if isinstance(other, ConfigurableUser):
1445  otherType = type(other._properties[name].getDefault())
1446  other._properties[name].setDefault(value)
1447  if otherType in [list, dict]:
1448  # Special case for list and dictionaries:
1449  # also set the property to the same value of the default (copy)
1450  other.setProp(name, otherType(value))
1451  else:
1452  other.setProp(name, value)
1453  # If not set and other set, do nothing
1454 
1455  def propagateProperties(self, names=None, others=None, force=True):
1456  """
1457  Call propagateProperty for each property listed in 'names'.
1458  If 'names' is None, all the properties are propagated.
1459  """
1460  if names is None:
1461  # use all the non-private slots
1462  names = [p for p in self.__slots__ if not p.startswith("_")]
1463  for n in names:
1464  self.propagateProperty(n, others, force)
1465 
1467  """
1468  Function to be overridden to convert the high level configuration into a
1469  low level one.
1470  The default implementation calls applyConf, which is the method defined
1471  in some ConfigurableUser implementations.
1472  """
1473  return self.applyConf()
1474 
1475  def applyConf(self):
1476  """
1477  Function to be overridden to convert the high level configuration into a
1478  low level one.
1479  """
1480  pass
1481 
1482  def _instanceName(self, cls):
1483  """
1484  Function used to define the name of the private instance of a given class
1485  name.
1486  This method is used when the __used_configurables_property__ declares the
1487  need of a private used configurable without specifying the name.
1488  """
1489  if type(cls) is str:
1490  clName = cls
1491  else:
1492  clName = cls.__name__
1493  return "%s_%s" % (self.name(), clName)
1494 
1495  def getUsedInstance(self, name):
1496  """
1497  Return the used instance with a given name.
1498  """
1499  for i in self.__used_instances__:
1500  if i.name() == name:
1501  if hasattr(i, "_enabled"):
1502  # ensure that the instances retrieved through the method are
1503  # enabled
1504  i._enabled = True
1505  return i
1506  raise KeyError(name)
1507 
1508  def isApplicable(self):
1509  '''
1510  Return True is the instance can be "applied".
1511  '''
1512  return (not self.__users__) and (not self._applied)
1513 
1514 
1515 # list of callables to be called after all the __apply_configuration__ are called.
1516 postConfigActions = []
1517 
1518 
1520  """
1521  Add a new callable ('function') to the list of post-configuration actions.
1522  If the callable is already in the list, it is moved to the end of the list.
1523  The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1524  """
1525  try:
1526  postConfigActions.remove(function)
1527  except:
1528  pass
1529  postConfigActions.append(function)
1530 
1531 
1533  """
1534  Remove a callable from the list of post-config actions.
1535  The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1536  """
1537  postConfigActions.remove(function)
1538 
1539 
1540 _appliedConfigurableUsers_ = False
1541 
1542 
1544  """
1545  Call the apply method of all the ConfigurableUser instances respecting the
1546  dependencies. First the C.U.s that are not used by anybody, then the used
1547  ones, when they are not used anymore.
1548  """
1549  # Avoid double calls
1550  global _appliedConfigurableUsers_, postConfigActions
1551  if _appliedConfigurableUsers_:
1552  return
1553  _appliedConfigurableUsers_ = True
1554 
1555  def applicableConfUsers():
1556  '''
1557  Generator returning all the configurables that can be applied in the
1558  order in which they can be applied.
1559  '''
1560  # This is tricky...
1561  # We keep on looking for the first configurable that can be applied.
1562  # When we cannot find any, 'next()' raises a StopIteration that is
1563  # propagated outside of the infinite loop and the function, then handled
1564  # correctly from outside (it is the exception that is raised when you
1565  # exit from a generator).
1566  # Checking every time the full list is inefficient, but it is the
1567  # easiest way to fix bug #103803.
1568  # <https://savannah.cern.ch/bugs/?103803>
1569  while True:
1570  try:
1571  yield next(c for c in Configurable.allConfigurables.values()
1572  if c.isApplicable())
1573  except StopIteration:
1574  break
1575 
1576  debugApplyOrder = 'GAUDI_DUBUG_CONF_USER' in os.environ
1577  for c in applicableConfUsers():
1578  if c._enabled:
1579  log.info("applying configuration of %s", c.name())
1580  if debugApplyOrder:
1581  sys.stderr.write('applying %r' % c)
1582  c.__apply_configuration__()
1583  log.info(c)
1584  else:
1585  log.info("skipping configuration of %s", c.name())
1586  c._applied = True # flag the instance as already applied
1587  if hasattr(c, "__detach_used__"):
1588  # tells the used configurables that they are not needed anymore
1589  c.__detach_used__()
1590 
1591  # check for dependency loops
1592  leftConfUsers = [
1593  c for c in Configurable.allConfigurables.values() if
1594  hasattr(c, '__apply_configuration__') and c._enabled and not c._applied
1595  ]
1596  # if an enabled configurable has not been applied, there must be a dependency loop
1597  if leftConfUsers:
1598  raise Error("Detected loop in the ConfigurableUser"
1599  " dependencies: %r" % [c.name() for c in leftConfUsers])
1600  # ensure that all the Handles have been triggered
1601  known = set()
1602  unknown = set(Configurable.allConfigurables)
1603  while unknown:
1604  for k in unknown:
1605  if not known: # do not print during the first iteration
1606  log.debug('new configurable created automatically: %s', k)
1607  # this trigger the instantiation from handles
1608  Configurable.allConfigurables[k].properties()
1609  known.add(k)
1610  unknown -= known
1611  # Call post-config actions
1612  for action in postConfigActions:
1613  action()
1614 
1615 
1617  """
1618  Obsolete (buggy) implementation of applyConfigurableUsers(), kept to provide
1619  backward compatibility for configurations that where relying (implicitly) on
1620  bug #103803, or on a specific (non guaranteed) order of execution.
1621 
1622  @see applyConfigurableUsers()
1623  """
1624  # Avoid double calls
1625  global _appliedConfigurableUsers_, postConfigActions
1626  if _appliedConfigurableUsers_:
1627  return
1628  _appliedConfigurableUsers_ = True
1629 
1630  debugApplyOrder = 'GAUDI_DUBUG_CONF_USER' in os.environ
1631  confUsers = [
1632  c for c in Configurable.allConfigurables.values()
1633  if hasattr(c, "__apply_configuration__")
1634  ]
1635  applied = True # needed to detect dependency loops
1636  while applied and confUsers:
1637  newConfUsers = [] # list of conf users that cannot be applied yet
1638  applied = False
1639  for c in confUsers:
1640  if hasattr(c, "__users__") and c.__users__:
1641  newConfUsers.append(c) # cannot use this one yet
1642  else: # it does not have users or the list is empty
1643  applied = True
1644  # the ConfigurableUser is enabled if it doesn't have an _enabled
1645  # property or its value is True
1646  enabled = (not hasattr(c, "_enabled")) or c._enabled
1647  if enabled:
1648  log.info("applying configuration of %s", c.name())
1649  if debugApplyOrder:
1650  sys.stderr.write('applying %r' % c)
1651  c.__apply_configuration__()
1652  log.info(c)
1653  else:
1654  log.info("skipping configuration of %s", c.name())
1655  if hasattr(c, "__detach_used__"):
1656  # tells the used configurables that they are not needed anymore
1657  c.__detach_used__()
1658  confUsers = newConfUsers # list of C.U.s still to go
1659  if confUsers:
1660  # this means that some C.U.s could not be applied because of a dependency loop
1661  raise Error("Detected loop in the ConfigurableUser "
1662  " dependencies: %r" % [c.name() for c in confUsers])
1663  # ensure that all the Handles have been triggered
1664  known = set()
1665  unknown = set(Configurable.allConfigurables)
1666  while unknown:
1667  for k in unknown:
1668  if not known: # do not print during the first iteration
1669  log.debug('new configurable created automatically: %s', k)
1670  # this trigger the instantiation from handles
1671  Configurable.allConfigurables[k].properties()
1672  known.add(k)
1673  unknown -= known
1674  # Call post-config actions
1675  for action in postConfigActions:
1676  action()
1677 
1678 
1680  """
1681  Function to select all and only the configurables that have to be used in
1682  GaudiPython.AppMgr constructor.
1683  This is needed because in Athena the implementation have to be different (the
1684  configuration is used in a different moment).
1685  """
1686  return sorted(
1687  k for k, v in Configurable.allConfigurables.items()
1688  if v.getGaudiType() != "User") # Exclude ConfigurableUser instances
1689 
1690 
1691 def purge():
1692  """
1693  Clean up all configurations and configurables.
1694  """
1695  for c in Configurable.allConfigurables.values():
1696  c.__class__.configurables.clear()
1697  Configurable.allConfigurables.clear()
1698  # FIXME: (MCl) this is needed because instances of ConfigurableGeneric are not
1699  # migrated to the correct class when this is known.
1700  ConfigurableGeneric.configurables.clear()
1701  from .ProcessJobOptions import _included_files
1702  import os.path
1703  import sys
1704  for file in _included_files:
1705  dirname, basname = os.path.split(file)
1706  basname, ext = os.path.splitext(basname)
1707  if basname in sys.modules:
1708  del sys.modules[basname]
1709  _included_files.clear()
1710 
1711 
1713  def __init__(self):
1714  self.stack = []
1715 
1716  @property
1717  def sequence(self):
1718  return self.stack[-1]
1719 
1720  def enter(self, visitee):
1721  pass
1722 
1723  def _getUniqueName(self, prefix):
1724  from Gaudi.Configuration import allConfigurables
1725  cnt = 0
1726  name = prefix + str(cnt)
1727  while name in allConfigurables:
1728  cnt += 1
1729  name = prefix + str(cnt)
1730  return name
1731 
1732  def _newSeq(self, prefix='seq_', **kwargs):
1733  from Configurables import GaudiSequencer
1734  return GaudiSequencer(self._getUniqueName('seq_'), **kwargs)
1735 
1736  def leave(self, visitee):
1737  stack = self.stack
1738  if visitee in (CFTrue, CFFalse):
1739  stack.append(self._newSeq(Invert=visitee is CFFalse))
1740  elif isinstance(visitee, (ControlFlowLeaf, ConfigurableAlgorithm)):
1741  stack.append(visitee)
1742  elif isinstance(visitee, (OrNode, AndNode, OrderedNode)):
1743  b = stack.pop()
1744  a = stack.pop()
1745  seq = self._newSeq(
1746  Members=[a, b],
1747  ModeOR=isinstance(visitee, OrNode),
1748  ShortCircuit=not isinstance(visitee, OrderedNode),
1749  MeasureTime=True)
1750  stack.append(seq)
1751  elif isinstance(visitee, ignore):
1752  if hasattr(stack[-1], 'IgnoreFilterPassed'):
1753  stack[-1].IgnoreFilterPassed = True
1754  else:
1755  stack.append(
1756  self._newSeq(
1757  Members=[stack.pop()], IgnoreFilterPassed=True))
1758  elif isinstance(visitee, InvertNode):
1759  if hasattr(stack[-1], 'Invert'):
1760  stack[-1].Invert = True
1761  else:
1762  stack.append(self._newSeq(Members=[stack.pop()], Invert=True))
1763 
1764 
1765 def makeSequences(expression):
1766  '''
1767  Convert a control flow expression to nested GaudiSequencers.
1768  '''
1769  if not isinstance(expression, ControlFlowNode):
1770  raise ValueError('ControlFlowNode instance expected, got %s' %
1771  type(expression).__name__)
1772  visitor = CreateSequencesVisitor()
1773  expression.visitNode(visitor)
1774  return visitor.sequence
1775 
1776 
1778  '''
1779  Helper class to use a ControlFlowNode as an algorithm configurable
1780  instance.
1781  '''
1782 
1783  def __new__(cls, name=None, **kwargs):
1784  if name is None:
1785  name = cls.__name__
1786  if name in Configurable.allConfigurables:
1787  instance = Configurable.allConfigurables[name]
1788  assert type(instance) is cls, \
1789  ('trying to reuse {0!r} as name of a {1} instance while it''s '
1790  'already used for an instance of {2}').format(
1791  name,
1792  cls.__name__,
1793  type(instance).__name__)
1794  return instance
1795  else:
1796  instance = super(SuperAlgorithm, cls).__new__(cls)
1797  Configurable.allConfigurables[name] = instance
1798  return instance
1799 
1800  def __init__(self, name=None, **kwargs):
1801  self._name = name or self.getType()
1802  self.graph = self._initGraph()
1803  for key in kwargs:
1804  setattr(self, key, kwargs[key])
1805 
1806  @property
1807  def name(self): # name is a read only property
1808  return self._name
1809 
1810  @classmethod
1811  def getType(cls):
1812  return cls.__name__
1813 
1814  # required to be registered in allConfigurables
1815  def properties(self):
1816  pass
1817 
1818  # required to be registered in allConfigurables
1819  def isApplicable(self):
1820  return False
1821 
1822  # required to be registered in allConfigurables
1823  @classmethod
1824  def getGaudiType(cls):
1825  return 'User'
1826 
1827  def _makeAlg(self, typ, **kwargs):
1828  '''
1829  Instantiate and algorithm of type 'typ' with a name suitable for use
1830  inside a SuperAlgorithm.
1831  '''
1832  name = '{0}_{1}'.format(self.name, kwargs.pop('name', typ.getType()))
1833  return typ(name, **kwargs)
1834 
1835  def _initGraph(self):
1836  raise NotImplementedError()
1837 
1838  def __repr__(self):
1839  return '{0}({1!r})'.format(self.getType(), self.name)
1840 
1841  def _visitSubNodes(self, visitor):
1842  if self.graph:
1843  self.graph.visitNode(visitor)
1844 
1845  def __setattr__(self, name, value):
1846  super(SuperAlgorithm, self).__setattr__(name, value)
1847  if name in ('_name', 'graph'):
1848  # do not propagate internal data members
1849  return
1850 
1851  class PropSetter(object):
1852  def enter(self, node):
1853  try:
1854  setattr(node, name, value)
1855  except (ValueError, AttributeError):
1856  # ignore type and name mismatch
1857  pass
1858 
1859  def leave(self, node):
1860  pass
1861 
1862  self._visitSubNodes(PropSetter())
GaudiKernel.Configurable.ConfigurableGeneric
Definition: Configurable.py:1036
GaudiKernel.Configurable.SuperAlgorithm.__repr__
def __repr__(self)
Definition: Configurable.py:1838
GaudiKernel.Configurable.Configurable.getSequence
def getSequence(self)
Definition: Configurable.py:601
GaudiKernel.Configurable.ConfigurableUser
Definition: Configurable.py:1296
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:1330
MSG::hex
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:282
GaudiKernel.Configurable.SuperAlgorithm.graph
graph
Definition: Configurable.py:1802
GaudiKernel.Configurable.ConfigurableAlgorithm.__init__
def __init__(self, name=Configurable.DefaultName)
Definition: Configurable.py:1092
GaudiKernel.Configurable.ConfigurableAlgTool.getFullName
def getFullName(self)
Definition: Configurable.py:1259
GaudiKernel.Configurable.ConfigurableUser._instanceName
def _instanceName(self, cls)
Definition: Configurable.py:1482
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:1475
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:1777
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:1712
GaudiKernel.Configurable.SuperAlgorithm.__setattr__
def __setattr__(self, name, value)
Definition: Configurable.py:1845
GaudiKernel.Configurable.CreateSequencesVisitor.leave
def leave(self, visitee)
Definition: Configurable.py:1736
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:1403
GaudiKernel.Configurable.ConfigurableUser.propagateProperties
def propagateProperties(self, names=None, others=None, force=True)
Definition: Configurable.py:1455
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:1390
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:1807
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:1316
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:1387
GaudiKernel.Configurable.Configurable.__setupDlls
def __setupDlls(self)
Definition: Configurable.py:888
GaudiKernel.Configurable.ConfigurableUser.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1384
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:1800
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:1720
GaudiKernel.Configurable.ConfigurableAuditor.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1285
GaudiKernel.Configurable.ConfigurableAlgTool.getParent
def getParent(self)
Definition: Configurable.py:1235
GaudiKernel.Configurable.applyConfigurableUsers_old
def applyConfigurableUsers_old()
Definition: Configurable.py:1616
GaudiKernel.Configurable.Configurable.getPropertiesWithDescription
def getPropertiesWithDescription(self)
Definition: Configurable.py:651
GaudiKernel.Configurable.CreateSequencesVisitor.sequence
def sequence(self)
Definition: Configurable.py:1717
GaudiKernel.Configurable.SuperAlgorithm.isApplicable
def isApplicable(self)
Definition: Configurable.py:1819
GaudiKernel.Configurable.makeSequences
def makeSequences(expression)
Definition: Configurable.py:1765
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:1255
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:1519
bug_34121.tool
tool
Definition: bug_34121.py:17
GaudiKernel.Configurable.ConfigurableUser._applied
_applied
Definition: Configurable.py:1322
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:1278
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:1783
GaudiKernel.Configurable.ConfigurableUser.__used_configurables__
list __used_configurables__
Definition: Configurable.py:1311
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:1291
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:1732
GaudiKernel.Configurable.ConfigurableService.copyChild
def copyChild(self, child)
Definition: Configurable.py:1163
GaudiKernel.Configurable.SuperAlgorithm._initGraph
def _initGraph(self)
Definition: Configurable.py:1835
GaudiKernel.Configurable.ConfigurableUser.isApplicable
def isApplicable(self)
Definition: Configurable.py:1508
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:1827
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:1274
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:1320
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:1363
GaudiConfig.ControlFlow.ControlFlowNode.visitNode
def visitNode(self, visitor)
Definition: ControlFlow.py:44
GaudiKernel.Configurable.ConfigurableAuditor.getJobOptName
def getJobOptName(self)
Definition: Configurable.py:1288
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:1532
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:1841
GaudiKernel.Configurable.ConfigurableUser.getUsedInstance
def getUsedInstance(self, name)
Definition: Configurable.py:1495
GaudiKernel.Configurable.Configurable.__children
__children
Definition: Configurable.py:332
GaudiKernel.Configurable.getNeededConfigurables
def getNeededConfigurables()
Definition: Configurable.py:1679
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:1466
GaudiKernel.Configurable.SuperAlgorithm._name
_name
Definition: Configurable.py:1801
GaudiKernel.Configurable.Configurable._inSetDefaults
_inSetDefaults
Definition: Configurable.py:345
GaudiKernel.Configurable.ConfigurableUser.__users__
__users__
Definition: Configurable.py:1321
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:1314
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:1393
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:1811
GaudiKernel.Configurable.SuperAlgorithm.properties
def properties(self)
Definition: Configurable.py:1815
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:1723
GaudiKernel.Configurable.ConfigurableAuditor
Definition: Configurable.py:1271
gaudirun.action
action
Definition: gaudirun.py:148
GaudiKernel.Configurable.SuperAlgorithm.getGaudiType
def getGaudiType(cls)
Definition: Configurable.py:1824
GaudiKernel.ConfigurableMeta.ConfigurableMeta
Definition: ConfigurableMeta.py:25
GaudiKernel.Configurable.purge
def purge()
Definition: Configurable.py:1691
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:1713
GaudiKernel.GaudiHandles
Definition: GaudiHandles.py:1
GaudiKernel.Configurable.ConfigurableAlgTool
Definition: Configurable.py:1181
GaudiKernel.Configurable.ConfigurableUser.__addPassiveUseOf
def __addPassiveUseOf(self, other)
Definition: Configurable.py:1372
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:1280
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:1714
GaudiPython.Pythonizations.items
items
Definition: Pythonizations.py:526
GaudiKernel.Configurable.applyConfigurableUsers
def applyConfigurableUsers()
Definition: Configurable.py:1543
GaudiConfig.ControlFlow.AndNode
Definition: ControlFlow.py:124