Skip to content

Reproducible Study Bundles

Max Haberbusch edited this page Jul 10, 2026 · 6 revisions

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.py follows the concept DOI to the current version automatically, so it keeps working when a new bundle version is deposited.


What's in a bundle

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

The manifest

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.


Export, import, replay

From the command line

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.

From Python

study.export_bundle("vagus.golgi")
golgi.Study.import_bundle("vagus.golgi", "/path/to/target")

In the GUI

File ▸ Export study / Import study, or the Export study button in the Project Details dialog.


Cached results + rendering figures

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 ./figs

This 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 dir

Scope. golgi figure renders 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 the paper_figs/ scripts (see Reproducing the Paper). A single-config bundle carries one config's slice of a figure's position×config sweep.


How replay verifies

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 cache

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.


See also

Command-Line Interface · Python API · Reproducing the Paper · Authentication & Audit

Clone this wiki locally