Skip to content

Commit 0ebd45c

Browse files
committed
refactored layer_selector_widgets to BaseWidget and fixed loading image before plugin problem
1 parent ff5be12 commit 0ebd45c

File tree

3 files changed

+176
-93
lines changed

3 files changed

+176
-93
lines changed

synaptic_reconstruction/tools/synaptic_plugin/base_widget.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,80 @@ def __init__(self):
1111
self.viewer = napari.current_viewer()
1212
self.attribute_dict = {}
1313

14+
def _create_layer_selector(self, selector_name, layer_type="Image"):
15+
"""
16+
Create a layer selector for an image or labels and store it in a dictionary.
17+
18+
Parameters:
19+
- selector_name (str): The name of the selector, used as a key in the dictionary.
20+
- layer_type (str): The type of layer to filter for ("Image" or "Labels").
21+
"""
22+
if not hasattr(self, "layer_selectors"):
23+
self.layer_selectors = {}
24+
25+
# Determine the annotation type for the widget
26+
if layer_type == "Image":
27+
layer_filter = napari.layers.Image
28+
elif layer_type == "Labels":
29+
layer_filter = napari.layers.Labels
30+
else:
31+
raise ValueError("layer_type must be either 'Image' or 'Labels'.")
32+
33+
selector_widget = QtWidgets.QWidget()
34+
image_selector = QtWidgets.QComboBox()
35+
layer_label = QtWidgets.QLabel(f"{selector_name} Layer:")
36+
37+
# Populate initial options
38+
self._update_selector(selector=image_selector, layer_filter=layer_filter)
39+
40+
# # Connect selection change to update image data in attribute_dict
41+
# image_selector.currentIndexChanged.connect(
42+
# lambda: self._update_layer_data(image_selector, selector_name)
43+
# )
44+
45+
# Update selector on layer events
46+
self.viewer.layers.events.inserted.connect(lambda event: self._update_selector(image_selector, layer_filter))
47+
self.viewer.layers.events.removed.connect(lambda event: self._update_selector(image_selector, layer_filter))
48+
49+
# Store the selector in the dictionary
50+
self.layer_selectors[selector_name] = selector_widget
51+
52+
# Set up layout
53+
layout = QVBoxLayout()
54+
layout.addWidget(layer_label)
55+
layout.addWidget(image_selector)
56+
selector_widget.setLayout(layout)
57+
return selector_widget
58+
59+
def _update_selector(self, selector, layer_filter):
60+
"""Update a single selector with the current image layers in the viewer."""
61+
selector.clear()
62+
image_layers = [layer.name for layer in self.viewer.layers if isinstance(layer, layer_filter)] # if isinstance(layer, napari.layers.Image)
63+
selector.addItems(image_layers)
64+
65+
# def _update_layer_data(self, selector, attribute_name):
66+
# """Update the specified attribute in the attribute_dict with selected layer data."""
67+
# selected_layer_name = selector.currentText()
68+
# if selected_layer_name in self.viewer.layers:
69+
# self.layer_selectors[attribute_name] = self.viewer.layers[selected_layer_name].data
70+
# else:
71+
# self.layer_selectors[attribute_name] = None # Reset if no valid selection
72+
73+
def _get_layer_selector_data(self, selector_name):
74+
"""Return the data for the layer currently selected in a given selector."""
75+
if selector_name in self.layer_selectors:
76+
selector_widget = self.layer_selectors[selector_name]
77+
78+
# Retrieve the QComboBox from the QWidget's layout
79+
image_selector = selector_widget.layout().itemAt(1).widget()
80+
81+
if isinstance(image_selector, QComboBox):
82+
selected_layer_name = image_selector.currentText()
83+
print("selector_name", selector_name, "selected_layer_name", selected_layer_name)
84+
if selected_layer_name in self.viewer.layers:
85+
return self.viewer.layers[selected_layer_name].data
86+
return None # Return None if layer not found
87+
1488
def _add_string_param(self, name, value, title=None, placeholder=None, layout=None, tooltip=None):
1589
if layout is None:
1690
layout = QtWidgets.QHBoxLayout()

synaptic_reconstruction/tools/synaptic_plugin/distance_measure_widget.py

Lines changed: 59 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ def __init__(self):
1717
self.viewer = napari.current_viewer()
1818
layout = QVBoxLayout()
1919

20-
self.selectors = {}
2120
self.image_selector_name1 = "Segmentation 1"
2221
self.image_selector_name2 = "Segmentation 2"
2322
# Create the image selection dropdown
24-
self.segmentation1_selector_widget = self.create_image_selector(selector_name=self.image_selector_name1)
25-
self.segmentation2_selector_widget = self.create_image_selector(selector_name=self.image_selector_name2)
23+
self.segmentation1_selector_widget = self._create_layer_selector(self.image_selector_name1, layer_type="Labels")
24+
self.segmentation2_selector_widget = self._create_layer_selector(self.image_selector_name2, layer_type="Labels")
2625

2726
# create save path
2827
self.settings = self._create_settings_widget()
@@ -45,17 +44,26 @@ def __init__(self):
4544

4645
self.setLayout(layout)
4746

48-
def get_selected_layer_data(self, selector_name):
49-
"""Return the data for the layer currently selected in a given selector."""
50-
if selector_name in self.selectors:
51-
selected_layer_name = self.selectors[selector_name].currentText()
52-
if selected_layer_name in self.viewer.layers:
53-
return self.viewer.layers[selected_layer_name].data
54-
return None # Return None if layer not found
47+
# def get_selected_layer_data(self, selector_name):
48+
# """Return the data for the layer currently selected in a given selector."""
49+
# if selector_name in self.layer_selectors:
50+
# selector_widget = self.layer_selectors[selector_name]
51+
52+
# # Retrieve the QComboBox from the QWidget's layout
53+
# image_selector = selector_widget.layout().itemAt(1).widget()
54+
55+
# if isinstance(image_selector, QComboBox):
56+
# selected_layer_name = image_selector.currentText()
57+
# if selected_layer_name in self.viewer.layers:
58+
# return self.viewer.layers[selected_layer_name].data
59+
# # selected_layer_name = self.layer_selectors[selector_name].currentText()
60+
# # if selected_layer_name in self.viewer.layers:
61+
# # return self.viewer.layers[selected_layer_name].data
62+
# return None # Return None if layer not found
5563

5664
def on_measure_segmentation_to_object(self):
57-
segmentation1_data = self.get_selected_layer_data(self.image_selector_name1)
58-
segmentation2_data = self.get_selected_layer_data(self.image_selector_name2)
65+
segmentation1_data = self._get_layer_selector_data(self.image_selector_name1)
66+
segmentation2_data = self._get_layer_selector_data(self.image_selector_name2)
5967
if segmentation1_data is None or segmentation2_data is None:
6068
show_info("Please choose both segmentation layers.")
6169
return
@@ -106,50 +114,50 @@ def on_measure_pairwise(self):
106114
# layer_kwargs = {"colormap": "inferno", "blending": "additive"}
107115
# return segmentation, layer_kwargs
108116

109-
def create_image_selector(self, selector_name):
110-
attribute_dict = {}
111-
viewer = self.viewer
112-
"""Create an image selector widget for a specific layer attribute."""
113-
selector_widget = QWidget()
114-
image_selector = QComboBox()
115-
title_label = QLabel(f"Select Layer for {selector_name}:")
117+
# def create_image_selector(self, selector_name):
118+
# attribute_dict = {}
119+
# viewer = self.viewer
120+
# """Create an image selector widget for a specific layer attribute."""
121+
# selector_widget = QWidget()
122+
# image_selector = QComboBox()
123+
# title_label = QLabel(f"Select Layer for {selector_name}:")
116124

117-
# Populate initial options
118-
self.update_selector(viewer, image_selector)
125+
# # Populate initial options
126+
# self.update_selector(viewer, image_selector)
119127

120-
# Connect selection change to update image data in attribute_dict
121-
image_selector.currentIndexChanged.connect(
122-
lambda: self.update_image_data(viewer, image_selector, attribute_dict, selector_name)
123-
)
128+
# # Connect selection change to update image data in attribute_dict
129+
# image_selector.currentIndexChanged.connect(
130+
# lambda: self.update_image_data(viewer, image_selector, attribute_dict, selector_name)
131+
# )
124132

125-
# Update selector on layer events
126-
viewer.layers.events.inserted.connect(lambda event: self.update_selector(viewer, image_selector))
127-
viewer.layers.events.removed.connect(lambda event: self.update_selector(viewer, image_selector))
133+
# # Update selector on layer events
134+
# viewer.layers.events.inserted.connect(lambda event: self.update_selector(viewer, image_selector))
135+
# viewer.layers.events.removed.connect(lambda event: self.update_selector(viewer, image_selector))
128136

129-
# Store this combo box in the selectors dictionary
130-
self.selectors[selector_name] = image_selector
137+
# # Store this combo box in the selectors dictionary
138+
# self.selectors[selector_name] = image_selector
131139

132-
# Set up layout
133-
layout = QVBoxLayout()
134-
layout.addWidget(title_label)
135-
layout.addWidget(image_selector)
136-
selector_widget.setLayout(layout)
137-
138-
return selector_widget
139-
140-
def update_selector(self, viewer, selector):
141-
"""Update a single selector with the current image layers in the viewer."""
142-
selector.clear()
143-
image_layers = [layer.name for layer in viewer.layers] # if isinstance(layer, napari.layers.Image)
144-
selector.addItems(image_layers)
145-
146-
def update_image_data(self, viewer, selector, attribute_dict, attribute_name):
147-
"""Update the specified attribute in the attribute_dict with selected layer data."""
148-
selected_layer_name = selector.currentText()
149-
if selected_layer_name in viewer.layers:
150-
attribute_dict[attribute_name] = viewer.layers[selected_layer_name].data
151-
else:
152-
attribute_dict[attribute_name] = None # Reset if no valid selection
140+
# # Set up layout
141+
# layout = QVBoxLayout()
142+
# layout.addWidget(title_label)
143+
# layout.addWidget(image_selector)
144+
# selector_widget.setLayout(layout)
145+
146+
# return selector_widget
147+
148+
# def update_selector(self, viewer, selector):
149+
# """Update a single selector with the current image layers in the viewer."""
150+
# selector.clear()
151+
# image_layers = [layer.name for layer in viewer.layers] # if isinstance(layer, napari.layers.Image)
152+
# selector.addItems(image_layers)
153+
154+
# def update_image_data(self, viewer, selector, attribute_dict, attribute_name):
155+
# """Update the specified attribute in the attribute_dict with selected layer data."""
156+
# selected_layer_name = selector.currentText()
157+
# if selected_layer_name in viewer.layers:
158+
# attribute_dict[attribute_name] = viewer.layers[selected_layer_name].data
159+
# else:
160+
# attribute_dict[attribute_name] = None # Reset if no valid selection
153161

154162
def _create_settings_widget(self):
155163
setting_values = QWidget()

synaptic_reconstruction/tools/synaptic_plugin/segmentation_widget.py

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ def __init__(self):
1515
super().__init__()
1616

1717
self.model = None
18-
self.image = None
1918
self.viewer = napari.current_viewer()
2019
layout = QVBoxLayout()
2120

2221
# Create the image selection dropdown
2322
# FIXME: this does not work for layers that were added before the plugin
24-
self.image_selector_widget = self.create_image_selector()
23+
# self.image_selector_widget = self.create_image_selector()
24+
self.image_selector_name = "Image data"
25+
self.image_selector_widget = self._create_layer_selector(self.image_selector_name, layer_type="Image")
2526

2627
# create buttons
2728
self.predict_button = QPushButton('Run Segmentation')
@@ -44,44 +45,44 @@ def __init__(self):
4445

4546
self.setLayout(layout)
4647

47-
def create_image_selector(self):
48-
selector_widget = QWidget()
49-
self.image_selector = QComboBox()
48+
# def create_image_selector(self):
49+
# selector_widget = QWidget()
50+
# self.image_selector = QComboBox()
5051

51-
title_label = QLabel("Select Layer to segment:")
52+
# title_label = QLabel("Select Layer to segment:")
5253

53-
# Populate initial options
54-
self.update_image_selector()
54+
# # Populate initial options
55+
# self.update_image_selector()
5556

56-
# Connect selection change to update self.image
57-
self.image_selector.currentIndexChanged.connect(self.update_image_data)
57+
# # Connect selection change to update self.image
58+
# self.image_selector.currentIndexChanged.connect(self.update_image_data)
5859

59-
# Connect to Napari layer events to update the list
60-
self.viewer.layers.events.inserted.connect(self.update_image_selector)
61-
self.viewer.layers.events.removed.connect(self.update_image_selector)
60+
# # Connect to Napari layer events to update the list
61+
# self.viewer.layers.events.inserted.connect(self.update_image_selector)
62+
# self.viewer.layers.events.removed.connect(self.update_image_selector)
6263

63-
layout = QVBoxLayout()
64-
layout.addWidget(title_label)
65-
layout.addWidget(self.image_selector)
66-
selector_widget.setLayout(layout)
67-
return selector_widget
68-
69-
def update_image_selector(self, event=None):
70-
"""Update dropdown options with current image layers in the viewer."""
71-
self.image_selector.clear()
72-
73-
# Add each image layer's name to the dropdown
74-
# image_layers = [layer.name for layer in self.viewer.layers if isinstance(layer, napari.layers.Image)]
75-
image_layers = [layer.name for layer in self.viewer.layers]
76-
self.image_selector.addItems(image_layers)
77-
78-
def update_image_data(self):
79-
"""Update the self.image attribute with data from the selected layer."""
80-
selected_layer_name = self.image_selector.currentText()
81-
if selected_layer_name in self.viewer.layers:
82-
self.image = self.viewer.layers[selected_layer_name].data
83-
else:
84-
self.image = None # Reset if no valid selection
64+
# layout = QVBoxLayout()
65+
# layout.addWidget(title_label)
66+
# layout.addWidget(self.image_selector)
67+
# selector_widget.setLayout(layout)
68+
# return selector_widget
69+
70+
# def update_image_selector(self, event=None):
71+
# """Update dropdown options with current image layers in the viewer."""
72+
# self.image_selector.clear()
73+
74+
# # Add each image layer's name to the dropdown
75+
# # image_layers = [layer.name for layer in self.viewer.layers if isinstance(layer, napari.layers.Image)]
76+
# image_layers = [layer.name for layer in self.viewer.layers]
77+
# self.image_selector.addItems(image_layers)
78+
79+
# def update_image_data(self):
80+
# """Update the self.image attribute with data from the selected layer."""
81+
# selected_layer_name = self.image_selector.currentText()
82+
# if selected_layer_name in self.viewer.layers:
83+
# self.image = self.viewer.layers[selected_layer_name].data
84+
# else:
85+
# self.image = None # Reset if no valid selection
8586

8687
def load_model_widget(self):
8788
model_widget = QWidget()
@@ -106,17 +107,17 @@ def on_predict(self):
106107
if model_key == "- choose -":
107108
show_info("Please choose a model.")
108109
return
109-
if self.image is None:
110-
show_info("Please choose an image.")
111-
return
112110

113111
# loading model
114112
model_registry = get_model_registry()
115113
model_key = self.model_selector.currentText()
116114
# model_path = "/home/freckmann15/.cache/synapse-net/models/vesicles" #
117115
model_path = model_registry.fetch(model_key)
118-
# model = get_2d_model(out_channels=2)
119-
# model = load_model_weights(model=model, model_path=model_path)
116+
# get image data
117+
image = self._get_layer_selector_data(self.image_selector_name)
118+
if image is None:
119+
show_info("Please choose an image.")
120+
return
120121

121122
# get tile shape and halo from the viewer
122123
tiling = {
@@ -138,9 +139,9 @@ def on_predict(self):
138139
if ts != 0 or h != 0: # if anything changed from default
139140
use_custom_tiling = True
140141
if use_custom_tiling:
141-
segmentation = run_segmentation(self.image, model_path=model_path, model_key=model_key, tiling=tiling)
142+
segmentation = run_segmentation(image, model_path=model_path, model_key=model_key, tiling=tiling)
142143
else:
143-
segmentation = run_segmentation(self.image, model_path=model_path, model_key=model_key)
144+
segmentation = run_segmentation(image, model_path=model_path, model_key=model_key)
144145

145146
# Add the segmentation layer
146147
self.viewer.add_labels(segmentation, name=f"{model_key}-segmentation")

0 commit comments

Comments
 (0)