Exercise 02: Diagnostics
This exercise introduces reusable diagnostics from the workshop helper script so later exercises can load and reuse them directly.
Loading dependencies
using CairoMakie
using Agate
using Oceananigans.Units: day
workshop_script = let dir = @__DIR__
while !isfile(joinpath(dir, "src", "AgateWorkshop.jl"))
parent = dirname(dir)
parent == dir && error("Could not find src/AgateWorkshop.jl")
dir = parent
end
joinpath(dir, "src", "AgateWorkshop.jl")
end
include(workshop_script)
mkpath(joinpath("outputs"))
mkpath(joinpath("figures"))
Run the Quick start model
The diagnostics operate on saved box-model output. We reuse the wrapper from Exercise 01 to create a small output file.
bgc = default_quickstart_bgc()
run = run_box_model(bgc; filename=joinpath("outputs", "02_diagnostics_quick_start.jld2"))
timeseries = read_box_tracer_timeseries(run.filename, run.tracer_syms)
times = timeseries.times
data = timeseries.data
[ Info: Initializing simulation...
[ Info: ... simulation initialization complete (2.559 ms)
[ Info: Executing initial time step...
[ Info: ... initial time step complete (150.237 μs).
[ Info: Simulation is stopping after running for 3.977 seconds.
[ Info: Simulation time 1095 days equals or exceeds stop time 1095 days.
Tracer concentrations
plot_box_timeseries accepts the complete named tuple returned by read_box_tracer_timeseries and plots each tracer in a separate panel.
tracer_concentrations_figure_path = joinpath("figures", "02_diagnostic_tracer_concentrations.png")
fig_tracers = plot_box_timeseries(timeseries)
save(tracer_concentrations_figure_path, fig_tracers; px_per_unit=1)
display(fig_tracers)
fig_tracersComparison
The same helper can also compare two or more box-model time series. The default detritus remineralization rate is 0.1213 / day. Here we compare the default run with a higher remineralization case, 0.25 / day, for all shared tracers.
high_remineralization_bgc = Agate.Models.NiPiZD.construct(;
parameters = (detritus_remineralization = 0.25 / day,),
)
high_remineralization_run = run_box_model(
high_remineralization_bgc;
filename=joinpath("outputs", "02_diagnostics_high_detritus_remineralization.jld2"),
)
high_remineralization_timeseries = read_box_tracer_timeseries(
high_remineralization_run.filename,
high_remineralization_run.tracer_syms,
)
comparison_figure_path = joinpath("figures", "02_diagnostic_timeseries_comparison.png")
fig_comparison = plot_box_timeseries(
[timeseries, high_remineralization_timeseries];
labels=["default", "detritus remineralization = 0.25 / day"],
)
save(comparison_figure_path, fig_comparison; px_per_unit=1)
display(fig_comparison)
fig_comparisonRelative nitrogen contributions
plot_contributions shows two coordinated stacked-area diagnostics: living versus non-living nitrogen, and phytoplankton versus zooplankton contributions to living biomass.
nitrogen_contributions_figure_path = joinpath("figures", "02_diagnostic_relative_nitrogen_contributions.png")
fig_nitrogen = plot_contributions(times, data)
save(nitrogen_contributions_figure_path, fig_nitrogen; px_per_unit=1)
display(fig_nitrogen)
fig_nitrogenCommunity-weighted mean size
Agate.jl stores plankton equivalent spherical diameter (ESD) metadata on constructed biogeochemistry objects. plot_cwm_size accepts a box-model time series and the matching biogeochemistry object, then computes the community-weighted mean size for all plankton, phytoplankton, and zooplankton.
cwm_size_figure_path = joinpath("figures", "02_diagnostic_cwm_size.png")
fig_size = plot_cwm_size(timeseries, bgc)
save(cwm_size_figure_path, fig_size; px_per_unit=1)
display(fig_size)
fig_sizeCommunity-weighted mean size comparison
The same helper can compare multiple runs. Each time series is paired with a biogeochemistry object because the plankton sizes are defined by the model, and different models may have different plankton groups or size structures.
cwm_size_comparison_figure_path = joinpath("figures", "02_diagnostic_cwm_size_comparison.png")
fig_size_comparison = plot_cwm_size(
[timeseries, high_remineralization_timeseries],
[bgc, high_remineralization_bgc];
labels=["default", "detritus remineralization = 0.25 / day"],
)
save(cwm_size_comparison_figure_path, fig_size_comparison; px_per_unit=1)
display(fig_size_comparison)
fig_size_comparisonParameter bars
The same helper can also inspect model parameters directly. Here we plot the default maximum phytoplankton growth-rate values for the plankton types represented in the model.
parameter_bar_figure_path = joinpath("figures", "02_diagnostic_mumax_parameter_bars.png")
fig_mumax_parameter = plot_plankton_parameter_bars(
bgc,
:maximum_growth_rate;
ylabel = "maximum_growth_rate",
title = "Maximum growth rate by phytoplankton type",
)
save(parameter_bar_figure_path, fig_mumax_parameter; px_per_unit=1)
display(fig_mumax_parameter)
fig_mumax_parameter