vivarium-public-health 2.3.2__py3-none-any.whl → 3.0.0__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.
- vivarium_public_health/_version.py +1 -1
- vivarium_public_health/disease/model.py +23 -21
- vivarium_public_health/disease/models.py +1 -0
- vivarium_public_health/disease/special_disease.py +40 -41
- vivarium_public_health/disease/state.py +42 -125
- vivarium_public_health/disease/transition.py +70 -27
- vivarium_public_health/mslt/delay.py +1 -0
- vivarium_public_health/mslt/disease.py +1 -0
- vivarium_public_health/mslt/intervention.py +1 -0
- vivarium_public_health/mslt/magic_wand_components.py +1 -0
- vivarium_public_health/mslt/observer.py +1 -0
- vivarium_public_health/mslt/population.py +1 -0
- vivarium_public_health/plugins/parser.py +61 -31
- vivarium_public_health/population/add_new_birth_cohorts.py +2 -3
- vivarium_public_health/population/base_population.py +2 -1
- vivarium_public_health/population/mortality.py +83 -80
- vivarium_public_health/{metrics → results}/__init__.py +2 -0
- vivarium_public_health/results/columns.py +22 -0
- vivarium_public_health/results/disability.py +187 -0
- vivarium_public_health/results/disease.py +222 -0
- vivarium_public_health/results/mortality.py +186 -0
- vivarium_public_health/results/observer.py +78 -0
- vivarium_public_health/results/risk.py +138 -0
- vivarium_public_health/results/simple_cause.py +18 -0
- vivarium_public_health/{metrics → results}/stratification.py +10 -8
- vivarium_public_health/risks/__init__.py +1 -2
- vivarium_public_health/risks/base_risk.py +134 -29
- vivarium_public_health/risks/data_transformations.py +65 -326
- vivarium_public_health/risks/distributions.py +315 -145
- vivarium_public_health/risks/effect.py +376 -75
- vivarium_public_health/risks/implementations/low_birth_weight_and_short_gestation.py +61 -89
- vivarium_public_health/treatment/magic_wand.py +1 -0
- vivarium_public_health/treatment/scale_up.py +1 -0
- vivarium_public_health/treatment/therapeutic_inertia.py +1 -0
- vivarium_public_health/utilities.py +17 -2
- {vivarium_public_health-2.3.2.dist-info → vivarium_public_health-3.0.0.dist-info}/METADATA +13 -3
- vivarium_public_health-3.0.0.dist-info/RECORD +49 -0
- {vivarium_public_health-2.3.2.dist-info → vivarium_public_health-3.0.0.dist-info}/WHEEL +1 -1
- vivarium_public_health/metrics/disability.py +0 -118
- vivarium_public_health/metrics/disease.py +0 -136
- vivarium_public_health/metrics/mortality.py +0 -144
- vivarium_public_health/metrics/risk.py +0 -110
- vivarium_public_health/testing/__init__.py +0 -0
- vivarium_public_health/testing/mock_artifact.py +0 -145
- vivarium_public_health/testing/utils.py +0 -71
- vivarium_public_health-2.3.2.dist-info/RECORD +0 -49
- {vivarium_public_health-2.3.2.dist-info → vivarium_public_health-3.0.0.dist-info}/LICENSE.txt +0 -0
- {vivarium_public_health-2.3.2.dist-info → vivarium_public_health-3.0.0.dist-info}/top_level.txt +0 -0
@@ -7,20 +7,26 @@ This module contains tools for modeling categorical and continuous risk
|
|
7
7
|
exposure.
|
8
8
|
|
9
9
|
"""
|
10
|
+
|
10
11
|
from typing import Any, Dict, List
|
11
12
|
|
12
13
|
import pandas as pd
|
13
14
|
from vivarium import Component
|
14
15
|
from vivarium.framework.engine import Builder
|
16
|
+
from vivarium.framework.event import Event
|
15
17
|
from vivarium.framework.population import SimulantData
|
16
18
|
from vivarium.framework.randomness import RandomnessStream
|
17
19
|
from vivarium.framework.values import Pipeline
|
18
20
|
|
19
|
-
from vivarium_public_health.risks.data_transformations import
|
20
|
-
|
21
|
+
from vivarium_public_health.risks.data_transformations import get_exposure_post_processor
|
22
|
+
from vivarium_public_health.risks.distributions import (
|
23
|
+
ContinuousDistribution,
|
24
|
+
DichotomousDistribution,
|
25
|
+
EnsembleDistribution,
|
26
|
+
PolytomousDistribution,
|
27
|
+
RiskExposureDistribution,
|
21
28
|
)
|
22
|
-
from vivarium_public_health.
|
23
|
-
from vivarium_public_health.utilities import EntityString
|
29
|
+
from vivarium_public_health.utilities import EntityString, get_lookup_columns
|
24
30
|
|
25
31
|
|
26
32
|
class Risk(Component):
|
@@ -81,25 +87,42 @@ class Risk(Component):
|
|
81
87
|
|
82
88
|
"""
|
83
89
|
|
84
|
-
|
85
|
-
"
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
+
exposure_distributions = {
|
91
|
+
"dichotomous": DichotomousDistribution,
|
92
|
+
"ordered_polytomous": PolytomousDistribution,
|
93
|
+
"unordered_polytomous": PolytomousDistribution,
|
94
|
+
"normal": ContinuousDistribution,
|
95
|
+
"lognormal": ContinuousDistribution,
|
96
|
+
"ensemble": EnsembleDistribution,
|
90
97
|
}
|
91
98
|
|
92
99
|
##############
|
93
100
|
# Properties #
|
94
101
|
##############
|
95
102
|
|
103
|
+
@property
|
104
|
+
def name(self) -> str:
|
105
|
+
return self.risk
|
106
|
+
|
96
107
|
@property
|
97
108
|
def configuration_defaults(self) -> Dict[str, Any]:
|
98
|
-
return {
|
109
|
+
return {
|
110
|
+
self.name: {
|
111
|
+
"data_sources": {
|
112
|
+
"exposure": f"{self.risk}.exposure",
|
113
|
+
"ensemble_distribution_weights": f"{self.risk}.exposure_distribution_weights",
|
114
|
+
"exposure_standard_deviation": f"{self.risk}.exposure_standard_deviation",
|
115
|
+
},
|
116
|
+
"distribution_type": f"{self.risk}.distribution",
|
117
|
+
# rebinned_exposed only used for DichotomousDistribution
|
118
|
+
"rebinned_exposed": [],
|
119
|
+
"category_thresholds": [],
|
120
|
+
}
|
121
|
+
}
|
99
122
|
|
100
123
|
@property
|
101
124
|
def columns_created(self) -> List[str]:
|
102
|
-
return [self.propensity_column_name]
|
125
|
+
return [self.propensity_column_name, self.exposure_column_name]
|
103
126
|
|
104
127
|
@property
|
105
128
|
def initialization_requirements(self) -> Dict[str, List[str]]:
|
@@ -122,30 +145,98 @@ class Risk(Component):
|
|
122
145
|
"""
|
123
146
|
super().__init__()
|
124
147
|
self.risk = EntityString(risk)
|
125
|
-
self.
|
126
|
-
self._sub_components = [self.exposure_distribution]
|
148
|
+
self.distribution_type = None
|
127
149
|
|
128
150
|
self.randomness_stream_name = f"initial_{self.risk.name}_propensity"
|
129
151
|
self.propensity_column_name = f"{self.risk.name}_propensity"
|
130
152
|
self.propensity_pipeline_name = f"{self.risk.name}.propensity"
|
131
153
|
self.exposure_pipeline_name = f"{self.risk.name}.exposure"
|
154
|
+
self.exposure_column_name = f"{self.risk.name}_exposure"
|
155
|
+
|
156
|
+
#################
|
157
|
+
# Setup methods #
|
158
|
+
#################
|
159
|
+
|
160
|
+
def build_all_lookup_tables(self, builder: "Builder") -> None:
|
161
|
+
# All lookup tables are built in the exposure distribution
|
162
|
+
pass
|
132
163
|
|
133
164
|
# noinspection PyAttributeOutsideInit
|
134
165
|
def setup(self, builder: Builder) -> None:
|
166
|
+
self.distribution_type = self.get_distribution_type(builder)
|
167
|
+
self.exposure_distribution = self.get_exposure_distribution(builder)
|
168
|
+
|
135
169
|
self.randomness = self.get_randomness_stream(builder)
|
136
170
|
self.propensity = self.get_propensity_pipeline(builder)
|
137
171
|
self.exposure = self.get_exposure_pipeline(builder)
|
138
172
|
|
139
|
-
|
140
|
-
|
141
|
-
|
173
|
+
def get_distribution_type(self, builder: Builder) -> str:
|
174
|
+
"""
|
175
|
+
Get the distribution type for the risk from the configuration.
|
142
176
|
|
143
|
-
|
144
|
-
|
177
|
+
If the configured distribution type is not one of the supported types,
|
178
|
+
it is assumed to be a data source and the data is retrieved using the
|
179
|
+
get_data method.
|
145
180
|
|
146
|
-
|
147
|
-
|
148
|
-
|
181
|
+
Parameters
|
182
|
+
----------
|
183
|
+
builder : Builder
|
184
|
+
the builder object
|
185
|
+
|
186
|
+
Returns
|
187
|
+
-------
|
188
|
+
str
|
189
|
+
the distribution type
|
190
|
+
"""
|
191
|
+
if self.configuration is None:
|
192
|
+
self.configuration = self.get_configuration(builder)
|
193
|
+
|
194
|
+
distribution_type = self.configuration["distribution_type"]
|
195
|
+
if distribution_type not in self.exposure_distributions.keys():
|
196
|
+
# todo deal with incorrect typing
|
197
|
+
distribution_type = self.get_data(builder, distribution_type)
|
198
|
+
|
199
|
+
if self.configuration["rebinned_exposed"]:
|
200
|
+
if distribution_type != "dichotomous" or "polytomous" not in distribution_type:
|
201
|
+
raise ValueError(
|
202
|
+
f"Unsupported risk distribution type '{distribution_type}' "
|
203
|
+
f"for {self.name}. Rebinned exposed categories are only "
|
204
|
+
"supported for dichotomous and polytomous distributions."
|
205
|
+
)
|
206
|
+
distribution_type = "dichotomous"
|
207
|
+
return distribution_type
|
208
|
+
|
209
|
+
def get_exposure_distribution(self, builder: Builder) -> RiskExposureDistribution:
|
210
|
+
"""
|
211
|
+
Creates and sets up the exposure distribution component for the Risk
|
212
|
+
based on its distribution type.
|
213
|
+
|
214
|
+
Parameters
|
215
|
+
----------
|
216
|
+
builder : Builder
|
217
|
+
the builder object
|
218
|
+
|
219
|
+
Returns
|
220
|
+
-------
|
221
|
+
RiskExposureDistribution
|
222
|
+
the exposure distribution
|
223
|
+
|
224
|
+
Raises
|
225
|
+
------
|
226
|
+
NotImplementedError
|
227
|
+
if the distribution type is not supported
|
228
|
+
"""
|
229
|
+
try:
|
230
|
+
exposure_distribution = self.exposure_distributions[self.distribution_type](
|
231
|
+
self.risk, self.distribution_type
|
232
|
+
)
|
233
|
+
except KeyError:
|
234
|
+
raise NotImplementedError(
|
235
|
+
f"Distribution type {self.distribution_type} is not supported."
|
236
|
+
)
|
237
|
+
|
238
|
+
exposure_distribution.setup_component(builder)
|
239
|
+
return exposure_distribution
|
149
240
|
|
150
241
|
def get_randomness_stream(self, builder: Builder) -> RandomnessStream:
|
151
242
|
return builder.randomness.get_stream(self.randomness_stream_name)
|
@@ -162,12 +253,18 @@ class Risk(Component):
|
|
162
253
|
)
|
163
254
|
|
164
255
|
def get_exposure_pipeline(self, builder: Builder) -> Pipeline:
|
256
|
+
required_columns = get_lookup_columns(
|
257
|
+
self.exposure_distribution.lookup_tables.values()
|
258
|
+
)
|
165
259
|
return builder.value.register_value_producer(
|
166
260
|
self.exposure_pipeline_name,
|
167
261
|
source=self.get_current_exposure,
|
168
|
-
requires_columns=
|
169
|
-
requires_values=[
|
170
|
-
|
262
|
+
requires_columns=required_columns,
|
263
|
+
requires_values=[
|
264
|
+
self.propensity_pipeline_name,
|
265
|
+
self.exposure_distribution.parameters_pipeline_name,
|
266
|
+
],
|
267
|
+
preferred_post_processor=get_exposure_post_processor(builder, self.name),
|
171
268
|
)
|
172
269
|
|
173
270
|
########################
|
@@ -175,11 +272,19 @@ class Risk(Component):
|
|
175
272
|
########################
|
176
273
|
|
177
274
|
def on_initialize_simulants(self, pop_data: SimulantData) -> None:
|
178
|
-
self.
|
179
|
-
|
180
|
-
|
181
|
-
|
275
|
+
propensity_values = self.randomness.get_draw(pop_data.index)
|
276
|
+
df = pd.DataFrame(
|
277
|
+
{
|
278
|
+
self.propensity_column_name: self.randomness.get_draw(pop_data.index),
|
279
|
+
self.exposure_column_name: self.exposure_distribution.ppf(propensity_values),
|
280
|
+
}
|
182
281
|
)
|
282
|
+
self.population_view.update(df)
|
283
|
+
|
284
|
+
def on_time_step_prepare(self, event: Event) -> None:
|
285
|
+
exposure_values = self.exposure(event.index)
|
286
|
+
exposure_col = pd.Series(exposure_values, name=self.exposure_column_name)
|
287
|
+
self.population_view.update(exposure_col)
|
183
288
|
|
184
289
|
##################################
|
185
290
|
# Pipeline sources and modifiers #
|