Skip to content

aerocm.utils.functions

Utility functions for the AeroCM package.

emission_profile_function

emission_profile_function(start_year, t0, time_horizon, profile, unit_value)

Generate an emission profile based on the specified type (e.g. pulse) and time horizon.

Parameters:

Name Type Description Default
start_year int

Start year of the simulation.

required
t0 int

Year when the emission event occurs.

required
time_horizon int

Duration of the emission profile in years.

required
profile str

Type of emission profile: "pulse", "step", or "1% growth".

required
unit_value float

Magnitude of the emission event.

required

Returns:

Name Type Description
emissions ndarray

Emission profile array.

Raises:

Type Description
ValueError

If an invalid profile type is provided.

Source code in aerocm/utils/functions.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
def emission_profile_function(
        start_year: int,
        t0: int,
        time_horizon: int,
        profile: str,
        unit_value: float
):
    """
    Generate an emission profile based on the specified type (e.g. pulse) and time horizon.

    Parameters
    ----------
    start_year : int
        Start year of the simulation.
    t0 : int
        Year when the emission event occurs.
    time_horizon : int
        Duration of the emission profile in years.
    profile : str
        Type of emission profile: "pulse", "step", or "1% growth".
    unit_value : float
        Magnitude of the emission event.

    Returns
    -------
    emissions : np.ndarray
        Emission profile array.

    Raises
    ------
    ValueError
        If an invalid profile type is provided.
    """
    if profile not in ["pulse", "step", "1% growth"]:
        raise ValueError(f"Invalid profile '{profile}'. Choose from 'pulse', 'step', or '1% growth'.")
    emissions = np.zeros(t0 - start_year + time_horizon + 1)
    if profile == "pulse":
        emissions[t0 - start_year] = unit_value
    elif profile == "step":
        for k in range(0, time_horizon + 1):
            emissions[t0 - start_year + k] = unit_value
    elif profile == "1% growth":
        for k in range(0, time_horizon + 1):
            emissions[t0 - start_year + k] = unit_value * (1 + 0.01) ** k
    return emissions

plot_simulation_results

plot_simulation_results(ds, data_var, species=None, title=None, figsize=(8, 5), stacked=False, ax=None, label_prefix=None)

Plot selected species over time for a chosen data variable.

Parameters:

Name Type Description Default
ds Dataset

Dataset with dimensions (species, year).

required
data_var str

Name of the data variable to plot (e.g. 'temperature_change').

required
species list[str]

Species names to plot. If None, all species are plotted.

None
title str

Custom plot title (ignored if ax is provided and already has one).

None
figsize tuple

Figure size in inches (only used if ax is None).

(8, 5)
stacked bool

If True, plots a stacked area chart instead of individual lines.

False
ax Axes

Existing matplotlib Axes to draw on. If None, a new figure is created.

None
label_prefix str

Optional prefix to add to species labels (useful when plotting multiple datasets).

None

Raises:

Type Description
TypeError

If 'ds' is not an xarray.Dataset.

ValueError

If 'data_var' is not found in the dataset or if specified species are missing.

Source code in aerocm/utils/functions.py
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
def plot_simulation_results(
    ds: xr.Dataset,
    data_var: str,
    species: list[str] | None = None,
    title: str | None = None,
    figsize=(8, 5),
    stacked: bool = False,
    ax: plt.Axes | None = None,
    label_prefix: str | None = None,
):
    """
    Plot selected species over time for a chosen data variable.

    Parameters
    ----------
    ds : xr.Dataset
        Dataset with dimensions (species, year).
    data_var : str
        Name of the data variable to plot (e.g. 'temperature_change').
    species : list[str], optional
        Species names to plot. If None, all species are plotted.
    title : str, optional
        Custom plot title (ignored if ax is provided and already has one).
    figsize : tuple, optional
        Figure size in inches (only used if ax is None).
    stacked : bool, optional
        If True, plots a stacked area chart instead of individual lines.
    ax : matplotlib.axes.Axes, optional
        Existing matplotlib Axes to draw on. If None, a new figure is created.
    label_prefix : str, optional
        Optional prefix to add to species labels (useful when plotting multiple datasets).

    Raises
    ------
    TypeError
        If 'ds' is not an xarray.Dataset.
    ValueError
        If 'data_var' is not found in the dataset or if specified species are missing.
    """

    # --- Validation ---
    if not isinstance(ds, xr.Dataset):
        raise TypeError("Input 'ds' must be an xarray.Dataset.")
    if data_var not in ds.data_vars:
        raise ValueError(f"'{data_var}' not found in dataset. Available: {list(ds.data_vars)}")

    if species is not None:
        missing = [s for s in species if s not in ds.species.values]
        if missing:
            raise ValueError(f"Species not found in dataset: {missing}")
        da = ds[data_var].sel(species=species)
    else:
        da = ds[data_var]

    years = da.year.values
    data = da.transpose("year", "species").values  # shape (year, species)
    species_list = da.species.values

    # --- Prepare axes ---
    if ax is None:
        fig, ax = plt.subplots(figsize=figsize)
        new_fig = True
    else:
        new_fig = False

    # --- Plot ---
    if stacked:
        ax.stackplot(years, data.T, labels=[f"{label_prefix or ''}{sp}" for sp in species_list])
    else:
        for i, sp in enumerate(species_list):
            label = f"{label_prefix or ''}{sp}"
            ax.plot(years, data[:, i], label=label)

    # --- Format ---
    if new_fig:
        ax.set_xlabel("Year")
        ax.set_ylabel(data_var.replace("_", " ").title())
        ax.set_title(title or f"{data_var.replace('_', ' ').title()}")
        ax.legend(title="Species", loc="upper left")
        ax.grid(True, linestyle="--", alpha=0.6)
        plt.tight_layout()
    else:
        # If reusing an existing axis, only update legend
        ax.legend(loc="upper left")

    return ax

show_model_info

show_model_info(obj)

Pretty-print all public attributes (with current/default values) and methods of a class or instance.

Source code in aerocm/utils/functions.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def show_model_info(obj: type | str):
    """
    Pretty-print all public attributes (with current/default values)
    and methods of a class or instance.
    """
    if isinstance(obj, str):
        if obj == "LWE":
            obj = LWEClimateModel
        elif obj == "GWP*":
            obj = GWPStarClimateModel
        elif obj == "FaIR":
            obj = FairClimateModel

    # Determine the class
    cls = obj if inspect.isclass(obj) else obj.__class__

    # --- Collect attributes (class + instance) ---
    attributes = {
        k: v for k, v in vars(cls).items()
        if not k.startswith("_") and not inspect.isroutine(v)
    }

    # --- Collect public methods ---
    methods = [
        name for name, func in inspect.getmembers(cls, predicate=inspect.isroutine)
        if not name.startswith("_")
    ]

    # --- Pretty print ---
    print(f"\nClass: {cls.__name__}")
    print("\nAttributes:")
    if attributes:
        for name, value in attributes.items():
            print(f"  • {name}: {value}")
    else:
        print("  (No public attributes)")

    print("\nMethods:")
    if methods:
        for name in methods:
            print(f"  • {name}()")
    else:
        print("  (No public methods)")