Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
4e84dc0
Initial commit of moud approach to consistent rates, for adapting to AD
aflaxman Sep 30, 2025
1c4808d
Refactor model parameters and update data handling for dementia rates…
aflaxman Oct 1, 2025
ff4bd7f
Refactor consistent rates module: enhance type hints, improve data ha…
aflaxman Oct 1, 2025
a87c963
Refactor ode_model parameters and update age range in generate_consis…
aflaxman Oct 1, 2025
c7062b6
tweak key names to be slightly clearer
aflaxman Oct 1, 2025
35ff3f6
code cleanup and run a bit faster for iterative development
aflaxman Oct 1, 2025
5826f18
BUG: square components of ode error to prevent big positive and negat…
aflaxman Oct 1, 2025
c964b7b
remove clipping for size of dementia compartment (D) in ODE
aflaxman Oct 1, 2025
49f6338
Reorganize code to make it easier to explain (I hope!)
aflaxman Oct 1, 2025
4d29b84
add stuff to make the consistent rate code more easily usable
aflaxman Oct 2, 2025
f615d88
Merge remote-tracking branch 'origin/main' into abie_consistent_rates
aflaxman Oct 20, 2025
8b5187a
ENH: Use consistent rates in sim
aflaxman Oct 21, 2025
7391b97
Incorporate consistent rate generation into into make_artifacts tool
aflaxman Oct 21, 2025
03fd1a4
pin artifact requirements to allow successful building of consistent …
aflaxman Oct 21, 2025
2117076
Merge branch 'main' of github.com:ihmeuw/vivarium_csu_alzheimers into…
aflaxman Oct 22, 2025
3524927
Better initialization of AD states
aflaxman Oct 24, 2025
a084b78
include data for mixed dementia
aflaxman Oct 24, 2025
c055183
include data for dementia severity
aflaxman Oct 25, 2025
bf14006
use mixed dementia and severity splits in consistent model
aflaxman Oct 25, 2025
4e2f0ea
make delta fractions sum to one, add excess mortality to moderate dem…
aflaxman Oct 25, 2025
06357c6
tweaks and bug fixes suggested by chatgpt
aflaxman Oct 26, 2025
d0b96d9
minor tweaks while iterating
aflaxman Oct 26, 2025
9b17649
update model to include severity and mixed dementia
aflaxman Oct 26, 2025
d1b660e
add lost line to make_artifacts
aflaxman Oct 26, 2025
317f6ce
keep trying, but seems like something is wrong in the mixed
aflaxman Oct 26, 2025
83c2372
remove mixed dementia, get pretty good results
aflaxman Oct 27, 2025
216b033
add mixed dementia (just for simulants who develop mixed dementia dur…
aflaxman Oct 27, 2025
1063d30
Test final run code
albrja Oct 29, 2025
8381562
Merge branch 'main' into final_runs
albrja Oct 29, 2025
1937714
Add config for runs
albrja Oct 29, 2025
12f9194
Update start year
albrja Oct 29, 2025
69934dd
Fix typo
albrja Oct 30, 2025
0e81057
merge and resolve conflicts
aflaxman Nov 1, 2025
f55607b
isort, black
aflaxman Nov 1, 2025
fd44bda
adding severity-specific emr
aflaxman Nov 2, 2025
1dbff2b
isort, black
aflaxman Nov 2, 2025
5af6f23
increase pop_size and tweak mixed_dementia prevalence; maybe the mixe…
aflaxman Nov 2, 2025
d16c145
remove mixed dementia initial prevalence
aflaxman Nov 2, 2025
7dcf384
dial down volume of run so that it routinely succeeds
aflaxman Nov 3, 2025
c579073
resolve conflicts in merged fix for bbbm-ad state initialization and …
aflaxman Nov 4, 2025
166eb47
Merge branch 'main' into final_runs
albrja Nov 5, 2025
2824d3b
Update config
albrja Nov 5, 2025
9e3689c
make this match final runs
aflaxman Nov 14, 2025
60ca9cc
v1 experiment: smooth first and second differences of h_S_to_BBBM age…
aflaxman Nov 15, 2025
4fe4521
add increasing prior
aflaxman Nov 15, 2025
f3619ee
Remove Mixed Dementia
aflaxman Nov 15, 2025
7d967ad
tweaks to better match old vals
aflaxman Nov 17, 2025
89f8b40
add 40 year olds to ODE calibrations
aflaxman Nov 17, 2025
5c496fd
pretty acceptable results :)
aflaxman Nov 17, 2025
7f74fc4
settings I used to make all the artifacts on 2025-11-16
aflaxman Nov 17, 2025
3f00272
all years
aflaxman Nov 19, 2025
f2376e2
isort, black
aflaxman Nov 20, 2025
cae6c47
update to run with latest gbd stuff
aflaxman Dec 4, 2025
b3ed2c0
update draws to be compatible with GBD 2023, which only has 250 draws…
aflaxman Dec 6, 2025
869f5b0
add TODO about low age values
aflaxman Dec 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion artifact_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ matplotlib
jax
numpyro
diffrax
interpax
138 changes: 138 additions & 0 deletions compare_results_after_consistent_rates.ipynb

Large diffs are not rendered by default.

443 changes: 443 additions & 0 deletions generate_and_test_consistent_rates.ipynb

Large diffs are not rendered by default.

74 changes: 53 additions & 21 deletions src/vivarium_csu_alzheimers/components/alzheimers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
DW_BBBM,
EMR_BBBM,
EMR_MCI,
MCI_AVG_DURATION,
)
from vivarium_csu_alzheimers.constants.models import ALZHEIMERS_DISEASE_MODEL
from vivarium_csu_alzheimers.data.mci_hazard import hazard
Expand Down Expand Up @@ -172,39 +173,70 @@ def _create_disease_model(self) -> AlzheimersModel:
),
excess_mortality_rate=EMR_MCI,
)
alzheimers_state = DiseaseState(
ALZHEIMERS_DISEASE_MODEL.ALZHEIMERS_DISEASE_STATE,
mild_dementia_state = DiseaseState(
ALZHEIMERS_DISEASE_MODEL.MILD_DEMENTIA_STATE,
allow_self_transition=True,
birth_prevalence=0.0,
prevalence=lambda builder: builder.data.load(
ALZHEIMERS.MILD_DEMENTIA_CONDITIONAL_PREVALENCE
),
disability_weight=lambda builder: builder.data.load(
ALZHEIMERS.MILD_DEMENTIA_DISABILITY_WEIGHT
),
excess_mortality_rate=lambda builder: builder.data.load(ALZHEIMERS.EMR_MILD),
)
moderate_dementia_state = DiseaseState(
ALZHEIMERS_DISEASE_MODEL.MODERATE_DEMENTIA_STATE,
allow_self_transition=True,
birth_prevalence=0.0,
prevalence=lambda builder: builder.data.load(
ALZHEIMERS.MODERATE_DEMENTIA_CONDITIONAL_PREVALENCE
),
disability_weight=lambda builder: builder.data.load(
ALZHEIMERS.MODERATE_DEMENTIA_DISABILITY_WEIGHT
),
excess_mortality_rate=lambda builder: builder.data.load(ALZHEIMERS.EMR_MODERATE),
)
severe_dementia_state = DiseaseState(
ALZHEIMERS_DISEASE_MODEL.SEVERE_DEMENTIA_STATE,
allow_self_transition=True,
birth_prevalence=0.0,
prevalence=lambda builder: builder.data.load(
ALZHEIMERS.DEMENTIA_CONDITIONAL_PREVALENCE
ALZHEIMERS.SEVERE_DEMENTIA_CONDITIONAL_PREVALENCE
),
disability_weight=lambda builder: builder.data.load(ALZHEIMERS.DISABILITY_WEIGHT),
excess_mortality_rate=lambda builder: builder.data.load(ALZHEIMERS.EMR),
disability_weight=lambda builder: builder.data.load(
ALZHEIMERS.SEVERE_DEMENTIA_DISABILITY_WEIGHT
),
excess_mortality_rate=lambda builder: builder.data.load(ALZHEIMERS.EMR_SEVERE),
)

# Add transitions between states
# AD progression transitions
bbbm_state.add_bbbm_transition(output=mci_state)
mci_state.add_rate_transition(
output=alzheimers_state,
output=mild_dementia_state,
transition_rate=1 / MCI_AVG_DURATION,
)
mild_dementia_state.add_rate_transition(
output=moderate_dementia_state,
transition_rate=lambda builder: builder.data.load(
ALZHEIMERS.MCI_TO_DEMENTIA_TRANSITION_RATE
ALZHEIMERS.MILD_TO_MODERATE_DEMENTIA_TRANSITION_RATE
),
)
moderate_dementia_state.add_rate_transition(
output=severe_dementia_state,
transition_rate=lambda builder: builder.data.load(
ALZHEIMERS.MODERATE_TO_SEVERE_DEMENTIA_TRANSITION_RATE
),
)

return AlzheimersModel(
ALZHEIMERS_DISEASE_MODEL.NAME,
initial_state=bbbm_state,
states=[bbbm_state, mci_state, alzheimers_state],
states=[
bbbm_state,
mci_state,
mild_dementia_state,
moderate_dementia_state,
severe_dementia_state,
],
)

def _get_alzheimers_disease_state_prevalence(self, builder: Builder) -> pd.DataFrame:
"""Get the Alzheimer's disease state prevalence table."""
bbbm_prevalence = builder.data.load(ALZHEIMERS.BBBM_CONDITIONAL_PREVALENCE)
mci_prevalence = builder.data.load(ALZHEIMERS.MCI_CONDITIONAL_PREVALENCE)
alz_prevalence = bbbm_prevalence.copy()
alz_prevalence["value"] = 1.0
alz_prevalence["value"] = alz_prevalence["value"] - (
bbbm_prevalence["value"] + mci_prevalence["value"]
)

return alz_prevalence
2 changes: 1 addition & 1 deletion src/vivarium_csu_alzheimers/components/population.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def load_population_structure(self, builder: Builder) -> pd.Series:
return pop_structure

def load_prevalence(self, builder: Builder) -> pd.Series:
prevalence = builder.data.load(data_keys.ALZHEIMERS_CONSISTENT.PREVALENCE_ANY)
prevalence = builder.data.load(data_keys.ALZHEIMERS_CONSISTENT.AD_PREVALENCE)

# Updating age_end to match configuration since some simulants are living past 125
prevalence.loc[prevalence["age_end"] == 125, "age_end"] = self.age_end
Expand Down
4 changes: 3 additions & 1 deletion src/vivarium_csu_alzheimers/components/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ def _update_baseline_testing(self, pop: pd.DataFrame) -> None:
eligible_state = pop[COLUMNS.DISEASE_STATE].isin(
[
ALZHEIMERS_DISEASE_MODEL.MCI_STATE,
ALZHEIMERS_DISEASE_MODEL.ALZHEIMERS_DISEASE_STATE,
ALZHEIMERS_DISEASE_MODEL.MILD_DEMENTIA_STATE,
ALZHEIMERS_DISEASE_MODEL.MODERATE_DEMENTIA_STATE,
ALZHEIMERS_DISEASE_MODEL.SEVERE_DEMENTIA_STATE,
]
)
eligible_test_propensity = pop[COLUMNS.TESTING_PROPENSITY] < (
Expand Down
95 changes: 74 additions & 21 deletions src/vivarium_csu_alzheimers/constants/data_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
class __Population(NamedTuple):
LOCATION: str = "population.location"
STRUCTURE: str = "population.structure"
SCALING_FACTOR: str = "population.scaling_factor"
AGE_BINS: str = "population.age_bins"
DEMOGRAPHY: str = "population.demographic_dimensions"
TMRLE: str = "population.theoretical_minimum_risk_life_expectancy"
ACMR: str = "cause.all_causes.cause_specific_mortality_rate"
LIVE_BIRTH_RATE: str = "covariate.live_births_by_sex.estimate"
SCALING_FACTOR: str = "population.scaling_factor"

@property
def name(self):
Expand All @@ -30,19 +30,40 @@ def log_name(self):


class __Alzheimers(NamedTuple):
PREVALENCE: str = "cause.alzheimers.prevalence"
BBBM_CONDITIONAL_PREVALENCE: str = "cause.alzheimers.bbbm_conditional_prevalence"
MCI_CONDITIONAL_PREVALENCE: str = "cause.alzheimers.mci_conditional_prevalence"
MCI_TO_DEMENTIA_TRANSITION_RATE: str = "cause.alzheimers.mci_to_dementia_transition_rate"
SUSCEPTIBLE_TO_BBBM_TRANSITION_COUNT: str = (
"cause.alzheimers.susceptible_to_bbbm_transition_count"
AD_DEMENTIA_PREVALENCE: str = "cause.alzheimers.ad_dementia_prevalence"
MIXED_DEMENTIA_PREVALENCE: str = "cause.alzheimers.mixed_dementia_prevalence"

AD_DEMENTIA_INCIDENCE_RATE_TOTAL_POPULATION: str = (
"cause.alzheimers.ad_dementia_population_incidence_rate"
)
# BBBM to MCI transition rate caluclated during sim using mci_hazard.py and time in state
INCIDENCE_RATE_TOTAL_POPULATION: str = "cause.alzheimers.population_incidence_rate"
CSMR: str = "cause.alzheimers_disease_and_other_dementias.cause_specific_mortality_rate"
EMR: str = "cause.alzheimers.excess_mortality_rate"
DISABILITY_WEIGHT: str = "cause.alzheimers_disease_and_other_dementias.disability_weight"
MIXED_DEMENTIA_INCIDENCE_RATE_TOTAL_POPULATION: str = (
"cause.alzheimers.mixed_dementia_population_incidence_rate"
)

MILD_DEMENTIA_PREVALENCE: str = (
"sequela.mild_alzheimers_disease_and_other_dementias.prevalence"
)
MODERATE_DEMENTIA_PREVALENCE: str = (
"sequela.moderate_alzheimers_disease_and_other_dementias.prevalence"
)
SEVERE_DEMENTIA_PREVALENCE: str = (
"sequela.severe_alzheimers_disease_and_other_dementias.prevalence"
)

EMR_COMO: str = "cause.alzheimers_disease_and_other_dementias.excess_mortality_rate"
EMR_DISMOD: str = "cause.dementia.excess_mortality_rate"

MCI_DISABILITY_WEIGHT: str = "cause.alzheimers.mci_disability_weight"
MILD_DEMENTIA_DISABILITY_WEIGHT: str = (
"sequela.mild_alzheimers_disease_and_other_dementias.disability_weight"
)
MODERATE_DEMENTIA_DISABILITY_WEIGHT: str = (
"sequela.moderate_alzheimers_disease_and_other_dementias.disability_weight"
)
SEVERE_DEMENTIA_DISABILITY_WEIGHT: str = (
"sequela.severe_alzheimers_disease_and_other_dementias.disability_weight"
)

RESTRICTIONS: str = "cause.alzheimers_disease_and_other_dementias.restrictions"

@property
Expand All @@ -58,27 +79,59 @@ def log_name(self):


class __AlzheimersConsistent(NamedTuple):
PREVALENCE_ANY: str = "cause.alzheimers_consistent.prevalence_any"
PREVALENCE: str = "cause.alzheimers.prevalence"
AD_PREVALENCE: str = "cause.alzheimers_consistent.alzheimers_prevalence"
MIXED_DEMENTIA_PREVALENCE: str = "cause.alzheimers_consistent.mixed_dementia_prevalence"
BBBM_CONDITIONAL_PREVALENCE: str = (
"cause.alzheimers_consistent.bbbm_conditional_prevalence"
)
MCI_CONDITIONAL_PREVALENCE: str = "cause.alzheimers_consistent.mci_conditional_prevalence"
DEMENTIA_CONDITIONAL_PREVALENCE: str = (
"cause.alzheimers_consistent.dementia_conditional_prevalence"
MILD_DEMENTIA_CONDITIONAL_PREVALENCE: str = (
"cause.alzheimers_consistent.mild_dementia_conditional_prevalence"
)
MODERATE_DEMENTIA_CONDITIONAL_PREVALENCE: str = (
"cause.alzheimers_consistent.moderate_dementia_conditional_prevalence"
)
SEVERE_DEMENTIA_CONDITIONAL_PREVALENCE: str = (
"cause.alzheimers_consistent.severe_dementia_conditional_prevalence"
)
MCI_TO_DEMENTIA_TRANSITION_RATE: str = "cause.alzheimers.mci_to_dementia_transition_rate"

SUSCEPTIBLE_TO_BBBM_TRANSITION_COUNT: str = (
"cause.alzheimers_consistent.susceptible_to_bbbm_transition_count"
)
# BBBM to MCI transition rate caluclated during sim using mci_hazard.py and time in state
INCIDENCE_RATE_TOTAL_POPULATION: str = (
"cause.alzheimers_consistent.population_incidence_dementia"
# MCI to MILD transition rate is specified in data_values.py
MILD_TO_MODERATE_DEMENTIA_TRANSITION_RATE: str = (
"cause.alzheimers_consistent.mild_to_moderate_dementia_transition_rate"
)
MODERATE_TO_SEVERE_DEMENTIA_TRANSITION_RATE: str = (
"cause.alzheimers_consistent.moderate_to_severe_dementia_transition_rate"
)

BBBM_AD_INCIDENCE_RATE: str = (
"cause.alzheimers_consistent.susceptible_to_bbbm_ad_transition_rate"
)
MIXED_DEMENTIA_INCIDENCE_RATE_TOTAL_POPULATION: str = (
"cause.alzheimers_consistent.mixed_dementia_population_incidence_rate"
)
MILD_DEMENTIA_INCIDENCE_RATE_TOTAL_POPULATION: str = (
"cause.alzheimers_consistent.population_incidence_mild_dementia"
)

CSMR: str = "cause.alzheimers_disease_and_other_dementias.cause_specific_mortality_rate"
EMR: str = "cause.alzheimers_consistent.excess_mortality_rate"
DISABILITY_WEIGHT: str = "cause.alzheimers_disease_and_other_dementias.disability_weight"
EMR_MILD: str = "cause.alzheimers_consistent.excess_mortality_rate_mild"
EMR_MODERATE: str = "cause.alzheimers_consistent.excess_mortality_rate_moderate"
EMR_SEVERE: str = "cause.alzheimers_consistent.excess_mortality_rate_severe"
MCI_DISABILITY_WEIGHT: str = "cause.alzheimers.mci_disability_weight"
MILD_DEMENTIA_DISABILITY_WEIGHT: str = (
"sequela.mild_alzheimers_disease_and_other_dementias.disability_weight"
)
MODERATE_DEMENTIA_DISABILITY_WEIGHT: str = (
"sequela.moderate_alzheimers_disease_and_other_dementias.disability_weight"
)
SEVERE_DEMENTIA_DISABILITY_WEIGHT: str = (
"sequela.severe_alzheimers_disease_and_other_dementias.disability_weight"
)

RESTRICTIONS: str = "cause.alzheimers_disease_and_other_dementias.restrictions"

@property
Expand Down
5 changes: 4 additions & 1 deletion src/vivarium_csu_alzheimers/constants/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ class __AlzheimersDiseaseModel(NamedTuple):
NAME: str = data_keys.ALZHEIMERS.log_name
BBBM_STATE: str = "alzheimers_blood_based_biomarker_state"
MCI_STATE: str = "alzheimers_mild_cognitive_impairment_state"
ALZHEIMERS_DISEASE_STATE: str = "alzheimers_disease_state"
MILD_DEMENTIA_STATE: str = "alzheimers_mild_dementia_state"
MODERATE_DEMENTIA_STATE: str = "alzheimers_moderate_dementia_state"
SEVERE_DEMENTIA_STATE: str = "alzheimers_severe_dementia_state"
MIXED_DEMENTIA_STATE: str = "mixed_dementia_state"

def __iter__(self):
"""Allow iteration over the named tuple field values."""
Expand Down
Loading