
# A new approach to determine national greenhouse gas budgets

This repository contains the code and data accompanying the article:

Partanen, A.-I., Ekholm, T., Seppälä, J., Weaver, S., Palosuo, T., Grassi, G., Smith, C., Kulovesi, K., Laine, H., & Ollikainen, M. (2026). A new approach to determine national greenhouse gas budgets. *Environmental Research Letters*. [https://doi.org/10.1088/1748-9326/ae9628](https://doi.org/10.1088/1748-9326/ae9628).

The repository provides:
- Fully reproducible analysis scripts
- Input datasets
- Processed outputs (a separate output.zip file)
- Figures used in the publication, along some additional figures

---

## Repository Structure
```
ghgbudgets/
│
├── LICENSE
├── README.md
│
|── .env
├── budget_functions.py
├── common.py
├── fair_runs.py
│
├── script_00_master.py
├── script_01_process_ghg_emissions_fi.py
├── script_02_plot_non_co2_ghg_emissions_fi.py
├── script_03_non_co2_analysis_fi.py
├── script_04_non_co2_analysis_gl.py
├── script_05_prep_real_countries.py
├── script_06_run_fair_real_countries.py
├── script_07_non_co2_normalization.py
├── script_08_indirect_effects.py
├── script_09_sample_budgets.py
├── script_10_plot_budget_terms_pdfs.py
├── script_11_calculate_best_estimates.py
├── script_12_plot_non-co2_ghg_adjustments.py
│
├── data/
│   ├── input/
│   └── output/
│
├── sensitivity/
│   ├── normalization/         # N-split sensitivity (equal-split vs. Dirichlet, N=1–200)
│   │   ├── config.py
│   │   ├── io_helpers.py
│   │   ├── script_01_run_fair.py
│   │   ├── script_02_sens_normalization.py
│   │   ├── script_03_plot_summary.py
│   │   ├── script_04_diagnostic_timeseries.py
│   │   └── script_05_analyse_real.py
│   └── scenario/              # SSP scenario sensitivity (SSP1-2.6 / SSP2-2.6)
│       ├── config.py
│       └── script_01_run_pipeline.py
│
└── figures/
```

---

## 1. Installation & Requirements

### Python version
- Python **3.10** (as pinned in `environment.yml`)

### Recommended installation (reproducible)
Create the environment from the provided YAML:

```bash
mamba env create -f environment.yml
mamba activate ghgbudgets
```

### Core runtime dependencies
If you prefer to install manually rather than using the environment file, the analysis requires:

```
python=3.10
fair=2.2.4
numpy=2.2.6
scipy=1.15.2
pandas=2.2.2
xarray=2024.7.0
matplotlib=3.10.9
netcdf4
openpyxl=3.1.4
tqdm=4.66.5
python-dotenv=1.0.1
python-kaleido=0.2.1
poppler=24.08.0
pooch=1.8.2
```

### FaIR calibration package
To reproduce results using the official FaIR calibration **v1.6.0** by Smith et al. (2024) (Reference: https://doi.org/10.5194/gmd-17-8569-2024):

1. Download the calibration dataset fair_calibrate.zip from Zenodo: [https://doi.org/10.5281/zenodo.18828694](https://doi.org/10.5281/zenodo.18828694) 
   
2. Unpack the archive anywhere on your system (e.g., `~/data/fair_calibrate/`).

3. If you have the calibration dataset elsewhere, edit your `.env` file so that `FAIR_CALIBRATION_DIR` points to the unpacked directory:
```bash
FAIR_CALIBRATION_DIR="/path/to/fair_calibrate"
```
---

## 2. How to Run the Analysis

Before running, make sure the `.env` file is configured with the correct path to your FaIR calibration directory (see Section 1).

> **Computational cost:** Scripts 03, 04, and 06 each run the full 841-member FaIR ensemble and take several hours on a modern laptop. The normalization sensitivity (`sensitivity/normalization/`) adds a similar cost. Scripts 01, 02, 08–12 are fast (minutes). The scenario sensitivity (`sensitivity/scenario/`) re-runs scripts 03, 04, 07–12 under alternative SSPs and takes a similar time to the main pipeline.

Run the complete workflow:

```bash
python script_00_master.py
```

Or execute individual steps:

```bash
# 1) Preprocess emissions (Finland)
python script_01_process_ghg_emissions_fi.py

# 2) Plot non-CO₂ GHG emissions (Finland)
python script_02_plot_non_co2_ghg_emissions_fi.py

# 3) Non-CO₂ GHG warming contribution analysis (Finland)
python script_03_non_co2_analysis_fi.py

# 4) Non-CO₂ warming contribution analysis (Global)
python script_04_non_co2_analysis_gl.py

# 5) Prepare per-country real-country emission trajectories
python script_05_prep_real_countries.py

# 6) Run FaIR removal scenarios for each real country
python script_06_run_fair_real_countries.py

# 7) Non-CO₂ GHG normalisation factor (equal-split N=200 baseline)
python script_07_non_co2_normalization.py

# 8) Process and plot indirect effects
python script_08_indirect_effects.py

# 9) Sample GHG budgets with Monte Carlo
python script_09_sample_budgets.py

# 10) Plot time evolution and probability density distributions of GHG budget terms
python script_10_plot_budget_terms_pdfs.py

# 11) Calculate best estimates for adjustment terms and GHG budgets
python script_11_calculate_best_estimates.py

# 12) Plot non-CO₂ GHG adjustments at national and global levels
python script_12_plot_non-co2_ghg_adjustments.py
```

---

## 3. Scripts Overview

### `.env`
An environment file for the FaIR model.

### `budget_functions.py`
Functions used in calculating GHG budgets for script_09_sample_budgets.py and script_11_calculate_best_estimates.py

### `common.py`
A module containing general settings for plots, directories and some shared functions.

### `fair_runs.py`
Functions to setup and run FaIR ensembles and make slight post-processing of the results.

### Analysis scripts

#### `script_00_master.py`
Master script that runs all the other scripts to reproduce the analysis.

#### `script_01_process_ghg_emissions_fi.py`
Script to interpolate annual emissions of non-CO2 GHGs for Finland and convert units to be compatible with the FaiR model. Emissions are saved in CSV files for later use. 

#### `script_02_plot_non_co2_ghg_emissions_fi.py`
Script to plot non-CO₂ GHG emissions of Finland. 

#### `script_03_non_co2_analysis_fi.py`
Script to run FaIR and calculate the non-CO2 GHG warming contribution for Finland.

#### `script_04_non_co2_analysis_gl.py`
Script to run FaIR and calculate the non-CO2 warming contribution terms at global level.

#### `script_05_prep_real_countries.py`
Reads the real-country-level dataset (PRIMAP-SSPIAMIE, Gütschow et al. 2021, https://essd.copernicus.org/articles/13/1005/2021/), converts to FaIR units, and writes one emission CSV per country to `data/output/real_countries/{scen}/` (one file per ISO3, plus `ROW.csv` and `country_list.csv`).

#### `script_06_run_fair_real_countries.py`
Runs FaIR removal scenarios for each real country (and a simultaneous-removal scenario). Writes `data/output/dT_real_countries.nc` (SSP1-1.9) or `data/output/dT_real_countries_{scen}.nc` (other SSPs).

#### `script_07_non_co2_normalization.py`
Computes the per-config sub-additivity correction factor *k = ΔT_sim / (ΔT_FI + Σ_{c≠FIN} ΔT_c)* using real-country decompositions and writes `data/output/non_co2_normalization_factor.csv`. Also produces distribution plots for *k* and Finland's raw vs normalised future non-CO₂ warming.

#### `script_08_indirect_effects.py`
Script to process and plot indirect effects at global and national level.

#### `script_09_sample_budgets.py`
Script to carry out Monte Carlo sampling to get uncertainty estimates for the adjustment terms and GHG budgets.

#### `script_10_plot_budget_terms_pdfs.py`
Script to make plots of time evolution and probability density functions of individual GHG budget terms.

#### `script_11_calculate_best_estimates.py`
Script to calculate best estimates for adjustment terms and GHG budgets.

#### `script_12_plot_non-co2_ghg_adjustments.py`
Script to plot the time evolution of non-CO₂ GHG adjustments at national and global level.

### Sensitivity analyses

#### `sensitivity/normalization/`
Tests robustness of the main-pipeline normalisation choice (equal-split, N=200) across different numbers of hypothetical countries (N=1–200) and random splits (Dirichlet vs. equal-split). Configuration in `sensitivity/normalization/config.py`. Scripts run in order 01→05:

1. `script_01_run_fair.py` — FaIR removal runs for each N-split specification.
2. `script_02_sens_normalization.py` — Computes k, WE_FI_norm, and adj_FI_norm for each spec; writes `normalization_sensitivity_table.csv`.
3. `script_03_plot_summary.py` — Summary plots of residual, k, and adjustment across N values.
4. `script_04_diagnostic_timeseries.py` — Diagnostic warming time series for selected specs.
5. `script_05_analyse_real.py` — Validation diagnostic: computes k from real-country-level FaIR runs and overlays the main-pipeline equal-split N=200 distribution.

#### `sensitivity/scenario/`
Tests sensitivity of the budget results to the background SSP scenario. Uses SSP1-2.6 for non-CO₂ GHG warming and SSP2-2.6 for indirect LULUCF effects (instead of SSP1-1.9 and SSP2-1.9 used in the main pipeline). Configuration in `sensitivity/scenario/config.py`. The single script `script_01_run_pipeline.py` calls the parameterised main-pipeline functions (scripts 03–12) with redirected SSP and output paths.

---

# 4. Input Files

All input datasets are located in `data/input/`. The global emission and forcing data sets required for the FaIR runs located at the FaIR calibration directory.

See [`data/input/README.md`](data/input/README.md) for full column definitions and units.

### Real-country-level emissions
- `PMSSPIE_05Feb20.csv` — Country-level GHG emission trajectories 1850–2100 (Gütschow et al. 2021, PRIMAP-SSPIAMIE, https://doi.org/10.5194/essd-13-1005-2021). Used by `script_05` to build per-country FaIR inputs.

  **This file is not included in the repository** (642 MB). Download it from Zenodo:
  1. Go to [https://doi.org/10.5281/zenodo.3638137](https://doi.org/10.5281/zenodo.3638137)
  2. Download `PMSSPIE_05Feb20.csv`
  3. Place it at `data/input/PMSSPIE_05Feb20.csv`

### Finland's historical GHG inventory
- `finland_historical_emissions_incl_lulucf.csv` — Finland's national GHG inventory actuals including LULUCF (1990–2024), all species in Gt CO₂-eq/yr.

### Datasets for indirect effects on managed land
- `indirect_1990-2020_fi.csv` — Historical indirect effects in Finland (1990–2020) from 16 global models (Grassi et al., 2023). Reference: https://doi.org/10.5194/essd-15-1093-2023
- `indirect_1990-2020_gl.csv` — Historical global indirect effects (1990–2020) from 16 global models (Grassi et al., 2023).
- `indirect_ssp219_fi.csv` — National projections of indirect effects under SSP2-1.9 for Finland (Grassi et al., 2021). Reference: https://doi.org/10.1038/s41558-021-01033-6
- `indirect_ssp219_gl.csv` — Global projections of indirect effects under SSP2-1.9 (Grassi et al., 2021).
- `indirect_ssp226_fi.csv` — National projections of indirect effects under SSP2-2.6 for Finland (Grassi et al., 2021). Used by the scenario sensitivity analysis.
- `indirect_ssp226_gl.csv` — Global projections of indirect effects under SSP2-2.6 (Grassi et al., 2021).

### Non-CO₂ emissions datasets
- `nonco2_ghg_emissions_ffi_fi.csv` — Projected non‑CO₂ GHG emissions from fossil fuels, agriculture, and waste sectors in Finland (2020–2050, 5-year steps, Gt CO₂-eq/yr).
- `nonco2_ghg_emissions_lulucf_fi.csv` — Projected non‑CO₂ GHG emissions from the LULUCF sector in Finland (same format).

---

# 5. Output Files

All outputs are generated to `data/output/`. Alternatively, you can download the output.zip separately.

See [`data/output/README.md`](data/output/README.md) for full variable definitions and units.

### Main results
- `best_estimates.csv` — Best estimates for adjustment terms and GHG budgets (Gt CO₂-eq) for each allocation convention.
- `sampled_results.csv` — Medians and 95 % confidence intervals for adjustment terms and GHG budgets from 1 000 000 Monte Carlo realizations.

### Full sampled data
- `sampled_input_AR6_tcre.nc` — Sampled input variables for adjustment terms and GHG budget calculations (1 000 000 realizations).
- `sampled_AR6_tcre.nc` — Sampled adjustment terms and GHG budget calculations (1 000 000 realizations).
- `best_estimates_AR6_tcre.nc` — Best estimates for adjustment terms and GHG budgets in a NetCDF file (single realization).

### Processed results
- `non_co2_normalization_factor.csv` — Per-config sub-additivity normalisation coefficient *k* and supporting quantities for all 841 FaIR configurations.
- `indirect_effects_ssp219.csv` — Interpolated LULUCF indirect effects for the SSP2-1.9 projection: unadjusted data from Grassi et al. (2021) and adjusted data with 66 % and 95 % confidence intervals.
- `non_co2_warming_contributions_fi.csv` — Per-FaIR-config warming contribution of Finland's future (2020–2050) non-CO₂ GHG emissions and GWP100-equivalent warming.
- `non_co2_warming_contributions_gl.csv` — Per-FaIR-config global non-CO₂ warming decomposition.

### Processed emission time series
- `ghg_emissions_fi.csv` — Finland's annual GHG emissions 1990–2050, inventory actuals (1990–2024) combined with scenario projections (2025–2050), in Gt CO₂-eq/yr.
- `ghg_emissions_fair_fi.csv` — Same coverage in FaIR-native units (CO₂: Gt CO₂/yr; CH₄/N₂O: Mt/yr; F-gases: Gt CO₂-eq/yr).
- `nonco2_ghg_emissions_fi.csv` — Annual interpolated non-CO₂ GHG emissions in Finland for 2020–2050 including all sectors. Emissions in Gt CO₂-eq/yr (AR6 GWP100).
- `nonco2_ghg_emissions_fair_fi.csv` — Same for 2020–2050 in FaIR-native units.
- `nonco2_ghg_emissions_gl.csv` — Global annual non-CO₂ GHG emissions 1750–2050, Gt CO₂-eq/yr (AR6 GWP100).

### Model outputs for surface temperature from the FaIR model
- `dT_real_countries.nc` — Per-country non-CO₂ GHG warming contributions for 117 real countries (plus synthetic ROW) over the 841-member ensemble (timebounds × config).
- `global_default.nc` — SSP1-1.9: Historical and SSP1-1.9 scenario (1750–2050).
- `non_co2_ghg_stop_gl.nc` — As SSP1-1.9, but non-CO₂ GHG emissions reset to pre-industrial baseline from 2020.
- `no_non_ghg_gl.nc` — As SSP1-1.9, but no non-GHG forcing.
- `no_non_co2_ghgs_gl.nc` — As SSP1-1.9 but no non-CO₂ GHGs.
- `co2_only_gl.nc` — As SSP1-1.9 but only CO₂ emissions.
- `dT_non_co2_ghg_2020_2050_fi.nc` — As SSP1-1.9 but Finland's non-CO₂ GHG emissions subtracted for 2020–2050.
- `dT_non_co2_ghg_2020_2050_gwp100_fi.nc` — As SSP1-1.9 but Finland's GWP100-equivalent non-CO₂ emissions subtracted for 2020–2050.

### Sensitivity analysis outputs

#### `data/output/sensitivity/normalization/`
Produced by `sensitivity/normalization/` scripts.
- `fair_runs/dT_equal_split_N{N}.nc` (N ∈ {1, 2, 5, 50, 100, 200}) — FaIR removal runs for N equal hypothetical countries; same variable structure as `dT_real_countries.nc`.
- `normalization_sensitivity_table.csv` — Normalisation coefficient *k*, sub-additivity residual, and adjustment for each N and method.
- `real_country_k_per_config.csv` — Per-FaIR-config *k* from the real-country decomposition.
- `diagnostic_dT_timeseries.csv` — Ensemble-mean annual warming time series for each N specification.

#### `data/output/sensitivity/scenario/`
Full re-run of the main pipeline under SSP1-2.6 (non-CO₂) and SSP2-2.6 (indirect effects).
Output file set mirrors the main pipeline; see [`data/output/README.md`](data/output/README.md) for variable definitions.
Key differences: `indirect_effects_ssp226.csv` (SSP2-2.6) and `dT_real_countries_ssp126.nc` (SSP1-2.6 base).

---

# 6. Figures

Figures used in the paper are saved to the `figures/` directory. Alternatively, you can download the figures.zip separately.

---

# 7. License

Licensed under the **MIT License** (see `LICENSE`).

---

# 8. Citation

If you use this code or data, please cite the dataset:

Partanen, A.-I., Ekholm, T., Seppälä, J., Weaver, S., Palosuo, T., Grassi, G., Smith, C., Kulovesi, K., Laine, H., & Ollikainen, M. (2026). Data and code for "A new approach to determine national greenhouse gas budgets" [Data set]. Finnish Meteorological Institute. https://doi.org/10.57707/fmi-b2share.9hxst-jfe98

and the accompanying paper:

Partanen, A.-I., Ekholm, T., Seppälä, J., Weaver, S., Palosuo, T., Grassi, G., Smith, C., Kulovesi, K., Laine, H., & Ollikainen, M. (2026). A new approach to determine national greenhouse gas budgets. *Environmental Research Letters*. [https://doi.org/10.1088/1748-9326/ae9628](https://doi.org/10.1088/1748-9326/ae9628).

