Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New image utilities widget #88

Merged
merged 20 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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 @@
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 @@
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

Check warning on line 129 in src/napari_ndev/_tests/test_napari_reader.py

View check run for this annotation

Codecov / codecov/patch

src/napari_ndev/_tests/test_napari_reader.py#L127-L129

Added lines #L127 - L129 were not covered by tests
Loading
Loading