diff --git a/caiman/source_extraction/volpy/volpy_gui.py b/caiman/source_extraction/volpy/volpy_gui.py old mode 100644 new mode 100755 index ae333dfc1..d8710de38 --- a/caiman/source_extraction/volpy/volpy_gui.py +++ b/caiman/source_extraction/volpy/volpy_gui.py @@ -6,6 +6,13 @@ and spike extraction step of VolPy. @author: @caichangjia """ + +# These imports apparently must come before importing pyqtgraph on some platforms +import PySide6 +from PySide6 import QtWidgets +from PySide6.QtWidgets import QApplication +from PySide6.QtGui import QShortcut + import cv2 import h5py import numpy as np @@ -15,18 +22,15 @@ from pyqtgraph import FileDialog from pyqtgraph.Qt import QtGui from pyqtgraph.parametertree import Parameter, ParameterTree -import PyQt5 -from PyQt5 import QtWidgets -from PyQt5.QtWidgets import QApplication, QShortcut import random from skimage.draw import polygon import sys import caiman as cm from caiman.external.cell_magic_wand import cell_magic_wand_single_point - + os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = os.fspath( - Path(PyQt5.__file__).resolve().parent / "Qt5" / "plugins") + Path(PySide6.__file__).resolve().parent / "Qt6" / "plugins") def mouseClickEvent(event): @@ -70,7 +74,7 @@ def mouseClickEvent(event): roi = roi * 1. except: pass - + elif mode == 'CHOOSE NEURONS': pos = img.mapFromScene(event.pos()) p1.clear() @@ -104,7 +108,7 @@ def add(): roi = np.zeros((dims[1], dims[0])) ff = np.array(polygon(np.array(pts)[:,0], np.array(pts)[:,1])) roi[ff[1],[ff[0]]] = 1 - + if len(pts) > 2 : flag = True while flag: @@ -187,7 +191,7 @@ def load_rois(): if (l_ROIs.shape[2], l_ROIs.shape[1]) != dims: print(dims);print(l_ROIs.shape[1:]) raise ValueError('Dimentions of movie and rois do not accord') - + for roi in l_ROIs: flag = True while flag: @@ -213,7 +217,7 @@ def save(): print(ffll[0]) save_ROIs = np.array(list(all_ROIs.values())).copy() save_ROIs = np.flip(save_ROIs, axis=1) - + if os.path.splitext(ffll[0])[1] == '.hdf5': cm.movie(save_ROIs).save(ffll[0]) summary_images = summary_images.transpose([0, 2, 1]) @@ -293,11 +297,13 @@ def overlay(all_ROIs): if __name__ == "__main__": ## Always start by initializing Qt (only once per application) + if sys.platform == 'darwin': + PySide6.QtWidgets.QApplication.setStyle("fusion") app = QApplication(sys.argv) - + ## Define a top-level widget to hold everything w = QtWidgets.QWidget() - + ## Create some widgets to be placed inside hist = pg.HistogramLUTItem() # Contrast/color control win = pg.GraphicsLayoutWidget() @@ -307,11 +313,11 @@ def overlay(all_ROIs): p1 = pg.PlotWidget() neuron_action = ParameterTree() neuron_list = QtWidgets.QListWidget() - + ## Create a grid layout to manage the widgets size and position layout = QtWidgets.QGridLayout() w.setLayout(layout) - + ## Add widgets to the layout in their proper positions layout.addWidget(win, 0, 1) layout.addWidget(p1, 0, 2) @@ -320,27 +326,27 @@ def overlay(all_ROIs): img = pg.ImageItem() p1.addItem(img) hist.setImageItem(img) - + # Add actions - params_action = [{'name': 'LOAD DATA', 'type':'action'}, - {'name': 'LOAD ROIS', 'type':'action'}, - {'name': 'SAVE', 'type':'action'}, - {'name': 'ADD', 'type': 'action'}, - {'name': 'REMOVE', 'type': 'action'}, - {'name': 'SHOW ALL', 'type': 'action'}, - {'name': 'CLEAR', 'type': 'action'}, - {'name': 'IMAGES', 'type': 'list', 'values': ['MEAN','CORR']}, - {'name': 'DISPLAY', 'type': 'list', 'values': ['CONTOUR','SPATIAL FOOTPRINTS']}, - {'name': 'MODE', 'type': 'list', 'values': ['POLYGON','CELL MAGIC WAND', 'CHOOSE NEURONS']}, + params_action = [{'name': 'LOAD DATA', 'type': 'action'}, + {'name': 'LOAD ROIS', 'type': 'action'}, + {'name': 'SAVE', 'type': 'action'}, + {'name': 'ADD', 'type': 'action'}, + {'name': 'REMOVE', 'type': 'action'}, + {'name': 'SHOW ALL', 'type': 'action'}, + {'name': 'CLEAR', 'type': 'action'}, + {'name': 'IMAGES', 'type': 'list', 'limits': ['MEAN','CORR']}, + {'name': 'DISPLAY', 'type': 'list', 'limits': ['CONTOUR', 'SPATIAL FOOTPRINTS']}, + {'name': 'MODE', 'type': 'list', 'limits': ['POLYGON', 'CELL MAGIC WAND', 'CHOOSE NEURONS']}, {'name': 'MAGIC WAND PARAMS', 'type': 'group', 'children': [{'name': 'MIN RADIUS', 'type': 'int', 'value': 4}, {'name': 'MAX RADIUS', 'type': 'int', 'value': 10}, {'name': 'ROUGHNESS', 'type': 'int', 'value': 1}]}] - + pars_action = Parameter.create(name='params_action', type='group', children=params_action) neuron_action.setParameters(pars_action, showTop=False) neuron_action.setWindowTitle('Parameter Action') mode = pars_action.getValues()['MODE'][0] - + # Add event p1.mousePressEvent = mouseClickEvent p1.mouseReleaseEvent = release @@ -358,7 +364,7 @@ def overlay(all_ROIs): shortcut_up = QShortcut(QtGui.QKeySequence("up"), w) shortcut_up.activated.connect(up) neuron_list.itemClicked.connect(show_neuron) - + # Create dictionary for saving F = FileDialog() all_pts = {} @@ -366,12 +372,9 @@ def overlay(all_ROIs): all_ROIs = {} pts = [] pen = pg.mkPen(color=(255, 255, 0), width=4)#, style=Qt.DashDotLine) - + ## Display the widget as a new window w.show() - + ## Start the Qt event loop - app.exec_() - - - + app.exec() diff --git a/environment.yml b/environment.yml index 014c3532c..eaa692baf 100644 --- a/environment.yml +++ b/environment.yml @@ -27,6 +27,7 @@ dependencies: - psutil - pynwb - pyqtgraph +- pyside6 - scikit-image >=0.19.0 - scikit-learn >=1.2 - scipy >= 1.10.1 diff --git a/pyproject.toml b/pyproject.toml index 0f9889a55..efd63c685 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ dependencies = [ "pims", "psutil", "pynwb", + "pyside6", "scikit-image", "scikit-learn", "scipy",