7 __version__ =
'$Revision: 1.11 $'
8 __author__ =
'Sebastien Binet <binet@cern.ch>'
10 __all__ = [
"CfgItemList",
"CfgKeyStore",
11 "loadKeyStoreFromPoolFile",
19 _allowedTriggerKeys = re.compile(
r"(?P<KlassName>.*?)#HLTAutoKey.*\*$" )
26 msg = logging.getLogger(
'CfgItemList' )
29 """ Python class to hold the so-called output ItemList of a given JobOption.
30 This class allows to fine tune what will be written out in a POOL file, as
31 it has a switch to prevent people from wildcarding containers (ie: no
32 outStream.ItemList += [ 'SomeContainer#*' ] allowed).
33 This check can however be disabled on a per CfgItemList instance basis:
35 >>> mycfg = CfgItemList( allowWildcard = True )
38 A typical use would look like:
40 esdList = CfgItemList( 'esd' )
41 # fetch an already existing list (using the singleton-ness of Configurables)
42 esdList += CfgItemList( 'InDetEsd' )
43 # create a list on the fly and add it to the ESD list
44 esdList += CfgItemList(
46 items = [ 'CaloCellContainer#CaloCells',
47 'CaloClusterContainer#Clusters' ]
49 # special case of trigger
50 esdList += CfgItemList(
52 items = [ 'JetCollection#HLT_AutoKey#*' ],
55 # fill the stream's output list
56 from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
57 StreamESD = AthenaPoolOutputStream('StreamESD')
58 StreamESD.ItemList = esdList()
61 instances = weakref.WeakValueDictionary()
62 __slots__ = {
'_name' :
'CfgItemList',
66 '_allowWildCard' :
False }
71 if len(p) == 0: kw[
'name'] = cls.
__slots__[
'_name']
72 else: kw[
'name'] = p[0]
74 kw[
'_name'] = kw[
'name']
81 obj = object.__new__(cls)
87 if k.startswith(
'__'):
continue
88 if k
in kw.keys(): v = kw[k]
100 super( CfgItemList, self ).
__init__()
106 if 'items' in kwargs:
107 items = kwargs[
'items']
109 if 'allowWildCard' in kwargs:
112 msg.verbose(
"create [%s] items = %r allowWildCard = %s",
115 if len(items) > 0: self.add( items )
120 d = {
'_name' : self._name,
128 for k,v
in dct.items():
133 return (self.name(),)
138 newconf._children = copy.deepcopy(self.
_children)
139 newconf._items = copy.deepcopy(self.
_items)
152 if not type(itemLists)
in (list,tuple):
153 itemLists = ( itemLists, )
155 for cfg
in itemLists:
157 if not isinstance( cfg, CfgItemList ):
158 raise TypeError(
"'%r' is not a CfgItemList" % cfg )
162 if c._name == cfg._name:
163 msg.error(
'%s already exists !! (in %s)',
164 cfg._name, self._name )
165 msg.error(
'attempt to add a duplicate ... dupe ignored' )
170 setattr(self, cfg._name, cfg)
171 except AttributeError:
178 if attr
in CfgItemList.__slots__:
179 return super(CfgItemList, self).__getattribute__(attr)
181 for c
in self.children():
185 return super(CfgItemList, self).__getattribute__(attr)
191 if k
in CfgItemList.__slots__:
193 for c
in self.children():
195 return setattr(c, k, v)
198 except AttributeError:
202 for c
in self._children:
204 self._children.
remove( c )
215 for i
in self._items:
221 self.removeItem( item )
222 for c
in self._children:
223 c.removeAllItems( item )
230 self._children = [ e
for e
in self._children
if e
not in items ]
233 self.remove( self._children )
240 msg.debug(
'setup of Output ItemList: %s', self._name )
241 if msg.isEnabledFor( logging.VERBOSE ):
242 msg.verbose(
'layout of sequence: %s\n%s', self._name,
str(self) )
244 for child
in self.children():
249 for item
in self._items:
250 cppType = item.split(
"#")[0]
251 sgKey = item.replace( cppType+
"#",
'' )
253 if sgKey
not in props[cppType]:
254 props[cppType].
append( sgKey )
256 props[cppType] = [ sgKey ]
260 if i.count(
"*" ) <= 0:
261 if i
not in self._items:
263 elif (self._allowWildCard
or _allowedTriggerKeys.match(i)):
264 if i
not in self._items:
267 msg.warning(
"Attempt to add an invalid element: '%s'", i )
268 msg.warning(
" ==> Ignoring invalid element: '%s'", i )
272 if isinstance(arg, (list, tuple) ):
275 elif isinstance(arg, str):
277 elif isinstance(arg, dict):
280 if not isinstance(new[k], (list,tuple)):
282 self.add( [
'%s#%s' % (k,e)
for e
in new[k] ] )
284 msg.error(
"Could not add '%r' of type '%s'", arg,
type(arg) )
288 from fnmatch
import fnmatchcase
as match
289 for i
in self._items:
294 for c
in self._children:
295 if c.has_item( item ):
300 self._allowWildCard = allow
304 items =
set( [ i
for i
in self._items
if i.startswith(key+
"#") ] )
306 items =
set( self._items )
307 for c
in self._children:
309 for i
in c.list( key ):
311 except AttributeError
as err:
314 items = [ i
for i
in items ]
322 props = self.getProperties()
323 for c
in self._children:
324 props.update( c.dict() )
325 for k
in props.keys():
326 props[k] =
sorted(props[k])
330 return '<%s/%s at %s>' % (self.__class__.__name__,self._name,
334 headerLastIndentUnit=Configurable.indentUnit ):
336 indentStr = indent * Configurable.indentUnit
338 title =
"%s/%s" % ( self.__class__.__name__, self._name )
342 headerIndent = (indent-1)*Configurable.indentUnit \
343 + headerLastIndentUnit
347 rep = Configurable._printHeader( headerIndent, title )
351 props = self.getProperties()
354 rep += indentStr +
'| ' + os.linesep
358 for p
in props.keys():
359 nameWidth=
max(nameWidth,len(p))
360 for p, v
in props.items():
362 prefix = indentStr +
'|-%-*s' % (nameWidth,p)
364 if msg.isEnabledFor( logging.DEBUG ):
365 address =
' @%11s' % hex(
id(v))
370 line = prefix +
' = ' + strVal
372 rep += line + os.linesep
374 for cfg
in self.allChildren():
375 rep += cfg.__str__( indent + 1,
'|=' ) + os.linesep
378 rep += Configurable._printFooter( indentStr, title )
385 return self._children
389 for c
in self._children:
391 children += c.allChildren()
400 """Python class to manage different stores of keys, their content and
401 origin ('StreamESD', 'StreamAOD', ...)
403 instances = weakref.WeakValueDictionary()
405 '_name' :
'KeyStore',
407 '__weakref__' :
None,
408 'Labels' : [
"inputBackNav",
"inputFile",
"transient",
409 "streamRDO",
"streamESD",
"streamAOD",
"streamTAG",
418 if len(p) == 0: kw[
'name'] = cls.
__slots__[
'_name']
419 else: kw[
'name'] = p[0]
426 obj = object.__new__(cls)
429 kw[
'_name'] = kw[
'name']
433 if k
in (
'__weakref__',
'Labels'):
continue
434 if k
in kw.keys(): v = kw[k]
446 super( CfgKeyStore, self ).
__init__()
451 for label
in [ l
for l
in self.
keys()
if l !=
'transient' ]:
453 if label.count(
'stream') > 0: self[
'transient'] += item
461 d = {
'_name' : self._name,
463 'Labels' : CfgKeyStore.__slots__[
'Labels'],
468 for k,v
in dct.items():
473 return (self.
name(),)
477 if k
not in CfgKeyStore.__slots__[
'Labels']:
478 raise KeyError(
"key [%s] is not an allowed one: %s" %
479 ( k, CfgKeyStore.__slots__[
'Labels'] ))
481 if k.count(
'stream') > 0:
482 root = getattr( root, self._name+
'_transient' )
484 return getattr( root, self._name+
"_"+k )
485 except AttributeError
as err:
486 raise KeyError(
str(err))
489 if k
not in CfgKeyStore.__slots__[
'Labels']:
490 raise KeyError(
"key [%s] is not an allowed one: %s" %
491 ( k, CfgKeyStore.__slots__[
'Labels'] ))
493 if k.count(
'stream') > 0:
494 root = getattr( root, self._name+
'_transient' )
495 return setattr( root, self._name+
"_"+k, v )
499 if k
in CfgKeyStore.__slots__[
'Labels']:
501 if k
in CfgKeyStore.__slots__:
502 return super(CfgKeyStore, self).__getattribute__(k)
503 return super(CfgKeyStore, self).__getattribute__(k)
504 except KeyError
as err:
505 raise AttributeError(
str(err))
508 if k
in CfgKeyStore.__slots__[
'Labels']:
516 return CfgKeyStore.__slots__[
'Labels']
522 return [ self[l]
for l
in self.
keys() ]
525 return zip( self.keys(), self.values() )
528 if label
is not None:
536 return '<%s/%s at %s>' % (self.__class__.__name__,self._name,
540 headerLastIndentUnit=Configurable.indentUnit ):
543 indentStr = indent * Configurable.indentUnit
545 title =
"%s/%s" % ( self.__class__.__name__, self._name )
549 headerIndent = (indent-1)*Configurable.indentUnit \
550 + headerLastIndentUnit
554 rep = Configurable._printHeader( headerIndent, title )
557 rep += self._items.
__str__( indent + 1,
'|=' ) + os.linesep
559 rep += Configurable._printFooter( indentStr, title )
565 from pprint
import pprint
566 from datetime
import datetime
567 from io
import StringIO
569 pprint( item.dict(), stream = buf )
571 out =
open( os.path.expanduser(os.path.expandvars(fileName)),
'w' )
572 out.writelines( os.linesep.join( [
573 "## autogenerated at [%s]" %
str(datetime.now()),
575 "## method filling an item-list with some data",
576 "def _fill( item ):",
577 " item.add(",
"%s )" % buf.getvalue(),
583 except Exception
as e:
584 print (
"Py:Error :",e)
588 def read( self, fileName, label ):
591 from AthenaCommon.Include
import FindFile,optionsPath
593 name = osp.expanduser( osp.expandvars( fileName ) )
594 name =
FindFile( name, optionsPath, os.R_OK )
596 name =
FindFile( osp.basename(fileName), optionsPath, os.R_OK )
597 uri =
open( name,
'r' )
598 mod = imp.load_source( uri.name[:-3], uri.name, uri )
601 fill = inspect.getmembers(
602 mod,
lambda o: inspect.isfunction(o)
and (o.__name__ ==
'_fill')
611 items_type='eventdata'):
613 Helper function to create a CfgKeyStore of name `keyStore` from the
614 content of the POOL file `pool_file` (a python string).
615 The content of the POOL file will be stored into the label `label`
617 if not isinstance(keyStore, str):
618 raise ValueError(
"argument 0 (`keyStore`) should be string")
619 if not isinstance(pool_file, str):
620 raise ValueError(
"argument 1 (`pool_file`) should be string")
621 if not isinstance(label, str):
622 raise ValueError(
"argument 2 (`label`) should be string")
624 from PyUtils.PoolFile
import extract_items
625 item_list = [
'%s#%s'%(name,key)
628 items_type=items_type)
631 ks_label = getattr(ks, label)
633 ks_label.add (item_list)
639 Helper function to print the 'diff' of two KeyStores `ref` and `chk` into
640 the file-like object `ofile` (default value: sys.stdout)
641 `ref` and `chk` can either be :
642 - @c KeyStore.CfgKeyStore instances or,
643 - strings being the names of the _already created_
644 @c KeyStore.CfgKeyStore instances
645 @param `labels` the list of labels (default: CfgKeyStore.Labels) to compare
646 between the two CfgKeyStores
648 if isinstance (ref, str):
649 if ref
not in CfgKeyStore.instances:
651 (
'invalid `ref` argument (non existing instance name [%s])'%\
653 ref = CfgKeyStore.instances [ref]
655 if isinstance (chk, str):
656 if chk
not in CfgKeyStore.instances:
658 (
'invalid `chk` argument (non existing instance name [%s])'%\
660 chk = CfgKeyStore.instances [chk]
663 labels = CfgKeyStore.__slots__[
'Labels']
664 elif isinstance (labels, str):
665 labels = [l.strip()
for l
in labels.split()
if l.strip() !=
'']
672 if ref
is chk
or ref == chk:
676 ref_content = sorted (ref[label].
list())
677 chk_content = sorted (chk[label].
list())
678 if len(ref_content) != len(chk_content):
679 diff.append (
"- len(ref[%s]) == %i" % (label,len(ref_content)))
680 diff.append (
"+ len(chk[%s]) == %i" % (label,len(chk_content)))
681 for r
in ref_content:
682 if r
not in chk_content:
683 diff.append (
"- ref[%s] : %s" % (label, r))
684 for c
in chk_content:
685 if c
not in ref_content:
686 diff.append (
"+ chk[%s] : %s" % (label, c))
691 map (ofile.writelines, (d
for d
in os.linesep.join(diff)))