ode2tn 1.0.0__py3-none-any.whl → 1.0.2__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
@@ -10,13 +10,14 @@ 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,
17
17
  beta: float,
18
18
  scale: float = 1.0,
19
19
  t_span: tuple[float, float] | None = None,
20
+ show_factors: bool = False,
20
21
  resets: dict[float, dict[sp.Symbol | str, float]] | None = None,
21
22
  dependent_symbols: dict[sp.Symbol | str, sp.Expr | str] | None = None,
22
23
  figure_size: tuple[float, float] = (10, 3),
@@ -54,6 +55,12 @@ def plot_tn(
54
55
  scale: "scaling factor" for the transcription network ODEs. Each variable `x` is replaced by a pair
55
56
  (`x_top`, `x_bot`). The initial `x_bot` value is `scale`, and the initial `x_top` value is
56
57
  `x*scale`.
58
+ show_factors: if True, then in addition to plotting the ratios x_top/x_bot,
59
+ also plot the factors x_top and x_bot separately in a second plot.
60
+ Mutually exlusive with `symbols_to_plot`, since it is equivalent to setting
61
+ `symbols_to_plot` to ``[ratios, factors]``, where ratios is a list of dependent symbols
62
+ `x=x_top/x_bot`, and factors is a list of symbols with the transcription factors `x_top`, `x_bot`,
63
+ for each original variable `x`.
57
64
  resets:
58
65
  If specified, this is a dict mapping times to "configurations"
59
66
  (i.e., dict mapping symbols/str to values).
@@ -77,44 +84,25 @@ def plot_tn(
77
84
  Typically None, but if return_ode_result is True, returns the result of the ODE integration.
78
85
  See documentation of `gpac.plot` for details.
79
86
  """
80
- tn_odes, tn_inits, tn_ratios = ode2tn(odes, initial_values, gamma=gamma, beta=beta, scale=scale)
87
+ if show_factors and symbols_to_plot is not None:
88
+ raise ValueError("Cannot use both show_factors and symbols_to_plot at the same time.")
89
+
90
+ tn_odes, tn_inits, tn_syms = ode2tn(odes, initial_values, gamma=gamma, beta=beta, scale=scale)
81
91
  dependent_symbols_tn = dict(dependent_symbols) if dependent_symbols is not None else {}
92
+ tn_ratios = {sym: sym_t/sym_b for sym, (sym_t, sym_b) in tn_syms.items()}
82
93
  dependent_symbols_tn.update(tn_ratios)
83
94
  symbols_to_plot = dependent_symbols_tn if symbols_to_plot is None else symbols_to_plot
84
95
 
96
+ if show_factors:
97
+ symbols_to_plot = [symbols_to_plot, [factor for pair in tn_syms.values() for factor in pair]]
98
+
99
+ legend = {}
100
+ for sym, (sym_t, sym_b) in tn_syms.items():
101
+ legend[sym_t] = f'${sym}^\\top$'
102
+ legend[sym_b] = f'${sym}^\\bot$'
103
+
85
104
  if resets is not None:
86
- # make copy since we are going to change it
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]
105
+ resets = update_resets_with_ratios(odes, resets, tn_odes, tn_syms, scale)
118
106
 
119
107
  return gp.plot(
120
108
  odes=tn_odes,
@@ -125,6 +113,7 @@ def plot_tn(
125
113
  resets=resets,
126
114
  figure_size=figure_size,
127
115
  symbols_to_plot=symbols_to_plot,
116
+ legend=legend,
128
117
  show=show,
129
118
  method=method,
130
119
  dense_output=dense_output,
@@ -137,14 +126,51 @@ def plot_tn(
137
126
  )
138
127
 
139
128
 
129
+ def update_resets_with_ratios(odes, resets, tn_odes, tn_syms, scale: float = 1.0) -> dict[float, dict[sp.Symbol, float]]:
130
+ tn_ratios = {sym: sym_t / sym_b for sym, (sym_t, sym_b) in tn_syms.items()}
131
+ # make copy since we are going to change it
132
+ new_resets = {}
133
+ for time, reset in resets.items():
134
+ new_resets[time] = {}
135
+ for x, val in reset.items():
136
+ new_resets[time][x] = val
137
+ resets = new_resets
138
+ # normalize resets keys and check that variables are valid
139
+ for reset in resets.values():
140
+ for x, val in reset.items():
141
+ if isinstance(x, str):
142
+ del reset[x]
143
+ x = sp.symbols(x)
144
+ reset[x] = val
145
+ if x not in odes.keys() and x not in tn_odes.keys():
146
+ raise ValueError(f"Symbol {x} not found in original variables: {', '.join(odes.keys())},\n"
147
+ f"nor found in transcription network variables: {', '.join(tn_odes.keys())}")
148
+ # ensure if original variable x is in resets, then neither x_top nor x_bot are in the resets
149
+ # and substitute x_top and x_bot for x in resets
150
+ for x, ratio in tn_ratios.items():
151
+ # x is an original; so make sure neither x_top nor x_bot are in the reset dict
152
+ if x in reset:
153
+ xt, xb = sp.fraction(ratio)
154
+ if xt in reset:
155
+ raise ValueError(f'Cannot use "top" variable {xt} in resets '
156
+ f'if original variable {x} is also used')
157
+ if xb in reset:
158
+ raise ValueError(f'Cannot use "bottom" variable {xb} in resets '
159
+ f'if original variable {x} is also used')
160
+ reset[xt] = reset[x] * scale
161
+ reset[xb] = scale
162
+ del reset[x]
163
+ return resets
164
+
165
+
140
166
  def ode2tn(
141
167
  odes: dict[sp.Symbol | str, sp.Expr | str | float],
142
- initial_values: dict[sp.Symbol | str, float],
168
+ initial_values: dict[sp.Symbol | str | gp.Specie, float],
143
169
  *,
144
170
  gamma: float,
145
171
  beta: float,
146
172
  scale: float = 1.0,
147
- ) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, sp.Expr]]:
173
+ ) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, tuple[sp.Symbol, sp.Symbol]]]:
148
174
  """
149
175
  Maps polynomial ODEs and and initial values to transcription network (represented by ODEs with positive
150
176
  Laurent polynomials and negative linear term) simulating it, as well as initial values.
@@ -155,7 +181,8 @@ def ode2tn(
155
181
  (representing RHS of ODEs)
156
182
  Raises ValueError if any of the ODEs RHS is not a polynomial
157
183
  initial_values: initial values,
158
- dict of sympy symbols or strings (representing symbols) to floats
184
+ dict of sympy symbols or strings (representing symbols) or gpac.Specie (representing chemical
185
+ species, if the ODEs were derived from `gpac.crn_to_odes`) to floats
159
186
  gamma: coefficient of the negative linear term in the transcription network
160
187
  beta: additive constant in x_top ODE
161
188
  scale: "scaling factor" for the transcription network ODEs. Each variable `x` is replaced by a pair
@@ -163,15 +190,21 @@ def ode2tn(
163
190
  `x*scale`.
164
191
 
165
192
  Return:
166
- triple (`tn_odes`, `tn_inits`, `tn_ratios`), where `tn_ratios` is a dict mapping each original symbol ``x``
167
- in the original ODEs to the sympy.Expr ``x_top / x_bot``.
193
+ triple (`tn_odes`, `tn_inits`, `tn_syms`), where `tn_syms` is a dict mapping each original symbol ``x``
194
+ in the original ODEs to the pair ``(x_top, x_bot)``.
168
195
  """
169
196
  # normalize initial values dict to use symbols as keys
170
- initial_values = {sp.Symbol(symbol) if isinstance(symbol, str) else symbol: value
171
- for symbol, value in initial_values.items()}
197
+ initial_values_norm = {}
198
+ for symbol, value in initial_values.items():
199
+ if isinstance(symbol, str):
200
+ symbol = sp.symbols(symbol)
201
+ if isinstance(symbol, gp.Specie):
202
+ symbol = sp.symbols(symbol.name)
203
+ initial_values_norm[symbol] = value
204
+ initial_values = initial_values_norm
172
205
 
173
206
  # normalize odes dict to use symbols as keys
174
- odes_symbols = {}
207
+ odes_normalized = {}
175
208
  symbols_found_in_expressions = set()
176
209
  for symbol, expr in odes.items():
177
210
  if isinstance(symbol, str):
@@ -179,11 +212,12 @@ def ode2tn(
179
212
  if isinstance(expr, (str, int, float)):
180
213
  expr = sp.sympify(expr)
181
214
  symbols_found_in_expressions.update(expr.free_symbols)
182
- odes_symbols[symbol] = expr
215
+ odes_normalized[symbol] = expr
216
+ odes = odes_normalized
183
217
 
184
218
  # ensure that all symbols that are keys in `initial_values` are also keys in `odes`
185
219
  initial_values_keys = set(initial_values.keys())
186
- odes_keys = set(odes_symbols.keys())
220
+ odes_keys = set(odes.keys())
187
221
  diff = initial_values_keys - odes_keys
188
222
  if len(diff) > 0:
189
223
  raise ValueError(f"\nInitial_values contains symbols that are not in odes: "
@@ -199,7 +233,7 @@ def ode2tn(
199
233
  f"The keys in the odes dict are: {odes_keys}")
200
234
 
201
235
  # ensure all odes are polynomials
202
- for symbol, expr in odes_symbols.items():
236
+ for symbol, expr in odes_normalized.items():
203
237
  if not expr.is_polynomial():
204
238
  raise ValueError(f"ODE for {symbol}' is not a polynomial: {expr}")
205
239
 
@@ -213,16 +247,14 @@ def normalized_ode2tn(
213
247
  gamma: float,
214
248
  beta: float,
215
249
  scale: float,
216
- ) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, sp.Expr]]:
250
+ ) -> tuple[dict[sp.Symbol, sp.Expr], dict[sp.Symbol, float], dict[sp.Symbol, tuple[sp.Symbol, sp.Symbol]]]:
217
251
  # Assumes ode2tn has normalized and done error-checking
218
252
 
219
- sym2pair: dict[sp.Symbol, tuple[sp.Symbol, sp.Symbol]] = {}
220
- tn_ratios: dict[sp.Symbol, sp.Expr] = {}
253
+ tn_syms: dict[sp.Symbol, tuple[sp.Symbol, sp.Symbol]] = {}
221
254
  for x in odes.keys():
222
255
  # create x_t, x_b for each symbol x
223
- x_top, x_bot = sp.symbols(f'{x}_t {x}_b')
224
- sym2pair[x] = (x_top, x_bot)
225
- tn_ratios[x] = x_top / x_bot
256
+ x_t, x_b = sp.symbols(f'{x}_t {x}_b')
257
+ tn_syms[x] = (x_t, x_b)
226
258
 
227
259
  tn_odes: dict[sp.Symbol, sp.Expr] = {}
228
260
  tn_inits: dict[sp.Symbol, float] = {}
@@ -231,19 +263,20 @@ def normalized_ode2tn(
231
263
 
232
264
  # replace sym with sym_top / sym_bot for each original symbol sym
233
265
  for sym in odes.keys():
234
- sym_top, sym_bot = sym2pair[sym]
235
- p_pos = p_pos.subs(sym, sym_top / sym_bot)
236
- p_neg = p_neg.subs(sym, sym_top / sym_bot)
266
+ sym_top, sym_bot = tn_syms[sym]
267
+ ratio = sym_top / sym_bot
268
+ p_pos = p_pos.subs(sym, ratio)
269
+ p_neg = p_neg.subs(sym, ratio)
237
270
 
238
- x_top, x_bot = sym2pair[x]
271
+ x_t, x_b = tn_syms[x]
239
272
  # tn_odes[x_top] = beta + p_pos * x_bot - gamma * x_top
240
273
  # tn_odes[x_bot] = p_neg * x_bot ** 2 / x_top + beta * x_bot / x_top - gamma * x_bot
241
- tn_odes[x_top] = beta * x_top / x_bot + p_pos * x_bot - gamma * x_top
242
- tn_odes[x_bot] = beta + p_neg * x_bot ** 2 / x_top - gamma * x_bot
243
- tn_inits[x_top] = initial_values[x]*scale
244
- tn_inits[x_bot] = scale
274
+ tn_odes[x_t] = beta * x_t / x_b + p_pos * x_b - gamma * x_t
275
+ tn_odes[x_b] = beta + p_neg * x_b ** 2 / x_t - gamma * x_b
276
+ tn_inits[x_t] = initial_values.get(x, 0) * scale
277
+ tn_inits[x_b] = scale
245
278
 
246
- return tn_odes, tn_inits, tn_ratios
279
+ return tn_odes, tn_inits, tn_syms
247
280
 
248
281
 
249
282
  def split_polynomial(expr: sp.Expr) -> tuple[sp.Expr, sp.Expr]:
@@ -297,7 +330,7 @@ def split_polynomial(expr: sp.Expr) -> tuple[sp.Expr, sp.Expr]:
297
330
  else:
298
331
  # For negative coefficients, add the negated term to p2
299
332
  p_neg += -term
300
- elif expanded.is_Mul:
333
+ elif expanded.is_Mul or expanded.is_Pow:
301
334
  # If it's a single term, just check the sign; is_Mul for things like x*y or -x (represented as -1*x)
302
335
  coeff = next((arg for arg in expanded.args if arg.is_number), 1)
303
336
  if coeff > 0:
@@ -324,60 +357,22 @@ def comma_separated(elts: Iterable[Any]) -> str:
324
357
 
325
358
 
326
359
  def main():
327
- x_sp, y_sp = gp.species('x y')
328
- rxns = [
329
- x_sp >> x_sp + y_sp,
330
- (3 * y_sp | 2 * y_sp).k(11).r(16.5),
331
- (y_sp >> gp.empty).k(6.5),
332
- ]
360
+ import gpac as gp
361
+ import numpy as np
362
+ import sympy as sp
363
+ from ode2tn import plot_tn
364
+
365
+ x = gp.species('X')
366
+ rxns = [2 * x >> 3 * x]
333
367
  odes = gp.crn_to_odes(rxns)
334
- # extract symbols from odes
335
- for var in odes.keys():
336
- if var.name == 'x':
337
- x = var
338
- if var.name == 'y':
339
- y = var
340
- # for v,ode in odes.items():
341
- # print(f"{v}' = {ode}")
342
- inits = {
343
- x: 1,
344
- y: 0.5,
345
- }
346
- gamma = 20
368
+ inits = {x: 1}
369
+ t_eval = np.linspace(0, 1, 100)
370
+ gamma = 1
347
371
  beta = 1
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
- resets = {
373
- 5: {x: 0.5},
374
- 10: {x: 0.01},
375
- 15: {x: 0.5},
376
- }
377
- scale = 0.1
378
- plot_tn(odes, inits, gamma=gamma, beta=beta, scale=scale,
379
- t_eval=t_eval, resets=resets, figure_size=figsize,
380
- symbols_to_plot=[[x, y], [xt, xb, yt, yb]])
372
+ # figsize = (16,4)
373
+
374
+ # gp.plot_crn(rxns, inits, t_eval, figure_size=figsize)
375
+ plot_tn(odes, inits, t_eval, gamma=gamma, beta=beta)
381
376
 
382
377
 
383
378
  if __name__ == '__main__':
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ode2tn
3
- Version: 1.0.0
3
+ Version: 1.0.2
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
@@ -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 turn arbitrary polynomial ODEs into a transcriptional network simulating it.
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,7 @@ 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, tn_ratios = 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_ratios=}')
61
- plot_tn(odes, inits, gamma, beta, t_eval=t_eval)
56
+ plot_tn(odes, inits, gamma=gamma, beta=beta, t_eval=t_eval, show_factors=True)
62
57
  ```
63
58
 
64
59
  This will print
@@ -69,14 +64,14 @@ x_b' = 2*x_b**2/x_t - 2*x_b + 1
69
64
  y_t' = 2*y_b - 2*y_t + y_t/y_b
70
65
  y_b' = -2*y_b + 1 + x_t*y_b**2/(x_b*y_t)
71
66
  tn_inits={x_t: 2, x_b: 1, y_t: 1, y_b: 1}
72
- tn_ratios={x: x_t/x_b, y: y_t/y_b}
67
+ tn_syms={x: (x_t, x_b), y: (y_t, y_b)}
73
68
  ```
74
69
 
75
70
  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
71
  The function `plot_tn` above does this conversion and then plots the ratios.
77
72
  Running the code above in a Jupyter notebook will print the above text and show this figure:
78
73
 
79
- ![](sine-cosine-plot.png)
74
+ ![](sine-cosine-plot.svg)
80
75
 
81
76
  One could also hand the transcriptional network ODEs to gpac to integrate, if you want to directly access the data being plotted above.
82
77
  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`:
@@ -85,20 +80,20 @@ The `OdeResult` object returned by `gpac.integrate_odes` is the same returned by
85
80
  t_eval = np.linspace(0, 2*pi, 5)
86
81
  sol = gp.integrate_odes(tn_odes, tn_inits, t_eval)
87
82
  print(f'times = {sol.t}')
88
- print(f'x_y = {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]}')
83
+ print(f'x_t = {sol.y[0]}')
84
+ print(f'x_b = {sol.y[1]}')
85
+ print(f'y_t = {sol.y[2]}')
86
+ print(f'y_b = {sol.y[3]}')
92
87
  ```
93
88
 
94
89
  which would print
95
90
 
96
91
  ```
97
92
  times = [0. 1.57079633 3.14159265 4.71238898 6.28318531]
98
- x_y = [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]
93
+ x_t = [2. 1.78280757 3.67207594 2.80592514 1.71859172]
94
+ x_b = [1. 1.78425369 1.83663725 0.93260227 0.859926 ]
95
+ y_t = [1. 1.87324904 2.14156469 2.10338162 2.74383426]
96
+ y_b = [1. 0.93637933 0.71348949 1.05261915 2.78279691]
102
97
  ```
103
98
 
104
99
 
@@ -0,0 +1,7 @@
1
+ ode2tn/__init__.py,sha256=b_mINIsNfCWzgG7QVYMsRsWKDLvp2QKFAzRqWtYqwDA,30
2
+ ode2tn/transform.py,sha256=8gQVHaCRTdiACQPZdkB3OPfc2KOZTA3YwMgbXDDnNkE,16155
3
+ ode2tn-1.0.2.dist-info/licenses/LICENSE,sha256=VV9UH0kkG-2edZvwJOqgtN12bZIzs2vn9_cq1SjoUJc,1091
4
+ ode2tn-1.0.2.dist-info/METADATA,sha256=MSGeKttEB-ImlNvBof07AeyxR1rOCBf48tUNinaIgS0,4095
5
+ ode2tn-1.0.2.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
6
+ ode2tn-1.0.2.dist-info/top_level.txt,sha256=fPQ9s5yLIYfazJS7wBBfU9EsWa9RGALq8VL-wUYRlao,7
7
+ ode2tn-1.0.2.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=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,,