From 586533de6148ff3c0a6c8453f31e01ec2483ec82 Mon Sep 17 00:00:00 2001 From: Daviddierickx Date: Thu, 21 Sep 2023 18:17:16 +1000 Subject: [PATCH] initial commit --- setup.cfg | 7 +- src/napari_openfibsem/__init__.py | 13 +--- src/napari_openfibsem/_reader.py | 72 ------------------- src/napari_openfibsem/_sample_data.py | 21 ------ src/napari_openfibsem/_tests/__init__.py | 0 src/napari_openfibsem/_tests/test_reader.py | 31 -------- .../_tests/test_sample_data.py | 7 -- src/napari_openfibsem/_tests/test_widget.py | 36 ---------- src/napari_openfibsem/_tests/test_writer.py | 7 -- src/napari_openfibsem/_widget.py | 46 ------------ src/napari_openfibsem/_writer.py | 64 ----------------- src/napari_openfibsem/app.py | 7 ++ src/napari_openfibsem/napari.yaml | 53 +++----------- 13 files changed, 23 insertions(+), 341 deletions(-) delete mode 100644 src/napari_openfibsem/_reader.py delete mode 100644 src/napari_openfibsem/_sample_data.py delete mode 100644 src/napari_openfibsem/_tests/__init__.py delete mode 100644 src/napari_openfibsem/_tests/test_reader.py delete mode 100644 src/napari_openfibsem/_tests/test_sample_data.py delete mode 100644 src/napari_openfibsem/_tests/test_widget.py delete mode 100644 src/napari_openfibsem/_tests/test_writer.py delete mode 100644 src/napari_openfibsem/_widget.py delete mode 100644 src/napari_openfibsem/_writer.py create mode 100644 src/napari_openfibsem/app.py diff --git a/setup.cfg b/setup.cfg index afd9670..bb7b56d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,11 +31,10 @@ project_urls = [options] packages = find: install_requires = - numpy - magicgui - qtpy + fibsem>=0.2.4a0 + autolamella>=0.2.4a1 -python_requires = >=3.8 +python_requires = >=3.9 include_package_data = True package_dir = =src diff --git a/src/napari_openfibsem/__init__.py b/src/napari_openfibsem/__init__.py index 2e91d97..e7d77e9 100644 --- a/src/napari_openfibsem/__init__.py +++ b/src/napari_openfibsem/__init__.py @@ -4,16 +4,9 @@ except ImportError: __version__ = "unknown" -from ._reader import napari_get_reader -from ._sample_data import make_sample_data -from ._widget import ExampleQWidget, example_magic_widget -from ._writer import write_multiple, write_single_image +from .app import autolamella_ui, autoliftout_ui __all__ = ( - "napari_get_reader", - "write_single_image", - "write_multiple", - "make_sample_data", - "ExampleQWidget", - "example_magic_widget", + "autolamella_ui", + "autoliftout_ui", ) diff --git a/src/napari_openfibsem/_reader.py b/src/napari_openfibsem/_reader.py deleted file mode 100644 index 8d93ff9..0000000 --- a/src/napari_openfibsem/_reader.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -This module is an example of a barebones numpy reader plugin for napari. - -It implements the Reader specification, but your plugin may choose to -implement multiple readers or even other plugin contributions. see: -https://napari.org/stable/plugins/guides.html?#readers -""" -import numpy as np - - -def napari_get_reader(path): - """A basic implementation of a Reader contribution. - - Parameters - ---------- - path : str or list of str - Path to file, or list of paths. - - Returns - ------- - function or None - If the path is a recognized format, return a function that accepts the - same path or list of paths, and returns a list of layer data tuples. - """ - if isinstance(path, list): - # reader plugins may be handed single path, or a list of paths. - # if it is a list, it is assumed to be an image stack... - # so we are only going to look at the first file. - path = path[0] - - # if we know we cannot read the file, we immediately return None. - if not path.endswith(".npy"): - return None - - # otherwise we return the *function* that can read ``path``. - return reader_function - - -def reader_function(path): - """Take a path or list of paths and return a list of LayerData tuples. - - Readers are expected to return data as a list of tuples, where each tuple - is (data, [add_kwargs, [layer_type]]), "add_kwargs" and "layer_type" are - both optional. - - Parameters - ---------- - path : str or list of str - Path to file, or list of paths. - - Returns - ------- - layer_data : list of tuples - A list of LayerData tuples where each tuple in the list contains - (data, metadata, layer_type), where data is a numpy array, metadata is - a dict of keyword arguments for the corresponding viewer.add_* method - in napari, and layer_type is a lower-case string naming the type of - layer. Both "meta", and "layer_type" are optional. napari will - default to layer_type=="image" if not provided - """ - # handle both a string and a list of strings - paths = [path] if isinstance(path, str) else path - # load all files into array - arrays = [np.load(_path) for _path in paths] - # stack arrays into single array - data = np.squeeze(np.stack(arrays)) - - # optional kwargs for the corresponding viewer.add_* method - add_kwargs = {} - - layer_type = "image" # optional, default is "image" - return [(data, add_kwargs, layer_type)] diff --git a/src/napari_openfibsem/_sample_data.py b/src/napari_openfibsem/_sample_data.py deleted file mode 100644 index 453db51..0000000 --- a/src/napari_openfibsem/_sample_data.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -This module is an example of a barebones sample data provider for napari. - -It implements the "sample data" specification. -see: https://napari.org/stable/plugins/guides.html?#sample-data - -Replace code below according to your needs. -""" -from __future__ import annotations - -import numpy - - -def make_sample_data(): - """Generates an image""" - # Return list of tuples - # [(data1, add_image_kwargs1), (data2, add_image_kwargs2)] - # Check the documentation for more information about the - # add_image_kwargs - # https://napari.org/stable/api/napari.Viewer.html#napari.Viewer.add_image - return [(numpy.random.rand(512, 512), {})] diff --git a/src/napari_openfibsem/_tests/__init__.py b/src/napari_openfibsem/_tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/napari_openfibsem/_tests/test_reader.py b/src/napari_openfibsem/_tests/test_reader.py deleted file mode 100644 index 20a1c49..0000000 --- a/src/napari_openfibsem/_tests/test_reader.py +++ /dev/null @@ -1,31 +0,0 @@ -import numpy as np - -from napari_openfibsem import napari_get_reader - - -# tmp_path is a pytest fixture -def test_reader(tmp_path): - """An example of how you might test your plugin.""" - - # write some fake data using your supported file format - my_test_file = str(tmp_path / "myfile.npy") - original_data = np.random.rand(20, 20) - np.save(my_test_file, original_data) - - # try to read it back in - reader = napari_get_reader(my_test_file) - assert callable(reader) - - # make sure we're delivering the right format - layer_data_list = reader(my_test_file) - assert isinstance(layer_data_list, list) and len(layer_data_list) > 0 - layer_data_tuple = layer_data_list[0] - assert isinstance(layer_data_tuple, tuple) and len(layer_data_tuple) > 0 - - # make sure it's the same as it started - np.testing.assert_allclose(original_data, layer_data_tuple[0]) - - -def test_get_reader_pass(): - reader = napari_get_reader("fake.file") - assert reader is None diff --git a/src/napari_openfibsem/_tests/test_sample_data.py b/src/napari_openfibsem/_tests/test_sample_data.py deleted file mode 100644 index 8a94862..0000000 --- a/src/napari_openfibsem/_tests/test_sample_data.py +++ /dev/null @@ -1,7 +0,0 @@ -# from napari_openfibsem import make_sample_data - -# add your tests here... - - -def test_something(): - pass diff --git a/src/napari_openfibsem/_tests/test_widget.py b/src/napari_openfibsem/_tests/test_widget.py deleted file mode 100644 index 7b8b696..0000000 --- a/src/napari_openfibsem/_tests/test_widget.py +++ /dev/null @@ -1,36 +0,0 @@ -import numpy as np - -from napari_openfibsem import ExampleQWidget, example_magic_widget - - -# make_napari_viewer is a pytest fixture that returns a napari viewer object -# capsys is a pytest fixture that captures stdout and stderr output streams -def test_example_q_widget(make_napari_viewer, capsys): - # make viewer and add an image layer using our fixture - viewer = make_napari_viewer() - viewer.add_image(np.random.random((100, 100))) - - # create our widget, passing in the viewer - my_widget = ExampleQWidget(viewer) - - # call our widget method - my_widget._on_click() - - # read captured output and check that it's as we expected - captured = capsys.readouterr() - assert captured.out == "napari has 1 layers\n" - - -def test_example_magic_widget(make_napari_viewer, capsys): - viewer = make_napari_viewer() - layer = viewer.add_image(np.random.random((100, 100))) - - # this time, our widget will be a MagicFactory or FunctionGui instance - my_widget = example_magic_widget() - - # if we "call" this object, it'll execute our function - my_widget(viewer.layers[0]) - - # read captured output and check that it's as we expected - captured = capsys.readouterr() - assert captured.out == f"you have selected {layer}\n" diff --git a/src/napari_openfibsem/_tests/test_writer.py b/src/napari_openfibsem/_tests/test_writer.py deleted file mode 100644 index 19c6202..0000000 --- a/src/napari_openfibsem/_tests/test_writer.py +++ /dev/null @@ -1,7 +0,0 @@ -# from napari_openfibsem import write_single_image, write_multiple - -# add your tests here... - - -def test_something(): - pass diff --git a/src/napari_openfibsem/_widget.py b/src/napari_openfibsem/_widget.py deleted file mode 100644 index fe7e1e7..0000000 --- a/src/napari_openfibsem/_widget.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -This module is an example of a barebones QWidget plugin for napari - -It implements the Widget specification. -see: https://napari.org/stable/plugins/guides.html?#widgets - -Replace code below according to your needs. -""" -from typing import TYPE_CHECKING - -from magicgui import magic_factory -from qtpy.QtWidgets import QHBoxLayout, QPushButton, QWidget - -if TYPE_CHECKING: - import napari - - -class ExampleQWidget(QWidget): - # your QWidget.__init__ can optionally request the napari viewer instance - # in one of two ways: - # 1. use a parameter called `napari_viewer`, as done here - # 2. use a type annotation of 'napari.viewer.Viewer' for any parameter - def __init__(self, napari_viewer): - super().__init__() - self.viewer = napari_viewer - - btn = QPushButton("Click me!") - btn.clicked.connect(self._on_click) - - self.setLayout(QHBoxLayout()) - self.layout().addWidget(btn) - - def _on_click(self): - print("napari has", len(self.viewer.layers), "layers") - - -@magic_factory -def example_magic_widget(img_layer: "napari.layers.Image"): - print(f"you have selected {img_layer}") - - -# Uses the `autogenerate: true` flag in the plugin manifest -# to indicate it should be wrapped as a magicgui to autogenerate -# a widget. -def example_function_widget(img_layer: "napari.layers.Image"): - print(f"you have selected {img_layer}") diff --git a/src/napari_openfibsem/_writer.py b/src/napari_openfibsem/_writer.py deleted file mode 100644 index e67fcc9..0000000 --- a/src/napari_openfibsem/_writer.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -This module is an example of a barebones writer plugin for napari. - -It implements the Writer specification. -see: https://napari.org/stable/plugins/guides.html?#writers - -Replace code below according to your needs. -""" -from __future__ import annotations - -from typing import TYPE_CHECKING, Any, List, Sequence, Tuple, Union - -if TYPE_CHECKING: - DataType = Union[Any, Sequence[Any]] - FullLayerData = Tuple[DataType, dict, str] - - -def write_single_image(path: str, data: Any, meta: dict) -> List[str]: - """Writes a single image layer. - - Parameters - ---------- - path : str - A string path indicating where to save the image file. - data : The layer data - The `.data` attribute from the napari layer. - meta : dict - A dictionary containing all other attributes from the napari layer - (excluding the `.data` layer attribute). - - Returns - ------- - [path] : A list containing the string path to the saved file. - """ - - # implement your writer logic here ... - - # return path to any file(s) that were successfully written - return [path] - - -def write_multiple(path: str, data: List[FullLayerData]) -> List[str]: - """Writes multiple layers of different types. - - Parameters - ---------- - path : str - A string path indicating where to save the data file(s). - data : A list of layer tuples. - Tuples contain three elements: (data, meta, layer_type) - `data` is the layer data - `meta` is a dictionary containing all other metadata attributes - from the napari layer (excluding the `.data` layer attribute). - `layer_type` is a string, eg: "image", "labels", "surface", etc. - - Returns - ------- - [path] : A list containing (potentially multiple) string paths to the saved file(s). - """ - - # implement your writer logic here ... - - # return path to any file(s) that were successfully written - return [path] diff --git a/src/napari_openfibsem/app.py b/src/napari_openfibsem/app.py new file mode 100644 index 0000000..5ea0313 --- /dev/null +++ b/src/napari_openfibsem/app.py @@ -0,0 +1,7 @@ + + +from autolamella.ui.AutoLamellaUI import AutoLamellaUI +from autolamella.liftout.ui.AutoLiftoutUIv2 import AutoLiftoutUIv2 +autolamella_ui = AutoLamellaUI +autoliftout_ui = AutoLiftoutUIv2 + diff --git a/src/napari_openfibsem/napari.yaml b/src/napari_openfibsem/napari.yaml index ece04d8..d2e6838 100644 --- a/src/napari_openfibsem/napari.yaml +++ b/src/napari_openfibsem/napari.yaml @@ -2,47 +2,14 @@ name: napari-openfibsem display_name: OpenFIBSEM Napari contributions: commands: - - id: napari-openfibsem.get_reader - python_name: napari_openfibsem._reader:napari_get_reader - title: Open data with OpenFIBSEM Napari - - id: napari-openfibsem.write_multiple - python_name: napari_openfibsem._writer:write_multiple - title: Save multi-layer data with OpenFIBSEM Napari - - id: napari-openfibsem.write_single_image - python_name: napari_openfibsem._writer:write_single_image - title: Save image data with OpenFIBSEM Napari - - id: napari-openfibsem.make_sample_data - python_name: napari_openfibsem._sample_data:make_sample_data - title: Load sample data from OpenFIBSEM Napari - - id: napari-openfibsem.make_qwidget - python_name: napari_openfibsem._widget:ExampleQWidget - title: Make example QWidget - - id: napari-openfibsem.make_magic_widget - python_name: napari_openfibsem._widget:example_magic_widget - title: Make example magic widget - - id: napari-openfibsem.make_func_widget - python_name: napari_openfibsem._widget:example_function_widget - title: Make example function widget - readers: - - command: napari-openfibsem.get_reader - accepts_directories: false - filename_patterns: ['*.npy'] - writers: - - command: napari-openfibsem.write_multiple - layer_types: ['image*','labels*'] - filename_extensions: [] - - command: napari-openfibsem.write_single_image - layer_types: ['image'] - filename_extensions: ['.npy'] - sample_data: - - command: napari-openfibsem.make_sample_data - display_name: OpenFIBSEM Napari - key: unique_id.1 + - id: napari-openfibsem.autolamella + python_name: napari_openfibsem.app:autolamella_ui + title: AutoLamella UI + - id: napari-openfibsem.autoliftout + python_name: napari_openfibsem.app:autoliftout_ui + title: AutoLiftout UI widgets: - - command: napari-openfibsem.make_qwidget - display_name: Example QWidget - - command: napari-openfibsem.make_magic_widget - display_name: Example Magic Widget - - command: napari-openfibsem.make_func_widget - autogenerate: true - display_name: Example Function Widget + - command: napari-openfibsem.autolamella + display_name: AutoLamella UI + - command: napari-openfibsem.autoliftout + display_name: AutoLiftout UI