napari-tmidas 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ try:
2
+ from ._version import version as __version__
3
+ except ImportError:
4
+ __version__ = "unknown"
5
+
6
+ from ._reader import napari_get_reader
7
+ from ._sample_data import make_sample_data
8
+ from ._widget import (
9
+ ExampleQWidget,
10
+ ImageThreshold,
11
+ threshold_autogenerate_widget,
12
+ threshold_magic_widget,
13
+ )
14
+ from ._writer import write_multiple, write_single_image
15
+
16
+ __all__ = (
17
+ "napari_get_reader",
18
+ "write_single_image",
19
+ "write_multiple",
20
+ "make_sample_data",
21
+ "ExampleQWidget",
22
+ "ImageThreshold",
23
+ "threshold_autogenerate_widget",
24
+ "threshold_magic_widget",
25
+ )
@@ -0,0 +1,73 @@
1
+ """
2
+ This module is an example of a barebones numpy reader plugin for napari.
3
+
4
+ It implements the Reader specification, but your plugin may choose to
5
+ implement multiple readers or even other plugin contributions. see:
6
+ https://napari.org/stable/plugins/guides.html?#readers
7
+ """
8
+
9
+ import numpy as np
10
+
11
+
12
+ def napari_get_reader(path):
13
+ """A basic implementation of a Reader contribution.
14
+
15
+ Parameters
16
+ ----------
17
+ path : str or list of str
18
+ Path to file, or list of paths.
19
+
20
+ Returns
21
+ -------
22
+ function or None
23
+ If the path is a recognized format, return a function that accepts the
24
+ same path or list of paths, and returns a list of layer data tuples.
25
+ """
26
+ if isinstance(path, list):
27
+ # reader plugins may be handed single path, or a list of paths.
28
+ # if it is a list, it is assumed to be an image stack...
29
+ # so we are only going to look at the first file.
30
+ path = path[0]
31
+
32
+ # if we know we cannot read the file, we immediately return None.
33
+ if not path.endswith(".npy"):
34
+ return None
35
+
36
+ # otherwise we return the *function* that can read ``path``.
37
+ return reader_function
38
+
39
+
40
+ def reader_function(path):
41
+ """Take a path or list of paths and return a list of LayerData tuples.
42
+
43
+ Readers are expected to return data as a list of tuples, where each tuple
44
+ is (data, [add_kwargs, [layer_type]]), "add_kwargs" and "layer_type" are
45
+ both optional.
46
+
47
+ Parameters
48
+ ----------
49
+ path : str or list of str
50
+ Path to file, or list of paths.
51
+
52
+ Returns
53
+ -------
54
+ layer_data : list of tuples
55
+ A list of LayerData tuples where each tuple in the list contains
56
+ (data, metadata, layer_type), where data is a numpy array, metadata is
57
+ a dict of keyword arguments for the corresponding viewer.add_* method
58
+ in napari, and layer_type is a lower-case string naming the type of
59
+ layer. Both "meta", and "layer_type" are optional. napari will
60
+ default to layer_type=="image" if not provided
61
+ """
62
+ # handle both a string and a list of strings
63
+ paths = [path] if isinstance(path, str) else path
64
+ # load all files into array
65
+ arrays = [np.load(_path) for _path in paths]
66
+ # stack arrays into single array
67
+ data = np.squeeze(np.stack(arrays))
68
+
69
+ # optional kwargs for the corresponding viewer.add_* method
70
+ add_kwargs = {}
71
+
72
+ layer_type = "image" # optional, default is "image"
73
+ return [(data, add_kwargs, layer_type)]
@@ -0,0 +1,22 @@
1
+ """
2
+ This module is an example of a barebones sample data provider for napari.
3
+
4
+ It implements the "sample data" specification.
5
+ see: https://napari.org/stable/plugins/guides.html?#sample-data
6
+
7
+ Replace code below according to your needs.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import numpy
13
+
14
+
15
+ def make_sample_data():
16
+ """Generates an image"""
17
+ # Return list of tuples
18
+ # [(data1, add_image_kwargs1), (data2, add_image_kwargs2)]
19
+ # Check the documentation for more information about the
20
+ # add_image_kwargs
21
+ # https://napari.org/stable/api/napari.Viewer.html#napari.Viewer.add_image
22
+ return [(numpy.random.rand(512, 512), {})]
File without changes
@@ -0,0 +1,31 @@
1
+ import numpy as np
2
+
3
+ from napari_tmidas import napari_get_reader
4
+
5
+
6
+ # tmp_path is a pytest fixture
7
+ def test_reader(tmp_path):
8
+ """An example of how you might test your plugin."""
9
+
10
+ # write some fake data using your supported file format
11
+ my_test_file = str(tmp_path / "myfile.npy")
12
+ original_data = np.random.rand(20, 20)
13
+ np.save(my_test_file, original_data)
14
+
15
+ # try to read it back in
16
+ reader = napari_get_reader(my_test_file)
17
+ assert callable(reader)
18
+
19
+ # make sure we're delivering the right format
20
+ layer_data_list = reader(my_test_file)
21
+ assert isinstance(layer_data_list, list) and len(layer_data_list) > 0
22
+ layer_data_tuple = layer_data_list[0]
23
+ assert isinstance(layer_data_tuple, tuple) and len(layer_data_tuple) > 0
24
+
25
+ # make sure it's the same as it started
26
+ np.testing.assert_allclose(original_data, layer_data_tuple[0])
27
+
28
+
29
+ def test_get_reader_pass():
30
+ reader = napari_get_reader("fake.file")
31
+ assert reader is None
@@ -0,0 +1,7 @@
1
+ # from napari_tmidas import make_sample_data
2
+
3
+ # add your tests here...
4
+
5
+
6
+ def test_something():
7
+ pass
@@ -0,0 +1,66 @@
1
+ import numpy as np
2
+
3
+ from napari_tmidas._widget import (
4
+ ExampleQWidget,
5
+ ImageThreshold,
6
+ threshold_autogenerate_widget,
7
+ threshold_magic_widget,
8
+ )
9
+
10
+
11
+ def test_threshold_autogenerate_widget():
12
+ # because our "widget" is a pure function, we can call it and
13
+ # test it independently of napari
14
+ im_data = np.random.random((100, 100))
15
+ thresholded = threshold_autogenerate_widget(im_data, 0.5)
16
+ assert thresholded.shape == im_data.shape
17
+ # etc.
18
+
19
+
20
+ # make_napari_viewer is a pytest fixture that returns a napari viewer object
21
+ # you don't need to import it, as long as napari is installed
22
+ # in your testing environment
23
+ def test_threshold_magic_widget(make_napari_viewer):
24
+ viewer = make_napari_viewer()
25
+ layer = viewer.add_image(np.random.random((100, 100)))
26
+
27
+ # our widget will be a MagicFactory or FunctionGui instance
28
+ my_widget = threshold_magic_widget()
29
+
30
+ # if we "call" this object, it'll execute our function
31
+ thresholded = my_widget(viewer.layers[0], 0.5)
32
+ assert thresholded.shape == layer.data.shape
33
+ # etc.
34
+
35
+
36
+ def test_image_threshold_widget(make_napari_viewer):
37
+ viewer = make_napari_viewer()
38
+ layer = viewer.add_image(np.random.random((100, 100)))
39
+ my_widget = ImageThreshold(viewer)
40
+
41
+ # because we saved our widgets as attributes of the container
42
+ # we can set their values without having to "interact" with the viewer
43
+ my_widget._image_layer_combo.value = layer
44
+ my_widget._threshold_slider.value = 0.5
45
+
46
+ # this allows us to run our functions directly and ensure
47
+ # correct results
48
+ my_widget._threshold_im()
49
+ assert len(viewer.layers) == 2
50
+
51
+
52
+ # capsys is a pytest fixture that captures stdout and stderr output streams
53
+ def test_example_q_widget(make_napari_viewer, capsys):
54
+ # make viewer and add an image layer using our fixture
55
+ viewer = make_napari_viewer()
56
+ viewer.add_image(np.random.random((100, 100)))
57
+
58
+ # create our widget, passing in the viewer
59
+ my_widget = ExampleQWidget(viewer)
60
+
61
+ # call our widget method
62
+ my_widget._on_click()
63
+
64
+ # read captured output and check that it's as we expected
65
+ captured = capsys.readouterr()
66
+ assert captured.out == "napari has 1 layers\n"
@@ -0,0 +1,7 @@
1
+ # from napari_tmidas import write_single_image, write_multiple
2
+
3
+ # add your tests here...
4
+
5
+
6
+ def test_something():
7
+ pass
@@ -0,0 +1,21 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
6
+ TYPE_CHECKING = False
7
+ if TYPE_CHECKING:
8
+ from typing import Tuple
9
+ from typing import Union
10
+
11
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
12
+ else:
13
+ VERSION_TUPLE = object
14
+
15
+ version: str
16
+ __version__: str
17
+ __version_tuple__: VERSION_TUPLE
18
+ version_tuple: VERSION_TUPLE
19
+
20
+ __version__ = version = '0.1.1'
21
+ __version_tuple__ = version_tuple = (0, 1, 1)
@@ -0,0 +1,129 @@
1
+ """
2
+ This module contains four napari widgets declared in
3
+ different ways:
4
+
5
+ - a pure Python function flagged with `autogenerate: true`
6
+ in the plugin manifest. Type annotations are used by
7
+ magicgui to generate widgets for each parameter. Best
8
+ suited for simple processing tasks - usually taking
9
+ in and/or returning a layer.
10
+ - a `magic_factory` decorated function. The `magic_factory`
11
+ decorator allows us to customize aspects of the resulting
12
+ GUI, including the widgets associated with each parameter.
13
+ Best used when you have a very simple processing task,
14
+ but want some control over the autogenerated widgets. If you
15
+ find yourself needing to define lots of nested functions to achieve
16
+ your functionality, maybe look at the `Container` widget!
17
+ - a `magicgui.widgets.Container` subclass. This provides lots
18
+ of flexibility and customization options while still supporting
19
+ `magicgui` widgets and convenience methods for creating widgets
20
+ from type annotations. If you want to customize your widgets and
21
+ connect callbacks, this is the best widget option for you.
22
+ - a `QWidget` subclass. This provides maximal flexibility but requires
23
+ full specification of widget layouts, callbacks, events, etc.
24
+
25
+ References:
26
+ - Widget specification: https://napari.org/stable/plugins/guides.html?#widgets
27
+ - magicgui docs: https://pyapp-kit.github.io/magicgui/
28
+
29
+ Replace code below according to your needs.
30
+ """
31
+
32
+ from typing import TYPE_CHECKING
33
+
34
+ from magicgui import magic_factory
35
+ from magicgui.widgets import CheckBox, Container, create_widget
36
+ from qtpy.QtWidgets import QHBoxLayout, QPushButton, QWidget
37
+ from skimage.util import img_as_float
38
+
39
+ if TYPE_CHECKING:
40
+ import napari
41
+
42
+
43
+ # Uses the `autogenerate: true` flag in the plugin manifest
44
+ # to indicate it should be wrapped as a magicgui to autogenerate
45
+ # a widget.
46
+ def threshold_autogenerate_widget(
47
+ img: "napari.types.ImageData",
48
+ threshold: "float",
49
+ ) -> "napari.types.LabelsData":
50
+ return img_as_float(img) > threshold
51
+
52
+
53
+ # the magic_factory decorator lets us customize aspects of our widget
54
+ # we specify a widget type for the threshold parameter
55
+ # and use auto_call=True so the function is called whenever
56
+ # the value of a parameter changes
57
+ @magic_factory(
58
+ threshold={"widget_type": "FloatSlider", "max": 1}, auto_call=True
59
+ )
60
+ def threshold_magic_widget(
61
+ img_layer: "napari.layers.Image", threshold: "float"
62
+ ) -> "napari.types.LabelsData":
63
+ return img_as_float(img_layer.data) > threshold
64
+
65
+
66
+ # if we want even more control over our widget, we can use
67
+ # magicgui `Container`
68
+ class ImageThreshold(Container):
69
+ def __init__(self, viewer: "napari.viewer.Viewer"):
70
+ super().__init__()
71
+ self._viewer = viewer
72
+ # use create_widget to generate widgets from type annotations
73
+ self._image_layer_combo = create_widget(
74
+ label="Image", annotation="napari.layers.Image"
75
+ )
76
+ self._threshold_slider = create_widget(
77
+ label="Threshold", annotation=float, widget_type="FloatSlider"
78
+ )
79
+ self._threshold_slider.min = 0
80
+ self._threshold_slider.max = 1
81
+ # use magicgui widgets directly
82
+ self._invert_checkbox = CheckBox(text="Keep pixels below threshold")
83
+
84
+ # connect your own callbacks
85
+ self._threshold_slider.changed.connect(self._threshold_im)
86
+ self._invert_checkbox.changed.connect(self._threshold_im)
87
+
88
+ # append into/extend the container with your widgets
89
+ self.extend(
90
+ [
91
+ self._image_layer_combo,
92
+ self._threshold_slider,
93
+ self._invert_checkbox,
94
+ ]
95
+ )
96
+
97
+ def _threshold_im(self):
98
+ image_layer = self._image_layer_combo.value
99
+ if image_layer is None:
100
+ return
101
+
102
+ image = img_as_float(image_layer.data)
103
+ name = image_layer.name + "_thresholded"
104
+ threshold = self._threshold_slider.value
105
+ if self._invert_checkbox.value:
106
+ thresholded = image < threshold
107
+ else:
108
+ thresholded = image > threshold
109
+ if name in self._viewer.layers:
110
+ self._viewer.layers[name].data = thresholded
111
+ else:
112
+ self._viewer.add_labels(thresholded, name=name)
113
+
114
+
115
+ class ExampleQWidget(QWidget):
116
+ # your QWidget.__init__ can optionally request the napari viewer instance
117
+ # use a type annotation of 'napari.viewer.Viewer' for any parameter
118
+ def __init__(self, viewer: "napari.viewer.Viewer"):
119
+ super().__init__()
120
+ self.viewer = viewer
121
+
122
+ btn = QPushButton("Click me!")
123
+ btn.clicked.connect(self._on_click)
124
+
125
+ self.setLayout(QHBoxLayout())
126
+ self.layout().addWidget(btn)
127
+
128
+ def _on_click(self):
129
+ print("napari has", len(self.viewer.layers), "layers")
@@ -0,0 +1,66 @@
1
+ """
2
+ This module is an example of a barebones writer plugin for napari.
3
+
4
+ It implements the Writer specification.
5
+ see: https://napari.org/stable/plugins/guides.html?#writers
6
+
7
+ Replace code below according to your needs.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from collections.abc import Sequence
13
+ from typing import TYPE_CHECKING, Any, Union
14
+
15
+ if TYPE_CHECKING:
16
+ DataType = Union[Any, Sequence[Any]]
17
+ FullLayerData = tuple[DataType, dict, str]
18
+
19
+
20
+ def write_single_image(path: str, data: Any, meta: dict) -> list[str]:
21
+ """Writes a single image layer.
22
+
23
+ Parameters
24
+ ----------
25
+ path : str
26
+ A string path indicating where to save the image file.
27
+ data : The layer data
28
+ The `.data` attribute from the napari layer.
29
+ meta : dict
30
+ A dictionary containing all other attributes from the napari layer
31
+ (excluding the `.data` layer attribute).
32
+
33
+ Returns
34
+ -------
35
+ [path] : A list containing the string path to the saved file.
36
+ """
37
+
38
+ # implement your writer logic here ...
39
+
40
+ # return path to any file(s) that were successfully written
41
+ return [path]
42
+
43
+
44
+ def write_multiple(path: str, data: list[FullLayerData]) -> list[str]:
45
+ """Writes multiple layers of different types.
46
+
47
+ Parameters
48
+ ----------
49
+ path : str
50
+ A string path indicating where to save the data file(s).
51
+ data : A list of layer tuples.
52
+ Tuples contain three elements: (data, meta, layer_type)
53
+ `data` is the layer data
54
+ `meta` is a dictionary containing all other metadata attributes
55
+ from the napari layer (excluding the `.data` layer attribute).
56
+ `layer_type` is a string, eg: "image", "labels", "surface", etc.
57
+
58
+ Returns
59
+ -------
60
+ [path] : A list containing (potentially multiple) string paths to the saved file(s).
61
+ """
62
+
63
+ # implement your writer logic here ...
64
+
65
+ # return path to any file(s) that were successfully written
66
+ return [path]
@@ -0,0 +1,57 @@
1
+ name: napari-tmidas
2
+ display_name: T-MIDAS
3
+ # use 'hidden' to remove plugin from napari hub search results
4
+ visibility: public
5
+ # see https://napari.org/stable/plugins/technical_references/manifest.html#fields for valid categories
6
+ categories: ["Annotation", "Segmentation", "Acquisition"]
7
+ contributions:
8
+ commands:
9
+ - id: napari-tmidas.get_reader
10
+ python_name: napari_tmidas._reader:napari_get_reader
11
+ title: Open data with T-MIDAS
12
+ - id: napari-tmidas.write_multiple
13
+ python_name: napari_tmidas._writer:write_multiple
14
+ title: Save multi-layer data with T-MIDAS
15
+ - id: napari-tmidas.write_single_image
16
+ python_name: napari_tmidas._writer:write_single_image
17
+ title: Save image data with T-MIDAS
18
+ - id: napari-tmidas.make_sample_data
19
+ python_name: napari_tmidas._sample_data:make_sample_data
20
+ title: Load sample data from T-MIDAS
21
+ - id: napari-tmidas.make_container_widget
22
+ python_name: napari_tmidas:ImageThreshold
23
+ title: Make threshold Container widget
24
+ - id: napari-tmidas.make_magic_widget
25
+ python_name: napari_tmidas:threshold_magic_widget
26
+ title: Make threshold magic widget
27
+ - id: napari-tmidas.make_function_widget
28
+ python_name: napari_tmidas:threshold_autogenerate_widget
29
+ title: Make threshold function widget
30
+ - id: napari-tmidas.make_qwidget
31
+ python_name: napari_tmidas:ExampleQWidget
32
+ title: Make example QWidget
33
+ readers:
34
+ - command: napari-tmidas.get_reader
35
+ accepts_directories: false
36
+ filename_patterns: ['*.npy']
37
+ writers:
38
+ - command: napari-tmidas.write_multiple
39
+ layer_types: ['image*','labels*']
40
+ filename_extensions: []
41
+ - command: napari-tmidas.write_single_image
42
+ layer_types: ['image']
43
+ filename_extensions: ['.npy']
44
+ sample_data:
45
+ - command: napari-tmidas.make_sample_data
46
+ display_name: T-MIDAS
47
+ key: unique_id.1
48
+ widgets:
49
+ - command: napari-tmidas.make_container_widget
50
+ display_name: Container Threshold
51
+ - command: napari-tmidas.make_magic_widget
52
+ display_name: Magic Threshold
53
+ - command: napari-tmidas.make_function_widget
54
+ autogenerate: true
55
+ display_name: Autogenerate Threshold
56
+ - command: napari-tmidas.make_qwidget
57
+ display_name: Example QWidget
@@ -0,0 +1,28 @@
1
+
2
+ Copyright (c) 2025, Marco Meer
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ * Neither the name of copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.2
2
+ Name: napari-tmidas
3
+ Version: 0.1.1
4
+ Summary: Tissue Microscopy Image Data Analysis Suite
5
+ Author: Marco Meer
6
+ Author-email: marco.meer@pm.me
7
+ License:
8
+ Copyright (c) 2025, Marco Meer
9
+ All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ * Redistributions of source code must retain the above copyright notice, this
15
+ list of conditions and the following disclaimer.
16
+
17
+ * Redistributions in binary form must reproduce the above copyright notice,
18
+ this list of conditions and the following disclaimer in the documentation
19
+ and/or other materials provided with the distribution.
20
+
21
+ * Neither the name of copyright holder nor the names of its
22
+ contributors may be used to endorse or promote products derived from
23
+ this software without specific prior written permission.
24
+
25
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
+
36
+ Project-URL: Bug Tracker, https://github.com/macromeer/napari-tmidas/issues
37
+ Project-URL: Documentation, https://github.com/macromeer/napari-tmidas#README.md
38
+ Project-URL: Source Code, https://github.com/macromeer/napari-tmidas
39
+ Project-URL: User Support, https://github.com/macromeer/napari-tmidas/issues
40
+ Classifier: Development Status :: 2 - Pre-Alpha
41
+ Classifier: Framework :: napari
42
+ Classifier: Intended Audience :: Developers
43
+ Classifier: License :: OSI Approved :: BSD License
44
+ Classifier: Operating System :: OS Independent
45
+ Classifier: Programming Language :: Python
46
+ Classifier: Programming Language :: Python :: 3
47
+ Classifier: Programming Language :: Python :: 3 :: Only
48
+ Classifier: Programming Language :: Python :: 3.9
49
+ Classifier: Programming Language :: Python :: 3.10
50
+ Classifier: Programming Language :: Python :: 3.11
51
+ Classifier: Programming Language :: Python :: 3.12
52
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
53
+ Requires-Python: >=3.9
54
+ Description-Content-Type: text/markdown
55
+ License-File: LICENSE
56
+ Requires-Dist: numpy
57
+ Requires-Dist: magicgui
58
+ Requires-Dist: qtpy
59
+ Requires-Dist: scikit-image
60
+ Provides-Extra: testing
61
+ Requires-Dist: tox; extra == "testing"
62
+ Requires-Dist: pytest; extra == "testing"
63
+ Requires-Dist: pytest-cov; extra == "testing"
64
+ Requires-Dist: pytest-qt; extra == "testing"
65
+ Requires-Dist: napari; extra == "testing"
66
+ Requires-Dist: pyqt5; extra == "testing"
67
+
68
+ # napari-tmidas
69
+
70
+ [![License BSD-3](https://img.shields.io/pypi/l/napari-tmidas.svg?color=green)](https://github.com/macromeer/napari-tmidas/raw/main/LICENSE)
71
+ [![PyPI](https://img.shields.io/pypi/v/napari-tmidas.svg?color=green)](https://pypi.org/project/napari-tmidas)
72
+ [![Python Version](https://img.shields.io/pypi/pyversions/napari-tmidas.svg?color=green)](https://python.org)
73
+ [![tests](https://github.com/macromeer/napari-tmidas/workflows/tests/badge.svg)](https://github.com/macromeer/napari-tmidas/actions)
74
+ [![codecov](https://codecov.io/gh/macromeer/napari-tmidas/branch/main/graph/badge.svg)](https://codecov.io/gh/macromeer/napari-tmidas)
75
+ [![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-tmidas)](https://napari-hub.org/plugins/napari-tmidas)
76
+
77
+ Tissue Microscopy Image Data Analysis Suite
78
+
79
+ ----------------------------------
80
+
81
+ This [napari] plugin was generated with [copier] using the [napari-plugin-template].
82
+
83
+ <!--
84
+ Don't miss the full getting started guide to set up your new package:
85
+ https://github.com/napari/napari-plugin-template#getting-started
86
+
87
+ and review the napari docs for plugin developers:
88
+ https://napari.org/stable/plugins/index.html
89
+ -->
90
+
91
+ ## Installation
92
+
93
+ You can install `napari-tmidas` via [pip]:
94
+
95
+ pip install napari-tmidas
96
+
97
+
98
+
99
+ To install latest development version :
100
+
101
+ pip install git+https://github.com/macromeer/napari-tmidas.git
102
+
103
+
104
+ ## Contributing
105
+
106
+ Contributions are very welcome. Tests can be run with [tox], please ensure
107
+ the coverage at least stays the same before you submit a pull request.
108
+
109
+ ## License
110
+
111
+ Distributed under the terms of the [BSD-3] license,
112
+ "napari-tmidas" is free and open source software
113
+
114
+ ## Issues
115
+
116
+ If you encounter any problems, please [file an issue] along with a detailed description.
117
+
118
+ [napari]: https://github.com/napari/napari
119
+ [copier]: https://copier.readthedocs.io/en/stable/
120
+ [@napari]: https://github.com/napari
121
+ [MIT]: http://opensource.org/licenses/MIT
122
+ [BSD-3]: http://opensource.org/licenses/BSD-3-Clause
123
+ [GNU GPL v3.0]: http://www.gnu.org/licenses/gpl-3.0.txt
124
+ [GNU LGPL v3.0]: http://www.gnu.org/licenses/lgpl-3.0.txt
125
+ [Apache Software License 2.0]: http://www.apache.org/licenses/LICENSE-2.0
126
+ [Mozilla Public License 2.0]: https://www.mozilla.org/media/MPL/2.0/index.txt
127
+ [napari-plugin-template]: https://github.com/napari/napari-plugin-template
128
+
129
+ [file an issue]: https://github.com/macromeer/napari-tmidas/issues
130
+
131
+ [napari]: https://github.com/napari/napari
132
+ [tox]: https://tox.readthedocs.io/en/latest/
133
+ [pip]: https://pypi.org/project/pip/
134
+ [PyPI]: https://pypi.org/
@@ -0,0 +1,18 @@
1
+ napari_tmidas/__init__.py,sha256=cVpVT4zJ5I9N6YFige0iySIMW3JzE35KKnEy-PFpFx0,592
2
+ napari_tmidas/_reader.py,sha256=A9_hdDxtVkVGmbOsbqgnARCSvpEh7GGPo7ylzmbnu8o,2485
3
+ napari_tmidas/_sample_data.py,sha256=khuv1jemz_fCjqNwEKMFf83Ju0EN4S89IKydsUMmUxw,645
4
+ napari_tmidas/_version.py,sha256=Mmxse1R0ki5tjz9qzU8AQyqUsLt8nTyCAbYQp8R87PU,511
5
+ napari_tmidas/_widget.py,sha256=u9uf9WILAwZg_InhFyjWInY4ej1TV1a59dR8Fe3vNF8,4794
6
+ napari_tmidas/_writer.py,sha256=wbVfHFjjHdybSg37VR4lVmL-kdCkDZsUPDJ66AVLaFQ,1941
7
+ napari_tmidas/napari.yaml,sha256=XRz2siVLEciSqUHv1tlLjX9BB0Sc1jBRB3KyAN2ISgA,2276
8
+ napari_tmidas/_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ napari_tmidas/_tests/test_reader.py,sha256=gN_2StATLZYUL56X27ImJTVru_qSoFiY4vtgajcx3H0,975
10
+ napari_tmidas/_tests/test_sample_data.py,sha256=D1HU_C3hWpO3mlSW_7Z94xaYHDtxz0XUrMjQoYop9Ag,104
11
+ napari_tmidas/_tests/test_widget.py,sha256=I_d-Cra_CTcS0QdMItg_HMphvhj0XCx81JnFyCHk9lg,2204
12
+ napari_tmidas/_tests/test_writer.py,sha256=4_MlZM9a5So74J16_4tIOJc6pwTOw9R0-oAE_YioIx4,122
13
+ napari_tmidas-0.1.1.dist-info/LICENSE,sha256=tSjiOqj57exmEIfP2YVPCEeQf0cH49S6HheQR8IiY3g,1485
14
+ napari_tmidas-0.1.1.dist-info/METADATA,sha256=TuiFctic_XaF8TxYPQYuLJOlVTKiF_Qxl0Lh6SiYBb4,5850
15
+ napari_tmidas-0.1.1.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
16
+ napari_tmidas-0.1.1.dist-info/entry_points.txt,sha256=fbVjzbJTm4aDMIBtel1Lyqvq-CwXY7wmCOo_zJ-jtRY,60
17
+ napari_tmidas-0.1.1.dist-info/top_level.txt,sha256=63ybdxCZ4SeT13f_Ou4TsivGV_2Gtm_pJOXToAt30_E,14
18
+ napari_tmidas-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [napari.manifest]
2
+ napari-tmidas = napari_tmidas:napari.yaml
@@ -0,0 +1 @@
1
+ napari_tmidas