Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addresses #1454 using pyside6 #1455

Merged
merged 6 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions caiman/source_extraction/volpy/volpy_gui.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 / "Qt5" / "plugins")
kushalkolar marked this conversation as resolved.
Show resolved Hide resolved


def mouseClickEvent(event):
Expand Down Expand Up @@ -70,7 +74,7 @@ def mouseClickEvent(event):
roi = roi * 1.
except:
pass

elif mode == 'CHOOSE NEURONS':
pos = img.mapFromScene(event.pos())
p1.clear()
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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])
Expand Down Expand Up @@ -294,10 +298,10 @@ def overlay(all_ROIs):
if __name__ == "__main__":
## Always start by initializing Qt (only once per application)
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()
Expand All @@ -307,11 +311,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)
Expand All @@ -320,7 +324,7 @@ 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'},
Expand All @@ -335,12 +339,12 @@ def overlay(all_ROIs):
{'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
Expand All @@ -358,20 +362,17 @@ 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 = {}
all_centers = {}
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()
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies:
- psutil
- pynwb
- pyqtgraph
- pyside6
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if including this in the deps could create issues with opencv, last time I remember it wants to have its own qt installed. That's why I always use opencv-python-headless but I'm not sure if opencv windowed stuff still works but just using the existing qt then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it pulls in qt6-main, so it's at least a closer version; more likely than sticking with qt5-based distros but something to watch out for.

Unfortunately, right now I think some of the code uses opencv's ability to launch a qt-based GUI, I think. I'd need to check to find out where but I'm pretty sure we do it.

- scikit-image >=0.19.0
- scikit-learn >=1.2
- scipy >= 1.10.1
Expand Down
Loading