Community Model

This executable article mirrors the lightest-weight path through the wrapper: create a community model in Python, run a projection in R through mizer, and bring the results back into Python objects.

Create And Project

import pymizer as mz

params = mz.new_community_params(no_w=20)
sim = params.project(
    t_max=5,
    dt=0.1,
    t_save=1,
    progress_bar=False,
)

The projection returns a wrapped MizerSim object that we can query directly from Python:

times = sim.times()
biomass = sim.biomass()

print(times)
print()
print(biomass.to_string())
[0. 1. 2. 3. 4. 5.]

species     Community
time                 
0        34926.721959
1        46146.578715
2        50503.969482
3        52101.198790
4        52906.953622
5        53493.609873

Inspect Outputs

The returned objects are chosen to feel natural in Python:

abundance = sim.abundance()
resource = sim.n_resource()
initial_n = params.initial_n()
initial_resource = params.initial_n_resource()
pred_rate = sim.pred_rate()

for name, value in [
    ("times", times),
    ("biomass", biomass),
    ("abundance", abundance),
    ("resource", resource),
    ("initial_n", initial_n),
    ("initial_resource", initial_resource),
    ("pred_rate", pred_rate),
]:
    print(f"{name}: {type(value).__name__}")
times: ndarray
biomass: DataFrame
abundance: DataFrame
resource: DataArray
initial_n: DataArray
initial_resource: Series
pred_rate: DataArray

A quick look at the resource spectrum from the first saved time step:

print(resource.isel(time=0).to_pandas().head().to_string())
w
7.85e-11    5.197440e+23
2.34e-10    5.555675e+22
6.95e-10    5.938602e+21
2.07e-09    6.347922e+20
6.16e-09    6.785455e+19

Focus On A Size Range

The high-level summary methods can also be narrowed to a size range without leaving Python:

community_biomass = sim.biomass(min_w=1, max_w=1000)
community_abundance = sim.abundance(min_w=1, max_w=1000)
mean_weight = params.mean_weight(min_w=1, max_w=1000)
large_fish = params.proportion_of_large_fish(threshold_w=100)

def show(value):
    print(value.to_string() if hasattr(value, "to_string") else value)

print(community_biomass.to_string())
print()
print(community_abundance.to_string())
print()
show(mean_weight)
print()
show(large_fish)
species     Community
time                 
0        10020.682639
1        19750.053450
2        23042.991156
3        23508.256860
4        23267.975191
5        22722.944352

species    Community
time                
0        1349.415244
1        3381.503254
2        2472.634763
3        1960.837934
4        1937.719916
5        2077.203355

7.425944450680252

0.32061391752645263

Edit And Reuse A Model

The wrapper preserves the mizer pattern where parameter edits return a new model object:

edited = params.set_metadata(
    title="Community demo",
    description="Edited from Python",
)

steady_ready = edited.set_initial_values(sim)

search_vol = params.search_volume(as_xarray=False).copy()
search_vol[:] = search_vol * 1.05

retuned = params.set_search_volume(search_vol)

This pattern also applies to set_interaction(), set_reproduction(), set_max_intake_rate(), set_metabolic_rate(), and set_pred_kernel().

Steady-State Helpers

For steady-state-oriented workflows, pymizer exposes the mizer helpers directly. These heavier examples are left unevaluated in the prototype so the rendered article stays fast:

steady_params = params.project_to_steady(
    t_per=0.5,
    t_max=0.5,
    dt=0.1,
    progress_bar=False,
    info_level=0,
)

For larger packaged models such as NS_params, you can also use:

ns_params = mz.load_dataset("NS_params")
ns_steady = ns_params.steady(
    t_per=1.5,
    t_max=1.5,
    dt=0.1,
    progress_bar=False,
    info_level=0,
)

Notes

  • The model construction and projection are still performed by the R mizer package.
  • The Python layer mainly handles conversion, object wrapping, and ergonomics.
  • When debugging environment problems, it is worth checking both Python and R package availability.

This first executable article keeps the code path small on purpose. Once the Quarto workflow is in place, the same pattern can be extended to the larger North Sea and plotting articles.