ode2tn 1.0.1__py3-none-any.whl → 1.0.3__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.
- ode2tn/transform.py +33 -36
- {ode2tn-1.0.1.dist-info → ode2tn-1.0.3.dist-info}/METADATA +43 -27
- ode2tn-1.0.3.dist-info/RECORD +7 -0
- {ode2tn-1.0.1.dist-info → ode2tn-1.0.3.dist-info}/WHEEL +1 -1
- ode2tn-1.0.1.dist-info/RECORD +0 -7
- {ode2tn-1.0.1.dist-info → ode2tn-1.0.3.dist-info}/licenses/LICENSE +0 -0
- {ode2tn-1.0.1.dist-info → ode2tn-1.0.3.dist-info}/top_level.txt +0 -0
ode2tn/transform.py
CHANGED
@@ -17,6 +17,8 @@ def plot_tn(
|
|
17
17
|
beta: float,
|
18
18
|
scale: float = 1.0,
|
19
19
|
t_span: tuple[float, float] | None = None,
|
20
|
+
show_factors: bool = False,
|
21
|
+
latex_legend: bool = True,
|
20
22
|
resets: dict[float, dict[sp.Symbol | str, float]] | None = None,
|
21
23
|
dependent_symbols: dict[sp.Symbol | str, sp.Expr | str] | None = None,
|
22
24
|
figure_size: tuple[float, float] = (10, 3),
|
@@ -54,6 +56,18 @@ def plot_tn(
|
|
54
56
|
scale: "scaling factor" for the transcription network ODEs. Each variable `x` is replaced by a pair
|
55
57
|
(`x_top`, `x_bot`). The initial `x_bot` value is `scale`, and the initial `x_top` value is
|
56
58
|
`x*scale`.
|
59
|
+
show_factors: if True, then in addition to plotting the ratios x_top/x_bot,
|
60
|
+
also plot the factors x_top and x_bot separately in a second plot.
|
61
|
+
Mutually exlusive with `symbols_to_plot`, since it is equivalent to setting
|
62
|
+
`symbols_to_plot` to ``[ratios, factors]``, where ratios is a list of dependent symbols
|
63
|
+
`x=x_top/x_bot`, and factors is a list of symbols with the transcription factors `x_top`, `x_bot`,
|
64
|
+
for each original variable `x`.
|
65
|
+
latex_legend: If True, surround each symbol name with dollar signs, unless it is already surrounded with them,
|
66
|
+
so that the legend is interpreted as LaTeX. If this is True, then the symbol name must either
|
67
|
+
start and end with `$`, or neither start nor end with `$`. Unlike in the gpac package, this is True
|
68
|
+
by default. The names of transcription factors are automatically surrounded by dollar signs.
|
69
|
+
This option makes sure the legend showing original variables (or dependent symbols) also have `$` added
|
70
|
+
so as to be interpreted as LaTeX.
|
57
71
|
resets:
|
58
72
|
If specified, this is a dict mapping times to "configurations"
|
59
73
|
(i.e., dict mapping symbols/str to values).
|
@@ -77,12 +91,18 @@ def plot_tn(
|
|
77
91
|
Typically None, but if return_ode_result is True, returns the result of the ODE integration.
|
78
92
|
See documentation of `gpac.plot` for details.
|
79
93
|
"""
|
94
|
+
if show_factors and symbols_to_plot is not None:
|
95
|
+
raise ValueError("Cannot use both show_factors and symbols_to_plot at the same time.")
|
96
|
+
|
80
97
|
tn_odes, tn_inits, tn_syms = ode2tn(odes, initial_values, gamma=gamma, beta=beta, scale=scale)
|
81
98
|
dependent_symbols_tn = dict(dependent_symbols) if dependent_symbols is not None else {}
|
82
99
|
tn_ratios = {sym: sym_t/sym_b for sym, (sym_t, sym_b) in tn_syms.items()}
|
83
100
|
dependent_symbols_tn.update(tn_ratios)
|
84
101
|
symbols_to_plot = dependent_symbols_tn if symbols_to_plot is None else symbols_to_plot
|
85
102
|
|
103
|
+
if show_factors:
|
104
|
+
symbols_to_plot = [symbols_to_plot, [factor for pair in tn_syms.values() for factor in pair]]
|
105
|
+
|
86
106
|
legend = {}
|
87
107
|
for sym, (sym_t, sym_b) in tn_syms.items():
|
88
108
|
legend[sym_t] = f'${sym}^\\top$'
|
@@ -99,6 +119,7 @@ def plot_tn(
|
|
99
119
|
dependent_symbols=dependent_symbols_tn,
|
100
120
|
resets=resets,
|
101
121
|
figure_size=figure_size,
|
122
|
+
latex_legend=latex_legend,
|
102
123
|
symbols_to_plot=symbols_to_plot,
|
103
124
|
legend=legend,
|
104
125
|
show=show,
|
@@ -317,7 +338,7 @@ def split_polynomial(expr: sp.Expr) -> tuple[sp.Expr, sp.Expr]:
|
|
317
338
|
else:
|
318
339
|
# For negative coefficients, add the negated term to p2
|
319
340
|
p_neg += -term
|
320
|
-
elif expanded.is_Mul:
|
341
|
+
elif expanded.is_Mul or expanded.is_Pow:
|
321
342
|
# If it's a single term, just check the sign; is_Mul for things like x*y or -x (represented as -1*x)
|
322
343
|
coeff = next((arg for arg in expanded.args if arg.is_number), 1)
|
323
344
|
if coeff > 0:
|
@@ -347,43 +368,19 @@ def main():
|
|
347
368
|
import gpac as gp
|
348
369
|
import numpy as np
|
349
370
|
import sympy as sp
|
350
|
-
from ode2tn import plot_tn
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
proportional_term = P * (setpoint - val)
|
358
|
-
integral_term = I * (integral - 10)
|
359
|
-
# derivative_term = D * (temperature - delayed_temperature)
|
360
|
-
c = 1
|
361
|
-
odes = {
|
362
|
-
val: proportional_term + integral_term, # + derivative_term,
|
363
|
-
integral: setpoint - val,
|
364
|
-
delayed_val: c * (val - delayed_val),
|
365
|
-
setpoint: 0,
|
366
|
-
}
|
367
|
-
inits = {
|
368
|
-
val: 5,
|
369
|
-
setpoint: 7,
|
370
|
-
integral: 10,
|
371
|
-
}
|
372
|
-
t_eval = np.linspace(0, 40, 500)
|
373
|
-
figsize = (16, 4)
|
374
|
-
resets = {
|
375
|
-
10: {val: 9},
|
376
|
-
20: {val: 3},
|
377
|
-
30: {bias: 2},
|
378
|
-
}
|
371
|
+
from ode2tn import plot_tn
|
372
|
+
|
373
|
+
x = gp.species('X')
|
374
|
+
rxns = [2 * x >> 3 * x]
|
375
|
+
odes = gp.crn_to_odes(rxns)
|
376
|
+
inits = {x: 1}
|
377
|
+
t_eval = np.linspace(0, 1, 100)
|
379
378
|
gamma = 1
|
380
379
|
beta = 1
|
381
|
-
#
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
tn_odes[bias] = 0
|
386
|
-
gp.plot(tn_odes, tn_inits, t_eval, resets=resets, figure_size=figsize)
|
380
|
+
# figsize = (16,4)
|
381
|
+
|
382
|
+
# gp.plot_crn(rxns, inits, t_eval, figure_size=figsize)
|
383
|
+
plot_tn(odes, inits, t_eval, gamma=gamma, beta=beta)
|
387
384
|
|
388
385
|
|
389
386
|
if __name__ == '__main__':
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ode2tn
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.3
|
4
4
|
Summary: A Python package to turn arbitrary polynomial ODEs into a transcriptional network simulating it.
|
5
5
|
Author-email: Dave Doty <doty@ucdavis.edu>
|
6
|
-
License: MIT
|
6
|
+
License-Expression: MIT
|
7
7
|
Project-URL: Homepage, https://github.com/UC-Davis-molecular-computing/ode-to-transcription-network
|
8
8
|
Project-URL: Issues, https://github.com/UC-Davis-molecular-computing/ode-to-transcription-network/issues
|
9
9
|
Requires-Python: >=3.10
|
@@ -14,7 +14,7 @@ Requires-Dist: scipy>=1.15
|
|
14
14
|
Requires-Dist: sympy>=1.13
|
15
15
|
Dynamic: license-file
|
16
16
|
|
17
|
-
#
|
17
|
+
# ode2tn
|
18
18
|
ode2tn is a Python package to compile arbitrary polynomial ODEs into a transcriptional network simulating the ODEs.
|
19
19
|
|
20
20
|
See this paper for details: TODO
|
@@ -52,53 +52,69 @@ inits = { # inits maps each symbol to its initial value
|
|
52
52
|
}
|
53
53
|
gamma = 2 # uniform decay constant; should be set sufficiently large that ???
|
54
54
|
beta = 1 # constant introduced to keep values from going to infinity or 0
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# print(f'{tn_inits=}')
|
60
|
-
# print(f'{tn_syms=}')
|
61
|
-
plot_tn(odes, inits, gamma=gamma, beta=beta, t_eval=t_eval)
|
55
|
+
tn_odes, tn_inits, tn_syms = ode2tn(odes, inits, gamma=gamma, beta=beta)
|
56
|
+
gp.display_odes(tn_odes)
|
57
|
+
print(f'{tn_inits=}')
|
58
|
+
print(f'{tn_syms=}')
|
62
59
|
```
|
63
60
|
|
64
|
-
|
61
|
+
When run in a Jupyter notebook, this will show
|
62
|
+
|
63
|
+

|
64
|
+
|
65
|
+
showing that the variables `x` and `y` have been replace by pairs `x_t,x_b` and `y_t,y_b`, whose ratios `x_t/x_b` and `y_t/y_b` will track the values of the original variable `x` and `y` over time.
|
65
66
|
|
67
|
+
If not in a Jupyter notebook, one could also inspect the transcriptional network ODEs via
|
68
|
+
```python
|
69
|
+
for var, ode in tn_odes.items():
|
70
|
+
print(f"{var}' = {ode}")
|
71
|
+
```
|
72
|
+
which would print a text-based version of the equations:
|
66
73
|
```
|
67
74
|
x_t' = x_b*y_t/y_b - 2*x_t + x_t/x_b
|
68
75
|
x_b' = 2*x_b**2/x_t - 2*x_b + 1
|
69
76
|
y_t' = 2*y_b - 2*y_t + y_t/y_b
|
70
77
|
y_b' = -2*y_b + 1 + x_t*y_b**2/(x_b*y_t)
|
71
|
-
tn_inits={x_t: 2, x_b: 1, y_t: 1, y_b: 1}
|
72
|
-
tn_syms={x: (x_t, x_b), y: (y_t, y_b)}
|
73
78
|
```
|
74
79
|
|
75
|
-
|
76
|
-
|
77
|
-
Running the code above in a Jupyter notebook will print the above text and show this figure:
|
80
|
+
The function `plot_tn` above does this conversion on the *original* odes and then plots the ratios.
|
81
|
+
Running
|
78
82
|
|
79
|
-
|
83
|
+
```python
|
84
|
+
t_eval = np.linspace(0, 6*pi, 1000)
|
85
|
+
# note below it is odes and inits, not tn_odes and tn_inits
|
86
|
+
# plot_tn calls ode2tn to convert the ODEs before plotting
|
87
|
+
plot_tn(odes, inits, gamma=gamma, beta=beta, t_eval=t_eval, show_factors=True)
|
88
|
+
```
|
89
|
+
|
90
|
+
in a Jupyter notebook will show this figure:
|
91
|
+
|
92
|
+

|
80
93
|
|
81
|
-
|
94
|
+
The parameter `show_factors` above indicates to show a second subplot with the underlying transcription factors ($x^\top, x^\bot, y^\top, y^\bot$ above).
|
95
|
+
If left unspecified, it defaults to `False` and plots only the original values (ratios of pairs of transcription factors, $x,y$ above).
|
96
|
+
|
97
|
+
One could also hand the transcriptional network ODEs to [gpac](https://github.com/UC-Davis-molecular-computing/gpac) to integrate, if you want to directly access the data being plotted above.
|
82
98
|
The `OdeResult` object returned by `gpac.integrate_odes` is the same returned by [`scipy.integrate.solve_ivp`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html), where the return value `sol` has a field `sol.y` that has the values of the variables in the order they were inserted into `tn_odes`, which will be the same as the order in which the original variables `x` and `y` were inserted, with `x_t` coming before `x_b`:
|
83
99
|
|
84
|
-
```
|
100
|
+
```python
|
85
101
|
t_eval = np.linspace(0, 2*pi, 5)
|
86
102
|
sol = gp.integrate_odes(tn_odes, tn_inits, t_eval)
|
87
103
|
print(f'times = {sol.t}')
|
88
|
-
print(f'x_t
|
89
|
-
print(f'x_b
|
90
|
-
print(f'y_t
|
91
|
-
print(f'y_b
|
104
|
+
print(f'x_t = {sol.y[0]}')
|
105
|
+
print(f'x_b = {sol.y[1]}')
|
106
|
+
print(f'y_t = {sol.y[2]}')
|
107
|
+
print(f'y_b = {sol.y[3]}')
|
92
108
|
```
|
93
109
|
|
94
110
|
which would print
|
95
111
|
|
96
112
|
```
|
97
113
|
times = [0. 1.57079633 3.14159265 4.71238898 6.28318531]
|
98
|
-
x_t
|
99
|
-
x_b
|
100
|
-
y_t
|
101
|
-
y_b
|
114
|
+
x_t = [2. 1.78280757 3.67207594 2.80592514 1.71859172]
|
115
|
+
x_b = [1. 1.78425369 1.83663725 0.93260227 0.859926 ]
|
116
|
+
y_t = [1. 1.87324904 2.14156469 2.10338162 2.74383426]
|
117
|
+
y_b = [1. 0.93637933 0.71348949 1.05261915 2.78279691]
|
102
118
|
```
|
103
119
|
|
104
120
|
|
@@ -0,0 +1,7 @@
|
|
1
|
+
ode2tn/__init__.py,sha256=b_mINIsNfCWzgG7QVYMsRsWKDLvp2QKFAzRqWtYqwDA,30
|
2
|
+
ode2tn/transform.py,sha256=8GciVR2iGRRWgKyvPoYoQ5TZjKrOdNyzaH_ZukJiVsw,16829
|
3
|
+
ode2tn-1.0.3.dist-info/licenses/LICENSE,sha256=VV9UH0kkG-2edZvwJOqgtN12bZIzs2vn9_cq1SjoUJc,1091
|
4
|
+
ode2tn-1.0.3.dist-info/METADATA,sha256=RbwHIvSA6PgVWV9I57Fs9n2OdU7ocksS65YPaxs7174,4882
|
5
|
+
ode2tn-1.0.3.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
6
|
+
ode2tn-1.0.3.dist-info/top_level.txt,sha256=fPQ9s5yLIYfazJS7wBBfU9EsWa9RGALq8VL-wUYRlao,7
|
7
|
+
ode2tn-1.0.3.dist-info/RECORD,,
|
ode2tn-1.0.1.dist-info/RECORD
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
ode2tn/__init__.py,sha256=b_mINIsNfCWzgG7QVYMsRsWKDLvp2QKFAzRqWtYqwDA,30
|
2
|
-
ode2tn/transform.py,sha256=0ok_lcHA2lOV8yrB-MBC9es-i7zVP50EktKeuUuhs0k,16148
|
3
|
-
ode2tn-1.0.1.dist-info/licenses/LICENSE,sha256=VV9UH0kkG-2edZvwJOqgtN12bZIzs2vn9_cq1SjoUJc,1091
|
4
|
-
ode2tn-1.0.1.dist-info/METADATA,sha256=klLivWzfNVnR3VDVSkWvSuGQDnBrdLCpL7lUOpTCTlc,4228
|
5
|
-
ode2tn-1.0.1.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
6
|
-
ode2tn-1.0.1.dist-info/top_level.txt,sha256=fPQ9s5yLIYfazJS7wBBfU9EsWa9RGALq8VL-wUYRlao,7
|
7
|
-
ode2tn-1.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|