Multiple emission inventories

In this example, no time evolution file is given, but multiple emission inventories are given as input. OpenAirClim will interpolate between discrete inventory years.

Imports

If the openairclim package cannot be imported, make sure that you have installed openairclim properly (see User Guide → Installation).

import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
from openairclim.utils.create_artificial_inventories import (
    ArtificialInventoryDict,
    convert_xr_dict_to_nc,
)
import openairclim as oac

xr.set_options(display_expand_attrs=False)
<xarray.core.options.set_options at 0x7f1aecd7cec0>

Input files

In order to be able to execute this example simulation, two types of input are required.

  • Configuration file multi_inv.toml

  • Emission inventories rnd_inv_20XX.nc

Emission inventories

  • Artificial (random) emission inventories generated with OpenAirClim

  • Inventory years: 2000, 2020, 2040, 2060, 2080, 2100

  • Emissions increase linearly with each year (relative to 2000)

The inventories are generated in the input directory of this demo. The random seed is fixed so that the example gives reproducible results.

np.random.seed(42)
rnd_inv_dict = ArtificialInventoryDict(year_arr=[2000, 2020, 2040, 2060, 2080, 2100]).create()
convert_xr_dict_to_nc(rnd_inv_dict, prefix="rnd_inv", out_path="../input/")

Simulation run

oac.run("multi_inv.toml")
2026-10-16 10:43:11,382 INFO main:449 (run): 
-------------- OPENAIRCLIM MAIN RUN LOG --------------
oac version: 0.20.0
timestamp: 2026-10-16 10:43:11.382826
input file: multi_inv.toml
user: runner
platform: Linux 6.17.0-1022-azure
oac_premium available: False

NOTE:
OpenAirClim is currently in development phase.
The computed output is not to be used for scientific
purposes until the release of our publication.
The NOx response surfaces using the tagging method
are not validated and can produce misleading results
(output species CH4, O3, PMO and SWV).
------------------------------------------------------
START OF LOG

2026-10-16 10:43:11,385 INFO read_config:537 (check_config): Configuration file checked.
2026-10-16 10:43:11,386 INFO read_config:572 (create_output_dir): Create new output directory results
2026-10-16 10:43:11,429 INFO read_netcdf:204 (open_inventories): Emission inventories openend, attribute sections and time constraints checked successfully.
2026-10-16 10:43:11,430 INFO read_netcdf:257 (_resolve_aircraft_list): No ac data variable found in the emission inventories. Reverting to 'DEFAULT' aircraft from config file.
2026-10-16 10:43:11,630 INFO main:313 (_calc_sub_species_response): No subsequent species (PMO) defined in config.
2026-10-16 10:43:11,776 INFO main:529 (run): Execution time: 0.3934597969055176 sec
2026-10-16 10:43:11,777 INFO main:530 (run): 

END OF LOG
------------------------------------------------------

Results

Time series

  • Emission sums

  • Concentrations

  • Radiative forcings

  • Temperature changes

results_ds = xr.load_dataset("results/multi_inv.nc")
display(results_ds)
<xarray.Dataset> Size: 17kB
Dimensions:        (ac: 2, time: 101)
Coordinates:
  * ac             (ac) <U7 56B 'DEFAULT' 'TOTAL'
  * time           (time) int64 808B 2000 2001 2002 2003 ... 2097 2098 2099 2100
Data variables:
    emis_CO2       (ac, time) float64 2kB 413.0 425.2 ... 1.646e+03 1.657e+03
    emis_distance  (ac, time) float64 2kB 2.68e+10 2.76e+10 ... 1.063e+11
    emis_H2O       (ac, time) float64 2kB 162.1 166.8 171.6 ... 645.8 650.4
    conc_CO2       (ac, time) float64 2kB 0.053 0.1047 0.1559 ... 8.243 8.356
    RF_CO2         (ac, time) float64 2kB 0.0008739 0.001722 ... 0.1062 0.1076
    RF_cont        (ac, time) float64 2kB 0.01033 0.01055 ... 0.03251 0.03276
    RF_H2O         (ac, time) float64 2kB 0.0003413 0.0003527 ... 0.001354
    dT_CO2         (ac, time) float64 2kB 6.656e-05 0.0001903 ... 0.06977
    dT_cont        (ac, time) float64 2kB 0.0001652 0.0003156 ... 0.004768
    dT_H2O         (ac, time) float64 2kB 2.6e-05 4.998e-05 ... 0.0009609
Attributes: (9)
# Plot Radiative Forcing and Temperature Changes

ac = "TOTAL"
species = ["CO2", "H2O", "cont"]
colors = ["tab:gray", "tab:blue", "tab:cyan"]

fig, ax = plt.subplots(ncols=2, figsize=(10, 5))
ax[0].grid(True)
ax[1].grid(True)
for spec, color in zip(species, colors):
    rf = results_ds[f"RF_{spec}"].sel(ac=ac) * 1000
    dt = results_ds[f"dT_{spec}"].sel(ac=ac) * 1000
    rf.plot(ax=ax[0], color=color, label=spec)
    dt.plot(ax=ax[1], color=color, label=spec)
ax[0].set_ylabel("Radiative Forcing [mW/m²]")
ax[1].set_ylabel("Temperature Change [mK]")
ax[0].legend()
ax[1].legend()
<matplotlib.legend.Legend at 0x7f1ae7e66e40>
../../_images/multi_inv_5_1.png