Publishing a reproducible study#
Four commands take a model from one run on your machine to an archive a reviewer can rerun
with a single command. modelly run writes the outputs and a manifest that records everything
that produced them; modelly verify reruns a manifest and compares; modelly bundle packs a
run into one zip; modelly odd writes the skeleton of the model’s ODD protocol description.
All four work the same on Windows, macOS and Linux, need no network, and use git only when
it is installed.
modelly run model.py:Epidemic --scenario scenario.toml --steps 365 --out runs/
modelly verify runs/manifest.json # outputs match
modelly bundle runs/ --out epidemic-study.zip
modelly odd model.py:Epidemic > ODD.md
For reviewers#
Unpack the archive, install the lock file in a fresh environment, and verify:
python -m venv .venv && .venv/bin/pip install -r requirements.lock
.venv/bin/modelly verify manifest.json
On Windows the scripts are in .venv\Scripts\ instead of .venv/bin/.
modelly verify reruns the model with the recorded parameters, seed and step count, then
compares every output table with the recorded one, column by column and row by row. It prints
outputs match, or the first difference:
outputs differ: table 'model', column 'Gini', row 12: expected 0.4312, got 0.4415
The row is the 0-based position in the table. Before the rerun it checks the code files, the input files and the Modelly and Python versions against the record and prints what differs as notes on stderr; a note alone does not fail the check.
Numeric columns are compared with numpy.isclose; both tolerances are 0 by default, so the
values must be identical. A study run on another processor or operating system may differ in
the last bits of some floating-point results; --rtol 1e-12 (or --atol) accepts that, and a
report should say which tolerance it used.
Exit code |
|
|---|---|
0 |
outputs match |
1 |
an output differs (the first difference is printed) |
2 |
bad command line, unreadable or unsupported manifest, or the model cannot be loaded |
3 |
the model raised during the rerun (traceback on stderr) |
modelly run and modelly odd exit 0 on success, 2 for a target or scenario that cannot be
used and 3 when the model raises; modelly bundle exits 0 or 2.
For journals#
A submission that ships the bundle lets the editor check three things without reading code:
the archive’s hash matches the one cited in the paper (the bundle is byte-deterministic);
modelly verify manifest.jsonprintsoutputs matchin a fresh environment built fromrequirements.lock;ODD.mdandCITATION.cffare complete (noTODOleft).
Rerunning needs neither the authors’ machine nor a network connection.
Limits#
The code root is the folder of the model file. Source files outside it that the model imports (an installed package) are identified by
environment.packages, not by hash.Hashes are over bytes: a checkout that converts line endings (git’s
autocrlfon Windows) changes the hash of the source files, andverifynotes it. The outputs are compared by value, so the check itself still passes.Parameters given as Python tuples are stored as JSON lists.
A model that reads data files is rerun with the paths in its parameters; keep those paths relative to where the study is run, and record the files with
--input.
From Python, the same steps are modelly.provenance.run_study, verify, bundle and
odd_markdown (API).