run

cli.run

tvbo run — execute a Study or Experiment.

Implements the cardinal HPC contract:

  • --engine slurm re-emits via :mod:tvbo.cli.workflow and submits through sbatch rather than running locally.
  • --container IMAGE re-execs the run inside the named OCI image (Singularity if SINGULARITY_BIND is set in the environment, else Docker).
  • --shard i/N runs one shard of the sweep in-process (no scheduler): cell index j runs iff j %% N == i. This is what the generated sbatch script invokes for every array index.

Functions

Name Description
nested_root Where the study the tree knows as label writes, for a tree writing into base.
run Run a SPEC (experiment or study) in the selected backend.
study_path_for The directory base gives role, per the study-layout record.

nested_root

cli.run.nested_root(base, recipe_dir, label)

Where the study the tree knows as label writes, for a tree writing into base.

None — the study’s own directory — whenever the run has not been redirected, which is the CLI’s behaviour and keeps a nested study’s results in its own layout. A redirected run gives each study a subdirectory named for its label, so a run that must not write into the source tree does not write into a nested study’s either. The label rather than the recipe stem, because a sub-study written inline has no recipe of its own and inherits the holding study’s: naming the directory after that would land every inline sub-study of one recipe in a single directory, each overwriting the last.

run

cli.run.run(
    spec=typer.Argument(..., help='Path, CURIE, or DB name.'),
    backend=typer.Option(None, '--backend', '-b', help="Execution backend (tvboptim, tvb, jax, brian2, pyrates, networkdynamics, ...). Default: each experiment's declared execution.backend, else tvboptim."),
    out_dir=typer.Option(None, '--out-dir', '-o', help='Directory to write results into.'),
    results_root=typer.Option(None, '--results-root', help="Directory searched for a sibling run's saved result when this experiment's initial_state.method=from_experiment (state / parameter warm-start). Defaults to the output dir's parent; set it to point at another run's output — e.g. the group fit's results dir for a per-subject warm-start (Run A → Run B)."),
    experiment=typer.Option(None, '--experiment', help='When SPEC is a Study, run only this named experiment.'),
    analysis=typer.Option(None, '--analysis', help='When SPEC is a Study, run only these named `analyses:` (comma-separated) and no experiments — for re-deriving a container after editing its callable, which no cache invalidates on its own. An input analysis is re-run only when it has no container yet; existing ones are read as they are. Figures are not redrawn — follow with `tvbo figure render`. Local engine only, and not combinable with any flag that selects or reshapes simulation work.'),
    duration=typer.Option(None, '--duration', help='Override integration.duration (ms).'),
    engine=typer.Option('local', '--engine', '-e', help='local | slurm | snakemake | nextflow. Non-local engines re-emit via `tvbo workflow ENGINE` and submit.'),
    container=typer.Option(None, '--container', help='OCI image (e.g. ghcr.io/the-virtual-brain/tvbo:0.7.0); re-execs the same `tvbo run` inside it.'),
    shard=typer.Option(None, '--shard', '--slurm-chunk', help='Run one shard of the sweep in-process: ``i/N`` runs cells where j%N==i (no scheduler needed). ``--slurm-chunk`` is a deprecated alias.'),
    limit=typer.Option(None, '--limit', min=1, help='Run at most N cells of the sweep (a spread sample) — a quick look without needing to know the grid size. Ignored when --shard is given.'),
    subject=typer.Option(None, '--subject', help="Active subject ID for a per-subject dataset experiment: resolves and injects that subject's empirical target (e.g. their FC). Set per shard by the workflow fan-out."),
    rendered=typer.Option(None, '--rendered', help="Run a PRE-RENDERED backend script instead of generating code at run time. The spec is still loaded for orchestration (subject/dataset resolution, seeds, network observations, output layout) — only the backend code source changes: the frozen script is executed as-is. Lets a workflow kit run on a stock tvbo runtime with no codegen step. The script must match the run's backend and the (single) experiment being run."),
    set_=typer.Option([], '--set', help='Override an experiment metadata field for THIS run only (the recipe file is not modified), e.g. --set integration.duration=8 --set integration.step_size=0.05. Repeatable; dotted keys traverse attributes and keyed collections. Lets one recipe stay the single source of truth while the CLI runs it with test settings.'),
    pin=typer.Option([], '--pin', help="Pin an exploration axis to a single value for THIS run, e.g. --pin Kuramoto.omega_mean_hz=20 --pin network.conduction_speed=6. The workflow fan-out emits one --pin per fanned axis per cell: it sets the axis's parameter AND drops the axis from the sweep, so the cell is a single run at that point (its base run — and every declared observation — computed there). The model-scope sibling of --subject. Repeatable."),
    compress=typer.Option(True, '--compress/--no-compress', help='gzip-deflate the result HDF5 (default on; grids compress well). --no-compress writes uncompressed for maximum write speed.'),
    save_all=typer.Option(False, '--save-all', help='Persist every observation, including intermediates. By default only recorded outputs are saved (leaves + `record: true`); this keeps the scaffolding (e.g. a raw BOLD feeding an FC) for debugging.'),
    max_iterations=typer.Option(None, '--max-iterations', min=1, help="Smoke cap: run at most N tuning iterations per algorithm AND per stage for THIS run (the recipe is untouched). A fit's post-tuning evaluation — the memory- and time-critical part of a long-horizon fit — is independent of how many tuning iterations preceded it, so `--max-iterations 1` reaches it in minutes to verify it runs/streams within memory."),
    smoke=typer.Option(False, '--smoke', help='Shorthand for --max-iterations 1: the quickest run that still reaches the post-tuning evaluation (verify a fit executes / streams end to end).'),
    figures=typer.Option(True, '--figures/--no-figures', help="After a Study's experiments finish, render its declarative `figures:` (emit each render script and run it), so one command produces results AND figures. On by default; --no-figures skips rendering (e.g. a partial/smoke run whose panels would be placeholders). No effect on an experiment spec or a study without figures."),
    skip=typer.Option([], '--skip', help='When SPEC nests studies, skip these sub-studies by label, at any depth, comma-separated/repeatable — their committed figures/results are reused as-is. Skipping a study skips the studies it holds.'),
    dry_run=typer.Option(False, '--dry-run', help='When SPEC nests studies, list the studies, analyses and result keys that WOULD run (honouring --skip) and emit nothing.'),
    manifest_only=typer.Option(False, '--manifest-only', help='When SPEC nests studies, emit the results manifest from existing containers and authored values only — run no study or experiment. The fast refresh for the two-tier build (the heavy `tvbo run` produces the containers; this restamps the manifest the manuscript reads).'),
)

Run a SPEC (experiment or study) in the selected backend.

Resolves spec to a SimulationExperiment or SimulationStudy, executes via backend on engine, and optionally writes results to --out-dir. Non-local engines re-emit the run through tvbo workflow ENGINE and submit.

study_path_for

cli.run.study_path_for(role, base)

The directory base gives role, per the study-layout record.