From 61d4f033b070e455fa3a1ee7b2fbfd216b8def2a Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 30 Sep 2024 11:12:53 +0200 Subject: [PATCH] Consolidate scripts and python package (#238) * some functionality from `scripts/` would be useful inside the library * some functionality from the library was replicated in `scripts/` -> consolidate (see also #208), turn separate scripts into entrypoints (currently prefixed with `bmp-` from Benchmark-Models-Petab) * Reduce number of package configuration files * replace isort/flake/... by ruff * Problem feature table accessible through the library (closes #169) * `--help` for the overview table entrypoint * Extend overview table: add objective priors (Closes #232 --- .github/pull_request_template.md | 4 +- .github/workflows/tests.yml | 11 +- .pre-commit-config.yaml | 50 +++- README.md | 70 ++--- scripts/_helpers.py | 20 -- scripts/check_petablint.py | 25 -- scripts/check_sbml_metadata.py | 51 ---- scripts/overview.py | 201 --------------- scripts/requirements.txt | 5 - src/python/benchmark_models_petab/C.py | 2 +- src/python/benchmark_models_petab/__init__.py | 1 + src/python/benchmark_models_petab/base.py | 3 +- .../benchmark_models_petab/check_petablint.py | 26 ++ .../check_sbml_metadata.py | 53 ++++ src/python/benchmark_models_petab/overview.py | 241 ++++++++++++++++++ src/python/build.sh | 3 +- src/python/pyproject.toml | 45 +++- src/python/setup.cfg | 29 --- src/python/setup.py | 5 - 19 files changed, 443 insertions(+), 402 deletions(-) delete mode 100644 scripts/_helpers.py delete mode 100755 scripts/check_petablint.py delete mode 100755 scripts/check_sbml_metadata.py delete mode 100755 scripts/overview.py delete mode 100644 scripts/requirements.txt create mode 100644 src/python/benchmark_models_petab/check_petablint.py create mode 100644 src/python/benchmark_models_petab/check_sbml_metadata.py create mode 100644 src/python/benchmark_models_petab/overview.py delete mode 100644 src/python/setup.cfg delete mode 100644 src/python/setup.py diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1b858e6..d679621 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -15,8 +15,8 @@ - [ ] The model ID and model name attributes in the SBML model file match the problem name ([example](https://github.com/Benchmarking-Initiative/Benchmark-Models-PEtab/blob/3154d27edbfc4eb19b768465945bc81381a7c964/Benchmark-Models/Rahman_MBS2016/model_Rahman_MBS2016.xml#L3)) - [ ] PEtab files - [ ] A "simulated data" measurement table is included, using the nominal parameters - - [ ] A visualization table is included, that can be used with the simulate data to reproduce figures from the original publication + - [ ] A visualization table is included, that can be used with the simulated data to reproduce figures from the original publication - [ ] The PEtab problem is valid (check with e.g. `petablint -vy problem.yaml`) - [ ] The PEtab problem author(s) are assigned to the GitHub issue -- [ ] The README has been updated with `python scripts/overview.py --update` +- [ ] The README has been updated with `bmp-create-overview --update` (requires `pip install -e src/python/bmp` from the repository root) - [ ] The new PEtab problem row in the generated table has the correct reference (and other entries) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 99b2223..c2cff8d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,16 +23,13 @@ jobs: run: | python -m pip install --upgrade pip pip install --upgrade setuptools wheel - pip install -r scripts/requirements.txt + cd src/python && pip install -e . - name: Check with petablint - run: ./check_petablint.py - working-directory: scripts/ + run: bmp-petablint - name: Show overview - run: ./overview.py - working-directory: scripts/ + run: bmp-create-overview - name: Check SBML metadata - run: ./check_sbml_metadata.py - working-directory: scripts/ + run: bmp-check-sbml-metadata diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 018151f..bc7c9c2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,18 +1,40 @@ files: src/python repos: -- repo: https://github.com/psf/black - rev: 23.7.0 +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 hooks: - - id: black - description: The uncompromising code formatter -- repo: https://github.com/pycqa/isort - rev: 5.12.0 + - id: check-yaml + description: Check yaml files for parseable syntax + - id: check-added-large-files + description: Prevent large files from being committed + - id: check-merge-conflict + description: Check for files that contain merge conflict strings + - id: check-symlinks + description: Check for symlinks which do not point to anything + - id: check-executables-have-shebangs + description: Check that (non-binary) executables have shebangs + - id: detect-private-key + description: Detects the presence of private keys + - id: end-of-file-fixer + description: Fix empty lines at ends of files + - id: mixed-line-ending + description: Replace or check mixed line endings + - id: trailing-whitespace + description: Trim trailing whitespaces + +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.6.7 hooks: - - id: isort - name: isort -- repo: https://github.com/pycqa/flake8 - rev: 6.0.0 - hooks: - - id: flake8 - args: [--config, src/python/setup.cfg] - additional_dependencies: [flake8-docstrings] + # Run the linter. + - id: ruff + args: + - --fix + - --config + - src/python/pyproject.toml + + # Run the formatter. + - id: ruff-format + args: + - --config + - src/python/pyproject.toml diff --git a/README.md b/README.md index 590e56d..8676397 100644 --- a/README.md +++ b/README.md @@ -6,41 +6,41 @@ Contributions to the collection are very welcome. Please see [CONTRIBUTING.md](C ## Overview -| PEtab Problem ID | Conditions | Estimated Parameters | Events | Preequilibration | Postequilibration | Measurements | Observables | Noise distribution(s) | Species | References | SBML4Humans | -|:---------------------------------------------------------------------------------------------|-------------:|-----------------------:|---------:|-------------------:|--------------------:|---------------:|--------------:|:------------------------|----------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Alkan_SciSignal2018](Benchmark-Models/Alkan_SciSignal2018/) | 73 | 56 | 0 | 0 | 0 | 1733 | 12 | normal | 36 | [\[1\]](http://identifiers.org/doi/10.1126/scisignal.aat0229) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Alkan_SciSignal2018/model_Alkan_SciSignal2018.xml) | -| [Bachmann_MSB2011](Benchmark-Models/Bachmann_MSB2011/) | 36 | 113 | 0 | 0 | 0 | 541 | 20 | normal; log10-normal | 25 | [\[1\]](http://identifiers.org/doi/10.1038/msb.2011.50) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Bachmann_MSB2011/model_Bachmann_MSB2011.xml) | -| [Beer_MolBioSystems2014](Benchmark-Models/Beer_MolBioSystems2014/) | 19 | 72 | 0 | 0 | 0 | 27132 | 2 | normal | 4 | [\[1\]](http://identifiers.org/doi/10.1039/c3mb70594c) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Beer_MolBioSystems2014/model_Beer_MolBioSystems2014.xml) | -| [Bertozzi_PNAS2020](Benchmark-Models/Bertozzi_PNAS2020/) | 2 | 8 | 0 | 0 | 0 | 22 | 2 | normal | 3 | [\[1\]](http://identifiers.org/doi/10.1073/pnas.2006520117) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Bertozzi_PNAS2020/model.xml) | -| [Blasi_CellSystems2016](Benchmark-Models/Blasi_CellSystems2016/) | 1 | 9 | 0 | 0 | 1 | 252 | 15 | log-normal | 16 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2016.01.002) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Blasi_CellSystems2016/model_Blasi_CellSystems2016.xml) | -| [Boehm_JProteomeRes2014](Benchmark-Models/Boehm_JProteomeRes2014/) | 1 | 9 | 0 | 0 | 0 | 48 | 3 | normal | 8 | [\[1\]](http://identifiers.org/doi/10.1021/pr5006923) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Boehm_JProteomeRes2014/model_Boehm_JProteomeRes2014.xml) | -| [Borghans_BiophysChem1997](Benchmark-Models/Borghans_BiophysChem1997/) | 1 | 23 | 0 | 0 | 0 | 111 | 1 | log10-normal | 3 | [\[1\]](http://identifiers.org/doi/10.1016/s0301-4622(97)00010-0) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Borghans_BiophysChem1997/model_Borghans_BiophysChem1997.xml) | -| [Brannmark_JBC2010](Benchmark-Models/Brannmark_JBC2010/) | 8 | 22 | 0 | 1 | 0 | 43 | 3 | normal | 9 | [\[1\]](http://identifiers.org/doi/10.1074/jbc.M110.106849) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Brannmark_JBC2010/model_Brannmark_JBC2010.xml) | -| [Bruno_JExpBot2016](Benchmark-Models/Bruno_JExpBot2016/) | 6 | 13 | 0 | 0 | 0 | 77 | 5 | normal | 7 | [\[1\]](http://identifiers.org/doi/10.1093/jxb/erw356) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Bruno_JExpBot2016/model_Bruno_JExpBot2016.xml) | -| [Chen_MSB2009](Benchmark-Models/Chen_MSB2009/) | 4 | 155 | 0 | 0 | 0 | 120 | 3 | normal | 500 | [\[1\]](http://identifiers.org/doi/10.1038/msb.2008.74) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Chen_MSB2009/model_Chen_MSB2009.xml) | -| [Crauste_CellSystems2017](Benchmark-Models/Crauste_CellSystems2017/) | 1 | 12 | 0 | 0 | 0 | 21 | 4 | normal | 5 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2017.01.014) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Crauste_CellSystems2017/model_Crauste_CellSystems2017.xml) | -| [Elowitz_Nature2000](Benchmark-Models/Elowitz_Nature2000/) | 1 | 21 | 0 | 0 | 0 | 58 | 1 | log10-normal | 8 | [\[1\]](http://identifiers.org/doi/10.1038/35002125) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Elowitz_Nature2000/model_Elowitz_Nature2000.xml) | -| [Fiedler_BMC2016](Benchmark-Models/Fiedler_BMC2016/) | 3 | 22 | 0 | 0 | 0 | 72 | 2 | normal | 6 | [\[1\]](http://identifiers.org/doi/10.1186/s12918-016-0319-7) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Fiedler_BMC2016/model_Fiedler_BMC2016.xml) | -| [Froehlich_CellSystems2018](Benchmark-Models/Froehlich_CellSystems2018/) | 9169 | 4231 | 0 | 0 | 9169 | 9169 | 1 | normal | 1396 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2018.10.013) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Froehlich_CellSystems2018/model_Froehlich_CellSystems2018.xml) | -| [Fujita_SciSignal2010](Benchmark-Models/Fujita_SciSignal2010/) | 6 | 19 | 0 | 0 | 0 | 144 | 3 | normal | 9 | [\[1\]](http://identifiers.org/doi/10.1126/scisignal.2000810) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Fujita_SciSignal2010/model_Fujita_SciSignal2010.xml) | -| [Giordano_Nature2020](Benchmark-Models/Giordano_Nature2020/) | 1 | 50 | 0 | 0 | 0 | 313 | 7 | normal | 13 | [\[1\]](http://identifiers.org/pubmed/32322102) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Giordano_Nature2020/Giordano_Nature2020_model.xml) | -| [Isensee_JCB2018](Benchmark-Models/Isensee_JCB2018/) | 123 | 46 | 0 | 1 | 0 | 687 | 3 | normal | 25 | [\[1\]](http://identifiers.org/doi/10.1083/jcb.201708053) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Isensee_JCB2018/model_Isensee_JCB2018.xml) | -| [Lang_PLOSComputBiol2024](Benchmark-Models/Lang_PLOSComputBiol2024/) | 1 | 294 | 0 | 0 | 0 | 9600 | 16 | normal | 124 | [\[1\]](http://identifiers.org/doi/10.1371/journal.pcbi.1011151) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Lang_PLOSComputBiol2024/model_Lang_PLOSComputBiol2024.xml) | -| [Laske_PLOSComputBiol2019](Benchmark-Models/Laske_PLOSComputBiol2019/) | 3 | 13 | 0 | 0 | 0 | 42 | 13 | normal; log-normal | 41 | [\[1\]](http://identifiers.org/biomodels.db/BIOMD0000000463) [\[2\]](http://identifiers.org/biomodels.db/MODEL1307270000) [\[3\]](http://identifiers.org/doi/10.1371/journal.pcbi.1006944) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Laske_PLOSComputBiol2019/model_Laske_PLOSComputBiol2019.xml) | -| [Lucarelli_CellSystems2018](Benchmark-Models/Lucarelli_CellSystems2018/) | 16 | 84 | 0 | 0 | 0 | 1755 | 65 | normal; log10-normal | 33 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2017.11.010) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Lucarelli_CellSystems2018/model_Lucarelli_CellSystems2018.xml) | -| [Okuonghae_ChaosSolitonsFractals2020](Benchmark-Models/Okuonghae_ChaosSolitonsFractals2020/) | 1 | 16 | 0 | 0 | 0 | 92 | 2 | normal | 9 | [\[1\]](http://identifiers.org/doi/10.1016/j.chaos.2020.110032) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Okuonghae_ChaosSolitonsFractals2020/Okuonghae_ChaosSolitonsFractals2020_model.xml) | -| [Oliveira_NatCommun2021](Benchmark-Models/Oliveira_NatCommun2021/) | 1 | 12 | 0 | 0 | 0 | 120 | 2 | normal | 9 | [\[1\]](http://identifiers.org/doi/10.1038/s41467-020-19798-3) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Oliveira_NatCommun2021/Oliveira_NatCommun2021_model.xml) | -| [Perelson_Science1996](Benchmark-Models/Perelson_Science1996/) | 1 | 3 | 0 | 0 | 0 | 16 | 1 | log10-normal | 4 | [\[1\]](http://identifiers.org/doi/10.1126/science.271.5255.1582) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Perelson_Science1996/model_Perelson_Science1996.xml) | -| [Rahman_MBS2016](Benchmark-Models/Rahman_MBS2016/) | 1 | 9 | 0 | 0 | 0 | 23 | 1 | normal | 7 | [\[1\]](http://identifiers.org/doi/10.1016/j.mbs.2016.07.009) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Rahman_MBS2016/model_Rahman_MBS2016.xml) | -| [Raia_CancerResearch2011](Benchmark-Models/Raia_CancerResearch2011/) | 4 | 39 | 0 | 0 | 0 | 205 | 8 | normal | 14 | [\[1\]](http://identifiers.org/doi/10.1158/0008-5472.CAN-10-2987) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Raia_CancerResearch2011/model_Raia_CancerResearch2011.xml) | -| [Raimundez_PCB2020](Benchmark-Models/Raimundez_PCB2020/) | 170 | 136 | 0 | 4 | 0 | 627 | 79 | normal | 22 | [\[1\]](http://identifiers.org/doi/10.1371/journal.pcbi.1007147) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Raimundez_PCB2020/model_Raimundez_PCB2020.xml) | -| [SalazarCavazos_MBoC2020](Benchmark-Models/SalazarCavazos_MBoC2020/) | 4 | 6 | 0 | 0 | 0 | 18 | 3 | normal | 75 | [\[1\]](http://identifiers.org/doi/10.1091/mbc.E19-09-0548) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/SalazarCavazos_MBoC2020/model_SalazarCavazos_MBoC2020.xml) | -| [Schwen_PONE2014](Benchmark-Models/Schwen_PONE2014/) | 19 | 30 | 0 | 0 | 0 | 286 | 4 | log10-normal | 11 | [\[1\]](http://identifiers.org/doi/10.1371/journal.pone.0133653) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Schwen_PONE2014/model_Schwen_PONE2014.xml) | -| [Smith_BMCSystBiol2013](Benchmark-Models/Smith_BMCSystBiol2013/) | 35 | 25 | 3 | 0 | 0 | 62 | 9 | normal | 133 | [\[1\]](http://identifiers.org/doi/10.1186/1752-0509-7-41) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Smith_BMCSystBiol2013/model_Smith_BMCSystBiol2013.xml) | -| [Sneyd_PNAS2002](Benchmark-Models/Sneyd_PNAS2002/) | 9 | 15 | 0 | 0 | 0 | 135 | 1 | normal | 6 | [\[1\]](http://identifiers.org/doi/10.1073/pnas.032281999) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Sneyd_PNAS2002/model_Sneyd_PNAS2002.xml) | -| [Weber_BMC2015](Benchmark-Models/Weber_BMC2015/) | 2 | 36 | 0 | 1 | 0 | 135 | 8 | normal | 7 | [\[1\]](http://identifiers.org/doi/10.1186/s12918-015-0147-1) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Weber_BMC2015/model_Weber_BMC2015.xml) | -| [Zhao_QuantBiol2020](Benchmark-Models/Zhao_QuantBiol2020/) | 7 | 28 | 0 | 0 | 0 | 82 | 1 | normal | 5 | [\[1\]](http://identifiers.org/pubmed/32219006) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Zhao_QuantBiol2020/SBML_Zhao_QuantBiol2020.xml) | -| [Zheng_PNAS2012](Benchmark-Models/Zheng_PNAS2012/) | 1 | 46 | 0 | 1 | 0 | 60 | 15 | normal | 15 | [\[1\]](http://identifiers.org/doi/10.1073/pnas.1201240109) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Zheng_PNAS2012/model_Zheng_PNAS2012.xml) | +| PEtab Problem ID | Conditions | Estimated Parameters | Events | Preequilibration | Postequilibration | Measurements | Observables | Noise distribution(s) | Objective prior distribution(s) | Species | References | SBML4Humans | +|:---------------------------------------------------------------------------------------------|-------------:|-----------------------:|---------:|-------------------:|--------------------:|---------------:|--------------:|:------------------------|:----------------------------------|----------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Alkan_SciSignal2018](Benchmark-Models/Alkan_SciSignal2018/) | 73 | 56 | 0 | 0 | 0 | 1733 | 12 | normal | | 36 | [\[1\]](http://identifiers.org/doi/10.1126/scisignal.aat0229) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Alkan_SciSignal2018/model_Alkan_SciSignal2018.xml) | +| [Bachmann_MSB2011](Benchmark-Models/Bachmann_MSB2011/) | 36 | 113 | 0 | 0 | 0 | 541 | 20 | normal; log10-normal | parameterScaleNormal | 25 | [\[1\]](http://identifiers.org/doi/10.1038/msb.2011.50) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Bachmann_MSB2011/model_Bachmann_MSB2011.xml) | +| [Beer_MolBioSystems2014](Benchmark-Models/Beer_MolBioSystems2014/) | 19 | 72 | 0 | 0 | 0 | 27132 | 2 | normal | | 4 | [\[1\]](http://identifiers.org/doi/10.1039/c3mb70594c) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Beer_MolBioSystems2014/model_Beer_MolBioSystems2014.xml) | +| [Bertozzi_PNAS2020](Benchmark-Models/Bertozzi_PNAS2020/) | 2 | 8 | 0 | 0 | 0 | 22 | 2 | normal | | 3 | [\[1\]](http://identifiers.org/doi/10.1073/pnas.2006520117) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Bertozzi_PNAS2020/model.xml) | +| [Blasi_CellSystems2016](Benchmark-Models/Blasi_CellSystems2016/) | 1 | 9 | 0 | 0 | 1 | 252 | 15 | log-normal | | 16 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2016.01.002) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Blasi_CellSystems2016/model_Blasi_CellSystems2016.xml) | +| [Boehm_JProteomeRes2014](Benchmark-Models/Boehm_JProteomeRes2014/) | 1 | 9 | 0 | 0 | 0 | 48 | 3 | normal | | 8 | [\[1\]](http://identifiers.org/doi/10.1021/pr5006923) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Boehm_JProteomeRes2014/model_Boehm_JProteomeRes2014.xml) | +| [Borghans_BiophysChem1997](Benchmark-Models/Borghans_BiophysChem1997/) | 1 | 23 | 0 | 0 | 0 | 111 | 1 | log10-normal | | 3 | [\[1\]](http://identifiers.org/doi/10.1016/s0301-4622(97)00010-0) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Borghans_BiophysChem1997/model_Borghans_BiophysChem1997.xml) | +| [Brannmark_JBC2010](Benchmark-Models/Brannmark_JBC2010/) | 8 | 22 | 0 | 1 | 0 | 43 | 3 | normal | | 9 | [\[1\]](http://identifiers.org/doi/10.1074/jbc.M110.106849) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Brannmark_JBC2010/model_Brannmark_JBC2010.xml) | +| [Bruno_JExpBot2016](Benchmark-Models/Bruno_JExpBot2016/) | 6 | 13 | 0 | 0 | 0 | 77 | 5 | normal | | 7 | [\[1\]](http://identifiers.org/doi/10.1093/jxb/erw356) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Bruno_JExpBot2016/model_Bruno_JExpBot2016.xml) | +| [Chen_MSB2009](Benchmark-Models/Chen_MSB2009/) | 4 | 155 | 0 | 0 | 0 | 120 | 3 | normal | | 500 | [\[1\]](http://identifiers.org/doi/10.1038/msb.2008.74) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Chen_MSB2009/model_Chen_MSB2009.xml) | +| [Crauste_CellSystems2017](Benchmark-Models/Crauste_CellSystems2017/) | 1 | 12 | 0 | 0 | 0 | 21 | 4 | normal | | 5 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2017.01.014) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Crauste_CellSystems2017/model_Crauste_CellSystems2017.xml) | +| [Elowitz_Nature2000](Benchmark-Models/Elowitz_Nature2000/) | 1 | 21 | 0 | 0 | 0 | 58 | 1 | log10-normal | | 8 | [\[1\]](http://identifiers.org/doi/10.1038/35002125) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Elowitz_Nature2000/model_Elowitz_Nature2000.xml) | +| [Fiedler_BMC2016](Benchmark-Models/Fiedler_BMC2016/) | 3 | 22 | 0 | 0 | 0 | 72 | 2 | normal | | 6 | [\[1\]](http://identifiers.org/doi/10.1186/s12918-016-0319-7) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Fiedler_BMC2016/model_Fiedler_BMC2016.xml) | +| [Froehlich_CellSystems2018](Benchmark-Models/Froehlich_CellSystems2018/) | 9169 | 4231 | 0 | 0 | 9169 | 9169 | 1 | normal | | 1396 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2018.10.013) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Froehlich_CellSystems2018/model_Froehlich_CellSystems2018.xml) | +| [Fujita_SciSignal2010](Benchmark-Models/Fujita_SciSignal2010/) | 6 | 19 | 0 | 0 | 0 | 144 | 3 | normal | | 9 | [\[1\]](http://identifiers.org/doi/10.1126/scisignal.2000810) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Fujita_SciSignal2010/model_Fujita_SciSignal2010.xml) | +| [Giordano_Nature2020](Benchmark-Models/Giordano_Nature2020/) | 1 | 50 | 0 | 0 | 0 | 313 | 7 | normal | | 13 | [\[1\]](http://identifiers.org/pubmed/32322102) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Giordano_Nature2020/Giordano_Nature2020_model.xml) | +| [Isensee_JCB2018](Benchmark-Models/Isensee_JCB2018/) | 123 | 46 | 0 | 1 | 0 | 687 | 3 | normal | parameterScaleNormal | 25 | [\[1\]](http://identifiers.org/doi/10.1083/jcb.201708053) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Isensee_JCB2018/model_Isensee_JCB2018.xml) | +| [Lang_PLOSComputBiol2024](Benchmark-Models/Lang_PLOSComputBiol2024/) | 1 | 294 | 0 | 0 | 0 | 9600 | 16 | normal | laplace; uniform | 124 | [\[1\]](http://identifiers.org/doi/10.1371/journal.pcbi.1011151) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Lang_PLOSComputBiol2024/model_Lang_PLOSComputBiol2024.xml) | +| [Laske_PLOSComputBiol2019](Benchmark-Models/Laske_PLOSComputBiol2019/) | 3 | 13 | 0 | 0 | 0 | 42 | 13 | normal; log-normal | | 41 | [\[1\]](http://identifiers.org/biomodels.db/BIOMD0000000463) [\[2\]](http://identifiers.org/biomodels.db/MODEL1307270000) [\[3\]](http://identifiers.org/doi/10.1371/journal.pcbi.1006944) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Laske_PLOSComputBiol2019/model_Laske_PLOSComputBiol2019.xml) | +| [Lucarelli_CellSystems2018](Benchmark-Models/Lucarelli_CellSystems2018/) | 16 | 84 | 0 | 0 | 0 | 1755 | 65 | normal; log10-normal | | 33 | [\[1\]](http://identifiers.org/doi/10.1016/j.cels.2017.11.010) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Lucarelli_CellSystems2018/model_Lucarelli_CellSystems2018.xml) | +| [Okuonghae_ChaosSolitonsFractals2020](Benchmark-Models/Okuonghae_ChaosSolitonsFractals2020/) | 1 | 16 | 0 | 0 | 0 | 92 | 2 | normal | | 9 | [\[1\]](http://identifiers.org/doi/10.1016/j.chaos.2020.110032) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Okuonghae_ChaosSolitonsFractals2020/Okuonghae_ChaosSolitonsFractals2020_model.xml) | +| [Oliveira_NatCommun2021](Benchmark-Models/Oliveira_NatCommun2021/) | 1 | 12 | 0 | 0 | 0 | 120 | 2 | normal | | 9 | [\[1\]](http://identifiers.org/doi/10.1038/s41467-020-19798-3) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Oliveira_NatCommun2021/Oliveira_NatCommun2021_model.xml) | +| [Perelson_Science1996](Benchmark-Models/Perelson_Science1996/) | 1 | 3 | 0 | 0 | 0 | 16 | 1 | log10-normal | | 4 | [\[1\]](http://identifiers.org/doi/10.1126/science.271.5255.1582) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Perelson_Science1996/model_Perelson_Science1996.xml) | +| [Rahman_MBS2016](Benchmark-Models/Rahman_MBS2016/) | 1 | 9 | 0 | 0 | 0 | 23 | 1 | normal | | 7 | [\[1\]](http://identifiers.org/doi/10.1016/j.mbs.2016.07.009) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Rahman_MBS2016/model_Rahman_MBS2016.xml) | +| [Raia_CancerResearch2011](Benchmark-Models/Raia_CancerResearch2011/) | 4 | 39 | 0 | 0 | 0 | 205 | 8 | normal | | 14 | [\[1\]](http://identifiers.org/doi/10.1158/0008-5472.CAN-10-2987) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Raia_CancerResearch2011/model_Raia_CancerResearch2011.xml) | +| [Raimundez_PCB2020](Benchmark-Models/Raimundez_PCB2020/) | 170 | 136 | 0 | 4 | 0 | 627 | 79 | normal | parameterScaleNormal; laplace | 22 | [\[1\]](http://identifiers.org/doi/10.1371/journal.pcbi.1007147) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Raimundez_PCB2020/model_Raimundez_PCB2020.xml) | +| [SalazarCavazos_MBoC2020](Benchmark-Models/SalazarCavazos_MBoC2020/) | 4 | 6 | 0 | 0 | 0 | 18 | 3 | normal | | 75 | [\[1\]](http://identifiers.org/doi/10.1091/mbc.E19-09-0548) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/SalazarCavazos_MBoC2020/model_SalazarCavazos_MBoC2020.xml) | +| [Schwen_PONE2014](Benchmark-Models/Schwen_PONE2014/) | 19 | 30 | 0 | 0 | 0 | 286 | 4 | log10-normal | parameterScaleNormal | 11 | [\[1\]](http://identifiers.org/doi/10.1371/journal.pone.0133653) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Schwen_PONE2014/model_Schwen_PONE2014.xml) | +| [Smith_BMCSystBiol2013](Benchmark-Models/Smith_BMCSystBiol2013/) | 35 | 25 | 3 | 0 | 0 | 62 | 9 | normal | | 133 | [\[1\]](http://identifiers.org/doi/10.1186/1752-0509-7-41) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Smith_BMCSystBiol2013/model_Smith_BMCSystBiol2013.xml) | +| [Sneyd_PNAS2002](Benchmark-Models/Sneyd_PNAS2002/) | 9 | 15 | 0 | 0 | 0 | 135 | 1 | normal | | 6 | [\[1\]](http://identifiers.org/doi/10.1073/pnas.032281999) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Sneyd_PNAS2002/model_Sneyd_PNAS2002.xml) | +| [Weber_BMC2015](Benchmark-Models/Weber_BMC2015/) | 2 | 36 | 0 | 1 | 0 | 135 | 8 | normal | | 7 | [\[1\]](http://identifiers.org/doi/10.1186/s12918-015-0147-1) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Weber_BMC2015/model_Weber_BMC2015.xml) | +| [Zhao_QuantBiol2020](Benchmark-Models/Zhao_QuantBiol2020/) | 7 | 28 | 0 | 0 | 0 | 82 | 1 | normal | | 5 | [\[1\]](http://identifiers.org/pubmed/32219006) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Zhao_QuantBiol2020/SBML_Zhao_QuantBiol2020.xml) | +| [Zheng_PNAS2012](Benchmark-Models/Zheng_PNAS2012/) | 1 | 46 | 0 | 1 | 0 | 60 | 15 | normal | | 15 | [\[1\]](http://identifiers.org/doi/10.1073/pnas.1201240109) | [\[1\]](https://sbml4humans.de/model_url?url=https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master/Benchmark-Models/Zheng_PNAS2012/model_Zheng_PNAS2012.xml) | ## License diff --git a/scripts/_helpers.py b/scripts/_helpers.py deleted file mode 100644 index 6a472fc..0000000 --- a/scripts/_helpers.py +++ /dev/null @@ -1,20 +0,0 @@ -from pathlib import Path - - -benchmark_path = Path(__file__).resolve().parent.parent / 'Benchmark-Models' -petab_yamls = { - petab_path.name: benchmark_path / petab_path.name / (petab_path.name + '.yaml') - for petab_path in benchmark_path.glob('*') - if petab_path.name != '.DS_Store' -} -petab_yamls = {k: petab_yamls[k] for k in sorted(petab_yamls)} - -for problem_id, petab_yaml in petab_yamls.items(): - if not petab_yaml.exists(): - petab_yamls[problem_id] = petab_yaml.parent / "problem.yaml" - if not petab_yamls[problem_id].exists(): - raise FileNotFoundError( - f"Could not find the YAML for problem `{problem_id}`." - ) - -readme_md = Path(__file__).resolve().parent.parent / "README.md" diff --git a/scripts/check_petablint.py b/scripts/check_petablint.py deleted file mode 100755 index eeda3bc..0000000 --- a/scripts/check_petablint.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 - -from pathlib import Path -import os -import sys - -from _helpers import petab_yamls - - -num_failures = 0 - -for petab_problem_id, petab_yaml in petab_yamls.items(): - print(petab_problem_id) - ret = os.system(f"petablint -v {petab_yaml}") - print('='*100) # just for output readability - - if ret: - num_failures += 1 - -num_passed = len(petab_yamls) - num_failures -print(f'Result: {Path(__file__).stem}') -print(f"{num_passed} out of {len(petab_yamls)} passed.") -print(f"{num_failures} out of {len(petab_yamls)} failed.") -# Fail unless all models passed -sys.exit(num_failures) diff --git a/scripts/check_sbml_metadata.py b/scripts/check_sbml_metadata.py deleted file mode 100755 index 72d4391..0000000 --- a/scripts/check_sbml_metadata.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -from pathlib import Path -import sys - -import petab.v1 as petab - -from overview import get_reference_uris -from _helpers import petab_yamls - - -num_failures = 0 - -for petab_problem_id, petab_yaml in petab_yamls.items(): - petab_problem = petab.Problem.from_yaml(petab_yaml) - - model_id = petab_problem.sbml_model.getId() - model_name = petab_problem.sbml_model.getName() - reference_uris = get_reference_uris(sbml_model=petab_problem.sbml_model) - - errors = [] - - if model_id != petab_problem_id: - errors.append( - 'Please change the model ID to match the problem ID.' - ) - - if model_name != petab_problem_id: - errors.append( - 'Please change the model name to match the problem ID.' - ) - - if not reference_uris: - errors.append( - 'Please add relevant references (e.g. the paper) to the model.' - ) - - errors = ['\t' + error for error in errors] - - print(petab_problem_id) - if errors: - print('\n'.join(errors)) - num_failures += 1 - print('='*100) # just for output readability - -num_passed = len(petab_yamls) - num_failures -print(f'Result: {Path(__file__).stem}') -print(f"{num_passed} out of {len(petab_yamls)} passed.") -print(f"{num_failures} out of {len(petab_yamls)} failed.") -# Fail unless all models passed -sys.exit(num_failures) diff --git a/scripts/overview.py b/scripts/overview.py deleted file mode 100755 index 3b06b1c..0000000 --- a/scripts/overview.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python3 -"""Print some stats for each benchmark PEtab problem""" - -import os -from typing import Dict, List - -import libsbml -import numpy as np -import pandas as pd -import petab.v1 as petab - -from _helpers import petab_yamls, readme_md - - -markdown_columns = { - 'conditions': 'Conditions', - 'estimated_parameters': 'Estimated Parameters', - 'events': 'Events', - 'preequilibration': 'Preequilibration', - 'postequilibration': 'Postequilibration', - 'measurements': 'Measurements', - 'petab_problem_id': 'PEtab Problem ID', - 'observables': 'Observables', - 'species': 'Species', - 'noise_distributions': 'Noise distribution(s)', - 'reference_uris': 'References', - 'sbml4humans_urls': 'SBML4Humans', -} - -index_column = 'petab_problem_id' - - -def get_summary( - petab_problem: petab.Problem, - petab_problem_id: str = None, -) -> Dict: - """Get dictionary with stats for the given PEtab problem""" - print(petab_problem_id) - return { - 'petab_problem_id': - petab_problem_id, - 'conditions': - petab_problem.get_simulation_conditions_from_measurement_df().shape[0], - 'estimated_parameters': - np.sum(petab_problem.parameter_df[petab.ESTIMATE]), - 'events': - len(petab_problem.sbml_model.getListOfEvents()), - 'preequilibration': - 0 if petab.PREEQUILIBRATION_CONDITION_ID not in - petab_problem.measurement_df.columns or - pd.isnull(petab_problem.measurement_df[ - petab.PREEQUILIBRATION_CONDITION_ID]).all() - else (pd.isnull(petab_problem.measurement_df[ - petab.PREEQUILIBRATION_CONDITION_ID].unique()) == False - ).sum(), - 'postequilibration': - petab.measurements.get_simulation_conditions( - petab_problem.measurement_df[ - petab_problem.measurement_df[petab.TIME] == np.inf]).shape[ - 0] if - np.isinf(petab_problem.measurement_df[petab.TIME]).any() - else 0, - 'measurements': - len(petab_problem.measurement_df.index), - 'observables': - len(petab_problem.measurement_df[petab.OBSERVABLE_ID].unique()), - 'noise_distributions': - get_noise_distributions(petab_problem.observable_df), - 'species': - len(petab_problem.sbml_model.getListOfSpecies()), - 'reference_uris': - get_reference_uris(petab_problem.sbml_model), - 'sbml4humans_urls': - get_sbml4humans_urls(petab_problem_id), - } - - -def get_reference_uris(sbml_model: libsbml.Model) -> List[str]: - """Get publication URIs from SBML is-described-by annotation""" - cv_terms = sbml_model.getCVTerms() - reference_uris = [] - for anno in cv_terms: - if anno.getBiologicalQualifierType() != libsbml.BQB_IS_DESCRIBED_BY: - continue - resources = anno.getResources() - for i in range(resources.getNumAttributes()): - uri = resources.getValue(i) - reference_uris.append(uri) - return reference_uris - - -def get_sbml4humans_urls(petab_problem_id: str) -> List[str]: - """Get URL to SBML4humans model""" - from petab.yaml import load_yaml - yaml_file = petab_yamls[petab_problem_id] - yaml_dict = load_yaml(yaml_file) - repo_root = "https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master" - urls = [] - for problem_dict in yaml_dict[petab.PROBLEMS]: - for model_filename in problem_dict[petab.SBML_FILES]: - gh_raw_url = f"{repo_root}/Benchmark-Models/{petab_problem_id}/{model_filename}" - urls.append(f"https://sbml4humans.de/model_url?url={gh_raw_url}") - return urls - - -def get_noise_distributions(observable_df): - - if petab.NOISE_DISTRIBUTION in observable_df.columns: - observable_df = observable_df.fillna( - value={petab.NOISE_DISTRIBUTION: petab.NORMAL}) - if petab.OBSERVABLE_TRANSFORMATION in observable_df.columns: - observable_df = observable_df.fillna( - value={petab.OBSERVABLE_TRANSFORMATION: petab.LIN}) - noise_distrs = [tuple(e.values) for _, e in observable_df[ - [petab.OBSERVABLE_TRANSFORMATION, - petab.NOISE_DISTRIBUTION]].iterrows()] - else: - noise_distrs = [(petab.LIN, e) for e in - observable_df[petab.NOISE_DISTRIBUTION]] - - else: - if petab.OBSERVABLE_TRANSFORMATION in observable_df.columns: - observable_df = observable_df.fillna( - value={petab.OBSERVABLE_TRANSFORMATION: petab.LIN}) - noise_distrs = [(e, petab.NORMAL) for e in - observable_df[petab.OBSERVABLE_TRANSFORMATION]] - else: - noise_distrs = {(petab.LIN, petab.NORMAL)} - - noise_distrs = sorted(set(noise_distrs)) - noise_distrs = ['-'.join(nd) if nd[0] != petab.LIN else - nd[1] for nd in noise_distrs] - return "; ".join(noise_distrs) - - -def get_overview_table() -> pd.DataFrame: - """Get overview table with stats for all benchmark PEtab problems""" - data = [] - for petab_problem_id, petab_yaml in petab_yamls.items(): - petab_problem = petab.Problem.from_yaml(petab_yaml) - summary = get_summary(petab_problem, petab_problem_id) - data.append(summary) - df = pd.DataFrame(data) - df.set_index([index_column], inplace=True) - return df - - -start_overview_table = '\n\n' -end_overview_table = '\n\n' - -def main( - markdown: bool = False, - update_readme: bool = False, -): - df = get_overview_table() - pd.options.display.width = 0 - - if markdown: - # directory as markdown link - df.rename(index=lambda x: f"[{x}](Benchmark-Models/{x}/)", - inplace=True) - # references to markdown links - for field in 'reference_uris', 'sbml4humans_urls': - df[field] = df[field].apply( - lambda x: " ".join([f"[\\[{i + 1}\\]]({uri})" - for i, uri in enumerate(x)]) - ) - df.index.rename(markdown_columns[index_column], inplace=True) - df.rename(columns=markdown_columns, inplace=True) - markdown_overview = df.to_markdown() - if update_readme: - with open(readme_md, "r") as f: - readme_content = f.read() - before_table = readme_content.split(start_overview_table)[0] - after_table = readme_content.split(end_overview_table)[1] - new_readme_content = ( - before_table - + start_overview_table - + markdown_overview - + end_overview_table - + after_table - ) - with open(readme_md, "w") as f: - f.write(new_readme_content) - else: - print(markdown_overview) - else: - print(df) - - -if __name__ == '__main__': - import sys - - markdown = False - update_readme = False - if '--markdown' in sys.argv: - markdown = True - if '--update' in sys.argv: - markdown = True - update_readme = True - main(markdown=markdown, update_readme=update_readme) diff --git a/scripts/requirements.txt b/scripts/requirements.txt deleted file mode 100644 index 2e904ea..0000000 --- a/scripts/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -numpy -pandas -petab>=0.2.3 -python-libsbml -tabulate diff --git a/src/python/benchmark_models_petab/C.py b/src/python/benchmark_models_petab/C.py index f1c336e..0f7bb6e 100644 --- a/src/python/benchmark_models_petab/C.py +++ b/src/python/benchmark_models_petab/C.py @@ -6,5 +6,5 @@ BASE_DIR: str = os.path.abspath(os.path.dirname(__file__)) MODELS_DIR: str = os.path.join(BASE_DIR, "Benchmark-Models") -MODELS: List[str] = os.listdir(MODELS_DIR) +MODELS: List[str] = sorted(os.listdir(MODELS_DIR)) MODEL_DIRS: List[str] = [os.path.join(MODELS_DIR, d) for d in MODELS] diff --git a/src/python/benchmark_models_petab/__init__.py b/src/python/benchmark_models_petab/__init__.py index 6de427e..6bf4828 100644 --- a/src/python/benchmark_models_petab/__init__.py +++ b/src/python/benchmark_models_petab/__init__.py @@ -7,3 +7,4 @@ from .base import get_problem, get_problem_yaml_path from .C import MODEL_DIRS, MODELS, MODELS_DIR from .version import __version__ +from .overview import get_overview_df diff --git a/src/python/benchmark_models_petab/base.py b/src/python/benchmark_models_petab/base.py index 25e6f0d..6550753 100644 --- a/src/python/benchmark_models_petab/base.py +++ b/src/python/benchmark_models_petab/base.py @@ -1,4 +1,5 @@ """Get a petab problem from the collection.""" + from pathlib import Path import petab.v1 as petab @@ -26,7 +27,7 @@ def get_problem_yaml_path(id_: str) -> Path: def get_problem(id_: str) -> petab.Problem: - """Read PEtab problem from benchmark collection by name. + """Read PEtab problem from the benchmark collection by name. Parameters ---------- diff --git a/src/python/benchmark_models_petab/check_petablint.py b/src/python/benchmark_models_petab/check_petablint.py new file mode 100644 index 0000000..6f34346 --- /dev/null +++ b/src/python/benchmark_models_petab/check_petablint.py @@ -0,0 +1,26 @@ +import os +import sys +from pathlib import Path + +from . import MODELS, get_problem_yaml_path + + +def main(): + """Check all PEtab problems with petablint.""" + num_failures = 0 + + for petab_problem_id in MODELS: + print(petab_problem_id) + petab_yaml = get_problem_yaml_path(petab_problem_id) + ret = os.system(f"petablint -v {petab_yaml}") + print("=" * 100) # just for output readability + + if ret: + num_failures += 1 + + num_passed = len(MODELS) - num_failures + print(f"Result: {Path(__file__).stem}") + print(f"{num_passed} out of {len(MODELS)} passed.") + print(f"{num_failures} out of {len(MODELS)} failed.") + # Fail unless all models passed + sys.exit(num_failures) diff --git a/src/python/benchmark_models_petab/check_sbml_metadata.py b/src/python/benchmark_models_petab/check_sbml_metadata.py new file mode 100644 index 0000000..7e46cf0 --- /dev/null +++ b/src/python/benchmark_models_petab/check_sbml_metadata.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +import sys +from pathlib import Path + +from . import MODELS, get_problem +from .overview import get_reference_uris + + +def main(): + """Check SBML metadata for all PEtab problems.""" + num_failures = 0 + + for petab_problem_id in MODELS: + petab_problem = get_problem(petab_problem_id) + + model_id = petab_problem.sbml_model.getId() + model_name = petab_problem.sbml_model.getName() + reference_uris = get_reference_uris( + sbml_model=petab_problem.sbml_model + ) + + errors = [] + + if model_id != petab_problem_id: + errors.append( + "Please change the model ID to match the problem ID." + ) + + if model_name != petab_problem_id: + errors.append( + "Please change the model name to match the problem ID." + ) + + if not reference_uris: + errors.append( + "Please add relevant references (e.g. the paper) to the model." + ) + + errors = ["\t" + error for error in errors] + + print(petab_problem_id) + if errors: + print("\n".join(errors)) + num_failures += 1 + print("=" * 100) # just for output readability + + num_passed = len(MODELS) - num_failures + print(f"Result: {Path(__file__).stem}") + print(f"{num_passed} out of {len(MODELS)} passed.") + print(f"{num_failures} out of {len(MODELS)} failed.") + # Fail unless all models passed + sys.exit(num_failures) diff --git a/src/python/benchmark_models_petab/overview.py b/src/python/benchmark_models_petab/overview.py new file mode 100644 index 0000000..4dfbbd0 --- /dev/null +++ b/src/python/benchmark_models_petab/overview.py @@ -0,0 +1,241 @@ +"""Print some stats for each benchmark PEtab problem""" + +from pathlib import Path +from typing import Dict, List +import argparse + +import libsbml +import numpy as np +import pandas as pd +import petab.v1 as petab +from petab.yaml import load_yaml + +from . import MODELS, get_problem, get_problem_yaml_path + +readme_md = Path(__file__).resolve().parent.parent / "README.md" + +markdown_columns = { + "conditions": "Conditions", + "estimated_parameters": "Estimated Parameters", + "events": "Events", + "preequilibration": "Preequilibration", + "postequilibration": "Postequilibration", + "measurements": "Measurements", + "petab_problem_id": "PEtab Problem ID", + "observables": "Observables", + "species": "Species", + "noise_distributions": "Noise distribution(s)", + "objective_prior_distributions": "Objective prior distribution(s)", + "reference_uris": "References", + "sbml4humans_urls": "SBML4Humans", +} + +index_column = "petab_problem_id" + + +def get_summary( + petab_problem: petab.Problem, + petab_problem_id: str = None, +) -> Dict: + """Get dictionary with stats for the given PEtab problem""" + print(petab_problem_id) + return { + "petab_problem_id": petab_problem_id, + "conditions": petab_problem.get_simulation_conditions_from_measurement_df().shape[ + 0 + ], + "estimated_parameters": np.sum( + petab_problem.parameter_df[petab.ESTIMATE] + ), + "events": len(petab_problem.sbml_model.getListOfEvents()), + "preequilibration": 0 + if petab.PREEQUILIBRATION_CONDITION_ID + not in petab_problem.measurement_df.columns + or pd.isnull( + petab_problem.measurement_df[petab.PREEQUILIBRATION_CONDITION_ID] + ).all() + else ( + ~pd.isnull( + petab_problem.measurement_df[ + petab.PREEQUILIBRATION_CONDITION_ID + ].unique() + ) + ).sum(), + "postequilibration": petab.measurements.get_simulation_conditions( + petab_problem.measurement_df[ + petab_problem.measurement_df[petab.TIME] == np.inf + ] + ).shape[0] + if np.isinf(petab_problem.measurement_df[petab.TIME]).any() + else 0, + "measurements": len(petab_problem.measurement_df.index), + "observables": len( + petab_problem.measurement_df[petab.OBSERVABLE_ID].unique() + ), + "noise_distributions": get_noise_distributions( + petab_problem.observable_df + ), + "objective_prior_distributions": get_prior_distributions( + petab_problem.parameter_df + ), + "species": len(petab_problem.sbml_model.getListOfSpecies()), + "reference_uris": get_reference_uris(petab_problem.sbml_model), + "sbml4humans_urls": get_sbml4humans_urls(petab_problem_id), + } + + +def get_reference_uris(sbml_model: libsbml.Model) -> List[str]: + """Get publication URIs from SBML is-described-by annotation""" + cv_terms = sbml_model.getCVTerms() + reference_uris = [] + for anno in cv_terms: + if anno.getBiologicalQualifierType() != libsbml.BQB_IS_DESCRIBED_BY: + continue + resources = anno.getResources() + for i in range(resources.getNumAttributes()): + uri = resources.getValue(i) + reference_uris.append(uri) + return reference_uris + + +def get_sbml4humans_urls(petab_problem_id: str) -> List[str]: + """Get URL to SBML4humans model""" + yaml_file = get_problem_yaml_path(petab_problem_id) + yaml_dict = load_yaml(yaml_file) + repo_root = "https://raw.githubusercontent.com/Benchmarking-Initiative/Benchmark-Models-PEtab/master" + urls = [] + for problem_dict in yaml_dict[petab.PROBLEMS]: + for model_filename in problem_dict[petab.SBML_FILES]: + gh_raw_url = f"{repo_root}/Benchmark-Models/{petab_problem_id}/{model_filename}" + urls.append(f"https://sbml4humans.de/model_url?url={gh_raw_url}") + return urls + + +def get_noise_distributions(observable_df): + if petab.NOISE_DISTRIBUTION in observable_df.columns: + observable_df = observable_df.fillna( + value={petab.NOISE_DISTRIBUTION: petab.NORMAL} + ) + if petab.OBSERVABLE_TRANSFORMATION in observable_df.columns: + observable_df = observable_df.fillna( + value={petab.OBSERVABLE_TRANSFORMATION: petab.LIN} + ) + noise_distrs = [ + tuple(e.values) + for _, e in observable_df[ + [petab.OBSERVABLE_TRANSFORMATION, petab.NOISE_DISTRIBUTION] + ].iterrows() + ] + else: + noise_distrs = [ + (petab.LIN, e) for e in observable_df[petab.NOISE_DISTRIBUTION] + ] + + else: + if petab.OBSERVABLE_TRANSFORMATION in observable_df.columns: + observable_df = observable_df.fillna( + value={petab.OBSERVABLE_TRANSFORMATION: petab.LIN} + ) + noise_distrs = [ + (e, petab.NORMAL) + for e in observable_df[petab.OBSERVABLE_TRANSFORMATION] + ] + else: + noise_distrs = {(petab.LIN, petab.NORMAL)} + + noise_distrs = sorted(set(noise_distrs)) + noise_distrs = [ + "-".join(nd) if nd[0] != petab.LIN else nd[1] for nd in noise_distrs + ] + return "; ".join(noise_distrs) + + +def get_prior_distributions(parameter_df: pd.DataFrame) -> str: + """Get the list of prior distributions entering the objective function.""" + df = parameter_df.loc[parameter_df[petab.ESTIMATE] == 1] + if ( + petab.OBJECTIVE_PRIOR_TYPE not in df + or df.get(petab.OBJECTIVE_PRIOR_TYPE).isna().all() + or petab.OBJECTIVE_PRIOR_PARAMETERS not in df + or df.get(petab.OBJECTIVE_PRIOR_PARAMETERS).isna().all() + ): + # nothing to do + return "" + unique = map(str, df[petab.OBJECTIVE_PRIOR_TYPE].fillna("").unique()) + return "; ".join(filter(None, unique)) + + +def get_overview_df() -> pd.DataFrame: + """Get overview table with stats for all benchmark PEtab problems""" + data = [] + for petab_problem_id in MODELS: + petab_problem = get_problem(petab_problem_id) + summary = get_summary(petab_problem, petab_problem_id) + data.append(summary) + df = pd.DataFrame(data) + df.set_index([index_column], inplace=True) + return df + + +start_overview_table = "\n\n" +end_overview_table = "\n\n" + + +def show_overview_table( + markdown: bool = False, + update_readme: bool = False, +): + df = get_overview_df() + pd.options.display.width = 0 + + if markdown or update_readme: + # directory as markdown link + df.rename( + index=lambda x: f"[{x}](Benchmark-Models/{x}/)", inplace=True + ) + # references to markdown links + for field in "reference_uris", "sbml4humans_urls": + df[field] = df[field].apply( + lambda x: " ".join( + [f"[\\[{i + 1}\\]]({uri})" for i, uri in enumerate(x)] + ) + ) + df.index.rename(markdown_columns[index_column], inplace=True) + df.rename(columns=markdown_columns, inplace=True) + markdown_overview = df.to_markdown() + if update_readme: + with open(readme_md, "r") as f: + readme_content = f.read() + before_table = readme_content.split(start_overview_table)[0] + after_table = readme_content.split(end_overview_table)[1] + new_readme_content = ( + before_table + + start_overview_table + + markdown_overview + + end_overview_table + + after_table + ) + with open(readme_md, "w") as f: + f.write(new_readme_content) + else: + print(markdown_overview) + else: + print(df) + + +def main(): + parser = argparse.ArgumentParser( + description="Show overview table for benchmark PEtab problems" + ) + parser.add_argument( + "--markdown", action="store_true", help="Output in markdown format" + ) + parser.add_argument( + "--update", + action="store_true", + help="Update the README.md file with the overview table", + ) + + args = parser.parse_args() + + show_overview_table(markdown=args.markdown, update_readme=args.update) diff --git a/src/python/build.sh b/src/python/build.sh index 90cf7ce..dbfe47a 100755 --- a/src/python/build.sh +++ b/src/python/build.sh @@ -1,3 +1,4 @@ +#!/bin/env bash # Build library as source distribution with included model files # Either, call `./build.sh` followed by `pip install build/dist/*` @@ -24,7 +25,7 @@ mkdir $BUILD_DIR # Copy code cp -r \ $CODE_DIR \ - "setup.cfg" "setup.py" "pyproject.toml" "MANIFEST.in" \ + "pyproject.toml" "MANIFEST.in" \ "../../LICENSE" "../../README.md" \ $BUILD_DIR # Remove link diff --git a/src/python/pyproject.toml b/src/python/pyproject.toml index cfc502a..8030d7a 100644 --- a/src/python/pyproject.toml +++ b/src/python/pyproject.toml @@ -2,13 +2,48 @@ requires = [ "setuptools", "wheel", + "petab", ] build-backend = "setuptools.build_meta" -[tool.black] + +[project] +name = "benchmark_models_petab" +description = "A collection of models with experimental data in the PEtab format" +dynamic = ["version"] +readme = { file = "README.md", content-type = "text/markdown" } +requires-python = ">=3.10" +license = { file = "LICENSE" } +maintainers = [ + { name = "Dilan Pathirana"}, + { name = "Maren Philipps"} +] +authors = [ + { name = "The Benchmark-Models-PEtab contributors" } +] +urls = { "Homepage" = "https://github.com/Benchmarking-Initiative/Benchmark-Models-PEtab" } +dependencies = [ + "petab>=0.4.0", + "numpy", + "pandas", + "python-libsbml", + "tabulate", +] + +[project.optional-dependencies] +dev = ["ruff"] + +[tool.setuptools.dynamic] +version = {attr = "benchmark_models_petab.__version__"} + +[project.scripts] +bmp-petablint = "benchmark_models_petab.check_petablint:main" +bmp-check-sbml-metadata = "benchmark_models_petab.check_sbml_metadata:main" +bmp-create-overview = "benchmark_models_petab.overview:main" + +[tool.ruff] line-length = 79 -[tool.isort] -profile = "black" -line_length = 79 -multi_line_output = 3 + +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["F401"] diff --git a/src/python/setup.cfg b/src/python/setup.cfg deleted file mode 100644 index 091bf78..0000000 --- a/src/python/setup.cfg +++ /dev/null @@ -1,29 +0,0 @@ -# Benchmark-Models-PEtab python package.""" - -[metadata] -name = benchmark_models_petab -version = attr: benchmark_models_petab.version.__version__ -description = "A collection of models with experimental data in the PEtab format" -long_description = file: README.md -long_description_content_type = text/markdown -url = "https://github.com/Benchmarking-Initiative/Benchmark-Models-PEtab" - -author = "The Benchmark-Models-PEtab maintainers" -author_email = "yannik.schaelte@gmail.com" - -license = BSD-3-Clause -license_file = LICENSE - -[options] -install_requires = - petab >= 0.4.0 - -python_requires = >= 3.10 -zip_safe = False -include_package_data = True - -packages = find: - -[flake8] -per-file-ignores = - */__init__.py:F401 diff --git a/src/python/setup.py b/src/python/setup.py deleted file mode 100644 index 0e53246..0000000 --- a/src/python/setup.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Setup.py required for editable install.""" - -import setuptools - -setuptools.setup()