Skip to content

Commit

Permalink
Replace Image2DCollection with ImageCollection
Browse files Browse the repository at this point in the history
- Replace 2D image collection with generical image collection that can
  be the base class for multiple multi-scale image types.
- Move axis order specification from LevelProperties to fixed collection
  property.
  • Loading branch information
jp-dark committed Aug 13, 2024
1 parent 7b77255 commit bf6851f
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 31 deletions.
4 changes: 2 additions & 2 deletions python-spec/src/somacore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from .data import SparseNDArray
from .data import SparseRead
from .experiment import Experiment
from .images import Image2DCollection
from .images import ImageCollection
from .measurement import Measurement
from .options import BatchSize
from .options import IOfN
Expand Down Expand Up @@ -60,7 +60,7 @@
"Experiment",
"Measurement",
"Scene",
"Image2DCollection",
"ImageCollection",
"BatchSize",
"IOfN",
"ResultOrder",
Expand Down
4 changes: 2 additions & 2 deletions python-spec/src/somacore/ephemeral/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

from .collections import Collection
from .collections import Experiment
from .collections import Image2DCollection
from .collections import ImageCollection
from .collections import Measurement
from .collections import Scene

__all__ = (
"Collection",
"Experiment",
"Measurement",
"Image2DCollection",
"ImageCollection",
"Scene",
)
16 changes: 9 additions & 7 deletions python-spec/src/somacore/ephemeral/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
Optional,
Sequence,
TypeVar,
Union,
)

import pyarrow as pa
Expand Down Expand Up @@ -135,7 +134,7 @@ class Collection( # type: ignore[misc] # __eq__ false positive
"""The loosest possible constraint of the abstract Measurement type."""

_BasicAbstractScene = scene.Scene[
data.DataFrame, images.Image2DCollection, base.SOMAObject
data.DataFrame, images.ImageCollection, base.SOMAObject
]
"""The loosest possible constraint of the abstract Scene type."""

Expand Down Expand Up @@ -166,11 +165,11 @@ def transformations(self) -> MutableMapping[str, coordinates.CoordinateTransform
raise NotImplementedError()


class Image2DCollection( # type: ignore[misc] # __eq__ false positive
class ImageCollection( # type: ignore[misc] # __eq__ false positive
BaseCollection[base.SOMAObject],
images.Image2DCollection[data.DenseNDArray, base.SOMAObject],
images.ImageCollection[data.DenseNDArray, base.SOMAObject],
):
"""An in-memory Collection with Image2D semantics."""
"""An in-memory Collection with Image semantics."""

__slots__ = ()

Expand All @@ -181,15 +180,18 @@ def add_new_level(
uri: Optional[str] = None,
type: pa.DataType,
shape: Sequence[int],
axis_order: Union[str, Sequence[str]],
) -> data.DenseNDArray:
raise NotImplementedError()

@property
def axis_order(self) -> str:
raise NotImplementedError()

@property
def level_count(self) -> int:
raise NotImplementedError()

def level_properties(self, level: int) -> images.Image2DCollection.LevelProperties:
def level_properties(self, level: int) -> images.ImageCollection.LevelProperties:
raise NotImplementedError()

def read_level(
Expand Down
32 changes: 15 additions & 17 deletions python-spec/src/somacore/images.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Implementation of the SOMA image collection for spatial data"""

import abc
from typing import Generic, Optional, Sequence, Tuple, TypeVar, Union
from typing import Generic, Optional, Sequence, Tuple, TypeVar

import pyarrow as pa
from typing_extensions import Final, Protocol
Expand All @@ -20,7 +20,7 @@
_RO_AUTO = options.ResultOrder.AUTO


class Image2DCollection(
class ImageCollection(
collection.BaseCollection[_RootSO],
Generic[_DenseND, _RootSO],
):
Expand All @@ -34,30 +34,21 @@ class Image2DCollection(
#
# # This type-ignore comment will always be needed due to limitations
# # of type annotations; it is (currently) expected.
# class Image2DCollection( # type: ignore[type-var]
# class ImageCollection( # type: ignore[type-var]
# ImplBaseCollection[ImplSOMAObject],
# somacore.Image2DCollection[ImplDenseNDArray, ImpSOMAObject],
# somacore.ImageCollection[ImplDenseNDArray, ImpSOMAObject],
# ):
# ...

__slots__ = ()
soma_type: Final = "SOMAImage2DCollection" # type: ignore[misc]
soma_type: Final = "SOMAImageCollection" # type: ignore[misc]

class LevelProperties(Protocol):
"""Class requirements for level properties of 2D images."""

@property
def axis_order(self) -> Tuple[str, ...]:
"""Axis order for the underlying data.
Must contain 'X' and 'Y' for single-channel images and 'X', 'Y', and 'C'
for multi-channel images. Here `X' denotes the axis along the width of
the image and `Y' denotes the axis along the height of an image.
"""
"""Class requirements for level properties of images."""

@property
def name(self) -> str:
"""The key for the level inside the Image2DCollection."""
"""The key for the image."""

@property
def shape(self) -> Tuple[int, ...]:
Expand All @@ -71,17 +62,24 @@ def add_new_level(
uri: Optional[str] = None,
type: pa.DataType,
shape: Sequence[int],
axis_order: Union[str, Sequence[str]],
) -> data.DenseNDArray:
"""TODO: Add dcoumentation."""
raise NotImplementedError()

@property
def axis_order(self) -> str:
"""The order of the axes in the stored images."""
raise NotImplementedError()

@property
@abc.abstractmethod
def level_count(self) -> int:
"""The number of image levels stored in the ImageCollection."""
raise NotImplementedError()

@abc.abstractmethod
def level_properties(self, level: int) -> LevelProperties:
"""The properties of an image at the specified level."""
raise NotImplementedError()

@abc.abstractmethod
Expand Down
2 changes: 1 addition & 1 deletion python-spec/src/somacore/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"_SpatialDF", bound=data.DataFrame
) # TODO: Update to GeometryDataFrame or PointCloud
"""A particular implementation of GeometryDataFrame and PointCloud."""
_ImageColl = TypeVar("_ImageColl", bound=images.Image2DCollection)
_ImageColl = TypeVar("_ImageColl", bound=images.ImageCollection)
"""A particular implementation of a collection of spatial arrays."""
_RootSO = TypeVar("_RootSO", bound=base.SOMAObject)
"""The root SomaObject type of the implementation."""
Expand Down
4 changes: 2 additions & 2 deletions python-spec/testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ def test_method_resolution_order(self):
self.assertEqual("SOMAExperiment", exp.soma_type)
scene = ephemeral.Scene()
self.assertEqual("SOMAScene", scene.soma_type)
img = ephemeral.Image2DCollection()
self.assertEqual("SOMAImage2DCollection", img.soma_type)
img = ephemeral.ImageCollection()
self.assertEqual("SOMAImageCollection", img.soma_type)

0 comments on commit bf6851f

Please sign in to comment.