diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 7d452ebae8ad0d1ae9b3d7009569042a3e8c4ed7..dcc9a2b78e06b63b2a4a0c995aaf41bab730caf2 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.1.0
     hooks:
       - id: check-docstring-first
       - id: end-of-file-fixer
@@ -24,11 +24,11 @@ repos:
     hooks:
       - id: isort
   - repo: https://github.com/psf/black
-    rev: 21.11b1
+    rev: 22.1.0
     hooks:
       - id: black
   - repo: https://github.com/asottile/pyupgrade
-    rev: v2.29.1
+    rev: v2.31.1
     hooks:
       - id: pyupgrade
         args: [--py38-plus, --keep-runtime-typing]
diff --git a/src/napari_segment/_reader.py b/src/napari_segment/_reader.py
index 8c324fc583bceae3fc721491f5debc0ea059df72..80560e03a6cbe1d78a2691df8e208b294537307c 100644
--- a/src/napari_segment/_reader.py
+++ b/src/napari_segment/_reader.py
@@ -5,6 +5,7 @@ It implements the Reader specification, but your plugin may choose to
 implement multiple readers or even other plugin contributions. see:
 https://napari.org/plugins/stable/guides.html#readers
 """
+import nd2
 import numpy as np
 
 
@@ -29,13 +30,30 @@ def napari_get_reader(path):
         path = path[0]
 
     # if we know we cannot read the file, we immediately return None.
-    if not path.endswith(".npy"):
-        return None
+    if path.endswith(".nd2"):
+        return read_nd2
 
     # otherwise we return the *function* that can read ``path``.
     return reader_function
 
 
+def read_nd2(path):
+    data = nd2.ND2File(path)
+    ddata = data.to_dask()
+    return [
+        (
+            ddata,
+            dict(
+                channel_axis=1,
+                name=["BF", "fluo"],
+                colormap=["gray", "green"],
+                contrast_limits=[(8500, 35000), (150, 20000)],
+            ),
+            "image",
+        )
+    ]
+
+
 def reader_function(path):
     """Take a path or list of paths and return a list of LayerData tuples.
 
@@ -54,7 +72,8 @@ def reader_function(path):
         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.
+        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
     """
diff --git a/src/napari_segment/_widget.py b/src/napari_segment/_widget.py
index 7f2fc5d116fb41de6ace8fb15e7a359906cca142..a7c0317830f4a87d4a7acac4a22ad8502ed17aaa 100644
--- a/src/napari_segment/_widget.py
+++ b/src/napari_segment/_widget.py
@@ -6,8 +6,16 @@ see: https://napari.org/plugins/stable/guides.html#widgets
 
 Replace code below according to your needs.
 """
-from qtpy.QtWidgets import QWidget, QHBoxLayout, QPushButton
+from functools import partial
+from multiprocessing import Pool
+
+import napari
+import numpy as np
 from magicgui import magic_factory
+from qtpy.QtWidgets import QHBoxLayout, QPushButton, QWidget
+from scipy.ndimage import binary_dilation
+from segment.seg import segment_bf
+from skimage.measure import regionprops_table
 
 
 class ExampleQWidget(QWidget):
@@ -37,5 +45,53 @@ def example_magic_widget(img_layer: "napari.layers.Image"):
 # 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}")
+@magic_factory()
+def segment_organoid(
+    BF_layer: "napari.layers.Image",
+    fluo_layer: "napari.layers.Image",
+    donut=10,
+    thr: float = 0.4,
+) -> napari.types.LabelsData:
+    # frame = napari.current_viewer().cursor.position[0]
+    try:
+        p = Pool()
+        stack = list(
+            p.map(
+                partial(seg_frame, thr=thr, donut=donut),
+                zip(BF_layer.data.compute(), fluo_layer.data.compute()),
+            )
+        )
+    except Exception as e:
+        print(e.args)
+    finally:
+        p.close()
+
+    return np.array(stack)
+    # (bg_mask.astype('uint8'), {"name": "donut", **kwargs}, 'image')
+
+
+def seg_frame(data, thr, donut):
+    bf, fluo = data
+    label = segment_bf(bf, thr=thr, plot=False)
+    print(bf.dtype, bf.shape)
+    props = regionprops_table(
+        label,
+        intensity_image=fluo,
+        properties=(
+            "label",
+            "centroid",
+            "bbox",
+            "mean_intensity",
+            "area",
+            "major_axis_length",
+        ),
+    )
+    # print(props)
+    biggest_prop_index = np.argmax(props["area"])
+    label_of_biggest_object = props["label"][biggest_prop_index]
+    spheroid_mask = label == label_of_biggest_object
+    bg_mask = np.bitwise_xor(
+        binary_dilation(spheroid_mask, structure=np.ones((donut, donut))),
+        spheroid_mask,
+    )
+    return spheroid_mask.astype("uint16") + 2 * bg_mask.astype("uint8")
diff --git a/src/napari_segment/napari.yaml b/src/napari_segment/napari.yaml
index 45fe55a77c234b219e3c9e59dfa8031c7124df16..14dfbbb0fcd2f2613d67de57761b8998efdd758b 100644
--- a/src/napari_segment/napari.yaml
+++ b/src/napari_segment/napari.yaml
@@ -13,36 +13,36 @@ contributions:
       title: Save image data with Segment organoid
     - id: napari-segment.make_sample_data
       python_name: napari_segment._sample_data:make_sample_data
-      title: Load sample data from Segment organoid 
-    - id: napari-segment.make_qwidget
-      python_name: napari_segment._widget:ExampleQWidget
-      title: Make example QWidget
-    - id: napari-segment.make_magic_widget
-      python_name: napari_segment._widget:example_magic_widget
-      title: Make example magic widget
-    - id: napari-segment.make_func_widget
-      python_name: napari_segment._widget:example_function_widget
-      title: Make example function widget 
+      title: Load sample data from Segment organoid
+    # - id: napari-segment.make_qwidget
+    #   python_name: napari_segment._widget:ExampleQWidget
+    #   title: Make example QWidget
+    # - id: napari-segment.make_magic_widget
+    #   python_name: napari_segment._widget:example_magic_widget
+    #   title: Make example magic widget
+    - id: napari-segment.segment_organoid
+      python_name: napari_segment._widget:segment_organoid
+      title: Segment organoid
   readers:
     - command: napari-segment.get_reader
       accepts_directories: false
-      filename_patterns: ['*.npy'] 
+      filename_patterns: ['*.npy', '*.nd2']
   writers:
     - command: napari-segment.write_multiple
       layer_types: ['image*','labels*']
       filename_extensions: []
     - command: napari-segment.write_single_image
       layer_types: ['image']
-      filename_extensions: ['.npy'] 
+      filename_extensions: ['.npy']
   sample_data:
     - command: napari-segment.make_sample_data
       display_name: Segment organoid
-      key: unique_id.1 
+      key: unique_id.1
   widgets:
-    - command: napari-segment.make_qwidget
-      display_name: Example QWidget
-    - command: napari-segment.make_magic_widget
-      display_name: Example Magic Widget
-    - command: napari-segment.make_func_widget
-      autogenerate: true
-      display_name: Example Function Widget 
\ No newline at end of file
+    # - command: napari-segment.make_qwidget
+    #   display_name: Example QWidget
+    # - command: napari-segment.make_magic_widget
+    #   display_name: Example Magic Widget
+    - command: napari-segment.segment_organoid
+      # autogenerate: true
+      display_name: Segment organoid