Health Impacts¶
This chapter describes how the model quantifies the health consequences of dietary choices. It begins with the epidemiological concepts that underpin the methodology, then explains the implementation strategy for embedding these nonlinear relationships into a linear optimisation framework.
The health module is off by default
health.enabled defaults to false. The health module relies on
manually-downloaded IHME GBD data (mortality rates and dietary
risk-exposure; see Data Sources), which cannot be fetched
automatically. When health is disabled, none of that data is required
and the workflow builds, solves, and analyses without it – the
YLL stores, health objective term, and health analysis/plots are
simply omitted, and a clear error is raised if the data is missing
while health is on.
Enabling health also turns on GBD anchoring of the baseline diet
by default (diet.anchor_groups_to_gbd: match_health), so that the
model’s attributable-burden numbers share the GBD intake basis. That
anchoring changes the baseline diet and is an independent switch – see
GBD Anchoring of Risk-Factor Groups (optional). Because the baseline diet feeds the
calibration, a run must consume the artefact set matching its resolved
anchoring: calibration.source: default (anchoring off) or
gbd-anchored (anchoring on); see Calibration.
Conceptual Framework¶
The health module converts dietary intake patterns into monetised health costs using epidemiological dose–response relationships from the Global Burden of Disease (GBD) Study. This section explains the key concepts and formulas.
Relative Risk¶
For a given disease \(d\) (e.g., coronary heart disease) and dietary risk factor (e.g., vegetable intake), the relative risk \(\mathrm{RR}_d(x)\) quantifies how the probability of developing that disease changes with intake level \(x\). Specifically, \(\mathrm{RR}_d(x)\) is the ratio of disease probability at intake \(x\) to the probability at some reference intake.
Example
From GBD data, vegetables and CHD: \(\mathrm{RR}_{\mathrm{CHD}}(0) = 1.0\), \(\mathrm{RR}_{\mathrm{CHD}}(100\text{g}) = 0.91\), \(\mathrm{RR}_{\mathrm{CHD}}(300\text{g}) = 0.80\). Consuming 300g/day of vegetables reduces CHD risk by 20% compared to zero intake.
For protective foods (fruits, vegetables, whole grains, etc.), RR decreases as intake increases. For harmful foods (red meat, processed meat), RR increases with intake.
Theoretical Minimum Risk Exposure Level (TMREL)¶
The TMREL, denoted \(\bar{x}\), is the counterfactual minimum-risk intake. We define:
as the reference relative risk at optimal intake. TMREL values are taken
directly from the GBD 2023 appendix (curated rr_tmrel.csv), not derived
from the curves: for protective foods it is a high real-world intake (e.g.
fruits 340-350 g/day), and for harmful foods it is typically zero. Each RR
curve is clipped at its TMREL so that intake beyond the TMREL yields no
further benefit (protective) and intake below it none (harmful). This keeps
the health cost non-negative and bounded, and avoids crediting implausibly
high intakes.
Population Attributable Fraction (PAF)¶
The population attributable fraction measures how much of the disease burden would change if intake shifted from a baseline level \(x^{\mathrm{base}}\) to a new level \(x\). It is defined as:
Interpretation:
\(\mathrm{PAF}_d(x) > 0\): intake \(x\) is healthier than baseline (disease burden decreases)
\(\mathrm{PAF}_d(x) < 0\): intake \(x\) is less healthy than baseline (disease burden increases)
\(\mathrm{PAF}_d(\bar{x})\) is the fraction of burden avoidable by shifting to optimal intake
Example
Suppose baseline vegetable intake is 150g/day with \(\mathrm{RR}_{\mathrm{CHD}}(150) = 0.87\), and we consider shifting to 300g/day with \(\mathrm{RR}_{\mathrm{CHD}}(300) = 0.80\). Then:
An 8% reduction in CHD burden is attributable to this dietary shift.
Years of Life Lost (YLL)¶
Years of life lost quantifies premature mortality by multiplying deaths by remaining life expectancy. Let \(\mathrm{YLL}_d\) denote the observed baseline YLL for disease \(d\) in a population.
When intake changes from baseline \(x^{\mathrm{base}}\) to \(x\), the change in YLL is:
Example
A population loses 50,000 years of life annually to CHD (\(\mathrm{YLL}_{\mathrm{CHD}} = 50{,}000\)). If a dietary intervention achieves \(\mathrm{PAF}_{\mathrm{CHD}} = 0.08\), then:
Multiple Risk Factors¶
When multiple dietary risk factors affect the same disease \(d\), their effects combine multiplicatively:
where \(r\) indexes risk factors and \(x_r\) is the intake for each.
Example
CHD is affected by both vegetables (\(\mathrm{RR}_{v,\mathrm{CHD}} = 0.80\)) and red meat (\(\mathrm{RR}_{m,\mathrm{CHD}} = 1.15\)). The combined effect:
Net 8% reduction in CHD risk despite increased red meat consumption.
Age-Specific Relative Risk¶
Relative risk for cardiovascular outcomes (CHD, Stroke) attenuates with age: the protective or harmful effect of dietary risk factors weakens in older age groups. T2DM and CRC have identical RR across all age groups.
The Burden of Proof tool serves only age-aggregated (“All Ages”) curves, so
the age structure is reconstructed. The attenuation is multiplicative in
log-RR and essentially exposure-independent, so each all-ages curve is
expanded as \(\mathrm{RR}_{a}(x) = \exp(\beta_{a} \cdot \log
\mathrm{RR}(x))\), with the per-(cause, age) factor \(\beta_a\) taken from
the curated rr_age_attenuation.csv (age shape from the GBD 2019 RR
appendix, normalized to GBD’s 60-64 reference age group – the age to which
GBD assigns the estimated risk curve, so the BoP “All Ages” curve is the RR at
60-64; \(\beta = 1\) for T2DM and CRC).
Since most years of life lost (YLL) from cardiovascular diseases come from older age groups, using the youngest age group’s RR would systematically overestimate health impacts. The model therefore computes YLL-weighted effective RR curves for each health cluster.
For each cluster \(c\), cause \(d\), and risk factor \(r\), the effective relative risk at intake \(x\) is:
where \(w_{a,c,d} = \mathrm{YLL}_{a,c,d} / \sum_{a'} \mathrm{YLL}_{a',c,d}\) are YLL-based age weights computed from age-specific mortality, population, and life expectancy data.
This approach is exact for causes with a single risk factor and a good approximation for causes with multiple risk factors (the approximation error is second-order, proportional to the covariance of age-specific RR curves across risk factors).
Health Cost Formulation¶
In GLADE, we define the health cost as the monetised value of years of life lost that could have been avoided by eating optimally. For a population cluster \(c\) and disease \(d\):
where \(V\) is the value per year of life lost (configured as
health.value_per_yll, default 50,000 USD). The term
\(\Delta\mathrm{YLL}_d(\bar{x})\) is the maximum YLL avoidable (at optimal
intake), while \(\Delta\mathrm{YLL}_d(x)\) is the YLL actually avoided at
intake \(x\). The difference is the YLL that could have been avoided but
wasn’t—the health cost of not eating optimally.
To get an implementation-friendly formula using relative risk factors directly, we can expand a simplify using \(\Delta\mathrm{YLL}_d(x) = \mathrm{PAF}_d(x) \times \mathrm{YLL}_{c,d}\) and the above formula for \(\mathrm{PAF_d}\):
This gives the final formula:
Key properties:
Zero cost at TMREL: When \(x = \bar{x}\), the cost is zero because we avoid as many years of life lost as possible.
Non-negative costs: Since TMREL minimises RR, we have \(\mathrm{RR}_d(x) \geq \mathrm{RR}_d^{\mathrm{ref}}\) always.
Example
Consider a cluster with:
\(\mathrm{YLL}_{\mathrm{CHD}} = 100{,}000\) years (observed CHD burden)
\(\mathrm{RR}_{\mathrm{CHD}}(x^{\mathrm{base}}) = 1.10\) (baseline diet slightly unhealthy)
\(\mathrm{RR}_{\mathrm{CHD}}^{\mathrm{ref}} = 0.85\) (at TMREL)
\(\mathrm{RR}_{\mathrm{CHD}}(x) = 0.95\) (optimised diet, not quite optimal)
\(V = 50{,}000\) USD/YLL
The health cost is approximately 455 million USD for this cluster–disease pair.
GBD Dietary Risk Factors¶
The model uses dietary risk factor definitions from the Global Burden of Disease Study 2021 [Brauer2024]. The following table reproduces a subset of these definitions from Brauer et al. (2024, Supplementary Appendix 1, p. 171).
Risk Factor |
Definition of Exposure |
Optimal Level (TMREL) |
|---|---|---|
Diet low in fruit |
Average daily consumption of fruit including fresh, frozen, cooked, canned, or dried fruit, excluding fruit juices and salted or pickled fruits |
340–350 g/day |
Diet low in vegetables |
Average daily consumption of vegetables, including fresh, frozen, cooked, canned, or dried vegetables, excluding legumes, salted or pickled vegetables, juices, nuts and seeds, and starchy vegetables |
306–372 g/day |
Diet low in whole grains |
Average daily consumption of whole grains (bran, germ, and endosperm in natural proportion) from cereals, bread, rice, pasta, etc. |
160–210 g/day |
Diet low in nuts and seeds |
Average daily consumption of nuts and seeds, including tree nuts, seeds, and peanuts |
19–24 g/day |
Diet low in legumes |
Average daily consumption of legumes and pulses, including fresh, frozen, cooked, canned, or dried legumes |
100–110 g/day |
Diet low in seafood omega-3 |
Average daily consumption of EPA and DHA (mg/day) |
470–660 mg/day |
Diet high in red meat |
Average daily consumption of unprocessed red meat (beef, pork, lamb, goat), excluding processed meats, poultry, fish, and eggs |
0–200 g/day |
Diet high in processed meat |
Average daily consumption of meat preserved by smoking, curing, salting, or chemical preservatives |
0 g/day |
Notes on current implementation:
Risk factors modelled by default: fruits, vegetables, whole_grains, nuts_seeds, legumes, red_meat (configured in
health.risk_factors). GBD also provides seafood omega-3 and processed meat risk factors, but fish/seafood and processed meat are not currently modelled as separate food groups.Processed meat in red_meat: GDD-IA’s processed/”other” red-meat category (
othr_meat) is folded into thered_meatexposure used by the health module so that consumption mass stays consistent with FAOSTAT slaughter-volume animal production (see Current Diets). Because GBD’s red-meat exposure-response curve was calibrated against unprocessed red meat intake levels, the resulting risk attribution is a slight conservative approximation: the higher per-gram carcinogenic risk that GBD assigns specifically to processed meat is not reproduced. A future improvement would be to addprc_meatas a real food group with its own RR; in the current model this trade-off is preferred over silently dropping the processed-meat mass, since closing the consumption-vs-production leak matters for emissions accounting.Disease causes modelled: CHD (coronary heart disease), Stroke, T2DM (type 2 diabetes), CRC (colorectal cancer)
Sugar: The GBD dataset includes relative risk factors for sugar-sweetened beverages, which are not represented in the model and thus not included here. No relative risk factors are given for total added sugar intake.
TMREL values: Taken from the GBD 2023 appendix (curated
rr_tmrel.csv), used to clip the curves (see TMREL and Curve Clipping)Age range: Risk factors evaluated for adults >=25 years (
health.intake_age_min). The all-ages BoP curves are expanded to all 15 adult age groups (25-29 through 95+) via the curated age-attenuation table and combined into YLL-weighted effective RR curves per health cluster (see Age-Specific Relative Risk).Intake units: Per-group basis matches the baseline-diet pipeline output (model basis; see Current Diets). GBD exposure is converted to that basis at load time via
diet.source_basisandweight_conversion.Alternative RR sources: The
health.alternative_rrconfig option allows substituting GBD dose-response curves with log-linear curves from literature meta-analyses on a per-risk-factor basis. By default, red meat uses literature estimates (Bechthold et al. 2019 for CHD/Stroke, Li et al. 2024 for T2DM, Chan et al. 2011 for CRC) with the curated age-attenuation factors applied. The log-linear assumption meansRR(x) = RR_{per\,unit}^{x/unit}. Confidence intervals propagate through the GSA quantile architecture vialog_rr_lowandlog_rr_highcolumns in the breakpoint tables.
TMREL and Curve Clipping¶
TMREL values are taken from the GBD 2023 appendix (Table 18) and stored in the
curated rr_tmrel.csv (GBD intake basis; converted to model basis at build
time, alongside the per-risk tmrel.csv consumed downstream). Each
(risk_factor, cause) curve is then clipped at its TMREL: for protective
risks the curve is truncated at the TMREL so intake beyond it gives no further
benefit; for harmful risks it is truncated below the TMREL. Because the
reference \(\mathrm{RR}_d^{\mathrm{ref}} = \mathrm{RR}_d(\bar{x})\) is the
plateau value, the modelled health cost is non-negative everywhere and zero on
the no-burden side of the TMREL, so the optimiser is never rewarded for
pushing intake to implausible levels.
Implementation Strategy¶
Embedding the health cost formulation into a linear programme requires careful handling of nonlinearities. This section provides a high-level overview of the implementation approach.
Linearizing multiplicative risk factors¶
The core challenge is that relative risks multiply across risk factors \(r\):
This product is nonlinear in the intake variables \(x_r\). This is a problem since GLADE is nominally formulated as a linear optimization model. Non-linear constraints such as the above cannot directly be incorporated into the overall linear program formulation, and generally make the optimization program more difficult to solve both theoretically and practically speaking.
In order to still incorporate the multiplicative factors, we convert multiplication to a logarithm + addition + exponential, and use piecewise-linear approximations of the logarithmic and exponential functions.
Convert multiplication to addition: \(\log(\prod_r \mathrm{RR}_{r,d}) = \sum_r \log(\mathrm{RR}_{r,d})\)
Approximate \(\log(\mathrm{RR}_{r,d}(x_r))\) as a piecewise-linear function of \(x_r\)
Approximate \(\exp(z)\) as a piecewise-linear function to recover \(\mathrm{RR}_d\)
Two-Stage Piecewise Interpolation¶
The implementation uses two formulations matched to the shape of each stage.
Stage 1: Intake → log(RR)
For each risk factor \(r\) and disease \(d\), preprocessing supplies breakpoints \((x_k, \log\mathrm{RR}_{r,d}(x_k))\) from the GBD dose-response data. Incremental variables interpolate between them. The LP fill-up formulation is exact for curves that are convex in the objective-relevant direction. Non-convex curves additionally use SOS1 segment indicators in exact mode, or segment fixing in the default relax-and-fix mode, to prevent interpolation across the convex hull.
Stage 2: Aggregated log(RR) → RR
Sum the log-RR contributions across risk factors: \(z_d = \sum_r \log\mathrm{RR}_{r,d}\). The exponential is convex, so Linopy’s pure-LP piecewise formulation bounds the YLL store below by every chord through the scaled points \((z_m, a_{c,d}(\exp(z_m)-\mathrm{RR}^{ref}_d))\). Minimising a non-negatively priced health store presses it onto this chord envelope. The same formulation enforces the sampled \(z_d\) domain and adds no Stage 2 auxiliary variables.
Health Clustering¶
Modelling health impacts for each country individually would create an intractable number of variables and constraints. Instead, countries are grouped into health clusters that share:
Similar geographic location
Similar GDP per capita (proxy for healthcare quality)
Roughly balanced population sizes
The clustering algorithm uses weighted K-means with iterative refinement. The
number of clusters is configured via health.region_clusters.
Health clusters grouping countries based on geographic proximity, GDP per capita similarity, and population balance.¶
Baseline diet-attributable chronic disease burden (years of life lost per 100,000 population) by health cluster, computed from Global Burden of Disease data. Clusters with higher burden tend to have diets with greater exposure to dietary risk factors such as low fruit and vegetable intake or high red meat consumption.¶
Solver Compatibility¶
Stage 1 uses a single delta (incremental) formulation for all solvers, and adds integer structure only where a curve actually needs it:
Convex curves (in the objective-relevant direction): the delta fill-up LP relaxation is already exact, because the health objective is monotone increasing in every log(RR) and so the LP fills the steepest-benefit segments first on its own. No integer variables are added. Harmful risk factors with a de-plateaued (linear) curve and protective curves with diminishing returns fall here.
Non-convex (S-shaped) curves: SOS1 segment indicators plus delta-y linking constraints forbid the LP from interpolating across the convex hull (which would under-count risk). On solvers without native SOS (e.g. HiGHS), linopy reformulates the SOS1 sets to binary + Big-M.
The convex/non-convex split is decided per (cluster, risk) pair, which keeps the Stage 1 MILP as small as the dose-response data allows.
Relax-and-Fix Mode¶
health.segment_formulation: relax_and_fix (the default) replaces the
SOS1 indicators with a two-pass LP scheme, so the model contains no integer
variables at all:
Solve the model without segment indicators. This is a relaxation: on non-convex curves the delta variables may interpolate across the convex hull, so the objective is a valid bound on the exact-MIP optimum.
For each non-convex (cluster, risk) pair, compute the relaxed intake and pin the delta bounds to the fill-up pattern of the segment containing it (only the active segment’s delta stays free).
Re-solve. The bound changes repair quickly from the pass-1 basis, and the solution now lies exactly on the piecewise dose-response curve.
The relative difference between the two objectives is a certified optimality
gap, checked against health.relax_and_fix_max_gap. If the check fails,
the solve first re-fixes the segments from the repaired solution (intakes
pressing against a pinned segment boundary select the neighbouring segment)
and, if the gap still exceeds the tolerance, automatically falls back to the
exact SOS1 MIP on the same model, seeded with the repaired solution as MIP
start – so a failed certificate costs extra solve time rather than an
error. On the full-resolution model the certified gap is well within the
0.1% MIP tolerance used with sos1, results agree across solvers, and the
solve is faster than the MIP even under Gurobi. Higher values per YLL
tighten rather than widen the gap: they push intakes to breakpoint corners,
where the relaxation is exact.
Because the scheme contains no integer variables it works with any LP
solver. With HiGHS, pair it with
solving.options_highs: {solver: ipm, run_crossover: on} so the relaxation
is solved by the interior-point method (the crossover basis warm-starts the
repair pass); HiGHS’s default simplex does not terminate on full-resolution
models. See Configuration for the solver options.
Delta Formulation¶
For n breakpoints \((x_0, x_1, \ldots, x_{n-1})\) with function values \((f_0, f_1, \ldots, f_{n-1})\):
Variables: δ_j ∈ [0,1] for j = 0, …, n-2 (one per segment)
Constraints:
where \(\Delta x_j = x_{j+1} - x_j\) and \(\Delta f_j = f_{j+1} - f_j\).
Why it works: The fill-up constraints ensure segments are “filled” from left to right. For a convex curve this is exactly the LP optimum (minimising \(\sum_j \delta_j \Delta f_j\) for a fixed input fills segments in increasing slope order, which equals left-to-right order iff the slopes are non-decreasing). For a non-convex curve the SOS1 indicators are needed to pin the single fractional segment.
Data Flow Overview¶
Preprocessing (workflow/scripts/prepare_health_costs.py):
Cluster countries into health regions
Compute baseline YLL and RR for each cluster–cause pair
Build breakpoint tables for piecewise interpolation
Output:
risk_breakpoints.csv,cause_log_breakpoints.csv,cluster_cause_baseline.csv
Solver (workflow/scripts/solve_model.py):
Read breakpoint tables
Create Stage 1 incremental constraints for each cluster-risk pair
Add Stage 2 convex piecewise bounds and the health cost to the objective
Detailed Implementation¶
This section provides technical details for developers working with the health module.
Data Inputs¶
workflow/scripts/prepare_health_costs.py assembles the following datasets:
Baseline diet (
processing/{name}/dietary_intake.csv): average daily food-group intake by country, merged from GDD-IA and NHANES (USA) — see Current Diets. The per-food disaggregation lives inprocessing/{name}/baseline_diet.csv.Relative risks (
processing/{name}/health/relative_risks.csv): dose–response pairs for each (risk factor, cause) combination from GBDMortality rates (
processing/{name}/health/gbd_mortality_rates.csv): cause-specific death rates by age, country and yearPopulation and life tables (
processing/{name}/population_age.csvandprocessing/{name}/health/life_table.csv): age-structured population counts and remaining life expectancy schedules
Preparation Workflow¶
The preprocessing script performs these steps:
Health clustering – groups countries into
health.region_clustersclusters using a multi-objective approach that balances:Geographic proximity (weight:
health.clustering.weights.geography)GDP per capita similarity (weight:
health.clustering.weights.gdp)Population balance (weight:
health.clustering.weights.population)
The cluster map is saved as
processing/{name}/health/country_clusters.csv.Baseline burden – combines mortality, population and life expectancy to compute years of life lost (YLL) per cluster. For each cause, it computes both total YLL and diet-attributable YLL using the population-attributable fraction. Results:
processing/{name}/health/cluster_cause_baseline.csv.TMREL derivation – finds the intake that minimises aggregate log(RR) for each risk factor. Results:
processing/{name}/health/derived_tmrel.csv.Risk-factor breakpoints – builds per-risk intake grids and evaluates \(\log(\mathrm{RR})\) at each knot. The grid domain runs from 0 to the larger of the empirical RR range and the per-capita consumption cap (
food_groups.max_per_capita, itself the storee_nom_max); capping at the consumption limit rather than a uniform generous value avoids a flat extrapolation plateau beyond the data, which would otherwise add a spurious concave kink for harmful (increasing) risk factors. Starting from the native (smooth) BoP exposure points, a Douglas-Peucker pass keeps the smallest knot set reproducing every (cluster, cause) curve – including the low/high uncertainty bounds – to withinhealth.breakpoint_rel_tolof each curve’s amplitude (default 5%). Results:processing/{name}/health/risk_breakpoints.csv.Cause-level breakpoints – constructs breakpoints for the aggregated log-RR and its exponential. Results:
processing/{name}/health/cause_log_breakpoints.csv.
From Diet to Risk Exposure¶
Per-capita intake
During optimisation, consumption is tracked using food group stores named
store_<group>_<ISO3>. For each health cluster \(c\) and risk factor
\(r\), the solver computes per-capita intake by summing store levels across
countries in the cluster:
where \(e_{i,r}\) is the store level for country \(i\) and food group \(r\) in Mt/year, and \(P_c\) is the cluster population. The factor \(10^{12}\) converts from megatonnes to grams.
Linearised relative risk curves
For every (cluster, risk) pair, incremental variables \(\delta_j \in [0,1]\) satisfy:
Aggregating across risk factors
The combined effect on each disease is:
Recovering total relative risk
Linopy bounds the health store below by the convex piecewise chord approximation of \(\exp(z)\) using precomputed breakpoints. This Stage 2 formulation is a pure LP and introduces no interpolation variables.
Health cost expression
The PyPSA store energy level encodes deviation from optimal:
measured in million YLL. The monetary contribution is
marginal_cost_storage × e.
Configuration¶
health:
# Whether to include the dietary health-burden module. When false, the
# manually-downloaded IHME GBD data is not needed (see docs/health.rst).
# IMPORTANT: this also drives diet.anchor_groups_to_gbd (sentinel
# "match_health"), so flipping it changes the baseline diet. The git-tracked
# calibration artefacts under data/curated/calibration/ are computed against a
# specific baseline diet, so after changing this (or anchoring) you must rerun
# `tools/calibrate` with matching options (see docs/calibration.rst).
enabled: false
# How non-convex dose-response curves are enforced in the optimisation:
# - "relax_and_fix": two-pass LP scheme (solve the relaxation, pin each
# non-convex curve to the segment of its relaxed intake, re-solve with a
# warm start). No integer variables, so it works with any LP solver
# (including HiGHS) and is faster than sos1 even under Gurobi. The gap
# between the two passes is certified against relax_and_fix_max_gap; if
# exceeded, the solve re-fixes from the repaired solution and ultimately
# falls back to the exact sos1 MIP seeded with the repaired solution.
# - "sos1": exact SOS1 segment indicators; the model becomes a MIP and
# needs a strong MIP solver (Gurobi).
segment_formulation: "relax_and_fix"
relax_and_fix_max_gap: 0.001 # max certified relative gap for relax_and_fix
region_clusters: 30
breakpoint_rel_tol: 0.05 # Max Stage 1 PWL deviation as a fraction of each RR curve's amplitude (5%)
log_rr_points: 15
value_per_yll: 50000 # USD_2024 per year of life lost
intake_age_min: 11 # GDD adult band starts at 11; set to 11 to retain adult intake data. Note however that GDB chronic disease risk factors are for adults of >=25 years.
# Dietary risk factors to consider (must match GBD risk-factor items)
risk_factors:
- fruits
- vegetables
- nuts_seeds
- legumes
- red_meat
- whole_grains
# GBD also covers seafood omega-3 and processed meat risk factors,
# but fish/seafood and processed meat are not modelled as food groups.
# GDB has data on sugar-sweetened beverage intake as a risk factor,
# from which we can in theory derive added sugar intake risk
# factors. The epidemiological evidence for this is, however,
# lacking, and so we don't count "sugar" as a risk factor.
# - sugar
# Health outcomes/causes to consider (must be present in IHME GBD data and relative risks)
causes:
- CHD # Coronary/Ischemic Heart Disease
- Stroke # Ischemic stroke (diet-attributable subtype)
- T2DM # Type 2 Diabetes Mellitus
- CRC # Colorectal Cancer
# Mapping of risk factors to the causes they affect
risk_cause_map:
fruits: [CHD, Stroke, T2DM]
vegetables: [CHD, Stroke]
nuts_seeds: [CHD]
legumes: [CHD]
red_meat: [CHD, Stroke, T2DM, CRC]
whole_grains: [CHD, Stroke, T2DM, CRC]
# sugar: [CHD, Stroke, T2DM, CRC]
# GBD identifiers driving the Burden-of-Proof retrieval: rei_id per risk
# factor and cause_id per cause. Stable across configs; used by
# retrieve_burden_of_proof and the id mapping in prepare_relative_risks.
gbd_rei_id:
fruits: 111
vegetables: 112
nuts_seeds: 114
legumes: 333
red_meat: 116
whole_grains: 113
gbd_cause_id:
CHD: 493 # Ischemic heart disease
Stroke: 495 # Ischemic stroke
T2DM: 976 # Diabetes mellitus type 2
CRC: 441 # Colon and rectum cancer
# Per risk-factor overrides using log-linear RR from literature CSV files.
# When a risk factor maps to a CSV path, the GBD dose-response curve is replaced
# with a log-linear curve derived from the CSV, age-corrected using relative
# attenuation factors from the GBD data.
alternative_rr:
red_meat: "data/curated/red_meat_rr_log_linear.csv"
# (Per-risk-factor basis is now declared centrally in
# diet.source_basis and applied automatically via the basis helper
# whenever the source basis differs from the food's basis declared
# in data/curated/food_basis.csv.)
# Multi-objective clustering settings for grouping countries into health clusters
clustering:
weights:
geography: 1.0 # Weight for geographic proximity
gdp: 0.5 # Weight for GDP per capita similarity
population: 0.3 # Weight for population balance across clusters
Key parameters:
region_clusters: Number of health clusters (more = finer resolution, slower)breakpoint_rel_tol: Stage 1 PWL accuracy as a fraction of each RR curve’s amplitude (default 5%)log_rr_points: Density of Stage 2 breakpointsvalue_per_yll: Monetary value per year of life lost (USD)risk_factors: Which dietary risk factors to modelrisk_cause_map: Which causes each risk factor affects
Outputs¶
The preprocessing rule saves all intermediate products under
processing/{name}/health/:
country_clusters.csv: Cluster assignmentscluster_cause_baseline.csv: Baseline YLL and RR by cluster–causecluster_summary.csv: Cluster populationsrisk_breakpoints.csv: Stage 1 breakpoint tablescause_log_breakpoints.csv: Stage 2 breakpoint tablesderived_tmrel.csv: TMREL values derived from RR curves
Plotting rules create visualisations under results/{name}/plots/.
References¶
Brauer M, Roth GA, Aravkin AY, et al. Global Burden and Strength of Evidence for 88 Risk Factors in 204 Countries and 811 Subnational Locations, 1990–2021: A Systematic Analysis for the Global Burden of Disease Study 2021. The Lancet, 2024;403(10440):2162–203. https://doi.org/10.1016/S0140-6736(24)00933-4