Skip to main content

Run, sweep, and analyze JuPedSim scenarios from the web-app JSON schema.

Project description

jupedsim-scenarios

CI PyPI version Python versions Downloads Ruff Checked with mypy License: MIT

Python toolkit for running, sweeping, and analyzing JuPedSim scenarios authored in the Web-Based JuPedSim editor.

Status

Alpha (0.3.3). Single-run (run_scenario), Monte Carlo sweeps (run_sweep — now multiprocess), and a jps-scenarios CLI are shipped. Restartable / resumable sweeps land in 0.4.0.

Install

pip install jupedsim-scenarios

For development from a clone:

pip install -e ".[dev]"

Single-run usage

from jupedsim_scenarios import Scenario, run_scenario

scenario = Scenario(
    raw=data_dict,                          # the JSON exported by the web app
    walkable_area_wkt=data_dict["walkable_area_wkt"],
    model_type="CollisionFreeSpeedModel",
    seed=42,
    sim_params=data_dict["config"]["simulation_settings"]["simulationParams"],
    source_path="my_scenario.json",
)
result = run_scenario(scenario, seed=42)
print(result.metrics["evacuation_time"])
df = result.trajectory_dataframe()
result.cleanup()

A higher-level load_scenario(path) is available for zipped exports (JSON + WKT file in the same archive or directory).

Mutating a scenario — copy first, then assign

Scenario is a mutable object. Direct assignments and add_* / remove_* / set_* calls all change the instance in place:

base = load_scenario(...)
base.seed = 99            # this mutates `base` — every later use sees seed=99

That's fine when you only want one variant. For sweeps or any time you want to keep the original intact, call .copy() first and edit the clone:

trial = base.copy()
trial.seed = 99
trial.max_simulation_time = 60
# base is untouched

run_sweep does this for you per trial. The pattern only matters when you build variants manually (see examples/howtos/10_sweep_via_copy.ipynb).

Monte Carlo sweep

from jupedsim_scenarios import load_scenario, run_sweep

base = load_scenario("faster_is_slower.zip")

sweep = run_sweep(
    base,
    axes={
        "v0":    [0.8, 1.2, 1.6, 1.8],
        "model": ["CollisionFreeSpeedModel", "AnticipationVelocityModel"],
    },
    apply={
        "v0":    lambda s, v: s.set_agent_params(0, desired_speed=v),
        "model": lambda s, v: s.set_model_type(v),
    },
    seeds=range(40, 50),
    output_dir="runs/",
)

df = sweep.to_dataframe()       # one row per (v0, model, seed) trial
print(df.groupby(["v0", "model"])["evacuation_time"].agg(["mean", "std"]))
sweep.cleanup()                 # delete the per-trial sqlite files

The library walks the cartesian product of the named axes, calls each axis's apply function on an isolated .copy() of the base scenario, runs the simulation, and tabulates the results. Anything the Scenario.set_* mutators can change is fair game for sweeping.

Pass workers=N (or workers=0 for one worker per CPU) to run trials in parallel:

sweep = run_sweep(base, axes=..., apply=..., seeds=range(40, 50), workers=4)

Mutations are applied in the calling process — only the resulting mutated Scenario crosses the process boundary, so user apply lambdas don't need to be picklable.

Factory-style sweeps

If the scenario can't be expressed as one base mutated by axis values — typically because the geometry itself depends on the trial parameters — use run_sweep_from_factory instead. Each trial parameter dict is handed to your factory; the factory builds a fresh Scenario and optionally returns a payload that rides along on Trial.extras:

from jupedsim_scenarios import run_sweep_from_factory

def build_loop(params):
    scenario, geometry = build_loop_scenario(
        num_agents=params["num_agents"],
        spacing=TRACK_LENGTH / params["num_agents"],
    )
    return scenario, geometry  # extras travel with the trial

sweep = run_sweep_from_factory(
    build_loop,
    trials=[{"num_agents": n} for n in (50, 100, 200, 400)],
    seeds=[42],
    workers=4,
)
df = sweep.to_dataframe()           # one row per trial; "num_agents" is a column
for t in sweep.trials:
    geometry = t.extras             # whatever the factory returned alongside

Command line

jps-scenarios run scenario.json --seed 42 --out trajectory.sqlite

Runs a single scenario and prints a one-line JSON summary (evacuation_time, agent counts, sqlite_file) to stdout. Useful in CI or scripted pipelines; notebook workflows should stay on the Python API.

Documentation

The full API reference and the bottleneck tutorial are built with Sphinx (stack mirrors jupedsim.org: sphinx-book-theme

  • sphinx-autoapi + myst-nb). Every push to main rebuilds and deploys the site via the .github/workflows/docs.yml GitHub Pages workflow.

To build locally:

pip install -e .
pip install -r docs/requirements.txt
sphinx-build -b html docs/source docs/build/html
open docs/build/html/index.html        # macOS; use xdg-open on Linux

conf.py mirrors examples/bottleneck_tutorial.ipynb into the docs tree at build time, so there's no committed duplicate. If you edit the notebook, regenerate it first with python examples/_build_notebook.py and re-execute with jupyter nbconvert --to notebook --execute --inplace examples/bottleneck_tutorial.ipynb before building the docs.

Roadmap

Release Scope
0.1.0 Verbatim extraction of Scenario + run_scenario from web app.
0.2.0 run_sweep(scenario, axes={...}, seeds=...).
0.3.0 Multiprocess worker pool + jps-scenarios CLI.
0.3.1 Public aliases for helpers shared with Web-Based-Jupedsim.
0.3.2 First PyPI release.
0.3.3 Fix: checkpoints honored without journeys (#8).
0.3.4 run_sweep_from_factory for factory-style sweeps (this release, #11).
0.4.0 Restartable / resumable sweeps, persisted results.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jupedsim_scenarios-0.6.0.tar.gz (74.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jupedsim_scenarios-0.6.0-py3-none-any.whl (58.7 kB view details)

Uploaded Python 3

File details

Details for the file jupedsim_scenarios-0.6.0.tar.gz.

File metadata

  • Download URL: jupedsim_scenarios-0.6.0.tar.gz
  • Upload date:
  • Size: 74.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for jupedsim_scenarios-0.6.0.tar.gz
Algorithm Hash digest
SHA256 429786d28ececa1a27f81ed334a22bc9ffc63b199267c0fcd9a4e6c6ea5b0219
MD5 0ffbbdafb48eff2a785e86b524f84e1c
BLAKE2b-256 017a3998e0b37dd1c7617c29527fe0fea67fd219e8a8e87cbce35ce197156afb

See more details on using hashes here.

Provenance

The following attestation bundles were made for jupedsim_scenarios-0.6.0.tar.gz:

Publisher: workflow.yml on PedestrianDynamics/jupedsim-scenarios

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jupedsim_scenarios-0.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for jupedsim_scenarios-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0928d0f66594e7e67fdef59fef3ac7f36be6ee0a0eaa24664ccf5ce2440e0b0b
MD5 2796994584c7374afdf456249f5badf8
BLAKE2b-256 65a3adb79dcb547faa4e7465430c2afc8c4a695187efc362e095f35d81e7a803

See more details on using hashes here.

Provenance

The following attestation bundles were made for jupedsim_scenarios-0.6.0-py3-none-any.whl:

Publisher: workflow.yml on PedestrianDynamics/jupedsim-scenarios

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page