mpbn 3.3__py3-none-any.whl → 3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mpbn might be problematic. Click here for more details.
- mpbn/converters.py +87 -0
- mpbn/simulation.py +47 -2
- {mpbn-3.3.dist-info → mpbn-3.5.dist-info}/METADATA +2 -2
- {mpbn-3.3.dist-info → mpbn-3.5.dist-info}/RECORD +7 -6
- {mpbn-3.3.dist-info → mpbn-3.5.dist-info}/WHEEL +1 -1
- {mpbn-3.3.dist-info → mpbn-3.5.dist-info}/entry_points.txt +0 -0
- {mpbn-3.3.dist-info → mpbn-3.5.dist-info}/top_level.txt +0 -0
mpbn/converters.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import networkx as nx
|
|
2
|
+
from pyeda.boolalg.minimization import *
|
|
3
|
+
import pyeda.boolalg.expr
|
|
4
|
+
from pyeda.inter import expr
|
|
5
|
+
|
|
6
|
+
from colomoto import minibn
|
|
7
|
+
|
|
8
|
+
def expr2str(ex):
|
|
9
|
+
"""
|
|
10
|
+
converts a pyeda Boolean expression to string representation
|
|
11
|
+
"""
|
|
12
|
+
def _protect(e):
|
|
13
|
+
if isinstance(e, (pyeda.boolalg.expr.OrOp, pyeda.boolalg.expr.AndOp)):
|
|
14
|
+
return f"({expr2str(e)})"
|
|
15
|
+
return expr2str(e)
|
|
16
|
+
if isinstance(ex, pyeda.boolalg.expr.Variable):
|
|
17
|
+
return str(ex)
|
|
18
|
+
elif isinstance(ex, pyeda.boolalg.expr._One):
|
|
19
|
+
return "1"
|
|
20
|
+
elif isinstance(ex, pyeda.boolalg.expr._Zero):
|
|
21
|
+
return "0"
|
|
22
|
+
elif isinstance(ex, pyeda.boolalg.expr.Complement):
|
|
23
|
+
return f"!{_protect(ex.__invert__())}"
|
|
24
|
+
elif isinstance(ex, pyeda.boolalg.expr.NotOp):
|
|
25
|
+
return f"!{_protect(ex.x)}"
|
|
26
|
+
elif isinstance(ex, pyeda.boolalg.expr.OrOp):
|
|
27
|
+
return " | ".join(map(_protect, ex.xs))
|
|
28
|
+
elif isinstance(ex, pyeda.boolalg.expr.AndOp):
|
|
29
|
+
return " & ".join(map(_protect, ex.xs))
|
|
30
|
+
raise NotImplementedError(str(ex), type(ex))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def bn_of_asynchronous_transition_graph(adyn, names,
|
|
34
|
+
parse_node=(lambda n: tuple(map(int, n))),
|
|
35
|
+
bn_class=minibn.BooleanNetwork,
|
|
36
|
+
simplify=True):
|
|
37
|
+
"""
|
|
38
|
+
Convert the transition graph of a (fully) asynchronous Boolean network to
|
|
39
|
+
a propositional logic representation.
|
|
40
|
+
|
|
41
|
+
The object `adyn` must be an instance of `networkx.DiGraph`.
|
|
42
|
+
The `parse_node` function must return a tuple of 0 and 1 from an `adyn`
|
|
43
|
+
node. By default, it is assumed that nodes are strings of binary values.
|
|
44
|
+
Returned object will be of `bn_class`, instantiated with a dictionnary
|
|
45
|
+
mapping component names to a string representation of their Boolean expression.
|
|
46
|
+
"""
|
|
47
|
+
relabel = {label: parse_node(label) for label in adyn.nodes()}
|
|
48
|
+
adyn = nx.relabel_nodes(adyn, relabel)
|
|
49
|
+
n = len(next(iter(adyn.nodes)))
|
|
50
|
+
assert n == len(names), "list of component names and dimension of configuraitons seem different"
|
|
51
|
+
assert adyn.number_of_nodes() == 2**n, "unexpected number of nodes in the transition graph"
|
|
52
|
+
|
|
53
|
+
def expr_of_cfg(x):
|
|
54
|
+
e = "&".join(f"{'~' if not v else ''}{names[i]}" for i, v in enumerate(x))
|
|
55
|
+
return f"({e})"
|
|
56
|
+
|
|
57
|
+
f = []
|
|
58
|
+
for i in range(n):
|
|
59
|
+
pos = []
|
|
60
|
+
for x in adyn.nodes():
|
|
61
|
+
dx = list(x)
|
|
62
|
+
dx[i] = 1-x[i]
|
|
63
|
+
y = dx if tuple(dx) in adyn[x] else x
|
|
64
|
+
target = y[i]
|
|
65
|
+
if target:
|
|
66
|
+
pos.append(x)
|
|
67
|
+
if not pos:
|
|
68
|
+
f.append(expr("0"))
|
|
69
|
+
else:
|
|
70
|
+
e = expr("|".join(map(expr_of_cfg,pos)))
|
|
71
|
+
e, = espresso_exprs(e.to_dnf())
|
|
72
|
+
f.append(e)
|
|
73
|
+
f = map(expr2str, f)
|
|
74
|
+
f = bn_class(dict(zip(names, f)))
|
|
75
|
+
if simplify:
|
|
76
|
+
f = f.simplify()
|
|
77
|
+
return f
|
|
78
|
+
|
|
79
|
+
if __name__ == "__main__":
|
|
80
|
+
import mpbn
|
|
81
|
+
|
|
82
|
+
f = mpbn.MPBooleanNetwork({
|
|
83
|
+
"x1": "x2",
|
|
84
|
+
"x2": "x3",
|
|
85
|
+
"x3": "x1"})
|
|
86
|
+
g = f.dynamics("asynchronous")
|
|
87
|
+
print(bn_of_asynchronous_transition_graph(g, list(f)))
|
mpbn/simulation.py
CHANGED
|
@@ -177,14 +177,14 @@ def step(f, mem, x, depth, W):
|
|
|
177
177
|
sample_configuration(f, mem, x, S, W)
|
|
178
178
|
return True
|
|
179
179
|
|
|
180
|
-
|
|
181
180
|
def is_subhypercube(a, b):
|
|
182
181
|
x, H = a
|
|
183
182
|
y, G = b
|
|
184
183
|
return H.issubset(G) and \
|
|
185
184
|
not [i for i in set(x).difference(G) if x[i] != y[i]]
|
|
186
185
|
|
|
187
|
-
def sample_reachable_attractor(f, mem, x, A, depth, W, refresh_rate=10):
|
|
186
|
+
def sample_reachable_attractor(f, mem, x, A, depth, W, refresh_rate=10, emit=None):
|
|
187
|
+
if not isinstance(f, MPBNSim): f = MPBNSim(f)
|
|
188
188
|
I = set(f)
|
|
189
189
|
n = len(f)
|
|
190
190
|
def filter_reachable_attractors(A, x):
|
|
@@ -194,6 +194,8 @@ def sample_reachable_attractor(f, mem, x, A, depth, W, refresh_rate=10):
|
|
|
194
194
|
x = x.copy()
|
|
195
195
|
A = filter_reachable_attractors(A, x)
|
|
196
196
|
while len(A) > 1:
|
|
197
|
+
if emit is not None:
|
|
198
|
+
emit(x)
|
|
197
199
|
if not step(f, mem, x, depth, W):
|
|
198
200
|
k = 0
|
|
199
201
|
if k % refresh_rate == 0:
|
|
@@ -201,6 +203,48 @@ def sample_reachable_attractor(f, mem, x, A, depth, W, refresh_rate=10):
|
|
|
201
203
|
k += 1
|
|
202
204
|
return A[0][0]
|
|
203
205
|
|
|
206
|
+
def sample_trace(f, mem, x, A, depth, W):
|
|
207
|
+
if not isinstance(f, MPBNSim): f = MPBNSim(f)
|
|
208
|
+
I = set(f)
|
|
209
|
+
n = len(f)
|
|
210
|
+
def filter_reachable_attractors(A, x):
|
|
211
|
+
H = spread(f, x, I, n)
|
|
212
|
+
return [(ia,a) for (ia,a) in A if is_subhypercube(a, (x,H))]
|
|
213
|
+
k = 1
|
|
214
|
+
x = x.copy()
|
|
215
|
+
trace = list()
|
|
216
|
+
trace.append(x.copy())
|
|
217
|
+
A = filter_reachable_attractors(A, x)
|
|
218
|
+
while len(A) and x != A[0][1][0]:
|
|
219
|
+
step(f, mem, x, depth, W)
|
|
220
|
+
trace.append(x.copy())
|
|
221
|
+
A = filter_reachable_attractors(A, x)
|
|
222
|
+
return trace
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def sample_switchpoint(f, mem, x, A, depth, W):
|
|
226
|
+
""" experimental: sample a trace and stop at an attractor's
|
|
227
|
+
strong bassin, returning the attractor as well."""
|
|
228
|
+
if not isinstance(f, MPBNSim): f = MPBNSim(f)
|
|
229
|
+
I = set(f)
|
|
230
|
+
n = len(f)
|
|
231
|
+
def filter_reachable_attractors(A, x):
|
|
232
|
+
H = spread(f, x, I, n)
|
|
233
|
+
return [(ia,a) for (ia,a) in A if is_subhypercube(a, (x,H))]
|
|
234
|
+
|
|
235
|
+
names = lambda _A: set(_a_name for _a_name, _a_cfg in _A)
|
|
236
|
+
k = 1
|
|
237
|
+
x = x.copy()
|
|
238
|
+
trace = list()
|
|
239
|
+
A = filter_reachable_attractors(A, x)
|
|
240
|
+
trace.append((x.copy(), names(A)))
|
|
241
|
+
while len(A) > 1:
|
|
242
|
+
step(f, mem, x, depth, W)
|
|
243
|
+
A = filter_reachable_attractors(A, x)
|
|
244
|
+
trace.append((x.copy(), names(A)))
|
|
245
|
+
#return [*trace, [a_name for a_name, a_x in A]]
|
|
246
|
+
return trace
|
|
247
|
+
|
|
204
248
|
def convert_attractor(A):
|
|
205
249
|
H = {i for i,v in A.items() if v == '*'}
|
|
206
250
|
x = {i:v for i,v in A.items() if v != '*'}
|
|
@@ -307,6 +351,7 @@ def nexponential_depth(f, base=2):
|
|
|
307
351
|
##
|
|
308
352
|
## Rates
|
|
309
353
|
##
|
|
354
|
+
## TODO: resolve this
|
|
310
355
|
def uniform_rates(f):
|
|
311
356
|
"""
|
|
312
357
|
Returns 1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mpbn
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5
|
|
4
4
|
Summary: Simple implementation of Most Permissive Boolean networks
|
|
5
5
|
Home-page: https://github.com/bnediction/mpbn
|
|
6
6
|
Author: Loïc Paulevé
|
|
@@ -20,7 +20,7 @@ Requires-Dist: scipy
|
|
|
20
20
|
Requires-Dist: tqdm
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
The `mpbn` Python module offers a simple implementation of reachability and attractor analysis (minimal trap spaces) in *Most Permissive Boolean Networks* ([doi:10.1038/s41467-020-18112-5](https://doi.org/10.1038/s41467-020-18112-5)).
|
|
23
|
+
The `mpbn` Python module offers a simple implementation of reachability and attractor analysis (minimal trap spaces) in *Most Permissive Boolean Networks* ([doi:10.1038/s41467-020-18112-5](https://doi.org/10.1038/s41467-020-18112-5)). The `mpbn` Python module also offers a *Most Permissive* simulator, which provides trajectory sampling and computes attractor propensities (see paper [Variable-Depth Simulation of Most Permissive Boolean Networks](https://link.springer.com/chapter/10.1007/978-3-031-15034-0_7) for more details).
|
|
24
24
|
|
|
25
25
|
It is built on the `minibn` module from [colomoto-jupyter](https://github.com/colomoto/colomoto-jupyter) which allows importation of Boolean networks in many formats. See http://colomoto.org/notebook.
|
|
26
26
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
mpbn/__init__.py,sha256=oPey2_tk0ymBGwiL9dcG88Hk-vUuWH-gpmP7ZDwXyu4,20578
|
|
2
|
-
mpbn/
|
|
2
|
+
mpbn/converters.py,sha256=33mhsGnFkJL4PlqYMIKu3zNb5oCNT6ZLaK6xoj9WsI4,3034
|
|
3
|
+
mpbn/simulation.py,sha256=3lk6yu7k2POrSytmtnsGIh596B-qcAgBtl16iZ0vzM4,10594
|
|
3
4
|
mpbn/asplib/eval_circuit.asp,sha256=5rIbkVmvobaQwE_gHr0_USccPuI0QUPuzfw_1011hSE,989
|
|
4
5
|
mpbn/asplib/eval_mixed.asp,sha256=n23pbjtxuWSCerL36Gb6O32bx8_1ukc52l1hQMMs8OE,787
|
|
5
6
|
mpbn/asplib/mp_attractor.asp,sha256=CawLNxlYBZG2cl8XQAxA6EXEZ89Y9iw20CZ73n97Nu8,185
|
|
@@ -14,8 +15,8 @@ tests/test_fixpoints.py,sha256=bdDttzimiby48nVkVL-HXZ2rBldICBRbIZrVVbTGfso,786
|
|
|
14
15
|
tests/test_input.py,sha256=mwMKd5UwAIY4Z1uZjYr09Ue8DLxD52CiPSoE-iXytfo,337
|
|
15
16
|
tests/test_reachability.py,sha256=X7anTwFSIYcV2rltJBOW8TcAJnrt3SjYLqttB0eIL_Q,588
|
|
16
17
|
tests/test_reachable_attractors.py,sha256=h78kvgmx9rTJWi3r2DZe_abYDxr02MLJ2iLDJUdLESY,540
|
|
17
|
-
mpbn-3.
|
|
18
|
-
mpbn-3.
|
|
19
|
-
mpbn-3.
|
|
20
|
-
mpbn-3.
|
|
21
|
-
mpbn-3.
|
|
18
|
+
mpbn-3.5.dist-info/METADATA,sha256=I6viVUknNQ532Vya9eUX-6u_QuwxrQx-w59njI7srYQ,2129
|
|
19
|
+
mpbn-3.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
20
|
+
mpbn-3.5.dist-info/entry_points.txt,sha256=CpzAc9SkB-mH_dojzt1N3YgDxy8hniDrIGzSHcPDo8g,68
|
|
21
|
+
mpbn-3.5.dist-info/top_level.txt,sha256=oe3jlFHbQ6oIXyE1q7yAAnf1m49oP_jBPUU05d71n74,11
|
|
22
|
+
mpbn-3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|