guts-base 2.0.0b0__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.
@@ -0,0 +1,170 @@
1
+ from functools import partial
2
+ import numpy as np
3
+ from pydantic import BeforeValidator, ConfigDict, PlainSerializer
4
+ from typing import Literal, Optional, List, Dict, Tuple, Annotated, Mapping
5
+ from pymob.sim.config import (
6
+ PymobModel,
7
+ string_to_list,
8
+ serialize_list_to_string,
9
+ nested_dict_to_string,
10
+ to_nested_dict,
11
+ string_to_dict,
12
+ serialize_dict_to_string,
13
+ OptionListStr,
14
+ )
15
+ from pymob.sim.config.casestudy_registry import register_case_study_config
16
+
17
+ OptionListMix = Annotated[
18
+ Optional[Tuple[float,float,int]],
19
+ BeforeValidator(string_to_list),
20
+ serialize_list_to_string
21
+ ]
22
+
23
+ OptionListFloat = Annotated[
24
+ List[float],
25
+ BeforeValidator(string_to_list),
26
+ serialize_list_to_string
27
+ ]
28
+
29
+ class ExposureDict(PymobModel):
30
+ start: float = 0.0
31
+ end: Optional[float] = None
32
+
33
+
34
+ serialize_datavar_to_string = PlainSerializer(
35
+ partial(nested_dict_to_string, dict_model=ExposureDict),
36
+ return_type=str,
37
+ when_used="json"
38
+ )
39
+
40
+ NestedDict = Annotated[
41
+ Dict[str,Dict[str,float|None]],
42
+ BeforeValidator(partial(to_nested_dict, dict_model=ExposureDict)),
43
+ serialize_datavar_to_string
44
+ ]
45
+
46
+
47
+ DictStr = Annotated[
48
+ Mapping[str, str],
49
+ BeforeValidator(partial(string_to_dict, split_str=" ", sep_str="=")),
50
+ serialize_dict_to_string
51
+ ]
52
+
53
+
54
+ AllowedTimeUnits = Literal["second", "hour", "day", "minute",]
55
+
56
+ class GutsBaseConfig(PymobModel):
57
+ # extra arguments can be passed to the settings file, but they won't be validated
58
+ model_config = ConfigDict(validate_assignment=True, extra="allow", validate_default=True)
59
+
60
+ # the time unit of the simulation
61
+ unit_time: AllowedTimeUnits = "day"
62
+
63
+ # the input unit of the simulation, by default no unit is given
64
+ # It is however, highly recommended to priovide a unit for each exposure path/substance
65
+ # this would be done by specifiying, e.g. unit_input={"A": "mg", "B": "ng/kg"}
66
+ # if the openguts file consists of two exposure sheets (A and B)
67
+ # In future versions, the unit of exposure might be read directly from the metadata,
68
+ # at the moment it must be provided explicitly
69
+ unit_input: DictStr = {"default": ""}
70
+
71
+ # if the units should be converted to a target this will be specified here.
72
+ # The syntax is input->output and {x} is a placeholder for the input unit.
73
+ # This means, if the unit input of exposure is 'mg', then '{x}->{x}' applies no
74
+ # transformation. The target unit will also be 'mg'.
75
+ # To change the target unit, you could apply '{x}->mg'. Provided {x} is a mass quantity,
76
+ # the conversion will work. If however {x} is a concentration (mg/ml), then a more
77
+ # elaborate transformation is necessary: {x}/(1.12g/ml)->mg/mg
78
+ # this will successfully bring the output unit to a mass concentration.
79
+ # Generally, the string accepts any arithmetic operations that can be handled with pint
80
+ # https://pint.readthedocs.io/en/stable/getting/tutorial.html
81
+ # TODO: Write a validation method for the string. I could use pint for this already
82
+ unit_target: DictStr = {"default": "{x}->{x}"}
83
+
84
+ # If the dataset provided to GutsBase contains additional DataArrays with substance
85
+ # names, that should be used for exposure AND an exposure DataArray does not exist.
86
+ # Use this instead. A copy of that data array <substance> will be placed in
87
+ # observations["exposure"]. By default GutsBase assumes that the exposure data is
88
+ # contained in observations["exposure"]
89
+ substance: Optional[str] = None
90
+
91
+ # start, end and the number fo timepoints to interpolate the results for plotting
92
+ # this will be inserted into numpy.linspace
93
+ results_interpolation: OptionListMix = (np.nan, np.nan, 100)
94
+
95
+ # whether GutsBase should make sure that the exposure profiles are forward
96
+ # interpolated. This means, if a rectangular profile is not explicitly given,
97
+ # by providing the same exposure (time, value) combination at the moment before the
98
+ # next recorded change in the exposure profile, the default behavior is to interpolate
99
+ # linearly over the profile. E.g. a profile like (time=0,value=10), (time=2,value=0)
100
+ # would implicitly yield the points, e.g.: (time=1,value=5), (time=1.99, value=~0).
101
+ # If forward_interpolate_exposure_data = True, then the interpolated point would be
102
+ # (time=1,value=10), (time=1.99,value=10)
103
+ forward_interpolate_exposure_data: bool = False
104
+
105
+ # if the IT model is used, the x-dim (time) resolution needs to be increased
106
+ # (reindexed), because the solution requires numeric integration of the hazard
107
+ # function in each solve. The default is to increase the temporal resolution to
108
+ # 100 datapoints. If the simulated time period is very long, 100 points may not be
109
+ # enough to capture the dynamics of the hazard function
110
+ n_reindexed_x: int = 100
111
+
112
+ # this is if case_study.observations is an .xlsx file. In this case you are allowed
113
+ # to pass a preprocessing script by the full module path. e.g.
114
+ # 'guts_base.data.preprocessing.ringtest' where the last element is the function
115
+ # name in a regular python file. The function must have the arguments path and new_path
116
+ # because it will read the file and save a processed file.
117
+ # create_database_and_import_data_main will try to import this function with
118
+ # import_module and execute the preprocessing
119
+ # The default behavior is not to pass a string and preprocess the file
120
+ data_preprocessing: Optional[str] = None
121
+
122
+ # private option (should only in case of errors be modified by the user)
123
+ # this will skip the data_processing section of GutsBase.initialize
124
+ # >>> if not _skip_data_processing: self.process_data()
125
+ # This option is set to true when simulations are exported with .nc files,
126
+ # which already are processed and do not need (and can't be) processed again
127
+ skip_data_processing: bool = False
128
+
129
+ # this parameter is not for user interaction. It is simply set when parsing the model
130
+ background_mortality_parameters: OptionListStr = []
131
+
132
+ # GUTS-REPORT Settings
133
+ # ====================
134
+
135
+ # Guts base uses pint to parse units. To see which other options are available to
136
+ # format the resulting strings see:
137
+ # https://pint.readthedocs.io/en/stable/user/formatting.html
138
+ unit_format_pint: str = "~P"
139
+
140
+ # Define the exposure scenarios that should be used for ecx computations
141
+ ecx_exposure_scenarios: NestedDict = {
142
+ "acute_1day": {"start": 0.0, "end": 1.0},
143
+ "chronic": {"start": 0.0, "end": None},
144
+ }
145
+
146
+ # whether to assess the uncertainty of the ECx estimate (draws) or not (mean)
147
+ ecx_mode: Literal["mean", "draws"] = "draws"
148
+
149
+ # number of draws from the posterior for assessing the uncertainty of the estimate
150
+ ecx_draws: int = 250
151
+
152
+ # if the number of draws is below 100, an error is raised. If ecx_force_draws,
153
+ # this error is supressed
154
+ ecx_force_draws: bool = False
155
+
156
+ # times after being of the exposure to estimate the ECx for
157
+ ecx_estimates_times: OptionListFloat = [1, 2, 4, 10]
158
+
159
+ # effect levels to estimate the ecx for
160
+ ecx_estimates_x: OptionListFloat = [0.1, 0.25, 0.5, 0.75, 0.9]
161
+
162
+ # whether the background mortality should be set to zero when estimating the ECx
163
+ ecx_set_background_mortality_to_zero: bool = True
164
+
165
+ # whether the posterior should be summarized with the mean or the median of the
166
+ # distribution. Median is more robust
167
+ table_parameter_stat_focus: Literal["mean", "median"] = "median"
168
+
169
+
170
+ register_case_study_config("guts_base", model_cls=GutsBaseConfig)
@@ -0,0 +1,31 @@
1
+ import os
2
+ import arviz as az
3
+ from guts_base.sim import GutsBase
4
+
5
+ def construct_sim_from_config(
6
+ scenario: str,
7
+ simulation_class: type,
8
+ output_path=None
9
+ ) -> GutsBase:
10
+ """Helper function to construct simulations for debugging"""
11
+ sim = simulation_class(f"scenarios/{scenario}/settings.cfg")
12
+
13
+ # this sets a different output directory
14
+ if output_path is not None:
15
+ p = output_path / sim.config.case_study.name / "results" / sim.config.case_study.scenario
16
+ sim.config.case_study.output_path = str(p)
17
+ else:
18
+ sim.config.case_study.scenario = "debug_test"
19
+ sim.setup()
20
+ return sim
21
+
22
+
23
+ def load_idata(sim: GutsBase, idata_file: str) -> GutsBase:
24
+ sim.set_inferer("numpyro")
25
+
26
+ if os.path.exists(idata_file):
27
+ sim.inferer.idata = az.from_netcdf(idata_file)
28
+ else:
29
+ sim.inferer.idata = None
30
+
31
+ return sim