Tutorials
Step-by-step guides for learning joshpy.
Getting Started
Single Run & Iteration
The essential workflow: run a simulation, tweak parameters, compare results.
- Use raw
.jshcconfig files with auto-parsed parameters - Label runs with
.with_label()for easy comparison - Compare with
plot_comparison(group_by="label") - Track experiments across sessions with
ProjectCatalog
Best for: Day-to-day research iteration. Start here.
SweepManager Workflow
Systematic parameter sweeps using SweepManager:
- Builder pattern for configuration
- Automatic registry management and result loading
- Cartesian product of parameter combinations
Best for: When you know what to sweep and want to cover the space.
Analysis & Visualization
Explore and visualize simulation results:
- Data discovery with
registry.get_data_summary() - Diagnostic plots with
SimulationDiagnostics - Custom queries with
DiagnosticQueries - Direct SQL access to DuckDB
- R/ggplot2 integration for publication-quality figures
Best for: Understanding the analysis layer (works with any registry).
External Data
Preprocessing External Data
Convert geospatial data to Josh’s optimized .jshd format:
- Preprocess NetCDF, GeoTIFF, and CSV files with
cli.preprocess() - Verify data with
load_jshd() - Spatial alignment to simulation grids
Best for: Preparing climate, land cover, or other external data.
Sweeping Over External Data
Run simulations with different input data files:
FileSweepParameterfor data file sweepsCompoundSweepParameterfor co-varying file groups- Compare scenarios (e.g., SSP126 vs SSP245)
Best for: Comparing climate scenarios, sensitivity to input data.
GridSpec Variant Sweeps
Automate file sweeps using GridSpec variant declarations:
- Declare variant axes in
grid.yamlwithtemplate_pathplaceholders variant_sweep()generatesCompoundSweepParameterautomatically- Combine with
ConfigSweepParameterfor cartesian parameter x scenario sweeps - Full end-to-end example with
.josh.j2,.jshc.j2, and GridSpec
Best for: Structured projects where data files follow a naming convention by scenario.
Timestep Interventions
Use single-time external data for initialization and discrete events:
- Initialize populations from spatial inventory data
- Apply disturbance events at specific timesteps
- Conditional logic with
meta.stepCount
Best for: Initial conditions from COGs, discrete disturbance events.
Project Structure
Project Organization
Structure multi-grid, multi-model projects:
- Recommended directory layout
GridSpecfor grid geometry and data manifests.josh.j2model templates to avoid file duplication
Best for: Real projects with multiple grids or model variants.
Complete Example
Full lifecycle with all three template types working together:
- Ad-hoc iteration with GridSpec,
.josh.j2, and.jshc.j2 - Promote to a cartesian parameter x variant sweep
- Track everything with ProjectCatalog
Best for: Seeing all joshpy components in one end-to-end workflow.
Multi-Session Sweeps
Track parameter sweeps across sessions with ProjectCatalog:
- One registry per sweep, catalog indexes them all
- Deduplication: check if a sweep was already run
- Recall past sweep registries for analysis
Best for: Projects with multiple systematic sweeps to keep organized.
Inspecting Runs from the Registry
View, export, and diff stored configs and josh sources:
registry.export_config()andregistry.export_josh()for file exportregistry.compare_configs()andregistry.compare_josh()for IDE diffingpython -m joshpy.inspectCLI for terminal use- Smart file resolution (real file when unchanged, snapshot when drifted)
Best for: Understanding what changed between runs, debugging failures.
Debugging & Profiling
Bottling Runs for Reproducibility
Create self-contained archives for bug reports, archival, and sharing:
manager.run(bottle="first_failure")to capture failures automaticallyregistry.bottle("baseline")to package a past run after the fact- Archive includes
run.sh– reproduce with just Java and the JAR
Best for: Bug reports, sharing reproducible examples, long-term archival.
Debug Output Inspection
Trace agent behavior with structured debug log analysis:
- Parse and filter debug output programmatically
python -m joshpy.debugCLI with colored terminal output- Trace individual entities across timesteps
Best for: Understanding why agents behave a certain way.
Finding Bottlenecks
Two profiling approaches for different needs:
- Josh profiling (
enable_profiler=True): measure attribute evaluation time with.evalDuration– best for optimizing model logic - JFR profiling (
JfrConfig): JVM-level CPU/GC/memory analysis – best for the Josh team diagnosing runtime issues
Best for: Understanding where time is spent in your simulation.
Advanced
Adaptive Parameter Optimization
Use Optuna’s Bayesian optimization for intelligent parameter search:
OptunaStrategyfor adaptive sampling- Custom objective functions
- Efficient exploration of large parameter spaces
Best for: Finding optimal parameters without exhaustive grid search.
Low-Level Components
Use joshpy’s individual components directly:
JobExpanderfor manual job expansionRunRegistryfor direct registry managementrun_sweep()for custom execution loops
Best for: Understanding internals or building custom workflows.
Switching Josh Versions
Switch between stable, development, and custom Josh builds.
Best for: Testing new Josh features or pinning versions.
Running on Josh Cloud
Distribute simulations across Josh Cloud for parallel execution.
Best for: Large sweeps where local execution would be too slow.
Prerequisites
All tutorials assume:
- joshpy is installed with all dependencies:
pip install joshpy[full] - Josh JAR is available (auto-downloaded if needed)
- Java 17+ is installed
Recommended Order
- Single Run & Iteration – the tinkering workflow
- SweepManager – systematic parameter sweeps
- Analysis – visualization and queries
- Project Organization – multi-grid/model structure
- Preprocessing – external geospatial data
- Complete Example – everything together
Reference:
- Best Practices & Troubleshooting - registry design, error diagnosis, and practical guidance