voxeldata 0.0.1__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.
- voxeldata-0.0.1/LICENSE +27 -0
- voxeldata-0.0.1/PKG-INFO +143 -0
- voxeldata-0.0.1/README.md +119 -0
- voxeldata-0.0.1/pyproject.toml +88 -0
- voxeldata-0.0.1/pyproject.toml.orig +83 -0
- voxeldata-0.0.1/src/voxeldata/__init__.py +82 -0
- voxeldata-0.0.1/src/voxeldata/_coordinates.py +201 -0
- voxeldata-0.0.1/src/voxeldata/_dims.py +21 -0
- voxeldata-0.0.1/src/voxeldata/accessors.py +606 -0
- voxeldata-0.0.1/src/voxeldata/affine.py +470 -0
- voxeldata-0.0.1/src/voxeldata/create.py +573 -0
- voxeldata-0.0.1/src/voxeldata/geometry.py +1947 -0
- voxeldata-0.0.1/src/voxeldata/py.typed +0 -0
- voxeldata-0.0.1/src/voxeldata/validation.py +559 -0
voxeldata-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026, The VoxelData developers
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
|
6
|
+
permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
|
9
|
+
conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
12
|
+
of conditions and the following disclaimer in the documentation and/or other
|
|
13
|
+
materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
16
|
+
used to endorse or promote products derived from this software without specific prior
|
|
17
|
+
written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY
|
|
20
|
+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
21
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
22
|
+
THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
23
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
24
|
+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
25
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
26
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
27
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
voxeldata-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: voxeldata
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Spatially referenced voxel arrays built on xarray.
|
|
5
|
+
Author: Samuel Le Meur-Diebolt
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Programming Language :: Python
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Dist: numpy>=2.3.4
|
|
20
|
+
Requires-Dist: pandas>=2.2.0
|
|
21
|
+
Requires-Dist: xarray>=2025.1.0
|
|
22
|
+
Requires-Python: >=3.11, <3.15
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# VoxelData
|
|
26
|
+
|
|
27
|
+
**VoxelData** is a small, modality-independent data model for spatially referenced
|
|
28
|
+
voxel arrays, built on [xarray](https://docs.xarray.dev).
|
|
29
|
+
|
|
30
|
+
A VoxelData array is an `xarray.DataArray` that is always:
|
|
31
|
+
|
|
32
|
+
- dimensioned `(*nonspatial_dims, k, j, i)` — leading dimensions may appear in any
|
|
33
|
+
order, including optional special dimensions `time` and `grid`; the native voxel
|
|
34
|
+
indices `k`/`j`/`i` are always present and always last;
|
|
35
|
+
- backed by a single [`VoxelToWorldIndex`](src/voxeldata/geometry.py) attached to
|
|
36
|
+
the world coordinates `z`/`y`/`x`, which derives them lazily from one affine
|
|
37
|
+
shared by all data or one affine per `grid`.
|
|
38
|
+
|
|
39
|
+
World coordinates are never stored directly. This keeps cropping, slicing,
|
|
40
|
+
registration, and I/O consistent: the affine always describes the whole physical
|
|
41
|
+
grid, and indexing updates it exactly.
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
uv add voxeldata
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or with pip:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install voxeldata
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick start
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import numpy as np
|
|
59
|
+
import voxeldata as vd
|
|
60
|
+
|
|
61
|
+
data = vd.create_voxeldata(
|
|
62
|
+
np.zeros((3, 64, 128)),
|
|
63
|
+
dims=("k", "j", "i"),
|
|
64
|
+
spacing=(0.5, 0.1, 0.1), # z, y, x in millimetres
|
|
65
|
+
origin=(0.0, 0.0, 0.0),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
data.coords["x"] # lazily derived world coordinates
|
|
69
|
+
data.sel(x=5.0) # select in world space
|
|
70
|
+
vd.validate_voxeldata(data)
|
|
71
|
+
|
|
72
|
+
data.vd.origin # {'z': 0.0, 'y': 0.0, 'x': 0.0}
|
|
73
|
+
data.vd.spacing # {'k': 0.5, 'j': 0.1, 'i': 0.1}
|
|
74
|
+
data.vd.direction # (3, 3) world direction matrix
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Oblique grids work the same way:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
data = vd.create_voxeldata(
|
|
81
|
+
np.zeros((3, 64, 128)),
|
|
82
|
+
dims=("k", "j", "i"),
|
|
83
|
+
voxel_to_world=affine, # (4, 4) homogeneous affine
|
|
84
|
+
)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The `grid` dimension selects a spatial sampling grid: each grid has one affine,
|
|
88
|
+
shared across time and all other nonspatial dimensions. Affines may be identical
|
|
89
|
+
across grids. A `grid` dimension requires an `(ngrid, 4, 4)` affine stack, even for
|
|
90
|
+
one grid; without it, geometry uses a single `(4, 4)` affine.
|
|
91
|
+
|
|
92
|
+
Grid-dependent geometry carries one affine per grid:
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
data = vd.create_voxeldata(
|
|
96
|
+
np.zeros((2, 3, 64, 128)),
|
|
97
|
+
dims=("grid", "k", "j", "i"),
|
|
98
|
+
grid=np.array([0, 1]),
|
|
99
|
+
voxel_to_world=affines, # (2, 4, 4)
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Creation preserves the supplied nonspatial dimension order. For example, both
|
|
104
|
+
`(time, grid, k, j, i)` and `(grid, time, k, j, i)` are valid.
|
|
105
|
+
`data.vd.canonicalize()` and `data.vd.ensure()` normalize to
|
|
106
|
+
`(...extra_dims, grid, time, k, j, i)`, preserving the relative order of extra
|
|
107
|
+
dimensions and omitting absent `grid`/`time` dimensions. Canonicalization also
|
|
108
|
+
restores scalar-selected spatial dimensions, but does not restore a selected grid.
|
|
109
|
+
|
|
110
|
+
## Public API
|
|
111
|
+
|
|
112
|
+
| Area | Functions |
|
|
113
|
+
|---|---|
|
|
114
|
+
| Dimensions | `VOXEL_DIMS`, `WORLD_DIMS`, `GRID_DIM`, `TIME_DIM`, `CORE_DIMS` |
|
|
115
|
+
| Construction | `create_voxeldata`, `attach_voxel_to_world_index` |
|
|
116
|
+
| Accessor | `data.vd` ([`VoxelDataAccessor`](src/voxeldata/accessors.py)) |
|
|
117
|
+
| Geometry | `get_voxel_to_world_affine`, `get_voxel_to_world_units`, `get_voxel_to_world_index_origin`, `get_voxel_to_world_index_spacing`, `get_voxel_to_world_direction_matrix`, `convert_length_units` |
|
|
118
|
+
| Validation | `validate_voxeldata`, `ensure_voxeldata`, `canonicalize_voxeldata` |
|
|
119
|
+
| Affine operations | `apply_affine`, `reindex_voxels`, `reindex_voxels_like`, `get_bounding_box`, `get_relative_affine` |
|
|
120
|
+
| Named affines | `data.vd.get_affine`, `set_affine`, `remove_affine`, `apply`, `to` |
|
|
121
|
+
|
|
122
|
+
The `VoxelToWorldIndex` and `VoxelToWorldTransform` classes implement the xarray
|
|
123
|
+
indexing machinery and are exported for advanced use.
|
|
124
|
+
|
|
125
|
+
## Relationship to ConfUSIus
|
|
126
|
+
|
|
127
|
+
VoxelData is extracted from [ConfUSIus](https://github.com/confusius-tools/confusius),
|
|
128
|
+
which uses it for functional ultrasound imaging data. The model itself makes no
|
|
129
|
+
assumption about modality, acquisition hardware, or signal semantics, so it is
|
|
130
|
+
usable by any package working with spatially referenced voxel data.
|
|
131
|
+
|
|
132
|
+
## Development
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
uv sync # install dependencies
|
|
136
|
+
just test # run tests
|
|
137
|
+
just pre-commit # run lint, format, type checks, docstring checks
|
|
138
|
+
just docs # build documentation
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
BSD-3-Clause. Portions derived from ConfUSIus; see `NOTICE`.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# VoxelData
|
|
2
|
+
|
|
3
|
+
**VoxelData** is a small, modality-independent data model for spatially referenced
|
|
4
|
+
voxel arrays, built on [xarray](https://docs.xarray.dev).
|
|
5
|
+
|
|
6
|
+
A VoxelData array is an `xarray.DataArray` that is always:
|
|
7
|
+
|
|
8
|
+
- dimensioned `(*nonspatial_dims, k, j, i)` — leading dimensions may appear in any
|
|
9
|
+
order, including optional special dimensions `time` and `grid`; the native voxel
|
|
10
|
+
indices `k`/`j`/`i` are always present and always last;
|
|
11
|
+
- backed by a single [`VoxelToWorldIndex`](src/voxeldata/geometry.py) attached to
|
|
12
|
+
the world coordinates `z`/`y`/`x`, which derives them lazily from one affine
|
|
13
|
+
shared by all data or one affine per `grid`.
|
|
14
|
+
|
|
15
|
+
World coordinates are never stored directly. This keeps cropping, slicing,
|
|
16
|
+
registration, and I/O consistent: the affine always describes the whole physical
|
|
17
|
+
grid, and indexing updates it exactly.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add voxeldata
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or with pip:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install voxeldata
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import numpy as np
|
|
35
|
+
import voxeldata as vd
|
|
36
|
+
|
|
37
|
+
data = vd.create_voxeldata(
|
|
38
|
+
np.zeros((3, 64, 128)),
|
|
39
|
+
dims=("k", "j", "i"),
|
|
40
|
+
spacing=(0.5, 0.1, 0.1), # z, y, x in millimetres
|
|
41
|
+
origin=(0.0, 0.0, 0.0),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
data.coords["x"] # lazily derived world coordinates
|
|
45
|
+
data.sel(x=5.0) # select in world space
|
|
46
|
+
vd.validate_voxeldata(data)
|
|
47
|
+
|
|
48
|
+
data.vd.origin # {'z': 0.0, 'y': 0.0, 'x': 0.0}
|
|
49
|
+
data.vd.spacing # {'k': 0.5, 'j': 0.1, 'i': 0.1}
|
|
50
|
+
data.vd.direction # (3, 3) world direction matrix
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Oblique grids work the same way:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
data = vd.create_voxeldata(
|
|
57
|
+
np.zeros((3, 64, 128)),
|
|
58
|
+
dims=("k", "j", "i"),
|
|
59
|
+
voxel_to_world=affine, # (4, 4) homogeneous affine
|
|
60
|
+
)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The `grid` dimension selects a spatial sampling grid: each grid has one affine,
|
|
64
|
+
shared across time and all other nonspatial dimensions. Affines may be identical
|
|
65
|
+
across grids. A `grid` dimension requires an `(ngrid, 4, 4)` affine stack, even for
|
|
66
|
+
one grid; without it, geometry uses a single `(4, 4)` affine.
|
|
67
|
+
|
|
68
|
+
Grid-dependent geometry carries one affine per grid:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
data = vd.create_voxeldata(
|
|
72
|
+
np.zeros((2, 3, 64, 128)),
|
|
73
|
+
dims=("grid", "k", "j", "i"),
|
|
74
|
+
grid=np.array([0, 1]),
|
|
75
|
+
voxel_to_world=affines, # (2, 4, 4)
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Creation preserves the supplied nonspatial dimension order. For example, both
|
|
80
|
+
`(time, grid, k, j, i)` and `(grid, time, k, j, i)` are valid.
|
|
81
|
+
`data.vd.canonicalize()` and `data.vd.ensure()` normalize to
|
|
82
|
+
`(...extra_dims, grid, time, k, j, i)`, preserving the relative order of extra
|
|
83
|
+
dimensions and omitting absent `grid`/`time` dimensions. Canonicalization also
|
|
84
|
+
restores scalar-selected spatial dimensions, but does not restore a selected grid.
|
|
85
|
+
|
|
86
|
+
## Public API
|
|
87
|
+
|
|
88
|
+
| Area | Functions |
|
|
89
|
+
|---|---|
|
|
90
|
+
| Dimensions | `VOXEL_DIMS`, `WORLD_DIMS`, `GRID_DIM`, `TIME_DIM`, `CORE_DIMS` |
|
|
91
|
+
| Construction | `create_voxeldata`, `attach_voxel_to_world_index` |
|
|
92
|
+
| Accessor | `data.vd` ([`VoxelDataAccessor`](src/voxeldata/accessors.py)) |
|
|
93
|
+
| Geometry | `get_voxel_to_world_affine`, `get_voxel_to_world_units`, `get_voxel_to_world_index_origin`, `get_voxel_to_world_index_spacing`, `get_voxel_to_world_direction_matrix`, `convert_length_units` |
|
|
94
|
+
| Validation | `validate_voxeldata`, `ensure_voxeldata`, `canonicalize_voxeldata` |
|
|
95
|
+
| Affine operations | `apply_affine`, `reindex_voxels`, `reindex_voxels_like`, `get_bounding_box`, `get_relative_affine` |
|
|
96
|
+
| Named affines | `data.vd.get_affine`, `set_affine`, `remove_affine`, `apply`, `to` |
|
|
97
|
+
|
|
98
|
+
The `VoxelToWorldIndex` and `VoxelToWorldTransform` classes implement the xarray
|
|
99
|
+
indexing machinery and are exported for advanced use.
|
|
100
|
+
|
|
101
|
+
## Relationship to ConfUSIus
|
|
102
|
+
|
|
103
|
+
VoxelData is extracted from [ConfUSIus](https://github.com/confusius-tools/confusius),
|
|
104
|
+
which uses it for functional ultrasound imaging data. The model itself makes no
|
|
105
|
+
assumption about modality, acquisition hardware, or signal semantics, so it is
|
|
106
|
+
usable by any package working with spatially referenced voxel data.
|
|
107
|
+
|
|
108
|
+
## Development
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
uv sync # install dependencies
|
|
112
|
+
just test # run tests
|
|
113
|
+
just pre-commit # run lint, format, type checks, docstring checks
|
|
114
|
+
just docs # build documentation
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
BSD-3-Clause. Portions derived from ConfUSIus; see `NOTICE`.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "voxeldata"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "Spatially referenced voxel arrays built on xarray."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "BSD-3-Clause"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.11,<3.15"
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Development Status :: 3 - Alpha",
|
|
11
|
+
"Programming Language :: Python",
|
|
12
|
+
"Programming Language :: Python :: 3.11",
|
|
13
|
+
"Programming Language :: Python :: 3.12",
|
|
14
|
+
"Programming Language :: Python :: 3.13",
|
|
15
|
+
"Programming Language :: Python :: 3.14",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
"Intended Audience :: Science/Research",
|
|
18
|
+
"Topic :: Scientific/Engineering",
|
|
19
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
20
|
+
"Typing :: Typed",
|
|
21
|
+
]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"numpy>=2.3.4",
|
|
24
|
+
"pandas>=2.2.0",
|
|
25
|
+
"xarray>=2025.1.0",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[[project.authors]]
|
|
29
|
+
name = "Samuel Le Meur-Diebolt"
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["uv-build>=0.9.5,<0.14.0"]
|
|
33
|
+
build-backend = "uv_build"
|
|
34
|
+
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
dev = [
|
|
37
|
+
"codespell>=2.3.0",
|
|
38
|
+
"numpydoc>=1.11.0",
|
|
39
|
+
"prek>=0.4.8",
|
|
40
|
+
"pytest>=9.1.1",
|
|
41
|
+
"pytest-cov>=6.0.0",
|
|
42
|
+
"ruff>=0.16.5",
|
|
43
|
+
"ty>=0.0.77,<0.1.0",
|
|
44
|
+
"zensical>=0.0.67",
|
|
45
|
+
"mkdocstrings[python]>=1.0.4",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[tool.numpydoc_validation]
|
|
49
|
+
exclude = [
|
|
50
|
+
'\.__init__$',
|
|
51
|
+
'\._.*$',
|
|
52
|
+
]
|
|
53
|
+
checks = [
|
|
54
|
+
"all",
|
|
55
|
+
"GL01",
|
|
56
|
+
"ES01",
|
|
57
|
+
"SA01",
|
|
58
|
+
"EX01",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.ruff]
|
|
62
|
+
line-length = 88
|
|
63
|
+
|
|
64
|
+
[tool.ty.src]
|
|
65
|
+
include = [
|
|
66
|
+
"src",
|
|
67
|
+
"tests",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.pytest.ini_options]
|
|
71
|
+
minversion = "8.0"
|
|
72
|
+
testpaths = ["tests"]
|
|
73
|
+
pythonpath = ["."]
|
|
74
|
+
python_files = ["test_*.py"]
|
|
75
|
+
python_classes = ["Test*"]
|
|
76
|
+
python_functions = ["test_*"]
|
|
77
|
+
addopts = [
|
|
78
|
+
"-ra",
|
|
79
|
+
"--strict-markers",
|
|
80
|
+
"--strict-config",
|
|
81
|
+
"--import-mode=importlib",
|
|
82
|
+
"--showlocals",
|
|
83
|
+
"--cov=voxeldata",
|
|
84
|
+
"--cov-report=term-missing",
|
|
85
|
+
"--cov-report=html",
|
|
86
|
+
"--cov-report=xml",
|
|
87
|
+
]
|
|
88
|
+
filterwarnings = ["error"]
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "voxeldata"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "Spatially referenced voxel arrays built on xarray."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "BSD-3-Clause"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Samuel Le Meur-Diebolt" }]
|
|
9
|
+
requires-python = ">=3.11,<3.15"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Programming Language :: Python",
|
|
13
|
+
"Programming Language :: Python :: 3.11",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Programming Language :: Python :: 3.13",
|
|
16
|
+
"Programming Language :: Python :: 3.14",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"Topic :: Scientific/Engineering",
|
|
20
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
21
|
+
"Typing :: Typed",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"numpy>=2.3.4",
|
|
25
|
+
"pandas>=2.2.0",
|
|
26
|
+
"xarray>=2025.1.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["uv-build>=0.9.5,<0.14.0"]
|
|
31
|
+
build-backend = "uv_build"
|
|
32
|
+
|
|
33
|
+
[dependency-groups]
|
|
34
|
+
dev = [
|
|
35
|
+
"codespell>=2.3.0",
|
|
36
|
+
"numpydoc>=1.11.0",
|
|
37
|
+
"prek>=0.4.8",
|
|
38
|
+
"pytest>=9.1.1",
|
|
39
|
+
"pytest-cov>=6.0.0",
|
|
40
|
+
"ruff>=0.16.5",
|
|
41
|
+
"ty>=0.0.77,<0.1.0",
|
|
42
|
+
"zensical>=0.0.67",
|
|
43
|
+
"mkdocstrings[python]>=1.0.4",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.numpydoc_validation]
|
|
47
|
+
exclude = [
|
|
48
|
+
'\.__init__$',
|
|
49
|
+
'\._.*$',
|
|
50
|
+
]
|
|
51
|
+
checks = [
|
|
52
|
+
"all",
|
|
53
|
+
"GL01",
|
|
54
|
+
"ES01",
|
|
55
|
+
"SA01",
|
|
56
|
+
"EX01",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[tool.ruff]
|
|
60
|
+
line-length = 88
|
|
61
|
+
|
|
62
|
+
[tool.ty.src]
|
|
63
|
+
include = ["src", "tests"]
|
|
64
|
+
|
|
65
|
+
[tool.pytest.ini_options]
|
|
66
|
+
minversion = "8.0"
|
|
67
|
+
testpaths = ["tests"]
|
|
68
|
+
pythonpath = ["."]
|
|
69
|
+
python_files = ["test_*.py"]
|
|
70
|
+
python_classes = ["Test*"]
|
|
71
|
+
python_functions = ["test_*"]
|
|
72
|
+
addopts = [
|
|
73
|
+
"-ra",
|
|
74
|
+
"--strict-markers",
|
|
75
|
+
"--strict-config",
|
|
76
|
+
"--import-mode=importlib",
|
|
77
|
+
"--showlocals",
|
|
78
|
+
"--cov=voxeldata",
|
|
79
|
+
"--cov-report=term-missing",
|
|
80
|
+
"--cov-report=html",
|
|
81
|
+
"--cov-report=xml",
|
|
82
|
+
]
|
|
83
|
+
filterwarnings = ["error"]
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""VoxelData: spatially referenced voxel arrays built on xarray.
|
|
2
|
+
|
|
3
|
+
VoxelData defines a small, modality-independent data model for arrays gridded in
|
|
4
|
+
space. A VoxelData array is an `xarray.DataArray` with native voxel dimensions
|
|
5
|
+
`(k, j, i)` (plus any extra leading dimensions) and a single
|
|
6
|
+
[VoxelToWorldIndex][voxeldata.geometry.VoxelToWorldIndex] that lazily derives world
|
|
7
|
+
coordinates `(z, y, x)` from a voxel-to-world affine.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from voxeldata._dims import CORE_DIMS, GRID_DIM, TIME_DIM, VOXEL_DIMS, WORLD_DIMS
|
|
11
|
+
from voxeldata.accessors import VoxelDataAccessor
|
|
12
|
+
from voxeldata.affine import (
|
|
13
|
+
apply_affine,
|
|
14
|
+
get_bounding_box,
|
|
15
|
+
get_relative_affine,
|
|
16
|
+
reindex_voxels,
|
|
17
|
+
reindex_voxels_like,
|
|
18
|
+
)
|
|
19
|
+
from voxeldata.create import create_voxeldata
|
|
20
|
+
from voxeldata.geometry import (
|
|
21
|
+
VoxelToWorldIndex,
|
|
22
|
+
VoxelToWorldTransform,
|
|
23
|
+
attach_voxel_to_world_index,
|
|
24
|
+
convert_length_units,
|
|
25
|
+
get_affine_axis_scalings,
|
|
26
|
+
get_affine_direction_matrix,
|
|
27
|
+
get_voxel_to_world_affine,
|
|
28
|
+
get_voxel_to_world_direction_matrix,
|
|
29
|
+
get_voxel_to_world_index,
|
|
30
|
+
get_voxel_to_world_index_origin,
|
|
31
|
+
get_voxel_to_world_index_spacing,
|
|
32
|
+
get_voxel_to_world_spatial_dims,
|
|
33
|
+
get_voxel_to_world_units,
|
|
34
|
+
has_axis_aligned_voxel_to_world_index,
|
|
35
|
+
has_voxel_to_world_index,
|
|
36
|
+
require_scalar_grid_affine,
|
|
37
|
+
restore_voxel_to_world_index,
|
|
38
|
+
)
|
|
39
|
+
from voxeldata.validation import (
|
|
40
|
+
canonicalize_voxeldata,
|
|
41
|
+
ensure_voxeldata,
|
|
42
|
+
require_dataarray,
|
|
43
|
+
require_positive_finite,
|
|
44
|
+
validate_voxeldata,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
__all__ = [
|
|
48
|
+
"CORE_DIMS",
|
|
49
|
+
"GRID_DIM",
|
|
50
|
+
"TIME_DIM",
|
|
51
|
+
"VOXEL_DIMS",
|
|
52
|
+
"WORLD_DIMS",
|
|
53
|
+
"VoxelDataAccessor",
|
|
54
|
+
"VoxelToWorldIndex",
|
|
55
|
+
"VoxelToWorldTransform",
|
|
56
|
+
"apply_affine",
|
|
57
|
+
"attach_voxel_to_world_index",
|
|
58
|
+
"canonicalize_voxeldata",
|
|
59
|
+
"convert_length_units",
|
|
60
|
+
"create_voxeldata",
|
|
61
|
+
"ensure_voxeldata",
|
|
62
|
+
"get_affine_axis_scalings",
|
|
63
|
+
"get_affine_direction_matrix",
|
|
64
|
+
"get_bounding_box",
|
|
65
|
+
"get_relative_affine",
|
|
66
|
+
"get_voxel_to_world_affine",
|
|
67
|
+
"get_voxel_to_world_direction_matrix",
|
|
68
|
+
"get_voxel_to_world_index",
|
|
69
|
+
"get_voxel_to_world_index_origin",
|
|
70
|
+
"get_voxel_to_world_index_spacing",
|
|
71
|
+
"get_voxel_to_world_spatial_dims",
|
|
72
|
+
"get_voxel_to_world_units",
|
|
73
|
+
"has_axis_aligned_voxel_to_world_index",
|
|
74
|
+
"has_voxel_to_world_index",
|
|
75
|
+
"reindex_voxels",
|
|
76
|
+
"reindex_voxels_like",
|
|
77
|
+
"require_dataarray",
|
|
78
|
+
"require_positive_finite",
|
|
79
|
+
"require_scalar_grid_affine",
|
|
80
|
+
"restore_voxel_to_world_index",
|
|
81
|
+
"validate_voxeldata",
|
|
82
|
+
]
|