Overview
Every Veydra model is a standalone Python project hosted on GitHub. You can clone any model repository and run it locally with standard Python tooling — no special platform or runtime required. This page walks through the repository structure, setup, execution, and testing workflow that all models follow.Quick Start
Requirements
Python 3.11+
A local Python installation. Any recent 3.11+ version works.
pip
Used to install dependencies from
requirements.txt.Dependencies
All models declare their dependencies inrequirements.txt. A typical model requires:
| Package | Purpose |
|---|---|
| veydra-model-standard | Base classes and utilities for VMS-compliant models |
| NumPy | Array computation and mathematical operations |
| SciPy | Scientific computing, ODE solvers, optimization |
| pytest | Running the test suite |
Repository Structure
Every model repository follows the same layout:Key Files
main.py
main.py
The command-line entry point. Initializes the model, runs a default simulation, then runs an interactive simulation with the same defaults to validate the full pipeline.
src/model.py
src/model.py
Contains the master orchestrator class (inherits from
VeydraModelStandard) and the two contract functions — initialize_model() and run_interactive_simulation(). This is where submodels are wired together, derivatives are computed, and the ODE solver is invoked.config/outputs.json
config/outputs.json
Controls which stocks and flows are included in simulation results. All variables are computed internally, but only those listed here are returned.
config/presets.json
config/presets.json
Defines named scenarios with specific parameter overrides. Each preset has an
id, a description, and a variables dict of parameter values.config/model-parameters.json
config/model-parameters.json
Full metadata for every parameter: label, min/max, step, default, units, category, and namespace. Generated automatically by the Veydra AST analysis pipeline.
The Model Contract
Every VMS-compliant model exposes two functions fromsrc/model.py:
initialize_model()— creates the model instance, runs a simulation with default parameters, and returns both the instance and the default results dict.run_interactive_simulation()— takes an existing model instance and a dict of parameter overrides, re-runs the simulation, and returns updated results. Passreturn_json=Trueto get a JSON string instead of a Python dict.
Results Format
Both functions return a results dictionary with this shape:submodel.variable_name).
Running Simulations
Default Run
Custom Parameters
You can override parameters programmatically by passing a dictionary torun_interactive_simulation():
Running Presets
Presets fromconfig/presets.json can be loaded and passed directly:
Testing
All models ship with two test files:Smoke Tests
Full Test Suite
- Default parameters — model runs and returns valid numeric results
- All presets — every preset from
config/presets.jsonis run and validated automatically
Model Architecture
Submodels
Models are decomposed into submodels — one per domain (e.g.,population_submodel.py, resource_submodel.py). Each submodel:
- Defines its own
VARIABLESdict with parameter metadata - Inherits from the
Submodelbase class inveydra_model_standard.py - Implements a
calculate_derivatives_and_flows()method
src/model.py wires all submodels together, collects their derivatives, and passes them to SciPy’s ODE solver (solve_ivp).
Parameter Namespacing
All parameters use asubmodel.variable_name naming convention to avoid collisions:
Simulation Variables
In addition to submodel parameters, every model has a set ofsimulation.* variables controlling execution:
| Variable | Default | Description |
|---|---|---|
simulation.duration | 200 | Total simulation length (years) |
simulation.time_step | 0.125 | Integration time step (years) |
simulation.start_date | 2024-01-01 | Calendar start date |
simulation.intervention_start_time | 100 | When interventions activate (years) |

