py-modelrunner 0.13.0__tar.gz → 0.14.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.13.0 → py-modelrunner-0.14.0}/.gitignore +6 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/PKG-INFO +19 -2
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/io_hdf.py +1 -1
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/io_json.py +1 -1
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/io_yaml.py +1 -1
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/model_class.py +5 -1
- py-modelrunner-0.14.0/examples/model_storage_output.py +27 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/script_function.py +1 -1
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/__init__.py +1 -19
- py-modelrunner-0.14.0/modelrunner/_version.py +16 -0
- py-modelrunner-0.14.0/modelrunner/compatibility/__init__.py +5 -0
- py-modelrunner-0.14.0/modelrunner/compatibility/triage.py +181 -0
- py-modelrunner-0.14.0/modelrunner/compatibility/version0.py +101 -0
- py-modelrunner-0.14.0/modelrunner/compatibility/version1.py +261 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/model.py +74 -36
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/parameters.py +6 -2
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/results.py +99 -176
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/run/job.py +31 -9
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/run/templates/background.template +9 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/run/templates/foreground.template +9 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/run/templates/qsub.template +9 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/run/templates/srun.template +9 -0
- py-modelrunner-0.14.0/modelrunner/storage/__init__.py +8 -0
- py-modelrunner-0.14.0/modelrunner/storage/access_modes.py +142 -0
- py-modelrunner-0.14.0/modelrunner/storage/attributes.py +88 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/__init__.py +28 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/hdf.py +267 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/json.py +28 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/memory.py +176 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/text_base.py +215 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/utils.py +64 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/yaml.py +36 -0
- py-modelrunner-0.14.0/modelrunner/storage/backend/zarr.py +232 -0
- py-modelrunner-0.14.0/modelrunner/storage/base.py +507 -0
- py-modelrunner-0.14.0/modelrunner/storage/group.py +411 -0
- py-modelrunner-0.14.0/modelrunner/storage/tools.py +139 -0
- py-modelrunner-0.14.0/modelrunner/storage/trajectory.py +231 -0
- py-modelrunner-0.14.0/modelrunner/storage/utils.py +232 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/py_modelrunner.egg-info/PKG-INFO +19 -2
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/py_modelrunner.egg-info/SOURCES.txt +51 -14
- py-modelrunner-0.14.0/py_modelrunner.egg-info/requires.txt +19 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/pyproject.toml +20 -6
- py-modelrunner-0.14.0/requirements.txt +4 -0
- py-modelrunner-0.14.0/requirements_full.txt +5 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/create_compatibility_files.py +13 -15
- py-modelrunner-0.14.0/tests/compatibility/2/array.hdf +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array.json +1 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array.pkl +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array.yaml +15 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array.zip +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array_col.hdf +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array_col.json +1 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array_col.pkl +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array_col.yaml +16 -0
- py-modelrunner-0.14.0/tests/compatibility/2/array_col.zip +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/dict.hdf +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/dict.json +1 -0
- py-modelrunner-0.14.0/tests/compatibility/2/dict.pkl +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/dict.yaml +17 -0
- py-modelrunner-0.14.0/tests/compatibility/2/dict.zip +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/nested.hdf +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/nested.json +1 -0
- py-modelrunner-0.14.0/tests/compatibility/2/nested.pkl +0 -0
- py-modelrunner-0.14.0/tests/compatibility/2/nested.yaml +15 -0
- py-modelrunner-0.14.0/tests/compatibility/2/nested.zip +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/test_compatibility.py +13 -15
- py-modelrunner-0.14.0/tests/helpers/__init__.py +2 -0
- py-modelrunner-0.14.0/tests/helpers/asserts.py +62 -0
- py-modelrunner-0.14.0/tests/helpers/storage.py +102 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/requirements.txt +2 -1
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/run/test_job.py +4 -2
- py-modelrunner-0.14.0/tests/run/test_run_main.py +26 -0
- py-modelrunner-0.14.0/tests/storage/test_group.py +18 -0
- py-modelrunner-0.14.0/tests/storage/test_storage_generic.py +279 -0
- py-modelrunner-0.14.0/tests/storage/test_storage_special.py +79 -0
- py-modelrunner-0.14.0/tests/storage/test_trajectory.py +147 -0
- py-modelrunner-0.14.0/tests/storage/test_utils.py +42 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/test_model.py +46 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/test_results.py +57 -3
- py-modelrunner-0.13.0/.settings/.gitignore +0 -1
- py-modelrunner-0.13.0/modelrunner/_version.py +0 -4
- py-modelrunner-0.13.0/modelrunner/state/__init__.py +0 -71
- py-modelrunner-0.13.0/modelrunner/state/array.py +0 -128
- py-modelrunner-0.13.0/modelrunner/state/array_collection.py +0 -192
- py-modelrunner-0.13.0/modelrunner/state/base.py +0 -413
- py-modelrunner-0.13.0/modelrunner/state/dict.py +0 -178
- py-modelrunner-0.13.0/modelrunner/state/io.py +0 -336
- py-modelrunner-0.13.0/modelrunner/state/object.py +0 -88
- py-modelrunner-0.13.0/modelrunner/state/trajectory.py +0 -171
- py-modelrunner-0.13.0/py_modelrunner.egg-info/requires.txt +0 -8
- py-modelrunner-0.13.0/requirements.txt +0 -8
- py-modelrunner-0.13.0/tests/state/test_dict.py +0 -39
- py-modelrunner-0.13.0/tests/state/test_generic.py +0 -178
- py-modelrunner-0.13.0/tests/state/test_trajectory.py +0 -107
- py-modelrunner-0.13.0/tests/utils/__init__.py +0 -0
- py-modelrunner-0.13.0/tests/utils/states.py +0 -84
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/.github/workflows/build.yml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/.github/workflows/check_docs.yml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/.github/workflows/coverage_report.yml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/.github/workflows/release_pip.yml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/.readthedocs.yaml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/LICENSE +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/README.md +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/codecov.yml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/Makefile +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/build_all.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/requirements.txt +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/source/.gitignore +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/source/conf.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/source/index.rst +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/source/installation.rst +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/source/run_autodoc.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/source/sphinx_simplify_typehints.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/docs/source/structure.rst +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/model_decorator.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/model_function.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/read_many.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/script_custom_func.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/script_many_classes.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/script_minimal.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/script_model_class.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/submit_function.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/submit_many_func.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/submit_many_iter.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/examples/submit_shebang.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/__main__.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/py.typed +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/run/__init__.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/modelrunner/run/__main__.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/py_modelrunner.egg-info/dependency_links.txt +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/py_modelrunner.egg-info/not-zip-safe +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/py_modelrunner.egg-info/top_level.txt +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/format_code.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/performance_hdf5_zarr.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/run_tests.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/tests_all.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/tests_codestyle.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/tests_coverage.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/tests_parallel.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/tests_run.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/scripts/tests_types.sh +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/setup.cfg +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/0/result.hdf +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/0/result.json +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/0/result.pkl +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/0/result.yaml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array.json +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array.pkl +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array.yaml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array.zarr +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array_col.json +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array_col.pkl +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array_col.yaml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/array_col.zarr +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/dict.json +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/dict.pkl +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/dict.yaml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/dict.zarr +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/object.json +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/object.pkl +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/object.yaml +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/compatibility/1/object.zarr +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/run/scripts/function.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/run/scripts/script.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/scripts/empty.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/scripts/function.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/scripts/function_main.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/scripts/function_marked.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/scripts/make_model.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/scripts/make_model_class.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/scripts/make_model_marked.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/test_examples.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/test_main.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/test_parameters.py +0 -0
- {py-modelrunner-0.13.0 → py-modelrunner-0.14.0}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: py-modelrunner
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14.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,9 +18,26 @@ 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
|
-
Requires-Python:
|
|
21
|
+
Requires-Python: <3.12,>=3.8
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
+
Requires-Dist: jinja2>=3
|
|
25
|
+
Requires-Dist: numpy>=1.18.0
|
|
26
|
+
Requires-Dist: tqdm>=4.45
|
|
27
|
+
Requires-Dist: numcodecs>=0.10
|
|
28
|
+
Provides-Extra: all
|
|
29
|
+
Requires-Dist: h5py>=3.5; extra == "all"
|
|
30
|
+
Requires-Dist: pandas>=1.3; extra == "all"
|
|
31
|
+
Requires-Dist: PyYAML>=5; extra == "all"
|
|
32
|
+
Requires-Dist: zarr>=2; extra == "all"
|
|
33
|
+
Provides-Extra: test
|
|
34
|
+
Requires-Dist: black>=19; extra == "test"
|
|
35
|
+
Requires-Dist: isort>=5.1; extra == "test"
|
|
36
|
+
Requires-Dist: pytest>=5.4; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-cov>=2.8; extra == "test"
|
|
38
|
+
Requires-Dist: pytest-xdist>=1.30; extra == "test"
|
|
39
|
+
Requires-Dist: py-pde>=0.33; extra == "test"
|
|
40
|
+
Requires-Dist: mypy>=0.770; extra == "test"
|
|
24
41
|
|
|
25
42
|
# py-modelrunner
|
|
26
43
|
|
|
@@ -5,6 +5,8 @@ This example shows defining a custom model class by subclassing.
|
|
|
5
5
|
.. codeauthor:: David Zwicker <david.zwicker@ds.mpg.de>
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
8
10
|
from modelrunner import ModelBase
|
|
9
11
|
|
|
10
12
|
|
|
@@ -12,10 +14,12 @@ class MyModel(ModelBase):
|
|
|
12
14
|
parameters_default = {"a": 1, "b": 2}
|
|
13
15
|
|
|
14
16
|
def __call__(self):
|
|
17
|
+
self.storage.write_array("arr", np.arange(4))
|
|
18
|
+
self.storage.write_attrs("arr", {"key": "value"}) # write extra information
|
|
15
19
|
return self.parameters["a"] * self.parameters["b"]
|
|
16
20
|
|
|
17
21
|
|
|
18
22
|
# create an instance of the model
|
|
19
|
-
model = MyModel({"a": 3})
|
|
23
|
+
model = MyModel({"a": 3}, output="test.yaml")
|
|
20
24
|
# run the instance
|
|
21
25
|
print(model())
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
This example shows defining a custom model that stores additional data
|
|
4
|
+
|
|
5
|
+
.. codeauthor:: David Zwicker <david.zwicker@ds.mpg.de>
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import tempfile
|
|
9
|
+
|
|
10
|
+
from modelrunner import make_model, open_storage
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def multiply(a, b=2, storage=None):
|
|
14
|
+
storage["data"] = {"additional": "information"}
|
|
15
|
+
return a * b
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
with tempfile.NamedTemporaryFile(suffix=".yaml") as fp:
|
|
19
|
+
# create an instance of the model defined by the function
|
|
20
|
+
model = make_model(multiply, {"a": 3}, output=fp.name)
|
|
21
|
+
# run the instance and store the data
|
|
22
|
+
model.write_result()
|
|
23
|
+
|
|
24
|
+
# read the file and check whether all the data is there
|
|
25
|
+
with open_storage(fp.name) as storage:
|
|
26
|
+
print("Stored data:", storage["data"])
|
|
27
|
+
print("Model result:", storage["result"].data)
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
.. inheritance-diagram::
|
|
4
|
-
state.io.IOBase
|
|
5
|
-
state.base.StateBase
|
|
6
|
-
state.array.ArrayState
|
|
7
|
-
state.array_collection.ArrayCollectionState
|
|
8
|
-
state.object.ObjectState
|
|
9
|
-
state.dict.DictState
|
|
10
|
-
results.Result
|
|
11
|
-
:parts: 1
|
|
12
|
-
|
|
13
2
|
.. codeauthor:: David Zwicker <david.zwicker@ds.mpg.de>
|
|
14
3
|
"""
|
|
15
4
|
|
|
@@ -41,11 +30,4 @@ from .model import (
|
|
|
41
30
|
from .parameters import HideParameter, Parameter, Parameterized
|
|
42
31
|
from .results import Result, ResultCollection
|
|
43
32
|
from .run import submit_job, submit_jobs
|
|
44
|
-
from .
|
|
45
|
-
ArrayCollectionState,
|
|
46
|
-
ArrayState,
|
|
47
|
-
DictState,
|
|
48
|
-
ObjectState,
|
|
49
|
-
load_state,
|
|
50
|
-
make_state,
|
|
51
|
-
)
|
|
33
|
+
from .storage import open_storage
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# file generated by setuptools_scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
TYPE_CHECKING = False
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from typing import Tuple, Union
|
|
6
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
|
+
else:
|
|
8
|
+
VERSION_TUPLE = object
|
|
9
|
+
|
|
10
|
+
version: str
|
|
11
|
+
__version__: str
|
|
12
|
+
__version_tuple__: VERSION_TUPLE
|
|
13
|
+
version_tuple: VERSION_TUPLE
|
|
14
|
+
|
|
15
|
+
__version__ = version = '0.14.0'
|
|
16
|
+
__version_tuple__ = version_tuple = (0, 14, 0)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains code necessary for deciding which format version was used to write a file
|
|
3
|
+
|
|
4
|
+
.. codeauthor:: David Zwicker <david.zwicker@ds.mpg.de>
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Mapping, Optional, Union
|
|
12
|
+
|
|
13
|
+
from ..model import ModelBase
|
|
14
|
+
from ..results import Result
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from zarr.storage import BaseStore
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
Store = Union[str, Path, "BaseStore"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def guess_format(path: Path) -> str:
|
|
24
|
+
"""guess the format of a given store
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
path (str or :class:`~pathlib.Path`):
|
|
28
|
+
Path pointing to a file
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
str: The store format
|
|
32
|
+
"""
|
|
33
|
+
# guess format from path extension
|
|
34
|
+
ext = Path(path).suffix.lower()
|
|
35
|
+
if ext == ".json":
|
|
36
|
+
return "json"
|
|
37
|
+
elif ext in {".yml", ".yaml"}:
|
|
38
|
+
return "yaml"
|
|
39
|
+
elif ext in {".h5", ".hdf", ".hdf5"}:
|
|
40
|
+
return "hdf"
|
|
41
|
+
else:
|
|
42
|
+
return "zarr" # fallback to the default storage method based on zarr
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def normalize_zarr_store(store: Store, mode: str = "a") -> Optional[Store]:
|
|
46
|
+
"""determine best file format for zarr storage
|
|
47
|
+
|
|
48
|
+
In particular, we use a :class:`~zarr.storage.ZipStore` when a path looking like a
|
|
49
|
+
file is given.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
store: User-provided store
|
|
53
|
+
mode (str): The mode with which the file will be opened
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
"""
|
|
57
|
+
import zipfile
|
|
58
|
+
|
|
59
|
+
import zarr
|
|
60
|
+
|
|
61
|
+
if isinstance(store, (str, Path)):
|
|
62
|
+
store = Path(store)
|
|
63
|
+
if store.is_file():
|
|
64
|
+
try:
|
|
65
|
+
store = zarr.storage.ZipStore(store, mode=mode)
|
|
66
|
+
except zipfile.BadZipfile:
|
|
67
|
+
return None
|
|
68
|
+
else:
|
|
69
|
+
return None
|
|
70
|
+
return store
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _find_version(data: Mapping[str, Any], label: str) -> Optional[int]:
|
|
74
|
+
"""try finding version information in different places in `data`
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
data (dict):
|
|
78
|
+
A mapping that contains attribute information
|
|
79
|
+
label (str):
|
|
80
|
+
The label of the data that should be loaded
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
int: The format version or None if it could not be found
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def read_version(item) -> Optional[str]:
|
|
87
|
+
"""try reading attribute from a particular item"""
|
|
88
|
+
if hasattr(item, "attrs"):
|
|
89
|
+
return read_version(item.attrs)
|
|
90
|
+
elif "__version__" in item:
|
|
91
|
+
return item["__version__"] # type: ignore
|
|
92
|
+
elif "format_version" in item:
|
|
93
|
+
return item["format_version"] # type: ignore
|
|
94
|
+
elif "__attrs__" in item:
|
|
95
|
+
return read_version(item["__attrs__"])
|
|
96
|
+
elif "attributes" in item:
|
|
97
|
+
return read_version(item["attributes"])
|
|
98
|
+
else:
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
format_version = read_version(data)
|
|
102
|
+
if format_version is None and label in data:
|
|
103
|
+
format_version = read_version(data[label])
|
|
104
|
+
if format_version is None and "state" in data:
|
|
105
|
+
format_version = read_version(data["state"])
|
|
106
|
+
|
|
107
|
+
if isinstance(format_version, str):
|
|
108
|
+
return json.loads(format_version) # type: ignore
|
|
109
|
+
else:
|
|
110
|
+
return format_version
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def result_check_load_old_version(
|
|
114
|
+
path: Path, loc: str, *, model: Optional[ModelBase] = None
|
|
115
|
+
) -> Optional[Result]:
|
|
116
|
+
"""check whether the resource can be loaded with an older version of the package
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
path (str or :class:`~pathlib.Path`):
|
|
120
|
+
The path to the resource to be loaded
|
|
121
|
+
loc (str):
|
|
122
|
+
Label, key, or location of the item to be loaded
|
|
123
|
+
model (:class:`~modelrunner.model.ModelBase`, optional):
|
|
124
|
+
Optional model that was used to write this result
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
:class:`~modelrunner.result.Result`:
|
|
128
|
+
The loaded result or `None` if we cannot load it with the old versions
|
|
129
|
+
"""
|
|
130
|
+
label = "data" if loc is None else loc
|
|
131
|
+
format_version = None
|
|
132
|
+
# check for compatibility
|
|
133
|
+
fmt = guess_format(path)
|
|
134
|
+
if fmt == "json":
|
|
135
|
+
with open(path, mode="r") as fp:
|
|
136
|
+
format_version = _find_version(json.load(fp), label)
|
|
137
|
+
|
|
138
|
+
elif fmt == "yaml":
|
|
139
|
+
import yaml
|
|
140
|
+
|
|
141
|
+
with open(path, mode="r") as fp:
|
|
142
|
+
format_version = _find_version(yaml.safe_load(fp), label)
|
|
143
|
+
|
|
144
|
+
elif fmt == "hdf":
|
|
145
|
+
import h5py
|
|
146
|
+
|
|
147
|
+
with h5py.File(path, mode="r") as root:
|
|
148
|
+
format_version = _find_version(root, label)
|
|
149
|
+
|
|
150
|
+
elif fmt == "zarr":
|
|
151
|
+
import zarr
|
|
152
|
+
|
|
153
|
+
store = normalize_zarr_store(path, mode="r")
|
|
154
|
+
if store is None:
|
|
155
|
+
return None # could not open zarr file
|
|
156
|
+
with zarr.open_group(store, mode="r") as root:
|
|
157
|
+
format_version = _find_version(root, label)
|
|
158
|
+
if format_version is None and label != "data":
|
|
159
|
+
format_version = _find_version(root, "data")
|
|
160
|
+
if format_version is not None:
|
|
161
|
+
label = "data"
|
|
162
|
+
|
|
163
|
+
else:
|
|
164
|
+
return None
|
|
165
|
+
|
|
166
|
+
if format_version in {0, None}:
|
|
167
|
+
# load result written with format version 0
|
|
168
|
+
from .version0 import result_from_file_v0
|
|
169
|
+
|
|
170
|
+
return result_from_file_v0(path, model=model)
|
|
171
|
+
|
|
172
|
+
elif format_version == 1:
|
|
173
|
+
# load result written with format version 1
|
|
174
|
+
from .version1 import result_from_file_v1
|
|
175
|
+
|
|
176
|
+
return result_from_file_v1(path, label=label, model=model)
|
|
177
|
+
|
|
178
|
+
elif not isinstance(format_version, int):
|
|
179
|
+
raise RuntimeError(f"Unsupported format version {format_version}")
|
|
180
|
+
|
|
181
|
+
return None
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contains code necessary for loading results from format version 0
|
|
3
|
+
|
|
4
|
+
.. codeauthor:: David Zwicker <david.zwicker@ds.mpg.de>
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, Mapping, Optional
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
from ..model import ModelBase
|
|
16
|
+
from ..results import Result
|
|
17
|
+
from .triage import guess_format
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def read_hdf_data(node):
|
|
21
|
+
"""read structured data written with :func:`write_hdf_dataset` from an HDF node"""
|
|
22
|
+
import h5py
|
|
23
|
+
|
|
24
|
+
if isinstance(node, h5py.Dataset):
|
|
25
|
+
return np.array(node)
|
|
26
|
+
else:
|
|
27
|
+
# this must be a group
|
|
28
|
+
data = {key: json.loads(value) for key, value in node.attrs.items()}
|
|
29
|
+
for key, value in node.items():
|
|
30
|
+
data[key] = read_hdf_data(value)
|
|
31
|
+
return data
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _Result_from_simple_objects(
|
|
35
|
+
content: Mapping[str, Any], model: Optional[ModelBase] = None
|
|
36
|
+
) -> Result:
|
|
37
|
+
"""read result from simple object (like loaded from a JSON file) using version 0
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
content (dict):
|
|
41
|
+
Data from which the result is restored
|
|
42
|
+
model (:class:`ModelBase`):
|
|
43
|
+
Model associated with the result
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
:class:`Result`: the restored result
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
return Result.from_data(
|
|
50
|
+
model_data=content.get("model", {}),
|
|
51
|
+
result=content.get("result"),
|
|
52
|
+
model=model,
|
|
53
|
+
info=content.get("info", {}),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _Result_from_hdf(hdf_element, model: Optional[ModelBase] = None) -> Result:
|
|
58
|
+
"""old reader for backward compatible reading"""
|
|
59
|
+
model_data = {key: json.loads(value) for key, value in hdf_element.attrs.items()}
|
|
60
|
+
if "result" in hdf_element:
|
|
61
|
+
result = read_hdf_data(hdf_element["result"])
|
|
62
|
+
else:
|
|
63
|
+
result = model_data.pop("result")
|
|
64
|
+
# check for other nodes, which might not be read
|
|
65
|
+
|
|
66
|
+
info = model_data.pop("__info__") if "__info__" in model_data else {}
|
|
67
|
+
|
|
68
|
+
return Result.from_data(
|
|
69
|
+
model_data=model_data, result=result, model=model, info=info
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def result_from_file_v0(path: Path, **kwargs) -> Result:
|
|
74
|
+
"""load object from a file using format version 1
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
store (str or :class:`zarr.Store`):
|
|
78
|
+
Path or instance describing the storage, which is either a file path or
|
|
79
|
+
a :class:`zarr.Storage`.
|
|
80
|
+
"""
|
|
81
|
+
fmt = guess_format(path)
|
|
82
|
+
if fmt == "json":
|
|
83
|
+
with open(path, mode="r") as fp:
|
|
84
|
+
content = json.load(fp)
|
|
85
|
+
return _Result_from_simple_objects(content, **kwargs)
|
|
86
|
+
|
|
87
|
+
elif fmt == "yaml":
|
|
88
|
+
import yaml
|
|
89
|
+
|
|
90
|
+
with open(path, mode="r") as fp:
|
|
91
|
+
content = yaml.safe_load(fp)
|
|
92
|
+
return _Result_from_simple_objects(content, **kwargs)
|
|
93
|
+
|
|
94
|
+
elif fmt == "hdf":
|
|
95
|
+
import h5py
|
|
96
|
+
|
|
97
|
+
with h5py.File(path, mode="r") as root:
|
|
98
|
+
return _Result_from_hdf(root, **kwargs)
|
|
99
|
+
|
|
100
|
+
else:
|
|
101
|
+
raise NotImplementedError(f"Format `{fmt}` not implemented")
|