sbmlsim 0.9.2__tar.gz → 0.9.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.bumpversion.toml +1 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/CITATION.cff +1 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/CLAUDE.md +4 -4
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/PKG-INFO +5 -5
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/README.md +4 -4
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/data.md +2 -2
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/index.md +1 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/plotting.md +1 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/simulation.md +5 -5
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/testsuite.md +4 -2
- sbmlsim-0.9.4/release-notes/0.9.3.md +12 -0
- sbmlsim-0.9.4/release-notes/0.9.4.md +14 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/__init__.py +1 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/data.py +183 -100
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/model_roadrunner.py +254 -34
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/symbols.py +71 -8
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/tolerances.py +7 -4
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/plot/points.py +18 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/plot/serialization_matplotlib.py +24 -25
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/plot/serialization_plotly.py +25 -28
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/testsuite_report.html +2 -2
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/sampling/references.py +6 -2
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/executor.py +68 -14
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/report.py +1 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/runner.py +212 -8
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_model_roadrunner_init.py +123 -13
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_symbols.py +24 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_points.py +19 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_scan_figures_matplotlib.py +80 -37
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_scan_figures_plotly.py +103 -41
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/sampling/test_references.py +16 -2
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/models.py +89 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_event_order.py +109 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_executor.py +101 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_simulator.py +320 -2
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_simulator_pool.py +48 -1
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_data.py +147 -2
- sbmlsim-0.9.4/tests/testsuite/test_runner.py +313 -0
- sbmlsim-0.9.2/tests/testsuite/test_runner.py +0 -162
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.claude/settings.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/CODEOWNERS +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/actions/setup/action.yml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/dependabot.yml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/pull_request_template.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/rulesets/apply.sh +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/rulesets/develop.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/rulesets/main.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/rulesets/tags.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/workflows/ci-cd.yml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/workflows/docs.yml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/workflows/lint.yml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.github/workflows/testsuite-pin.yml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.gitignore +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.pre-commit-config.yaml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.python-version +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.ruff.toml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/.zenodo.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/LICENSE +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/conftest.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/comparison.diff.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/console.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/data.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/display.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/experiment.experiment.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/experiment.runner.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.cli.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.derived.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.display.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.fisher.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.helpers.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.identifiability.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.metrics.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.objects.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.optimization.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.options.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.parameter_mapping.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.parameters.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_omex.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.benchmark.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.export.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.extension.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.gaps.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.likelihood.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.reader.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.sciml.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.sciml_export.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.symbols.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.petab_v2.testsuite.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.report.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.result.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.runner.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/fit.sampling.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/index.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/log.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/model.model.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/model.model_resources.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/model.model_roadrunner.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/model.provenance.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/model.roottol.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/model.symbols.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/parallel.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/plot.plotting.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/plot.points.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/plot.serialization_matplotlib.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/report.experiment_report.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/result.scan.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/result.timecourse.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.backend.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.compiler.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.errors.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.formula.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.hybridization.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.interpreter.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.layers.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.network.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.parameters.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sciml.testsuite.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sensitivity.classification.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sensitivity.indices.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sensitivity.plots.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sensitivity.result.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/sensitivity.uncertainty.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/serialization.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulation.definition.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulation.observables.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulation.sampling.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulation.scan.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulator.executor.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulator.formula.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulator.observables.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulator.pk.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulator.plan.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulator.simulator.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/simulator.worker.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/task.task.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/testsuite.baseline.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/testsuite.cache.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/testsuite.cases.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/testsuite.comparison.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/testsuite.report.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/testsuite.runner.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/testsuite.submission.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/units.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/api/utils.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/development.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/experiments.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/fitting.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/identifiability.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/about.txt +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/android-chrome-192x192.png +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/android-chrome-512x512.png +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/apple-touch-icon.png +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/favicon-16x16.png +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/favicon-32x32.png +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/favicon.ico +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/sbmlsim-100x100-300dpi.png +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/images/favicon/site.webmanifest +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/installation.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/models.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/observables.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/petab.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/petab_benchmark.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/petab_sciml.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/petab_testsuite.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/references.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/robots.txt +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/sampling.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/scans.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/sciml_testsuite.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/sensitivity.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/testsuites.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/docs/units.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/README.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/example_1.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/example_2.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/example_3.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/example_4.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/example_5.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/example_6.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/jws/example_1.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/jws/example_2.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/jws/example_3.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/jws/example_4.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/jws/example_5.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff/jws/example_6.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/diff_example.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/example_comparison.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/example_copasi.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/icg_amici_simulation.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/resources/condition.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/resources/condition_liver.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/resources/icg_events_sd.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/resources/icg_liver.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/resources/icg_sd.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/simulate.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/simulate_amici.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/simulate_copasi.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/comparison/simulate_roadrunner.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/curve_types/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/curve_types/experiment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/curve_types/model.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/demo/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/demo/demo.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/experiment_scans.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/fit_sampling.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/data/DoseResponse/.DoseResponse_TabEpinephrine.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/data/DoseResponse/.DoseResponse_TabGlucagon.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/data/DoseResponse/.DoseResponse_TabInsulin.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/experiments/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/experiments/dose_response.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/glucose.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/model/liver_glucose.html +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/glucose/model/liver_glucose.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Beermann1976/.Beermann1976_Fig2.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Beermann1976/.Beermann1976_Fig3.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Beermann1976/.Beermann1976_Tab1A.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Patel1984/.Patel1984_Fig1.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Patel1984/.Patel1984_Fig2.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Patel1984/.Patel1984_Tab4.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Weir1998/.Weir1998_Fig2.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Weir1998/.Weir1998_Fig3.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/data/Weir1998/.Weir1998_Tab4.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/experiments/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/experiments/base_experiment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/experiments/metadata.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/experiments/studies/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/experiments/studies/beermann1976.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/experiments/studies/patel1984.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/experiments/studies/weir1998.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/fitting.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/identifiability.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/identifiability_report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/mapping_collections.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/parameters.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/petab_problem.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/fitting/run_report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/helpers.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/models/hctz_body_flat.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/hctz_fitting/simulations.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/initial_assignment/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/initial_assignment/initial_assignment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/initial_assignment/initial_assignment.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/model_sensitivity.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/observables.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/Boehm_JProteomeRes2014.yaml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/README.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/experimentalCondition_Boehm_JProteomeRes2014.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/measurementData_Boehm_JProteomeRes2014.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/model_Boehm_JProteomeRes2014.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/observables_Boehm_JProteomeRes2014.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/parameters_Boehm_JProteomeRes2014.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Boehm_JProteomeRes2014/visualizationSpecification_Boehm_JProteomeRes2014.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/Perelson_Science1996.yaml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/README.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/experimentalCondition_Perelson_Science1996.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/measurementData_Perelson_Science1996.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/model_Perelson_Science1996.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/observables_Perelson_Science1996.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/parameters_Perelson_Science1996.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/Perelson_Science1996/visualizationSpecification_Perelson_Science1996.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/petab/benchmark.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/repressilator/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/repressilator/repressilator.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/repressilator/repressilator_scans.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/scan.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/README.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/experiments.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/hybridization.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/lv.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/mapping.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/measurements.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/net1.yaml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/net1_ps.hdf5 +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/observables.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/parameters.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra/problem.yaml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/lotka_volterra_fit.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/neural_ode/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/neural_ode/data.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/neural_ode/experiment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/neural_ode/fitting.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/neural_ode/lotka_volterra_neural_ode.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sciml/neural_ode/network.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sensitivity/.gitignore +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sensitivity/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sensitivity/sensitivity_example.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sensitivity/simple_chain.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/sensitivity/simple_chain.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/timecourse.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/examples/units.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/pyproject.toml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.10.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.11.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.13.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.14.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.3.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.4.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.6.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.7.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.8.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.1.9.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.2.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.2.1.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.2.2.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.3.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.4.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.5.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.6.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.6.1.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.7.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.7.1.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.7.2.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.8.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.8.1.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.8.2.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.8.3.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.8.4.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.8.5.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.9.0.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.9.1.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/release-notes/0.9.2.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/scripts/llms_txt.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/scripts/petab_benchmark.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/scripts/petab_testsuite.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/scripts/plain_install.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/scripts/sciml_testsuite.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/scripts/testsuite.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/comparison/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/comparison/diff.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/console.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/display.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/experiment/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/experiment/experiment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/experiment/runner.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/cli.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/derived.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/display.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/fisher.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/helpers.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/identifiability.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/metrics.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/objects.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/optimization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/options.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/parameter_mapping.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/parameters.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_omex.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/benchmark.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/export.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/extension.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/gaps.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/likelihood.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/reader.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/sciml.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/sciml_export.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/symbols.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/petab_v2/testsuite.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/result.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/runner.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/fit/sampling.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/log.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/model.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/model_resources.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/provenance.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/model/roottol.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/parallel.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/plot/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/plot/padding.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/plot/plotting.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/report/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/report/experiment_report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/report/templates.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/models/Koenig_demo_14.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/models/midazolam_body_flat.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/models/repressilator.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/experiment.html +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/experiment.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/fit_report.html +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/index.html +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/index.md +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/index.tex +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/resources/templates/report_base.html +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/result/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/result/scan.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/result/timecourse.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/backend.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/compiler.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/errors.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/formula.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/hybridization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/interpreter.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/convolution.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/core.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/functions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/normalization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/pooling.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/registry.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/layers/windows.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/network.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/parameters.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sciml/testsuite.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sensitivity/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sensitivity/classification.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sensitivity/indices.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sensitivity/plots.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sensitivity/result.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/sensitivity/uncertainty.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/serialization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/definition.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/observables.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/sampling/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/sampling/designs.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/sampling/distributions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/sampling/fit.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/sampling/population.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulation/scan.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/formula.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/observables.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/pk.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/plan.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/simulator.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/simulator/worker.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/task/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/task/task.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/baseline.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/cache.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/cases.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/comparison.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/testsuite/submission.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/units.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/src/sbmlsim/utils.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/comparison/test_diff.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/conftest.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/benchmark_baseline.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/datasets/Allonen1981/.Allonen1981_Fig3A.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/datasets/Faber1978/.Faber1978_Fig1.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/models/lotka_volterra.xml +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/petab/sciml_001_llh.tsv +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/petab_baseline.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/scan_regression.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/sciml_baseline.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/data/testsuite_baseline.json +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/docs/test_docs_code.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/examples/test_example_scripts.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_experiment_examples.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_experiment_keys.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_experiment_observables.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_experiment_run.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_experiment_units.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_model_changes_merge.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_runner_errors.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/experiment/test_runner_model_cache.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/conftest.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/hooks.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/scalar_experiment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_cli.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_data_at_change.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_derived_changes.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_display.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_fisher.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_fit.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_fit_data_sel.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_fitting_lifecycle.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_helpers.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_identifiability.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_initial_assignment_parameter.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_mapping_kinds.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_metrics.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_objects.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_observable_model.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_optimization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_optimization_result.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_parameter_mapping.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_parameter_scale.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_parameter_sets.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_parameter_units.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_benchmark.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_benchmark_problems.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_benchmark_script.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_omex.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_scalar_gaps.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_testsuite.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_testsuite_cases.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_testsuite_script.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_definition.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_dosing.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_export_security.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_import_boundaries.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_likelihood.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_noise.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_reader.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_symbols.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_petab_v2_versions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_pool.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_predictions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_prior.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_robustness.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_sampling.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_scalar_mappings.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/fit/test_scalar_report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_hierarchical_units.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_model_parameters.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_provenance.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_roottol.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_selections.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_time_dependent.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/model/test_tolerances.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/models/test_model_roadrunner.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/scan_experiment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_figure_settings.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_jumps.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_padding.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_plotting.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_scan_figure_model.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/plot/test_serialization_matplotlib.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/report/test_experiment_report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/result/test_interpolation_endpoints.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/result/test_scan_result.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/result/test_scan_result_pk.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/result/test_timecourse.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/conftest.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/experiment.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/hybrid.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/petab.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_backend.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_compiler.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_export.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_expressions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_fit.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_formula.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_functions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_hybridization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_ids.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_interpreter.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_layers_convolution.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_layers_core.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_layers_normalization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_layers_pooling.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_network.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_package.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_parameters.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_reader.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_report.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_script.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_suite_cases.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sciml/test_testsuite.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sensitivity/models.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sensitivity/test_classification.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sensitivity/test_global.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sensitivity/test_local.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sensitivity/test_plots.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sensitivity/test_result.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/sensitivity/test_uncertainty.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/sampling/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/sampling/test_designs.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/sampling/test_distributions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/sampling/test_fit_designs.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/sampling/test_population.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/sampling/test_salib_designs.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/test_definition.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/test_design_record.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/test_observables.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/test_scan.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/test_scan_definition.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulation/test_simulation.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_benchmark.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_event_rows.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_execution_contract.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_formula.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_formula_reductions.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_local_time.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_memory.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_model_snapshot.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_observables.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_pk.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_plan.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_plan_values.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_pool_transport.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_reserved_targets.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_scan_point_plans.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_scan_regression.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_simulator_observables.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/simulator/test_worker.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_data_arrays.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_data_function.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_display_links.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_imports.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_log.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_parallel.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_serialization.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_units.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/test_utils.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/testsuite/__init__.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/testsuite/conftest.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/testsuite/test_cache.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/testsuite/test_cases.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/testsuite/test_report_path.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tests/testsuite/test_semantic.py +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/tox.ini +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/uv.lock +0 -0
- {sbmlsim-0.9.2 → sbmlsim-0.9.4}/zensical.toml +0 -0
|
@@ -8,7 +8,7 @@ authors:
|
|
|
8
8
|
given-names: "Matthias"
|
|
9
9
|
orcid: "https://orcid.org/0000-0003-1725-179X"
|
|
10
10
|
affiliation: "Humboldt-University Berlin, Faculty of Life Science, Institute for Biology, Biology, Berlin; University Lübeck; University Hospital Schleswig-Holstein, Campus Lübeck, First Department of Medicine, Germany"
|
|
11
|
-
version: "0.9.
|
|
11
|
+
version: "0.9.4"
|
|
12
12
|
date-released: "2026-10-12"
|
|
13
13
|
doi: "10.5281/zenodo.3597770"
|
|
14
14
|
license: MIT
|
|
@@ -50,13 +50,13 @@ Documentation is [Zensical](https://zensical.org/): markdown sources in `docs/`,
|
|
|
50
50
|
|
|
51
51
|
## Architecture
|
|
52
52
|
|
|
53
|
-
**`simulation/`, `simulator/`, `result/` - the simulation core.** `Simulation` (`simulation/definition.py`) is the one way to set up a simulation, used by experiments, scans, fits and PEtab: `start`/`end` in its `time_unit` (negative times allowed), `preinit_changes` set on the model before its initialization (the initial assignments see them), `changes`, a list of `Change(times, values)` at absolute times (one time or a vector, i.e. multiple dosing; a value is a number, a `Quantity` or a formula string of PEtab math over roadrunner selections, `S` amount, `[S]` concentration, `time`), `presimulation=SteadyState(...)`, and the output: the steps of the integrator by default, `times` or `steps`. The semantics are PEtab v2 (pre-initialization, simultaneous evaluation of the values of a change, compartment changes keep concentrations; the output at the time of a change after the start has two rows, the state before the change and the state after it, the steps of the integrator at every change and an output of times at its times which are changes; the steps of the integrator have an event of the model as two rows as well, also an event at the end of the simulation). `Scan(simulation, dimensions)` (`simulation/scan.py`) runs it over `Dimension` objects, each of `values` (targets to arrays, coupled within a dimension; a value replaces its target wherever the simulation sets it, `Simulation.with_values`, `at=` makes it a `Change` at that time, and `Scan.__init__` logs one warning per dimension and target when a dimension without `at` replaces a target the simulation sets to different values, e.g. the stop of an infusion), `simulations` or `models`; several dimensions span their product in C order. A dimension copies its values into read-only arrays and has `labels`, which are given or default to `0..n-1` for values and to the keys otherwise; neither a dimension nor a scan changes after it was created, and a run never changes the objects of the user. `simulator/plan.py` compiles a simulation against a model (`ModelSymbols`, `UnitsInformation`) into a frozen, picklable `Plan` without units, output times closer than `TIME_RTOL * max(abs(start), abs(end), end - start)` are one output time, a cluster becoming its smallest time (`merge_times(times, start, end)` gives the merged times and the index of each given time, which `compile_simulation` and the data times of a fit share, so the rows of a fit stay aligned), and a point of a scan is that plan with other values (`Plan.with_values(values, at=None)`), never a compiled simulation; `simulator/executor.py` `execute(plan, model, selections)` runs it on roadrunner (no pint, no pandas, no xarray); every segment between two changes ends in its state at its end, which the next change is applied to: with the steps of the integrator roadrunner's variable step `simulate` ends after the end and interpolates its last row linearly, so `_steps` calls the integrator once more with exact output at the end (`_to_the_end`, CVODE interpolates from its last step, no integration), which also fires an event roadrunner kept pending, and so does every horizon of a steady state; every segment of a model with events stops just before its end (`_stop`, a unit in the last place of the larger magnitude of its start and end in the time of roadrunner, which CVODE resolves, and at least four machine epsilons, below which roadrunner applies an event at the start of a call of the integrator without its rows, so the stop is never a subnormal number before an end at 0), so an event of the model at the time of a change fires after it, the last row of a segment which ends at a change, the one at the end included, is the state before the change at the time of the change, and the next segment starts with the state after it; a segment too short for CVODE (`_integrable`, its condition `CV_TOO_CLOSE`, a few units in the last place in absolute time, e.g. between two changes a few units in the last place apart) is not integrated, its state is the one at its start; the triggers before a change and at the end are evaluated at the time the model is at (`stopped`: the time of the model after the segment before, which roadrunner may integrate one unit in the last place past its stop, the start of a segment which is not integrated, `plan.start` before the first one), so an event of the time fires once whatever segments are held; roadrunner does not see a trigger which a change makes true, the executor fires such events after the change (`_fire_events`, PEtab v2 reinitialization): one at a time in the order of their priorities, which are evaluated again after every event (ties in document order, a priority which is no formula of `compile_formula`, e.g. one with `floor` or a function definition, is reported and counts as 0, the priority of an event without one), the triggers are evaluated again after every event as well and a pending event whose trigger is not persistent is cancelled when it becomes false, the values of the assignments are the ones at the trigger or at the execution as `useValuesFromTriggerTime` says, an event with a delay or with assignments which are no formulas is reported and not fired, and one event fires at most `MAX_EXECUTIONS_PER_EVENT` times, which stops events which trigger each other in a cycle without limiting the number of events which fire; after the last segment `_event_at_the_end` integrates the steps of the integrator to the resolution of the time after the end, pairing the rows of an event within the rounding of `at_event_times`, an event there is at the end (two rows in the steps of the integrator, the state after it at an output time at the end, after a change at the end), and the steady state after the end starts at the time of the model after it, so an event of the time does not fire twice; roadrunner integrates an exact output time from the one before it, `t + (next - t)`, which can round up to the time of the change, `_simulate_times` then puts a time between from which the sum is exact; a segment of a model with events past whose end roadrunner fired an event runs again with exact output at the times of its steps (`_PastTheEnd`, `_exact_times`, an event inside integrated to a resolution of the time before and after it, its rows at the times of the steps): the plan runs once more, after a second such segment a third time, which keeps the state at the start of every later segment in a temporary file (`_saved_state`, `saveState(path)`; `saveStateS` of roadrunner 2.10 keeps every state in memory) that a later segment past its end starts again from, so a plan runs at most three times; `_variable_steps` hides roadrunner's warning that a negative end was not reached. `Simulator(n_workers=None, **integrator_settings)` (`simulator/simulator.py`) has `load`, `compile`, `simulate` (one `TimecourseResult`) and `run(model, scan, observables=None, *, time, keep, on_error, progress)`: it compiles one plan per combination of the simulations and models of a scan, cuts the points into chunks of one plan (at most `ceil(n_points / (4 * n_workers))` and `MAX_CHUNK` points) and runs them with `simulator/worker.py` serially or in the kept pool of `sbmlsim/parallel.py` (the same function `run_chunk`, a worker loads a model once from its `ModelSpec`, keyed on the hash of its SBML as the parent loaded it (`RoadrunnerSBMLModel.sbml`), the added parameters, the integrator and every one of its settings as the model of the parent has them, so a setting of the model holds in a worker as well and a file rewritten or deleted after the model was loaded changes nothing; `parallel.shared_payloads` writes the SBML of the models of a run into files of a private temporary directory, one file per content, which a worker reads instead of receiving the SBML with every chunk, and removes them after the run, also after an error; a pool run keeps at most two chunks per worker pending, submitted in the order of their first point, and submits no chunk after a failed point, while the chunks before it still run; every chunk checks that its plan was compiled for the symbols and units of its model, `Plan.check_model` with `model_units`, the base unit and the scale of the unit of every entity, a factor of a unit such as `item/(31557600.0*s)` in the scale and a unit pint does not normalize as it is), and assembles a `ScanResult` (`result/scan.py`), which wraps an `xarray.Dataset` (`ds`) with the scan dimensions first and the time last, `(*dims, time)` on a common grid or `(*dims, _point)` with the native time points padded with `NaN`, the labels and the changed values as coordinates (a changed target which is also a variable or a name of the result, `RESERVED` of `simulation/scan.py`: `time`, `_point`, `statistic` and `status`, keeps the variable and its values as `<dimension>.<target>`, which must not be a dimension or an output, and a coordinate of a dimension must not take a name of the result, an output, a dimension id or a changed target), `attrs["units"]`, `attrs["changes"]` (the times of the changes after the start in the time of the result), `summary`, `interpolate` (onto a grid of the times of the simulations, a time twice at a change; `time_points` keeps a time twice which a simulation has twice) and netCDF (`to_netcdf`/`from_netcdf` through h5netcdf, the attributes as JSON). `time=` interpolates every timecourse onto a grid in the worker; `on_error="raise"` raises a `ScanError` for the first failing point in the order of the scan with its labels and values, `"flag"` gives `NaN` and the variable `status`. The result does not depend on the number of workers, except in a process in which roadrunner integrated before sbmlsim loaded a model (see `model/roottol.py`, which warns once): there the steps of the integrator inside a segment lack the first step of CVODE after an event if it is shorter than roadrunner's root tolerance of the process, and the rows of an event which CVODE finds in that step, both of which a worker has, so the rows differ by them and the values on a grid by the interpolation across them. The selections of a run without observables are the ones of the model (`RoadrunnerSBMLModel.set_selections`), with observables `time`, what the needed observables read and the selections `keep` names, which the result keeps as timecourses of their own names; the changes of a model are defaults of the pre-initialization changes (`Simulator.compile`). `sbmlsim/parallel.py` owns every pool of the package: `process_context()` is the start method (see Conventions), `pool(n)` is kept per process and number of workers and replaced when it broke or was shut down, `start_pool(n)` is a new pool which its caller stops with `stop` (it terminates the workers and waits for the thread of the pool, the only one which waits for the workers, since two waiting threads race under `spawn`), `shutdown` stops the kept pools (at exit), `worker_cache(key, factory)` keeps objects in a worker (the models of a scan, the problem of a fit) and `resolve_workers(n_workers, n_tasks)` turns `n_workers` into processes: `1` is serial in the calling process, a number is taken as given, `None` is every CPU from `POOL_THRESHOLD = 256` tasks (measured by `tests/simulator/test_benchmark.py`) and serial below and inside a worker, which never starts a pool. The workers ignore SIGINT (on POSIX they start with it blocked, so Ctrl-C does not reach a worker which still imports), the parent stops the pool of a run which Ctrl-C interrupts, and a worker which ran a chunk silences SUNDIALS, so a failing point is reported by its error. `Simulator.run` computes observables from every simulation: `Formula` (a formula of PEtab math over the selections and other observables, with the reductions `max`/`min`/`mean`/`at` over the time of each simulation), `PK` (the non-compartmental analysis of pkpdutils, every parameter a value per simulation `<id>.<parameter>`) and `Custom` (a function of a module, `function(time, values)`), defined in `simulation/observables.py`, frozen and picklable. `simulator/observables.py` holds `compile_observables`, which orders them, checks the symbols against the first model, derives kinds (value per simulation or timecourse) and units (a declared `unit` is the unit of the observable everywhere, the factor from the derived unit is applied when the formula is evaluated; mixed scales of one dimension raise), prunes to what `keep` needs and gives the picklable `ObservableGraph`; a run without observables has the `identity_graph` of the selections. `simulator/pk.py` finds the doses from the plans (the values assigned to the dose target and their times), the parameters by a probe analysis of the plan of the first point of every simulation and model, which counts every assignment of the dose target as a dose, a zero value included (so a zero first dose keeps the dose parameters, while a point's own zero doses are dropped and give `NaN`), analyses the points in groups of the same number of doses and time points (so a parameter does not depend on the chunking) on the timecourses without the states before the changes (`without_states_before`, pkpdutils takes a time once and its first value at the time of a dose as the state after it; `ScanResult.to_timecourses` hands over the same) and imports pkpdutils lazily. A run with observables stacks the native solutions of a chunk and evaluates the graph on them before it interpolates, on a chunk at once and after a failure point by point, so a point fails exactly when its own simulation or observables fail; a run without observables interpolates every solution onto the grid right after `execute` and never stacks them. The result keeps timecourses over `(*dims, time|_point)` and values per simulation over `dims` (no time dimension when all kept observables are values), the definitions in `attrs["observables"]`; `ScanResult.nca`/`to_timecourses` hand a PK analysis and a timecourse over to pkpdutils, and `nca` flags a failed point `NCAFlag.NO_DATA`. `simulation/sampling/` is the sampler: distributions (`Uniform`, `LogUniform`, `Normal`, `LogNormal`, `Truncated`, `Empirical`, `Fixed`, each with `ppf(u, reference)`; a distribution without a location is relative to the reference of its target, `references(model, targets, simulation)`, the value after the pre-initialization) and designs which return a `Dimension` with a `Design` record (`local`, `random`, `lhs` with correlations by a Gaussian copula and by Iman and Conover, `sobol`, `fast`, `morris` on the unit cube of SALib, `fit_parameters` from the Fisher covariance (only in the directions it constrains, the others stay at the fitted value, an error without degrees of freedom), `profile_parameters` from the profile likelihoods (a closed side continued by its quadratic tail, an open side to the bound, never outside the bounds), `fit_repeats`, `population` with covariates as `coordinates` of the dimension, which must not clash with a variable, a dimension id or a target; the designs of a fit write a parameter to `FitParameter.target_id`); the record is in the provenance of the result (`Dimension.to_dict`), so an analysis needs only the result, and `seed=None` draws a recorded seed. `correlation` is the Spearman rank correlation of the values. `fit/sampling.py` draws the start values of a fit with it (the same values for a seed). `sensitivity/uncertainty.py` draws the bands (`plot_bands`) and distributions (`plot_distribution`) of a scan over draws. A simulation answers with a `TimecourseResult` (`result/timecourse.py`), the array roadrunner returns with the names of its columns; `grid_weights`/`apply_weights` are the one linear interpolation onto a grid (a time before a change is interpolated toward the state before it, also within the resolution before it, the time of a change or of a time point which appears twice sees the state after it and not a step of the integrator after it within the resolution, the first of two equal times of the grid or a time in `left` the state before it; a chain of jumps starts at a jump and has the time points after it at most the resolution of the time of the simulation apart, e.g. a change and a dose event closer than the resolution, the steps of the integrator before its first jump are no part of it, and a time at a change, at an event or inside the chain sees the state after its last jump; an event of the model which the steps of the integrator have as two rows at its time (libroadrunner 2.10 reports them `roottol` before and after it, a `static` of `CVODEIntegrator::integrate` which the first integration of the process fixes to `3200 * eps * (|t0| + |h|)` of its first call, 7.1e-9 after the steps of the integrator over `0..10000`, 1.42e-10 after roadrunner's default `simulate(0, 10000)`; on a roadrunner without the static, a failing probe or one without the rows of its event the probe gives 0 and the rows stay as roadrunner reports them; `model/roottol.py` runs a probe before the first model of a process and at the start of a worker (`parallel._initialize_worker`, after the worker imported the main module), which fixes it to 6.2e-31 where sbmlsim integrates first and measures it, and `_steps` gives both rows the time of the event, `at_event_times`, which never sees roadrunner's last row, interpolated to the end; roadrunner folds the row after an event less than `roottol` before or after the end into its last row and leaves the model at the event in the state after it, from which `_events_at_the_end` gives an event before the end its row after it and continues the steps, and sends a segment whose event at or after the end roadrunner applied before the change to exact output), and a time at most the resolution before an event, since CVODE locates an event a little after its time, sees the state after it, but not before a change, whose times every caller passes (`Plan.output_change_times`): the point plan in the worker, the plans in the `at` reduction, `attrs["changes"]` in `ScanResult.interpolate`), which the worker, the `at` reduction, `ScanResult.interpolate` and the fit's `_interpolate_after_jumps` share, each with the resolution of its simulation (`time_tolerance`).
|
|
53
|
+
**`simulation/`, `simulator/`, `result/` - the simulation core.** `Simulation` (`simulation/definition.py`) is the one way to set up a simulation, used by experiments, scans, fits and PEtab: `start`/`end` in its `time_unit` (negative times allowed), `preinit_changes` set on the model before its initialization (the initial assignments see them), `changes`, a list of `Change(times, values)` at absolute times (one time or a vector, i.e. multiple dosing; a value is a number, a `Quantity` or a formula string of PEtab math over roadrunner selections, `S` amount, `[S]` concentration, `time`), `presimulation=SteadyState(...)`, and the output: the steps of the integrator by default, `times` or `steps`. The semantics are PEtab v2 (pre-initialization, simultaneous evaluation of the values of a change, compartment changes keep concentrations, a species of an assignment rule follows its rule; the output at the time of a change after the start has two rows, the state before the change and the state after it, the steps of the integrator at every change and an output of times at its times which are changes; the steps of the integrator have an event of the model as two rows as well, also an event at the end of the simulation). `Scan(simulation, dimensions)` (`simulation/scan.py`) runs it over `Dimension` objects, each of `values` (targets to arrays, coupled within a dimension; a value replaces its target wherever the simulation sets it, `Simulation.with_values`, `at=` makes it a `Change` at that time, and `Scan.__init__` logs one warning per dimension and target when a dimension without `at` replaces a target the simulation sets to different values, e.g. the stop of an infusion), `simulations` or `models`; several dimensions span their product in C order. A dimension copies its values into read-only arrays and has `labels`, which are given or default to `0..n-1` for values and to the keys otherwise; neither a dimension nor a scan changes after it was created, and a run never changes the objects of the user. `simulator/plan.py` compiles a simulation against a model (`ModelSymbols`, `UnitsInformation`) into a frozen, picklable `Plan` without units, output times closer than `TIME_RTOL * max(abs(start), abs(end), end - start)` are one output time, a cluster becoming its smallest time (`merge_times(times, start, end)` gives the merged times and the index of each given time, which `compile_simulation` and the data times of a fit share, so the rows of a fit stay aligned), and a point of a scan is that plan with other values (`Plan.with_values(values, at=None)`), never a compiled simulation; `simulator/executor.py` `execute(plan, model, selections)` runs it on roadrunner (no pint, no pandas, no xarray); every segment between two changes ends in its state at its end, which the next change is applied to: with the steps of the integrator roadrunner's variable step `simulate` ends after the end and interpolates its last row linearly, so `_steps` calls the integrator once more with exact output at the end (`_to_the_end`, CVODE interpolates from its last step, no integration), which also fires an event roadrunner kept pending, and so does every horizon of a steady state; every segment of a model with events stops just before its end (`_stop`, a unit in the last place of the larger magnitude of its start and end in the time of roadrunner, which CVODE resolves, and at least four machine epsilons, below which roadrunner applies an event at the start of a call of the integrator without its rows, so the stop is never a subnormal number before an end at 0), so an event of the model at the time of a change fires after it, the last row of a segment which ends at a change, the one at the end included, is the state before the change at the time of the change, and the next segment starts with the state after it; a segment too short for CVODE (`_integrable`, its condition `CV_TOO_CLOSE`, a few units in the last place in absolute time, e.g. between two changes a few units in the last place apart) is not integrated, its state is the one at its start; the triggers before a change and at the end are evaluated at the time the model is at (`stopped`: the time of the model after the segment before, which roadrunner may integrate one unit in the last place past its stop, the start of a segment which is not integrated, `plan.start` before the first one), so an event of the time fires once whatever segments are held; roadrunner does not see a trigger which a change makes true, the executor fires such events after the change (`_fire_events`, PEtab v2 reinitialization): one at a time in the order of their priorities, which are evaluated again after every event (ties in document order, a priority which is no formula of `compile_formula`, e.g. one with `floor` or a function definition, is reported and counts as 0, the priority of an event without one), the triggers are evaluated again after every event as well and a pending event whose trigger is not persistent is cancelled when it becomes false, the values of the assignments are the ones at the trigger or at the execution as `useValuesFromTriggerTime` says, an event with a delay or with assignments which are no formulas is reported and not fired, a trigger which is no formula is reported once per event and model instance (`RoadrunnerSBMLModel.reported_triggers`, so once per worker of a pool) and a change does not fire its event (`ModelSymbols` writes the math of an event without the units of its numbers, `0.5 dimensionless` of sbmlutils is no formula, #293, with the constants `pi`, `exponentiale` and `avogadro` as their values and the base of a logarithm last, as PEtab reads `log(x, b)`, #296), and one event fires at most `MAX_EXECUTIONS_PER_EVENT` times, which stops events which trigger each other in a cycle without limiting the number of events which fire; after the last segment `_event_at_the_end` integrates the steps of the integrator to the resolution of the time after the end, pairing the rows of an event within the rounding of `at_event_times`, an event there is at the end (two rows in the steps of the integrator, the state after it at an output time at the end, after a change at the end), and the steady state after the end starts at the time of the model after it, so an event of the time does not fire twice; roadrunner integrates an exact output time from the one before it, `t + (next - t)`, which can round up to the time of the change, `_simulate_times` then puts a time between from which the sum is exact; a segment of a model with events past whose end roadrunner fired an event runs again with exact output at the times of its steps (`_PastTheEnd`, `_exact_times`, an event inside integrated to a resolution of the time before and after it, its rows at the times of the steps): the plan runs once more, after a second such segment a third time, which keeps the state at the start of every later segment in a temporary file (`_saved_state`, `saveState(path)`; `saveStateS` of roadrunner 2.10 keeps every state in memory) that a later segment past its end starts again from, so a plan runs at most three times; `_variable_steps` hides roadrunner's warning that a negative end was not reached. `Simulator(n_workers=None, **integrator_settings)` (`simulator/simulator.py`) has `load`, `compile`, `simulate` (one `TimecourseResult`) and `run(model, scan, observables=None, *, time, keep, on_error, progress)`: it compiles one plan per combination of the simulations and models of a scan, cuts the points into chunks of one plan (at most `ceil(n_points / (4 * n_workers))` and `MAX_CHUNK` points) and runs them with `simulator/worker.py` serially or in the kept pool of `sbmlsim/parallel.py` (the same function `run_chunk`, a worker loads a model once from its `ModelSpec`, keyed on the hash of its SBML as the parent loaded it (`RoadrunnerSBMLModel.sbml`), the added parameters, the integrator and every one of its settings as the model of the parent has them, so a setting of the model holds in a worker as well and a file rewritten or deleted after the model was loaded changes nothing; `parallel.shared_payloads` writes the SBML of the models of a run into files of a private temporary directory, one file per content, which a worker reads instead of receiving the SBML with every chunk, and removes them after the run, also after an error; a pool run keeps at most two chunks per worker pending, submitted in the order of their first point, and submits no chunk after a failed point, while the chunks before it still run; every chunk checks that its plan was compiled for the symbols and units of its model, `Plan.check_model` with `model_units`, the base unit and the scale of the unit of every entity, a factor of a unit such as `item/(31557600.0*s)` in the scale and a unit pint does not normalize as it is), and assembles a `ScanResult` (`result/scan.py`), which wraps an `xarray.Dataset` (`ds`) with the scan dimensions first and the time last, `(*dims, time)` on a common grid or `(*dims, _point)` with the native time points padded with `NaN`, the labels and the changed values as coordinates (a changed target which is also a variable or a name of the result, `RESERVED` of `simulation/scan.py`: `time`, `_point`, `statistic` and `status`, keeps the variable and its values as `<dimension>.<target>`, which must not be a dimension or an output, and a coordinate of a dimension must not take a name of the result, an output, a dimension id or a changed target), `attrs["units"]`, `attrs["changes"]` (the times of the changes after the start in the time of the result), `summary`, `interpolate` (onto a grid of the times of the simulations, a time twice at a change; `time_points` keeps a time twice which a simulation has twice) and netCDF (`to_netcdf`/`from_netcdf` through h5netcdf, the attributes as JSON). `time=` interpolates every timecourse onto a grid in the worker; `on_error="raise"` raises a `ScanError` for the first failing point in the order of the scan with its labels and values, `"flag"` gives `NaN` and the variable `status`. The result does not depend on the number of workers, except in a process in which roadrunner integrated before sbmlsim loaded a model (see `model/roottol.py`, which warns once): there the steps of the integrator inside a segment lack the first step of CVODE after an event if it is shorter than roadrunner's root tolerance of the process, and the rows of an event which CVODE finds in that step, both of which a worker has, so the rows differ by them and the values on a grid by the interpolation across them. The selections of a run without observables are the ones of the model (`RoadrunnerSBMLModel.set_selections`), with observables `time`, what the needed observables read and the selections `keep` names, which the result keeps as timecourses of their own names; the changes of a model are defaults of the pre-initialization changes (`Simulator.compile`). `sbmlsim/parallel.py` owns every pool of the package: `process_context()` is the start method (see Conventions), `pool(n)` is kept per process and number of workers and replaced when it broke or was shut down, `start_pool(n)` is a new pool which its caller stops with `stop` (it terminates the workers and waits for the thread of the pool, the only one which waits for the workers, since two waiting threads race under `spawn`), `shutdown` stops the kept pools (at exit), `worker_cache(key, factory)` keeps objects in a worker (the models of a scan, the problem of a fit) and `resolve_workers(n_workers, n_tasks)` turns `n_workers` into processes: `1` is serial in the calling process, a number is taken as given, `None` is every CPU from `POOL_THRESHOLD = 256` tasks (measured by `tests/simulator/test_benchmark.py`) and serial below and inside a worker, which never starts a pool. The workers ignore SIGINT (on POSIX they start with it blocked, so Ctrl-C does not reach a worker which still imports), the parent stops the pool of a run which Ctrl-C interrupts, and a worker which ran a chunk silences SUNDIALS, so a failing point is reported by its error. `Simulator.run` computes observables from every simulation: `Formula` (a formula of PEtab math over the selections and other observables, with the reductions `max`/`min`/`mean`/`at` over the time of each simulation), `PK` (the non-compartmental analysis of pkpdutils, every parameter a value per simulation `<id>.<parameter>`) and `Custom` (a function of a module, `function(time, values)`), defined in `simulation/observables.py`, frozen and picklable. `simulator/observables.py` holds `compile_observables`, which orders them, checks the symbols against the first model, derives kinds (value per simulation or timecourse) and units (a declared `unit` is the unit of the observable everywhere, the factor from the derived unit is applied when the formula is evaluated; mixed scales of one dimension raise), prunes to what `keep` needs and gives the picklable `ObservableGraph`; a run without observables has the `identity_graph` of the selections. `simulator/pk.py` finds the doses from the plans (the values assigned to the dose target and their times), the parameters by a probe analysis of the plan of the first point of every simulation and model, which counts every assignment of the dose target as a dose, a zero value included (so a zero first dose keeps the dose parameters, while a point's own zero doses are dropped and give `NaN`), analyses the points in groups of the same number of doses and time points (so a parameter does not depend on the chunking) on the timecourses without the states before the changes (`without_states_before`, pkpdutils takes a time once and its first value at the time of a dose as the state after it; `ScanResult.to_timecourses` hands over the same) and imports pkpdutils lazily. A run with observables stacks the native solutions of a chunk and evaluates the graph on them before it interpolates, on a chunk at once and after a failure point by point, so a point fails exactly when its own simulation or observables fail; a run without observables interpolates every solution onto the grid right after `execute` and never stacks them. The result keeps timecourses over `(*dims, time|_point)` and values per simulation over `dims` (no time dimension when all kept observables are values), the definitions in `attrs["observables"]`; `ScanResult.nca`/`to_timecourses` hand a PK analysis and a timecourse over to pkpdutils, and `nca` flags a failed point `NCAFlag.NO_DATA`. `simulation/sampling/` is the sampler: distributions (`Uniform`, `LogUniform`, `Normal`, `LogNormal`, `Truncated`, `Empirical`, `Fixed`, each with `ppf(u, reference)`; a distribution without a location is relative to the reference of its target, `references(model, targets, simulation)`, the value after the pre-initialization) and designs which return a `Dimension` with a `Design` record (`local`, `random`, `lhs` with correlations by a Gaussian copula and by Iman and Conover, `sobol`, `fast`, `morris` on the unit cube of SALib, `fit_parameters` from the Fisher covariance (only in the directions it constrains, the others stay at the fitted value, an error without degrees of freedom), `profile_parameters` from the profile likelihoods (a closed side continued by its quadratic tail, an open side to the bound, never outside the bounds), `fit_repeats`, `population` with covariates as `coordinates` of the dimension, which must not clash with a variable, a dimension id or a target; the designs of a fit write a parameter to `FitParameter.target_id`); the record is in the provenance of the result (`Dimension.to_dict`), so an analysis needs only the result, and `seed=None` draws a recorded seed. `correlation` is the Spearman rank correlation of the values. `fit/sampling.py` draws the start values of a fit with it (the same values for a seed). `sensitivity/uncertainty.py` draws the bands (`plot_bands`) and distributions (`plot_distribution`) of a scan over draws. A simulation answers with a `TimecourseResult` (`result/timecourse.py`), the array roadrunner returns with the names of its columns; `grid_weights`/`apply_weights` are the one linear interpolation onto a grid (a time before a change is interpolated toward the state before it, also within the resolution before it, the time of a change or of a time point which appears twice sees the state after it and not a step of the integrator after it within the resolution, the first of two equal times of the grid or a time in `left` the state before it; a chain of jumps starts at a jump and has the time points after it at most the resolution of the time of the simulation apart, e.g. a change and a dose event closer than the resolution, the steps of the integrator before its first jump are no part of it, and a time at a change, at an event or inside the chain sees the state after its last jump; an event of the model which the steps of the integrator have as two rows at its time (libroadrunner 2.10 reports them `roottol` before and after it, a `static` of `CVODEIntegrator::integrate` which the first integration of the process fixes to `3200 * eps * (|t0| + |h|)` of its first call, 7.1e-9 after the steps of the integrator over `0..10000`, 1.42e-10 after roadrunner's default `simulate(0, 10000)`; on a roadrunner without the static, a failing probe or one without the rows of its event the probe gives 0 and the rows stay as roadrunner reports them; `model/roottol.py` runs a probe before the first model of a process and at the start of a worker (`parallel._initialize_worker`, after the worker imported the main module), which fixes it to 6.2e-31 where sbmlsim integrates first and measures it, and `_steps` gives both rows the time of the event, `at_event_times`, which never sees roadrunner's last row, interpolated to the end; roadrunner folds the row after an event less than `roottol` before or after the end into its last row and leaves the model at the event in the state after it, from which `_events_at_the_end` gives an event before the end its row after it and continues the steps, and sends a segment whose event at or after the end roadrunner applied before the change to exact output), and a time at most the resolution before an event, since CVODE locates an event a little after its time, sees the state after it, but not before a change, whose times every caller passes (`Plan.output_change_times`): the point plan in the worker, the plans in the `at` reduction, `attrs["changes"]` in `ScanResult.interpolate`), which the worker, the `at` reduction, `ScanResult.interpolate` and the fit's `_interpolate_after_jumps` share, each with the resolution of its simulation (`time_tolerance`).
|
|
54
54
|
|
|
55
|
-
**`model/` - models.** `AbstractModel` is the description (source, language, changes, selections) without loading; `model_resources.Source` resolves the source (path relative to `base_path` or the SBML itself). `RoadrunnerSBMLModel` owns the `roadrunner.RoadRunner` instance `r` (`None` until loaded), keeps the SBML it hands to roadrunner as `sbml` (flattened, a hierarchical model read from its file or, inline, resolved against its `base_path`, before the added parameters and the helpers; the snapshot a worker loads, never roadrunner's `getSBML()`, which drops elements without math), reads the units from it into `uinfo` (a hierarchical model has the units of its submodels) and the `ModelSymbols` (`model/symbols.py`: parameters, compartments, species, `hasOnlySubstanceUnits`, the initial assignments in their order) into `symbols`, and adds a helper parameter `<x>__initial` with an assignment rule per initial assignment. `initialize(assignments)` resets the model (`reset_all`, the binding of `resetAll`, because a symbol named `reset` hides the method) and sets the pre-initialization values as current values and evaluates the dependent initial assignments again from the helpers: roadrunner's `init(...)` regenerates the model on every call (0.3 to 0.5 s on the HCTZ model). It never resets twice without a simulation in between, roadrunner fires the events at t0 once per reset. The changes of an `AbstractModel` are `preinit_changes` of every simulation of it unless the simulation sets the target. `set_integrator_settings` is a method of the model and passes every setting on to roadrunner, only the ones which changed, so a simulator which applies its settings before every simulation costs nothing (the tolerances are computed again only for another tolerance, another roadrunner instance or
|
|
55
|
+
**`model/` - models.** `AbstractModel` is the description (source, language, changes, selections) without loading; `model_resources.Source` resolves the source (path relative to `base_path` or the SBML itself). `RoadrunnerSBMLModel` owns the `roadrunner.RoadRunner` instance `r` (`None` until loaded), keeps the SBML it hands to roadrunner as `sbml` (flattened, a hierarchical model read from its file or, inline, resolved against its `base_path`, before the added parameters and the helpers; the snapshot a worker loads, never roadrunner's `getSBML()`, which drops elements without math), reads the units from it into `uinfo` (a hierarchical model has the units of its submodels) and the `ModelSymbols` (`model/symbols.py`: parameters, compartments, species, `hasOnlySubstanceUnits`, the initial assignments in their order) into `symbols`, and adds a helper parameter `<x>__initial` with an assignment rule per initial assignment. `initialize(assignments)` resets the model (`reset_all`, the binding of `resetAll`, because a symbol named `reset` hides the method; `resetAll` evaluates the initial values with the parameters of the simulation before and misses the values as loaded in the last bits, so `_restore_loaded_state` sets back every settable value which differs from the model as loaded, #303; `reset_all` sets the integration start times of the integrator and of the model to 0 first, roadrunner queues the events at t0 at the start of the last `simulate` call, and `discard_pending_events` regenerates a model with delayed events before a simulation which integrates beyond the time the last simulation since the load or the last regeneration reached, also after an initialization without a simulation, roadrunner's reset keeps the pending events, with a number as the absolute tolerance during `regenerateModel`, whose restore of a vector raises for a species of an assignment rule, #305) and sets the pre-initialization values as current values and evaluates the dependent initial assignments again from the helpers: roadrunner's `init(...)` regenerates the model on every call (0.3 to 0.5 s on the HCTZ model). It never resets twice without a simulation in between, roadrunner fires the events at t0 once per reset. The changes of an `AbstractModel` are `preinit_changes` of every simulation of it unless the simulation sets the target. `set_integrator_settings` is a method of the model and passes every setting on to roadrunner, only the ones which changed, so a simulator which applies its settings before every simulation costs nothing (the tolerances are computed again only for another tolerance, another roadrunner instance or a vector of CVODE set elsewhere); `absolute_tolerance` (a float or an `AbsoluteTolerance` per kind with overrides by id, `model/tolerances.py`) becomes one tolerance per state, set as the vector of CVODE in the order of `state_ids()` (not with `setIndividualTolerance`, which indexes the states in another order): an amount species and a state of a rate rule get the tolerance of their kind, a concentration species the tolerance of a concentration times the initial volume of its compartment in the model as loaded (`_loaded_volumes`, read once per roadrunner instance: roadrunner answers the initial volume of a compartment with an initial assignment or a rule from the current parameters, i.e. from the pre-initialization of the last simulation, which made a run depend on the one before it, #292), raised to `1e-6` times the largest volume when it is degenerate; `tolerances()` lists them. `ModelSymbols.time_dependent` is true when a math reads the csymbol `time` or `delay` or an event has a delay (roadrunner keeps a pending event at a time of its clock); the executor integrates every other model in local time, every segment between two changes from the time 0 of roadrunner, so that the first step of CVODE after a late change is not below the resolution of the time.
|
|
56
56
|
|
|
57
57
|
**`units.py` - units.** One registry for the package, `sbmlsim.units.ureg`, and its quantity `sbmlsim.Q`; the registry adds `none`, `item` and `percent` to pint and no international unit, which is specific to a substance (a model or a user defines its own, e.g. `IU_insulin`). `UnitsInformation` maps identifiers to unit expressions; `from_sbml` reads the units of a model as expressions pint parses (`Units.udef_to_str`, prefixes and names of pint, e.g. `mmol/min`), the ids of unit definitions are not defined in the registry except for a unit with a factor which is no prefix, under a collision free name. `sbmlsim.Q` takes the units of pint only (its `UndefinedUnitError` carries a note naming `model.Q` and `experiment.Q`); the unit ids of a model are kept in its `UnitsInformation` (`unit_ids`, unit id to expression, from `model_uid_dict`), and `UnitsInformation.quantity` replaces every whole identifier of a unit string which is a unit id by its expression in brackets (`replace_unit_ids`, a number like `1e-3` is no identifier, a unit id wins over a pint unit of the same name), so `mg_per_min/kg` works; `RoadrunnerSBMLModel.Q` is that function, `SimulationExperiment.Q(value, unit, model=None)` resolves the ids of the models the runner loaded before `initialize` (without `model=` an id must have one expression in every model which has it), and a `FitParameter.unit` may be a unit id of the model of its target (`ParameterMapping.parameter_units` resolves it in the models of the simulations it reaches and compares the units of versions as parsed units); the parameter keeps its unit for the display and the PEtab export, while the values of a fit carry the resolved units of pint (`OptimizationProblem.parameter_units`, the units of a `ParameterSet`, `OptimizationResult.units`, `FisherInformation.units`, the parameter set of an `IdentifiabilityResult`), which the designs of `simulation/sampling` read without a model. `normalize_changes` converts quantities to model units, and `Quantity` (an alias of pint's `PlainQuantity`, the base of every quantity a registry creates) is the type used in all annotations.
|
|
58
58
|
|
|
59
|
-
**`experiment/`, `data.py`, `task/`, `plot/`, `report/` - simulation experiments.** `SimulationExperiment` (`experiment/experiment.py`) is subclassed with `models()`, `datasets()`, `simulations()`, `observables()` (the `Formula`, `PK` and `Custom` of the scan core by their id), `tasks()`, `data()`, `figures()` and `fit_mappings()`, each returning a dict keyed by id; `initialize()` collects them and `run(simulator)` runs the tasks, evaluates the data and renders the figures. `ExperimentRunner` (`experiment/runner.py`) resolves the abstract models into roadrunner models, loaded once per `model_key` (the resolved path of a file, the content of inline SBML and, for a hierarchical one, its resolved base directory, the changes, the added parameters and the selections), runs several experiments and writes results, figures and the JSON serialization (`to_json`, encoded before the file is written, raises for a value `ObjectJSONEncoder` has no codec for; the run of an experiment reports it, names the type and writes no JSON instead of failing). A run keeps what the report needs and not more: an experiment keeps only the keys of its matplotlib figures once they are written (a figure holds the pixel buffer of its last rendering), and the runner releases the results of an experiment once its outputs are written (`keep_results=False`, `SimulationExperiment.results` raises then; `SimulationExperiment.run` keeps them by default), so a run of many experiments holds only the one it runs. `Data` (`data.py`) is a promise for data of a task (`Data("[X]", task=...)`, an observable `Data("pk.cmax", task=...)`), a dataset column or a function of other data; `DataSet` is a `pandas.DataFrame` with `uinfo
|
|
59
|
+
**`experiment/`, `data.py`, `task/`, `plot/`, `report/` - simulation experiments.** `SimulationExperiment` (`experiment/experiment.py`) is subclassed with `models()`, `datasets()`, `simulations()`, `observables()` (the `Formula`, `PK` and `Custom` of the scan core by their id), `tasks()`, `data()`, `figures()` and `fit_mappings()`, each returning a dict keyed by id; `initialize()` collects them and `run(simulator)` runs the tasks, evaluates the data and renders the figures. `ExperimentRunner` (`experiment/runner.py`) resolves the abstract models into roadrunner models, loaded once per `model_key` (the resolved path of a file, the content of inline SBML and, for a hierarchical one, its resolved base directory, the changes, the added parameters and the selections), runs several experiments and writes results, figures and the JSON serialization (`to_json`, encoded before the file is written, raises for a value `ObjectJSONEncoder` has no codec for; the run of an experiment reports it, names the type and writes no JSON instead of failing). A run keeps what the report needs and not more: an experiment keeps only the keys of its matplotlib figures once they are written (a figure holds the pixel buffer of its last rendering), and the runner releases the results of an experiment once its outputs are written (`keep_results=False`, `SimulationExperiment.results` raises then; `SimulationExperiment.run` keeps them by default), so a run of many experiments holds only the one it runs. `Data` (`data.py`) is a promise for data of a task (`Data("[X]", task=...)`, an observable `Data("pk.cmax", task=...)`), a dataset column or a function of other data; `DataSet` is a `pandas.DataFrame` with `uinfo`; `DataSet.from_df` brings the rows of a column to the unit of its first row and reads a unit with a numeric factor, which PK-DB writes (`ml/min/(1.73*m^2)`, `micromol/(0.5*hr)`), as a number of the values (`_parse_unit`, #294): the numbers of its rows are multiplied by the factor and the column gets the unit without it; a `*_unit` column applies to its column and its `_sd`, `_se`, `_min` and `_max`, the `unit` column to all numbers of a row (`mean`, `value`, `median`, `sd`, `se`, `min`, `max`, not `cv`), converted in one pass (`_unify_units`), so the statistics get one unit and shared numbers are converted once. `Task` pairs a model and a `Simulation` or a `Scan`; the results are `ScanResult`s, written as netCDF. The index of every task data of `data()`, the fit mappings and the figures is classified at `initialize()` as `time`, an observable, a coordinate of the scan or a selection of the model (an unknown one raises), and a task whose data read observables runs with the observables they need and keeps them next to its selections in one run. `Data.get_data` returns an `xarray.DataArray` with the dimensions of its source, their coordinates and `attrs["units"]` (`to_quantity` gives the pint quantity): a task variable over `(*dims, time)`, `(*dims, _point)` for a ragged result padded with `NaN`, or `(*dims)`, a dataset column over `row`, a function broadcast by dimension name; the plain name of a symbol is its timecourse, every array of a task names the values a dimension sets `<dimension>.<target>`, the plain name of an unkept changed target raises; `sel=` selects labels (a dimension of the scan the data has not is skipped) or the rows of a dataset by column values, and `sel` of task data is checked against the scan at `initialize()`. A curve names the dimensions of a scan it draws one line per point of (`over=`) and a band (`Plot.band`, `Band`) reduces a dimension of draws to two quantiles and the median; `plot/points.py` splits the broadcast arrays into the lines (`curve_lines`, `band_lines`, without the padding) and gives their colours (shades of the colour of the curve or viridis, a second dimension sets the line style), legend labels (the value and unit of the changed target) and from eleven points a colour bar, which both serializers draw; `initialize()` checks from the definitions that every dimension of a scan a curve or band reads is its axis, in `over`/`across` or selected, and a band of a ragged scan raises. `plot/plotting.py` is the backend independent figure model (`Figure`, `Plot`, `Axis`, `Curve`, `Band`, `ShadedArea`, `Style` with `Line`, `Marker`, `Fill`); `plot/serialization_matplotlib.py` renders it as the static images and `plot/serialization_plotly.py` as the interactive pages; the format chooses the backend, i.e. `figure_formats=["svg", "html"]`, `STATIC_FORMAT`/`INTERACTIVE_FORMAT` name the two and a run which asks only for `html` never builds a matplotlib figure. `FigureSettings` (`plot/plotting.py`) holds the settings of the rendering (dpi, panel size, fonts, legend), which cascade, the more specific wins: its defaults, the run (`figure_settings=` of `SimulationExperiment.run`, `ExperimentRunner.run_experiments` and `run_experiments`, checked when it starts), the experiment (the read-only class attribute `SimulationExperiment.figure_settings`, inherited by subclasses, checked at `initialize`) and the figure (`Figure(settings=...)`); both serializers read only the resolved settings (`Figure.resolved_settings`), a figure without an explicit `width`/`height` gets its size from the panels when it is rendered (`Figure.size`), and the names of the settings on `Figure`, on a figure or in the body of a subclass raise an `AttributeError` with the migration (the settings were class attributes which leaked into later experiments, #260). plotly is in the `dev` extra and not a dependency; matplotlib keeps the static images because plotly writes them through a headless browser at 301 ms per figure against 117 ms. `report/experiment_report.py` renders HTML/markdown reports from jinja2 templates in `resources/templates/`; `report/templates.py` provides the shared jinja2 environment and `report_base.html`, the base the HTML reports of the experiments and of a fit extend, which carries the style, the search, the filter chips, the sortable tables and the figure overlay.
|
|
60
60
|
|
|
61
61
|
**`fit/` - parameter fitting.** `FitMappingCollection` (the former `FitExperiment`) names a simulation experiment class, the mappings of it a fit uses together, their `MappingKind` and an `sid`; it is the unit a fit is defined in and the unit a PEtab problem is built from, `FitMapping` pairs a reference `FitData` (dataset) with an observable `FitData` (task), optionally with an `ObservableModel` when the observable is a formula of selections, `FitParameter` carries bounds, unit and an optional `Prior` (the priors of PEtab v2, truncated at the bounds, which `petab_v2.likelihood.log_prior` evaluates and the optimizer does not use), plus a `target` (the model entity it writes, `pid` by default) and a `mappings` selector so several parameters can estimate one target separately for different parts of the data, e.g. a dissolution rate once for oral and once for intravenous dosing; a selector must be a module level function, not a lambda or a closure, because `OptimizationProblem.__getstate__` pickles the parameters for the workers of a parallel fit. A fit mapping is a timecourse, a value per simulation (`FitData(xid=None)`, e.g. `pk.cmax`, against one or several rows of a reference) or values over one dimension of a scan (`xid="<dimension>.<target>"`, interpolated along the values of the dimension), decided at `initialize` from the dimensions of the observable after `sel` (`OptimizationProblem.observation_kinds`); a simulation group of a scan computes the values and times of its points once (`simulator.scan_point_values`, which `scan_point_plans` shares) and simulates every point on the plan of an evaluation with the fitted values applied first (`worker.point_plan`), so a dimension wins over a fitted parameter of its target (`initialize` warns), and evaluates its observables with `simulator.worker.observe`, as the workers of a run do; a scan without dimensions is its simulation, while a group of timecourses of a plain simulation runs as before; the PEtab export raises for such mappings (the gaps `scalar-observable` and `scan-task`). `fit/parameter_mapping.py` holds `ParameterMapping`, which resolves the selectors to the simulation groups of an initialized problem, validates the binding (a selector must not split a simulation, two parameters must not write one target in one simulation, the versions of a target must agree on their unit) and reports the coverage of every parameter, which the console and the HTML report show as a table once a parameter is versioned. `OptimizationProblem` (`fit/optimization.py`) is picklable; `initialize(settings)` creates the runner, resolves the data and the weights and is a no-op when the `FitSettings` did not change, `residuals`/`cost_least_square` are the objective, `optimize` runs scipy least squares or differential evolution. `FitSettings` (`fit/options.py`, which also enumerates residual, loss, weighting and parameter scale types) is the bundle both a fit and its report need; `parameter_scale` (`LOG10` by default) is the space the optimizer searches, `problem.to_scale`/`from_scale` convert and the bounds and fitted parameters stay on the linear scale. `data_at_change` (`DataAtChangeType`, `before` by default) compares a data point at the time of a change after the start, within the resolution of the time of `merge_times` (`time_tolerance`, `Plan.at_change`), with the state before the change, except the first point of a curve (the point or points with the smallest time of a mapping which has data at a later time, `_first_after`; a curve of a single time takes the state before), which takes the state after it: the output of a fit is the one of a run, with two rows at a change after the start (an output time of the data at a change is the time of the change), and a data point takes one of them (`_rows` of a group which outputs the times of its data, whose output has the times of the changes within them as well; the mask `before` of `_interpolate_after_jumps`, the rule of `grid_weights`, for a group which keeps its output, which interpolates the data up to a change toward the state before it and from it from the state after it); a group which keeps its output of explicit times and has a timecourse outputs the times of the changes within them too (`_group_added`), computes its values per simulation on the output without them, as a run has it, and its timecourses on the output with them (`_timecourse_graph`), so its observables, e.g. the `PK` parameters, are the ones of the run, and the curve of a mapping in the report jumps at a change; a PEtab problem read without the extension and the PEtab suites use `after`, and the export reports the gap `measurement-at-change`. `fit/runner.py` samples the start points of all repeats (`fit/sampling.py`), so they do not depend on the number of workers, and runs the repeats serially in the calling process for one worker (the default, `n_cores=1`, or `serial=True`) and otherwise as tasks of a pool of `sbmlsim.parallel.start_pool` which the fit stops after it, a worker initializes the problem once per fit and keeps it in `parallel.worker_cache`; `FitPool` keeps at most `n_cores` repeats in flight and collects them as they finish, ordered by their index, a pool which breaks because a worker dies is started again (at most `MAX_POOL_RESTARTS` times) and the repeats which were running, the suspects, run again one at a time, so only a repeat which breaks the pool alone fails; it shows the progress of the runs with rich. A parallel fit needs the `if __name__ == "__main__":` guard, the runner reports it when the workers die while they start; `fit/result.py` collects the fits into an `OptimizationResult`, which stores the settings and hands out the fitted parameters as the `ParameterSets` of `fit/parameters.py`. Reporting is separate from optimizing: `FitReport` (`fit/report.py`) is built from a problem, its settings and one or more parameter sets, so a report is created from stored parameters without running a fit and several sets are compared in one report. Two figures per fit mapping are 88% of the cost of a report, `mapping_figures=False` (and `--no-mapping-figures` on the command line tools) leaves them out, which is what the tests do. Its `index.html` is rendered from the jinja2 template `resources/templates/fit_report.html` into the sections overview, results and fit mappings; the page carries its own css and javascript (search, filter chips, sortable tables, click to enlarge) and loads nothing from the network. The `MappingKind` of a `FitExperiment` decides what a fit does with the mappings it selects: `TRAINING` enters the cost, `VALIDATION` (data a fit is checked against) and `OUTLIER` (unusable data) are resolved, simulated and evaluated but not fitted, `EXCLUDED` (data the model does not describe) is not resolved at all; `EVALUATED_KINDS` and `UNUSED_KINDS` are the two halves, and `training_indices`/`validation_indices`/`outlier_indices` are the positions in the resolved data. The kind belongs to the selection of the data, not to the fit mappings of a simulation experiment, whose `MappingMetaData` describes the curve; `fit/helpers.py` is the selection: `FitMappings` is the complete list of the fit mappings of the experiments, loaded once, and `FitMappings.select(filters, outliers, validation)` sets the kind of every mapping in three ordered steps, the filters select the training data and exclude the rest, the outlier keys tag the training data which is not usable, and the validation keys or filter take part of what is left, so excluded beats outlier beats validation beats training; the `MappingSelection` holds the kinds, the overview table and one `FitMappingCollection` per experiment and kind, `select_mapping_collections` is the one call version a `FitDefinition` uses. `fit/metrics.py` (the former `rmse.py`) calculates the metrics of a parameter set on a problem, i.e., the `DV`/`PRED`/`IPRED` table with the residuals and MSE, RMSE, R² and AIC per mapping (keyed by experiment and mapping), per kind (training, validation and outlier) and overall, the AIC and BIC of a perfect fit are `-inf` and R² of fewer than two points `NaN`; a report writes them as TSV. `FitReport.points`/`point_kinds` are the data points with their kind and the kinds the problem has, which `plot_goodness_of_fit` (prediction against measurement) and `plot_bland_altman` (the ratio over the geometric mean with the bias and the limits of agreement of `agreement`, i.e. of the training data, as fold factors and the same lines in every panel) draw one panel each for; both draw that band in the same styles (`IDENTITY_STYLE`, `BIAS_STYLE`, `LIMITS_STYLE`, `BAND_ALPHA`), horizontal in the one and parallel to the diagonal in the other; there is no `all` panel and no `all` row in `summary_df`, which would pool fitted with dropped data. The points of both carry the color of their study (`studies`/`study_color`, `STUDY_COLORS`) and the marker of their parameter set (`set_marker`, `SET_MARKERS`). A report only shows what a fit evaluates, i.e. `EVALUATED_KINDS`; the excluded data has no rows, no chip and no figures. `fit/display.py` renders the console output of a fit as sections (the problem, the parameters, the settings and the data with its kinds), so that the runner, the command line tools and an interactive session look the same. `fit/cli.py` holds what every fit shares: a `FitDefinition` is the fit experiments, the parameters, the paths and the settings of a problem, `run_fit` builds the problems for an `OptimizationStrategy` and runs them, and `fit_cli`/`report_cli` are the command line tools a model reuses, so `examples/hctz_fitting/fitting/fitting.py` is only the definitions. `fit/identifiability.py` is the profile likelihood: `profile_likelihood(problem, settings, parameter_set)` scans every parameter around the optimum in the space of the `parameter_scale` with adaptive steps, re-optimizes the other parameters at every point in the worker pool of the runner, and classifies the parameters from the shape of the profile against the threshold `cost_min + chi2.ppf(alpha, df) / 2` (the cost is `0.5 * Σ r²`); `FitReport(identifiability=...)` adds the section with the profiles and `cli.identifiability_cli` is the tool for stored parameters. `fit/fisher.py` is the local analysis next to it: `fisher_information` builds `FIM = J'J` from one jacobian of the weighted residuals in the space of the `parameter_scale` and gives the standard errors, the correlations, the confidence intervals `θ ± t·SE`, the eigenvalues, the rank and the condition number, so a direction the data does not constrain is found without scanning; `FitRun.fisher()` computes it for a finished fit and `FitReport(fisher=...)` writes it into the same identifiability section, which `identifiability_cli` does unless `--no-fisher` is given. Pickling an initialized `OptimizationProblem` gives its uninitialized definition (`__getstate__`), which is what the workers need. `fit/petab_omex.py` packages PEtab problems as archives. `fit/petab_v2/` is the PEtab v2 layer: `export.py` writes an `OptimizationProblem` as a PEtab v2 problem (models, conditions/experiments from the timecourses, observables and measurements from the fit mappings, parameters, a versioned parameter as a condition which assigns its target the value of the estimated parameter), `reader.py` reads one back and builds a `SimulationExperiment` subclass at runtime, resolving such a condition into a `FitParameter` selected by `helpers.filter_keys`, i.e. by the mapping ids the condition covers rather than by the selector which chose them, `extension.py` is the `sbmlsim` block of the problem YAML which carries what PEtab drops (units, `FitSettings`, mapping kinds, mapping weights, the output grid) so a round trip is exact, an observable of the problem which is a formula rather than an entity is read as an `ObservableModel` (`fit/objects.py`, the formula in the selections of roadrunner with placeholders and their values per measurement), which the fit evaluates on the simulation at the data, so the model is not rewritten, and `gaps.py` is the catalogue of the differences with `gaps_of_problem` reporting the ones a given problem hits. `testsuite.py` runs the PEtab v2 test suite (a pinned commit, cached like the SBML Test Suite, `SBMLSIM_PETAB_SUITE_PATH`): a case of a model is read, simulated at the nominal values of its parameter table and compared on llh, chi2, simulations, log prior and log posterior, a math case compiles its expression with `compile_formula`; `scripts/petab_testsuite.py` writes and checks `tests/data/petab_baseline.json` (with `sbmlsim.testsuite.baseline`, which the SciML suite shares) and the cases are tests with the marker `petab_testsuite`. `benchmark.py` is the same for the benchmark collection (a pinned commit converted with `petab1to2`, `SBMLSIM_BENCHMARK_PATH`): a problem is simulated once at its nominal values and compared with the simulations of the collection, matched by row or by their keys, and with the log-likelihood of AMICI; `scripts/petab_benchmark.py` runs the problems in parallel with a time limit and keeps `tests/data/benchmark_baseline.json`, marker `petab_benchmark`. A problem which is read builds its `SimulationExperiment` at runtime as a subclass of `reader.PetabExperiment` bound to its `_PetabExperimentDefinition` (the tables, the paths and the compiled models, without the reader), which pickles as that definition and builds the reader again in a worker, so such a fit runs in parallel as well. `examples/hctz_fitting` is the reference problem, `tests/fit/` runs against it.
|
|
62
62
|
|
|
@@ -66,7 +66,7 @@ Documentation is [Zensical](https://zensical.org/): markdown sources in `docs/`,
|
|
|
66
66
|
|
|
67
67
|
**`comparison/` - comparison of results.** `diff.py` holds `DataSetsComparison`, which takes a `pandas.DataFrame` or an `xarray.Dataset` (e.g. `ScanResult.ds`) per simulator, matches the columns of the results of two simulators and reports the absolute and relative differences above the tolerances. The scripts which produce such results with AMICI and COPASI are `examples/comparison/`, they import the optional dependencies; `examples/comparison/diff_example.py` compares roadrunner with JWS Online.
|
|
68
68
|
|
|
69
|
-
**`testsuite/` - the SBML Test Suite.** `SemanticCase` (`testsuite/cases.py`) is a semantic case on disk, read from its `NNNNN-settings.txt` and its `NNNNN-model.m` (`componentTags`, `testTags`), not from the SED-ML it also ships; `SemanticSuite` is a directory of cases with the download and the cache of a release under `~/.cache/sbmlsim/test-suite/<version>/` (`SBMLSIM_TEST_SUITE_PATH` overrides it). `SUITE_VERSION` pins the release the tests and the documentation run against, a release resolves `latest_version()` instead and `.github/workflows/testsuite-pin.yml` opens the pull request which adopts a newer one. `run_case` (`testsuite/runner.py`) simulates a case in the newest encoding it provides and answers with a `CaseResult` and its `CaseStatus` (`PASS`, `TOLERANCE`, `NOT_READ`, `SIMULATION_ERROR`, `MISSING_VARIABLE`) rather than raising; the model is initialized with `reset_all`, the binding of `resetAll`, because a model with a species or parameter named `reset` hides the roadrunner method of that name for every instance created afterwards (case 00952). `compare_case` (`testsuite/comparison.py`) applies `comparison.diff.within_tolerance`, i.e. `|c-u| <= abs_tol + rel_tol*|c|`, which `DataSetsComparison` shares. `TestSuiteReport` (`testsuite/report.py`) renders the run into the interactive page `resources/templates/testsuite_report.html`, aggregated over the tags and filtered by outcome. `scripts/testsuite.py` is the command line (`download`, `run`, `report`, `baseline`, `submission`), `run_suite` (`testsuite/runner.py`) and `write_submission` (`testsuite/submission.py`) run the cases in one process per core through `map_cases`, on the kept pool of `sbmlsim.parallel`; only the timecourse cases are run,
|
|
69
|
+
**`testsuite/` - the SBML Test Suite.** `SemanticCase` (`testsuite/cases.py`) is a semantic case on disk, read from its `NNNNN-settings.txt` and its `NNNNN-model.m` (`componentTags`, `testTags`), not from the SED-ML it also ships; `SemanticSuite` is a directory of cases with the download and the cache of a release under `~/.cache/sbmlsim/test-suite/<version>/` (`SBMLSIM_TEST_SUITE_PATH` overrides it). `SUITE_VERSION` pins the release the tests and the documentation run against, a release resolves `latest_version()` instead and `.github/workflows/testsuite-pin.yml` opens the pull request which adopts a newer one. `run_case` (`testsuite/runner.py`) simulates a case in the newest encoding it provides and answers with a `CaseResult` and its `CaseStatus` (`PASS`, `TOLERANCE`, `NOT_READ`, `SIMULATION_ERROR`, `MISSING_VARIABLE`, `REPEAT`) rather than raising; a case which passes is simulated again on its loaded model, the same simulation, the simulation after one of half its duration and a steady state against a fresh model, and each must equal the first bitwise (`REPEAT` otherwise, #305, `repeat_check`; the cases tagged `RandomEventExecution` within their tolerances where a regeneration draws from `std::rand`), with `std::rand`, which orders simultaneous events of equal priority in libroadrunner, seeded before every simulation (`seed_event_order`); the model is initialized with `reset_all`, the binding of `resetAll`, because a model with a species or parameter named `reset` hides the roadrunner method of that name for every instance created afterwards (case 00952). `compare_case` (`testsuite/comparison.py`) applies `comparison.diff.within_tolerance`, i.e. `|c-u| <= abs_tol + rel_tol*|c|`, which `DataSetsComparison` shares. `TestSuiteReport` (`testsuite/report.py`) renders the run into the interactive page `resources/templates/testsuite_report.html`, aggregated over the tags and filtered by outcome. `scripts/testsuite.py` is the command line (`download`, `run`, `report`, `baseline`, `submission`), `run_suite` (`testsuite/runner.py`) and `write_submission` (`testsuite/submission.py`) run the cases in one process per core through `map_cases`, on the kept pool of `sbmlsim.parallel`; only the timecourse cases are run, in one encoding per case (a case which passes is simulated again by the repeat checks of `run_case`), and `tests/testsuite/test_semantic.py` is one test per case against `tests/data/testsuite_baseline.json`, which fails both on a regression and on a case which passes and is still listed. The cases carry the `testsuite` marker and `addopts` deselects it, so they are not part of a normal run: they answer what libroadrunner supports, which a change to `sbmlsim` rarely moves. The `testsuite` job of `ci-cd.yml` runs them on a tag and the release waits for it; the documentation generates the report on `develop` and not on a pull request.
|
|
70
70
|
|
|
71
71
|
`console.py` (rich console, for scripts and examples) and `log.py` provide the shared output/logging. Modules get their logger from the standard library with `logging.getLogger(__name__)`. The package never configures logging: `log.enable_rich_logging()` is the opt-in for scripts. Library code logs, it does not print, and log calls use lazy `%s` formatting rather than f-strings (enforced by ruff `G`).
|
|
72
72
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sbmlsim
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.4
|
|
4
4
|
Summary: sbmlsim are python utilities for the simulation of SBML models.
|
|
5
5
|
Project-URL: Homepage, https://matthiaskoenig.github.io/sbmlsim
|
|
6
6
|
Project-URL: Documentation, https://matthiaskoenig.github.io/sbmlsim
|
|
@@ -92,7 +92,7 @@ If you have any questions or issues please [open an issue](https://github.com/ma
|
|
|
92
92
|
|
|
93
93
|
If you use `sbmlsim` please cite the archived software on [Zenodo](https://doi.org/10.5281/zenodo.3597770):
|
|
94
94
|
|
|
95
|
-
> König, M. (2026). *sbmlsim: SBML simulation made easy* (Version 0.9.
|
|
95
|
+
> König, M. (2026). *sbmlsim: SBML simulation made easy* (Version 0.9.3) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.23313716
|
|
96
96
|
|
|
97
97
|
```bibtex
|
|
98
98
|
@software{konig_sbmlsim,
|
|
@@ -100,10 +100,10 @@ If you use `sbmlsim` please cite the archived software on [Zenodo](https://doi.o
|
|
|
100
100
|
title = {sbmlsim: SBML simulation made easy},
|
|
101
101
|
year = {2026},
|
|
102
102
|
month = oct,
|
|
103
|
-
version = {0.9.
|
|
103
|
+
version = {0.9.3},
|
|
104
104
|
publisher = {Zenodo},
|
|
105
|
-
doi = {10.5281/zenodo.
|
|
106
|
-
url = {https://doi.org/10.5281/zenodo.
|
|
105
|
+
doi = {10.5281/zenodo.23313716},
|
|
106
|
+
url = {https://doi.org/10.5281/zenodo.23313716},
|
|
107
107
|
}
|
|
108
108
|
```
|
|
109
109
|
|
|
@@ -27,7 +27,7 @@ If you have any questions or issues please [open an issue](https://github.com/ma
|
|
|
27
27
|
|
|
28
28
|
If you use `sbmlsim` please cite the archived software on [Zenodo](https://doi.org/10.5281/zenodo.3597770):
|
|
29
29
|
|
|
30
|
-
> König, M. (2026). *sbmlsim: SBML simulation made easy* (Version 0.9.
|
|
30
|
+
> König, M. (2026). *sbmlsim: SBML simulation made easy* (Version 0.9.3) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.23313716
|
|
31
31
|
|
|
32
32
|
```bibtex
|
|
33
33
|
@software{konig_sbmlsim,
|
|
@@ -35,10 +35,10 @@ If you use `sbmlsim` please cite the archived software on [Zenodo](https://doi.o
|
|
|
35
35
|
title = {sbmlsim: SBML simulation made easy},
|
|
36
36
|
year = {2026},
|
|
37
37
|
month = oct,
|
|
38
|
-
version = {0.9.
|
|
38
|
+
version = {0.9.3},
|
|
39
39
|
publisher = {Zenodo},
|
|
40
|
-
doi = {10.5281/zenodo.
|
|
41
|
-
url = {https://doi.org/10.5281/zenodo.
|
|
40
|
+
doi = {10.5281/zenodo.23313716},
|
|
41
|
+
url = {https://doi.org/10.5281/zenodo.23313716},
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -4,7 +4,7 @@ Simulation experiments compare simulations with experimental data. `sbmlsim` rep
|
|
|
4
4
|
|
|
5
5
|
## Datasets
|
|
6
6
|
|
|
7
|
-
A `DataSet` is a `pandas.DataFrame` with units. It is created from a data frame whose columns declare their units, either with a `*_unit` column per column or with one `unit` column which applies to `mean`, `value`, `median
|
|
7
|
+
A `DataSet` is a `pandas.DataFrame` with units. It is created from a data frame whose columns declare their units, either with a `*_unit` column per column, which applies to the column and its `*_sd`, `*_se`, `*_min` and `*_max` columns, or with one `unit` column which applies to all numbers of a row: `mean`, `value`, `median`, their `sd`/`se` columns and the range `min`/`max` (`cv` is relative and has no unit):
|
|
8
8
|
|
|
9
9
|
```python
|
|
10
10
|
import pandas as pd
|
|
@@ -26,7 +26,7 @@ print(dset.uinfo["time"], dset.uinfo["mean"])
|
|
|
26
26
|
print(dset)
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
The unit of a column is the unit of its first row with a value. The unit of a row which carries no number (no value, sd or
|
|
29
|
+
The unit of a column is the unit of its first row with a value. The unit of a row which carries no number (no value, sd, se, min or max) is ignored, and a column without any unit has no unit. Rows with another unit of the same dimension are converted to the unit of the column, all their numbers, and their unit column is rewritten; the rows of a `unit` column are converted in one pass, so `mean`, `value` and `median` get one unit and the numbers they share (`sd`, `se`, `min`, `max`) are converted once. The data frame passed in is not changed. A column whose rows cannot be brought to one unit raises a `ValueError` which names the column and its units: a unit of another dimension or with an offset (`degC` next to `kelvin`), a unit which is undefined, is no string or has a factor which is no positive number, and values which are no numbers. A unit with a numeric factor, as PK-DB writes the unit of a publication (`ml/min/(1.73*m^2)`, `micromol/(0.5*hr)`, `(10*ml)/hr`, `10^9/l`), is read as a number of the values: the numbers of its rows (values, sd, se, min and max) are multiplied by the factor, and a column whose first unit has a factor gets the unit without it, e.g. `8.6` in `micromol/(0.5*hr)` is `17.2` in `micromole/hour`. Every unit is read on import, also the one unit of a column whose rows all have it, so a unit the registry does not define fails here, see [Units](units.md#the-unit-registry-and-q).
|
|
30
30
|
|
|
31
31
|
```python
|
|
32
32
|
mixed = pd.DataFrame({"dose": [1.0, 500.0], "dose_unit": ["g", "mg"]})
|
|
@@ -67,7 +67,7 @@ Continue with [Installation](installation.md) and the [simulation guide](simulat
|
|
|
67
67
|
|
|
68
68
|
If you use `sbmlsim` please cite the archived software on [Zenodo](https://doi.org/10.5281/zenodo.3597770):
|
|
69
69
|
|
|
70
|
-
> König, M. (2026). *sbmlsim: SBML simulation made easy* (Version 0.9.
|
|
70
|
+
> König, M. (2026). *sbmlsim: SBML simulation made easy* (Version 0.9.3) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.23313716
|
|
71
71
|
|
|
72
72
|
## License
|
|
73
73
|
|
|
@@ -71,7 +71,7 @@ A value per simulation is drawn over the values a dimension sets: `plot.curve(x=
|
|
|
71
71
|
|
|
72
72
|
## Bands
|
|
73
73
|
|
|
74
|
-
`plot.band(x, y, across="draw", quantiles=(0.05, 0.95), median=True)` reduces the dimension `across` of y, e.g. the draws of a Latin hypercube design (see [Sampling and uncertainty](sampling.md)), to two quantiles, ignoring `NaN`, and draws the area between them with the median as a line and the quantile boundaries as thin lines in the band colour; `over=` (at most one dimension) gives one band per point of another dimension, in the colours of a curve over it. A band takes `color=`, `alpha=`, `sid=` and `order=` and may sit on the right y axis; a band without a colour takes the colour of the colour cycle at its position among the bands of its plot (`C0`, `C1`, ...), in both backends. The areas are drawn under the lines in both backends. The legend has one entry per
|
|
74
|
+
`plot.band(x, y, across="draw", quantiles=(0.05, 0.95), median=True)` reduces the dimension `across` of y, e.g. the draws of a Latin hypercube design (see [Sampling and uncertainty](sampling.md)), to two quantiles, ignoring `NaN`, and draws the area between them with the median as a line and the quantile boundaries as thin lines in the band colour; `over=` (at most one dimension) gives one band per point of another dimension, in the colours of a curve over it. A band takes `color=`, `alpha=`, `sid=` and `order=` and may sit on the right y axis; a band without a colour takes the colour of the colour cycle at its position among the bands of its plot (`C0`, `C1`, ...), in both backends. The areas are drawn under the lines in both backends. The legend has one entry per band, its area in its colour labelled with the name and the quantiles in percent, `<name> (<low>-<high> %)`, e.g. `C (5-95 %)`: one per point with `over` (`<name>, <point label> (<low>-<high> %)`), or one of the name in the middle colour of the colour map for a band with a colour bar. The quantiles are computed when the figure is drawn, so no summary of the result is needed; a band needs a common grid of times, a ragged scan raises. `examples/experiment_scans.py` draws curves per dose, cmax over dose and a band over draws.
|
|
75
75
|
|
|
76
76
|
## Styles
|
|
77
77
|
|
|
@@ -127,11 +127,11 @@ A model which does not reach a steady state by `SteadyState(max_time=...)` raise
|
|
|
127
127
|
|
|
128
128
|
| step | what happens |
|
|
129
129
|
| --- | --- |
|
|
130
|
-
| pre-initialization | the `preinit_changes` are set on the model before its initialization |
|
|
131
|
-
| initialization | the initial assignments are evaluated, except the ones of the targets of the pre-initialization |
|
|
130
|
+
| pre-initialization | the `preinit_changes` are set on the model before its initialization; a compartment keeps the concentration of a species whose initial value is a concentration or which is set as a concentration and the amount of every other species, a species of an assignment rule follows its rule |
|
|
131
|
+
| initialization | the model is reset to its values as loaded, bitwise, also when roadrunner's reset misses them after the parameters of the simulation before (#303); the events which fire at the time 0 are queued at 0 on every simulation of a loaded model, and the events of earlier simulations which are still pending are discarded when the simulation integrates beyond the time the last simulation of the model reached, also after an initialization without a simulation in between, e.g. the references of a design (#305); the order of simultaneous events of the same priority is random, see [SBML Test Suite](testsuite.md); then the initial assignments are evaluated, except the ones of the targets of the pre-initialization |
|
|
132
132
|
| steady state | with a `SteadyState`, the model is integrated until the rates of change vanish |
|
|
133
|
-
| a change at a time | every value is evaluated with the state at that time, then all values are set at once; a compartment keeps the concentration of the concentration species in it and the amount of the amount species |
|
|
134
|
-
| events | the events of the model whose trigger became true fire after the change |
|
|
133
|
+
| a change at a time | every value is evaluated with the state at that time, then all values are set at once; a compartment keeps the concentration of the concentration species in it and the amount of the amount species, a species of an assignment rule follows its rule |
|
|
134
|
+
| events | the events of the model whose trigger became true fire after the change; a number with a unit in the math of an event, as sbmlutils writes it, is its value, so are the constants `pi`, `exponentiale` and `avogadro` (the value of roadrunner), and a logarithm to a base keeps its base; an event whose trigger or assignments are no formulas the simulator evaluates, e.g. with a function definition, is reported with a warning which names it and does not fire at the change (a trigger once per model instance, i.e. once per worker of a pool) |
|
|
135
135
|
| integration | the interval is split at the times of the changes, and every segment ends in its state at its end, which the change at that time is applied to, also with the steps of the integrator as the output; an event of the model fires at its time, except that with the steps of the integrator roadrunner fires an event with a delay at the end of the step after its time |
|
|
136
136
|
| output | an output time at a change after the start, the change at the end included, has two time points, the state before the change and the state after it, in that order; the steps of the integrator have every change. A time of a grid (`time=`, `ScanResult.interpolate`) sees: (1) before a change, the value interpolated toward the state before it; (2) at a change, the state after it; (3) the first of two equal times of the grid, the state before it. Jumps closer than the resolution of the time, e.g. a change and an event of the model, are one chain, and a time at it or inside it sees the state after the last jump. A fit compares its data at a change with the state before it, see [Parameter fitting](fitting.md#data-at-the-time-of-a-change). An event of the model at the time of a change fires after the change, also at the end |
|
|
137
137
|
| events in the output | with the steps of the integrator an event of the model is two time points at the time of the event, the states before and after it, also an event at the end of the simulation, which an output time at the end sees after it. A time of a grid at an event sees the state after it, and so does a time at most the resolution of the time before it, since the integrator locates an event a little after its time. sbmlsim gives both time points the time of the event with a tolerance of libroadrunner which the first integration of a process fixes, see [`model.roottol`](api/model.roottol.md): load a model with sbmlsim before integrating with roadrunner directly, otherwise sbmlsim warns once, and a run lacks the steps of the integrator right after an event which a run with workers has |
|
|
@@ -153,7 +153,7 @@ simulator = Simulator(absolute_tolerance=1e-10, relative_tolerance=1e-10)
|
|
|
153
153
|
simulator.set_integrator_settings(stiff=True)
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
The absolute tolerance of CVODE is one value per state, which sbmlsim sets from the kind of the state. The tolerances are plain numbers in the units of the model, so they work for a model without units. A species with `hasOnlySubstanceUnits=true` is an `amount`, its tolerance is the one of the amounts. Any other species is a `concentration`: CVODE integrates its amount, so its tolerance is the one of the concentrations times the reference volume of its compartment. The reference volume is the initial volume, raised to `1e-6` times the largest initial volume of the model when it is smaller, not finite or not positive, which is logged once per model. Every other state, i.e. a parameter or a compartment with a rate rule, is `other`. A float is the same tolerance for every kind, an `AbsoluteTolerance` gives one per kind and overrides single states by their id; an override is the tolerance of the integrated value, i.e. the amount of a concentration species. The default is `1e-10` for every kind. `tolerances()` of the model lists the tolerance of every state:
|
|
156
|
+
The absolute tolerance of CVODE is one value per state, which sbmlsim sets from the kind of the state. The tolerances are plain numbers in the units of the model, so they work for a model without units. A species with `hasOnlySubstanceUnits=true` is an `amount`, its tolerance is the one of the amounts. Any other species is a `concentration`: CVODE integrates its amount, so its tolerance is the one of the concentrations times the reference volume of its compartment. The reference volume is the initial volume of the model as loaded, raised to `1e-6` times the largest initial volume of the model when it is smaller, not finite or not positive, which is logged once per model; a volume which the pre-initialization of a simulation changes, e.g. through a body weight, does not change the tolerances, so a simulation does not depend on the one which ran before it on the same model and a pool gives the serial result. Every other state, i.e. a parameter or a compartment with a rate rule, is `other`. A float is the same tolerance for every kind, an `AbsoluteTolerance` gives one per kind and overrides single states by their id; an override is the tolerance of the integrated value, i.e. the amount of a concentration species. The default is `1e-10` for every kind. `tolerances()` of the model lists the tolerance of every state:
|
|
157
157
|
|
|
158
158
|
```python
|
|
159
159
|
from sbmlsim.model.tolerances import AbsoluteTolerance
|
|
@@ -6,7 +6,7 @@ The [SBML Test Suite](https://github.com/sbmlteam/sbml-test-suite) is the confor
|
|
|
6
6
|
|
|
7
7
|
## What is run
|
|
8
8
|
|
|
9
|
-
The semantic cases which are timecourse simulations,
|
|
9
|
+
The semantic cases which are timecourse simulations, in the newest SBML encoding it provides:
|
|
10
10
|
|
|
11
11
|
- the **stochastic** cases need many replicates and a comparison of distributions, and the **flux balance** cases need a steady state rather than a simulation, so neither is run,
|
|
12
12
|
- the other encodings of a case, i.e. the same model as SBML L1V2 through L3V2, test the reader and not the simulation; reading is covered by [sbmlutils](https://github.com/matthiaskoenig/sbmlutils),
|
|
@@ -20,7 +20,9 @@ A case passes when every point of every compared variable is within the toleranc
|
|
|
20
20
|
|
|
21
21
|
with the expected value `c` and the simulated value `u`. The integration itself runs an order of magnitude tighter than the tolerances a case compares with: integrating no more accurately than the comparison demands is how a suite runner passes cases it should not.
|
|
22
22
|
|
|
23
|
-
A case which
|
|
23
|
+
A case which passes is simulated again on its loaded model, as every point of a scan after the first of its chunk and every simulation of an experiment after the first are, and each of these simulations must equal the first, bitwise (the repeat check, #305): (1) the same simulation again; (2) a simulation of half the duration, then the simulation of the case, which integrates beyond it, so a model with an event with a delay is generated again to discard the pending events of the shorter one; (3) the simulation with a steady state before it, which integrates without end, compared with that simulation of a fresh model (the steady state for at most the duration of the case; both may fail to reach it, then with the same error). libroadrunner executes simultaneous events of the same priority in a random order drawn with `std::rand` of the C library, whose state belongs to the process, so the runner seeds that generator before every simulation of a case (`seed_event_order`): without it the 13 cases with such events (e.g. 00952, 01588) differ in the last bits between the first and the second simulation, and between processes. A regeneration of a model draws from the generator as well, so in (2) and (3) a case with the test tag `RandomEventExecution` is compared with its expected results and within the tolerances of the case instead: 00952, 00962, 00964, 00965, 00966, 01466, 01590, 01591, 01599, 01605, 01626 and 01627 (01589, 01592 and 01593 are not read). Only 01590 needs it: it has an event with a delay, its model is generated again, and it differs by `7.1e-14`. Over the 1789 timecourse cases of 3.5.0, all 1580 which pass pass the repeat check.
|
|
24
|
+
|
|
25
|
+
A case which does not pass does so in one of five ways, and the report separates them because they say different things: `tolerance` (it was simulated and the results are wrong), `not_read` (the model could not be loaded, e.g. an algebraic rule), `simulation_error` (the integration failed), `missing_variable` (a compared variable was not produced) and `repeat` (the results are right, and a simulation of the loaded model after the first differs from it or fails).
|
|
24
26
|
|
|
25
27
|
## Running it
|
|
26
28
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Release notes for sbmlsim 0.9.3
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
A patch release of fixes: the result of a simulation no longer depends on the simulation which ran before it on the same model, a change fires the events of a model written by sbmlutils with the right values, and a dataset reads the units with a numeric factor which PK-DB writes and converts the range of a row with its values.
|
|
5
|
+
|
|
6
|
+
## Fixes
|
|
7
|
+
|
|
8
|
+
- **A simulation does not depend on the one before it** ([#292](https://github.com/matthiaskoenig/sbmlsim/issues/292), [#295](https://github.com/matthiaskoenig/sbmlsim/pull/295)). The absolute tolerance of a concentration species is the tolerance of a concentration times the volume of its compartment. 0.9.0 to 0.9.2 read the volumes from roadrunner before every run, and roadrunner answers the initial volume of a compartment with an initial assignment or an assignment rule from the current parameters, i.e. from the pre-initialization of the simulation which ran last, e.g. its body weight. A simulation after one of another body weight therefore integrated with other tolerances (relative differences of up to `7e-6` in a model of pkdb_models), and a serial run differed from a run in a pool, whose workers load the model. The tolerances are now computed from the initial volumes of the model as loaded, so the result of a simulation is the same whatever ran before it, serially and in a pool, bitwise; it is the result of the first run on a model in 0.9.2, and the one of 0.8.5 within a simulator (0.8.5 computed the tolerances again at every `set_model`, i.e. at the start of every experiment, from the volumes the experiment before left on a cached model). A model with a compartment of the size `NaN` no longer computes its tolerances again before every run.
|
|
9
|
+
- **A change fires the events of a model written by sbmlutils** ([#293](https://github.com/matthiaskoenig/sbmlsim/issues/293), [#295](https://github.com/matthiaskoenig/sbmlsim/pull/295)). The simulator fires an event whose trigger a change makes true. The math of the event was read with the units of its numbers (`necrosis > 0.5 dimensionless`, `0 mmole`), which is no formula of the simulator, and sbmlutils writes a unit on every number: the event did not fire, without a message for its trigger (also in 0.8.5). The numbers are now read without their units, which do not change their values. A trigger which is still no formula the simulator evaluates, e.g. one with a function definition, is reported with a warning which names the event, once per event and model instance, i.e. once per worker of a pool; assignments and priorities which are no formulas were reported already. The constants `pi`, `exponentiale` and `avogadro` in the math of an event are their values (`avogadro` the one of roadrunner, `6.02214179e23`), they stopped the simulation with an error of roadrunner before.
|
|
10
|
+
- **A dataset reads a unit with a numeric factor** ([#294](https://github.com/matthiaskoenig/sbmlsim/issues/294), [#295](https://github.com/matthiaskoenig/sbmlsim/pull/295)). `DataSet.from_df` refused every unit with a factor (`Unit expression cannot have a scaling factor`), also the units of publications which PK-DB writes by design, e.g. `ml/min/(1.73*m^2)`, `micromol/(0.5*hr)`, `(10*ml)/hr` or `10^9/l`. Such a unit is now read as a number of the values: the numbers of its rows, values, sd, se, min and max, are multiplied by the factor, and a column whose first unit has a factor gets the unit without it, so `8.6` in `micromol/(0.5*hr)` is `17.2` in `micromole/hour` and converts into the units of a model. A unit without a factor is read as before; a factor which is no positive number, or with an offset unit such as `degC`, is an error.
|
|
11
|
+
- **A logarithm to a base in the math of an event** ([#296](https://github.com/matthiaskoenig/sbmlsim/issues/296), [#295](https://github.com/matthiaskoenig/sbmlsim/pull/295)). SBML writes the base of a logarithm first, `log(2, x)`, the formulas of the simulator have it last, so an event which a change fired evaluated `log(2, 8)` as `0.333` instead of `3`, without a message (also in 0.8.5). The base is now the second argument of the formula.
|
|
12
|
+
- **The range of a row is converted with its values** ([#294](https://github.com/matthiaskoenig/sbmlsim/issues/294), [#295](https://github.com/matthiaskoenig/sbmlsim/pull/295)). `DataSet.from_df` converted the values, sd and se of the rows with another unit of a column (since 0.9.0) but not their range, `min` and `max` (or `*_min` and `*_max`), which then did not bracket their values. The rows of a `unit` column are now converted in one pass, all numbers of a row once (`cv` is relative and stays), so `mean`, `value` and `median` get one unit, the unit of the first row with one of them; a table whose first mean and first value had different units gave the two columns different units before.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Release notes for sbmlsim 0.9.4
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
A patch release of fixes: the size of a compartment can be changed with a species of an assignment rule in it, which stopped every scan of the body weight of a model with such a species; a simulation of a loaded model no longer depends on the simulations which ran before it on the model, so a serial run, a pool and two runs give the same result, bitwise (but for the random order of simultaneous events of the same priority, see below): the model starts from its values as loaded and the events at the time 0 fire at 0 on every simulation, which the SBML Test Suite now checks for every case it passes by simulating it again on its loaded model (the same simulation, a simulation after a shorter one and one with a steady state); and the legend of a band has one entry per band, its area in its own colour.
|
|
5
|
+
|
|
6
|
+
## Fixes
|
|
7
|
+
|
|
8
|
+
- **A compartment with a species of an assignment rule in it can be changed** ([#300](https://github.com/matthiaskoenig/sbmlsim/issues/300), [#301](https://github.com/matthiaskoenig/sbmlsim/pull/301)). A compartment keeps the concentrations of its species (PEtab v2): the pre-initialization and a change at a time set the concentration of every concentration species in it again after the compartment, also of a species of an assignment rule, which roadrunner refuses to set (`Could not set value for NON conserved moiety floating species ..., it is defined by an assignment rule`). A change of such a compartment, a scan of it and a scan of a parameter its initial assignment reads, e.g. the body weight, failed (0.8.4 to 0.9.3). A species of an assignment rule now follows its rule; every other species keeps its concentration (a concentration species) or its amount (an amount species) as before. In the HCTZ model of pkdb_models the species `hctz` of the extracellular fluid is such a species in a compartment which follows the body weight, so every sensitivity analysis of the model failed at the reference point of its design.
|
|
9
|
+
- **An initialization which fails does not break the model** ([#300](https://github.com/matthiaskoenig/sbmlsim/issues/300), [#301](https://github.com/matthiaskoenig/sbmlsim/pull/301)). The next initialization of a model which was not simulated restores the values the last one replaced. A value was recorded before it was set, so a value which roadrunner refused to set was restored by every later initialization of the loaded model, which failed on it as well: every later point of a scan on the model failed, also a plain simulation. A value is now recorded once it is replaced.
|
|
10
|
+
- **`parameters_of` leaves out the species of an assignment rule** ([#300](https://github.com/matthiaskoenig/sbmlsim/issues/300), [#301](https://github.com/matthiaskoenig/sbmlsim/pull/301)). `sampling.parameters_of(model, species=True)` listed them, and a design of all parameters and species stopped at the compile of its dimension, since a change cannot set such a species.
|
|
11
|
+
- **One legend entry per band, its area in its colour** ([#302](https://github.com/matthiaskoenig/sbmlsim/issues/302), [#301](https://github.com/matthiaskoenig/sbmlsim/pull/301)). The legend of a band had two entries, its median (or its upper boundary without a median, a thin line) and a grey area of its quantile range, e.g. `0-100 %`, once per panel and range, whatever the colour of the band, so two bands of different colours could not be told apart in the legend. A band now has one entry, its area in its own colour, labelled `<name> (<low>-<high> %)`, e.g. `C (5-95 %)`; a band per point of `over` has an entry per point, `<name>, <point label> (<low>-<high> %)`, and a band with a colour bar one entry of its name in the middle colour of the colour map. matplotlib and plotly draw the same entries; the median has no entry, and its hover in plotly names it `<name> median` ([#304](https://github.com/matthiaskoenig/sbmlsim/pull/304)).
|
|
12
|
+
- **A simulation starts from the model as loaded, also in the last bits** ([#303](https://github.com/matthiaskoenig/sbmlsim/issues/303), [#304](https://github.com/matthiaskoenig/sbmlsim/pull/304)). roadrunner's `resetAll` evaluates the initial values of a model with the parameters current at the reset, i.e. with the values the simulation before set: the amount of a concentration species in a compartment whose initial assignment reads an assignment rule of the body weight missed the amount as loaded in the last bits (`95.2875` instead of `95.28750000000002` after `BW = 70.46`). The first point of a loaded model starts from the model as loaded and every later one from such a reset, so a point of a scan depended on the points of its chunk, and a serial run, a pool and two runs of a pool differed (0.8.4 to 0.9.3): in the sensitivity analysis of the HCTZ model of pkdb_models up to `2.6e-7` between a point of a scan and the point alone, up to `1.63e-5` between two runs of a sampling and in every table of a Sobol analysis. A reset now sets every parameter, compartment and species amount which is not the variable of an assignment rule and differs from the model as loaded back to its value as loaded, which costs microseconds per simulation; the results of a point after another one change in the last bits, the first point of a model and a model whose reset restores it bitwise do not change.
|
|
13
|
+
- **The events at the time 0 fire on every simulation of a loaded model** ([#305](https://github.com/matthiaskoenig/sbmlsim/issues/305), [#306](https://github.com/matthiaskoenig/sbmlsim/pull/306)). roadrunner's reset queues the events which fire at the time 0 at the integration start time of the last `simulate` call, and a simulation of sbmlsim with events ends with an integration of its own at its end: every simulation after the first of a loaded model, i.e. every point of a scan after the first of its chunk, fired such an event with a delay after its end, or not at all (case 01757: `P1(10)` 25, 1.5, 1.5 in three simulations; a scan `[25, 1.5, 1.5]`; since 0.9.0, which integrates the end of a simulation with events in a call of its own, measured on 0.9.3). The integration start times are set to 0 before every reset. roadrunner's reset also keeps the events of the simulation before which are still pending, which fired in a later simulation reaching their time (`P1 = 625` after a simulation which ended at 1): a model with an event with a delay is generated again, which empties the queue, before a simulation which integrates beyond the time the last simulation of the model reached, also after an initialization without a simulation in between, e.g. the references of a design (milliseconds for a small model, tenths of a second for a large one; a scan, whose points end at the same time, regenerates nothing unless it integrates to a steady state). The runner of the SBML Test Suite simulates every case which passes again on its loaded model, as a scan does, and each simulation must equal the first, bitwise (status `repeat` otherwise): the same simulation, the simulation after one of half its duration, which integrates beyond it, and the simulation with a steady state before it (for at most the duration of the case), compared with that of a fresh model; both may fail to reach the steady state, then with the same error. Before these fixes 8 cases failed the same simulation by their events (01120, 01335, 01713, 01754 to 01758) and 14 differed in the last bits, 01000 by its event at t0 and 13 by the random order in which libroadrunner executes simultaneous events of the same priority; that order is drawn with `std::rand` of the C library, whose state belongs to the process, so the runner seeds it before every simulation of a case. A regeneration of a model draws from that generator as well, so a case tagged `RandomEventExecution` is compared within its tolerances after a shorter simulation and with a steady state, which only 01590 needs (`7.1e-14`). With these fixes all 1580 cases which pass also pass the repeat check. A model with simultaneous events of the same priority still depends on the state of that generator outside the runner.
|
|
14
|
+
- **A steady state of a model with a rate rule of a stoichiometry** ([#307](https://github.com/matthiaskoenig/sbmlsim/issues/307), [#306](https://github.com/matthiaskoenig/sbmlsim/pull/306)). A simulation with a steady state before it failed with a `ValueError` of numpy (`operands could not be broadcast together`) for a model with a rate rule of a species reference (0.8.4 to 0.9.3): roadrunner's `getRatesOfChangeNamedArray` has the rate of every state but no name of such a species reference, and the steady state read the states by its names. The rates and the states are now read by the ids of the states of the integrator. Found by the repeat check with a steady state, in 10 cases of the SBML Test Suite (01452, 01453, 01563, 01633, 01727 to 01729, 01736 to 01738).
|