Skip to content

Commit

Permalink
Merge branch 'develop' into pre-commit-ci-update-config
Browse files Browse the repository at this point in the history
  • Loading branch information
Czaki authored Dec 10, 2024
2 parents 62702ad + 917c93a commit 117c0d1
Show file tree
Hide file tree
Showing 17 changed files with 90 additions and 37 deletions.
3 changes: 2 additions & 1 deletion .github/project_dict.pws
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 12
personal_ws-1.1 en 14
napari
autoupdate
aspell
Expand All @@ -12,3 +12,4 @@ pre
bool
changelog
czi
PartSeg
2 changes: 1 addition & 1 deletion launcher.spec
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ hiddenimports = (
"psygnal._weak_callback",
"imagecodecs._imagecodecs",
"PartSeg.plugins.napari_widgets",
"PartSegCore.napari_plugins",
"PartSegCore.napari_io",
]
+ [x.module_name for x in imageio_known_plugins.values()]
+ [x for x in collect_submodules("skimage") if "tests" not in x]
Expand Down
10 changes: 5 additions & 5 deletions package/PartSeg/common_backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This module contains non gui Qt based components
"""

import contextlib
import os.path
from typing import TYPE_CHECKING

Expand All @@ -14,11 +15,10 @@ def napari_get_settings(path=None) -> "NapariSettings":

if path is not None:
path = os.path.join(path, "settings.yaml")

try:
return _napari_get_settings(path)
except Exception: # pylint: disable=broad-except
return _napari_get_settings()
if path is not None:
with contextlib.suppress(Exception):
return _napari_get_settings(path)
return _napari_get_settings()


__all__ = ("napari_get_settings",)
7 changes: 3 additions & 4 deletions package/PartSeg/launcher_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ def _test_imports(): # pragma: no cover
from PartSeg._roi_mask.main_window import MainWindow as MaskMain
from PartSeg.common_backend.base_argparser import _setup_sentry
from PartSeg.common_gui.label_create import LabelChoose
from PartSeg.plugins import napari_widgets
from PartSegCore import napari_plugins
from PartSeg.plugins import napari_io, napari_widgets

if "BorderSmooth" not in dir(napari_widgets):
raise ImportError("napari_widgets not loaded")

if "load_image" not in dir(napari_plugins):
raise ImportError("napari_plugins not loaded")
if "load_image" not in dir(napari_io):
raise ImportError("napari_io not loaded")

with suppress(ImportError):
from napari.qt import get_app
Expand Down
19 changes: 12 additions & 7 deletions package/PartSeg/napari.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ contributions:
commands:
- id: PartSeg.load_roi_project
title: Get PartSeg ROI project Reader
python_name: PartSegCore.napari_plugins.load_roi_project:napari_get_reader
python_name: PartSeg.plugins.napari_io.load_roi_project:napari_get_reader
- id: PartSeg.load_image
title: Get Image Reader
python_name: PartSegCore.napari_plugins.load_image:napari_get_reader
python_name: PartSeg.plugins.napari_io.load_image:napari_get_reader
- id: PartSeg.write_tiff_image
title: Write tiff Image
python_name: PartSegCore.napari_plugins.save_tiff_layer:napari_write_images
python_name: PartSeg.plugins.napari_io.save_tiff_layer:napari_write_images
- id: PartSeg.write_tiff_labels
title: Write tiff Labels
python_name: PartSegCore.napari_plugins.save_tiff_layer:napari_write_labels
python_name: PartSeg.plugins.napari_io.save_tiff_layer:napari_write_labels
- id: PartSeg.load_mask_project
title: Get PartSeg mask project Reader
python_name: PartSegCore.napari_plugins.load_mask_project:napari_get_reader
python_name: PartSeg.plugins.napari_io.load_mask_project:napari_get_reader
- id: PartSeg.save_mask_roi
title: Write Labels as mask project
python_name: PartSegCore.napari_plugins.save_mask_roi:napari_write_labels
python_name: PartSeg.plugins.napari_io.save_mask_roi:napari_write_labels
- id: PartSeg.load_masked_image
title: Get Reader for image with mask
python_name: PartSegCore.napari_plugins.load_masked_image:napari_get_reader
python_name: PartSeg.plugins.napari_io.load_masked_image:napari_get_reader
- id: PartSeg.SimpleMeasurement
title: Create Simple Measurement
python_name: PartSeg.plugins.napari_widgets.simple_measurement_widget:SimpleMeasurement
Expand Down Expand Up @@ -77,6 +77,9 @@ contributions:
- id: PartSeg.Metadata
title: View Layer Metadata
python_name: PartSeg.plugins.napari_widgets:LayerMetadata
- id: PartSeg.Settings
title: PartSeg Settings
python_name: PartSeg.plugins.napari_widgets:SettingsEditor
readers:
- command: PartSeg.load_roi_project
filename_patterns:
Expand Down Expand Up @@ -162,3 +165,5 @@ contributions:
display_name: Watershed
- command: PartSeg.Metadata
display_name: Layer Metadata
- command: PartSeg.Settings
display_name: Settings Editor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from PartSegCore.napari_plugins import (
from PartSeg.plugins.napari_io import (
load_image,
load_mask_project,
load_masked_image,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import functools

from PartSeg.plugins.napari_io.loader import partseg_loader
from PartSegCore.analysis.load_functions import LoadStackImage
from PartSegCore.napari_plugins.loader import partseg_loader


def napari_get_reader(path: str):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import functools

from PartSeg.plugins.napari_io.loader import partseg_loader
from PartSegCore.mask.io_functions import LoadROI
from PartSegCore.napari_plugins.loader import partseg_loader


def napari_get_reader(path: str):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import functools
import os.path

from PartSeg.plugins.napari_io.loader import partseg_loader
from PartSegCore.mask.io_functions import LoadStackImageWithMask
from PartSegCore.napari_plugins.loader import partseg_loader


def napari_get_reader(path: str):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import functools
import os.path

from PartSeg.plugins.napari_io.loader import partseg_loader
from PartSegCore.analysis.load_functions import LoadProject
from PartSegCore.napari_plugins.loader import partseg_loader


def napari_get_reader(path: str):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import numpy as np
from packaging.version import parse as parse_version

from PartSeg.plugins.napari_widgets._settings import get_settings
from PartSegCore import UNIT_SCALE
from PartSegCore.analysis import ProjectTuple
from PartSegCore.io_utils import LoadBase, WrongFileTypeException
from PartSegCore.mask.io_functions import MaskProjectTuple
Expand Down Expand Up @@ -84,7 +86,8 @@ def _image_to_layers(project_info, scale, translate):
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()
settings = get_settings()
scale = project_info.image.normalized_scaling(UNIT_SCALE[settings.io_units.value])
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))
Expand Down
2 changes: 2 additions & 0 deletions package/PartSeg/plugins/napari_widgets/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from PartSeg._launcher.main_window import PartSegGUILauncher
from PartSeg.plugins.napari_widgets._settings import SettingsEditor
from PartSeg.plugins.napari_widgets.algorithm_widgets import (
BorderSmooth,
ConnectedComponents,
Expand Down Expand Up @@ -33,4 +34,5 @@
"SplitCoreObjects",
"Threshold",
"Watershed",
"SettingsEditor",
)
29 changes: 28 additions & 1 deletion package/PartSeg/plugins/napari_widgets/_settings.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import os

from magicgui.widgets import Container, create_widget
from napari.layers import Layer

from PartSeg._roi_analysis.partseg_settings import PartSettings
from PartSeg.common_backend import napari_get_settings
from PartSegCore import Units
from PartSegCore.json_hooks import PartSegEncoder

_SETTINGS = None
Expand All @@ -19,8 +21,16 @@ def default(self, o):
class PartSegNapariSettings(PartSettings):
json_encoder_class = PartSegNapariEncoder

@property
def io_units(self) -> Units:
return self.get("io_units", Units.nm)

def get_settings() -> PartSettings:
@io_units.setter
def io_units(self, value: Units):
self.set("io_units", value)


def get_settings() -> PartSegNapariSettings:
global _SETTINGS # noqa: PLW0603 # pylint: disable=global-statement
if _SETTINGS is None:
napari_settings = napari_get_settings()
Expand All @@ -31,3 +41,20 @@ def get_settings() -> PartSettings:
_SETTINGS = PartSegNapariSettings(os.path.join(save_path, "PartSeg_napari_plugins"))
_SETTINGS.load()
return _SETTINGS


class SettingsEditor(Container):
def __init__(self):
super().__init__()
self.settings = get_settings()
self.units_select = create_widget(self.settings.io_units, annotation=Units, label="Units for io")
self.units_select.changed.connect(self.units_selection_changed)
self.settings.connect_("io_units", self.units_changed)
self.append(self.units_select)

def units_selection_changed(self, value):
self.settings.io_units = value
self.settings.dump()

def units_changed(self):
self.units_select.value = self.settings.io_units
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
from napari.layers import Image, Labels, Layer
from packaging.version import parse as parse_version

from PartSegCore.analysis import ProjectTuple
from PartSegCore.mask.io_functions import LoadROIFromTIFF
from PartSegCore.napari_plugins.load_image import napari_get_reader as napari_get_reader_image
from PartSegCore.napari_plugins.load_mask_project import napari_get_reader as napari_get_reader_mask
from PartSegCore.napari_plugins.load_masked_image import napari_get_reader as napari_get_reader_mask_image
from PartSegCore.napari_plugins.load_roi_project import napari_get_reader as napari_get_reader_roi
from PartSegCore.napari_plugins.loader import project_to_layers
from PartSegCore.napari_plugins.save_mask_roi import napari_write_labels
from PartSegCore.napari_plugins.save_tiff_layer import (
from PartSeg.plugins.napari_io.load_image import napari_get_reader as napari_get_reader_image
from PartSeg.plugins.napari_io.load_mask_project import napari_get_reader as napari_get_reader_mask
from PartSeg.plugins.napari_io.load_masked_image import napari_get_reader as napari_get_reader_mask_image
from PartSeg.plugins.napari_io.load_roi_project import napari_get_reader as napari_get_reader_roi
from PartSeg.plugins.napari_io.loader import project_to_layers
from PartSeg.plugins.napari_io.save_mask_roi import napari_write_labels
from PartSeg.plugins.napari_io.save_tiff_layer import (
napari_write_images,
)
from PartSegCore.napari_plugins.save_tiff_layer import (
from PartSeg.plugins.napari_io.save_tiff_layer import (
napari_write_labels as napari_write_labels_tiff,
)
from PartSegCore.analysis import ProjectTuple
from PartSegCore.mask.io_functions import LoadROIFromTIFF
from PartSegImage import GenericImageReader
from PartSegImage import Image as PImage

Expand Down
20 changes: 18 additions & 2 deletions package/tests/test_PartSeg/test_napari_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from packaging.version import parse as parse_version
from qtpy.QtCore import QObject, QTimer, Signal

from PartSeg._roi_analysis.partseg_settings import PartSettings
from PartSeg._roi_analysis.profile_export import ExportDialog, ImportDialog
from PartSeg.common_gui.custom_load_dialog import CustomLoadDialog
from PartSeg.common_gui.custom_save_dialog import CustomSaveDialog
Expand Down Expand Up @@ -46,6 +45,7 @@
from PartSeg.plugins.napari_widgets.measurement_widget import update_properties
from PartSeg.plugins.napari_widgets.roi_extraction_algorithms import ProfilePreviewDialog, QInputDialog
from PartSeg.plugins.napari_widgets.search_label_widget import HIGHLIGHT_LABEL_NAME
from PartSegCore import Units
from PartSegCore.algorithm_describe_base import ROIExtractionProfile
from PartSegCore.analysis.algorithm_description import AnalysisAlgorithmSelection
from PartSegCore.analysis.load_functions import LoadProfileFromJSON
Expand Down Expand Up @@ -85,7 +85,7 @@ def check_direct_mode(layer):
@pytest.fixture(autouse=True)
def _clean_settings(tmp_path):
old_settings = _settings._SETTINGS
_settings._SETTINGS = PartSettings(tmp_path)
_settings._SETTINGS = _settings.PartSegNapariSettings(tmp_path)
yield
_settings._SETTINGS = old_settings

Expand Down Expand Up @@ -639,3 +639,19 @@ def test_add_layer_post_init(self, make_napari_viewer, qtbot):
def test_enum():
assert " " in str(CompareType.lower_threshold)
assert " " in str(FlowType.dark_center)


class TestSettingsWidget:
def test_create(self, qtbot):
w = _settings.SettingsEditor()
qtbot.addWidget(w.native)

def test_change_units(self, qtbot):
s = _settings.get_settings()
s.io_units = Units.µm
w = _settings.SettingsEditor()
qtbot.addWidget(w.native)
w.units_select.value = Units.nm
assert s.io_units == Units.nm
s.io_units = Units.mm
assert w.units_select.value == Units.mm

0 comments on commit 117c0d1

Please sign in to comment.