Skip to content

Commit

Permalink
Merge pull request #88 from TimMonko/new-image-utilities
Browse files Browse the repository at this point in the history
New image utilities widget
  • Loading branch information
TimMonko authored Oct 14, 2024
2 parents 574ffc1 + 28d09f2 commit 31d60c5
Show file tree
Hide file tree
Showing 7 changed files with 701 additions and 434 deletions.
6 changes: 3 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ install_requires =
pyclesperanto-prototype
dask
napari-workflows
natsort
seaborn
stackview
tifffile >= 2023.3.15 # https://github.com/AllenCellModeling/aicsimageio/issues/523 maybe keep for legacy reasons?
Expand Down Expand Up @@ -81,8 +82,8 @@ testing =
pytest-qt # https://pytest-qt.readthedocs.io/en/latest/
napari
pyqt5
napari-ndev[all] # just to confirm that bioio dependencies don't conflict with expected readers in tests
# napari-bioio @ git+https://github.com/TimMonko/napari-bioio.git@main#egg=napari-bioio
bioio-czi >= 1.0.1
napari_ndev[extras]

extras =
napari-pyclesperanto-assistant
Expand All @@ -93,7 +94,6 @@ gpl_extras =
# bioio GPL3 dependencies
bioio-czi >= 1.0.1
bioio-lif >= 1
# napari-bioio @ git+https://github.com/TimMonko/napari-bioio.git@main#egg=napari-bioio

docs =
mkdocs
Expand Down
32 changes: 7 additions & 25 deletions src/napari_ndev/_napari_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,9 @@ def napari_reader_function(
logger.info("Bioio: Expected a single path, got a list of paths.")
return None

in_memory = _determine_in_memory(path) if in_memory is None else in_memory
logger.info('Bioio: Reading in-memory: %s', in_memory)

img = nImage(path, reader=reader)
in_memory = img._determine_in_memory(path) if in_memory is None else in_memory
logger.info('Bioio: Reading in-memory: %s', in_memory)

if len(img.scenes) > 1 and not open_first_scene_only:
_get_scenes(path=path, img=img, in_memory=in_memory)
Expand All @@ -126,23 +125,6 @@ def napari_reader_function(

return [(img_data.data, img_meta, layer_type)]

def _determine_in_memory(
path: PathLike,
max_mem_bytes: int = 4e9,
max_mem_percent: int = 0.3
) -> bool:
"""Determine whether to read the file in memory."""
from bioio_base.io import pathlike_to_fs
from psutil import virtual_memory

fs, path = pathlike_to_fs(path)
filesize = fs.size(path)
available_mem = virtual_memory().available
return (
filesize <= max_mem_bytes
and filesize / available_mem <= max_mem_percent
)

def _widget_is_checked(widget_name: str) -> bool:
import napari

Expand Down Expand Up @@ -173,18 +155,18 @@ def _get_scenes(path: PathLike, img: nImage, in_memory: bool) -> None:

# Create a checkbox widget to set "Unpack Channels" or not
channel_unpack_checkbox = QCheckBox(UNPACK_CHANNELS_TO_LAYERS)
channel_unpack_checkbox.setChecked(False)
channel_unpack_checkbox.setChecked(True)

# Create a checkbox widget to set "Mosaic Merge" or not
dont_merge_mosaics_checkbox = QCheckBox(DONT_MERGE_MOSAICS)
dont_merge_mosaics_checkbox.setChecked(False)
# # Create a checkbox widget to set "Mosaic Merge" or not
# dont_merge_mosaics_checkbox = QCheckBox(DONT_MERGE_MOSAICS)
# dont_merge_mosaics_checkbox.setChecked(False)

# Add all scene management state to a single box
scene_manager_group = QGroupBox()
scene_manager_group_layout = QVBoxLayout()
scene_manager_group_layout.addWidget(scene_clear_checkbox)
scene_manager_group_layout.addWidget(channel_unpack_checkbox)
scene_manager_group_layout.addWidget(dont_merge_mosaics_checkbox)
# scene_manager_group_layout.addWidget(dont_merge_mosaics_checkbox)
scene_manager_group.setLayout(scene_manager_group_layout)
scene_manager_group.setFixedHeight(100)

Expand Down
Binary file not shown.
65 changes: 55 additions & 10 deletions src/napari_ndev/_tests/test_napari_reader.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING, Any
from typing import Any

import dask.array as da

Expand All @@ -11,12 +11,10 @@

from napari_ndev._napari_reader import napari_get_reader

if TYPE_CHECKING:
from npe2._pytest_plugin import TestPluginManager

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

RGB_TIFF = "RGB.tiff" # has two scense
MULTISCENE_CZI = r"0T-4C-0Z-7pos.czi"
# PNG_FILE = "example.png"
# GIF_FILE = "example.gif"
# OME_TIFF = "pipeline-4.ome.tiff"
Expand Down Expand Up @@ -49,9 +47,9 @@ def test_reader(
filename: str,
in_memory: bool,
expected_shape: tuple[int, ...],
expected_dtype: type,
expected_dtype,
expected_meta: dict[str, Any],
npe2pm: TestPluginManager,
# npe2pm: TestPluginManager,
) -> None:
# Resolve filename to filepath
if isinstance(filename, str):
Expand All @@ -78,7 +76,54 @@ def test_reader(
meta.pop('metadata', None)
assert meta == expected_meta

# # confirm that this also works via npe2
# with npe2pm.tmp_plugin(package='napari-ndev') as plugin:
# [via_npe2] = npe2.read([path], stack=False, plugin_name=plugin.name)
# assert via_npe2[0].shape == data.shape

@pytest.mark.parametrize(
("in_memory", "expected_dtype"),
[
(True, np.ndarray),
(False, da.core.Array),
],
)
@pytest.mark.parametrize(
("filename", "expected_shape"),
[
(RGB_TIFF, (120, 160, 3)),
(MULTISCENE_CZI, (32, 32)),
],
)
def test_for_multiscene_widget(
make_napari_viewer,
resources_dir: Path,
filename: str,
in_memory: bool,
expected_dtype,
expected_shape: tuple[int, ...],
) -> None:
# Make a viewer
viewer = make_napari_viewer()
assert len(viewer.layers) == 0
assert len(viewer.window._dock_widgets) == 0

# Resolve filename to filepath
if isinstance(filename, str):
path = str(resources_dir / filename)

# Get reader
reader = napari_get_reader(path, in_memory)

if reader is not None:
# Call reader on path
reader(path)

if len(viewer.window._dock_widgets) != 0:
# Get the second scene
viewer.window._dock_widgets[f"{filename} :: Scenes"].widget().setCurrentRow(
1
)
data = viewer.layers[0].data
assert isinstance(data, expected_dtype)
assert data.shape == expected_shape
else:
data, _, _ = reader(path)[0]
assert isinstance(data, expected_dtype)
assert data.shape == expected_shape
Loading

0 comments on commit 31d60c5

Please sign in to comment.