Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"Scripts to parse and collate substitutions"
2import warnings as pywarnings
3import numpy as np
4from ..small_scripts import splitsweep
7def parse_subs(varkeys, substitutions, clean=False):
8 "Seperates subs into the constants, sweeps, linkedsweeps actually present."
9 constants, sweep, linkedsweep = {}, {}, {}
10 if clean:
11 for var in varkeys:
12 if dict.__contains__(substitutions, var):
13 sub = dict.__getitem__(substitutions, var)
14 append_sub(sub, [var], constants, sweep, linkedsweep)
15 else:
16 varkeys.update_keymap()
17 if hasattr(substitutions, "keymap"):
18 for var in varkeys.keymap:
19 if dict.__contains__(substitutions, var):
20 sub = dict.__getitem__(substitutions, var)
21 keys = varkeys.keymap[var]
22 append_sub(sub, keys, constants, sweep, linkedsweep)
23 else:
24 for var in substitutions:
25 key = getattr(var, "key", var)
26 if key in varkeys.keymap:
27 sub, keys = substitutions[var], varkeys.keymap[key]
28 append_sub(sub, keys, constants, sweep, linkedsweep)
29 return constants, sweep, linkedsweep
32def append_sub(sub, keys, constants, sweep, linkedsweep):
33 "Appends sub to constants, sweep, or linkedsweep."
34 sweepsub, sweepval = splitsweep(sub)
35 if sweepsub: # if the whole key is swept
36 sub = sweepval
37 for key in keys:
38 if not key.shape or not getattr(sub, "shape", hasattr(sub, "__len__")):
39 value = sub
40 else:
41 with pywarnings.catch_warnings():
42 pywarnings.filterwarnings("error")
43 try:
44 sub = np.array(sub) if not hasattr(sub, "shape") else sub
45 except Warning: # pragma: no cover #TODO: coverage this
46 # ragged nested sequences, eg [[2]], [3, 4]], in py3.7+
47 sub = np.array(sub, dtype=object)
48 if key.shape == sub.shape:
49 value = sub[key.idx]
50 sweepel, sweepval = splitsweep(value)
51 if sweepel: # if only an element is swept
52 value = sweepval
53 sweepsub = True
54 elif sweepsub:
55 try:
56 np.broadcast(sub, np.empty(key.shape))
57 except ValueError:
58 raise ValueError("cannot sweep variable %s of shape %s"
59 " with array of shape %s; array shape"
60 " must either be %s or %s" %
61 (key.veckey, key.shape, sub.shape,
62 key.shape, ("N",)+key.shape))
63 idx = (slice(None),)+key.descr["idx"]
64 value = sub[idx]
65 else:
66 raise ValueError("cannot substitute array of shape %s for"
67 " variable %s of shape %s." %
68 (sub.shape, key.veckey, key.shape))
69 if hasattr(value, "__call__") and not hasattr(value, "key"):
70 linkedsweep[key] = value
71 elif sweepsub:
72 sweep[key] = value
73 else:
74 try:
75 assert np.isnan(value)
76 except (AssertionError, TypeError, ValueError):
77 constants[key] = value