ode2tn 1.0.0__py3-none-any.whl → 1.0.1__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 +116 -110
- {ode2tn-1.0.0.dist-info → ode2tn-1.0.1.dist-info}/METADATA +11 -11
- ode2tn-1.0.1.dist-info/RECORD +7 -0
- ode2tn-1.0.0.dist-info/RECORD +0 -7
- {ode2tn-1.0.0.dist-info → ode2tn-1.0.1.dist-info}/WHEEL +0 -0
- {ode2tn-1.0.0.dist-info → ode2tn-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {ode2tn-1.0.0.dist-info → ode2tn-1.0.1.dist-info}/top_level.txt +0 -0
ode2tn/transform.py
CHANGED
@@ -10,7 +10,7 @@ from scipy.integrate._ivp.ivp import OdeResult # noqa
|
|
10
10
|
|
11
11
|
def plot_tn(
|
12
12
|
odes: dict[sp.Symbol | str, sp.Expr | str | float],
|
13
|
-
initial_values: dict[sp.Symbol | str, float],
|
13
|
+
initial_values: dict[sp.Symbol | str | gp.Specie, float],
|
14
14
|
t_eval: Iterable[float] | None = None,
|
15
15
|
*,
|
16
16
|
gamma: float,
|
@@ -77,44 +77,19 @@ def plot_tn(
|
|
77
77
|
Typically None, but if return_ode_result is True, returns the result of the ODE integration.
|
78
78
|
See documentation of `gpac.plot` for details.
|
79
79
|
"""
|
80
|
-
tn_odes, tn_inits,
|
80
|
+
tn_odes, tn_inits, tn_syms = ode2tn(odes, initial_values, gamma=gamma, beta=beta, scale=scale)
|
81
81
|
dependent_symbols_tn = dict(dependent_symbols) if dependent_symbols is not None else {}
|
82
|
+
tn_ratios = {sym: sym_t/sym_b for sym, (sym_t, sym_b) in tn_syms.items()}
|
82
83
|
dependent_symbols_tn.update(tn_ratios)
|
83
84
|
symbols_to_plot = dependent_symbols_tn if symbols_to_plot is None else symbols_to_plot
|
84
85
|
|
86
|
+
legend = {}
|
87
|
+
for sym, (sym_t, sym_b) in tn_syms.items():
|
88
|
+
legend[sym_t] = f'${sym}^\\top$'
|
89
|
+
legend[sym_b] = f'${sym}^\\bot$'
|
90
|
+
|
85
91
|
if resets is not None:
|
86
|
-
|
87
|
-
new_resets = {}
|
88
|
-
for time, reset in resets.items():
|
89
|
-
new_resets[time] = {}
|
90
|
-
for x, val in reset.items():
|
91
|
-
new_resets[time][x] = val
|
92
|
-
resets = new_resets
|
93
|
-
# normalize resets keys and check that variables are valid
|
94
|
-
for reset in resets.values():
|
95
|
-
for x, val in reset.items():
|
96
|
-
if isinstance(x, str):
|
97
|
-
del reset[x]
|
98
|
-
x = sp.symbols(x)
|
99
|
-
reset[x] = val
|
100
|
-
if x not in odes.keys() and x not in tn_odes.keys():
|
101
|
-
raise ValueError(f"Symbol {x} not found in original variables: {', '.join(odes.keys())},\n"
|
102
|
-
f"nor found in transcription network variables: {', '.join(tn_odes.keys())}")
|
103
|
-
# ensure if original variable x is in resets, then neither x_top nor x_bot are in the resets
|
104
|
-
# and substitute x_top and x_bot for x in resets
|
105
|
-
for x, ratio in tn_ratios.items():
|
106
|
-
# x is an original; so make sure neither x_top nor x_bot are in the reset dict
|
107
|
-
if x in reset:
|
108
|
-
xt,xb = sp.fraction(ratio)
|
109
|
-
if xt in reset:
|
110
|
-
raise ValueError(f'Cannot use "top" variable {xt} in resets '
|
111
|
-
f'if original variable {x} is also used')
|
112
|
-
if xb in reset:
|
113
|
-
raise ValueError(f'Cannot use "bottom" variable {xb} in resets '
|
114
|
-
f'if original variable {x} is also used')
|
115
|
-
reset[xt] = reset[x] * scale
|
116
|
-
reset[xb] = scale
|
117
|
-
del reset[x]
|
92
|
+
resets = update_resets_with_ratios(odes, resets, tn_odes, tn_syms, scale)
|
118
93
|
|
119
94
|
return gp.plot(
|
120
95
|
odes=tn_odes,
|
@@ -125,6 +100,7 @@ def plot_tn(
|
|
125
100
|
resets=resets,
|
126
101
|
figure_size=figure_size,
|
127
102
|
symbols_to_plot=symbols_to_plot,
|
103
|
+
legend=legend,
|
128
104
|
show=show,
|
129
105
|
method=method,
|
130
106
|
dense_output=dense_output,
|
@@ -137,14 +113,51 @@ def plot_tn(
|
|
137
113
|
)
|
138
114
|
|
139
115
|
|
116
|
+
def update_resets_with_ratios(odes, resets, tn_odes, tn_syms, scale: float = 1.0) -> dict[float, dict[sp.Symbol, float]]:
|
117
|
+
tn_ratios = {sym: sym_t / sym_b for sym, (sym_t, sym_b) in tn_syms.items()}
|
118
|
+
# make copy since we are going to change it
|
119
|
+
new_resets = {}
|
120
|
+
for time, reset in resets.items():
|
121
|
+
new_resets[time] = {}
|
122
|
+
for x, val in reset.items():
|
123
|
+
new_resets[time][x] = val
|
124
|
+
resets = new_resets
|
125
|
+
# normalize resets keys and check that variables are valid
|
126
|
+
for reset in resets.values():
|
127
|
+
for x, val in reset.items():
|
128
|
+
if isinstance(x, str):
|
129
|
+
del reset[x]
|
130
|
+
x = sp.symbols(x)
|
131
|
+
reset[x] = val
|
132
|
+
if x not in odes.keys() and x not in tn_odes.keys():
|
133
|
+
raise ValueError(f"Symbol {x} not found in original variables: {', '.join(odes.keys())},\n"
|
134
|
+
f"nor found in transcription network variables: {', '.join(tn_odes.keys())}")
|
135
|
+
# ensure if original variable x is in resets, then neither x_top nor x_bot are in the resets
|
136
|
+
# and substitute x_top and x_bot for x in resets
|
137
|
+
for x, ratio in tn_ratios.items():
|
138
|
+
# x is an original; so make sure neither x_top nor x_bot are in the reset dict
|
139
|
+
if x in reset:
|
140
|
+
xt, xb = sp.fraction(ratio)
|
141
|
+
if xt in reset:
|
142
|
+
raise ValueError(f'Cannot use "top" variable {xt} in resets '
|
143
|
+
f'if original variable {x} is also used')
|
144
|
+
if xb in reset:
|
145
|
+
raise ValueError(f'Cannot use "bottom" variable {xb} in resets '
|
146
|
+
f'if original variable {x} is also used')
|
147
|
+
reset[xt] = reset[x] * scale
|
148
|
+
reset[xb] = scale
|
149
|
+
del reset[x]
|
150
|
+
return resets
|
151
|
+
|
152
|
+
|
140
153
|
def ode2tn(
|
141
154
|
odes: dict[sp.Symbol | str, sp.Expr | str | float],
|
142
|
-
initial_values: dict[sp.Symbol | str, float],
|
155
|
+
initial_values: dict[sp.Symbol | str | gp.Specie, float],
|
143
156
|
*,
|
144
157
|
gamma: float,
|
145
158
|
beta: float,
|
146
159
|
scale: float = 1.0,
|
147
|
-
) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, sp.
|
160
|
+
) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, tuple[sp.Symbol, sp.Symbol]]]:
|
148
161
|
"""
|
149
162
|
Maps polynomial ODEs and and initial values to transcription network (represented by ODEs with positive
|
150
163
|
Laurent polynomials and negative linear term) simulating it, as well as initial values.
|
@@ -155,7 +168,8 @@ def ode2tn(
|
|
155
168
|
(representing RHS of ODEs)
|
156
169
|
Raises ValueError if any of the ODEs RHS is not a polynomial
|
157
170
|
initial_values: initial values,
|
158
|
-
dict of sympy symbols or strings (representing symbols)
|
171
|
+
dict of sympy symbols or strings (representing symbols) or gpac.Specie (representing chemical
|
172
|
+
species, if the ODEs were derived from `gpac.crn_to_odes`) to floats
|
159
173
|
gamma: coefficient of the negative linear term in the transcription network
|
160
174
|
beta: additive constant in x_top ODE
|
161
175
|
scale: "scaling factor" for the transcription network ODEs. Each variable `x` is replaced by a pair
|
@@ -163,15 +177,21 @@ def ode2tn(
|
|
163
177
|
`x*scale`.
|
164
178
|
|
165
179
|
Return:
|
166
|
-
triple (`tn_odes`, `tn_inits`, `
|
167
|
-
in the original ODEs to the
|
180
|
+
triple (`tn_odes`, `tn_inits`, `tn_syms`), where `tn_syms` is a dict mapping each original symbol ``x``
|
181
|
+
in the original ODEs to the pair ``(x_top, x_bot)``.
|
168
182
|
"""
|
169
183
|
# normalize initial values dict to use symbols as keys
|
170
|
-
|
171
|
-
|
184
|
+
initial_values_norm = {}
|
185
|
+
for symbol, value in initial_values.items():
|
186
|
+
if isinstance(symbol, str):
|
187
|
+
symbol = sp.symbols(symbol)
|
188
|
+
if isinstance(symbol, gp.Specie):
|
189
|
+
symbol = sp.symbols(symbol.name)
|
190
|
+
initial_values_norm[symbol] = value
|
191
|
+
initial_values = initial_values_norm
|
172
192
|
|
173
193
|
# normalize odes dict to use symbols as keys
|
174
|
-
|
194
|
+
odes_normalized = {}
|
175
195
|
symbols_found_in_expressions = set()
|
176
196
|
for symbol, expr in odes.items():
|
177
197
|
if isinstance(symbol, str):
|
@@ -179,11 +199,12 @@ def ode2tn(
|
|
179
199
|
if isinstance(expr, (str, int, float)):
|
180
200
|
expr = sp.sympify(expr)
|
181
201
|
symbols_found_in_expressions.update(expr.free_symbols)
|
182
|
-
|
202
|
+
odes_normalized[symbol] = expr
|
203
|
+
odes = odes_normalized
|
183
204
|
|
184
205
|
# ensure that all symbols that are keys in `initial_values` are also keys in `odes`
|
185
206
|
initial_values_keys = set(initial_values.keys())
|
186
|
-
odes_keys = set(
|
207
|
+
odes_keys = set(odes.keys())
|
187
208
|
diff = initial_values_keys - odes_keys
|
188
209
|
if len(diff) > 0:
|
189
210
|
raise ValueError(f"\nInitial_values contains symbols that are not in odes: "
|
@@ -199,7 +220,7 @@ def ode2tn(
|
|
199
220
|
f"The keys in the odes dict are: {odes_keys}")
|
200
221
|
|
201
222
|
# ensure all odes are polynomials
|
202
|
-
for symbol, expr in
|
223
|
+
for symbol, expr in odes_normalized.items():
|
203
224
|
if not expr.is_polynomial():
|
204
225
|
raise ValueError(f"ODE for {symbol}' is not a polynomial: {expr}")
|
205
226
|
|
@@ -213,16 +234,14 @@ def normalized_ode2tn(
|
|
213
234
|
gamma: float,
|
214
235
|
beta: float,
|
215
236
|
scale: float,
|
216
|
-
) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, sp.
|
237
|
+
) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, tuple[sp.Symbol, sp.Symbol]]]:
|
217
238
|
# Assumes ode2tn has normalized and done error-checking
|
218
239
|
|
219
|
-
|
220
|
-
tn_ratios: dict[sp.Symbol, sp.Expr] = {}
|
240
|
+
tn_syms: dict[sp.Symbol, tuple[sp.Symbol, sp.Symbol]] = {}
|
221
241
|
for x in odes.keys():
|
222
242
|
# create x_t, x_b for each symbol x
|
223
|
-
|
224
|
-
|
225
|
-
tn_ratios[x] = x_top / x_bot
|
243
|
+
x_t, x_b = sp.symbols(f'{x}_t {x}_b')
|
244
|
+
tn_syms[x] = (x_t, x_b)
|
226
245
|
|
227
246
|
tn_odes: dict[sp.Symbol, sp.Expr] = {}
|
228
247
|
tn_inits: dict[sp.Symbol, float] = {}
|
@@ -231,19 +250,20 @@ def normalized_ode2tn(
|
|
231
250
|
|
232
251
|
# replace sym with sym_top / sym_bot for each original symbol sym
|
233
252
|
for sym in odes.keys():
|
234
|
-
sym_top, sym_bot =
|
235
|
-
|
236
|
-
|
253
|
+
sym_top, sym_bot = tn_syms[sym]
|
254
|
+
ratio = sym_top / sym_bot
|
255
|
+
p_pos = p_pos.subs(sym, ratio)
|
256
|
+
p_neg = p_neg.subs(sym, ratio)
|
237
257
|
|
238
|
-
|
258
|
+
x_t, x_b = tn_syms[x]
|
239
259
|
# tn_odes[x_top] = beta + p_pos * x_bot - gamma * x_top
|
240
260
|
# tn_odes[x_bot] = p_neg * x_bot ** 2 / x_top + beta * x_bot / x_top - gamma * x_bot
|
241
|
-
tn_odes[
|
242
|
-
tn_odes[
|
243
|
-
tn_inits[
|
244
|
-
tn_inits[
|
261
|
+
tn_odes[x_t] = beta * x_t / x_b + p_pos * x_b - gamma * x_t
|
262
|
+
tn_odes[x_b] = beta + p_neg * x_b ** 2 / x_t - gamma * x_b
|
263
|
+
tn_inits[x_t] = initial_values.get(x, 0) * scale
|
264
|
+
tn_inits[x_b] = scale
|
245
265
|
|
246
|
-
return tn_odes, tn_inits,
|
266
|
+
return tn_odes, tn_inits, tn_syms
|
247
267
|
|
248
268
|
|
249
269
|
def split_polynomial(expr: sp.Expr) -> tuple[sp.Expr, sp.Expr]:
|
@@ -324,60 +344,46 @@ def comma_separated(elts: Iterable[Any]) -> str:
|
|
324
344
|
|
325
345
|
|
326
346
|
def main():
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
347
|
+
import gpac as gp
|
348
|
+
import numpy as np
|
349
|
+
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
|
+
}
|
342
367
|
inits = {
|
343
|
-
|
344
|
-
|
368
|
+
val: 5,
|
369
|
+
setpoint: 7,
|
370
|
+
integral: 10,
|
345
371
|
}
|
346
|
-
|
347
|
-
|
348
|
-
scale = 0.1
|
349
|
-
import numpy as np
|
350
|
-
t_eval = np.linspace(0, 20, 500)
|
351
|
-
|
352
|
-
tn_odes, tn_inits, tn_ratios = ode2tn(odes, inits, gamma=gamma, beta=beta, scale=scale)
|
353
|
-
for ratio_symbol in tn_inits.keys():
|
354
|
-
if ratio_symbol.name == 'x_t':
|
355
|
-
xt = ratio_symbol
|
356
|
-
if ratio_symbol.name == 'x_b':
|
357
|
-
xb = ratio_symbol
|
358
|
-
if ratio_symbol.name == 'y_t':
|
359
|
-
yt = ratio_symbol
|
360
|
-
if ratio_symbol.name == 'y_b':
|
361
|
-
yb = ratio_symbol
|
362
|
-
from IPython.display import display
|
363
|
-
for sym, expr in tn_odes.items():
|
364
|
-
print(f"{sym}' = ", end='')
|
365
|
-
display(sp.simplify(expr))
|
366
|
-
print(f'{tn_inits=}')
|
367
|
-
print(f'{tn_ratios=}')
|
368
|
-
# for var, val in tn_inits.items():
|
369
|
-
# tn_inits[var] *= 0.1
|
370
|
-
# print(f'after reducing t/b values by 10x: {tn_inits=}')
|
371
|
-
figsize = (15, 6)
|
372
|
+
t_eval = np.linspace(0, 40, 500)
|
373
|
+
figsize = (16, 4)
|
372
374
|
resets = {
|
373
|
-
|
374
|
-
|
375
|
-
|
375
|
+
10: {val: 9},
|
376
|
+
20: {val: 3},
|
377
|
+
30: {bias: 2},
|
376
378
|
}
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
379
|
+
gamma = 1
|
380
|
+
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)
|
381
387
|
|
382
388
|
|
383
389
|
if __name__ == '__main__':
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ode2tn
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.1
|
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
6
|
License: MIT
|
@@ -15,7 +15,7 @@ Requires-Dist: sympy>=1.13
|
|
15
15
|
Dynamic: license-file
|
16
16
|
|
17
17
|
# ode-to-transcription-network
|
18
|
-
ode2tn is a Python package to
|
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
|
21
21
|
|
@@ -53,12 +53,12 @@ inits = { # inits maps each symbol to its initial value
|
|
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
55
|
t_eval = np.linspace(0, 6*pi, 1000)
|
56
|
-
tn_odes, tn_inits,
|
57
|
-
for sym, expr in tn_odes.items():
|
58
|
-
|
59
|
-
print(f'{tn_inits=}')
|
60
|
-
print(f'{
|
61
|
-
plot_tn(odes, inits, gamma, beta, t_eval=t_eval)
|
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)
|
62
62
|
```
|
63
63
|
|
64
64
|
This will print
|
@@ -69,7 +69,7 @@ x_b' = 2*x_b**2/x_t - 2*x_b + 1
|
|
69
69
|
y_t' = 2*y_b - 2*y_t + y_t/y_b
|
70
70
|
y_b' = -2*y_b + 1 + x_t*y_b**2/(x_b*y_t)
|
71
71
|
tn_inits={x_t: 2, x_b: 1, y_t: 1, y_b: 1}
|
72
|
-
|
72
|
+
tn_syms={x: (x_t, x_b), y: (y_t, y_b)}
|
73
73
|
```
|
74
74
|
|
75
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.
|
@@ -85,7 +85,7 @@ The `OdeResult` object returned by `gpac.integrate_odes` is the same returned by
|
|
85
85
|
t_eval = np.linspace(0, 2*pi, 5)
|
86
86
|
sol = gp.integrate_odes(tn_odes, tn_inits, t_eval)
|
87
87
|
print(f'times = {sol.t}')
|
88
|
-
print(f'
|
88
|
+
print(f'x_t = {sol.y[0]}')
|
89
89
|
print(f'x_b = {sol.y[1]}')
|
90
90
|
print(f'y_t = {sol.y[2]}')
|
91
91
|
print(f'y_b = {sol.y[3]}')
|
@@ -95,7 +95,7 @@ which would print
|
|
95
95
|
|
96
96
|
```
|
97
97
|
times = [0. 1.57079633 3.14159265 4.71238898 6.28318531]
|
98
|
-
|
98
|
+
x_t = [2. 1.78280757 3.67207594 2.80592514 1.71859172]
|
99
99
|
x_b = [1. 1.78425369 1.83663725 0.93260227 0.859926 ]
|
100
100
|
y_t = [1. 1.87324904 2.14156469 2.10338162 2.74383426]
|
101
101
|
y_b = [1. 0.93637933 0.71348949 1.05261915 2.78279691]
|
@@ -0,0 +1,7 @@
|
|
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,,
|
ode2tn-1.0.0.dist-info/RECORD
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
ode2tn/__init__.py,sha256=b_mINIsNfCWzgG7QVYMsRsWKDLvp2QKFAzRqWtYqwDA,30
|
2
|
-
ode2tn/transform.py,sha256=k_yzuUck-RGgS-WI7cUzNRfC4nKIMip_q5mJfVukg28,15847
|
3
|
-
ode2tn-1.0.0.dist-info/licenses/LICENSE,sha256=VV9UH0kkG-2edZvwJOqgtN12bZIzs2vn9_cq1SjoUJc,1091
|
4
|
-
ode2tn-1.0.0.dist-info/METADATA,sha256=UQ7FvLFnOyzWs9qK3fS8NZtsVxd8ESDwT3_QdHpl-cE,4198
|
5
|
-
ode2tn-1.0.0.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
6
|
-
ode2tn-1.0.0.dist-info/top_level.txt,sha256=fPQ9s5yLIYfazJS7wBBfU9EsWa9RGALq8VL-wUYRlao,7
|
7
|
-
ode2tn-1.0.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|