| The Gaudi Framework v32r1 (f65d50dc)

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