guts-base 0.8.4__py3-none-any.whl → 0.8.6__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 guts-base might be problematic. Click here for more details.
- guts_base/__init__.py +1 -1
- guts_base/data/generator.py +4 -4
- guts_base/mod.py +6 -0
- guts_base/sim/base.py +86 -24
- guts_base/sim/ecx.py +63 -21
- guts_base/sim/report.py +9 -8
- {guts_base-0.8.4.dist-info → guts_base-0.8.6.dist-info}/METADATA +3 -3
- {guts_base-0.8.4.dist-info → guts_base-0.8.6.dist-info}/RECORD +12 -12
- {guts_base-0.8.4.dist-info → guts_base-0.8.6.dist-info}/WHEEL +0 -0
- {guts_base-0.8.4.dist-info → guts_base-0.8.6.dist-info}/entry_points.txt +0 -0
- {guts_base-0.8.4.dist-info → guts_base-0.8.6.dist-info}/licenses/LICENSE +0 -0
- {guts_base-0.8.4.dist-info → guts_base-0.8.6.dist-info}/top_level.txt +0 -0
guts_base/__init__.py
CHANGED
guts_base/data/generator.py
CHANGED
|
@@ -67,7 +67,8 @@ def design_exposure_scenario(
|
|
|
67
67
|
"""
|
|
68
68
|
TODO: tmax, dt and eps are probably not necessary
|
|
69
69
|
"""
|
|
70
|
-
|
|
70
|
+
# add dt so that tmax is definitely inclded
|
|
71
|
+
time = np.arange(0, t_max+dt, step=dt) # daily time resolution
|
|
71
72
|
time = np.unique(np.concatenate([time] + [
|
|
72
73
|
np.array([time[-1] if vals["end"] is None else vals["end"]])
|
|
73
74
|
for key, vals in exposures.items()
|
|
@@ -79,13 +80,12 @@ def design_exposure_scenario(
|
|
|
79
80
|
treat = design_exposure_timeseries(time, expo, eps)
|
|
80
81
|
treatments.update({key: treat})
|
|
81
82
|
|
|
82
|
-
data = np.column_stack(list(treatments.values()))
|
|
83
|
+
data = np.column_stack(list(treatments.values()))
|
|
83
84
|
data = np.expand_dims(data, axis=0)
|
|
84
85
|
|
|
85
86
|
coords = {"id": [0], "time": time}
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
coords.update({exposure_dimension: list(treatments.keys())})
|
|
88
|
+
coords.update({exposure_dimension: list(treatments.keys())})
|
|
89
89
|
|
|
90
90
|
exposures_dataset = xr.Dataset(
|
|
91
91
|
data_vars={"exposure": (tuple(coords.keys()), data)},
|
guts_base/mod.py
CHANGED
|
@@ -32,7 +32,13 @@ from mempy.model import (
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
red_sd = RED_SD._rhs_jax
|
|
35
|
+
red_sd_post_processing = RED_SD._solver_post_processing
|
|
36
|
+
|
|
35
37
|
red_it = RED_IT._rhs_jax
|
|
38
|
+
red_it_post_processing = RED_IT._solver_post_processing
|
|
39
|
+
|
|
40
|
+
red_sd_ia = RED_SD_IA._rhs_jax
|
|
41
|
+
red_sd_ia_post_processing = RED_SD_IA._solver_post_processing
|
|
36
42
|
|
|
37
43
|
|
|
38
44
|
def p_survival(results, t, interpolation, z, k_k, h_b):
|
guts_base/sim/base.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import glob
|
|
3
|
+
from functools import partial
|
|
4
|
+
from copy import deepcopy
|
|
3
5
|
import warnings
|
|
4
6
|
import numpy as np
|
|
5
7
|
import xarray as xr
|
|
@@ -13,6 +15,7 @@ from pymob.sim.config import DataVariable, Param, string_to_list
|
|
|
13
15
|
|
|
14
16
|
from pymob.solvers import JaxSolver
|
|
15
17
|
from pymob.solvers.base import rect_interpolation
|
|
18
|
+
from pymob.sim.config import ParameterDict
|
|
16
19
|
from expyDB.intervention_model import (
|
|
17
20
|
Treatment, Timeseries, select, from_expydb
|
|
18
21
|
)
|
|
@@ -24,7 +27,6 @@ from guts_base.data import (
|
|
|
24
27
|
)
|
|
25
28
|
from guts_base.sim.report import GutsReport
|
|
26
29
|
|
|
27
|
-
|
|
28
30
|
class GutsBase(SimulationBase):
|
|
29
31
|
"""
|
|
30
32
|
Initializes GUTS models from a variety of data sources
|
|
@@ -36,15 +38,15 @@ class GutsBase(SimulationBase):
|
|
|
36
38
|
"""
|
|
37
39
|
solver = JaxSolver
|
|
38
40
|
Report = GutsReport
|
|
39
|
-
unit_time: Literal["day", "hour", "minute", "second"] = "day"
|
|
40
|
-
results_interpolation: Optional[List[float|int]] = [np.nan, np.nan, 100]
|
|
41
|
-
ecx_mode: Literal["mean", "draws"] = "mean"
|
|
42
41
|
|
|
43
42
|
def initialize(self, input: Dict = None):
|
|
43
|
+
self.ecx_mode: Literal["mean", "draws"] = "mean"
|
|
44
44
|
|
|
45
|
+
self.unit_time: Literal["day", "hour", "minute", "second"] = "day"
|
|
45
46
|
if hasattr(self.config.simulation, "unit_time"):
|
|
46
47
|
self.unit_time = self.config.simulation.unit_time # type: ignore
|
|
47
48
|
|
|
49
|
+
self.results_interpolation: Optional[List[float|int]] = [np.nan, np.nan, 100]
|
|
48
50
|
if hasattr(self.config.simulation, "results_interpolation"):
|
|
49
51
|
self.results_interpolation = string_to_list(self.config.simulation.results_interpolation)
|
|
50
52
|
self.results_interpolation[0] = float(self.results_interpolation[0])
|
|
@@ -229,6 +231,9 @@ class GutsBase(SimulationBase):
|
|
|
229
231
|
"""This function interpolates the posterior with a given resolution
|
|
230
232
|
posterior_predictions calculate proper survival predictions for the
|
|
231
233
|
posterior.
|
|
234
|
+
|
|
235
|
+
It also makes sure that the new interpolation does not include fewer values
|
|
236
|
+
than the original dataset
|
|
232
237
|
"""
|
|
233
238
|
|
|
234
239
|
if np.isnan(self.results_interpolation[0]):
|
|
@@ -244,8 +249,15 @@ class GutsBase(SimulationBase):
|
|
|
244
249
|
stop=self.results_interpolation[1],
|
|
245
250
|
num=self.results_interpolation[2]
|
|
246
251
|
)
|
|
252
|
+
|
|
253
|
+
# combine original coordinates and interpolation. This
|
|
254
|
+
# a) helps error checking during posterior predictions.
|
|
255
|
+
# b) makes sure that the original time vector is retained, which may be
|
|
256
|
+
# relevant for the simulation success (e.g. IT model)
|
|
247
257
|
self.observations = self.observations.reindex(
|
|
248
|
-
time=
|
|
258
|
+
time=np.unique(np.concatenate(
|
|
259
|
+
[time_interpolate, self.observations["time"]]
|
|
260
|
+
))
|
|
249
261
|
)
|
|
250
262
|
|
|
251
263
|
self.dispatch_constructor()
|
|
@@ -272,35 +284,85 @@ class GutsBase(SimulationBase):
|
|
|
272
284
|
|
|
273
285
|
def copy(self):
|
|
274
286
|
with warnings.catch_warnings(action="ignore"):
|
|
275
|
-
sim_copy = type(self)(self.config)
|
|
276
|
-
sim_copy.observations = self.observations
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
287
|
+
sim_copy = type(self)(self.config.copy(deep=True))
|
|
288
|
+
sim_copy.observations = self.observations.copy(deep=True)
|
|
289
|
+
|
|
290
|
+
# must copy individual parts of the dict due to the on_update method
|
|
291
|
+
model_parameters = {k: deepcopy(v) for k, v in self.model_parameters.items()}
|
|
292
|
+
|
|
293
|
+
# TODO: Refactor this once the parameterize method is removed.
|
|
294
|
+
sim_copy.parameterize = partial(sim_copy.parameterize, model_parameters=model_parameters)
|
|
295
|
+
sim_copy._model_parameters = ParameterDict(model_parameters, callback=sim_copy._on_params_updated)
|
|
296
|
+
|
|
297
|
+
sim_copy.load_modules()
|
|
298
|
+
if hasattr(self, "inferer"):
|
|
299
|
+
sim_copy.inferer = type(self.inferer)(sim_copy)
|
|
300
|
+
# idata uses deepcopy by default
|
|
301
|
+
sim_copy.inferer.idata = self.inferer.idata.copy()
|
|
281
302
|
sim_copy.model = self.model
|
|
282
303
|
sim_copy.solver_post_processing = self.solver_post_processing
|
|
283
|
-
sim_copy.load_modules()
|
|
284
304
|
|
|
285
305
|
return sim_copy
|
|
286
|
-
|
|
287
306
|
|
|
288
|
-
@property
|
|
289
307
|
def predefined_scenarios(self):
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
308
|
+
"""
|
|
309
|
+
TODO: Fix timescale to observations
|
|
310
|
+
TODO: Incorporate extra exposure patterns (constant, pulse_1day, pulse_2day)
|
|
311
|
+
"""
|
|
312
|
+
# get the maximum possible time to provide exposure scenarios that are definitely
|
|
313
|
+
# long enough
|
|
314
|
+
time_max = max(
|
|
315
|
+
self.observations[self.config.simulation.x_dimension].max(),
|
|
316
|
+
*self.Report.ecx_estimates_times
|
|
298
317
|
)
|
|
299
318
|
|
|
300
|
-
|
|
301
|
-
|
|
319
|
+
# this produces a exposure x_in dataset with only the dimensions ID and TIME
|
|
320
|
+
standard_dimensions = (
|
|
321
|
+
self.config.simulation.batch_dimension,
|
|
322
|
+
self.config.simulation.x_dimension,
|
|
302
323
|
)
|
|
303
324
|
|
|
325
|
+
# get dimensions different from standard dimensions
|
|
326
|
+
exposure_dimension = [
|
|
327
|
+
d for d in self.observations.exposure.dims if d not in
|
|
328
|
+
standard_dimensions
|
|
329
|
+
]
|
|
330
|
+
|
|
331
|
+
# raise an error if the number of extra dimensions is larger than 1
|
|
332
|
+
if len(exposure_dimension) > 1:
|
|
333
|
+
raise ValueError(
|
|
334
|
+
f"{type(self).__name__} can currently handle one additional dimension for "+
|
|
335
|
+
f"the exposure beside {standard_dimensions}. You provided an exposure "+
|
|
336
|
+
f"array with the dimensions: {self.observations.exposure.dims}"
|
|
337
|
+
)
|
|
338
|
+
else:
|
|
339
|
+
exposure_dimension = exposure_dimension[0]
|
|
340
|
+
|
|
341
|
+
# iterate over the coordinates of the exposure dimensions to
|
|
342
|
+
exposure_coordinates = self.observations.exposure[exposure_dimension].values
|
|
343
|
+
|
|
344
|
+
scenarios = {}
|
|
345
|
+
for coord in exposure_coordinates:
|
|
346
|
+
concentrations = np.where(coord == exposure_coordinates, 1, 0)
|
|
347
|
+
|
|
348
|
+
exposure_dict = {
|
|
349
|
+
coord: dict(start=0.0, end=1.0, concentration=conc)
|
|
350
|
+
for coord, conc in zip(exposure_coordinates, concentrations)
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
scenario = design_exposure_scenario(
|
|
354
|
+
exposures=exposure_dict,
|
|
355
|
+
t_max=time_max,
|
|
356
|
+
dt=1/24,
|
|
357
|
+
exposure_dimension=exposure_dimension
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
scenarios.update({
|
|
361
|
+
f"1day_exposure_{coord}": scenario
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
return scenarios
|
|
365
|
+
|
|
304
366
|
def expand_batch_like_coordinate_to_new_dimension(self, coordinate, variables):
|
|
305
367
|
"""This method will take an existing coordinate of a dataset that has the same
|
|
306
368
|
coordinate has the batch dimension. It will then re-express the coordinate as a
|
guts_base/sim/ecx.py
CHANGED
|
@@ -37,23 +37,32 @@ class ECxEstimator:
|
|
|
37
37
|
else:
|
|
38
38
|
self.sim.coordinates["id"] = [id]
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
# ensure correct coordinate order with x_in and raise errors early
|
|
41
|
+
self.sim.model_parameters["x_in"] = self.sim.parse_input("x_in", x_in)
|
|
41
42
|
|
|
42
|
-
# self.sim.observations = self.sim.expand_batch_like_coordinate_to_new_dimension(
|
|
43
|
-
# coordinate="exposure_path",
|
|
44
|
-
# variables=["Flupyradifurone"]
|
|
45
|
-
# )
|
|
46
|
-
|
|
47
|
-
# self.sim.config.data_structure.remove("Flupyradifurone")
|
|
48
|
-
|
|
49
|
-
# # TODO: COnstruct a sim if the input dims change
|
|
50
|
-
# self.sim.config.data_structure.exposure.dimensions = ["id", "time", "exposure_path"]
|
|
51
43
|
self.sim.config.data_structure.survival.observed = False
|
|
52
44
|
self.sim.observations = self.sim.observations.sel(id=self.sim.coordinates["id"])
|
|
53
45
|
|
|
46
|
+
# fix time after observations have been set. The outcome of the simulation
|
|
47
|
+
# can dependend on the time vector, because in e.g. IT models, the time resolution
|
|
48
|
+
# is important. Therefore the time at which the ECx is computed is just inserted
|
|
49
|
+
# into the time vector at the right position.
|
|
50
|
+
self.sim.coordinates["time"] = np.unique(np.concatenate([
|
|
51
|
+
self.sim.coordinates["time"], np.array(time, ndmin=1)
|
|
52
|
+
]))
|
|
53
|
+
|
|
54
54
|
self.sim.model_parameters["y0"] = self.sim.parse_input("y0", drop_dims="time")
|
|
55
55
|
self.sim.dispatch_constructor()
|
|
56
56
|
|
|
57
|
+
self.results = pd.Series({
|
|
58
|
+
"mean": np.nan,
|
|
59
|
+
"q05": np.nan,
|
|
60
|
+
"q95": np.nan,
|
|
61
|
+
"std": np.nan,
|
|
62
|
+
"cv": np.nan,
|
|
63
|
+
"msg": np.nan
|
|
64
|
+
})
|
|
65
|
+
|
|
57
66
|
|
|
58
67
|
|
|
59
68
|
def _evaluate(self, factor, theta):
|
|
@@ -114,6 +123,7 @@ class ECxEstimator:
|
|
|
114
123
|
accept_tol: float = 1e-5,
|
|
115
124
|
optimizer_tol: float = 1e-5,
|
|
116
125
|
method: str = "cobyla",
|
|
126
|
+
show_plot: bool = True,
|
|
117
127
|
**optimizer_kwargs
|
|
118
128
|
):
|
|
119
129
|
"""The minimizer for the EC_x operates on the unbounded linear scale, estimating
|
|
@@ -163,6 +173,9 @@ class ECxEstimator:
|
|
|
163
173
|
method : str
|
|
164
174
|
Minization algorithm. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html
|
|
165
175
|
Default: 'cobyla'
|
|
176
|
+
|
|
177
|
+
show_plot : bool
|
|
178
|
+
Show the results plot of the lpx. Default: True
|
|
166
179
|
|
|
167
180
|
optimizer_kwargs :
|
|
168
181
|
Additional arguments to pass to the optimizer
|
|
@@ -184,9 +197,18 @@ class ECxEstimator:
|
|
|
184
197
|
)
|
|
185
198
|
else:
|
|
186
199
|
pass
|
|
200
|
+
|
|
201
|
+
warnings.warn(
|
|
202
|
+
"Values passed to 'parameters' don't have an effect in mode='draws'"
|
|
203
|
+
)
|
|
187
204
|
|
|
188
205
|
elif mode == "mean":
|
|
189
206
|
draws = 1
|
|
207
|
+
|
|
208
|
+
warnings.warn(
|
|
209
|
+
"Values passed to 'parameters' don't have an effect in mode='draws'"
|
|
210
|
+
)
|
|
211
|
+
|
|
190
212
|
elif mode == "manual":
|
|
191
213
|
draws = 1
|
|
192
214
|
if parameters is None:
|
|
@@ -226,6 +248,7 @@ class ECxEstimator:
|
|
|
226
248
|
)
|
|
227
249
|
|
|
228
250
|
success = opt_res.fun < accept_tol
|
|
251
|
+
iteration += 1
|
|
229
252
|
|
|
230
253
|
# convert to linear scale from log scale
|
|
231
254
|
factor = np.exp(opt_res.x)
|
|
@@ -235,24 +258,43 @@ class ECxEstimator:
|
|
|
235
258
|
loss.append(opt_res.fun)
|
|
236
259
|
|
|
237
260
|
res_full = pd.DataFrame(dict(factor = mult_factor, loss=loss, retries=iterations))
|
|
238
|
-
|
|
261
|
+
self.results_full = res_full
|
|
262
|
+
|
|
263
|
+
metric = "{name}_{x}".format(name=self._name, x=int(self.x * 100),)
|
|
264
|
+
|
|
265
|
+
successes = sum(res_full.loss < accept_tol)
|
|
266
|
+
if successes < draws:
|
|
239
267
|
warnings.warn(
|
|
240
|
-
f"Not all optimizations converged on the {
|
|
268
|
+
f"Not all optimizations converged on the {metric} ({successes/draws*100}%). " +
|
|
241
269
|
"Adjust starting values and method")
|
|
242
270
|
print(res_full)
|
|
271
|
+
|
|
272
|
+
short_msg = f"Estimation success rate: {successes/draws*100}%"
|
|
273
|
+
self.results["msg"] = short_msg
|
|
243
274
|
|
|
244
275
|
res = res_full.loc[res_full.loss < accept_tol,:]
|
|
245
276
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
277
|
+
if len(res) == 0:
|
|
278
|
+
self.msg = (
|
|
279
|
+
f"{metric} could not be found. Two reasons typically cause this problem: "+
|
|
280
|
+
f"1) no expoure before the time at which the {metric} is calculated. "+
|
|
281
|
+
"Check the the exposure profile. " +
|
|
282
|
+
f"2) Too high background mortality. If the time at which the {metric} is "+
|
|
283
|
+
f"calculated is large and background mortality is high, the {metric}, " +
|
|
284
|
+
"may be reached independent of the effect and optimization cannot succeed."
|
|
285
|
+
)
|
|
253
286
|
|
|
254
|
-
|
|
255
|
-
|
|
287
|
+
print(self.msg)
|
|
288
|
+
return
|
|
289
|
+
|
|
290
|
+
self.results["mean"] = np.round(np.mean(res.factor.values), 4)
|
|
291
|
+
self.results["q05"] = np.round(np.quantile(res.factor.values, 0.05), 4)
|
|
292
|
+
self.results["q95"] = np.round(np.quantile(res.factor.values, 0.95), 4)
|
|
293
|
+
self.results["std"] = np.round(np.std(res.factor.values), 4)
|
|
294
|
+
self.results["cv"] = np.round(np.std(res.factor.values)/np.mean(res.factor.values), 2)
|
|
295
|
+
|
|
296
|
+
if show_plot:
|
|
297
|
+
self.plot_profile_and_effect(parameters=parameters)
|
|
256
298
|
|
|
257
299
|
print("{name}_{x}".format(name=self._name, x=int(self.x * 100),))
|
|
258
300
|
print(self.results)
|
guts_base/sim/report.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import itertools as it
|
|
3
|
+
from typing import List
|
|
3
4
|
import pandas as pd
|
|
4
5
|
|
|
5
6
|
from pymob import SimulationBase
|
|
@@ -9,6 +10,8 @@ from guts_base.plot import plot_survival_multipanel
|
|
|
9
10
|
from guts_base.sim.ecx import ECxEstimator
|
|
10
11
|
|
|
11
12
|
class GutsReport(Report):
|
|
13
|
+
ecx_estimates_times: List = [1, 2, 4, 10]
|
|
14
|
+
ecx_estimates_x: List = [0.1, 0.25, 0.5, 0.75, 0.9]
|
|
12
15
|
|
|
13
16
|
def additional_reports(self, sim: "SimulationBase"):
|
|
14
17
|
super().additional_reports(sim=sim)
|
|
@@ -33,9 +36,9 @@ class GutsReport(Report):
|
|
|
33
36
|
|
|
34
37
|
@reporting
|
|
35
38
|
def LCx_estimates(self, sim):
|
|
36
|
-
X =
|
|
37
|
-
T =
|
|
38
|
-
P = sim.predefined_scenarios
|
|
39
|
+
X = self.ecx_estimates_x
|
|
40
|
+
T = self.ecx_estimates_times
|
|
41
|
+
P = sim.predefined_scenarios()
|
|
39
42
|
|
|
40
43
|
estimates = pd.DataFrame(
|
|
41
44
|
it.product(X, T, P.keys()),
|
|
@@ -57,6 +60,7 @@ class GutsReport(Report):
|
|
|
57
60
|
ecx_estimator.estimate(
|
|
58
61
|
mode=sim.ecx_mode,
|
|
59
62
|
draws=250,
|
|
63
|
+
show_plot=False
|
|
60
64
|
)
|
|
61
65
|
|
|
62
66
|
ecx.append(ecx_estimator.results)
|
|
@@ -64,9 +68,6 @@ class GutsReport(Report):
|
|
|
64
68
|
results = pd.DataFrame(ecx)
|
|
65
69
|
estimates[results.columns] = results
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
estimates.to_csv()
|
|
69
|
-
file = os.path.join(sim.output_path, "lcx_estimates.csv")
|
|
70
|
-
lab = self._label.format(placeholder='$LC_x$ estimates')
|
|
71
|
-
self._write_table(tab=estimates, label_insert=f"$LC_x$ estimates \label{{{lab}}}]({os.path.basename(file)})")
|
|
71
|
+
out = self._write_table(tab=estimates, label_insert="$LC_x$ estimates")
|
|
72
72
|
|
|
73
|
+
return out
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guts_base
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.6
|
|
4
4
|
Summary: Basic GUTS model implementation in pymob
|
|
5
5
|
Author-email: Florian Schunck <fluncki@protonmail.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -686,14 +686,14 @@ Classifier: Natural Language :: English
|
|
|
686
686
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
687
687
|
Classifier: Operating System :: OS Independent
|
|
688
688
|
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
689
|
-
Requires-Python:
|
|
689
|
+
Requires-Python: <3.12,>=3.10
|
|
690
690
|
Description-Content-Type: text/markdown
|
|
691
691
|
License-File: LICENSE
|
|
692
692
|
Requires-Dist: openpyxl>=3.1.3
|
|
693
693
|
Requires-Dist: Bottleneck>=1.5.0
|
|
694
694
|
Requires-Dist: expydb>=0.6.0
|
|
695
695
|
Requires-Dist: mempyguts>=1.5.0
|
|
696
|
-
Requires-Dist: pymob[numpyro]<
|
|
696
|
+
Requires-Dist: pymob[interactive,numpyro]<0.6.0,>=0.4.1
|
|
697
697
|
Provides-Extra: dev
|
|
698
698
|
Requires-Dist: pytest>=7.3; extra == "dev"
|
|
699
699
|
Requires-Dist: bumpver; extra == "dev"
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
guts_base/__init__.py,sha256=
|
|
2
|
-
guts_base/mod.py,sha256=
|
|
1
|
+
guts_base/__init__.py,sha256=dYv5zH5jYPdPZXIzku6YPkvB47XD8qaTlY-0olh-4cA,208
|
|
2
|
+
guts_base/mod.py,sha256=aLb09E-6CwgKgq0GbwIT_Alv167cVFA5zAxwx80F1aE,7454
|
|
3
3
|
guts_base/plot.py,sha256=rjIzyPUikOtubjWI5mX_ZY8ARWl2NiHDmwAZAdoaPS8,5693
|
|
4
4
|
guts_base/prob.py,sha256=k1b-gc8yZNg8DMnxJHJzCy8Pud8_qEygGkrnmS2AcMY,14004
|
|
5
5
|
guts_base/sim.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
guts_base/data/__init__.py,sha256=U5sJJgPwEVHVGTLeZNwl8VKLIgn1twpDNkOCMRSV1Nk,808
|
|
7
7
|
guts_base/data/expydb.py,sha256=Kcc6CeZMl3oEelk5UBN9VEfwgNF3CzTh13ooVkufAjE,8218
|
|
8
|
-
guts_base/data/generator.py,sha256=
|
|
8
|
+
guts_base/data/generator.py,sha256=fos7y-xxTlBVpYsHD_2kdYSH40KILPUQ_Jy0mwjO5jc,2897
|
|
9
9
|
guts_base/data/openguts.py,sha256=WvhYl_AOdvNgzrcVS2f_PYbXNH_wSAz2uIBSR6BMSh0,11078
|
|
10
10
|
guts_base/data/preprocessing.py,sha256=qggYkx2x62ingU1BNhJFyL1eQdFQsDJR2lefVfVWW2U,1732
|
|
11
11
|
guts_base/data/survival.py,sha256=yNNZ7MabzrMeqPHOa8-LPxCgsIN4_X0aj_ANmeC9Wd8,4878
|
|
12
12
|
guts_base/data/time_of_death.py,sha256=hwngUwfRP3u8WmD3dHyXrphuu5d8ZJTKyBovGRwAHNQ,21014
|
|
13
13
|
guts_base/data/utils.py,sha256=u3gGDJK15MfRUP4iIxsS-I1oqxD2qH_ugsT7o_Eac18,236
|
|
14
14
|
guts_base/sim/__init__.py,sha256=vgZu2oi4RHIQuLS19570xBdLQasL75puxabGrbLuIGA,276
|
|
15
|
-
guts_base/sim/base.py,sha256=
|
|
16
|
-
guts_base/sim/ecx.py,sha256=
|
|
15
|
+
guts_base/sim/base.py,sha256=lxfHQ57pXKz1ZGnFqOIoeUplzvFWM1OjDX0xYQpSgaw,20921
|
|
16
|
+
guts_base/sim/ecx.py,sha256=IvZQnmMs3FLX6unuj7mPv2AaZ7l-S4TJmYmPI4fXE1k,14573
|
|
17
17
|
guts_base/sim/mempy.py,sha256=xsA3Q7jQrdcmQZJzKBdQnr8yZk-f36YgbLlV-VvJpxg,9514
|
|
18
|
-
guts_base/sim/report.py,sha256=
|
|
19
|
-
guts_base-0.8.
|
|
20
|
-
guts_base-0.8.
|
|
21
|
-
guts_base-0.8.
|
|
22
|
-
guts_base-0.8.
|
|
23
|
-
guts_base-0.8.
|
|
24
|
-
guts_base-0.8.
|
|
18
|
+
guts_base/sim/report.py,sha256=D_6eoSvjdcsDtB0PlmNkzC1LRk_7WXzb_T6D6AZjQNE,1985
|
|
19
|
+
guts_base-0.8.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
20
|
+
guts_base-0.8.6.dist-info/METADATA,sha256=n0OWLZd2CZWg7j7M2sqcXfFuiOSPqSG60KvQ9IuoqHM,45437
|
|
21
|
+
guts_base-0.8.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
22
|
+
guts_base-0.8.6.dist-info/entry_points.txt,sha256=icsHzG2jQ90ZS7XvLsI5Qj0-qGuPv2T0RBVN5daGCPU,183
|
|
23
|
+
guts_base-0.8.6.dist-info/top_level.txt,sha256=PxhBgUd4r39W_VI4FyJjARwKbV5_glgCVnd6v_zAGdE,10
|
|
24
|
+
guts_base-0.8.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|