Helper for making LOD functions to evaluate flags.
Numerous parts of the D3PD configuration use arbitrary global flags
to control which blocks are included. This is bad because there
can be interference when multiple tuples are configured in the
same job.
Better is to use the level-of-detail mechanism to do this,
passing in flags as extra arguments to the D3PDObject.
This helper is to ease this conversion, while still allowing
backwards compatibility with flag-based configuration.
flagTestLOD will return a level-of-detail function that evaluates
the provided expression string EXP. This will be evaluated
in an environment that includes names for all flags in the flags
class(es) FLAGS, merged with the value of the hookargs.
The requested level of detail is also available as `reqlev'.
Thus, if you have something like:
myobj = make_SGDataVector_D3PDObject ('mycont', 'mykey', 'my_', 'myob',
allow_args = ['myLevel'])
myobj.defineBlock (flagTestLOD('myLevel>2', myFlags),
'myblock', filler_tool)
then myblock will be included in the tuple if the property
myFlags.myLevel() is greater than two. However, this can be overridden
by passing an argument to the D3PDObject:
alg += myobj (level, myLevel=4)
Explicit inclusion / exclusion also overrides this determination.
Flags are evaluated at the point where flagTestLOD is called.
If HOOK is supplied, then it is called if the LOD test passes.
It is passed as arguments two dictionaries: the block filler tool
arguments and the hook arguments.
Examples:
>>> from AthenaCommon.JobProperties import JobPropertyContainer, JobProperty
>>> f1=JobPropertyContainer ('f1')
>>> f2=JobPropertyContainer ('f2')
>>> class flag1(JobProperty):
... statusOn = True
... allowedTypes=['bool']
... StoredValue = True
>>> class flag2(JobProperty):
... statusOn = True
... allowedTypes=['bool']
... StoredValue = False
>>> f1.add_JobProperty(flag1)
>>> f2.add_JobProperty(flag2)
>>> lod = flagTestLOD ('flag1', f1)
>>> lod(2, {}, {})
True
>>> lod(2, {}, {'flag1': False})
False
>>> lod(-999, {}, {})
False
>>> lod(999, {}, {'flag1': False})
True
>>> lod = flagTestLOD ('flag2 or reqlev>4', [f1,f2])
>>> lod(2, {}, {})
False
>>> lod(10, {}, {})
True
>>> def hook(*args):
... print(args)
>>> lod = flagTestLOD ('flag2 or reqlev>4', [f1,f2], hook)
>>> lod(2, {}, {})
False
>>> lod(10, {'a':1}, {'b':2})
({'a': 1}, {'b': 2})
True
Definition at line 37 of file flagTestLOD.py.
38 """Helper for making LOD functions to evaluate flags.
40 Numerous parts of the D3PD configuration use arbitrary global flags
41 to control which blocks are included. This is bad because there
42 can be interference when multiple tuples are configured in the
45 Better is to use the level-of-detail mechanism to do this,
46 passing in flags as extra arguments to the D3PDObject.
48 This helper is to ease this conversion, while still allowing
49 backwards compatibility with flag-based configuration.
51 flagTestLOD will return a level-of-detail function that evaluates
52 the provided expression string EXP. This will be evaluated
53 in an environment that includes names for all flags in the flags
54 class(es) FLAGS, merged with the value of the hookargs.
55 The requested level of detail is also available as `reqlev'.
56 Thus, if you have something like:
58 myobj = make_SGDataVector_D3PDObject ('mycont', 'mykey', 'my_', 'myob',
59 allow_args = ['myLevel'])
60 myobj.defineBlock (flagTestLOD('myLevel>2', myFlags),
61 'myblock', filler_tool)
63 then myblock will be included in the tuple if the property
64 myFlags.myLevel() is greater than two. However, this can be overridden
65 by passing an argument to the D3PDObject:
67 alg += myobj (level, myLevel=4)
69 Explicit inclusion / exclusion also overrides this determination.
71 Flags are evaluated at the point where flagTestLOD is called.
73 If HOOK is supplied, then it is called if the LOD test passes.
74 It is passed as arguments two dictionaries: the block filler tool
75 arguments and the hook arguments.
78 >>> from AthenaCommon.JobProperties import JobPropertyContainer, JobProperty
79 >>> f1=JobPropertyContainer ('f1')
80 >>> f2=JobPropertyContainer ('f2')
81 >>> class flag1(JobProperty):
83 ... allowedTypes=['bool']
84 ... StoredValue = True
85 >>> class flag2(JobProperty):
87 ... allowedTypes=['bool']
88 ... StoredValue = False
89 >>> f1.add_JobProperty(flag1)
90 >>> f2.add_JobProperty(flag2)
91 >>> lod = flagTestLOD ('flag1', f1)
94 >>> lod(2, {}, {'flag1': False})
98 >>> lod(999, {}, {'flag1': False})
100 >>> lod = flagTestLOD ('flag2 or reqlev>4', [f1,f2])
107 >>> lod = flagTestLOD ('flag2 or reqlev>4', [f1,f2], hook)
110 >>> lod(10, {'a':1}, {'b':2})
115 fdict = _make_fdict (flags)
116 def flagTestLODFunc (reqlev, args, hookargs):
117 if reqlev < 0:
return False
121 ret = _eval_deferred (expr, fdict, hookargs, reqlev=reqlev)
123 hook (args, hookargs)
125 return flagTestLODFunc