20def flagTestLOD (expr, flags, hook = None):
21 """Helper for making LOD functions to evaluate flags.
22
23 Numerous parts of the D3PD configuration use arbitrary global flags
24 to control which blocks are included. This is bad because there
25 can be interference when multiple tuples are configured in the
26 same job.
27
28 Better is to use the level-of-detail mechanism to do this,
29 passing in flags as extra arguments to the D3PDObject.
30
31 This helper is to ease this conversion, while still allowing
32 backwards compatibility with flag-based configuration.
33
34 flagTestLOD will return a level-of-detail function that evaluates
35 the provided expression string EXP. This will be evaluated
36 in an environment that includes names for all flags in the flags
37 class(es) FLAGS, merged with the value of the hookargs.
38 The requested level of detail is also available as `reqlev'.
39 Thus, if you have something like:
40
41 myobj = make_SGDataVector_D3PDObject ('mycont', 'mykey', 'my_', 'myob',
42 allow_args = ['myLevel'])
43 myobj.defineBlock (flagTestLOD('myLevel>2', myFlags),
44 'myblock', filler_tool)
45
46 then myblock will be included in the tuple if the property
47 myFlags.myLevel() is greater than two. However, this can be overridden
48 by passing an argument to the D3PDObject:
49
50 alg += myobj (level, myLevel=4)
51
52 Explicit inclusion / exclusion also overrides this determination.
53
54 Flags are evaluated at the point where flagTestLOD is called.
55
56 If HOOK is supplied, then it is called if the LOD test passes.
57 It is passed as arguments two dictionaries: the block filler tool
58 arguments and the hook arguments.
59
60 Examples:
61 >>> from AthenaConfiguration.AllConfigFlags import initConfigFlags
62 >>> flags = initConfigFlags()
63 >>> flags.addFlag ('D3PD.flag1', True)
64 >>> flags.addFlag ('D3PD.flag2', False)
65
66 >>> lod = flagTestLOD ('flag1', flags.D3PD)
67 >>> lod(2, {}, {})
68 True
69 >>> lod(2, {}, {'flag1': False})
70 False
71 >>> lod(-999, {}, {})
72 False
73 >>> lod(999, {}, {'flag1': False})
74 True
75 >>> lod = flagTestLOD ('flag2 or reqlev>4', flags.D3PD)
76 >>> lod(2, {}, {})
77 False
78 >>> lod(10, {}, {})
79 True
80 >>> def hook(*args):
81 ... print(args)
82 >>> lod = flagTestLOD ('flag2 or reqlev>4', flags.D3PD, hook)
83 >>> lod(2, {}, {})
84 False
85 >>> lod(10, {'a':1}, {'b':2})
86 ({'a': 1}, {'b': 2})
87 True
88"""
89
90 fdict = flags.asdict()
91 def flagTestLODFunc (reqlev, args, hookargs):
92 if reqlev < 0: return False
93 if reqlev > 900:
94 ret = True
95 else:
96 ret = _eval_deferred (expr, fdict, hookargs, reqlev=reqlev)
97 if ret and hook:
98 hook (args, hookargs)
99 return ret
100 return flagTestLODFunc
101
102