umfive 0.2.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.
Files changed (75) hide show
  1. umfive-0.2.0/.flake8 +29 -0
  2. umfive-0.2.0/.github/workflows/build-and-deploy-wheels-on-pypi.yml +101 -0
  3. umfive-0.2.0/.github/workflows/pytest.yml +57 -0
  4. umfive-0.2.0/.gitignore +48 -0
  5. umfive-0.2.0/.pre-commit-config.yaml +79 -0
  6. umfive-0.2.0/.pydocstyle.ini +10 -0
  7. umfive-0.2.0/LICENSE +21 -0
  8. umfive-0.2.0/MANIFEST.in +1 -0
  9. umfive-0.2.0/PKG-INFO +91 -0
  10. umfive-0.2.0/README.md +71 -0
  11. umfive-0.2.0/environment.yml +17 -0
  12. umfive-0.2.0/pyproject.toml +64 -0
  13. umfive-0.2.0/setup.cfg +4 -0
  14. umfive-0.2.0/setup.py +13 -0
  15. umfive-0.2.0/tests/data/aaaaoa.pmh8dec.pp +0 -0
  16. umfive-0.2.0/tests/data/cl_umfile +0 -0
  17. umfive-0.2.0/tests/data/cl_umfile_dump.txt +10041 -0
  18. umfive-0.2.0/tests/data/extra_data.pp +0 -0
  19. umfive-0.2.0/tests/data/extra_data_dump.txt +238 -0
  20. umfive-0.2.0/tests/data/test1.nc +0 -0
  21. umfive-0.2.0/tests/data/test2-viacf.nc +0 -0
  22. umfive-0.2.0/tests/data/test2.pp +0 -0
  23. umfive-0.2.0/tests/data/test2_dump.txt +653 -0
  24. umfive-0.2.0/tests/data/umfile.pp +0 -0
  25. umfive-0.2.0/tests/data/umfile_dump.txt +310 -0
  26. umfive-0.2.0/tests/data/wgdos_packed.pp +0 -0
  27. umfive-0.2.0/tests/data/wgdos_packed_dump.txt +511 -0
  28. umfive-0.2.0/tests/tests_core/test_DataVariable_api.py +126 -0
  29. umfive-0.2.0/tests/tests_core/test_File_api.py +311 -0
  30. umfive-0.2.0/tests/tests_core/test_filetype.py +33 -0
  31. umfive-0.2.0/tests/tests_core/test_packed_data_loading.py +79 -0
  32. umfive-0.2.0/tests/tests_core/test_pyfive_interoperability.py +40 -0
  33. umfive-0.2.0/tests/tests_core/test_scanner.py +88 -0
  34. umfive-0.2.0/tests/tests_core/test_stash_table.py +129 -0
  35. umfive-0.2.0/tests/tests_core/test_wgdos_extension.py +15 -0
  36. umfive-0.2.0/tests/tests_io/test_chunk_index.py +70 -0
  37. umfive-0.2.0/tests/tests_io/test_file.py +63 -0
  38. umfive-0.2.0/tests/tests_io/test_fileobj_reader.py +74 -0
  39. umfive-0.2.0/tests/tests_io/test_lazy_subselection.py +62 -0
  40. umfive-0.2.0/tests/tests_io/test_local_reader.py +47 -0
  41. umfive-0.2.0/tests/tests_io/test_parallel_reads.py +89 -0
  42. umfive-0.2.0/tests/tests_io/test_umdump.py +88 -0
  43. umfive-0.2.0/umfive/__init__.py +4 -0
  44. umfive-0.2.0/umfive/c_ext/wgdos_impl.h +295 -0
  45. umfive-0.2.0/umfive/c_ext/wgdos_module.c +246 -0
  46. umfive-0.2.0/umfive/constants.py +424 -0
  47. umfive-0.2.0/umfive/core/__init__.py +24 -0
  48. umfive-0.2.0/umfive/core/data.py +242 -0
  49. umfive-0.2.0/umfive/core/extra_data.py +184 -0
  50. umfive-0.2.0/umfive/core/filetype.py +213 -0
  51. umfive-0.2.0/umfive/core/header.py +143 -0
  52. umfive-0.2.0/umfive/core/interpret.py +150 -0
  53. umfive-0.2.0/umfive/core/models.py +104 -0
  54. umfive-0.2.0/umfive/core/scanner.py +324 -0
  55. umfive-0.2.0/umfive/core/variables.py +631 -0
  56. umfive-0.2.0/umfive/data/STASH_to_CF.txt +7046 -0
  57. umfive-0.2.0/umfive/data/field_codes.txt +1412 -0
  58. umfive-0.2.0/umfive/high_level.py +2929 -0
  59. umfive-0.2.0/umfive/inspect.py +158 -0
  60. umfive-0.2.0/umfive/io/__init__.py +5 -0
  61. umfive-0.2.0/umfive/io/bytereader.py +41 -0
  62. umfive-0.2.0/umfive/io/chunk_read.py +314 -0
  63. umfive-0.2.0/umfive/io/fileobj.py +77 -0
  64. umfive-0.2.0/umfive/io/local_posix_reader.py +129 -0
  65. umfive-0.2.0/umfive/io/mock_filesystem.py +18 -0
  66. umfive-0.2.0/umfive/stash.py +281 -0
  67. umfive-0.2.0/umfive/umdump.py +50 -0
  68. umfive-0.2.0/umfive/variable.py +1219 -0
  69. umfive-0.2.0/umfive/wgdos.py +35 -0
  70. umfive-0.2.0/umfive.egg-info/PKG-INFO +91 -0
  71. umfive-0.2.0/umfive.egg-info/SOURCES.txt +73 -0
  72. umfive-0.2.0/umfive.egg-info/dependency_links.txt +1 -0
  73. umfive-0.2.0/umfive.egg-info/entry_points.txt +2 -0
  74. umfive-0.2.0/umfive.egg-info/requires.txt +11 -0
  75. umfive-0.2.0/umfive.egg-info/top_level.txt +1 -0
umfive-0.2.0/.flake8 ADDED
@@ -0,0 +1,29 @@
1
+ # Configure the flake8 code style checker. Note this must be in INI style
2
+ # (see https://flake8.pycqa.org/en/latest/). To run the flake8 checker with
3
+ # this configuration, simply execute 'flake8' under the root of the repo.
4
+
5
+ [flake8]
6
+ # Ignores should include listing of pycodestyle ignores as in test_style.py.
7
+ # Note W503 is incompatible with PEP8 which we want to abide by
8
+ ignore =
9
+ W605,
10
+ E272,
11
+ E402,
12
+ E501,
13
+ E203,
14
+ W503
15
+ # Exclude these directories/files, otherwise check all *.py files
16
+ exclude =
17
+ .git,
18
+ __pycache__,
19
+ cfdm.egg-info,
20
+ docs/build/
21
+
22
+ # Ignore certain rules for some files (can't do this via comments in the files)
23
+ per-file-ignores =
24
+ # Ignore unused imports in __init__ modules, as they are there to provide
25
+ # the project namespace (decide not to use __all__ to contain these, as
26
+ # suggested in some flake8 discussions e.g. by the core maintainer at
27
+ # https://stackoverflow.com/questions/59167405/)
28
+ __init__.py: F401
29
+ */__init__.py: F401
@@ -0,0 +1,101 @@
1
+ name: Build and Publish Wheels
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ # use this for testing
7
+ push:
8
+ branches:
9
+ - main
10
+
11
+ permissions:
12
+ contents: read
13
+ id-token: write # required for PyPI trusted publishing
14
+
15
+ jobs:
16
+ build_wheels:
17
+ name: Build wheels on ${{ matrix.os }}
18
+ runs-on: ${{ matrix.os }}
19
+
20
+ strategy:
21
+ fail-fast: false
22
+ matrix:
23
+ os: [ubuntu-latest, macos-latest] # windows-latest fails
24
+
25
+ steps:
26
+ - name: Checkout source
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Set up Python
30
+ uses: actions/setup-python@v5
31
+ with:
32
+ python-version: "3.12"
33
+
34
+ - name: Build wheels
35
+ uses: pypa/cibuildwheel@v3.2.1
36
+ env:
37
+ # Build CPython 3.11-3.14
38
+ CIBW_BUILD: "cp311-* cp312-* cp313-* cp314-*"
39
+ CIBW_SKIP: "*-musllinux_* pp*"
40
+ # Run tests after build (optional)
41
+ # CIBW_TEST_COMMAND: "python -c \"import umfive; print('import ok')\""
42
+
43
+ - name: Upload wheel artifacts
44
+ uses: actions/upload-artifact@v4
45
+ with:
46
+ name: wheels-${{ matrix.os }}
47
+ path: ./wheelhouse/*.whl
48
+
49
+ build_sdist:
50
+ name: Build source distribution
51
+ runs-on: ubuntu-latest
52
+
53
+ steps:
54
+ - name: Checkout source
55
+ uses: actions/checkout@v4
56
+
57
+ - name: Set up Python
58
+ uses: actions/setup-python@v5
59
+ with:
60
+ python-version: "3.12"
61
+
62
+ - name: Install build backend
63
+ run: python -m pip install --upgrade build
64
+
65
+ - name: Build sdist
66
+ run: python -m build --sdist
67
+
68
+ - name: Upload sdist artifact
69
+ uses: actions/upload-artifact@v4
70
+ with:
71
+ name: sdist
72
+ path: dist/*.tar.gz
73
+
74
+ publish:
75
+ name: Publish to PyPI
76
+ needs: [build_wheels, build_sdist]
77
+ runs-on: ubuntu-latest
78
+ # publish only on version tags like v0.1.0
79
+ if: startsWith(github.ref, 'refs/tags')
80
+ environment:
81
+ name: pypi
82
+ url: https://pypi.org/project/umfive/
83
+ permissions:
84
+ id-token: write
85
+
86
+ steps:
87
+ - name: Download all artifacts
88
+ uses: actions/download-artifact@v4
89
+ with:
90
+ path: distfiles
91
+
92
+ - name: Flatten artifacts
93
+ run: |
94
+ mkdir upload
95
+ find distfiles -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} upload/ \;
96
+ ls -la upload
97
+
98
+ - name: Publish to PyPI
99
+ uses: pypa/gh-action-pypi-publish@release/v1
100
+ with:
101
+ packages-dir: upload
@@ -0,0 +1,57 @@
1
+ # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2
+ # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3
+
4
+ name: Umfive Test
5
+
6
+ on:
7
+ push:
8
+ branches:
9
+ - main
10
+ pull_request:
11
+ branches:
12
+ - main
13
+ schedule:
14
+ - cron: '0 0 * * *' # nightly
15
+
16
+ # Required shell entrypoint to have properly configured bash shell
17
+ defaults:
18
+ run:
19
+ shell: bash -l {0}
20
+
21
+ jobs:
22
+ build:
23
+
24
+ name: Test Python ${{ matrix.python-version }}
25
+ runs-on: ubuntu-latest
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
30
+
31
+ steps:
32
+ - uses: actions/checkout@v6
33
+ with:
34
+ fetch-depth: 0
35
+ - uses: conda-incubator/setup-miniconda@v3
36
+ with:
37
+ activate-environment: umfive
38
+ environment-file: environment.yml
39
+ python-version: ${{ matrix.python-version }}
40
+ miniforge-version: "latest"
41
+ use-mamba: true
42
+ - name: Install Umfive Test Mode
43
+ run: |
44
+ mamba install -c conda-forge pip
45
+ pip install -e .[test]
46
+ - name: Run pip check
47
+ run: pip check
48
+ # - name: Run pre-commit with mypy
49
+ # run: |
50
+ # pre-commit install
51
+ # pre-commit run -a
52
+ - name: Check environment contents
53
+ run: |
54
+ conda list
55
+ pip list
56
+ - name: Test with pytest
57
+ run: pytest -n 2
@@ -0,0 +1,48 @@
1
+ # macOS
2
+ .DS_Store
3
+
4
+ # Python bytecode/cache
5
+ __pycache__/
6
+ *.py[cod]
7
+ *.pyo
8
+
9
+ # Packaging/build artifacts
10
+ build/
11
+ dist/
12
+ *.egg-info/
13
+ .eggs/
14
+
15
+ # Virtual/env files
16
+ .venv/
17
+ venv/
18
+ env/
19
+ .python-version
20
+
21
+ # Test/cache/tool outputs
22
+ .pytest_cache/
23
+ .mypy_cache/
24
+ .ruff_cache/
25
+ .coverage
26
+ .coverage.*
27
+ htmlcov/
28
+
29
+ # Notebook/checkpoint noise
30
+ .ipynb_checkpoints/
31
+
32
+ # IDE/editor
33
+ .vscode/settings.json
34
+
35
+ # Local logs/temp
36
+ *.log
37
+ *.tmp
38
+
39
+ # Do not commit original source snapshot
40
+ orig/
41
+
42
+ # SO object
43
+ umfive/_wgdos.cpython-314-x86_64-linux-gnu.so
44
+ umfive/_wgdos.cpython-312-darwin.so
45
+ umfive/_wgdos.cpython*
46
+
47
+ # Local large test data (do not commit)
48
+ tests/data/dk922*
@@ -0,0 +1,79 @@
1
+ # Configure pre-commit hooks to check for Python code validity, formatting and
2
+ # style issues and prompt for these to be corrected before committing.
3
+
4
+ # Excludes for *all* pre-commit hooks as listed below:
5
+ # (these are documentation files, either old ones or aut-generated ones)
6
+ exclude: docs\/1\..*\d\/|docs\/_downloads\/|docs\/.*\/tutorial\.py
7
+
8
+ repos:
9
+
10
+ # Use specific format-enforcing pre-commit hooks from the core library
11
+ # with the default configuration (see pre-commit.com for documentation)
12
+ - repo: https://github.com/pre-commit/pre-commit-hooks
13
+ rev: v4.6.0
14
+ hooks:
15
+ - id: check-ast
16
+ - id: debug-statements
17
+ - id: end-of-file-fixer
18
+ types: [python]
19
+ - id: trailing-whitespace
20
+ types: [python]
21
+
22
+ # Also validate against 'black' for unambiguous Python formatting
23
+ # (see https://black.readthedocs.io/en/stable/ for documentation and see
24
+ # the cfdm pyproject.toml file for our custom black configuration)
25
+ - repo: https://github.com/ambv/black
26
+ rev: 24.4.2
27
+ hooks:
28
+ - id: black
29
+ language_version: python3
30
+
31
+ # Also format docstrings in a consistent way, on top of 'black' requirements
32
+ # with the aim to auto-correct towards the Google docstring format (see
33
+ # https://google.github.io/styleguide/pyguide.html#381-docstrings) as much
34
+ # as possible (see https://github.com/myint/docformatter for docs, with
35
+ # configuration as below)
36
+ # - repo: https://github.com/myint/docformatter
37
+ - repo: https://github.com/PyCQA/docformatter
38
+ rev: v1.7.6
39
+ hooks:
40
+ - id: docformatter
41
+ # These arguments act as the configuration for docformatter. They:
42
+ # * make docformatter auto-format in-place if not compliant;
43
+ # * ensure there is a blank line after the final non-empty line;
44
+ # * wraps both summary and description at 72 characters (the latter
45
+ # by default).
46
+ args: [--in-place, --blank, --wrap-summaries=72]
47
+
48
+ # Check the docstrings conforms to Google docstring format as much as can
49
+ # be detected by the 'pydocstyle' checker
50
+ # (see http://www.pydocstyle.org/en/stable/index.html for
51
+ # docs and see the cfdm .pydocstyle.ini file for our custom configuration)
52
+ - repo: https://github.com/PyCQA/pydocstyle
53
+ rev: 6.3.0
54
+ hooks:
55
+ - id: pydocstyle
56
+
57
+ # Additionally validate againt flake8 for other Python style enforcement
58
+ # (see https://flake8.pycqa.org/en/latest/ for documentation and see
59
+ # the cfdm .flake8 file for our custom flake8 configuration)
60
+ - repo: https://github.com/PyCQA/flake8
61
+ rev: 7.1.0
62
+ hooks:
63
+ - id: flake8
64
+
65
+ # Apply the 'isort' tool to sort Python import statements systematically
66
+ # (see https://pycqa.github.io/isort/ for documentation). It is fully
67
+ # compatible with 'black' with the lines set to ensure so in the repo's
68
+ # pyproject.toml. Other than that and the below, no extra config is required.
69
+ - repo: https://github.com/PyCQA/isort
70
+ rev: 5.13.2
71
+ hooks:
72
+ - id: isort
73
+ name: isort (python)
74
+ - id: isort
75
+ name: isort (cython)
76
+ types: [cython]
77
+ - id: isort
78
+ name: isort (pyi)
79
+ types: [pyi]
@@ -0,0 +1,10 @@
1
+ [pydocstyle]
2
+ inherit = false
3
+ match = .*\.py
4
+ convention = google
5
+
6
+ # Don't require a docstring for every module and package (i.e. in any __init__)
7
+ #
8
+ # Ignore D415: First line should end with a period, question mark, or
9
+ # exclamation point
10
+ add-ignore=D100,D104,D105,D107,D415
umfive-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 NCAS CMS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ recursive-exclude doc *
umfive-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,91 @@
1
+ Metadata-Version: 2.4
2
+ Name: umfive
3
+ Version: 0.2.0
4
+ Summary: PP/Fields reader with pyfive-style high-level API
5
+ Author: David Hassell, Alan Iwi, Bryan Lawrence, Valeriu Predoi - package
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: cftime
11
+ Requires-Dist: numpy>=1.24
12
+ Requires-Dist: pyfive>=1.1.2
13
+ Provides-Extra: io
14
+ Requires-Dist: fsspec>=2024.3.0; extra == "io"
15
+ Provides-Extra: test
16
+ Requires-Dist: pytest>=8; extra == "test"
17
+ Requires-Dist: pytest-cov>=5; extra == "test"
18
+ Requires-Dist: pytest-xdist; extra == "test"
19
+ Dynamic: license-file
20
+
21
+ # umfive
22
+
23
+ A PP and Fields file reader that mimics relevant parts of the `pyfive` high-level API,
24
+ with support for lazy metadata loading and parallel data loading when necessary.
25
+
26
+ This is NOT an alternative to pyfive, it is a package which makes pp and fields files
27
+ look like and taste ("quack like") chunked HDF5 files written by a NetCDF library.
28
+
29
+ ## API Contract (umfive vs pyfive)
30
+
31
+ `umfive` is designed to be **pyfive-compatible** as far as likely users of pyfive
32
+ would need such compatability. That is, it produces a chunk index (for kerchunk)
33
+ if you really want that, and it supports all the information needed by CF/CFDM
34
+ workflows to make pp-data as CF-compliant as possible.
35
+
36
+
37
+ For the canonical pyfive interface, see the pyfive docs:
38
+
39
+ - https://pyfive.readthedocs.io/
40
+
41
+ ### What maps directly to pyfive
42
+
43
+ - `umfive.File` is registered as a `umfive.File` virtual type (when `umfive` is installed).
44
+ - `umfive.Variable` is registered as a `umfive.Dataset` virtual type.
45
+ - File/root-level members expected by pyfive-style callers are present:
46
+ - `attrs`, `groups`, `variables`, `dimensions`, `name`, `path`, `parent`
47
+ - Mapping-style access works:
48
+ - `f["var"]`, iteration over variables, `items()`, `len(f)`
49
+ - Dataset-like variable members needed by downstream consumers are present:
50
+ - `shape`, `dtype`, `ndim`, `size`, `attrs`, `chunks`/`chunk_shape`, `file`, `parent`
51
+ - slicing/indexing via `__getitem__` (for example `f["var"][:]`)
52
+ - `read_direct`, `astype(...)`, `iter_chunks(...)`
53
+
54
+ Like `pyfive`, `umfive` is read-only:
55
+
56
+ - `File(..., mode="r")` is supported; write/update modes are not.
57
+
58
+ ### Important differences from pyfive
59
+
60
+
61
+ - No nested groups in PP/Fields model:
62
+ - `f["group/var"]` is not supported.
63
+ - `groups` exists for compatibility but is empty for current PP/Fields inputs.
64
+ - `get_lazy_view(...)` fallback behavior:
65
+ - `pyfive`-style API entry exists, but returns the normal variable view with an info log.
66
+ - Some Dataset properties are intentionally placeholders (`None`) because they are
67
+ not meaningful for PP/Fields records:
68
+ - `compression`, `compression_opts`, `shuffle`, `fletcher32`, `maxshape`,
69
+ `fillvalue`, `dims`, `scaleoffset`.
70
+ - Compatibility metadata is synthesized for CF/cfdm bridging:
71
+ - dimension-scale datasets and `DIMENSION_LIST` are created where needed.
72
+ - rotated-grid helper variables (for example `latitude`, `longitude`,
73
+ `rotated_latitude_longitude`) may be exposed when implied by UM headers.
74
+ - umfive-specific extension API:
75
+ - `File.set_parallelism(thread_count=..., cat_range_allowed=...)`
76
+ is provided by `umfive` and is not part of `pyfive`.
77
+
78
+
79
+ ### Practical expectation
80
+
81
+ If your code treats `umfive.File` as a `pyfive`-like read object,
82
+ common analysis workflows should work, including chunk-level access (PP records
83
+ are treated as chunks).
84
+
85
+ ## Authorship
86
+
87
+ Key authors of this package are:
88
+
89
+ - David Hassell (@davidhassell)
90
+ - Alan Iwi (@alaniwi)
91
+ - Bryan Lawrence (@bnlawrence)
umfive-0.2.0/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # umfive
2
+
3
+ A PP and Fields file reader that mimics relevant parts of the `pyfive` high-level API,
4
+ with support for lazy metadata loading and parallel data loading when necessary.
5
+
6
+ This is NOT an alternative to pyfive, it is a package which makes pp and fields files
7
+ look like and taste ("quack like") chunked HDF5 files written by a NetCDF library.
8
+
9
+ ## API Contract (umfive vs pyfive)
10
+
11
+ `umfive` is designed to be **pyfive-compatible** as far as likely users of pyfive
12
+ would need such compatability. That is, it produces a chunk index (for kerchunk)
13
+ if you really want that, and it supports all the information needed by CF/CFDM
14
+ workflows to make pp-data as CF-compliant as possible.
15
+
16
+
17
+ For the canonical pyfive interface, see the pyfive docs:
18
+
19
+ - https://pyfive.readthedocs.io/
20
+
21
+ ### What maps directly to pyfive
22
+
23
+ - `umfive.File` is registered as a `umfive.File` virtual type (when `umfive` is installed).
24
+ - `umfive.Variable` is registered as a `umfive.Dataset` virtual type.
25
+ - File/root-level members expected by pyfive-style callers are present:
26
+ - `attrs`, `groups`, `variables`, `dimensions`, `name`, `path`, `parent`
27
+ - Mapping-style access works:
28
+ - `f["var"]`, iteration over variables, `items()`, `len(f)`
29
+ - Dataset-like variable members needed by downstream consumers are present:
30
+ - `shape`, `dtype`, `ndim`, `size`, `attrs`, `chunks`/`chunk_shape`, `file`, `parent`
31
+ - slicing/indexing via `__getitem__` (for example `f["var"][:]`)
32
+ - `read_direct`, `astype(...)`, `iter_chunks(...)`
33
+
34
+ Like `pyfive`, `umfive` is read-only:
35
+
36
+ - `File(..., mode="r")` is supported; write/update modes are not.
37
+
38
+ ### Important differences from pyfive
39
+
40
+
41
+ - No nested groups in PP/Fields model:
42
+ - `f["group/var"]` is not supported.
43
+ - `groups` exists for compatibility but is empty for current PP/Fields inputs.
44
+ - `get_lazy_view(...)` fallback behavior:
45
+ - `pyfive`-style API entry exists, but returns the normal variable view with an info log.
46
+ - Some Dataset properties are intentionally placeholders (`None`) because they are
47
+ not meaningful for PP/Fields records:
48
+ - `compression`, `compression_opts`, `shuffle`, `fletcher32`, `maxshape`,
49
+ `fillvalue`, `dims`, `scaleoffset`.
50
+ - Compatibility metadata is synthesized for CF/cfdm bridging:
51
+ - dimension-scale datasets and `DIMENSION_LIST` are created where needed.
52
+ - rotated-grid helper variables (for example `latitude`, `longitude`,
53
+ `rotated_latitude_longitude`) may be exposed when implied by UM headers.
54
+ - umfive-specific extension API:
55
+ - `File.set_parallelism(thread_count=..., cat_range_allowed=...)`
56
+ is provided by `umfive` and is not part of `pyfive`.
57
+
58
+
59
+ ### Practical expectation
60
+
61
+ If your code treats `umfive.File` as a `pyfive`-like read object,
62
+ common analysis workflows should work, including chunk-level access (PP records
63
+ are treated as chunks).
64
+
65
+ ## Authorship
66
+
67
+ Key authors of this package are:
68
+
69
+ - David Hassell (@davidhassell)
70
+ - Alan Iwi (@alaniwi)
71
+ - Bryan Lawrence (@bnlawrence)
@@ -0,0 +1,17 @@
1
+ name: umfive-dev
2
+ channels:
3
+ - conda-forge
4
+ - nodefaults # stay away from Anaconda like the plague
5
+
6
+ dependencies:
7
+ - python >=3.11
8
+ - numpy >=1.24
9
+ - fsspec >=2024.3.0
10
+ - pyfive >=1.1.2
11
+ - pytest >=8
12
+ - pytest-xdist
13
+ - udunits2 # cf-python needs it
14
+ - pip
15
+ - pip:
16
+ - cf-python @ git+https://github.com/davidhassell/cf-python.git@kerchunk-read
17
+ - cfdm @ git+https://github.com/davidhassell/cfdm.git@pyfive-netcdf
@@ -0,0 +1,64 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools>=80",
4
+ "setuptools_scm>=8",
5
+ "numpy>=1.24",
6
+ ]
7
+ build-backend = "setuptools.build_meta"
8
+
9
+ [project]
10
+ name = "umfive"
11
+ version = "0.2.0"
12
+ description = "PP/Fields reader with pyfive-style high-level API"
13
+ license = {text = "MIT"}
14
+ readme = "README.md"
15
+ requires-python = ">=3.11"
16
+ authors = [
17
+ {name = "David Hassell"},
18
+ {name = "Alan Iwi"},
19
+ {name = "Bryan Lawrence"},
20
+ {name = "Valeriu Predoi - package"},
21
+ ]
22
+ dependencies = [
23
+ "cftime",
24
+ "numpy>=1.24",
25
+ "pyfive>=1.1.2",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ io = ["fsspec>=2024.3.0"]
30
+ test = [
31
+ "pytest>=8",
32
+ "pytest-cov>=5",
33
+ "pytest-xdist",
34
+ ]
35
+
36
+ [project.scripts]
37
+ ppdump = "umfive.ppdump:main"
38
+
39
+ [tool.setuptools]
40
+ include-package-data = true
41
+ license-files = ["LICENSE"]
42
+
43
+ [tool.setuptools.packages.find]
44
+ include = ["umfive*"]
45
+
46
+ [tool.setuptools.package-data]
47
+ umfive = ["data/*.txt"]
48
+
49
+ [tool.pytest.ini_options]
50
+ testpaths = ["tests"]
51
+
52
+ [tool.isort]
53
+ profile = "black"
54
+ # ... and since we set this against the black default line length:
55
+ line_length=79
56
+ # Prevent isort from auto-formatting '__init__.py' file imports because
57
+ # they require a specific non-aphabetical (etc.) ordering else they will
58
+ # cause errors due to bad or circular importing across the modules.
59
+ extend_skip_glob = [
60
+ "**/__init__.py",
61
+ ]
62
+
63
+ [tool.black]
64
+ line-length = 79
umfive-0.2.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
umfive-0.2.0/setup.py ADDED
@@ -0,0 +1,13 @@
1
+ import numpy as np
2
+ from setuptools import Extension, setup
3
+
4
+ print(np.get_include())
5
+ setup(
6
+ ext_modules=[
7
+ Extension(
8
+ "umfive._wgdos",
9
+ sources=["umfive/c_ext/wgdos_module.c"],
10
+ include_dirs=[np.get_include(), "umfive/c_ext"],
11
+ )
12
+ ]
13
+ )
Binary file