diff --git a/GUI_main.py b/GUI_main.py index e1fecc12cb0c395c6dc5971fcdadfc4076690fa9..21f14d1e553376540e168390c8f14529b27c81b9 100644 --- a/GUI_main.py +++ b/GUI_main.py @@ -61,7 +61,7 @@ import skimage #from openpyxl import Workbook # Import everything for the Graphical User Interface from the PyQt5 library. -from PyQt5.QtWidgets import (QApplication, QMainWindow, QDialog, QFileDialog, +from PyQt5.QtWidgets import (QApplication, QMainWindow, QDialog, QMessageBox, QPushButton, QCheckBox, QAction, QStatusBar, QLabel) from PyQt5 import QtGui @@ -201,8 +201,8 @@ class App(QMainWindow): self.button_add_region = QPushButton("Add region") self.buttonlist.append(self.button_add_region) - self.button_savemask = QPushButton("Save Mask") - self.buttonlist.append(self.button_savemask) +# self.button_savemask = QPushButton("Save Mask") +# self.buttonlist.append(self.button_savemask) self.button_drawmouse = QPushButton('Brush') self.buttonlist.append(self.button_drawmouse) @@ -228,12 +228,6 @@ class App(QMainWindow): self.button_cnn = QPushButton('Launch CNN') self.buttonlist.append(self.button_cnn) - self.button_threshold = QCheckBox('Threshold prediction') - self.buttonlist.append(self.button_threshold) - - self.button_segment = QCheckBox('Segment') - self.buttonlist.append(self.button_segment) - self.button_cellcorespondance = QPushButton('Tracking') self.buttonlist.append(self.button_cellcorespondance) @@ -295,7 +289,7 @@ class App(QMainWindow): self.fileMenu = menubar.addMenu('File') self.saveactionmenu = QAction('Save') self.fileMenu.addAction(self.saveactionmenu) - self.saveactionmenu.triggered.connect(self.ButtonSaveMask) + self.saveactionmenu.triggered.connect(self.SaveMask) # hide the toolbar and instead of the original buttons of matplotlib, # QPushbuttons are used and are connected to the functions of the toolbar @@ -313,17 +307,6 @@ class App(QMainWindow): self.show() - - def mousePressEvent(self, QMouseEvent): - """this function is implemented just to have the QLineButtons of the - change time index button, setthreshold button and the setsegmentation - button out of focus when the user clicks somewhere - on the gui. (to unfocus the buttons) - """ - self.button_timeindex.clearFocus() - if self.button_SetSegmentation.isEnabled(): - self.button_SetSegmentation.clearFocus() - # ----------------------------------------------------------------------------- # FUNCTIONS LINKED TO NAVIGATION @@ -356,31 +339,9 @@ class App(QMainWindow): """ self.Nvgtlbar.zoom() - if (self.button_zoom.isChecked() and not(self.button_segment.isChecked() - or self.button_threshold.isChecked())): + if (self.button_zoom.isChecked()): self.Disable(self.button_zoom) - elif self.button_zoom.isChecked() and self.button_segment.isChecked(): - self.Disable(self.button_zoom) - self.button_segment.setEnabled(True) - - elif self.button_zoom.isChecked() and self.button_threshold.isChecked(): - self.Disable(self.button_zoom) - self.button_threshold.setEnabled(True) - - elif self.button_zoom.isChecked() == False and self.button_segment.isChecked(): - self.button_pan.setEnabled(True) - self.button_home.setEnabled(True) - self.button_back.setEnabled(True) - self.button_forward.setEnabled(True) - self.EnableCorrectionsButtons() - - elif self.button_zoom.isChecked() == False and self.button_threshold.isChecked(): - self.button_pan.setEnabled(True) - self.button_home.setEnabled(True) - self.button_back.setEnabled(True) - self.button_forward.setEnabled(True) - else: self.Enable(self.button_zoom) @@ -402,7 +363,6 @@ class App(QMainWindow): self.Nvgtlbar.back() - def ForwardTlbar(self): """ It calls the forward function of the matplotlib toolbar which sets the @@ -441,33 +401,8 @@ class App(QMainWindow): self.Nvgtlbar.pan() - if (self.button_pan.isChecked() and not(self.button_segment.isChecked() - or self.button_threshold.isChecked())): - self.Disable(self.button_pan) - - elif self.button_pan.isChecked() and self.button_segment.isChecked(): - self.Disable(self.button_pan) - self.button_segment.setEnabled(True) - - elif self.button_pan.isChecked() and self.button_threshold.isChecked(): + if (self.button_pan.isChecked()): self.Disable(self.button_pan) - self.button_threshold.setEnabled(True) - - elif not(self.button_pan.isChecked()) and self.button_segment.isChecked(): - - self.button_zoom.setEnabled(True) - self.button_home.setEnabled(True) - self.button_back.setEnabled(True) - self.button_forward.setEnabled(True) - - self.EnableCorrectionsButtons() - - elif not(self.button_pan.isChecked()) and self.button_threshold.isChecked(): - self.button_zoom.setEnabled(True) - self.button_home.setEnabled(True) - self.button_back.setEnabled(True) - self.button_forward.setEnabled(True) - else: self.Enable(self.button_pan) @@ -674,26 +609,16 @@ class App(QMainWindow): """ if self.button_hide_show.isChecked(): self.button_cnn.setVisible(True) - self.button_segment.setVisible(True) - self.button_savesegmask.setVisible(True) - self.button_threshold.setVisible(True) - self.button_savethresholdmask.setVisible(True) - self.button_SetSegmentation.setVisible(True) else: self.button_cnn.setVisible(False) - self.button_segment.setVisible(False) - self.button_savesegmask.setVisible(False) - self.button_threshold.setVisible(False) - self.button_savethresholdmask.setVisible(False) - self.button_SetSegmentation.setVisible(False) def LaunchBatchPrediction(self): """This function is called whenever the button Launch CNN is pressed. It allows to run the neural network over a time range and selected field of views. - + It creates a dialog window with two entries, that define the time range and a list where the user can select the desired fields of view. @@ -1014,44 +939,7 @@ class App(QMainWindow): self.Enable(self.button_cellcorespondance) self.button_cellcorespondance.setChecked(False) self.ClearStatusBar() - - - def SegmentBoxCheck(self): - if self.button_segment.isChecked(): - self.Disable(self.button_segment) - self.EnableCorrectionsButtons() - self.m.SegmentedMask = self.reader.LoadSeg(self.Tindex, self.FOVindex) - self.m.tempplotmask = self.m.plotmask.copy() - self.m.plotmask = self.m.SegmentedMask.copy() - self.m.currmask.set_data((self.m.SegmentedMask%10 + 1)*(self.m.SegmentedMask != 0)) - self.m.ax.draw_artist(self.m.currplot) - self.m.ax.draw_artist(self.m.currmask) - self.m.update() - self.m.flush_events() - - # update the graph - self.button_SetSegmentation.setEnabled(True) - self.button_savesegmask.setEnabled(True) - - else: - self.m.SegmentedMask = self.m.plotmask.copy() - self.m.plotmask = self.m.tempplotmask.copy() - self.m.updatedata() - self.button_SetSegmentation.setEnabled(False) - self.button_savesegmask.setEnabled(False) - self.Enable(self.button_segment) - - - def SegmentThresholdedPredMask(self): - # update the plots to display the segmentation view - segparamvalue = int(self.button_SetSegmentation.text()) - self.m.plotmask = self.reader.Segment(segparamvalue, self.Tindex,self.FOVindex) - self.m.currmask.set_data((self.m.plotmask%10 + 1)*(self.m.plotmask != 0)) - self.m.ax.draw_artist(self.m.currplot) - self.m.ax.draw_artist(self.m.currmask) - self.m.update() - self.m.flush_events() - + def ButtonSaveSegMask(self): """saves the segmented mask @@ -1208,8 +1096,7 @@ class App(QMainWindow): # displaying the instructions on the statusbar self.WriteStatusBar(( - 'Select one cell using the left click ' - 'and then enter the desired value in the dialog box.')) + 'Left-click to select cell, right-click to abort.')) # disables all the buttons self.Disable(self.button_changecellvalue) @@ -1262,8 +1149,6 @@ class App(QMainWindow): #reads the new value to set and converts it from str to int value = int(dlg.entry1.text()) - # self.m.plotmask[newy, newx] the value selected by the user - # self.m.plotmask == self.m.plotmask[newy, newx] # gives the coordinates where it is equal to the value # selected by the user. And it replaces it with the new # value. @@ -1272,9 +1157,12 @@ class App(QMainWindow): # updates the plot to see the modification. self.m.updatedata() + self.Enable(self.button_changecellvalue) self.button_changecellvalue.setChecked(False) self.m.ShowCellNumbers() + self.SaveMask() + self.ClearStatusBar() def DialogBoxECV(self, s): @@ -1296,9 +1184,12 @@ class App(QMainWindow): value2 = int(dlg.entry2.text()) # calls the function which does the swap - self.m.ExchangeCellValue(value1,value2) + try: + self.m.ExchangeCellValue(value1,value2) + except ValueError as e: + QMessageBox.critical(self, 'Error', str(e)) self.m.ShowCellNumbers() - + self.SaveMask() else: return @@ -1356,7 +1247,7 @@ class App(QMainWindow): QApplication.restoreOverrideCursor() self.Enable(self.button_drawmouse) self.Enable(self.button_eraser) - + self.SaveMask() self.ClearStatusBar() @@ -1422,6 +1313,7 @@ class App(QMainWindow): self.Enable(self.button_newcell) self.m.ShowCellNumbers() self.ClearStatusBar() + self.SaveMask() def TestSelectedPoints(self): @@ -1489,6 +1381,7 @@ class App(QMainWindow): self.Enable(self.button_add_region) self.m.ShowCellNumbers() self.ClearStatusBar() + self.SaveMask() # ----------------------------------------------------------------------------- @@ -1500,17 +1393,9 @@ class App(QMainWindow): index. (next and previous buttons should not be turned on if t = 0 or t = lasttimeindex) """ - if self.button_segment.isChecked(): - self.EnableCorrectionsButtons() - self.button_home.setEnabled(True) - self.button_zoom.setEnabled(True) - self.button_pan.setEnabled(True) - self.button_back.setEnabled(True) - self.button_forward.setEnabled(True) - else: - for k in range(0, len(self.buttonlist)): - if button != self.buttonlist[k]: - self.buttonlist[k].setEnabled(True) + for k in range(0, len(self.buttonlist)): + if button != self.buttonlist[k]: + self.buttonlist[k].setEnabled(True) if self.Tindex == 0: self.button_previousframe.setEnabled(False) @@ -1526,39 +1411,17 @@ class App(QMainWindow): this functions turns off all the buttons except the one given in argument. """ - flag = False - if (button == self.button_add_region - or button == self.button_newcell - or button == self.button_exval - or button == self.button_changecellvalue - or button == self.button_drawmouse - or button == self.button_eraser): - if self.button_segment.isChecked(): - flag = True for k in range(0,len(self.buttonlist)): if button != self.buttonlist[k]: self.buttonlist[k].setEnabled(False) - if flag: - self.button_segment.setEnabled(True) - - if button == self.button_segment or button == self.button_threshold: - self.button_home.setEnabled(True) - self.button_zoom.setEnabled(True) - self.button_pan.setEnabled(True) - self.button_back.setEnabled(True) - self.button_forward.setEnabled(True) def EnableCNNButtons(self): if self.reader.TestTimeExist(self.Tindex, self.FOVindex): - self.button_threshold.setEnabled(True) - self.button_segment.setEnabled(True) self.button_cellcorespondance.setEnabled(True) self.button_extractfluorescence.setEnabled(True) else: - self.button_threshold.setEnabled(False) - self.button_segment.setEnabled(False) self.button_cellcorespondance.setEnabled(False) self.button_extractfluorescence.setEnabled(False) @@ -1583,7 +1446,7 @@ class App(QMainWindow): self.button_showval.setEnabled(False) - def ButtonSaveMask(self): + def SaveMask(self): """ When this function is called, it saves the current mask (self.m.plotmask) diff --git a/init/InitButtons.py b/init/InitButtons.py index 2eb9c13dff09a118b1e7f69a0a0c91190d5f2328..19d23c60fe10db71339d902ee5e97dff38b5f05d 100644 --- a/init/InitButtons.py +++ b/init/InitButtons.py @@ -115,15 +115,6 @@ def Init(parent): parent.button_pan.setStatusTip('Pan') parent.buttonlist.append(parent.button_pan) - # SAVE - parent.button_savemask.toggle() - parent.button_savemask.setEnabled(True) - parent.button_savemask.clicked.connect(parent.ButtonSaveMask) - parent.button_savemask.setToolTip("Use S Key for shortcut") - parent.button_savemask.setMaximumWidth(150) - parent.button_savemask.setShortcut("S") - parent.button_savemask.setStatusTip('Save the mask') - # BRUSH parent.button_drawmouse.setCheckable(True) parent.button_drawmouse.clicked.connect(parent.MouseDraw) @@ -154,48 +145,7 @@ def Init(parent): parent.button_changecellvalue.setMaximumWidth(150) parent.button_changecellvalue.setStatusTip('Change value of one cell') parent.button_changecellvalue.setToolTip('Use left click to select one cell and enter a new value') - -# # THRESHOLD THE PREDICTION CHECKBOX -# parent.button_threshold.setEnabled(False) -# parent.button_threshold.stateChanged.connect(parent.ThresholdBoxCheck) - -# # TEXT BOX FOR ENTERING THRESHOLD VALUE -# parent.button_SetThreshold = QLineEdit() -# parent.button_SetThreshold.setPlaceholderText('Enter a threshold value') -# parent.button_SetThreshold.setValidator(QtGui.QDoubleValidator()) -# parent.button_SetThreshold.setMaximumWidth(150) -# parent.button_SetThreshold.returnPressed.connect(parent.ThresholdPrediction) -# parent.button_SetThreshold.setEnabled(False) - -# # SAVE BUTTON FOR THE THRESHOLDED PREDICTION -# parent.button_savethresholdmask = QPushButton('Save Threshold') -# parent.button_savethresholdmask.toggle() -# parent.button_savethresholdmask.setEnabled(False) -# parent.button_savethresholdmask.clicked.connect(parent.ButtonSaveThresholdMask) -# parent.button_savethresholdmask.setMaximumWidth(150) -# parent.button_savethresholdmask.setStatusTip('Save the thresholded prediction') - - # SEGMENT THE OUTPUT OF THE THRESHOLD - parent.button_segment.setEnabled(False) - parent.button_segment.stateChanged.connect(parent.SegmentBoxCheck) - - # TEXT BOX FOR THE PARAMETERS OF THE SEGMENTATION - parent.button_SetSegmentation = QLineEdit() - parent.button_SetSegmentation.setPlaceholderText('Enter param for seg') - parent.button_SetSegmentation.setValidator(QtGui.QIntValidator()) - parent.button_SetSegmentation.setMaximumWidth(80) - parent.button_SetSegmentation.returnPressed.connect(parent.SegmentThresholdedPredMask) - parent.button_SetSegmentation.setEnabled(False) - parent.button_SetSegmentation.setText('10') - - # SAVE BUTTON FOR THE SEGMENTATION OF THE THRESHOLDED PREDICTION - parent.button_savesegmask = QPushButton('Save Seg') - parent.button_savesegmask.toggle() - parent.button_savesegmask.setEnabled(False) - parent.button_savesegmask.clicked.connect(parent.ButtonSaveSegMask) - parent.button_savesegmask.setMaximumWidth(150) - parent.button_savesegmask.setStatusTip('Save the segmented thresholded prediction') - + # MAKE THE CELL CORRESPONDANCE parent.button_cellcorespondance.setEnabled(False) parent.button_cellcorespondance.setCheckable(True) diff --git a/init/InitLayout.py b/init/InitLayout.py index 7428f1fa3c68cb23e86d2e527de870b5e89b8d63..141842048e8e1bec28c18d3daa49f40fc405ba7c 100644 --- a/init/InitLayout.py +++ b/init/InitLayout.py @@ -3,130 +3,60 @@ Initializing the layout of the main window. It places the buttons and the pictures at the desired positions. """ -#from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget, QPushButton, QShortcut, QComboBox, QCheckBox, QLineEdit, QMenu, QAction, QStatusBar -#from PyQt5 import QtGui -#from PyQt5.QtCore import pyqtSignal, QObject, Qt -from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5 +from matplotlib.backends.qt_compat import QtWidgets def Init(parent): - -# LAYOUT OF THE MAIN WINDOW - layout = QtWidgets.QVBoxLayout(parent._main) - - -# LAYOUT FOR THE THRESHOLD BUTTONS -# all the buttons of the threshold function are placed in an horizontal -# stack -# hbox_threshold = QtWidgets.QHBoxLayout() -# hbox_threshold.addWidget(parent.button_threshold) -# hbox_threshold.addWidget(parent.button_SetThreshold) -# hbox_threshold.addWidget(parent.button_savethresholdmask) -## if this line is not put, then the buttons are placed along the whole -## length of the window, in this way they are all grouped to the left. -# hbox_threshold.addStretch(1) - - - -# LAYOUT FOR THE SEGMENTATION BUTTONS -# all the buttons of the segment function are placed in an -# horizontal stack - hbox_segment = QtWidgets.QHBoxLayout() - hbox_segment.addWidget(parent.button_segment) - hbox_segment.addWidget(parent.button_SetSegmentation) - hbox_segment.addWidget(parent.button_savesegmask) -# if this line is not put, then the buttons are placed along the whole -# length of the window, in this way they are all grouped to the left. - hbox_segment.addStretch(1) - - -# LAYOUT FOR THE TOOLBAR BUTTONS -# all the buttons of the toolbar are placed in an -# horizontal stack - hbox = QtWidgets.QHBoxLayout() - - hbox.addWidget(parent.button_home) - hbox.addWidget(parent.button_back) - hbox.addWidget(parent.button_forward) - hbox.addWidget(parent.button_pan) - hbox.addWidget(parent.button_zoom) - - hbox.addStretch(1) -# we add all our widgets in the layout - layout.addLayout(hbox) -# layout.addWidget(parent.button_zoom) -# layout.addWidget - - -# makes a horizontal layout for the buttons used to navigate through -# the time axis. - hboxtimeframes = QtWidgets.QHBoxLayout() - - hboxtimeframes.addWidget(parent.button_fov) - hboxtimeframes.addWidget(parent.button_channel) - hboxtimeframes.addStretch() - hboxtimeframes.addWidget(parent.button_previousframe) - hboxtimeframes.addWidget(parent.button_timeindex) - hboxtimeframes.addWidget(parent.button_nextframe) - hboxtimeframes.addStretch() - - - # add the frames of the pictures in the layout. - hlayout = QtWidgets.QHBoxLayout() - hlayout.addWidget(parent.m) - hlayout.setContentsMargins(0, 0, 0, 0) - - layout.addLayout(hlayout) - - layout.addLayout(hboxtimeframes) - -# layout.addStretch(0.7) - - hboxcorrectionsbuttons = QtWidgets.QHBoxLayout() - hboxcorrectionsbuttons.addWidget(parent.button_add_region) - hboxcorrectionsbuttons.addWidget(parent.button_newcell) - hboxcorrectionsbuttons.addWidget(parent.button_drawmouse) - hboxcorrectionsbuttons.addWidget(parent.button_eraser) - hboxcorrectionsbuttons.addWidget(parent.button_savemask) - hboxcorrectionsbuttons.addStretch(1) - hboxcorrectionsbuttons.addWidget(parent.button_showval) - hboxcorrectionsbuttons.addWidget(parent.button_hidemask) - layout.addLayout(hboxcorrectionsbuttons) - - - - -# LAYOUT FOR EDITING CELL VALUES, SHOW CELL VALUES AND HIDE MASK, CNN BUTTONS - - hboxcellval = QtWidgets.QHBoxLayout() - hboxcellval.addWidget(parent.button_exval) - hboxcellval.addWidget(parent.button_changecellvalue) - hboxcellval.addStretch(1) - hboxcellval.addWidget(parent.button_cnn) - hboxcellval.addWidget(parent.button_cellcorespondance) - hboxcellval.addWidget(parent.button_extractfluorescence) - layout.addLayout(hboxcellval) - - - -# # LAYOUT FOR LAUNCH NN, TRACK CELLS AND EXTRACT FLUORESCENCE - -# hboxcnnbuttons = QtWidgets.QHBoxLayout() -# hboxcnnbuttons.addStretch(1) - - - -# layout.addLayout(hboxcnnbuttons) - - - - - # BUTTONS TO SHOW THE THRESHOLD AND SEGMENTATION ARE HIDDEN HERE! - # UNCOMMENT THEM TO MAKE THEM APPEAR ON THE GUI. - - # layout.addLayout(hbox_threshold) - - # layout.addLayout(hbox_segment) - + + # LAYOUT OF THE MAIN WINDOW + layout = QtWidgets.QVBoxLayout(parent._main) + + # LAYOUT FOR THE TOOLBAR BUTTONS + hbox = QtWidgets.QHBoxLayout() + hbox.addWidget(parent.button_home) + hbox.addWidget(parent.button_back) + hbox.addWidget(parent.button_forward) + hbox.addWidget(parent.button_pan) + hbox.addWidget(parent.button_zoom) + hbox.addStretch(1) + layout.addLayout(hbox) + + # TIME NAVIGATION + hboxtimeframes = QtWidgets.QHBoxLayout() + hboxtimeframes.addWidget(parent.button_fov) + hboxtimeframes.addWidget(parent.button_channel) + hboxtimeframes.addStretch() + hboxtimeframes.addWidget(parent.button_previousframe) + hboxtimeframes.addWidget(parent.button_timeindex) + hboxtimeframes.addWidget(parent.button_nextframe) + hboxtimeframes.addStretch() + + # IMAGE DISPLAY + hlayout = QtWidgets.QHBoxLayout() + hlayout.addWidget(parent.m) + hlayout.setContentsMargins(0, 0, 0, 0) + layout.addLayout(hlayout) + layout.addLayout(hboxtimeframes) + + # CORRECTIONS/ IMAGE EDITS + hboxcorrectionsbuttons = QtWidgets.QHBoxLayout() + hboxcorrectionsbuttons.addWidget(parent.button_add_region) + hboxcorrectionsbuttons.addWidget(parent.button_newcell) + hboxcorrectionsbuttons.addWidget(parent.button_drawmouse) + hboxcorrectionsbuttons.addWidget(parent.button_eraser) + hboxcorrectionsbuttons.addStretch(1) + hboxcorrectionsbuttons.addWidget(parent.button_showval) + hboxcorrectionsbuttons.addWidget(parent.button_hidemask) + layout.addLayout(hboxcorrectionsbuttons) + + # LAYOUT FOR EDITING CELL VALUES, SHOW CELL VALUES AND HIDE MASK, CNN BUTTONS + hboxcellval = QtWidgets.QHBoxLayout() + hboxcellval.addWidget(parent.button_exval) + hboxcellval.addWidget(parent.button_changecellvalue) + hboxcellval.addStretch(1) + hboxcellval.addWidget(parent.button_cnn) + hboxcellval.addWidget(parent.button_cellcorespondance) + hboxcellval.addWidget(parent.button_extractfluorescence) + layout.addLayout(hboxcellval) diff --git a/misc/PlotCanvas.py b/misc/PlotCanvas.py index 801bd2c072ebff24b1383c5cfd8a8c57a9a2ab27..f3c04d2bfc6a4d2a7797dcb9bab4603cd7a7d83d 100644 --- a/misc/PlotCanvas.py +++ b/misc/PlotCanvas.py @@ -126,9 +126,8 @@ class PlotCanvas(FigureCanvas): for i in range(0,len(indices[0])): self.plotmask[indices[0][i], indices[1][i]] = val2 self.updatedata() - else: - return + raise ValueError('Cell value does not exist.') def ReleaseClick(self, event):