Skip to content

Releases: VirtualPlantLab/PlantSimEngine.jl

v0.14.1

15 May 08:33
503af98

Choose a tag to compare

PlantSimEngine v0.14.1

Diff since v0.14.0

v0.14.1

Changes in this section are based on the git history since v0.14.0, corresponding to the GitHub compare view for v0.14.1.

Summary

This release adds a dependency graph visualizer and an interactive graph editor.
The new tooling makes it possible to inspect a ModelMapping, see which models
produce and consume each variable, diagnose missing initialization values, and
interactively build or revise a mapping from a browser UI.

The static graph viewer is available directly from PlantSimEngine through
write_graph_view, graph_view, and graph_view_json. The live editor is
provided by the PlantSimEngineGraphEditorExt package extension and is loaded
when HTTP.jl is available in the session. The release also includes benchmark
and CI maintenance, updated developer guidance, and a new agent skill for
working with PlantSimEngine internals.

Added

  • New dependency graph visualization API:
    graph_view, graph_view_json, compile_graph_view, and
    write_graph_view.
  • A standalone HTML graph viewer with model nodes, variable ports, hard-call
    edges, variable dependency edges, scale filters, relationship filters, search,
    overview/detail modes, and an inspector.
  • An interactive browser-based graph editor through edit_graph, backed by a
    local HTTP.jl server and WebSocket session.
  • The live graph editor runs as a package extension that depends on
    HTTP.jl; static graph visualization is available without loading
    HTTP.
  • Editing support for adding, updating, removing, and reconnecting models in a
    ModelMapping.
  • Support for starting the editor from a blank mapping with edit_graph().
  • Mapping-code generation from the editor, including using PackageName
    statements for loaded model packages and a top-level mapping variable.
  • Save, autosave, recent-file reopening, undo, and redo support in live graph
    editing sessions.
  • Model discovery helpers:
    available_processes, available_models, model_descriptor, and
    model_constructor_descriptor.
  • Editor suggestions for adding producer models from input variables and
    consumer models from output variables.
  • Cycle diagnostics in the graph UI, including highlighted cycle edges and an
    interactive way to wrap selected inputs in PreviousTimeStep.
  • Visualization of required initialization values and graph diagnostics even
    when a mapping is incomplete or cyclic.
  • A new documentation page for graph visualization and editing:
    docs/src/step_by_step/graph_visualization_editor.md.
  • Playwright end-to-end tests for the browser editor and new Julia tests for
    the static graph viewer and editor extension.
  • A local plantsimengine Codex skill describing the package architecture and
    contributor workflow.

Fixed

  • Fixed type promotion behavior with ModelMapping.
  • Fixed benchmark and documentation issues that were blocking CI.

Merged pull requests:

Closed issues:

  • Dependency graph visualization (#108)
  • API for supercharging models with more informations about time steps, multiscale mapping... (#121)
  • Variable timestep considerations (#124)
  • Simplified development workflow for modelers (#139)

v0.2.0

15 May 12:01
696c477

Choose a tag to compare

What's Changed

  • CompatHelper: bump compat for MultiScaleTreeGraph to 0.9, (keep existing compat) by @github-actions[bot] in #15

Full Changelog: v0.1.9...v0.2.0

v0.14.0

18 Mar 17:24
a6949b9

Choose a tag to compare

PlantSimEngine v0.14.0

Diff since v0.13.2

Summary

This release introduces first-class multi-rate execution for MTG simulations.
The main addition is a new configuration layer around ModelMapping and
ModelSpec, making it possible to run models at different cadences in the same
simulation, define how inputs and weather are resampled across rates, and export
derived time series at requested clocks.

The release also consolidates mapping APIs, improves validation and
introspection, updates the package to the newer MultiScaleTreeGraph release,
and substantially expands the documentation.

Changes in this section are based on the git history since v0.13.2, corresponding to the GitHub compare view for v0.14.0.

Breaking changes

The main user-facing breaking change in this release is the move toward
Symbol-based scale names in mappings and multi-scale configuration. Code that
still uses string scales such as "Leaf" or "Plant" should be updated to use
symbols such as :Leaf and :Plant, especially in ModelMapping(...),
MultiScaleModel(...), and explicit multi-rate bindings. ModelList is also on
the deprecation path in favor of ModelMapping, so this release is a good time
to migrate mapping code to the newer API.

Added

  • First-class multi-rate MTG execution support, including runtime clocks,
    temporal input resolution, weather sampling, stream publishing, scoping, and
    requested-output export.
  • New multi-rate configuration building blocks:
    ModelMapping, ModelSpec, ClockSpec, TimeStepModel,
    InputBindings, MeteoBindings, MeteoWindow, OutputRouting, and
    ScopeModel.
  • New model traits for multi-rate inference and defaults:
    output_policy, timestep_hint, and meteo_hint.
  • New export API for resampled output streams with OutputRequest(...) and
    collect_outputs(...).
  • New debugging/introspection helpers:
    resolved_model_specs(mapping) and explain_model_specs(mapping_or_sim).
  • Support for calendar-aligned weather windows through PlantMeteo windows such
    as CalendarWindow(:day, ...).
  • Support for Dates periods in model timesteps
    (Dates.Minute, Dates.Hour, Dates.Day, ...), in addition to numeric steps
    and ClockSpec.
  • Interpolate() as a policy for slow-to-fast couplings, alongside clarified
    Integrate() and Aggregate() behavior.
  • A dedicated benchmark suite for the multi-rate implementation.
  • A new multi-rate documentation track:
    introduction,
    step-by-step tutorial,
    and advanced configuration.

Changed

  • ModelMapping is now the canonical mapping type for both single-scale and
    multiscale usage. It replaces the old "plain Dict for multiscale,
    ModelList for single-scale" split.
  • Multi-rate execution is now inferred from the mapping/runtime configuration.
    The old explicit multirate=true flag has been removed.
  • Runtime timestep resolution is now explicit and consistent:
    ModelSpec.timestep > non-default timespec(model) > meteo base timestep.
  • Input-source inference is more capable and more predictable:
    same-scale unique producers are preferred, mapped variables participate in
    inference, and the runtime gives better errors when ambiguity remains.
  • Multi-rate weather aggregation now relies on PlantMeteo’s sampling APIs and
    default transforms for common Atmosphere variables.
  • Same-rate hard dependencies no longer require the explicit multi-rate
    machinery that slower/faster couplings need.
  • Scale names are moving toward Symbol consistently across the API and docs.
  • Package compatibility was updated to newer core dependencies:
    Julia 1.10, MultiScaleTreeGraph = 0.15.1, PlantMeteo = 0.8.2,
    Term = 2.

Deprecated

  • run!(::ModelList, ...) is deprecated. Use run!(ModelMapping(...), ...)
    instead.
  • run! with collections of ModelList is deprecated. Use collections of
    ModelMapping instead.
  • run!(mtg, mapping::AbstractDict, ...) is deprecated. Construct a
    ModelMapping(...) first, or call run!(mtg, ModelMapping(mapping), ...).
  • String scale names are deprecated in multi-scale mapping APIs. Use Symbol
    scales such as :Leaf instead of "Leaf".
  • ModelList remains available for now but is being phased out in favor of
    ModelMapping.

Migration guide

1. Replace ad hoc mappings with ModelMapping

If you previously used ModelList(...) directly for single-scale runs, or a
plain Dict for MTG runs, migrate to ModelMapping(...).

Before:

leaf = ModelList(
    process1 = Process1Model(),
    process2 = Process2Model(),
    status = (x = 1.0,),
)

mapping = Dict(
    :Leaf => (ToyAssimModel(),),
    :Plant => (ToyGrowthModel(),),
)

After:

leaf = ModelMapping(
    process1 = Process1Model(),
    process2 = Process2Model(),
    status = (x = 1.0,),
)

mapping = ModelMapping(
    :Leaf => (ToyAssimModel(),),
    :Plant => (ToyGrowthModel(),),
)

2. Use rate-specific behavior in ModelSpec(...)

When a model should run at a cadence different from the meteo, wrap it in
ModelSpec(...) and add the relevant transforms.

Typical pattern:

mapping = ModelMapping(
    :Leaf => (
        ModelSpec(HourlyLeafModel()) |> TimeStepModel(1.0),
    ),
    :Plant => (
        ModelSpec(DailyPlantModel()) |>
        TimeStepModel(Dates.Day(1)) |>
        InputBindings(; A=(process=:hourlyleaf, var=:A, scale=:Leaf, policy=Integrate())) |>
        MeteoBindings(; T=MeanWeighted()),
    ),
)

You do not always need explicit InputBindings(...) or MeteoBindings(...):
the runtime can infer simple cases, and PlantMeteo already defines defaults for
common weather variables. But this is now the place where explicit multi-rate
behavior belongs.

3. Ensure weather rows define duration

When meteo is provided, duration is now mandatory on every weather row.
Without it, PlantSimEngine cannot determine the meteo base timestep or perform
correct aggregation over coarser model clocks.

Before:

Weather([
    Atmosphere(T=20.0, Wind=1.0, Rh=0.65),
])

After:

Weather([
    Atmosphere(duration=Dates.Hour(1), T=20.0, Wind=1.0, Rh=0.65),
])

4. Use Symbol scale names

If your mappings still use string scales, migrate them to symbols.

Before:

mapping = ModelMapping(
    "Leaf" => (ToyAssimModel(),),
)

ModelSpec(DailyPlantModel()) |>
MultiScaleModel([:A => "Leaf"])

After:

mapping = ModelMapping(
    :Leaf => (ToyAssimModel(),),
)

ModelSpec(DailyPlantModel()) |>
MultiScaleModel([:A => :Leaf])

5. Prefer OutputRequest(...) for explicit exported clocks

If you want clean hourly/daily/weekly exports from a multi-rate simulation, use
OutputRequest(...) in tracked_outputs and optionally return them directly
from run!.

req = OutputRequest(:Plant, :plant_assim_d;
    name=:plant_assim_daily,
    clock=ClockSpec(24.0, 0.0),
)

out_status, exported = run!(
    mtg,
    mapping,
    meteo;
    tracked_outputs=[req],
    return_requested_outputs=true,
)

This is the recommended way to export resampled streams instead of manually
rebuilding them from mixed-rate internal outputs.

6. Add trait defaults where they improve clarity

For reusable models, it is now often worth defining:

  • output_policy(::Type{<:MyModel}) to describe the natural aggregation rule
    for a produced variable,
  • timestep_hint(::Type{<:MyModel}) to declare valid/preferred cadences,
  • meteo_hint(::Type{<:MyModel}) to declare default weather aggregation rules.

This is optional, but it makes inference more useful and error messages more
actionable.

Documentation

The documentation was significantly reorganized and expanded around this
release:

  • multi-rate now has dedicated introduction, tutorial, and advanced pages;
  • the model execution and API pages describe the new scheduling and inference
    rules;
  • outdated draft pages were removed from the published docs;
  • multiscale docs were refreshed to match the newer mapping APIs.

Internal and maintenance notes

  • CI and benchmark workflows were refreshed around the new multi-rate runtime.
  • Downstream/benchmark setup was cleaned up as part of the release prep.
  • Several doc and benchmark follow-up commits after the core implementation were
    included in this release range.

Included pull requests

Read more

v0.13.2

11 Aug 12:43
ec1d3b1

Choose a tag to compare

PlantSimEngine v0.13.2

Diff since v0.13.1

Merged pull requests:

Closed issues:

  • Don't print the graph if too many models (#109)
  • Information display, printing (#133)
  • Regression in benchmark for ModelList (#145)

v0.13.1

09 Aug 07:15
af81844

Choose a tag to compare

PlantSimEngine v0.13.1

Diff since v0.13.0

Patch

Fixing performance regressions:

Full Changelog: v0.13.0...v0.14.0

Merged pull requests:

Closed issues:

  • Add dependency tree in the ModelList (#29)
  • Change default output structure (#123)
  • Improve performance of inputs pre-allocation step in run! (#146)
  • Improve performance of dependency graph creation (#148)

v0.13.0

28 May 19:20
a3abf9e

Choose a tag to compare

PlantSimEngine v0.13.0

Diff since v0.12.0

Breaking changes

PRs:

Summary: The outputs are now stored differently during the simulation for better performance. You now need to call convert_outputs on the outputs of the simulation, e.g. if the simulation outputs are stored outputs_sim:

df_dict = convert_outputs(outputs_sim, DataFrame)

df_dict will be a dictionary of dataframes, with the scale as the key and the results for this scale as the value.

Full Changelog: v0.12.0...v0.13.0

Merged pull requests:

Closed issues:

  • ModelList -> better manage models that takes values from the previous time-step (#85)
  • BoundsError with a single model and several Weather timesteps (#86)
  • XPalm Github action for testing (#90)
  • Non-obvious Julia errors (#92)
  • Documentation improvements (#93)
  • Collapse similar codepaths, and create a mapping for single-scale simulations (#101)
  • No outputs when simulating a mapping with one meteo timestep (#105)
  • Multiscale : outputs not saved when dependency graph only has one depth level (#111)

PlantSimEngine v0.12.0

14 Apr 14:33
7e352d4

Choose a tag to compare

Release notes:

Breaking changes

Most of the main features are breaking changes. You can update by simply updating function names and kwargs as mentioned in these release notes, or read the new documentation.

Expect an upcoming release of downstream packages PlantBiophysics and XPalm to update to the API changes.

Main features

  • Added a means of filtering outputs in ModelList mode, to align with multi-scale simulations, via a tracked_outputs keyword argument, changing the simulation output structure
  • Major documentation overhaul, with several more pages, extended examples/tutorials, a multi-scale toy plant example with PlantGeom 3D visualization, additional explanations on subtler aspects of simulations, specific pages explaining how to work with data or troubleshoot issues...

API changes

  • Removed Multi-object parallelisation, to be potentially reintroduced later
  • Renamed the outputs kwarg to tracked_outputs in multi-scale mode
  • Handle corner cases where user-requested outputs were empty in multi-scale mode, or missing weather data
  • Renamed some of the outputs functions to convert_outputs, for clarity
  • Changed mapping kwarg to mapped_variables for MultiScaleModel objects
  • The run! function returns the output data instead of the whole GraphSimulation in multi-scale mode
  • Some run! function default behaviours are changed to be made consistent between single- and multi-scale.
  • A couple of warnings may have changed.

CI-related changes

  • Added benchmarks and performance-related tests, as well as a Github Action tracking changes over time. More work needed.
  • Added a test to validate output filtering changes, that combines a meteo, a modellist and a list of outputs and runs it in ModelList mode, then converts to multiscale and compares results
  • Added a naive test that tries different meteo/modellist-mapping/outputs combos and expects either a successful run! or a dimensional mismatch

Fixed issues

#86, #105, #111

Generated release notes:

What's Changed

Full Changelog: v0.11.3...v0.12.0

v0.11.3

17 Jan 10:17
0d3652c

Choose a tag to compare

PlantSimEngine v0.11.3

Diff since v0.11.2

Merged pull requests:

  • Incomplete working version of a modellist to mapping conversion function (#122) (@Samuel-amap)

Closed issues:

  • API : enable passing in a vector providing values per timestep in multi-scale modelling (#117)

v0.11.2

18 Nov 16:55
d892f2c

Choose a tag to compare

PlantSimEngine v0.11.2

Diff since v0.11.1

Merged pull requests:

v0.11.1

25 Oct 12:27
a8578f6

Choose a tag to compare

PlantSimEngine v0.11.1

Diff since v0.11.0

Merged pull requests:

  • Fix issue of overspecialisation of outputs Dict of variables requested by the user (#104) (@Samuel-amap)