Skip to content

Commit

Permalink
add validation example
Browse files Browse the repository at this point in the history
  • Loading branch information
d-v-b committed Mar 20, 2024
1 parent b5e6ba9 commit 88290a4
Showing 1 changed file with 91 additions and 35 deletions.
126 changes: 91 additions & 35 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,24 @@ group_model = Group.from_zarr(zgroup)
multi_meta = group_model.attributes.multiscales
print(multi_meta)
"""
[
(
MultiscaleMetadata(
version='0.4',
name=None,
type=None,
metadata=None,
datasets=[
datasets=(
Dataset(
path='0',
coordinateTransformations=(
VectorScale(
type='scale',
scale=[
scale=(
1.0,
0.5002025531914894,
0.3603981534640209,
0.3603981534640209,
],
),
),
),
),
Expand All @@ -74,12 +74,12 @@ print(multi_meta)
coordinateTransformations=(
VectorScale(
type='scale',
scale=[
scale=(
1.0,
0.5002025531914894,
0.7207963069280418,
0.7207963069280418,
],
),
),
),
),
Expand All @@ -88,25 +88,25 @@ print(multi_meta)
coordinateTransformations=(
VectorScale(
type='scale',
scale=[
scale=(
1.0,
0.5002025531914894,
1.4415926138560835,
1.4415926138560835,
],
),
),
),
),
],
axes=[
),
axes=(
Axis(name='c', type='channel', unit=None),
Axis(name='z', type='space', unit='micrometer'),
Axis(name='y', type='space', unit='micrometer'),
Axis(name='x', type='space', unit='micrometer'),
],
),
coordinateTransformations=None,
)
]
),
)
"""

# to get the Zarr arrays referenced by the multiscale metadata, we access them by name from the Zarr group.
Expand Down Expand Up @@ -180,43 +180,43 @@ print(group_model.model_dump())
{
'zarr_version': 2,
'attributes': {
'multiscales': [
'multiscales': (
{
'version': '0.4',
'name': None,
'type': None,
'metadata': None,
'datasets': [
'datasets': (
{
'path': 's0',
'coordinateTransformations': (
{'type': 'scale', 'scale': [1.0, 2.0, 2.0, 2.0]},
{'type': 'scale', 'scale': (1.0, 2.0, 2.0, 2.0)},
{
'type': 'translation',
'translation': [0.0, 0.0, 0.0, 0.0],
'translation': (0.0, 0.0, 0.0, 0.0),
},
),
},
{
'path': 's1',
'coordinateTransformations': (
{'type': 'scale', 'scale': [2.0, 4.0, 4.0, 4.0]},
{'type': 'scale', 'scale': (2.0, 4.0, 4.0, 4.0)},
{
'type': 'translation',
'translation': [0.5, 1.0, 1.0, 1.0],
'translation': (0.5, 1.0, 1.0, 1.0),
},
),
},
],
'axes': [
),
'axes': (
{'name': 't', 'type': 'time', 'unit': 'second'},
{'name': 'z', 'type': 'space', 'unit': 'nanometer'},
{'name': 'y', 'type': 'space', 'unit': 'nanometer'},
{'name': 'x', 'type': 'space', 'unit': 'nanometer'},
],
),
'coordinateTransformations': None,
}
]
},
)
},
'members': {
's0': {
Expand Down Expand Up @@ -269,37 +269,93 @@ foo
print(stored_group.attrs.asdict())
"""
{
'multiscales': [
'multiscales': (
{
'version': '0.4',
'name': None,
'type': None,
'metadata': None,
'datasets': [
'datasets': (
{
'path': 's0',
'coordinateTransformations': (
{'type': 'scale', 'scale': [1.0, 2.0, 2.0, 2.0]},
{'type': 'translation', 'translation': [0.0, 0.0, 0.0, 0.0]},
{'type': 'scale', 'scale': (1.0, 2.0, 2.0, 2.0)},
{'type': 'translation', 'translation': (0.0, 0.0, 0.0, 0.0)},
),
},
{
'path': 's1',
'coordinateTransformations': (
{'type': 'scale', 'scale': [2.0, 4.0, 4.0, 4.0]},
{'type': 'translation', 'translation': [0.5, 1.0, 1.0, 1.0]},
{'type': 'scale', 'scale': (2.0, 4.0, 4.0, 4.0)},
{'type': 'translation', 'translation': (0.5, 1.0, 1.0, 1.0)},
),
},
],
'axes': [
),
'axes': (
{'name': 't', 'type': 'time', 'unit': 'second'},
{'name': 'z', 'type': 'space', 'unit': 'nanometer'},
{'name': 'y', 'type': 'space', 'unit': 'nanometer'},
{'name': 'x', 'type': 'space', 'unit': 'nanometer'},
],
),
'coordinateTransformations': None,
}
]
},
)
}
"""
```


## Data validation

This library attempts to detect invalid OME-NGFF containers and provide useful error messages when something is broken. The following examples illustrate a few ways in which OME-NGFF metadata can be broken, and what the error messages look like.

```python
from pydantic import ValidationError
from pydantic_zarr.v2 import ArraySpec
from pydantic_ome_ngff.v04.multiscale import Group
from pydantic_ome_ngff.v04.axis import Axis
import numpy as np

arrays = np.zeros((10,10)), np.zeros((5,5))
scales = ((1,1), (2,2))
translations = ((0,0), (0.5, 0.5))
paths = ('s0','s1')
axes = (
Axis(name='y', unit='nanometer', type='space'),
Axis(name='x', unit='nanometer', type='space')
)

# create a valid multiscale group
group_model = Group.from_arrays(arrays, paths=paths, axes=axes, scales=scales, translations=translations)

# convert that group to a dictionary, so we can break it
group_model_missing_array = group_model.model_dump()

# remove one of the arrays. this invalidates the multiscale metadata
group_model_missing_array['members'].pop('s0')

try:
Group(**group_model_missing_array)
except ValidationError as e:
print(e)
"""
1 validation error for Group
Value error, Dataset s0 was specified in multiscale metadata, but no array with that name was found in the hierarchy. All arrays referenced in multiscale metadata must be contained in the group. [type=value_error, input_value={'zarr_version': 2, 'attr...: 'zstd', 'level': 3}}}}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.6/v/value_error
"""

group_model_wrong_array = group_model.model_dump()

# insert an array with incorrect dimensionality
group_model_wrong_array['members']['s0'] = ArraySpec.from_array(np.arange(10)).model_dump()

try:
Group(**group_model_wrong_array)
except ValidationError as e:
print(e)
"""
1 validation error for Group
Value error, Transform type='scale' scale=(1, 1) has dimensionality 2, which does not match the dimensionality of the array found in this group at s0 (1). Transform dimensionality must match array dimensionality. [type=value_error, input_value={'zarr_version': 2, 'attr...: 'zstd', 'level': 3}}}}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.6/v/value_error
"""
```

0 comments on commit 88290a4

Please sign in to comment.