def __init__(self, *args, **kw): super(ImportDialog, self).__init__(*args, **kw) loadUI(splitext(__file__)[0] + '.ui', self) for name, scn in FileScanner.iterclasses(): self.structType.addItem(scn.icon(), name) self.structType.setIconSize(QtCore.QSize(48, 24)) self.metadata = None self._files = None self.progressBar.hide() self.segdlg = SegmentationDialog(self) self.segdlg.hide() self.thread = AtThread(self) self.viewer.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) self.cbar = ChannelBar(self, self.viewer) self.cbox.addWidget(self.cbar) self.cbar.newPixmap.connect(self.viewer.showPixmap, Qt.DirectConnection) self.cbar.newContourImage.connect(self.viewer.contourImage) self.dataFileBtn.clicked.connect(self.onOpenOutFile) self.imageDirBtn.clicked.connect(self.onOpenImageDir) self.startBtn.clicked.connect(self.raw2hdf) self.closeBtn.clicked.connect(self.close) self.closeBtn.clicked.connect(self.cbar.clear) self.segmentationBtn.clicked.connect(self.onSegmentationBtn) self.slider.newValue.connect(self.showObjects) self.slider.valueChanged.connect(self.showImage) self.slider.sliderReleased.connect(self.showObjects) self.slider.sliderPressed.connect(self.cbar.clearContours) self.contoursCb.stateChanged.connect(self.onContours) self.showBBoxes.stateChanged.connect(self.onBBoxes) self.showBBoxes.stateChanged.connect(self.showObjects) self.segdlg.paramsChanged.connect(self.showObjects) self.segdlg.refreshBtn.clicked.connect(self.showObjects) self.segdlg.imageUpdate.connect(self.showImage) self.segdlg.activateChannels.connect(self.cbar.activateChannels) self.segdlg.changeColor.connect(self.cbar.setColor) self.nextBtn.clicked.connect(self.onNextBtn) self.prevBtn.clicked.connect(self.onPrevBtn)
def __init__(self, *args, **kw): super(ImportDialog, self).__init__(*args, **kw) loadUI(splitext(__file__)[0]+'.ui', self) for name, scn in FileScanner.iterclasses(): self.structType.addItem(scn.icon(), name) self.structType.setIconSize(QtCore.QSize(48, 24)) self.metadata = None self._files = None self.progressBar.hide() self.segdlg = SegmentationDialog(self) self.segdlg.hide() self.thread = AtThread(self) self.viewer.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) self.cbar = ChannelBar(self, self.viewer) self.cbox.addWidget(self.cbar) self.cbar.newPixmap.connect(self.viewer.showPixmap, Qt.DirectConnection) self.cbar.newContourImage.connect(self.viewer.contourImage) self.dataFileBtn.clicked.connect(self.onOpenOutFile) self.imageDirBtn.clicked.connect(self.onOpenImageDir) self.startBtn.clicked.connect(self.raw2hdf) self.closeBtn.clicked.connect(self.close) self.closeBtn.clicked.connect(self.cbar.clear) self.segmentationBtn.clicked.connect(self.onSegmentationBtn) self.slider.newValue.connect(self.showObjects) self.slider.valueChanged.connect(self.showImage) self.slider.sliderReleased.connect(self.showObjects) self.slider.sliderPressed.connect(self.cbar.clearContours) self.contoursCb.stateChanged.connect(self.onContours) self.showBBoxes.stateChanged.connect(self.onBBoxes) self.showBBoxes.stateChanged.connect(self.showObjects) self.segdlg.paramsChanged.connect(self.showObjects) self.segdlg.refreshBtn.clicked.connect(self.showObjects) self.segdlg.imageUpdate.connect(self.showImage) self.segdlg.activateChannels.connect(self.cbar.activateChannels) self.segdlg.changeColor.connect(self.cbar.setColor) self.nextBtn.clicked.connect(self.onNextBtn) self.prevBtn.clicked.connect(self.onPrevBtn)
def __init__(self, file_=None, *args, **kw): super(AtMainWindow, self).__init__(*args, **kw) loadUI(splitext(__file__)[0]+'.ui', self) self.setWindowTitle(version.appstr) self.setAcceptDrops(True) self.featuredlg = AtFeatureSelectionDlg(self) self.featuredlg.hide() self.loaderThread = AtThread(self) self.loader = AtLoader() self._lastdir = expanduser("~") try: self.assistant = AtAssistant(MANUAL) self.assistant.hide() except IOError: QMessageBox.information(self, "Information", "Sorry help files are not installed") self.setupToolbar() self.tileview = AtGraphicsView( parent=self, gsize=self.navToolBar.galsize) self.toolBar.valueChanged.connect(self.tileview.zoom) self.toolBar.classification.stateChanged.connect( self.tileview.toggleClassIndicators, Qt.QueuedConnection) self.toolBar.masking.stateChanged.connect( self.tileview.toggleMasks, Qt.QueuedConnection) self.toolBar.outline.stateChanged.connect( self.tileview.toggleOutlines, Qt.QueuedConnection) self.toolBar.description.stateChanged.connect( self.tileview.toggleDescription, Qt.QueuedConnection) self.setCentralWidget(self.tileview) self.setupDock() self.setupProgressBar() self.loader.fileOpened.connect(self.updateToolbars) self.loader.progressUpdate.connect(self.updateProgressBar) self.loader.itemLoaded.connect(self.tileview.addItem) self.abort.connect(self.loader.abort) self.actionNewFile.triggered.connect(self.newDataFile) self.actionOpenHdf.triggered.connect(self.onFileOpen) self.actionCloseHdf.triggered.connect(self.onFileClose) self.actionPreferences.triggered.connect(self.onPreferences) self.actionExportViewPanel.triggered.connect(self.saveImage) self.actionSaveData2Csv.triggered.connect(self.saveData2Csv) self.actionSaveCountingStats.triggered.connect(self.saveCountingStats) self.actionAboutQt.triggered.connect(self.onAboutQt) self.actionAboutAnnotationTool.triggered.connect(self.onAbout) self.actionFeatureSelection.triggered.connect( self.showFeatureDlg) self.actionHelpManual.triggered.connect(self.onHelpManual) self.actionShortcuts.triggered.connect(self.onHelpShortcuts) self.actionRefresh.triggered.connect(self.refresh) self.actionSelectAll.triggered.connect( self.tileview.actionSelectAll.trigger) self.actionInvertSelection.triggered.connect( self.tileview.actionInvertSelection.trigger) self.tileview.zoomChanged.connect(self.updateZoomFactor) self.featuredlg.selectionChanged.connect( self.annotation.predictionInvalid) self.loader.started.connect(self.onLoadingStarted) self.zoom = QtWidgets.QLabel('100%') self.statusbar.insertPermanentWidget(0, self.zoom) self.statusbar.insertPermanentWidget(1, QtWidgets.QLabel('Number of items:')) self.nitems = QtWidgets.QLabel('0') self.statusbar.insertPermanentWidget(2, self.nitems) self._restoreSettings() self.navToolBar.hide() self.show() if file_ is not None: self.loader.openFile(file_) self.loadItems()
class AtMainWindow(QtWidgets.QMainWindow): coordUpdated = QtCore.pyqtSignal("PyQt_PyObject") abort = QtCore.pyqtSignal() def __init__(self, file_=None, *args, **kw): super(AtMainWindow, self).__init__(*args, **kw) loadUI(splitext(__file__)[0]+'.ui', self) self.setWindowTitle(version.appstr) self.setAcceptDrops(True) self.featuredlg = AtFeatureSelectionDlg(self) self.featuredlg.hide() self.loaderThread = AtThread(self) self.loader = AtLoader() self._lastdir = expanduser("~") try: self.assistant = AtAssistant(MANUAL) self.assistant.hide() except IOError: QMessageBox.information(self, "Information", "Sorry help files are not installed") self.setupToolbar() self.tileview = AtGraphicsView( parent=self, gsize=self.navToolBar.galsize) self.toolBar.valueChanged.connect(self.tileview.zoom) self.toolBar.classification.stateChanged.connect( self.tileview.toggleClassIndicators, Qt.QueuedConnection) self.toolBar.masking.stateChanged.connect( self.tileview.toggleMasks, Qt.QueuedConnection) self.toolBar.outline.stateChanged.connect( self.tileview.toggleOutlines, Qt.QueuedConnection) self.toolBar.description.stateChanged.connect( self.tileview.toggleDescription, Qt.QueuedConnection) self.setCentralWidget(self.tileview) self.setupDock() self.setupProgressBar() self.loader.fileOpened.connect(self.updateToolbars) self.loader.progressUpdate.connect(self.updateProgressBar) self.loader.itemLoaded.connect(self.tileview.addItem) self.abort.connect(self.loader.abort) self.actionNewFile.triggered.connect(self.newDataFile) self.actionOpenHdf.triggered.connect(self.onFileOpen) self.actionCloseHdf.triggered.connect(self.onFileClose) self.actionPreferences.triggered.connect(self.onPreferences) self.actionExportViewPanel.triggered.connect(self.saveImage) self.actionSaveData2Csv.triggered.connect(self.saveData2Csv) self.actionSaveCountingStats.triggered.connect(self.saveCountingStats) self.actionAboutQt.triggered.connect(self.onAboutQt) self.actionAboutAnnotationTool.triggered.connect(self.onAbout) self.actionFeatureSelection.triggered.connect( self.showFeatureDlg) self.actionHelpManual.triggered.connect(self.onHelpManual) self.actionShortcuts.triggered.connect(self.onHelpShortcuts) self.actionRefresh.triggered.connect(self.refresh) self.actionSelectAll.triggered.connect( self.tileview.actionSelectAll.trigger) self.actionInvertSelection.triggered.connect( self.tileview.actionInvertSelection.trigger) self.tileview.zoomChanged.connect(self.updateZoomFactor) self.featuredlg.selectionChanged.connect( self.annotation.predictionInvalid) self.loader.started.connect(self.onLoadingStarted) self.zoom = QtWidgets.QLabel('100%') self.statusbar.insertPermanentWidget(0, self.zoom) self.statusbar.insertPermanentWidget(1, QtWidgets.QLabel('Number of items:')) self.nitems = QtWidgets.QLabel('0') self.statusbar.insertPermanentWidget(2, self.nitems) self._restoreSettings() self.navToolBar.hide() self.show() if file_ is not None: self.loader.openFile(file_) self.loadItems() def updateProgressBar(self, value): if value < 0: self.progressbar.setRange(0, 0) self.progressbar.setValue(value) def updateZoomFactor(self, factor): self.zoom.setText("%d%s" %(round(100*factor, 0), "%")) def dragEnterEvent(self, event): event.acceptProposedAction() def dragMoveEvent(self, event): event.acceptProposedAction() def dropEvent(self, event): mimeData = event.mimeData() if mimeData.hasUrls(): if len(mimeData.urls()) == 1: self.abort.emit() self.loaderThread.wait() self.loader.close() self.onDropEvent(fix_path(mimeData.urls()[0].path())) event.acceptProposedAction() def dragLeaveEvent(self, event): event.accept() def onHelpManual(self): self.assistant.show() self.assistant.raise_() def onHelpShortcuts(self): self.onHelpManual() self.assistant.openKeyword("Shortcuts") def refresh(self): self.tileview.actionRefresh.trigger() self.contrast.enhanceContrast() def showFeatureDlg(self): self.featuredlg.show() self.featuredlg.raise_() def onPreferences(self): dlg = AtPreferencesDialog(self) dlg.exec_() def onAboutQt(self): QMessageBox.aboutQt(self, "about Qt") def onAbout(self): dlg = AtAboutDialog(self) dlg.exec_() def _saveSettings(self): settings = QtCore.QSettings(version.organisation, version.appname) settings.beginGroup('Gui') settings.setValue('state', self.saveState()) settings.setValue('geometry', self.saveGeometry()) settings.setValue('classifier', self.annotation.classifiers.currentText()) settings.endGroup() AtConfig().saveSettings() def _restoreSettings(self): settings = QtCore.QSettings(version.organisation, version.appname) settings.beginGroup('Gui') if settings.contains('geometry'): geometry = settings.value('geometry') self.restoreGeometry(geometry) if settings.contains('state'): state = settings.value('state') self.restoreState(state) if settings.contains('classifier'): clfname = settings.value("classifier") self.annotation.setCurrentClassifier(clfname) AtConfig().restoreSettings() settings.endGroup() def closeEvent(self, event): self.assistant.close() self._saveSettings() try: self.abort.emit() self.loaderThread.wait() self.loader.close() if self.assistant is not None: self.assistant.close() except AttributeError: pass def setupDock(self): self.contrast = AtContrastWidget(self, self.tileview) self.sorting = AtSortWidget(self, self.tileview, self.featuredlg) self.annotation = AtAnnotationWidget( self, self.tileview, self.featuredlg) self.contrastdock = QtWidgets.QDockWidget("Contrast", self) self.contrastdock.setWidget(self.contrast) self.contrastdock.setObjectName("contrast") self.addDockWidget(Qt.LeftDockWidgetArea, self.contrastdock) self.sortdock = QtWidgets.QDockWidget("Sorting", self) self.sortdock.setWidget(self.sorting) self.sortdock.setObjectName("sorting") self.addDockWidget(Qt.RightDockWidgetArea, self.sortdock) self.annodock = QtWidgets.QDockWidget("Annotation", self) self.annodock.setWidget(self.annotation) self.annodock.setObjectName("annotation") self.addDockWidget(Qt.RightDockWidgetArea, self.annodock) self.tabifyDockWidget(self.sortdock, self.annodock) # add action to the view menu sort_action = self.sortdock.toggleViewAction() sort_action.setShortcuts(QKeySequence(Qt.ALT + Qt.SHIFT + Qt.Key_S)) self.menuView.addAction(sort_action) anno_action = self.annodock.toggleViewAction() anno_action.setShortcuts(QKeySequence(Qt.ALT + Qt.SHIFT + Qt.Key_A)) self.menuView.addAction(anno_action) contrast_action = self.contrastdock.toggleViewAction() contrast_action.setShortcuts( QKeySequence(Qt.ALT + Qt.SHIFT + Qt.Key_C)) self.menuView.addAction(contrast_action) # crosslink sorter dock and sorter toolbar self.sortToolBar.sortAlgorithm.currentIndexChanged.connect( self.sorting.sortAlgorithm.setCurrentIndex) self.sorting.sortAlgorithm.currentIndexChanged.connect( self.sortToolBar.sortAlgorithm.setCurrentIndex) self.sortToolBar.sortAscendingBtn.clicked.connect( self.sorting.sortAscending) self.sortToolBar.sortDescendingBtn.clicked.connect( self.sorting.sortDescending) def setupProgressBar(self): frame = QtWidgets.QFrame(self) self.progressbar = QtWidgets.QProgressBar(frame) self.progressbar.setMaximumHeight(15) self.abortBtn = QtWidgets.QPushButton('abort', self) self.abortBtn.clicked.connect(self.abort.emit) self.abortBtn.setMaximumHeight(20) hbox = QtWidgets.QHBoxLayout(frame) hbox.addWidget(self.progressbar) hbox.addWidget(self.abortBtn) hbox.setContentsMargins(0, 0, 0, 0) self.loaderThread.started.connect(frame.show) self.loaderThread.finished.connect(frame.hide) frame.hide() self.statusBar().addPermanentWidget(frame) def saveImage(self): filename = QFileDialog.getSaveFileName( self, "Save image as ...", self._lastdir.replace('.hdf', '.png'), "png - Image (*.png)")[0] if filename: scene = self.tileview.scene() size = scene.sceneRect().size().toSize() image = QtGui.QImage(size, QtGui.QImage.Format_RGB32) painter = QtGui.QPainter(image) image.fill(QtCore.Qt.white) scene.render(painter) painter.end() image.save(filename) self.statusBar().showMessage("Image saved to %s" %filename) def saveData2Csv(self): filename = QFileDialog.getSaveFileName( self, "Save csv-file as ...", self._lastdir.replace(".hdf", ".csv"), "Comma separated values (*.csv)")[0] if filename: features = self.featuredlg.checkedItems() exporter = CsvExporter(filename, self.tileview.items, features) exporter.save() self.statusBar().showMessage("Image saved to %s" %filename) def saveCountingStats(self): filename = QFileDialog.getSaveFileName( self, "Save csv-file as ...", self._lastdir.replace(".hdf", "_statistics.csv"), "Comma separated values (*.csv)")[0] if filename: features = self.featuredlg.checkedItems() exporter = StatsExporter(filename, self.tileview.items, features) exporter.save() self.statusBar().showMessage("Image saved to %s" %filename) def updateToolbars(self, props): # in case of cellh5 file if props.gal_settings_mutable: self.navToolBar.show() self.navToolBar.updateToolbar(props) self.contrast.setChannelNames(props.channel_names, props.colors) self.nitems.setText(str(props.n_items)) def setupToolbar(self): self.toolBar = ViewToolBar(self) self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) self.toolBar.actionOpen.triggered.connect(self.onFileOpen) self.toolBar.actionNew.triggered.connect(self.newDataFile) self.actionReloadFile.triggered.connect(self.loadItems) self.navToolBar = NavToolBar(self) self.addToolBar(QtCore.Qt.BottomToolBarArea, self.navToolBar) self.navToolBar.coordUpdated.connect(self.loader.setCoordinate) self.sortToolBar = SortToolBar(self) self.addToolBar(QtCore.Qt.TopToolBarArea, self.sortToolBar) def newDataFile(self): dlg = ImportDialog(self, Qt.WindowMinMaxButtonsHint|Qt.WindowCloseButtonHint) dlg.loadData.connect(self._openAndLoad) dlg.exec_() def onThrowAnchor(self): self.sorting.removeAll() self.sorting.addItems(self.tileview.selectedItems()) self.sorting.applyDefaultSortAlgorithm() self.sorting.sortAscending() def addToSortPanel(self): self.sorting.addItems(self.tileview.selectedItems()) def onFileClose(self): self.loader.close() self.tileview.clear() self.featuredlg.clear() self.sorting.clear() def onFileOpen(self): file_ = QFileDialog.getOpenFileName( self, "Open hdf5 file", self._lastdir, "Hdf files (*.hdf5 *.ch5 *.hdf *.h5)")[0] if bool(file_): self._fileOpen(file_) self.loadItems() def _fileOpen(self, file_): self._lastdir = abspath(file_) try: self.loader.openFile(file_) except Exception as e: self.statusBar().showMessage(str(e)) msg = "Could not open file\n %s" %str(e) QMessageBox.critical(self, "Error", msg) else: self.statusBar().showMessage(basename(file_)) def _openAndLoad(self, file_): self.onFileClose() self._fileOpen(file_) self.loadItems() def onLoadingStarted(self): self.annotation.setFeatureNames(self.loader.featureNames) try: self.featuredlg.setFeatureGroups(self.loader.featureGroups) self.sorting.setFeatureGroups(self.loader.featureGroups) except RuntimeError as e: pass def onDropEvent(self, path): self._fileOpen(path) self.loadItems() def loadItems(self): self.abort.emit() self.loaderThread.wait() self.tileview.setViewFlags(self.toolBar.viewFlags()) self.tileview.clear() self.tileview.updateRaster(self.navToolBar.galsize) self.tileview.updateNColumns(self.tileview.size().width()) self.progressbar.setRange(0, self.navToolBar.nitems) self.loader.setNumberItems(self.navToolBar.nitems) self.loader.setGallerySize(self.navToolBar.galsize) self.loaderThread.start(self.loader)
class ImportDialog(QtWidgets.QDialog): loadData = QtCore.pyqtSignal(str) def __init__(self, *args, **kw): super(ImportDialog, self).__init__(*args, **kw) loadUI(splitext(__file__)[0] + '.ui', self) for name, scn in FileScanner.iterclasses(): self.structType.addItem(scn.icon(), name) self.structType.setIconSize(QtCore.QSize(48, 24)) self.metadata = None self._files = None self.progressBar.hide() self.segdlg = SegmentationDialog(self) self.segdlg.hide() self.thread = AtThread(self) self.viewer.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) self.cbar = ChannelBar(self, self.viewer) self.cbox.addWidget(self.cbar) self.cbar.newPixmap.connect(self.viewer.showPixmap, Qt.DirectConnection) self.cbar.newContourImage.connect(self.viewer.contourImage) self.dataFileBtn.clicked.connect(self.onOpenOutFile) self.imageDirBtn.clicked.connect(self.onOpenImageDir) self.startBtn.clicked.connect(self.raw2hdf) self.closeBtn.clicked.connect(self.close) self.closeBtn.clicked.connect(self.cbar.clear) self.segmentationBtn.clicked.connect(self.onSegmentationBtn) self.slider.newValue.connect(self.showObjects) self.slider.valueChanged.connect(self.showImage) self.slider.sliderReleased.connect(self.showObjects) self.slider.sliderPressed.connect(self.cbar.clearContours) self.contoursCb.stateChanged.connect(self.onContours) self.showBBoxes.stateChanged.connect(self.onBBoxes) self.showBBoxes.stateChanged.connect(self.showObjects) self.segdlg.paramsChanged.connect(self.showObjects) self.segdlg.refreshBtn.clicked.connect(self.showObjects) self.segdlg.imageUpdate.connect(self.showImage) self.segdlg.activateChannels.connect(self.cbar.activateChannels) self.segdlg.changeColor.connect(self.cbar.setColor) self.nextBtn.clicked.connect(self.onNextBtn) self.prevBtn.clicked.connect(self.onPrevBtn) def keyPressEvent(self, event): if event.key() == Qt.Key_F5: self.showObjects() def closeEvent(self, event): super(ImportDialog, self).closeEvent(event) ofile = self.dataFile.text() if self.loadOnClose.isChecked() and isfile(ofile): self.loadData.emit(ofile) def onNextBtn(self): self.slider.setValue(self.slider.value() + 1) self.showObjects() def onPrevBtn(self): self.slider.setValue(self.slider.value() - 1) self.showObjects() def onContours(self, state): if state == Qt.Checked: self.showObjects() else: self.cbar.clearContours() self.viewer.clearPolygons() def onBBoxes(self, state): if state == Qt.Checked: self.showObjects() else: self.viewer.clearRects() def onSegmentationBtn(self): self.segdlg.show() self.segdlg.raise_() def onOpenOutFile(self): ofile = self.dataFile.text() idir = self.imageDir.text() if isfile(ofile): path = dirname(ofile) elif isdir(idir): path = dirname(idir) else: path = expanduser("~") ofile = QFileDialog.getSaveFileName(self, "save to hdf file", path, "hdf (*.hdf *.h5)")[0] self.dataFile.setText(ofile) def onOpenImageDir(self): self.cbar.clearContours() self.viewer.clearRects() self.viewer.clearPolygons() idir = self.imageDir.text() ofile = self.dataFile.text() if isdir(idir): path = dirname(idir) elif isfile(ofile): path = dirname(ofile) else: path = expanduser("~") # TODO use getOpenFileNames instead idir = QFileDialog.getExistingDirectory(self, "Select an image directory", path) # cancel button if not idir: return self.imageDir.setText(idir) scanner = FileScanner(self.structType.currentText(), idir) self._files = scanner() if not self._files: QMessageBox.warning(self, "Error", "No files found") return self.dirinfo.setText("%d images found" % len(self._files)) proc = LsmProcessor(self._files.keys()[0], self.segdlg.segmentationParams(), self.cbar.checkedChannels(), treatment=self._files.values()[0]) self.metadata = proc.metadata self.metadata.n_images = len(self._files) images = list(proc.iterQImages()) props = list(proc.iterprops()) self.cbar.addChannels(len(images)) self.cbar.setImages(images, list(proc.iterprops())) state = self.segdlg.blockSignals(True) self.segdlg.setRegions(self.cbar.allChannels(), props) self.segdlg.setMaxZSlice(self.metadata.n_zslices - 1) self.segdlg.blockSignals(state) self.slider.setRange(0, self.metadata.n_images - 1) self.slider.setValue(0) self.showObjects() def showImage(self, index=0): # no image directory yet if self._files is None: return try: proc = LsmProcessor(self._files.keys()[index], self.segdlg.segmentationParams(), self.cbar.checkedChannels(), treatment=self._files.values()[index]) except IndexError: return self.viewer.clearPolygons() self.viewer.clearRects() images = list(proc.iterQImages()) self.cbar.setImages(images, list(proc.iterprops())) def showObjects(self): if not (self.contoursCb.isChecked() or \ self.showBBoxes.isChecked()) or \ self._files is None: return index = self.slider.value() try: mp = LsmProcessor(self._files.keys()[index], self.segdlg.segmentationParams(), self.cbar.checkedChannels(), treatment=self._files.values()[index]) # first channel for primary segementation mp.segmentation() except Exception as e: QMessageBox.critical(self, "Error", "%s:%s" % (type(e), str(e))) finally: if not mp.objects: return if self.contoursCb.isChecked(): self.cbar.setContours(mp.objects.contours) if self.showBBoxes.isChecked(): self.cbar.drawRectangles(mp.objects.centers.values(), self.segdlg.galSize.value(), isize=self.metadata.size) def onError(self, exc): self.startBtn.setText("Start") QMessageBox.critical(self, "Error", str(exc)) def onFinished(self): self.raise_() self.startBtn.setText("Start") QMessageBox.information(self, "finished", "training set saved") def showSlider(self): self.progressBar.hide() self.sliderframe.show() def hideSlider(self): self.progressBar.show() self.sliderframe.hide() def raw2hdf(self): if self.thread.isRunning(): self.startBtn.setText("Start") self.thread.worker.abort() else: self.viewer.clearPolygons() self.viewer.clearRects() try: worker = AtImporter(self._files, self.metadata, self.dataFile.text(), self.cbar.checkedChannels(), self.cbar.colors(), self.segdlg.segmentationParams(), self.segdlg.featureGroups()) except Exception as e: QMessageBox.critical(self, str(e), traceback.format_exc()) return worker.connetToProgressBar(self.progressBar, Qt.QueuedConnection) worker.started.connect(self.hideSlider) worker.finished.connect(self.showSlider) worker.finished.connect(self.onFinished, Qt.QueuedConnection) worker.error.connect(self.onError, Qt.QueuedConnection) worker.contourImage.connect(self.cbar.contourImage, Qt.QueuedConnection) self.thread.start(worker) self.startBtn.setText("Abort")
class ImportDialog(QtWidgets.QDialog): loadData = QtCore.pyqtSignal(str) def __init__(self, *args, **kw): super(ImportDialog, self).__init__(*args, **kw) loadUI(splitext(__file__)[0]+'.ui', self) for name, scn in FileScanner.iterclasses(): self.structType.addItem(scn.icon(), name) self.structType.setIconSize(QtCore.QSize(48, 24)) self.metadata = None self._files = None self.progressBar.hide() self.segdlg = SegmentationDialog(self) self.segdlg.hide() self.thread = AtThread(self) self.viewer.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) self.cbar = ChannelBar(self, self.viewer) self.cbox.addWidget(self.cbar) self.cbar.newPixmap.connect(self.viewer.showPixmap, Qt.DirectConnection) self.cbar.newContourImage.connect(self.viewer.contourImage) self.dataFileBtn.clicked.connect(self.onOpenOutFile) self.imageDirBtn.clicked.connect(self.onOpenImageDir) self.startBtn.clicked.connect(self.raw2hdf) self.closeBtn.clicked.connect(self.close) self.closeBtn.clicked.connect(self.cbar.clear) self.segmentationBtn.clicked.connect(self.onSegmentationBtn) self.slider.newValue.connect(self.showObjects) self.slider.valueChanged.connect(self.showImage) self.slider.sliderReleased.connect(self.showObjects) self.slider.sliderPressed.connect(self.cbar.clearContours) self.contoursCb.stateChanged.connect(self.onContours) self.showBBoxes.stateChanged.connect(self.onBBoxes) self.showBBoxes.stateChanged.connect(self.showObjects) self.segdlg.paramsChanged.connect(self.showObjects) self.segdlg.refreshBtn.clicked.connect(self.showObjects) self.segdlg.imageUpdate.connect(self.showImage) self.segdlg.activateChannels.connect(self.cbar.activateChannels) self.segdlg.changeColor.connect(self.cbar.setColor) self.nextBtn.clicked.connect(self.onNextBtn) self.prevBtn.clicked.connect(self.onPrevBtn) def keyPressEvent(self, event): if event.key() == Qt.Key_F5: self.showObjects() def closeEvent(self, event): super(ImportDialog, self).closeEvent(event) ofile = self.dataFile.text() if self.loadOnClose.isChecked() and isfile(ofile): self.loadData.emit(ofile) def onNextBtn(self): self.slider.setValue(self.slider.value()+1) self.showObjects() def onPrevBtn(self): self.slider.setValue(self.slider.value()-1) self.showObjects() def onContours(self, state): if state == Qt.Checked: self.showObjects() else: self.cbar.clearContours() self.viewer.clearPolygons() def onBBoxes(self, state): if state == Qt.Checked: self.showObjects() else: self.viewer.clearRects() def onSegmentationBtn(self): self.segdlg.show() self.segdlg.raise_() def onOpenOutFile(self): ofile = self.dataFile.text() idir = self.imageDir.text() if isfile(ofile): path = dirname(ofile) elif isdir(idir): path = dirname(idir) else: path = expanduser("~") ofile = QFileDialog.getSaveFileName(self, "save to hdf file", path, "hdf (*.hdf *.h5)")[0] self.dataFile.setText(ofile) def onOpenImageDir(self): self.cbar.clearContours() self.viewer.clearRects() self.viewer.clearPolygons() idir = self.imageDir.text() ofile = self.dataFile.text() if isdir(idir): path = dirname(idir) elif isfile(ofile): path = dirname(ofile) else: path = expanduser("~") # TODO use getOpenFileNames instead idir = QFileDialog.getExistingDirectory(self, "Select an image directory", path) # cancel button if not idir: return self.imageDir.setText(idir) scanner = FileScanner(self.structType.currentText(), idir) self._files = scanner() if not self._files: QMessageBox.warning(self, "Error", "No files found") return self.dirinfo.setText("%d images found" %len(self._files)) proc = LsmProcessor(self._files.keys()[0], self.segdlg.segmentationParams(), self.cbar.checkedChannels(), treatment=self._files.values()[0]) self.metadata = proc.metadata self.metadata.n_images = len(self._files) images = list(proc.iterQImages()) props = list(proc.iterprops()) self.cbar.addChannels(len(images)) self.cbar.setImages(images, list(proc.iterprops())) state = self.segdlg.blockSignals(True) self.segdlg.setRegions(self.cbar.allChannels(), props) self.segdlg.setMaxZSlice(self.metadata.n_zslices-1) self.segdlg.blockSignals(state) self.slider.setRange(0, self.metadata.n_images-1) self.slider.setValue(0) self.showObjects() def showImage(self, index=0): # no image directory yet if self._files is None: return try: proc = LsmProcessor(self._files.keys()[index], self.segdlg.segmentationParams(), self.cbar.checkedChannels(), treatment=self._files.values()[index]) except IndexError: return self.viewer.clearPolygons() self.viewer.clearRects() images = list(proc.iterQImages()) self.cbar.setImages(images, list(proc.iterprops())) def showObjects(self): if not (self.contoursCb.isChecked() or \ self.showBBoxes.isChecked()) or \ self._files is None: return index = self.slider.value() try: mp = LsmProcessor(self._files.keys()[index], self.segdlg.segmentationParams(), self.cbar.checkedChannels(), treatment=self._files.values()[index]) # first channel for primary segementation mp.segmentation() except Exception as e: QMessageBox.critical(self, "Error", "%s:%s" %(type(e), str(e))) finally: if not mp.objects: return if self.contoursCb.isChecked(): self.cbar.setContours(mp.objects.contours) if self.showBBoxes.isChecked(): self.cbar.drawRectangles(mp.objects.centers.values(), self.segdlg.galSize.value(), isize=self.metadata.size) def onError(self, exc): self.startBtn.setText("Start") QMessageBox.critical(self, "Error", str(exc)) def onFinished(self): self.raise_() self.startBtn.setText("Start") QMessageBox.information(self, "finished", "training set saved") def showSlider(self): self.progressBar.hide() self.sliderframe.show() def hideSlider(self): self.progressBar.show() self.sliderframe.hide() def raw2hdf(self): if self.thread.isRunning(): self.startBtn.setText("Start") self.thread.worker.abort() else: self.viewer.clearPolygons() self.viewer.clearRects() try: worker = AtImporter(self._files, self.metadata, self.dataFile.text(), self.cbar.checkedChannels(), self.cbar.colors(), self.segdlg.segmentationParams(), self.segdlg.featureGroups()) except Exception as e: QMessageBox.critical(self, str(e), traceback.format_exc()) return worker.connetToProgressBar(self.progressBar, Qt.QueuedConnection) worker.started.connect(self.hideSlider) worker.finished.connect(self.showSlider) worker.finished.connect(self.onFinished, Qt.QueuedConnection) worker.error.connect(self.onError, Qt.QueuedConnection) worker.contourImage.connect(self.cbar.contourImage, Qt.QueuedConnection) self.thread.start(worker) self.startBtn.setText("Abort")