anu-ctlab-io 1.0.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.
- anu_ctlab_io-1.0.0/.github/workflows/ci.yml +40 -0
- anu_ctlab_io-1.0.0/.github/workflows/publish.yml +40 -0
- anu_ctlab_io-1.0.0/.gitignore +12 -0
- anu_ctlab_io-1.0.0/.pre-commit-config.yaml +57 -0
- anu_ctlab_io-1.0.0/.prettierignore +1 -0
- anu_ctlab_io-1.0.0/.python-version +1 -0
- anu_ctlab_io-1.0.0/CHANGELOG.md +65 -0
- anu_ctlab_io-1.0.0/LICENSE.md +9 -0
- anu_ctlab_io-1.0.0/PKG-INFO +44 -0
- anu_ctlab_io-1.0.0/README.rst +1 -0
- anu_ctlab_io-1.0.0/_typos.toml +6 -0
- anu_ctlab_io-1.0.0/docs/conf.py +30 -0
- anu_ctlab_io-1.0.0/docs/index.rst +15 -0
- anu_ctlab_io-1.0.0/docs/introduction.rst +19 -0
- anu_ctlab_io-1.0.0/justfile +7 -0
- anu_ctlab_io-1.0.0/pyproject.toml +88 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/__init__.py +22 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/_dataset.py +189 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/_datatype.py +130 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/_parse_history.py +75 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/_version.py +3 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/_voxel_properties.py +57 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/netcdf/__init__.py +89 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/py.typed +0 -0
- anu_ctlab_io-1.0.0/src/anu_ctlab_io/zarr/__init__.py +52 -0
- anu_ctlab_io-1.0.0/tests/data/README.md +18 -0
- anu_ctlab_io-1.0.0/tests/data/generate_test_data_zarr.py +49 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes.zarr/c.1.0.0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes.zarr/c.2.0.0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes.zarr/c.3.0.0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes.zarr/zarr.json +83 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes_SS_nc/block00000000.nc +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes_SS_nc/block00000001.nc +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes_SS_nc/block00000002.nc +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes_SS_nc/block00000003.nc +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes_SS_nc/block00000004.nc +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoHiRes_SS_nc/block00000005.nc +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes.zarr/c.0.0.0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes.zarr/c.1.0.0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes.zarr/c.2.0.0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes.zarr/c.3.0.0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes.zarr/zarr.json +83 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes_SS.nc +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes_SS_AM.zarr/0/c/0/0/0 +0 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes_SS_AM.zarr/0/zarr.json +78 -0
- anu_ctlab_io-1.0.0/tests/data/tomoLoRes_SS_AM.zarr/zarr.json +171 -0
- anu_ctlab_io-1.0.0/tests/schema/anu_ctlab_zarr_1_0_example.json +20 -0
- anu_ctlab_io-1.0.0/tests/test_datatype.py +19 -0
- anu_ctlab_io-1.0.0/tests/test_manual_read.py +78 -0
- anu_ctlab_io-1.0.0/tests/test_netcdf.py +53 -0
- anu_ctlab_io-1.0.0/tests/test_parse_history.py +77 -0
- anu_ctlab_io-1.0.0/tests/test_voxel_unit.py +12 -0
- anu_ctlab_io-1.0.0/tests/test_zarr.py +41 -0
- anu_ctlab_io-1.0.0/tox.ini +26 -0
- anu_ctlab_io-1.0.0/uv.lock +1008 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
name: test
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- name: checkout
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
- name: install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v3
|
|
24
|
+
with:
|
|
25
|
+
version: "0.6.3"
|
|
26
|
+
- name: run tests
|
|
27
|
+
run: uvx --with tox-uv tox
|
|
28
|
+
lint:
|
|
29
|
+
name: lint
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- name: checkout
|
|
33
|
+
uses: actions/checkout@v4
|
|
34
|
+
- name: install uv
|
|
35
|
+
uses: astral-sh/setup-uv@v3
|
|
36
|
+
with:
|
|
37
|
+
version: "0.6.3"
|
|
38
|
+
- name: run pre-commit checks
|
|
39
|
+
run: |
|
|
40
|
+
uv run pre-commit run --all-files --show-diff-on-failure
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v[0-9]+.[0-9]+.[0-9]+"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v5
|
|
13
|
+
- name: Install UV
|
|
14
|
+
uses: astral-sh/setup-uv@v6
|
|
15
|
+
with:
|
|
16
|
+
version: "0.6.3"
|
|
17
|
+
- name: Build source distribution
|
|
18
|
+
run: uv build
|
|
19
|
+
- uses: actions/upload-artifact@v4
|
|
20
|
+
with:
|
|
21
|
+
name: pypi-files-sdist
|
|
22
|
+
path: dist
|
|
23
|
+
|
|
24
|
+
pypi-publish:
|
|
25
|
+
name: "build and publish release"
|
|
26
|
+
needs: [build]
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
environment:
|
|
29
|
+
name: pypi
|
|
30
|
+
permissions:
|
|
31
|
+
id-token: write
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/download-artifact@v5
|
|
34
|
+
with:
|
|
35
|
+
pattern: pypi-files-*
|
|
36
|
+
merge-multiple: true
|
|
37
|
+
path: dist/
|
|
38
|
+
- run: ls -lh dist/
|
|
39
|
+
- name: Publish package distributions to PyPI
|
|
40
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
ci:
|
|
2
|
+
autoupdate_commit_msg: "chore: update pre-commit hooks"
|
|
3
|
+
|
|
4
|
+
repos:
|
|
5
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
6
|
+
rev: v5.0.0
|
|
7
|
+
hooks:
|
|
8
|
+
- id: check-yaml
|
|
9
|
+
- id: check-toml
|
|
10
|
+
- id: end-of-file-fixer
|
|
11
|
+
exclude: "^tests/(data|schema)/"
|
|
12
|
+
- id: trailing-whitespace
|
|
13
|
+
- repo: https://github.com/pre-commit/mirrors-prettier
|
|
14
|
+
rev: "v3.1.0"
|
|
15
|
+
hooks:
|
|
16
|
+
- id: prettier
|
|
17
|
+
exclude: "^tests/(data|schema)/"
|
|
18
|
+
types_or: [yaml, markdown, html, css, scss, javascript, json]
|
|
19
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
20
|
+
# Ruff version.
|
|
21
|
+
rev: v0.9.2
|
|
22
|
+
hooks:
|
|
23
|
+
# Run the linter.
|
|
24
|
+
- id: ruff
|
|
25
|
+
args: ["--fix", "--show-fixes"]
|
|
26
|
+
# Run the formatter.
|
|
27
|
+
- id: ruff-format
|
|
28
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
29
|
+
rev: v1.15.0
|
|
30
|
+
hooks:
|
|
31
|
+
- id: mypy
|
|
32
|
+
pass_filenames: false
|
|
33
|
+
always_run: true
|
|
34
|
+
args: [src]
|
|
35
|
+
additional_dependencies:
|
|
36
|
+
- pandas-stubs
|
|
37
|
+
- numpy
|
|
38
|
+
- xarray
|
|
39
|
+
- matplotlib
|
|
40
|
+
- lark
|
|
41
|
+
- zarr
|
|
42
|
+
- dask
|
|
43
|
+
- deprecation
|
|
44
|
+
- repo: https://github.com/adamchainz/blacken-docs
|
|
45
|
+
rev: "v1.12.1"
|
|
46
|
+
hooks:
|
|
47
|
+
- id: blacken-docs
|
|
48
|
+
additional_dependencies:
|
|
49
|
+
- black==22.12.0
|
|
50
|
+
- repo: https://github.com/crate-ci/typos
|
|
51
|
+
rev: v1.36.2
|
|
52
|
+
hooks:
|
|
53
|
+
- id: typos
|
|
54
|
+
- repo: https://github.com/rbubley/mirrors-prettier
|
|
55
|
+
rev: "v3.6.2"
|
|
56
|
+
hooks:
|
|
57
|
+
- id: prettier
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tests/data/*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0] - 2025-09-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Github CI for build and release to PyPI
|
|
15
|
+
- Documentation using Sphinx
|
|
16
|
+
- justfile to build docs and run tests
|
|
17
|
+
- Support for units to `VoxelUnit` to match MANGO support: `angstrom`, `centimeters`, `voxels`
|
|
18
|
+
- Tests for `DataType.from_basename`
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Replace README.md with README.rst
|
|
23
|
+
- Improve typehinting
|
|
24
|
+
- Privatise unintentionally public modules: `dataset`, `datatype`, `parse_history`, `version`, `voxel_properties`
|
|
25
|
+
- Privatise objects not intended to be public:
|
|
26
|
+
- `_datatype.DataTypeProperties`
|
|
27
|
+
- `_datatype.DATATYPE_PROPERTIES`
|
|
28
|
+
- `netcdf._read_netcdf`
|
|
29
|
+
- Rename `_datatype.storage_dtypes` to `_datatype.StorageDType` (PEP8)
|
|
30
|
+
- Capitalise `DataType` members (PEP8)
|
|
31
|
+
- Capitalise `VoxelUnit` members (PEP8)
|
|
32
|
+
- Move zarr and netcdf dependencies to extras
|
|
33
|
+
- Improve `tox` testing configuration, including testing with and without extras
|
|
34
|
+
- Update changelog formatting to better match the Keep a Changelog format.
|
|
35
|
+
|
|
36
|
+
### Removed
|
|
37
|
+
|
|
38
|
+
- Remove features which were deprecated in 0.2.0:
|
|
39
|
+
- NetCDFDataset
|
|
40
|
+
- Xarray dataset support
|
|
41
|
+
- Remove `UnknownVoxelUnitException`
|
|
42
|
+
- Remove `DatasetFormatException`
|
|
43
|
+
|
|
44
|
+
## [0.2.0] - 2025-09-07
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- Support for reading ANU CTLab Zarr files
|
|
49
|
+
- Direct access to the data loaded as Dask arrays
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- Interface changed to use the Dataset class for both Zarr and NetCDF files
|
|
54
|
+
- Xarray output deprecated (to be removed in 1.0.0)
|
|
55
|
+
|
|
56
|
+
## [0.0.1]
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- Support for reading ANU CTLab NetCDF files
|
|
61
|
+
- Support for outputting Xarray data
|
|
62
|
+
|
|
63
|
+
[unreleased]: https://github.com/MaterialsPhysicsANU/anu_ctlab_io/compare/v1.0.0...HEAD
|
|
64
|
+
[1.0.0]: https://github.com/MaterialsPhysicsANU/anu_ctlab_io/releases/tag/v1.0.0
|
|
65
|
+
[0.2.0]: https://github.com/MaterialsPhysicsANU/anu_ctlab_io/releases/tag/v0.2.0
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, the Australian National University (ANU)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: anu-ctlab-io
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: python I/O for the ANU CTLab array storage format(s)
|
|
5
|
+
Project-URL: Repository, https://github.com/MaterialsPhysicsANU/anu_ctlab_io
|
|
6
|
+
Project-URL: Issues, https://github.com/MaterialsPhysicsANU/anu_ctlab_io/issues
|
|
7
|
+
Project-URL: Changelog, https://github.com/MaterialsPhysicsANU/anu_ctlab_io/main/CHANGELOG.md
|
|
8
|
+
Author-email: Owen Dowley <owen.dowley@anu.edu.au>, Bogdan Maviichuk <bogdan.maviichuk@anu.edu.au>, Lachlan Deakin <lachlan.deakin@anu.edu.au>
|
|
9
|
+
Maintainer-email: Owen Dowley <owen.dowley@anu.edu.au>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE.md
|
|
12
|
+
Requires-Python: >=3.12
|
|
13
|
+
Requires-Dist: dask[array]>=2025.2.0
|
|
14
|
+
Requires-Dist: deprecation>=2.1.0
|
|
15
|
+
Requires-Dist: dictdiffer>=0.9.0
|
|
16
|
+
Requires-Dist: lark>=1.2.2
|
|
17
|
+
Requires-Dist: numpy>=2.2.3
|
|
18
|
+
Requires-Dist: xarray>=2025.1.2
|
|
19
|
+
Provides-Extra: netcdf
|
|
20
|
+
Requires-Dist: netcdf4>=1.7.2; extra == 'netcdf'
|
|
21
|
+
Requires-Dist: scipy>=1.16.1; extra == 'netcdf'
|
|
22
|
+
Provides-Extra: zarr
|
|
23
|
+
Requires-Dist: zarr>=3.1.1; extra == 'zarr'
|
|
24
|
+
Description-Content-Type: text/x-rst
|
|
25
|
+
|
|
26
|
+
Introduction
|
|
27
|
+
------------
|
|
28
|
+
python I/O for the ANU CTLab array storage format(s).
|
|
29
|
+
|
|
30
|
+
This package loads data provided in the specific NetCDF and Zarr formats produced by the ANU CTLab.
|
|
31
|
+
The intention is that the consumers of the data we produce should be able to load that data and then
|
|
32
|
+
work with that directly in standard scientific python workflows, rather than needing to use the
|
|
33
|
+
pre-existing MANGO toolchain.
|
|
34
|
+
|
|
35
|
+
Examples
|
|
36
|
+
--------
|
|
37
|
+
.. code-block :: python3
|
|
38
|
+
|
|
39
|
+
import anu_ctlab_io
|
|
40
|
+
from dask_image import ndfilters
|
|
41
|
+
|
|
42
|
+
dataset = anu_ctlab_io.Dataset.from_path(<path-to-your-data>)
|
|
43
|
+
blurred = ndfilters.gaussian_filter(dataset.data, sigma=3)
|
|
44
|
+
print(blurred.mean().compute())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
docs/introduction.rst
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
|
|
3
|
+
# Sphinx configuration for anu-ctlab-io docs
|
|
4
|
+
project = "anu-ctlab-io"
|
|
5
|
+
copyright = "2025, the Australian National University (ANU)"
|
|
6
|
+
author = "Materials Physics, ANU" # Can only be a single author, so can't match pyproject.toml. Find actual authors there.
|
|
7
|
+
release = importlib.metadata.version("anu_ctlab_io")
|
|
8
|
+
extensions = [
|
|
9
|
+
# 'myst_parser',
|
|
10
|
+
"sphinx_rtd_theme",
|
|
11
|
+
"sphinx.ext.autodoc",
|
|
12
|
+
# "sphinx.ext.napoleon",
|
|
13
|
+
"sphinx.ext.autosummary",
|
|
14
|
+
"sphinx_autodoc_typehints",
|
|
15
|
+
]
|
|
16
|
+
html_theme = "sphinx_rtd_theme"
|
|
17
|
+
autosummary_generate = True
|
|
18
|
+
source_suffix = {
|
|
19
|
+
# '.md': 'markdown',
|
|
20
|
+
".rst": "restructuredtext",
|
|
21
|
+
}
|
|
22
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
23
|
+
autodoc_default_options = {
|
|
24
|
+
"members": True,
|
|
25
|
+
"undoc-members": True,
|
|
26
|
+
"member-order": "bysource",
|
|
27
|
+
"show-inheritance": True,
|
|
28
|
+
"inherited-members": True,
|
|
29
|
+
"special-members": "__init__",
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
anu_ctlab_io package
|
|
2
|
+
====================
|
|
3
|
+
.. toctree::
|
|
4
|
+
introduction
|
|
5
|
+
|
|
6
|
+
.. .. automodule:: anu_ctlab_io
|
|
7
|
+
.. :members:
|
|
8
|
+
.. :undoc-members:
|
|
9
|
+
.. :show-inheritance:
|
|
10
|
+
|
|
11
|
+
.. autosummary::
|
|
12
|
+
:toctree: _autosummary
|
|
13
|
+
:recursive:
|
|
14
|
+
|
|
15
|
+
anu_ctlab_io
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Introduction
|
|
2
|
+
------------
|
|
3
|
+
python I/O for the ANU CTLab array storage format(s).
|
|
4
|
+
|
|
5
|
+
This package loads data provided in the specific NetCDF and Zarr formats produced by the ANU CTLab.
|
|
6
|
+
The intention is that the consumers of the data we produce should be able to load that data and then
|
|
7
|
+
work with that directly in standard scientific python workflows, rather than needing to use the
|
|
8
|
+
pre-existing MANGO toolchain.
|
|
9
|
+
|
|
10
|
+
Examples
|
|
11
|
+
--------
|
|
12
|
+
.. code-block :: python3
|
|
13
|
+
|
|
14
|
+
import anu_ctlab_io
|
|
15
|
+
from dask_image import ndfilters
|
|
16
|
+
|
|
17
|
+
dataset = anu_ctlab_io.Dataset.from_path(<path-to-your-data>)
|
|
18
|
+
blurred = ndfilters.gaussian_filter(dataset.data, sigma=3)
|
|
19
|
+
print(blurred.mean().compute())
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "anu-ctlab-io"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "python I/O for the ANU CTLab array storage format(s)"
|
|
9
|
+
readme = "README.rst"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"dask[array]>=2025.2.0",
|
|
13
|
+
"xarray>=2025.1.2",
|
|
14
|
+
"numpy>=2.2.3",
|
|
15
|
+
"lark>=1.2.2",
|
|
16
|
+
"dictdiffer>=0.9.0",
|
|
17
|
+
"deprecation>=2.1.0",
|
|
18
|
+
]
|
|
19
|
+
default-optional-dependency-keys = [
|
|
20
|
+
"netcdf",
|
|
21
|
+
"zarr",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
license = "MIT"
|
|
25
|
+
license-files = ["LICENSE.md"]
|
|
26
|
+
authors = [
|
|
27
|
+
{name = "Owen Dowley", email = "owen.dowley@anu.edu.au"},
|
|
28
|
+
{name = "Bogdan Maviichuk", email = "bogdan.maviichuk@anu.edu.au"},
|
|
29
|
+
{name = "Lachlan Deakin", email = "lachlan.deakin@anu.edu.au"},
|
|
30
|
+
]
|
|
31
|
+
maintainers = [
|
|
32
|
+
{name = "Owen Dowley", email = "owen.dowley@anu.edu.au"},
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
netcdf = [
|
|
37
|
+
"netcdf4>=1.7.2",
|
|
38
|
+
"scipy>=1.16.1", # netCDF 3 support
|
|
39
|
+
]
|
|
40
|
+
zarr = [
|
|
41
|
+
"zarr>=3.1.1",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.urls]
|
|
45
|
+
# FIXME: Add Homepage on v1.0.0 release
|
|
46
|
+
Repository = "https://github.com/MaterialsPhysicsANU/anu_ctlab_io"
|
|
47
|
+
Issues = "https://github.com/MaterialsPhysicsANU/anu_ctlab_io/issues"
|
|
48
|
+
Changelog = "https://github.com/MaterialsPhysicsANU/anu_ctlab_io/main/CHANGELOG.md"
|
|
49
|
+
|
|
50
|
+
[dependency-groups]
|
|
51
|
+
dev = [
|
|
52
|
+
"pre-commit>=4.1.0",
|
|
53
|
+
"ruff>=0.9.5",
|
|
54
|
+
"pytest>=8.3.5",
|
|
55
|
+
"sphinx>=8.2.3",
|
|
56
|
+
"sphinx-rtd-theme>=3.0.2",
|
|
57
|
+
"sphinx-autodoc-typehints>=3.2.0",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[tool.pytest.ini_options]
|
|
61
|
+
filterwarnings = [
|
|
62
|
+
# known behaviour, caused by numpy changes which are ABI compatible with older versions,
|
|
63
|
+
# but which cython flags as a warning despite everything being fine
|
|
64
|
+
# See https://github.com/cython/cython/issues/2498, https://github.com/cython/cython/issues/4366
|
|
65
|
+
'ignore:numpy.ndarray size changed, may indicate binary incompatibility.'
|
|
66
|
+
]
|
|
67
|
+
addopts = [
|
|
68
|
+
"--import-mode=importlib", # recommended by pytest
|
|
69
|
+
"-ra",
|
|
70
|
+
"--strict-config",
|
|
71
|
+
"--strict-markers"
|
|
72
|
+
]
|
|
73
|
+
minversion = "7.0"
|
|
74
|
+
testpaths = ["tests"]
|
|
75
|
+
log_cli_level = "INFO"
|
|
76
|
+
xfail_strict = true
|
|
77
|
+
|
|
78
|
+
[tool.mypy]
|
|
79
|
+
strict = true
|
|
80
|
+
warn_unreachable = true
|
|
81
|
+
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
|
|
82
|
+
|
|
83
|
+
[tool.ruff.lint]
|
|
84
|
+
extend-select = [
|
|
85
|
+
"B", # flake8-bugbear
|
|
86
|
+
"I", # isort
|
|
87
|
+
"UP", # pyupgrade
|
|
88
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
2
|
+
|
|
3
|
+
from anu_ctlab_io._dataset import Dataset
|
|
4
|
+
from anu_ctlab_io._datatype import DataType, StorageDType
|
|
5
|
+
from anu_ctlab_io._version import version as __version__
|
|
6
|
+
from anu_ctlab_io._voxel_properties import VoxelUnit
|
|
7
|
+
|
|
8
|
+
with suppress(ImportError):
|
|
9
|
+
import anu_ctlab_io.netcdf as netcdf
|
|
10
|
+
|
|
11
|
+
with suppress(ImportError):
|
|
12
|
+
import anu_ctlab_io.zarr as zarr
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Dataset", # out of sorted order so it comes first in the docs
|
|
16
|
+
"DataType",
|
|
17
|
+
"StorageDType",
|
|
18
|
+
"VoxelUnit",
|
|
19
|
+
"__version__",
|
|
20
|
+
"netcdf",
|
|
21
|
+
"zarr",
|
|
22
|
+
]
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod, abstractproperty
|
|
2
|
+
from importlib import import_module
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from types import ModuleType
|
|
5
|
+
from typing import Any, Self
|
|
6
|
+
|
|
7
|
+
import dask.array as da
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
from anu_ctlab_io._datatype import DataType, StorageDType
|
|
11
|
+
from anu_ctlab_io._voxel_properties import VoxelUnit
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AbstractDataset(ABC):
|
|
15
|
+
@classmethod
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def from_path(
|
|
18
|
+
cls, path: Path, *, parse_history: bool = True, **kwargs: Any
|
|
19
|
+
) -> Self:
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
@abstractproperty
|
|
23
|
+
def voxel_size(self) -> tuple[np.float32, np.float32, np.float32]:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
@abstractproperty
|
|
27
|
+
def voxel_unit(self) -> VoxelUnit:
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
@abstractproperty
|
|
31
|
+
def dimension_names(self) -> tuple[str, ...]:
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@abstractproperty
|
|
35
|
+
def history(self) -> dict[Any, Any] | str:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
@abstractproperty
|
|
39
|
+
def mask_value(self) -> StorageDType | None:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
@abstractproperty
|
|
43
|
+
def data(self) -> da.Array:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Dataset(AbstractDataset):
|
|
48
|
+
"""A :any:`Dataset`, containing the data and metadata read from one of the ANU CTLab file formats.
|
|
49
|
+
|
|
50
|
+
:any:`Dataset`\\ s are the primary interface to the :py:mod:`anu_ctlab_io` package, and should generally be
|
|
51
|
+
constructed by users via the :any:`Dataset.from_path` classmethod.
|
|
52
|
+
|
|
53
|
+
The initializer of this class should only be used when manually constructing a :any:`Dataset`, which is not
|
|
54
|
+
the primary usage of this library.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
_data: da.Array
|
|
58
|
+
_datatype: DataType
|
|
59
|
+
_voxel_unit: VoxelUnit
|
|
60
|
+
_voxel_size: tuple[np.float32, np.float32, np.float32]
|
|
61
|
+
_history: dict[Any, Any] | str
|
|
62
|
+
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
data: da.Array,
|
|
66
|
+
*,
|
|
67
|
+
dimension_names: tuple[str, ...],
|
|
68
|
+
voxel_unit: VoxelUnit,
|
|
69
|
+
voxel_size: tuple[np.float32, np.float32, np.float32],
|
|
70
|
+
datatype: DataType,
|
|
71
|
+
history: dict[str, Any] | None = None,
|
|
72
|
+
) -> None:
|
|
73
|
+
"""
|
|
74
|
+
Manually constructs a :any:`Dataset`.
|
|
75
|
+
|
|
76
|
+
:param data: The data contained in the :any:`Dataset`.
|
|
77
|
+
:param dimension_names: The names of the dimensions of the :any:`Dataset`.
|
|
78
|
+
:param voxel_unit: The unit the `voxel_size` is in terms of.
|
|
79
|
+
:param voxel_size: The size of each voxel in the :any:`Dataset`.
|
|
80
|
+
:param datatype: The mango datatype of the data. This is an implementation detail only required for parsing NetCDF files.
|
|
81
|
+
:param history: The history of the :any:`Dataset`.
|
|
82
|
+
"""
|
|
83
|
+
if history is None:
|
|
84
|
+
history = {}
|
|
85
|
+
|
|
86
|
+
self._data = data
|
|
87
|
+
self._dimension_names = dimension_names
|
|
88
|
+
self._datatype = datatype
|
|
89
|
+
self._voxel_unit = voxel_unit
|
|
90
|
+
self._voxel_size = voxel_size
|
|
91
|
+
self._history = history
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def _import_with_extra(module: str, extra: str) -> ModuleType:
|
|
95
|
+
try:
|
|
96
|
+
return import_module(module)
|
|
97
|
+
except ImportError as e:
|
|
98
|
+
raise ImportError(
|
|
99
|
+
f"{module} is missing. Please install with the '{extra}' extra: pip install anu-ctlab-io[{extra}]"
|
|
100
|
+
) from e
|
|
101
|
+
|
|
102
|
+
@classmethod
|
|
103
|
+
def from_path(
|
|
104
|
+
cls,
|
|
105
|
+
path: Path | str,
|
|
106
|
+
*,
|
|
107
|
+
filetype: str = "auto",
|
|
108
|
+
parse_history: bool = True,
|
|
109
|
+
**kwargs: Any,
|
|
110
|
+
) -> "Dataset":
|
|
111
|
+
"""Creates a :any:`Dataset` from the data at the given ``path``.
|
|
112
|
+
|
|
113
|
+
The data at ``path`` must be in one of the ANU mass data storage formats, and the optional dependencies required for the specific
|
|
114
|
+
file format must be installed.
|
|
115
|
+
|
|
116
|
+
:param path: The ``path`` to read data from.
|
|
117
|
+
:rtype: :any:`Dataset`
|
|
118
|
+
"""
|
|
119
|
+
if isinstance(path, str):
|
|
120
|
+
path = Path(path)
|
|
121
|
+
|
|
122
|
+
match filetype:
|
|
123
|
+
case "NetCDF":
|
|
124
|
+
netcdf_mod = cls._import_with_extra("anu_ctlab_io.netcdf", "netcdf")
|
|
125
|
+
return netcdf_mod.dataset_from_netcdf( # type: ignore[no-any-return]
|
|
126
|
+
path, parse_history=parse_history, **kwargs
|
|
127
|
+
)
|
|
128
|
+
case "zarr":
|
|
129
|
+
zarr_mod = cls._import_with_extra("anu_ctlab_io.zarr", "zarr")
|
|
130
|
+
return zarr_mod.dataset_from_zarr( # type: ignore[no-any-return]
|
|
131
|
+
path, parse_history=parse_history, **kwargs
|
|
132
|
+
)
|
|
133
|
+
case "auto":
|
|
134
|
+
if path.name[-2:] == "nc":
|
|
135
|
+
netcdf_mod = cls._import_with_extra("anu_ctlab_io.netcdf", "netcdf")
|
|
136
|
+
return netcdf_mod.dataset_from_netcdf( # type: ignore[no-any-return]
|
|
137
|
+
path, parse_history=parse_history, **kwargs
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
if path.name[-4:] == "zarr":
|
|
141
|
+
zarr_mod = cls._import_with_extra("anu_ctlab_io.zarr", "zarr")
|
|
142
|
+
return zarr_mod.dataset_from_zarr( # type: ignore[no-any-return]
|
|
143
|
+
path, parse_history=parse_history, **kwargs
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
raise (
|
|
147
|
+
ValueError(
|
|
148
|
+
"Unable to construct Dataset from given `path`, perhaps specify `filetype`?",
|
|
149
|
+
path,
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def voxel_size(self) -> tuple[np.float32, np.float32, np.float32]:
|
|
155
|
+
"""The voxel size of the data."""
|
|
156
|
+
return self._voxel_size
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def voxel_unit(self) -> VoxelUnit:
|
|
160
|
+
"""The unit the data's voxel size is in."""
|
|
161
|
+
return self._voxel_unit
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def dimension_names(self) -> tuple[str, ...]:
|
|
165
|
+
"""The names of the data's dimensions. Usually ``("z", "y", "x")``."""
|
|
166
|
+
return self._dimension_names
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def history(self) -> dict[Any, Any] | str:
|
|
170
|
+
"""The history metadata associated with the :any:`Dataset`.
|
|
171
|
+
|
|
172
|
+
If parsing is enabled this will be a nested dict, otherwise it will be a dictionary
|
|
173
|
+
without any guaranteed structure."""
|
|
174
|
+
return self._history
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def mask_value(self) -> StorageDType | None:
|
|
178
|
+
"""The mask value being used by the data."""
|
|
179
|
+
return self._datatype.mask_value
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def data(self) -> da.Array:
|
|
183
|
+
"""The data contained within the :any:`Dataset`.
|
|
184
|
+
|
|
185
|
+
This is a `Dask Array <https://docs.dask.org/en/stable/array.html>`_."""
|
|
186
|
+
return self._data
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
AbstractDataset.register(Dataset)
|