| The Gaudi Framework v28r2-patches (bc4ad17a)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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