Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion bioio_base/image_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@

from .dimensions import Dimensions
from .standard_metadata import StandardMetadata
from .types import ImageLike, PhysicalPixelSizes, Scale, TimeInterval
from .types import (
DimensionProperties,
ImageLike,
PhysicalPixelSizes,
Scale,
TimeInterval,
)

###############################################################################

Expand Down Expand Up @@ -126,6 +132,11 @@ def physical_pixel_sizes(self) -> PhysicalPixelSizes:
def scale(self) -> Scale:
pass

@property
@abstractmethod
def dimension_properties(self) -> DimensionProperties:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love "properties" in the names here, but the only things I can think of that make it better are words like "metadata" or "info" which aren't a huge step up. Maybe dimension_info is a little better than dimension_properties? idk...

pass

@property
@abstractmethod
def time_interval(self) -> TimeInterval:
Expand Down
51 changes: 50 additions & 1 deletion bioio_base/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@
timelapse_interval,
total_time_duration,
)
from .types import PhysicalPixelSizes, Scale, TimeInterval
from .types import (
DimensionProperties,
DimensionProperty,
PhysicalPixelSizes,
Scale,
TimeInterval,
)

###############################################################################

Expand Down Expand Up @@ -915,6 +921,49 @@ def scale(self) -> Scale:
X=self.physical_pixel_sizes.X,
)

@property
def dimension_properties(self) -> DimensionProperties:
"""
Returns
-------
dimension_properties: DimensionProperties
Per-dimension properties.

Each dimension stores:
* value: The numeric scaling value.
* type: A semantic label for the dimension (e.g. "temporal", "spatial").
* unit: The unit associated with the value.
"""
s = self.scale

return DimensionProperties(
T=DimensionProperty(
value=s.T,
type="temporal" if s.T is not None else None,
unit=None,
),
C=DimensionProperty(
value=s.C,
type="channel" if s.C is not None else None,
unit=None,
),
Z=DimensionProperty(
value=s.Z,
type="spatial" if s.Z is not None else None,
unit=None,
),
Y=DimensionProperty(
value=s.Y,
type="spatial" if s.Y is not None else None,
unit=None,
),
X=DimensionProperty(
value=s.X,
type="spatial" if s.X is not None else None,
unit=None,
),
)

def get_mosaic_tile_position(
self, mosaic_tile_index: int, **kwargs: int
) -> Tuple[int, int]:
Expand Down
2 changes: 1 addition & 1 deletion bioio_base/standard_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class StandardMetadata:
imaged_by: Optional[str]
The experimentalist who produced this data.

imaging_date: Optional[str]
imaging_datetime: Optional[datetime]
Date this file was imaged.

objective: Optional[str]
Expand Down
31 changes: 31 additions & 0 deletions bioio_base/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,34 @@ class Scale(NamedTuple):
Z: Optional[float]
Y: Optional[float]
X: Optional[float]


class DimensionProperty(NamedTuple):
"""
Per-dimension descriptor for dimension metadata.

value:
The numeric value for this dimension (e.g. from Scale or PhysicalPixelSizes).
type:
Semantic meaning of the dimension (e.g. "spatial", "temporal", "channel").
unit:
Unit string associated with the value (e.g. "micrometer", "second", "index").
"""

value: Optional[float]
type: Optional[str]
unit: Optional[str]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few questions about the value, type, unit design here.

  1. can we put some actual typing on unit? (check with what OME advocates, or pick a well used python units library). Or do we want to just allow any old unit whatsoever?
  2. If we have typed units, then I would think about whether you might want to distinguish "unitless" (like for channels) vs None? Could there be a warning for when a reader finds an unexpected/unrecognized unit?)
  3. can we put some typing on type? For this it seems that the OME dimension types are what is expected here.
  4. value is not explained very well in the docstring. What is the value of a DimensionProperty? Is it the scaling from the multiscale transform? In other words, is it the number of unit units in one pixel of this dimension? If so, then it changes depending on what multiresolution level is selected and we might want to note that in a comment too. Kinda wondering if there's a better word than value. Thinking out loud: unit_scale perhaps?



class DimensionProperties(NamedTuple):
"""
Container for dimension properties for all supported dims.

These align with the standard bioio dimension order (T, C, Z, Y, X).
"""

T: DimensionProperty
C: DimensionProperty
Z: DimensionProperty
Y: DimensionProperty
X: DimensionProperty