Skip to content

Commit

Permalink
(WIP) First pass at cleaning up MultiscaleImage API
Browse files Browse the repository at this point in the history
  • Loading branch information
jp-dark committed Oct 22, 2024
1 parent aba232b commit af2996e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 71 deletions.
1 change: 0 additions & 1 deletion python-spec/src/somacore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
from .query import ExperimentAxisQuery
from .scene import Scene
from .spatial import GeometryDataFrame
from .spatial import ImageProperties
from .spatial import MultiscaleImage
from .spatial import PointCloudDataFrame
from .spatial import SpatialRead
Expand Down
87 changes: 17 additions & 70 deletions python-spec/src/somacore/spatial.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)

import pyarrow as pa
from typing_extensions import Final, Protocol, Self
from typing_extensions import Final, Self

from . import base
from . import coordinates
Expand Down Expand Up @@ -528,23 +528,29 @@ def create(
uri: str,
*,
type: pa.DataType,
reference_level_shape: Sequence[int],
axis_names: Sequence[str] = ("c", "y", "x"),
shape: Sequence[int],
coordinate_space: Union[Sequence[str], coordinates.CoordinateSpace] = (
"x",
"y",
),
axis_types: Sequence[str] = ("channel", "height", "width"),
platform_config: Optional[options.PlatformConfig] = None,
context: Optional[Any] = None,
) -> Self:
"""Creates a new collection of this type at the given URI.
"""Creates a new MultiscaleImage with one initial level.
Args:
uri: The URI where the collection will be created.
reference_level_shape: The shape of the reference level for the multiscale
image. In most cases, this corresponds to the size of the image
at ``level=0``.
axis_names: The names of the axes of the image.
type: The Arrow type to store the image data in the array.
If the type is unsupported, an error will be raised.
shape: The shape of the multiscale image for ``level=0``. Must include the
channel dimension if there is one.
axis_types: The types of the axes of the image. Must be the same length as
``axis_names``. Valid types are: ``channel``, ``height``, ``width``,
``shape``. Valid types are: ``channel``, ``height``, ``width``,
and ``depth``.
coordinate_space: Either the coordinate space or the axis names for the
coordinate space the ``level=0`` image is defined on. This does not
include the channel dimension, only spatial dimensions.
Returns:
The newly created collection, opened for writing.
Expand All @@ -565,7 +571,7 @@ def add_new_level(
Parameters are as in :meth:`data.DenseNDArray.create`. The provided shape will
be used to compute the scale between images and must correspond to the image
size for the entire image.
size for the entire image. The image must be smaller than the ``level=0`` image.
Lifecycle: experimental
"""
Expand Down Expand Up @@ -618,15 +624,6 @@ def read_spatial_region(

# Metadata operations

@property
@abc.abstractmethod
def axis_names(self) -> Tuple[str, ...]:
"""The name of the image axes.
Lifecycle: experimental
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def coordinate_space(self) -> coordinates.CoordinateSpace:
Expand Down Expand Up @@ -666,15 +663,6 @@ def get_transform_to_level(
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def image_type(self) -> str:
"""The order of the axes as stored in the data model.
Lifecycle: experimental
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def level_count(self) -> int:
Expand All @@ -685,54 +673,13 @@ def level_count(self) -> int:
raise NotImplementedError()

@abc.abstractmethod
def level_properties(self, level: Union[int, str]) -> "ImageProperties":
def level_shape(self, level: Union[int, str]) -> Tuple[int, ...]:
"""The properties of an image at the specified level.
Lifecycle: experimental
"""
raise NotImplementedError()

@property
def reference_level(self) -> Optional[int]:
"""The index of image level that is used as a reference level.
This will return ``None`` if no current image level matches the size of the
reference level.
Lifecycle: experimental
"""
raise NotImplementedError()

@property
@abc.abstractmethod
def reference_level_properties(self) -> "ImageProperties":
"""The image properties of the reference level.
Lifecycle: experimental
"""
raise NotImplementedError()


class ImageProperties(Protocol):
"""Class requirements for level properties of images.
Lifecycle: experimental
"""

@property
def name(self) -> str:
"""The key for the image.
Lifecycle: experimental
"""

@property
def shape(self) -> Tuple[int, ...]:
"""Size of each axis of the image.
Lifecycle: experimental
"""


@dataclass
class SpatialRead(Generic[_ReadData]):
Expand Down

0 comments on commit af2996e

Please sign in to comment.