diff --git a/spikeinterface_gui/controller.py b/spikeinterface_gui/controller.py
index dd5b9d5d..d73d288b 100644
--- a/spikeinterface_gui/controller.py
+++ b/spikeinterface_gui/controller.py
@@ -902,6 +902,27 @@ def make_manual_merge_if_possible(self, merge_unit_ids):
print(f"Merged unit group: {[str(u) for u in merge_unit_ids]}")
return True
+
+ def remove_units_from_merge_if_possible(self, merge_unit_ids):
+ """
+ Check if selected units are in a merge group. If they are, remove them.
+ """
+ if not self.curation:
+ return False
+
+ merges = self.curation_data["merges"]
+ for i, merge in enumerate(merges):
+ if set(merge_unit_ids).issubset(set(merge['unit_ids'])):
+ merge_ids_with_removed_ids = list(set(merge['unit_ids']).difference(set(merge_unit_ids)))
+ if len(merge_ids_with_removed_ids) > 1:
+ merges[i]['unit_ids'] = merge_ids_with_removed_ids
+ return True
+ else:
+ return False
+
+ return False
+
+
def make_manual_split_if_possible(self, unit_id):
"""
Check if the a unit_id can be split into a new split in the curation_data.
diff --git a/spikeinterface_gui/unitlistview.py b/spikeinterface_gui/unitlistview.py
index ef6a6958..23800964 100644
--- a/spikeinterface_gui/unitlistview.py
+++ b/spikeinterface_gui/unitlistview.py
@@ -20,16 +20,6 @@ def __init__(self, controller=None, parent=None, backend="qt"):
## common ##
- def show_all(self):
- self.controller.set_visible_unit_ids(self.controller.unit_ids)
- self.notify_unit_visibility_changed()
- self.refresh()
-
- def hide_all(self):
- self.controller.set_all_unit_visibility_off()
- self.notify_unit_visibility_changed()
- self.refresh()
-
def get_selected_unit_ids(self):
if self.backend == 'qt':
return self._qt_get_selected_unit_ids()
@@ -88,10 +78,6 @@ def _qt_make_layout(self):
self.column_order = None
self.menu = QT.QMenu()
- act = self.menu.addAction('Show all')
- act.triggered.connect(self.show_all)
- act = self.menu.addAction('Hide all')
- act.triggered.connect(self.hide_all)
self.shortcut_only_previous = QT.QShortcut(self.qt_widget)
self.shortcut_only_previous.setKey(QT.QKeySequence(QT.CTRL | QT.Key_Up))
@@ -106,6 +92,8 @@ def _qt_make_layout(self):
act.triggered.connect(self._qt_delete_unit)
act = self.menu.addAction('Merge selected')
act.triggered.connect(self._qt_merge_selected)
+ act = self.menu.addAction('Remove from merge')
+ act.triggered.connect(self._qt_remove_from_merge)
self.shortcut_delete = QT.QShortcut(self.qt_widget)
self.shortcut_delete.setKey(QT.QKeySequence("ctrl+d"))
self.shortcut_delete.activated.connect(self._qt_on_delete_shortcut)
@@ -156,11 +144,17 @@ def _qt_refresh_visibility_items(self):
from .myqt import QT
self.table.itemChanged.disconnect(self._qt_on_item_changed)
+
+ visible_unit_ids = self.controller.get_visible_unit_ids()
+
+ view_target_unit_id = visible_unit_ids[0]
+ target_item = self.items_visibility[view_target_unit_id]
+ self.table.scrollToItem(target_item, QT.QAbstractItemView.PositionAtCenter)
for unit_id in self.controller.unit_ids:
item = self.items_visibility[unit_id]
item.setCheckState(QT.Qt.Unchecked)
- for unit_id in self.controller.get_visible_unit_ids():
+ for unit_id in visible_unit_ids:
item = self.items_visibility[unit_id]
item.setCheckState(QT.Qt.Checked)
self._qt_refresh_color_icons()
@@ -435,9 +429,19 @@ def _qt_merge_selected(self):
"merged, or split already."
)
return
- self.notify_manual_curation_updated()
-
+ else:
+ self.notify_manual_curation_updated()
+ def _qt_remove_from_merge(self):
+ merge_unit_ids = self.get_selected_unit_ids()
+ success = self.controller.remove_units_from_merge_if_possible(merge_unit_ids)
+ if not success:
+ self.warning(
+ "Could not remove units from a merge. Ensure all selected units are in a merge group, and that you are not leaving zero or one units in the merge group."
+ )
+ return
+ else:
+ self.notify_manual_curation_updated()
## panel zone ##
def _panel_make_layout(self):
@@ -526,35 +530,19 @@ def _panel_make_layout(self):
column_callbacks={"visible": self._panel_on_visible_checkbox_toggled},
)
- self.select_all_button = pn.widgets.Button(name="Select All", button_type="default")
- self.unselect_all_button = pn.widgets.Button(name="Unselect All", button_type="default")
self.refresh_button = pn.widgets.Button(name="↻", button_type="default")
- button_list = [
- self.select_all_button,
- self.unselect_all_button,
- ]
+ button_list = []
if self.controller.curation:
self.delete_button = pn.widgets.Button(name="Delete", button_type="default")
self.merge_button = pn.widgets.Button(name="Merge", button_type="default")
- # self.hide_noise = pn.widgets.Toggle(name="Show/Hide Noise", button_type="default")
-
- # if "quality" in self.label_definitions:
- # self.show_only = pn.widgets.Select(
- # name="Show only",
- # options=["all"] + list(self.label_definitions["quality"]['label_options']),
- # sizing_mode="stretch_width",
- # )
- # else:
- # self.show_only = None
-
- # self.hide_noise.param.watch(self._panel_on_hide_noise, 'value')
- # self.show_only.param.watch(self._panel_on_show_only, 'value')
+ self.unmerge_button = pn.widgets.Button(name="Unmerge", button_type="default")
button_list.extend(
[
self.delete_button,
self.merge_button,
+ self.unmerge_button,
]
)
@@ -596,14 +584,12 @@ def _panel_make_layout(self):
self.layout.append(shortcuts_component)
self.table.tabulator.on_edit(self._panel_on_edit)
-
- self.select_all_button.on_click(self._panel_select_all)
- self.unselect_all_button.on_click(self._panel_unselect_all)
self.refresh_button.on_click(self._panel_refresh_click)
if self.controller.curation:
self.delete_button.on_click(self._panel_delete_unit_callback)
self.merge_button.on_click(self._panel_merge_units_callback)
+ self.unmerge_button.on_click(self._panel_remove_from_merge_callback)
def _panel_refresh_click(self, event):
self.table.reset()
@@ -658,14 +644,6 @@ def _panel_refresh_header(self):
txt = f"All units: {n1} - visible: {n2} - selected: {n3}"
self.info_text.object = txt
- def _panel_select_all(self, event):
- self.show_all()
- self.notifier.notify_active_view_updated()
-
- def _panel_unselect_all(self, event):
- self.hide_all()
- self.notifier.notify_active_view_updated()
-
def _panel_delete_unit_callback(self, event):
self._panel_delete_unit()
self.notifier.notify_active_view_updated()
@@ -674,6 +652,10 @@ def _panel_merge_units_callback(self, event):
self._panel_merge_units()
self.notifier.notify_active_view_updated()
+ def _panel_remove_from_merge_callback(self, event):
+ self._panel_remove_from_merge()
+ self.notifier.notify_active_view_updated()
+
def _panel_on_visible_checkbox_toggled(self, row):
# print("checkbox toggled on row", row)
unit_ids = self.table.value.index.values
@@ -759,6 +741,18 @@ def _panel_merge_units(self):
self.notify_manual_curation_updated()
self.refresh()
+ def _panel_remove_from_merge(self):
+ merge_unit_ids = self.get_selected_unit_ids()
+ success = self.controller.remove_units_from_merge_if_possible(merge_unit_ids)
+ if not success:
+ self.warning(
+ "Could not remove units from a merge. Ensure all selected units are in a merge "
+ "group, and that you are not leaving zero or one units in the merge group."
+ )
+ return
+ self.notify_manual_curation_updated()
+ self.refresh()
+
def _panel_handle_shortcut(self, event):
if self.is_view_active():
selected_unit_ids = self._panel_get_selected_unit_ids()