Repository navigation
Reproducible Study Bundles
A study bundle is golgi's unit of reproducibility: a single self-contained archive of an entire study — inputs, every stage's outputs, the software version, a frozen dependency list, and an audit excerpt — with a SHA-256 hash of every file and pipeline stage. Hand it to a colleague or a reviewer and they can reconstitute the study and verify it byte-for-byte with one command.
Source: golgi/projects/bundle.py (export/import), golgi/projects/replay.py (verification),
golgi/projects/sweep_cache.py. CLI in golgi/cli.py; API in golgi.Study.
📦 Download the paper's bundles. Every figure in the paper is backed by a study bundle archived on Zenodo at doi.org/10.5281/zenodo.21300944 (concept DOI — always resolves to the latest version). Fetch and verify them all with one script:
python paper_figs/fetch_bundles.py # download + md5-verify every bundle from Zenodo python paper_figs/fetch_bundles.py --only fig06 # just one; --list to preview; --dest to choose the dir golgi replay paper_figs/out/zenodo_bundles/fig06_human_cervical_vagus.golgi.zip # verify byte-for-byte
fetch_bundles.pyfollows the concept DOI to the current version automatically, so it keeps working when a new bundle version is deposited.
A bundle is a ZIP (conventionally given the .golgi extension) that mirrors the project flat, plus a
manifest:
MANIFEST.json # schema, version, exporter, file hashes, pipeline DAG
project.json # project metadata
source/<nerve>.stl|nas|obj # the original imported geometry
mesh_config.json · electrode_config.json · conductivities.json · nerve_paths_seed_config.json
nerve.msh # mesh
nerve_paths_fibers.npz · nerve_paths_caps.json # fibers
axis_line.npz · slice_volume.npz · paths_Ve.npz · nerve_surface_Ve.npz # FEM
Ve.xdmf/.h5 · E.xdmf/.h5 # full fields
designs/<id>/… · sims/<id>/… # per-design meshes / FEM / sims
sweep_<sha>.npz · sweep_<sha>.json # sweep results
env/golgi_version.txt · env/requirements-frozen.txt # environment
audit/audit_excerpt.json # project-scoped audit rows
MANIFEST.json records the pipeline DAG and the hashes that make verification possible:
{
"schema": "golgi.study.bundle.v1",
"golgi_version": "1.0.0",
"exported_at": "2026-06-29T15:30:00+00:00",
"exported_by": "user@example.com",
"project": { "name": "...", "source_file": "..." },
"files": [ { "name": "nerve.msh", "sha256": "..." }, ... ],
"dag": [
{ "stage": "mesh", "present": true, "inputs": ["mesh_config.json", "source/*"], "outputs": ["nerve.msh"], "sha256": "..." },
{ "stage": "fem", "present": true, "inputs": ["nerve.msh", "electrode_config.json", "conductivities.json"], "outputs": ["paths_Ve.npz", ...], "sha256": "..." },
{ "stage": "fibers", "present": true, ... },
{ "stage": "fiber_sim", "present": false, ... },
{ "stage": "pop_sim", "present": false, ... },
{ "stage": "sweep", "present": true, "outputs": ["sweep_<sha>.npz", ...], "sha256": "..." }
]
}Each file's sha256 is streamed (64 KB chunks), and each stage hash is the SHA-256 of its
outputs' hashes in canonical order — so a single changed byte anywhere is detectable, and you can see
which stage diverged.
golgi export ~/projects/vagus_study vagus.golgi # pack
golgi import vagus.golgi ~/projects/vagus_copy # unpack into a fresh project
golgi replay vagus.golgi # verify (default: re-hash every file)
golgi replay vagus.golgi --json # machine-readable report
golgi figure vagus.golgi --out ./figs # render result figures to PNG (headless)See Command-Line Interface for all flags.
study.export_bundle("vagus.golgi")
golgi.Study.import_bundle("vagus.golgi", "/path/to/target")File ▸ Export study / Import study, or the Export study button in the Project Details dialog.
Every paper bundle carries the mesh, the FEM lead field, the traced fibers and the figure's
computed activation thresholds — the exact published numbers, reconstituted into the project's
sweeps/ cache (no recomputation on import). So opening a bundle in the GUI lands you in a fully
populated project: the Simulate ▸ Sweep tab shows the activation-threshold-vs-diameter scatter
straight away, and the Vₑ field / fibers render in the viewport.
To render a bundle's result figures from the command line — no GUI, no re-solve, no re-run:
golgi figure fig05_swine_cervical_vagus.golgi --out ./figsThis reads the bundle's cached threshold sweep and config field and writes PNGs (the
activation-threshold-vs-diameter scatter and the Vₑ FEM slice) using the same figure builders the
GUI uses, so the output matches what the bundle shows on import. It accepts a .golgi/.zip or an
already-extracted project dir; --name sets the filename stem.
Batch — render the whole deposit at once by pointing it at a directory of bundles:
golgi figure paper_figs/out/study_bundles --out ./figs # renders every *.golgi in the dirScope.
golgi figurerenders golgi's built-in result figures (the threshold scatter + field slice). It does not reproduce the multi-panel paper-figure layouts (e.g. the 7-panel species figures) — those are assembled by thepaper_figs/scripts (see Reproducing the Paper). A single-config bundle carries one config's slice of a figure's position×config sweep.
replay_study unpacks the bundle to a temp dir and, in the default check-only mode, re-hashes
every file and compares against the manifest. It returns a structured ReplayReport
(ok, per-file matched, and a per-stage breakdown), so a failure pinpoints the diverging stage
and output:
✗ replay FAILED · mode=check_only · 159 / 160 files verified
stage `fem` diverged:
paths_Ve.npz: (sha mismatch)
Exit code is 0 on a clean verify, 1 on any mismatch. A --full re-run-from-inputs mode is part of
the design (currently it falls back to check-only). Import re-registers the project under the importing
user and replays the audit excerpt tagged with the original provenance (see
Authentication & Audit).
The paper's figures ship as replay-verified bundles, archived on Zenodo at doi.org/10.5281/zenodo.21300944 (concept DOI) — fetch them with
python paper_figs/fetch_bundles.py; see Reproducing the Paper.
Sweep results live in <project>/sweeps/ named by a SHA over the request
(sweep_<sha>.npz + .json + CSVs), with latest markers per config. Identical sweeps hit the cache
instantly, and bundles include these results so recruitment/selectivity figures reproduce. See
Recruitment Sweeps & Selectivity.
Command-Line Interface · Python API · Reproducing the Paper · Authentication & Audit
golgi · open image-to-recruitment modeling of peripheral nerve stimulation · repository · issues · AGPL-3.0-or-later · data CC-BY-4.0
Get started
Tutorial
Build a model
Simulate & analyze
- Finite-Element Solver
- Fiber Populations & Trajectories
- Fiber Models & Activation
- Recruitment Sweeps & Selectivity
- Recording & CNAP
Share & reproduce
Scripting & scale
Reference
Research & project