Analyses¶
python -m sbmlsim.run runs the analyses of a model package from the command line: its simulation experiments, fits, profile likelihoods, scans, sensitivity and uncertainty analyses, the build of its models and the actions of its own. It runs an analysis of a project from a spec, a small YAML or JSON file of its settings, into an output directory. The same analysis runs whole on one machine or in units on several machines, which merge to the result of the whole run, so a fit of 64 repeats or a scan of 10000 points can be spread over a cluster with simrun and give the same numbers as on a laptop.
Quick start¶
The HCTZ example of the fitting has a project, examples.hctz_fitting.project:PROJECT. Run from the root of the repository, which python -m puts on the path, list its analyses:
kind name description
simulate all the simulation experiments of the project
fit PK fit of the problem 'PK'
identifiability PK profile likelihoods of the fit of the problem 'PK'
fisher PK Fisher information of the fit of the problem 'PK'
report PK report of the fit of the problem 'PK'
petab PK PEtab v2 problem of the fit problem 'PK'
fit IV fit of the problem 'IV'
...
scan dose oral doses of 12.5, 25 and 50 mg over one day
scan sobol Sobol design of the dissolution and the renal excretion of a 25 mg oral dose
sensitivity sobol sobol indices of the scan 'sobol'
uncertainty cl the AUC of a 25 mg oral dose under a renal excretion uncertain by 30 %
A spec names the project and the analysis:
and the run fits the problem, then profiles the parameters of the fit and writes the report of both:
python -m sbmlsim.run fit fit.yaml --out results/fit
python -m sbmlsim.run identifiability profiles.yaml --out results/profiles --input fit=results/fit
python -m sbmlsim.run report report.yaml --out results/report --input fit=results/profiles
where profiles.yaml and report.yaml hold the same project and subset. The fit uses every CPU it may use, see CPU quota, --workers 4 limits it.
The command¶
python -m sbmlsim.run <kind> <spec> --out DIR [--workers N] [--resume] [--provenance FILE] [--input PORT=PATH ...] [--summary FILE]
python -m sbmlsim.run plan <kind> <spec> [-o FILE]
python -m sbmlsim.run unit <kind> <spec> <index> --out DIR [--input PORT=PATH ...]
python -m sbmlsim.run merge <kind> <spec> --out DIR [--input PORT=PATH ...] [--summary FILE]
python -m sbmlsim.run list <project> [--json] [--experiments]
python -m sbmlsim.run verify <subcommand> ...
The first form runs an analysis whole (its command is run, which may be left out). plan, unit and merge run it in units, list lists the analyses of a project as a table or, with --json, as JSON; with --experiments it also lists the groups of the simulation experiments and every experiment (kind simulate, which runs them by these names), which imports the experiments. verify is a family of commands that compare the results of two checkouts, see Verify. --profile, anywhere in the command line, runs a command which writes into --out under the sampling profiler of python 3.15, see Profiling.
| argument | meaning |
|---|---|
<kind> |
the kind of analysis, see Kinds, or module:attribute of a kind of another package |
<spec> |
the spec, a JSON file (.json) or a YAML file; a relative path of a path field of the spec, e.g. the input fit, is relative to the file, a path inside another value, e.g. in optimizer, is taken as it is |
--out DIR |
the output directory; a whole run needs it empty or not existing (unless --resume), while the unit and merge commands of one plan share it, see Units; nothing is written outside of it |
--workers N |
the number of processes, every CPU of the quota for a kind which uses several and 1 for the others without |
--resume |
continue the run of the same spec in --out, see Checkpoints |
--provenance FILE |
the provenance of the sources the run runs on, see Provenance |
--input PORT=PATH |
the path of an input of the spec, the output of another run, e.g. --input fit=results/fit; repeated per input, also as --input=PORT=PATH |
--summary FILE |
write the summary of a successful run also into this file |
plan writes the planned spec as JSON to stdout or to -o FILE; the messages of every command go to stderr. unit and merge take no --workers, --resume or --provenance: a unit runs serially in its process, a unit or a merge into an output with files continues it, and the provenance of their sources is the file of the environment variable SIMRUN_PROVENANCE, if set.
Kinds¶
| kind | runs | units | input |
|---|---|---|---|
simulate |
the simulation experiments of the project with their report | whole | |
fit |
the repeats of the optimization of a fit problem | blocks of repeats | |
identifiability |
the profile likelihoods of the parameters of a fit | one per parameter | fit |
fisher |
the Fisher information of a fit | whole | fit |
report |
the report of a fit, with its profiles and Fisher information when the input has them | whole | fit |
petab |
the fit problem as a PEtab v2 problem, starting from the best parameters of a fit if one is given | whole | fit |
adopt |
the adoption of a finished fit: its record and the adopted fits of the project with it | whole | fit |
scan |
a scan of the project | blocks of points | |
sensitivity |
a scan with sensitivity indices, and the indices, or a sensitivity analysis of the project over the groups of its simulations | blocks of points, or one per analysis | |
uncertainty |
the propagation of an uncertainty analysis | blocks of draws | |
factory |
the models built by the factory of the project, compared with the ones of the package | whole | |
action |
an action of the project, an analysis of its own | whole | |
credibility |
the assessment of the contexts of use of the project against its adopted fits, its record, tables and report | whole | cross_validation, record |
release |
the build of a release of the project as a repository of its own, which python -m sbmlsim.release publish publishes, see Release |
whole |
A spec forbids unknown fields. The fit kinds name a fit problem, the other kinds an analysis of the project:
| field | kinds | meaning |
|---|---|---|
project |
all | the project, module:attribute |
subset |
fit, identifiability, fisher, report, petab |
the fit problem, a key of the fits of the project |
analysis |
scan, sensitivity, uncertainty |
the scan, the sensitivity analysis or the uncertainty analysis, a key of the project |
fit |
identifiability, fisher, report, petab, adopt |
the records of a fit, the input fit |
name |
action |
the action, a key of the actions of the project |
arguments |
action |
the arguments of the action, JSON values by the names of the keywords of its function, {} without; the plan refuses arguments the function does not take. They are passed as they are: a relative path among them is relative to the current directory of the run, not to the spec file |
version |
release |
the version of the release, X.Y.Z |
repository |
release |
a checkout of the release repository, cloned instead of the repository on GitHub; only read |
framework_path |
release |
a local checkout of the framework of the release (ReleaseSettings.framework) instead of the released one; such a build is not published |
units |
the split kinds | the number of units, set by the plan |
fit¶
| field | default | meaning |
|---|---|---|
opid |
the subset, with adopt the id of a fit |
the id of the fit, the directory of its records in the output; an adopted fit has the id of a fit of its subset, <subset>_<date>_<time>__<hash> |
repeats |
4 | the number of optimization runs |
algorithm |
LSQ |
least squares LSQ or differential evolution DE |
seed |
drawn by the plan | the seed of the start values and of the runs |
studies |
all | the studies of the problem to fit |
timeout |
none | the seconds a single run may take |
optimizer |
{} |
further arguments of the optimizer, e.g. {"max_nfev": 50}, and of the runner, e.g. the sampling of the start values sampling by its name (LOGUNIFORM, UNIFORM, LOGUNIFORM_LHS, UNIFORM_LHS, START); a setting of the spec, e.g. seed, is refused here |
start |
none | the point least squares starts from instead of samples of the bounds: the values by parameter id ({"k": 0.3}), a JSON file of them, the directory of the records of a fit or the id of a fit, adopted in the project (fits_dir) before a directory of that name; needs LSQ and one repeat. The plan resolves it into the values, which the planned spec keeps, so every unit and a resume start from the same point, and keeps the given start in start_from, which the provenance of the fit records; a relative path of a spec file is relative to the file, a fit id stays an id |
record_adopted |
true |
record the adopted fits of the other subsets, whose values the models of the project carry, and these values in the provenance of the fit and name them in its report; nothing is fixed by it, the models carry the values |
fixed_fits, fixed_values |
set by the plan | the adopted fits of the other subsets and the values of their parameters which the fit does not fit, read once by the plan with record_adopted, so every unit records the same |
identifiability |
false |
compute the profile likelihoods of the parameters of the best run after the fit, <opid>/identifiability.json |
profile |
the defaults | the settings of these profiles, the ones of the kind identifiability (ProfileSpec), e.g. {"max_points": 10}, with pids the parameters to profile (every parameter which is no element of a network without) |
fisher |
true |
compute the Fisher information with the profiles, <opid>/fisher.json |
report |
false, with adopt true |
write the report of the fit into <opid>, with the title of the project and the fixed adopted fits |
mapping_figures |
true |
draw the figure of every fit mapping in the report |
adopt |
false |
adopt the fit, which needs identifiability: its record into fits/<opid> and adopted.json, the adopted fits of the project with this fit for its subset |
The plan refuses a fit whose upper bounds let a remainder of a model of the project become negative, an initial assignment f_c = 1 - f_a - f_b whose fitted fractions and the values of the others sum above 1 (sbmlsim.fit.project_fits.remainder_problems), and checks the start before a repeat runs.
identifiability¶
| field | default | meaning |
|---|---|---|
pids |
set by the plan | the parameters to profile, every parameter which is no element of a network without |
alpha |
0.95 | the confidence level of the intervals |
degrees_of_freedom |
1 | the degrees of freedom of the threshold |
initial_step, min_step, max_step |
0.1, 0.01, 1.0 | the steps of a scan in decades |
max_points |
50 | the largest number of points of a scan in one direction |
reoptimize |
true |
optimize the other parameters at every point |
optimizer |
{} |
arguments of the least squares optimizer of the other parameters |
fisher |
true |
compute the Fisher information as well |
The settings are the ones of the profile likelihood. A profile is computed on the problem of the studies the fit was restricted to and with the settings the fit ran with, both read from its records; the same holds for fisher, report and petab.
fisher, report and petab¶
| kind | field | default | meaning |
|---|---|---|---|
fisher |
step |
of fisher_information |
the relative step of the finite differences |
report |
mapping_figures |
true |
draw the figure of every fit mapping |
report |
group_by |
the groupings of the problem | the groupings of the report, the columns of one grouping per list |
report |
adopted |
false |
report the adopted fit of the subset from its record in the project, of every adopted fit for the subset all (no fit subset of a project may be named all), into <fit id>/, without the input fit |
adopt |
force |
false |
adopt a fit which the project has adopted already, replacing its record |
adopt adopts the fit of its input fit, the out of a fit or a records directory: the id of its result, which has the form of the id of a fit of a subset of the project, names the subset; it needs the profiles or the Fisher information of the fit and writes its record into fits/<fit id> and adopted.json with the fit adopted for its subset, as fit with adopt does.
| petab | required_extension | true | mark the extension sbmlsim as required |
simulate, scan, sensitivity and uncertainty¶
| kind | field | default | meaning |
|---|---|---|---|
simulate |
experiments |
every experiment | the names of the groups and of the classes of the experiments to run, every experiment once; the plan sets the names of the classes |
simulate |
figure_formats |
the formats of the project | the formats of the figures, e.g. ["svg", "html"], which the plan writes in lower case |
simulate |
uncertainty |
none | run the experiments over draws of the fitted parameters of the default variant of the model, the curves of their simulations as bands (see Simulation experiments): draws (100), seed (drawn by the plan without) and the quantiles of the bands ([0.05, 0.95]) |
scan, sensitivity |
scan_hash |
set by the plan | the hash of the scan the plan built; none for a sensitivity analysis over groups |
sensitivity |
analyses |
the default analyses of the runner | the analyses of a sensitivity analysis over groups (Project.sensitivities), e.g. [local, sampling], which the plan sets for a single runner |
sensitivity |
subfolders |
every subfolder | the subfolders of a sensitivity analysis of several runners, which the plan sets |
sensitivity |
run_plan |
set by the plan | what every unit of a sensitivity analysis over groups computes: the hash of the table of the parameters and every analysis with its groups and resolved settings, e.g. the number of samples of SBMLSIM_SENSITIVITY_N; a unit or a merge which resolves to another plan fails with a PlanMismatch |
uncertainty |
seed |
the seed of the analysis, else drawn by the plan | the seed of the draws |
The scan, its observables and its design are defined in the project, so the spec of a scan, a sensitivity or an uncertainty analysis only names it, e.g. the Sobol indices of the scan sobol and the propagation cl with a seed of its own:
python -m sbmlsim.run sensitivity sobol.yaml --out results/sobol
python -m sbmlsim.run uncertainty cl.yaml --out results/cl
A sensitivity analysis of the project over the groups of its simulations (Project.sensitivities, see Sensitivity analysis) is run by the same kind; the spec names it and may choose its analyses:
Every analysis is a unit, which writes its folder of the output, and the merge writes the table of the parameters; a resumed run keeps the analyses whose folder was written by the same plan. The plan fixes the numbers of samples: a unit run with another SBMLSIM_SENSITIVITY_N than its plan fails.
The output¶
Every run writes the same files describing it into its output, besides its results:
| file | content |
|---|---|
run.json |
the record of the run: the kind, the hash of the spec, the versions of the packages and of the project, python, the host, the provenance of the sources or else the git revision of the project, the variables of the task which simrun sets in a pod (SIMRUN_TASK_DIR, SIMRUN_TASK_TYPE, SIMRUN_INPUTS, SIMRUN_ATTEMPT, SIMRUN_ROLE, SIMRUN_WORKER, SIMRUN_NODE, SIMRUN_PROVENANCE, SIMRUN_MEMORY_*, ...; never a credential such as SIMRUN_TOKEN), the workers, the times and the status (running, done, or failed with its error) |
spec.json |
the planned spec, which a resume runs as it is |
summary.json |
the summary of the run, e.g. the best cost of a fit or the failed points of a scan |
progress.jsonl |
the events of the run, see Progress; the events of a unit go to progress/unit-<index>.jsonl |
The results of the kinds:
| kind | results |
|---|---|
simulate |
index.html and a directory per experiment |
fit |
<opid>/runs/<opid>_run_<k>.json (the repeats), <opid>/optimization_result.json, <opid>/parameters.json (the best run), <opid>/fits.tsv, with identifiability also <opid>/identifiability.json and <opid>/fisher.json, with report the report in <opid>, with adopt also fits/<opid> (the record of the adopted fit) and adopted.json |
identifiability |
profiles/<pid>.json (the profiles), identifiability.json, fisher.json and a copy of the records of the fit, optimization_result.json and parameters.json |
fisher |
fisher.json and a copy of the records of the fit |
report |
report/, with adopted a directory per adopted fit, <fit id>/ |
adopt |
fits/<fit id> (the record of the fit) and adopted.json |
petab |
petab/problem.yaml and its tables |
scan |
blocks/points-<start>-<stop>.nc (the points of the units), result.nc (the ScanResult) |
sensitivity |
as scan, and sensitivity.nc (the SensitivityResult); of a sensitivity analysis over groups the files of its runner (see Sensitivity analysis): parameters.tsv, parameters.tex and a folder per analysis, <analysis>/ or <subfolder>/<analysis>/, each written atomically by its unit with the hash of its plan in .sensitivity-plan, so a folder of another plan, e.g. of a smoke run, is computed again |
uncertainty |
checkpoint/<scenario>/draws-<start>-<stop>.nc (the draws of the units), uncertainty/ (the UncertaintyResult) |
factory |
the files of the factory with the layout of the package, e.g. models/toy.xml; the files of the package are never written. The summary has the number of the compared outputs (outputs): the factory_outputs of the project (declared true), else, with a warning, the variants and every file the factory wrote which the package has (declared false); a rebuild with nothing to compare fails. changed names the compared outputs which differ from the ones of the package, an SBML file compared without the dates of its model history and an antimony file (.ant) without its model created/model modified lines |
action |
what the action writes; the summary is the mapping the action returns, followed by its action |
credibility |
credibility/ (the record credibility.json, the tables and the report index.html, see Credibility), with lock also credibility.lock.json; the summary has the verdict of every context of use (verdicts), the verified contexts (verified) and the state of the lock (lock) |
release |
repository/, a clone of the release repository with the build of the release, not committed; the summary has the version, the source commit, the framework and its version, the number of files of the manifest, the steps which ran, the outputs of the factory which differ from the source package (changed, part of the release), the skipped steps with their reason (skipped) and whether the build can be published (publishable) |
The input fit of a kind is the output of a fit run, whose records are in its directory <opid>, or a directory of records itself, e.g. the output of an identifiability or fisher run, which copy the records of their fit, so a report shows the fit and its analyses from one directory. Every file is written atomically: a reader sees the old or the new file and never a partial one. A run never writes into the project: even adopt writes adopted.json and the record fits/<opid> into the output, which you copy into the directory of the fit records of the project (fits_dir) and commit to adopt the fit. A report of a project has its context: the title of the project and the adopted fits the fit kept fixed, as its records name them.
The results are the files of the classes of sbmlsim, which read them back: OptimizationResult.from_json reads optimization_result.json of a fit, IdentifiabilityResult.from_json reads identifiability.json, ScanResult.from_netcdf reads result.nc of a scan, SensitivityResult.from_netcdf reads sensitivity.nc and UncertaintyResult.from_netcdf reads the directory uncertainty/. The fitted parameters of parameters.json are the input of a report or of the identifiability tools.
Units and merges¶
A run of a split kind computes units, each of its own files, and merges them. python -m sbmlsim.run <kind> does all of it in one process and its pool. The commands plan, unit and merge do it in separate processes, which may run at the same time, on one machine or on several machines which share the output directory. First write the scan of three doses as a spec:
plan completes the spec into what every unit computes alike and sets the number of units, units:
{
"units": 3,
"project": "examples.hctz_fitting.project:PROJECT",
"analysis": "dose",
"scan_hash": "cdbdb9ebc0c25da8b9a67857cd198d315c47ffb183a6330148b3ed4b4f3ce080"
}
The units are numbered from 0 to units - 1. Compute each one into the shared output, in any order, here one after another (& and wait, or one machine per unit, run them in parallel), then merge them:
for i in 0 1 2; do python -m sbmlsim.run unit scan dose-planned.json $i --out results/dose; done
python -m sbmlsim.run merge scan dose-planned.json --out results/dose
The merge writes result.nc, the same result as a whole run, python -m sbmlsim.run scan dose.yaml --out results/dose-whole. A unit which is missing makes the merge exit with 3 and name it, e.g. 1 of 3 units are missing: 1, so compute that unit and merge again. A fit splits the same way, and so does a profile likelihood, whose unit and merge need the records of the fit as their input:
python -m sbmlsim.run plan fit fit.yaml -o fit-planned.json
for i in $(seq 0 7); do python -m sbmlsim.run unit fit fit-planned.json $i --out results/fit; done
python -m sbmlsim.run merge fit fit-planned.json --out results/fit
python -m sbmlsim.run plan identifiability profiles.yaml -o profiles-planned.json
python -m sbmlsim.run unit identifiability profiles-planned.json 0 --out results/profiles --input fit=results/fit
python -m sbmlsim.run merge identifiability profiles-planned.json --out results/profiles --input fit=results/fit
with one unit per parameter of pids in profiles-planned.json. The rules:
- A fit, a scan and a propagation of a given number of draws are cut into at most 64 units of consecutive items,
max(1, ceil(n / 64))repeats, points or draws each; a profile likelihood has one unit per parameter, and the adaptive number of draws of a propagation is one unit, whose rounds are its checkpoints. - The plan of a fit and of a propagation draws the seed when the spec has none, so every unit draws the same start values or the same points. The plan of a scan records the hash of the identity of the scan, which every unit and the merge compare with the scan they build: its record without the numbers a design draws and the references it reads (
scan_identity: the method, the distributions and the options of a design with its seed and its number of points, the labels, the targets, and the whole record of the simulation and of a dimension of given values), so a unit on another platform than the plan, whose numerics differ in the last bits, builds the same scan. The plan builds the scan twice and compares the whole records; a scan which builds other points every time, e.g. a design without a seed, is refused. - A whole run computes the same units on the workers of the run: the consecutive blocks of a scan or of a propagation of a given number of draws which have no file run in spans of as many blocks as the run has workers, a span one run of the simulator, so it is parallel whatever the size of a block, and the result of a span is cut into the files of its blocks, each the file its unit writes (a block whose messages of failed points the span does not keep, more than ten failed points before them, runs alone).
- The first unit writes
spec.jsoninto the output, and a unit or a merge of another plan is refused, so the units of two plans never mix. A unit writes norun.json, the merge does. - A unit computed again, e.g. after its machine was lost, writes the same complete files again, and a unit whose files exist is not computed again; the merge names the units it misses and exits with 3.
- The merged result equals the result of the whole run bitwise with roadrunner, apart from the times and durations of the records: the blocks of a scan combine to the
ScanResultof the whole scan (ScanResult.combine), the repeats of a fit to itsOptimizationResult, the profiles to theIdentifiabilityResult(IdentifiabilityResult.combine) and the blocks of draws to theUncertaintyResult, every block taking its rows of the points of the design of all the draws, so a Latin hypercube stays one hypercube.
Checkpoints and resume¶
The units are the checkpoints of a run: a repeat of a fit is written once it finished, a profile once both of its scans finished, a block of points or draws once it ran, in a whole run once its span of about workers blocks ran. A run which was interrupted, by Ctrl-C, a lost machine or a time limit, continues with --resume into the same output, which computes only what is missing:
A resume runs the planned spec of spec.json, so a drawn seed stays, and is accepted only for the spec file the run was started with (and not for spec.json, the planned spec); its inputs are left out of the comparison, so they may be staged at another path. A run into an output which is not empty without --resume is refused, and so is a resume with another spec, as both would mix the results of two runs. A resume of a finished run runs it again, keeps every result and merges again; --resume into an empty output starts a run, and progress.jsonl collects the events of every attempt.
Progress and provenance¶
progress.jsonl has one JSON line per step of the analysis, which a program outside of the run can follow, e.g. tail -f:
{"time": "2026-11-06T13:03:03.374+00:00", "event": "scan.chunk", "points": 1, "done": 1, "total": 1}
{"time": "2026-11-06T13:03:03.490+00:00", "event": "scan.block", "analysis": "dose", "start": 0, "stop": 1, "points": 3}
| event | fields |
|---|---|
fit.repeat |
opid, run: a repeat of a fit finished and is stored, its file written right after the event |
identifiability.profile |
opid, pid: the profile of a parameter finished |
scan.chunk |
points, done, total: a chunk of points of a scan finished |
scan.block |
analysis, start, stop, points: the block of a unit of a scan finished |
sensitivity.analysis |
analysis, folder: an analysis of a sensitivity analysis over groups finished, its folder written |
propagation.block |
scenario, start, stop: a block of draws ran or was read |
experiment |
sid, phase, activity, completed, total: a phase of a simulation experiment |
The provenance of a run is the git revision of the root of the project, recorded in run.json. A run on a snapshot of the sources, e.g. on a cluster, has no checkout: --provenance FILE, or the file the environment variable SIMRUN_PROVENANCE names, is the JSON list of its sources (name, branch, commit, uncommitted changes), which run.json, the records of a fit (FitProvenance.sources) and the methods of its report record instead of the git revision.
Exit codes¶
| code | meaning |
|---|---|
| 0 | done |
| 2 | a bad command line |
| 3 | the analysis failed, its traceback is logged; also a merge with missing units |
| 4 | a configuration error, its message on stderr: an invalid spec or input, an unknown kind, project or analysis, a planned spec which does not match what it resolves to, an output which is not empty without --resume or a resume of another spec |
An output which a run may not run into raises sbmlsim.run.OutInUse, a ConfigurationError with the output (out) and why (reason: not_a_directory, not_empty without --resume, no_record and unreadable for a resume without a readable run.json, other_run for the record of another kind or spec). sbmlsim.run.check_out(kind, spec, out, resume=...) makes these checks and the validation of the spec without running and without writing anything, so a wrapper refuses before it starts:
from sbmlsim import run
try:
run.check_out("release", {"project": "my_model:PROJECT", "version": "0.8.0"}, out)
except run.OutInUse as err:
print(err.reason, err.out)
Verify¶
python -m sbmlsim.run verify <subcommand> checks that a change of a model changes only what it is meant to change: a refactoring, an update of sbmlsim or a refresh of the study data should leave the simulations of the model as they were. It is a family of local commands like plan and list, not a kind: it compares the results of checkouts on this machine, writes only where it is told to (--out) and has no units, no merge and no simrun task type. The result of a command goes to stdout, the progress and the problems are logged on stderr. The exit code is 0 when nothing differs, 1 when a difference is found and 2 for a command that cannot be run as it was asked (an unknown project or experiment, a bad option, a missing directory).
git worktree add --detach ../base develop
# the experiments simulate the models of the project, which are generated:
# create them with the factory of each checkout right before its dump
python -m sbmlsim.run verify dump --root ../base --project my_models.hctz:PROJECT --out base.pkl --atol 1e-16 --rtol 1e-12 --grid 1000
python -m sbmlsim.run verify dump --root . --project my_models.hctz:PROJECT --out new.pkl --order base.pkl --atol 1e-16 --rtol 1e-12 --grid 1000
python -m sbmlsim.run verify compare base.pkl new.pkl
| subcommand | what it does |
|---|---|
dump --project REF --out FILE |
runs the experiments of the project (or the named ones, --all adds those defined below its package but not in its experiments) serially and stores the results, datasets, fit mappings, figures and the variant of every task in a pickle; --atol/--rtol take a number or model for the tolerance of the project, --grid N outputs every simulation at N + 1 equidistant times and at its changes instead of the steps of the integrator, --order FILE runs in the order of another dump, --skip A,B leaves experiments out, --reduced-selections simulates only the selections the experiments need |
compare OLD NEW |
compares two dumps: the simulations on the matched rows of their output times (a row at a time which only one dump has is compared with the other dump interpolated at its time, relative to the scale of the array, an array whose interpolation cannot resolve the --threshold is reported as unresolved, not as equal), everything else exactly; --renames FILE applies the expected renames and differences of a change to the old dump first |
ranges DUMP |
lists the fit mappings whose data lie outside of the simulated range |
fits --project REF --out DIR |
starts a minimal fit of every fit definition |
definitions --project REF --out FILE |
writes the fit definitions as JSON (settings, parameters, mappings), to compare two checkouts with diff; the checkout is <root> |
settings --project REF --out FILE |
writes the settings a run of the experiments hands to sbmlsim as JSON, without simulating |
png OLD NEW |
compares the PNG figures of two directories pixel by pixel; --sids pairs an old figure with the figure of the SId of its file name |
sbml OLD NEW |
compares SBML models (files or directories) by their elements, ignoring the order and the annotations |
scorecard RECORDS... |
reads the credibility records of many models into one table, compares it with --baseline and pools a qualification with the evidence extension named by --pool (--field); the extensions are those of --project and --extensions MODULE:ATTRIBUTE |
--project is the reference module:attribute of the project and --root the directory put first on the python path, e.g. a checkout (the project must be imported from below it). The variant of the model a task runs on is stored with every task: the variant SimulationExperiment.variant_of(simulation) names, which a framework that builds a model per group of subjects implements, else the variant of the project whose file is the source of the model of the task; a study that moves to another variant is a difference of its own. The renames file has the parts metadata (fields, members and added, the renamed metadata of the fit mappings), strings and ids (renamed texts and ids), sids (true when the ids became SIds), figure_fields (fields of a figure left out of both dumps) and expected (patterns of the keys per part of the dump, results, datasets, mappings, figures, ranges and builds, whose differences are expected: they are printed and not counted, and an expected difference that does not occur is counted).
CPU quota and threads¶
The number of processes of a run is the number of CPUs the process may use, bounded by the CPU quota of its cgroup, so a run in a container with a quota of 4 CPUs on a host of 64 starts 4 workers and not 64. With cgroup v2 the quota is the smallest one of the cgroup of the process and its parents (cpu.max), with cgroup v1 the one quota of the cgroup as the container sees it (cpu.cfs_quota_us over cpu.cfs_period_us), rounded down and at least 1; the pools of sbmlsim (Simulator, a fit, the experiments) bound their default size the same way.
A run uses its CPUs through the processes of its pools, so the numerical libraries run with one thread each: the command sets OMP_NUM_THREADS, OPENBLAS_NUM_THREADS and MKL_NUM_THREADS to 1 unless they are set, starting itself once more with them, and draws its figures with the matplotlib backend Agg (MPLBACKEND unless set).
Profiling¶
--profile runs a command which writes into --out (run, unit, merge) under the statistical sampling profiler of python 3.15 (profiling.sampling, PEP 799), which samples the stack of the command from a process of its own, so the command runs at nearly its normal speed:
After the command the profile is written into profiling/<command>_<kind>_<time>/ of the output (of a unit profiling/unit_<kind>_<index>_<time>/, so the units which compute into one output at once do not share a folder): flamegraph.html (the interactive flame graph), heatmap/ (the source lines with their samples), profile.pstats (for pstats and its viewers), summary.txt (the functions with the most samples) and profile.bin (the samples, against which a later profile is compared, python -m profiling.sampling replay --diff-flamegraph profile.bin). The command exits with its own code, which it records for the profiler (the profiler exits with 0 whatever the command did), 1 if it recorded none; a failure of the profiler or of the conversion of the profile is logged and does not change the code. With an older python --profile is a bad command line (exit code 2) and the command does not run.
sbmlsim.run.profiling.run_profiled(arguments, folder, module=...) profiles any entry point which runs as python -m <module>, e.g. the command line of a framework of its own, which calls record_exit_code(code) before it exits. The profiler runs with one change: python 3.15.2 reads now and then a name of a frame while it changes, which broke the writer of the profile and ended the command; such a sample is left out and their number reported on stderr.
Projects¶
A project, sbmlsim.project.Project, describes a model package once: its model variants, factory, experiments, fits, scans, uncertainty and sensitivity analyses and the settings of its simulator, figures, checks and release. It is an attribute of a module of the package, which the run layer imports, and every spec names it as project: module:attribute. The fields, the references and the project of the HCTZ example are described on the page Projects.
Credibility¶
The kind credibility assesses the contexts of use of a model declared in Project.credibility against its adopted fits into out/credibility/, with the options verification, battery, cross_simulator, lock, uncertainty, variability and source_commit and the inputs cross_validation and record; the declaration, the evidence, the verdicts and the options are described on the page Credibility.
python -m sbmlsim.run credibility credibility.yaml --out results/credibility
python -m sbmlsim.run credibility credibility.yaml --out results/report --input record=results/credibility
Release¶
The kind release builds the release of a project as a repository of its own into out/repository; it commits nothing, and python -m sbmlsim.release publish publishes the build. The build, the release metadata (Project.release), the review and the publishing are described on the page Release.
Checks of a project¶
sbmlsim.project_checks has the checks of a model package as functions, which its tests call (check_model, check_registry, initialize_experiments, run_all_experiments, check_battery, start_fits), see Projects.
simrun¶
simrun runs the tasks of a workflow on a cluster. sbmlsim registers its kinds but action as the task types sbmlsim.<kind> of simrun, sbmlsim.fit, sbmlsim.identifiability, sbmlsim.scan, sbmlsim.adopt, sbmlsim.factory, sbmlsim.credibility, sbmlsim.release and so on (verify is a command and no kind, so it has no task type until a workflow needs one); the extra simrun installs simrun, which needs python 3.14:
The settings of a task are the spec of its kind. A split kind (fit, identifiability, scan, sensitivity, uncertainty) is split by simrun: its workers compute the units and its merge merges them. The other kinds run as the command python -m sbmlsim.run <kind> {settings} --out {out}/out --summary {out}/summary.json --resume --input={input}, whose --resume lets a retry after an eviction continue the run it finds. A task writes the output of its run into its output port out, which a task downstream reads as the input <task>.out, and its summary into summary.json of the task.
A workflow which fits the HCTZ problem in units, profiles its parameters and writes the report of both:
name: hctz-fit
tasks:
- id: fit
type: sbmlsim.fit
settings:
project: examples.hctz_fitting.project:PROJECT
subset: PK
repeats: 64
- id: identifiability
type: sbmlsim.identifiability
settings:
project: examples.hctz_fitting.project:PROJECT
subset: PK
inputs:
fit: fit.out
- id: report
type: sbmlsim.report
settings:
project: examples.hctz_fitting.project:PROJECT
subset: PK
inputs:
fit: identifiability.out
The HCTZ project lives in the repository of sbmlsim, which is the only source here. A project of a model package outside of sbmlsim adds the source of the model first and then the one of sbmlsim, as simrun orders them, e.g. simrun submit fit.yaml --source model=~/git/my_model --source sbmlsim=~/git/sbmlsim.
The fit is 64 units of one repeat, the profile likelihood one unit per parameter, and the report reads the fit and its profiles from the output of the identifiability analysis.
- The plan runs in the client.
simrun submitplans every task whose type is installed where it runs, before it takes the snapshots, and submits the planned settings: the seed of the fit, the units, the parameters of the profiles. The client therefore needssbmlsim[simrun]and the model package, so that it imports the project; a task submitted without its plan has nounitsand fails in the service. - The project is imported in the pods. The pods install the snapshots editable, which installs the package of a source and not the rest of its repository: a model package is found, while the HCTZ example in
examples/needs the root of the repository onPYTHONPATH. - Provenance. simrun writes the provenance of the snapshots of a run and names it in
SIMRUN_PROVENANCE, whichrun.jsonand the records of a fit record, see Provenance. - Development. The development environment is python 3.14 (
.python-version), souv sync --extra devinstalls simrun anduv run ty checkcheckssbmlsim.simrunagainst it; the tests of the plugin skip without simrun. The tox environments, which resolve frompyproject.toml, do not install it.