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 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, ode2tn
351
-
352
- P = 1
353
- I = 1
354
- D = 1
355
- val, setpoint, bias, integral, derivative_p, derivative_m, delayed_val = \
356
- sp.symbols('val setpoint bias integral derivative_p derivative_m delayed_val')
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
- # plot_tn(odes, inits, t_eval, gamma=gamma, beta=beta, resets=resets, figure_size=figsize)
382
- tn_odes, tn_inits, tn_syms = ode2tn(odes, inits, gamma=gamma, beta=beta)
383
- val_top = tn_syms[val][0]
384
- tn_odes[val_top] += bias
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.1
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
- # ode-to-transcription-network
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
- t_eval = np.linspace(0, 6*pi, 1000)
56
- # tn_odes, tn_inits, tn_syms = ode2tn(odes, inits, gamma, beta)
57
- # for sym, expr in tn_odes.items():
58
- # print(f"{sym}' = {expr}")
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
- This will print
61
+ When run in a Jupyter notebook, this will show
62
+
63
+ ![](ode-display.png)
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
- 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.
76
- The function `plot_tn` above does this conversion and then plots the ratios.
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
- ![](sine-cosine-plot.png)
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
+ ![](sine-cosine-plot.svg)
80
93
 
81
- One could also hand the transcriptional network ODEs to gpac to integrate, if you want to directly access the data being plotted above.
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 = {sol.y[0]}')
89
- print(f'x_b = {sol.y[1]}')
90
- print(f'y_t = {sol.y[2]}')
91
- print(f'y_b = {sol.y[3]}')
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 = [2. 1.78280757 3.67207594 2.80592514 1.71859172]
99
- x_b = [1. 1.78425369 1.83663725 0.93260227 0.859926 ]
100
- y_t = [1. 1.87324904 2.14156469 2.10338162 2.74383426]
101
- y_b = [1. 0.93637933 0.71348949 1.05261915 2.78279691]
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.1)
2
+ Generator: setuptools (79.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -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,,