Skip to content

Commit 4487bc8

Browse files
authored
Changes to RFC4 (#264)
* Update orientation field name * Check that orientation can only be set on spatial axes * Use new orientation data structure
1 parent cffbf6a commit 4487bc8

File tree

5 files changed

+57
-42
lines changed

5 files changed

+57
-42
lines changed

src/ome_zarr_models/_v06/axes.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,38 @@
11
from collections.abc import Sequence
2-
from typing import Literal
2+
from typing import Self
3+
4+
from pydantic import BaseModel, JsonValue, model_validator
35

46
from ome_zarr_models.common.axes import Axis as BaseAxis
57
from ome_zarr_models.common.axes import AxisType
68

79
__all__ = ["Axes", "Axis", "AxisType"]
810

911

10-
Orientation = Literal[
11-
"left-to-right",
12-
"right-to-left",
13-
"anterior-to-posterior",
14-
"posterior-to-anterior",
15-
"inferior-to-superior",
16-
"superior-to-inferior",
17-
"dorsal-to-ventral",
18-
"ventral-to-dorsal",
19-
"dorsal-to-palmar",
20-
"palmar-to-dorsal",
21-
"dorsal-to-plantar",
22-
"plantar-to-dorsal",
23-
"rostral-to-caudal",
24-
"caudal-to-rostral",
25-
"cranial-to-caudal",
26-
"caudal-to-cranial",
27-
"proximal-to-distal",
28-
"distal-to-proximal",
29-
]
12+
class Orientation(BaseModel):
13+
"""
14+
Model for an orientation object.
15+
"""
16+
17+
type: JsonValue
18+
value: JsonValue
3019

3120

3221
class Axis(BaseAxis):
3322
"""
34-
Model for an element of multiscale axes.
23+
Model for an element of `Multiscale.axes`.
3524
"""
3625

37-
anatomicalOrientation: Orientation | None = None
26+
orientation: Orientation | None = None
27+
28+
@model_validator(mode="after")
29+
def _check_orientation_only_on_spatial(self) -> Self:
30+
if self.type != "space" and self.orientation is not None:
31+
raise ValueError(
32+
f"Orientation can only be set on a spatial axis "
33+
f"(got Axis type='{self.type}')"
34+
)
35+
return self
3836

3937

4038
Axes = Sequence[Axis]

src/ome_zarr_models/_v06/multiscales.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Self
22

3-
from pydantic import model_validator
3+
from pydantic import JsonValue, model_validator
44

5-
from ome_zarr_models._v06.axes import Axes, Orientation
5+
from ome_zarr_models._v06.axes import Axes
66
from ome_zarr_models.common.multiscales import Dataset, MultiscaleBase
77

88
__all__ = ["Dataset", "Multiscale"]
@@ -20,10 +20,8 @@ def _ensure_valid_orientations(self: Self) -> Self:
2020
"""
2121
Validate anatomical orientations.
2222
"""
23-
orientations: list[Orientation] = [
24-
a.anatomicalOrientation
25-
for a in self.axes
26-
if a.anatomicalOrientation is not None
23+
orientations: list[JsonValue] = [
24+
a.orientation.value for a in self.axes if a.orientation is not None
2725
]
2826
_check_only_one_value(
2927
orientations=orientations, values=["right-to-left", "left-to-right"]
@@ -55,7 +53,7 @@ def _ensure_valid_orientations(self: Self) -> Self:
5553

5654

5755
def _check_only_one_value(
58-
*, orientations: list[Orientation], values: list[Orientation]
56+
*, orientations: list[JsonValue], values: list[JsonValue]
5957
) -> None:
6058
counter = 0
6159
for value in values:

tests/_v06/test_axes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import pytest
2+
from pydantic import ValidationError
3+
4+
from ome_zarr_models._v06.axes import Axis
5+
6+
7+
def test_orientation_only_spatial() -> None:
8+
with pytest.raises(
9+
ValidationError, match="Orientation can only be set on a spatial axis"
10+
):
11+
Axis(
12+
name="my_axis",
13+
type="time",
14+
orientation={"type": "anatomical", "value": "anterior-to-posterior"},
15+
)

tests/_v06/test_image.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,28 +43,28 @@ def test_image(store: Store) -> None:
4343
name="t",
4444
type="time",
4545
unit="millisecond",
46-
anatomicalOrientation="left-to-right",
47-
),
48-
Axis(
49-
name="c", type="channel", unit=None, anatomicalOrientation=None
5046
),
47+
Axis(name="c", type="channel", unit=None, orientation=None),
5148
Axis(
5249
name="z",
5350
type="space",
5451
unit="micrometer",
55-
anatomicalOrientation=None,
52+
orientation=None,
5653
),
5754
Axis(
5855
name="y",
5956
type="space",
6057
unit="micrometer",
61-
anatomicalOrientation=None,
58+
orientation=None,
6259
),
6360
Axis(
6461
name="x",
6562
type="space",
6663
unit="micrometer",
67-
anatomicalOrientation=None,
64+
orientation={
65+
"type": "anatomical",
66+
"value": "left-to-right",
67+
},
6868
),
6969
],
7070
datasets=(
@@ -280,13 +280,13 @@ def test_invalid_orientations() -> None:
280280
name="z",
281281
type="space",
282282
unit="micrometer",
283-
anatomicalOrientation="left-to-right",
283+
orientation={"type": "anatomical", "value": "left-to-right"},
284284
),
285285
Axis(
286286
name="y",
287287
type="space",
288288
unit="micrometer",
289-
anatomicalOrientation="right-to-left",
289+
orientation={"type": "anatomical", "value": "right-to-left"},
290290
),
291291
],
292292
datasets=(

tests/data/examples/v06/image_example.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
{
99
"name": "t",
1010
"type": "time",
11-
"unit": "millisecond",
12-
"anatomicalOrientation": "left-to-right"
11+
"unit": "millisecond"
1312
},
1413
{ "name": "c", "type": "channel" },
1514
{ "name": "z", "type": "space", "unit": "micrometer" },
1615
{ "name": "y", "type": "space", "unit": "micrometer" },
17-
{ "name": "x", "type": "space", "unit": "micrometer" }
16+
{
17+
"name": "x",
18+
"type": "space",
19+
"unit": "micrometer",
20+
"orientation": { "type": "anatomical", "value": "left-to-right" }
21+
}
1822
],
1923
"datasets": [
2024
{

0 commit comments

Comments
 (0)