Skip to content

Commit

Permalink
feat: add reading skew from czi files
Browse files Browse the repository at this point in the history
  • Loading branch information
Czaki committed Oct 9, 2024
1 parent ca2021b commit f3e8a54
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
13 changes: 8 additions & 5 deletions package/PartSegCore/napari_plugins/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ def add_color(image: Image, idx: int) -> dict: # noqa: ARG001
return {}


def _image_to_layers(project_info, scale, translate):
def _image_to_layers(project_info, scale, translate, shear):
res_layers = []
if project_info.image.name == "ROI" and project_info.image.channels == 1:
res_layers.append(
(
project_info.image.get_channel(0),
{"scale": scale, "name": project_info.image.channel_names[0], "translate": translate},
{"scale": scale, "name": project_info.image.channel_names[0], "translate": translate, "shear": shear},
"labels",
)
)
Expand All @@ -71,6 +71,7 @@ def _image_to_layers(project_info, scale, translate):
"blending": "additive",
"translate": translate,
"metadata": project_info.image.metadata,
"shear": shear,
**add_color(project_info.image, i),
},
"image",
Expand All @@ -85,14 +86,15 @@ def project_to_layers(project_info: typing.Union[ProjectTuple, MaskProjectTuple]
res_layers = []
if project_info.image is not None and not isinstance(project_info.image, str):
scale = project_info.image.normalized_scaling()
shear = project_info.image.shear
translate = project_info.image.shift
translate = (0,) * (len(project_info.image.axis_order.replace("C", "")) - len(translate)) + translate
res_layers.extend(_image_to_layers(project_info, scale, translate))
res_layers.extend(_image_to_layers(project_info, scale, translate, shear))
if project_info.roi_info.roi is not None:
res_layers.append(
(
project_info.image.fit_array_to_image(project_info.roi_info.roi),
{"scale": scale, "name": "ROI", "translate": translate},
{"scale": scale, "name": "ROI", "translate": translate, "shear": shear},
"labels",
)
)
Expand All @@ -105,6 +107,7 @@ def project_to_layers(project_info: typing.Union[ProjectTuple, MaskProjectTuple]
"name": name,
"translate": translate,
"visible": False,
"shear": shear,
},
"labels",
)
Expand All @@ -115,7 +118,7 @@ def project_to_layers(project_info: typing.Union[ProjectTuple, MaskProjectTuple]
res_layers.append(
(
project_info.image.fit_array_to_image(project_info.mask),
{"scale": scale, "name": "Mask", "translate": translate},
{"scale": scale, "name": "Mask", "translate": translate, "shear": shear},
"labels",
)
)
Expand Down
6 changes: 6 additions & 0 deletions package/PartSegImage/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ def __init__(
channel_info: list[ChannelInfo | ChannelInfoFull] | None = None,
axes_order: str | None = None,
shift: Spacing | None = None,
shear: np.ndarray | None = None,
name: str = "",
metadata_dict: dict | None = None,
):
Expand All @@ -243,6 +244,7 @@ def __init__(
self._image_spacing = tuple(el if el > 0 else 10**-6 for el in self._image_spacing)

self._shift = tuple(shift) if shift is not None else (0,) * len(self._image_spacing)
self._shear = shear
self.name = name

self.file_path = file_path
Expand Down Expand Up @@ -369,6 +371,10 @@ def _merge_channel_names(base_channel_names: list[str], new_channel_names: list[
base_channel_names.append(new_name)
return base_channel_names

@property
def shear(self) -> np.ndarray | None:
return self._shear

@property
def channel_info(self) -> list[ChannelInfoFull]:
return [copy(x) for x in self._channel_info]
Expand Down
29 changes: 29 additions & 0 deletions package/PartSegImage/image_reader.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import inspect
import os.path
import typing
import warnings
from abc import abstractmethod
from contextlib import suppress
from importlib.metadata import version
Expand Down Expand Up @@ -388,8 +389,36 @@ def read(self, image_path: typing.Union[str, BytesIO, Path], mask_path=None, ext
axes_order=self.return_order(),
metadata_dict=metadata,
channel_info=self._get_channel_info(),
shear=self._read_shear(metadata),
)

def _read_shear(self, metadata: dict):
skew = self._read_skew(metadata)
shear = np.diag([1.0] * len(skew))
for i, val in enumerate(skew):
if val == 0:
continue
shear[i, i + 1] = np.tan(np.radians(val))

Check warning on line 401 in package/PartSegImage/image_reader.py

View check run for this annotation

Codecov / codecov/patch

package/PartSegImage/image_reader.py#L401

Added line #L401 was not covered by tests
return shear

@staticmethod
def _read_skew(metadata: dict):
dimensions = metadata["ImageDocument"]["Metadata"]["Information"]["Image"]["Dimensions"]
res = [0.0] * 4
for i, dim in enumerate("TZYX"):
if dim not in dimensions:
continue
if f"{dim}AxisShear" not in dimensions[dim]:
continue

shear_value = dimensions[dim][f"{dim}AxisShear"]
if not shear_value.startswith("Skew"):
warnings.warn(f"Unknown shear value {shear_value}", stacklevel=1)
continue
res[i] = float(shear_value[4:])

Check warning on line 418 in package/PartSegImage/image_reader.py

View check run for this annotation

Codecov / codecov/patch

package/PartSegImage/image_reader.py#L414-L418

Added lines #L414 - L418 were not covered by tests

return res

@classmethod
def update_array_shape(cls, array: np.ndarray, axes: str):
if "B" in axes:
Expand Down

0 comments on commit f3e8a54

Please sign in to comment.