Skip to content

r.sim: Add -p flag with format=json run summary and normalize history - #7972

Merged
cwhite911 merged 3 commits into
OSGeo:mainfrom
cwhite911:r-sim-run-summary
Sep 30, 2026
Merged

cwhite911 merged 3 commits into
OSGeo:mainfrom
cwhite911:r-sim-run-summary

Conversation

@cwhite911

Copy link
Copy Markdown
Contributor

Addresses #7923.

Summary

r.sim.water and r.sim.sediment gain a -p flag and a format=plain|json option which print a summary of the run to standard output after the last map is written. -p requests printing; format only chooses the shape, so without -p nothing goes to standard output regardless of format (same as g.region). The same values are written to the history of the depth, discharge and sediment_flux maps under the same keys.

Following the review feedback on the issue, the schema is flat and keeps only the setup and run values plus an outputs array. There is no region, inputs, parameters, tool or schema_version block.

{
    "walkers_requested": 100000,
    "walkers_generated": 120000,
    "walkers_active": 112724,
    "duration": 1200,
    "simulated_time": 1199,
    "time_step": 0.26578203020127966,
    "time_coefficient": 4,
    "iterations_planned": 1128,
    "iterations_completed": 1128,
    "iterations_per_output": 564,
    "stopped_early": false,
    "elevation_min": 91.686592102050781,
    "elevation_max": 343.03448486328125,
    "mean_velocity": 9.4062040165270862,
    "mean_mannings_n": 0.050000000000000003,
    "mean_source_rate": 1.390000000000819e-05,
    "mean_infiltration": 0,
    "threads": 1,
    "outputs": [
        {
            "simulated_time": 599,
            "timestamp": "10 minutes",
            "walkers_active": 113464,
            "depth": "depth.10",
            "discharge": "discharge.10",
            "error": null,
            "walkers": null
        },
        {
            "simulated_time": 1199,
            "timestamp": "20 minutes",
            "walkers_active": 112724,
            "depth": "depth.20",
            "discharge": "discharge.20",
            "error": null,
            "walkers": null
        }
    ]
}

Top-level walkers_active and simulated_time describe the end of the run; each outputs entry holds the values at the time its maps were written. r.sim.sediment adds time_step_sediment, velocity_max and sigma_max, omits mean_infiltration, and names transport_capacity, tlimit_erosion_deposition, sediment_concentration, sediment_flux, erosion_deposition and walkers in its single outputs entry. mean_mannings_n is the harmonic mean (inverse of the mean of 1/n) and is null when undefined. Units are documented in the manuals, not in the key names.

AI Summary

Changes

  • New simlib/summary.c collects one record per output_data call and prints the JSON (via G_json_*) or plain key: value lines.
  • The three near-identical history blocks in simlib/output.c (init.walk vs init.walkers, rem. walkers vs remaining walkers, the time-serie typo, mean mann missing for depth, %e vs %f) are replaced by one helper that writes identical lines to every map, labelled with the JSON keys. A small name helper removes the six duplicated time-series branches, and the time-series map names are now freed instead of leaked.
  • main_loop records an early stop and the number of completed iterations. The simulated time of the final maps is now computed from the completed iterations rather than the loop counter, which was one past the last iteration.
  • Three printf calls in the walker loop's out-of-bounds branch become G_debug so standard output stays clean for JSON.
  • grad_check stores the elevation range and, for sediment, the sediment time step, maximum sigma and maximum velocity on Setup.
  • Both manuals gain a "Run summary" subsection with a key table and real example output (.md and .html).
  • pytest tests for both tools reuse the shared session_tools fixture from raster/conftest.py and its rows_raster plane: key sets and values, time-series entries, an early-stop case, walker vector naming, plain output, empty stdout without -p, and history contents. 12 tests pass locally.

Not in this PR

Pre-existing behavior surfaced by the summary

Two things the summary makes visible that this PR does not change, since changing them would alter results and the reference tests:

  1. time_coefficient is 4 whenever the water time step is used (so always for r.sim.water) and 1.25 when the sediment time step is smaller. The table in [Feat] r.sim.water, r.sim.sediment: add format=json run summary and normalize history metadata #7923 has this the other way round; the docs here follow the code.
  2. r.sim.sediment computes the number of iterations from the water time step in grad_check before replacing it with the smaller sediment time step. When the sediment step governs, the run covers much less simulated time than duration: on a fractal test surface a 10 minute run reported simulated_time of 1 second. This looks like a long-standing bug worth a separate issue.

Verification

Built with CMake (no warnings), pre-commit passes on all changed files. The gunittest suites need the NC dataset and are left to CI. Memory was checked with Apple's leaks on this arm64 Mac (valgrind and LeakSanitizer are unavailable there) against an unmodified build of main: leaked allocation counts match within noise for every case, and no reported stack passes through the new code.

AI assisted.

@cwhite911 cwhite911 self-assigned this Sep 29, 2026
@github-actions github-actions Bot added raster Related to raster data processing Python Related code is in Python C Related code is in C HTML Related code is in HTML module docs markdown Related to markdown, markdown files tests Related to Test Suite CMake labels Sep 29, 2026
@wenzeslaus

Copy link
Copy Markdown
Member

If you update from main, you will get fixed pytest (or at least significantly less flaky).

Comment thread raster/r.sim/simlib/summary.c Outdated
Comment thread raster/r.sim/simlib/summary.c Outdated
Comment thread raster/r.sim/simlib/summary.c Outdated
Comment thread raster/r.sim/r.sim.sediment/Makefile Outdated
Comment thread raster/r.sim/r.sim.sediment/r.sim.sediment.md Outdated
Comment thread raster/r.sim/simlib/output.c Outdated
Comment thread raster/r.sim/simlib/simlib.h Outdated
Comment thread raster/r.sim/simlib/summary.c Outdated
Comment thread raster/r.sim/r.sim.water/r.sim.water.md Outdated
Comment thread raster/r.sim/r.sim.water/r.sim.water.md Outdated
Comment thread raster/r.sim/r.sim.sediment/tests/r_sim_sediment_summary_test.py
Comment thread raster/r.sim/r.sim.water/r.sim.water.md Outdated
Add a -p flag and a format=plain|json option to r.sim.water and
r.sim.sediment which print a summary of the run (walker counts, time
step, iteration counts, mean velocity, mean Manning's n, mean source
rate, early stop, and the names and simulated times of the written maps)
to standard output. Without -p nothing is printed to standard output.

Replace the three inconsistent history blocks in simlib with one helper
whose labels are the same keys as the printed summary, and record the
same values for every written map. Free the time series map names which
were leaked before, and compute the simulated time of the final maps
from the number of completed iterations rather than the loop counter.
Convert stray printf calls in the walker loop to G_debug so standard
output stays clean.

Add pytest tests on the shared raster fixture, and document the keys and
units in both manuals.

Addresses OSGeo#7923. Seeds are left to OSGeo#7884.

AI assisted.
Report time_step as the simulated time per iteration (the time step
times the time coefficient) and drop time_coefficient,
iterations_per_output, elevation_min and elevation_max. Rename
walkers_active to walkers_remaining. Report transport_capacity and
tlimit_erosion_deposition once at the top level of the sediment summary
since they are written before the simulation starts. Emit null for a
non-finite sediment time step instead of dropping the key. List only the
given input maps in the history data source fields instead of formatting
NULL names. Reuse the simulated time helper in the main loop, link parson
only from the library, and add the SPDX header to summary.c.

AI assisted.
…ests

The number of iterations is rounded down, so the simulated time reached
is slightly less than the requested duration. Reporting it as an integer
hid that. Report it as a floating point number in the summary and in the
history, and use the same value for the map timestamps.

AI assisted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C Related code is in C CMake docs HTML Related code is in HTML markdown Related to markdown, markdown files module Python Related code is in Python raster Related to raster data processing tests Related to Test Suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] r.sim.water, r.sim.sediment: add format=json run summary and normalize history metadata

3 participants