feat: init
This commit is contained in:
189
test/model/metadata_sources/test_zarr_metadata.py
Normal file
189
test/model/metadata_sources/test_zarr_metadata.py
Normal file
@@ -0,0 +1,189 @@
|
||||
import pytest
|
||||
|
||||
SPACE_UNITS = [
|
||||
"angstrom",
|
||||
"attometer",
|
||||
"centimeter",
|
||||
"decimeter",
|
||||
"exameter",
|
||||
"femtometer",
|
||||
"foot",
|
||||
"gigameter",
|
||||
"hectometer",
|
||||
"inch",
|
||||
"kilometer",
|
||||
"megameter",
|
||||
"meter",
|
||||
"micrometer",
|
||||
"mile",
|
||||
"millimeter",
|
||||
"nanometer",
|
||||
"parsec",
|
||||
"petameter",
|
||||
"picometer",
|
||||
"terameter",
|
||||
"yard",
|
||||
"yoctometer",
|
||||
"yottameter",
|
||||
"zeptometer",
|
||||
"zettameter",
|
||||
]
|
||||
|
||||
TIME_UNITS = [
|
||||
"attosecond",
|
||||
"centisecond",
|
||||
"day",
|
||||
"decisecond",
|
||||
"exasecond",
|
||||
"femtosecond",
|
||||
"gigasecond",
|
||||
"hectosecond",
|
||||
"hour",
|
||||
"kilosecond",
|
||||
"megasecond",
|
||||
"microsecond",
|
||||
"millisecond",
|
||||
"minute",
|
||||
"nanosecond",
|
||||
"petasecond",
|
||||
"picosecond",
|
||||
"second",
|
||||
"terasecond",
|
||||
"yoctosecond",
|
||||
"yottasecond",
|
||||
"zeptosecond",
|
||||
"zettasecond",
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def dummy_metadata(dummy_model):
|
||||
from navigate.model.metadata_sources.zarr_metadata import OMEZarrMetadata
|
||||
|
||||
# Create metadata
|
||||
md = OMEZarrMetadata()
|
||||
|
||||
md.configuration = dummy_model.configuration
|
||||
|
||||
return md
|
||||
|
||||
|
||||
def test_axes(dummy_metadata):
|
||||
|
||||
axes = dummy_metadata._axes
|
||||
|
||||
# Check length
|
||||
assert (len(axes) > 1) and (len(axes) < 6)
|
||||
|
||||
# Check list types and count
|
||||
time_count = 0
|
||||
space_count = 0
|
||||
channel_count = 0
|
||||
custom_count = 0
|
||||
for d in axes:
|
||||
if d["type"] == "time":
|
||||
assert d["unit"] in TIME_UNITS
|
||||
time_count += 1
|
||||
elif d["type"] == "space":
|
||||
assert d["unit"] in SPACE_UNITS
|
||||
space_count += 1
|
||||
elif d["type"] == "channel":
|
||||
channel_count += 1
|
||||
else:
|
||||
custom_count += 1
|
||||
|
||||
assert (space_count > 1) and (space_count < 4)
|
||||
assert time_count < 2
|
||||
assert ((channel_count < 2) and (custom_count == 0)) or (
|
||||
(channel_count == 0) and (custom_count < 2)
|
||||
)
|
||||
|
||||
# Check order
|
||||
order_type = [x["type"] for x in axes]
|
||||
if "time" in order_type:
|
||||
# Time must be first, if present
|
||||
assert order_type.index("time") == 0
|
||||
if "channel" in order_type:
|
||||
# Channel must be before all the space axes, if present
|
||||
ci = order_type.index("channel")
|
||||
for i, el in enumerate(order_type):
|
||||
if el == "space":
|
||||
assert i > ci
|
||||
|
||||
# Skip zyx order spec as the naming of axes is not enforcable.
|
||||
|
||||
|
||||
def test_stage_positions_to_translation_transform(dummy_metadata):
|
||||
import random
|
||||
|
||||
pos = [random.random() for _ in range(5)]
|
||||
|
||||
translation = dummy_metadata._stage_positions_to_translation_transform(*pos)
|
||||
|
||||
axes = dummy_metadata._axes
|
||||
|
||||
assert len(translation) == len(axes)
|
||||
|
||||
|
||||
def test_scale_transform(dummy_metadata):
|
||||
scale = dummy_metadata._scale_transform()
|
||||
|
||||
axes = dummy_metadata._axes
|
||||
|
||||
assert len(scale) == len(axes)
|
||||
|
||||
|
||||
def test_coordinate_transformations(dummy_metadata):
|
||||
import random
|
||||
|
||||
pos = [random.random() for _ in range(5)]
|
||||
|
||||
translation = dummy_metadata._stage_positions_to_translation_transform(*pos)
|
||||
scale = dummy_metadata._scale_transform()
|
||||
|
||||
assert len(dummy_metadata._coordinate_transformations(scale)) == 1
|
||||
|
||||
combo = dummy_metadata._coordinate_transformations(scale, translation)
|
||||
assert len(combo) == 2
|
||||
assert combo[0]["type"] == "scale" and combo[1]["type"] == "translation"
|
||||
|
||||
with pytest.raises(UserWarning):
|
||||
dummy_metadata._coordinate_transformations(translation=translation)
|
||||
|
||||
|
||||
def test_multiscale_metadata(dummy_metadata):
|
||||
"""https://ngff.openmicroscopy.org/0.4/#multiscale-md"""
|
||||
import numpy as np
|
||||
import random
|
||||
|
||||
resolutions = np.array([[1, 1, 1], [2, 2, 1], [4, 4, 1], [8, 8, 1]], dtype=int)
|
||||
paths = [f"path{i}" for i in range(resolutions.shape[0])]
|
||||
view = {k: random.random() for k in ["x", "y", "z", "theta", "f"]}
|
||||
|
||||
msd = dummy_metadata.multiscales_dict("test", paths, resolutions, view)
|
||||
|
||||
# Each "multiscales" dictionary MUST contain the field "axes"
|
||||
assert "axes" in msd.keys()
|
||||
|
||||
# Each "multiscales" dictionary MUST contain the field "datasets"
|
||||
assert "datasets" in msd.keys()
|
||||
# Each dictionary in "datasets" MUST contain the field "path",
|
||||
# whose value contains the path to the array for this resolution
|
||||
# relative to the current zarr group. The "path"s MUST be ordered
|
||||
# from largest (i.e. highest resolution) to smallest.
|
||||
# Each "datasets" dictionary MUST have the same number of dimensions
|
||||
# and MUST NOT have more than 5 dimensions.
|
||||
|
||||
# Each "multiscales" dictionary SHOULD contain the field "name"
|
||||
assert "name" in msd.keys()
|
||||
|
||||
# Each "multiscales" dictionary MAY contain the field "coordinateTransformations"
|
||||
assert "coordinateTransformations" in msd.keys()
|
||||
|
||||
# It SHOULD contain the field "version"
|
||||
assert "version" in msd.keys()
|
||||
|
||||
# Each "multiscales" dictionary SHOULD contain the field "type", which gives
|
||||
# the type of downscaling method used to generate the multiscale image pyramid.
|
||||
# It SHOULD contain the field "metadata", which contains a dictionary with
|
||||
# additional information about the downscaling method.
|
||||
Reference in New Issue
Block a user