py-modelrunner 0.14.0__tar.gz → 0.16.0__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.
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/.github/workflows/build.yml +8 -1
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/PKG-INFO +3 -2
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/requirements.txt +1 -1
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/source/.gitignore +1 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/source/conf.py +17 -10
- py-modelrunner-0.16.0/docs/source/examples.rst +10 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/source/index.rst +4 -2
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/source/installation.rst +1 -1
- py-modelrunner-0.16.0/docs/source/parse_examples.py +65 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/source/run_autodoc.py +1 -1
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/source/sphinx_simplify_typehints.py +1 -1
- py-modelrunner-0.16.0/docs/source/user_manual.rst +53 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/__init__.py +0 -1
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/__main__.py +2 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/_version.py +2 -2
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/compatibility/triage.py +8 -8
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/compatibility/version0.py +5 -5
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/compatibility/version1.py +17 -20
- py-modelrunner-0.16.0/modelrunner/config.py +149 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/model.py +34 -26
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/parameters.py +74 -91
- py-modelrunner-0.16.0/modelrunner/py.typed +1 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/results.py +17 -16
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/run/__main__.py +3 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/run/job.py +103 -32
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/run/templates/background.template +8 -8
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/run/templates/foreground.template +8 -8
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/run/templates/qsub.template +10 -12
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/run/templates/srun.template +10 -12
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/access_modes.py +11 -5
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/attributes.py +2 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/hdf.py +41 -19
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/memory.py +5 -5
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/text_base.py +7 -6
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/utils.py +1 -29
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/zarr.py +7 -8
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/base.py +29 -32
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/group.py +31 -23
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/tools.py +19 -4
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/trajectory.py +32 -22
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/utils.py +17 -27
- py-modelrunner-0.16.0/modelrunner/utils.py +71 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/py_modelrunner.egg-info/PKG-INFO +3 -2
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/py_modelrunner.egg-info/SOURCES.txt +7 -2
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/pyproject.toml +2 -1
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/requirements.txt +1 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/requirements_full.txt +0 -1
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/format_code.sh +5 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/run_tests.py +12 -2
- py-modelrunner-0.16.0/tests/conftest.py +4 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/helpers/storage.py +1 -29
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/requirements.txt +2 -2
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/storage/test_storage_generic.py +46 -3
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/storage/test_storage_special.py +4 -5
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/storage/test_trajectory.py +81 -4
- py-modelrunner-0.16.0/tests/test_config.py +107 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/test_examples.py +2 -3
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/test_model.py +57 -2
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/test_parameters.py +41 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/test_results.py +3 -3
- py-modelrunner-0.14.0/codecov.yml +0 -11
- py-modelrunner-0.14.0/docs/source/structure.rst +0 -61
- py-modelrunner-0.14.0/modelrunner/py.typed +0 -1
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/.github/workflows/check_docs.yml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/.github/workflows/coverage_report.yml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/.github/workflows/release_pip.yml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/.gitignore +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/.readthedocs.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/LICENSE +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/README.md +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/Makefile +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/docs/build_all.sh +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/io_hdf.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/io_json.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/io_yaml.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/model_class.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/model_decorator.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/model_function.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/model_storage_output.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/read_many.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/script_custom_func.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/script_function.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/script_many_classes.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/script_minimal.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/script_model_class.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/submit_function.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/submit_many_func.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/submit_many_iter.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/examples/submit_shebang.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/compatibility/__init__.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/run/__init__.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/__init__.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/__init__.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/json.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/modelrunner/storage/backend/yaml.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/py_modelrunner.egg-info/dependency_links.txt +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/py_modelrunner.egg-info/not-zip-safe +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/py_modelrunner.egg-info/requires.txt +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/py_modelrunner.egg-info/top_level.txt +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/create_compatibility_files.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/performance_hdf5_zarr.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/tests_all.sh +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/tests_codestyle.sh +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/tests_coverage.sh +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/tests_parallel.sh +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/tests_run.sh +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/scripts/tests_types.sh +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/setup.cfg +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/0/result.hdf +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/0/result.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/0/result.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/0/result.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array.zarr +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array_col.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array_col.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array_col.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/array_col.zarr +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/dict.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/dict.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/dict.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/dict.zarr +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/object.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/object.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/object.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/1/object.zarr +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array.hdf +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array.zip +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array_col.hdf +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array_col.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array_col.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array_col.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/array_col.zip +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/dict.hdf +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/dict.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/dict.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/dict.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/dict.zip +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/nested.hdf +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/nested.json +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/nested.pkl +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/nested.yaml +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/2/nested.zip +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/compatibility/test_compatibility.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/helpers/__init__.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/helpers/asserts.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/run/scripts/function.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/run/scripts/script.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/run/test_job.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/run/test_run_main.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/scripts/empty.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/scripts/function.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/scripts/function_main.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/scripts/function_marked.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/scripts/make_model.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/scripts/make_model_class.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/scripts/make_model_marked.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/storage/test_group.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/storage/test_utils.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/test_main.py +0 -0
- {py-modelrunner-0.14.0 → py-modelrunner-0.16.0}/tests/test_version.py +0 -0
|
@@ -9,20 +9,27 @@ jobs:
|
|
|
9
9
|
strategy:
|
|
10
10
|
matrix:
|
|
11
11
|
os: [macos-latest, ubuntu-latest, windows-latest]
|
|
12
|
-
python-version: ['3.8', '3.
|
|
12
|
+
python-version: ['3.8', '3.12']
|
|
13
13
|
|
|
14
14
|
steps:
|
|
15
15
|
- uses: actions/checkout@v3
|
|
16
|
+
|
|
16
17
|
- name: Set up Python ${{ matrix.python-version }}
|
|
17
18
|
uses: actions/setup-python@v4
|
|
18
19
|
with:
|
|
19
20
|
python-version: ${{ matrix.python-version }}
|
|
21
|
+
|
|
20
22
|
- name: Install dependencies
|
|
21
23
|
run: |
|
|
22
24
|
python -m pip install --upgrade pip
|
|
23
25
|
pip install -r requirements.txt
|
|
24
26
|
pip install -r tests/requirements.txt
|
|
25
27
|
|
|
28
|
+
- name: Install optional dependencies
|
|
29
|
+
continue-on-error: true
|
|
30
|
+
run: |
|
|
31
|
+
pip install py-pde
|
|
32
|
+
|
|
26
33
|
- name: Test with pytest
|
|
27
34
|
env:
|
|
28
35
|
NUMBA_WARNINGS: 1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: py-modelrunner
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0
|
|
4
4
|
Summary: Python classes for organizing (HPC) simulations
|
|
5
5
|
Author-email: David Zwicker <david.zwicker@ds.mpg.de>
|
|
6
6
|
License: MIT
|
|
@@ -18,7 +18,8 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
-
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Requires-Python: <3.13,>=3.8
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
24
|
License-File: LICENSE
|
|
24
25
|
Requires-Dist: jinja2>=3
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
#
|
|
3
2
|
# Configuration file for the Sphinx documentation builder.
|
|
4
3
|
#
|
|
@@ -226,8 +225,8 @@ napoleon_numpy_docstring = False
|
|
|
226
225
|
napoleon_include_init_with_doc = False
|
|
227
226
|
napoleon_include_private_with_doc = False
|
|
228
227
|
napoleon_include_special_with_doc = False
|
|
229
|
-
napoleon_use_admonition_for_examples =
|
|
230
|
-
napoleon_use_admonition_for_notes =
|
|
228
|
+
napoleon_use_admonition_for_examples = True
|
|
229
|
+
napoleon_use_admonition_for_notes = True
|
|
231
230
|
napoleon_use_admonition_for_references = False
|
|
232
231
|
napoleon_use_ivar = False
|
|
233
232
|
napoleon_use_param = True
|
|
@@ -239,13 +238,16 @@ napoleon_custom_sections = None
|
|
|
239
238
|
|
|
240
239
|
# Example configuration for intersphinx: refer to the Python standard library.
|
|
241
240
|
intersphinx_mapping = {
|
|
242
|
-
"https://docs.
|
|
243
|
-
"https://
|
|
244
|
-
"https://
|
|
245
|
-
"https://
|
|
246
|
-
"
|
|
247
|
-
"https://
|
|
248
|
-
"https://py-
|
|
241
|
+
"h5py": ("https://docs.h5py.org/en/latest", None),
|
|
242
|
+
"matplotlib": ("https://matplotlib.org/stable", None),
|
|
243
|
+
"modelrunner": ("https://py-modelrunner.readthedocs.io/en/latest", None),
|
|
244
|
+
"napari": ("https://napari.org/", None),
|
|
245
|
+
"numba": ("https://numba.pydata.org/numba-doc/latest/", None),
|
|
246
|
+
"numpy": ("https://numpy.org/doc/stable", None),
|
|
247
|
+
"pde": ("https://py-pde.readthedocs.io/en/latest", None),
|
|
248
|
+
"python": ("https://docs.python.org/3/", None),
|
|
249
|
+
"scipy": ("https://docs.scipy.org/doc/scipy/", None),
|
|
250
|
+
"sympy": ("https://docs.sympy.org/latest/", None),
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
|
|
@@ -255,6 +257,11 @@ graphviz_output_format = "svg"
|
|
|
255
257
|
# for the graph, which we here corrected manually, but which lead to issues if we also
|
|
256
258
|
# used the inheritance_diagram extension
|
|
257
259
|
|
|
260
|
+
# create all example files
|
|
261
|
+
from parse_examples import main
|
|
262
|
+
|
|
263
|
+
main()
|
|
264
|
+
|
|
258
265
|
# run autodoc
|
|
259
266
|
autodoc_typehints = "description"
|
|
260
267
|
|
|
@@ -26,7 +26,7 @@ You can thus install it using
|
|
|
26
26
|
|
|
27
27
|
conda install -c conda-forge py-modelrunner
|
|
28
28
|
|
|
29
|
-
This installation includes all required dependencies to have all features of `py-
|
|
29
|
+
This installation includes all required dependencies to have all features of `py-modelrunner`.
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
Installing from source
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import pathlib
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
# Root direcotry of the package
|
|
7
|
+
ROOT = pathlib.Path(__file__).absolute().parents[2]
|
|
8
|
+
# directory where all the examples reside
|
|
9
|
+
INPUT = ROOT / "examples"
|
|
10
|
+
# directory to which the documents are writen
|
|
11
|
+
OUTPUT = ROOT / "docs" / "source" / "examples"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
"""parse all examples and write them in a special example module"""
|
|
16
|
+
# create the output directory
|
|
17
|
+
OUTPUT.mkdir(parents=True, exist_ok=True)
|
|
18
|
+
|
|
19
|
+
regex = r'"""((?!""").*?)"""'
|
|
20
|
+
|
|
21
|
+
# iterate over all examples
|
|
22
|
+
for path_in in INPUT.glob("*.py"):
|
|
23
|
+
path_out = OUTPUT / (path_in.stem + ".rst")
|
|
24
|
+
print(f"Found example {path_in}")
|
|
25
|
+
with path_in.open("r") as file_in, path_out.open("w") as file_out:
|
|
26
|
+
# write the header for the rst file
|
|
27
|
+
file_out.write(path_in.name + "\n")
|
|
28
|
+
file_out.write("-" * len(path_in.name) + "\n\n")
|
|
29
|
+
|
|
30
|
+
# read all content
|
|
31
|
+
file_content = file_in.read()
|
|
32
|
+
|
|
33
|
+
# identify shebang
|
|
34
|
+
if file_content.startswith("#"):
|
|
35
|
+
shebang, file_content = file_content.split("\n", 1)
|
|
36
|
+
if shebang == "#!/usr/bin/env python3":
|
|
37
|
+
shebang = "" # filter trivial case
|
|
38
|
+
else:
|
|
39
|
+
shebang = None
|
|
40
|
+
|
|
41
|
+
# locate file docstring
|
|
42
|
+
matches = re.search(regex, file_content, re.DOTALL)
|
|
43
|
+
if matches:
|
|
44
|
+
for line in matches.group(1).split("\n"):
|
|
45
|
+
if ".. codeauthor::" in line:
|
|
46
|
+
continue
|
|
47
|
+
file_out.write(f"{line}\n")
|
|
48
|
+
|
|
49
|
+
file_content = file_content[matches.end(0) :]
|
|
50
|
+
|
|
51
|
+
# write actual code
|
|
52
|
+
file_out.write(".. code-block:: python\n\n")
|
|
53
|
+
if shebang:
|
|
54
|
+
file_out.write(f" {shebang}\n\n")
|
|
55
|
+
header = True
|
|
56
|
+
for line in file_content.split("\n"):
|
|
57
|
+
# skip the shebang, comments and empty lines in the beginning
|
|
58
|
+
if header and (line.startswith("#") or len(line.strip()) == 0):
|
|
59
|
+
continue
|
|
60
|
+
header = False # first real line was reached
|
|
61
|
+
file_out.write(f" {line}\n")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
main()
|
|
@@ -83,7 +83,7 @@ REPLACEMENTS = collections.OrderedDict(
|
|
|
83
83
|
# replacement rules based on regular expressions
|
|
84
84
|
REPLACEMENTS_REGEX = {
|
|
85
85
|
# remove full package path and only leave the module/class identifier
|
|
86
|
-
"multicomp\.(\w+\.)*": "",
|
|
86
|
+
r"multicomp\.(\w+\.)*": "",
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
User Manual
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
Main structure of the package
|
|
5
|
+
-----------------------------
|
|
6
|
+
|
|
7
|
+
The package offers several different components that can be used separately or together:
|
|
8
|
+
|
|
9
|
+
Hierarchical input/output using :mod:`~modelrunner.storage`:
|
|
10
|
+
The module provides an abstract interface for writing and reading data using an
|
|
11
|
+
hierarchical organization.
|
|
12
|
+
Storages are conveniently created by :func:`~modelrunner.storage.tools.open_storage`,
|
|
13
|
+
which returns a storage object that offers a dict-like interface.
|
|
14
|
+
|
|
15
|
+
Defining parameters using :mod:`~modelrunner.parameters`:
|
|
16
|
+
The module provides the :class:`~modelrunner.parameters.Parameter` class, describing a single parameter.
|
|
17
|
+
This can be used together with the mixin :class:`~modelrunner.parameters.Parametrized`,
|
|
18
|
+
which allows to equip classes with default parameters and some convenience methods.
|
|
19
|
+
|
|
20
|
+
Defining models using :mod:`~modelrunner.model`:
|
|
21
|
+
Models are augmented functions, which define input, calculations, and output.
|
|
22
|
+
Models can be conveniently created by decorating a function or by subclassing
|
|
23
|
+
:class:`~modelrunner.model.ModelBase`, which is built on the parameter classes.
|
|
24
|
+
|
|
25
|
+
Model results are captured by :mod:`~modelrunner.results`:
|
|
26
|
+
Results are returned as the special :class:`~modelrunner.results.Result`, which
|
|
27
|
+
keeps track of the input parameters and the data calculated by the model.
|
|
28
|
+
:class:`~modelrunner.results.ResultCollection` describes a collections of the same
|
|
29
|
+
model evoked with different parameter values.
|
|
30
|
+
|
|
31
|
+
Submitting models to HPC using :mod:`~modelrunner.run`:
|
|
32
|
+
A single model can be submitted to a compute node using :func:`~modelrunner.run.job.submit_job`,
|
|
33
|
+
e.g., to run the computation on a high performance compute cluster.
|
|
34
|
+
A parameter study using multiple jobs can be conveniently submitted using :func:`~modelrunner.run.job.submit_jobs`.
|
|
35
|
+
The results written to one directory can then be conveniently analyzed using :meth:`~modelrunner.results.ResultCollection.from_folder`.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
Design philosophy
|
|
39
|
+
-----------------
|
|
40
|
+
|
|
41
|
+
The main requirements for the storage classes were
|
|
42
|
+
|
|
43
|
+
- *Usability*: The user should not need to think about how data is stored in different files
|
|
44
|
+
- *Flexibility*: We want a general interface to write data in multiple file formats (YAML, HDF, zarr, ...)
|
|
45
|
+
- *Stability*: Future versions of the package should be able to read older files even when the internal definitions of file formats change
|
|
46
|
+
- *Extensibility*: States should be subclasses to implement more complicated requirements (e.g., particular serialization)
|
|
47
|
+
- *Self-explainability*: The files should in principle contain all information to reconstruct the data, even if the `py-modelrunner` package is no longer available.
|
|
48
|
+
- *Efficiency*: The files should only store necessary information.
|
|
49
|
+
|
|
50
|
+
The last point results in particular constraints if we want to store temporal simulation results.
|
|
51
|
+
In most cases, there are are some data that are kept fixed for the simulation (describing physical parameters) and others that evolve with time.
|
|
52
|
+
We denote by `attributes` the parameters that are kept fixed and by `data` the data that varies over time.
|
|
53
|
+
The state classes are already prepared to deal with such data, in conjuction with the :mod:`~modelrunner.storage.trajectory` module.
|
|
@@ -8,7 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
import json
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import TYPE_CHECKING, Any, Mapping,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Mapping, Union
|
|
12
12
|
|
|
13
13
|
from ..model import ModelBase
|
|
14
14
|
from ..results import Result
|
|
@@ -42,7 +42,7 @@ def guess_format(path: Path) -> str:
|
|
|
42
42
|
return "zarr" # fallback to the default storage method based on zarr
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def normalize_zarr_store(store: Store, mode: str = "a") ->
|
|
45
|
+
def normalize_zarr_store(store: Store, mode: str = "a") -> Store | None:
|
|
46
46
|
"""determine best file format for zarr storage
|
|
47
47
|
|
|
48
48
|
In particular, we use a :class:`~zarr.storage.ZipStore` when a path looking like a
|
|
@@ -70,7 +70,7 @@ def normalize_zarr_store(store: Store, mode: str = "a") -> Optional[Store]:
|
|
|
70
70
|
return store
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
def _find_version(data: Mapping[str, Any], label: str) ->
|
|
73
|
+
def _find_version(data: Mapping[str, Any], label: str) -> int | None:
|
|
74
74
|
"""try finding version information in different places in `data`
|
|
75
75
|
|
|
76
76
|
Args:
|
|
@@ -83,7 +83,7 @@ def _find_version(data: Mapping[str, Any], label: str) -> Optional[int]:
|
|
|
83
83
|
int: The format version or None if it could not be found
|
|
84
84
|
"""
|
|
85
85
|
|
|
86
|
-
def read_version(item) ->
|
|
86
|
+
def read_version(item) -> str | None:
|
|
87
87
|
"""try reading attribute from a particular item"""
|
|
88
88
|
if hasattr(item, "attrs"):
|
|
89
89
|
return read_version(item.attrs)
|
|
@@ -111,8 +111,8 @@ def _find_version(data: Mapping[str, Any], label: str) -> Optional[int]:
|
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
def result_check_load_old_version(
|
|
114
|
-
path: Path, loc: str, *, model:
|
|
115
|
-
) ->
|
|
114
|
+
path: Path, loc: str, *, model: ModelBase | None = None
|
|
115
|
+
) -> Result | None:
|
|
116
116
|
"""check whether the resource can be loaded with an older version of the package
|
|
117
117
|
|
|
118
118
|
Args:
|
|
@@ -132,13 +132,13 @@ def result_check_load_old_version(
|
|
|
132
132
|
# check for compatibility
|
|
133
133
|
fmt = guess_format(path)
|
|
134
134
|
if fmt == "json":
|
|
135
|
-
with open(path
|
|
135
|
+
with open(path) as fp:
|
|
136
136
|
format_version = _find_version(json.load(fp), label)
|
|
137
137
|
|
|
138
138
|
elif fmt == "yaml":
|
|
139
139
|
import yaml
|
|
140
140
|
|
|
141
|
-
with open(path
|
|
141
|
+
with open(path) as fp:
|
|
142
142
|
format_version = _find_version(yaml.safe_load(fp), label)
|
|
143
143
|
|
|
144
144
|
elif fmt == "hdf":
|
|
@@ -8,7 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
import json
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any, Mapping
|
|
11
|
+
from typing import Any, Mapping
|
|
12
12
|
|
|
13
13
|
import numpy as np
|
|
14
14
|
|
|
@@ -32,7 +32,7 @@ def read_hdf_data(node):
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def _Result_from_simple_objects(
|
|
35
|
-
content: Mapping[str, Any], model:
|
|
35
|
+
content: Mapping[str, Any], model: ModelBase | None = None
|
|
36
36
|
) -> Result:
|
|
37
37
|
"""read result from simple object (like loaded from a JSON file) using version 0
|
|
38
38
|
|
|
@@ -54,7 +54,7 @@ def _Result_from_simple_objects(
|
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def _Result_from_hdf(hdf_element, model:
|
|
57
|
+
def _Result_from_hdf(hdf_element, model: ModelBase | None = None) -> Result:
|
|
58
58
|
"""old reader for backward compatible reading"""
|
|
59
59
|
model_data = {key: json.loads(value) for key, value in hdf_element.attrs.items()}
|
|
60
60
|
if "result" in hdf_element:
|
|
@@ -80,14 +80,14 @@ def result_from_file_v0(path: Path, **kwargs) -> Result:
|
|
|
80
80
|
"""
|
|
81
81
|
fmt = guess_format(path)
|
|
82
82
|
if fmt == "json":
|
|
83
|
-
with open(path
|
|
83
|
+
with open(path) as fp:
|
|
84
84
|
content = json.load(fp)
|
|
85
85
|
return _Result_from_simple_objects(content, **kwargs)
|
|
86
86
|
|
|
87
87
|
elif fmt == "yaml":
|
|
88
88
|
import yaml
|
|
89
89
|
|
|
90
|
-
with open(path
|
|
90
|
+
with open(path) as fp:
|
|
91
91
|
content = yaml.safe_load(fp)
|
|
92
92
|
return _Result_from_simple_objects(content, **kwargs)
|
|
93
93
|
|
|
@@ -10,7 +10,7 @@ import json
|
|
|
10
10
|
import warnings
|
|
11
11
|
from abc import ABCMeta
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import TYPE_CHECKING, Any,
|
|
13
|
+
from typing import TYPE_CHECKING, Any, TypeVar, Union
|
|
14
14
|
|
|
15
15
|
import numpy as np
|
|
16
16
|
|
|
@@ -55,10 +55,10 @@ class StateBase(metaclass=ABCMeta):
|
|
|
55
55
|
_state_format_version = 2
|
|
56
56
|
"""int: number indicating the version of the file format"""
|
|
57
57
|
|
|
58
|
-
_state_classes:
|
|
58
|
+
_state_classes: dict[str, type[StateBase]] = {}
|
|
59
59
|
"""dict: class-level list of all subclasses of StateBase"""
|
|
60
60
|
|
|
61
|
-
def _state_init(self, attributes:
|
|
61
|
+
def _state_init(self, attributes: dict[str, Any], data=NoData) -> None:
|
|
62
62
|
"""initialize the state with attributes and (optionally) data
|
|
63
63
|
|
|
64
64
|
Args:
|
|
@@ -71,7 +71,7 @@ class StateBase(metaclass=ABCMeta):
|
|
|
71
71
|
self._state_attributes = attributes
|
|
72
72
|
|
|
73
73
|
@classmethod
|
|
74
|
-
def from_data(cls:
|
|
74
|
+
def from_data(cls: type[TState], attributes: dict[str, Any], data=NoData) -> TState:
|
|
75
75
|
"""create instance of any state class from attributes and data
|
|
76
76
|
|
|
77
77
|
Args:
|
|
@@ -84,7 +84,8 @@ class StateBase(metaclass=ABCMeta):
|
|
|
84
84
|
# copy attributes since they are modified in this function
|
|
85
85
|
attributes = attributes.copy()
|
|
86
86
|
cls_name = attributes["__class__"]
|
|
87
|
-
|
|
87
|
+
if cls_name != cls.__name__:
|
|
88
|
+
raise RuntimeError(f"Expected `{cls.__name__}` but data had `{cls_name}`")
|
|
88
89
|
|
|
89
90
|
format_version = attributes.pop("__version__", 0)
|
|
90
91
|
if format_version != 1:
|
|
@@ -97,7 +98,7 @@ class StateBase(metaclass=ABCMeta):
|
|
|
97
98
|
return obj
|
|
98
99
|
|
|
99
100
|
@classmethod
|
|
100
|
-
def _from_simple_objects(cls, content:
|
|
101
|
+
def _from_simple_objects(cls, content: dict[str, Any]) -> StateBase:
|
|
101
102
|
"""create state from text data
|
|
102
103
|
|
|
103
104
|
Args:
|
|
@@ -115,7 +116,7 @@ class StateBase(metaclass=ABCMeta):
|
|
|
115
116
|
return ArrayCollectionState.from_data(content["attributes"], col_data)
|
|
116
117
|
|
|
117
118
|
elif cls_name == "DictState":
|
|
118
|
-
dict_data:
|
|
119
|
+
dict_data: dict[str, StateBase] = {}
|
|
119
120
|
for label, substate in content["data"].items():
|
|
120
121
|
dict_data[label] = cls._from_simple_objects(substate)
|
|
121
122
|
|
|
@@ -128,7 +129,7 @@ class StateBase(metaclass=ABCMeta):
|
|
|
128
129
|
raise TypeError(f"Do not know how to load `{cls_name}`")
|
|
129
130
|
|
|
130
131
|
@classmethod
|
|
131
|
-
def _from_zarr(cls, zarr_element:
|
|
132
|
+
def _from_zarr(cls, zarr_element: zarrElement, *, index=...) -> StateBase:
|
|
132
133
|
"""create instance of correct subclass from data stored in zarr"""
|
|
133
134
|
# determine the class that knows how to read this data
|
|
134
135
|
cls_name = zarr_element.attrs["__class__"]
|
|
@@ -163,24 +164,20 @@ class StateBase(metaclass=ABCMeta):
|
|
|
163
164
|
raise TypeError(f"Do not know how to load `{cls_name}`")
|
|
164
165
|
|
|
165
166
|
|
|
166
|
-
class ArrayState(StateBase):
|
|
167
|
-
...
|
|
167
|
+
class ArrayState(StateBase): ...
|
|
168
168
|
|
|
169
169
|
|
|
170
|
-
class ArrayCollectionState(StateBase):
|
|
171
|
-
...
|
|
170
|
+
class ArrayCollectionState(StateBase): ...
|
|
172
171
|
|
|
173
172
|
|
|
174
|
-
class DictState(StateBase):
|
|
175
|
-
...
|
|
173
|
+
class DictState(StateBase): ...
|
|
176
174
|
|
|
177
175
|
|
|
178
|
-
class ObjectState(StateBase):
|
|
179
|
-
...
|
|
176
|
+
class ObjectState(StateBase): ...
|
|
180
177
|
|
|
181
178
|
|
|
182
179
|
def _Result_from_simple_objects(
|
|
183
|
-
content:
|
|
180
|
+
content: dict[str, Any], model: ModelBase | None = None
|
|
184
181
|
) -> Result:
|
|
185
182
|
"""read result from simple object (like loaded from a JSON file) using version 1
|
|
186
183
|
|
|
@@ -202,7 +199,7 @@ def _Result_from_simple_objects(
|
|
|
202
199
|
|
|
203
200
|
|
|
204
201
|
def _Result_from_zarr(
|
|
205
|
-
zarr_element:
|
|
202
|
+
zarr_element: zarrElement, *, index=..., model: ModelBase | None = None
|
|
206
203
|
) -> Result:
|
|
207
204
|
"""create result from data stored in zarr"""
|
|
208
205
|
attributes = {key: json.loads(value) for key, value in zarr_element.attrs.items()}
|
|
@@ -236,14 +233,14 @@ def result_from_file_v1(store: Path, *, label: str = "data", **kwargs) -> Result
|
|
|
236
233
|
"""
|
|
237
234
|
fmt = guess_format(store)
|
|
238
235
|
if fmt == "json":
|
|
239
|
-
with open(store
|
|
236
|
+
with open(store) as fp:
|
|
240
237
|
content = json.load(fp)
|
|
241
238
|
return _Result_from_simple_objects(content, **kwargs)
|
|
242
239
|
|
|
243
240
|
elif fmt == "yaml":
|
|
244
241
|
import yaml
|
|
245
242
|
|
|
246
|
-
with open(store
|
|
243
|
+
with open(store) as fp:
|
|
247
244
|
content = yaml.safe_load(fp)
|
|
248
245
|
return _Result_from_simple_objects(content, **kwargs)
|
|
249
246
|
|