def _chooseDirectory(self):
        # Find the directory of the most recently opened image file
        mostRecentStackDirectory = PreferencesManager().get( 'DataSelection', 'recent stack directory' )
        if mostRecentStackDirectory is not None:
            defaultDirectory = os.path.split(mostRecentStackDirectory)[0]
        else:
            defaultDirectory = os.path.expanduser('~')

        options = QFileDialog.Options(QFileDialog.ShowDirsOnly)
        if ilastik.config.cfg.getboolean("ilastik", "debug"):
            options |= QFileDialog.DontUseNativeDialog

        # Launch the "Open File" dialog
        directory = QFileDialog.getExistingDirectory( 
                     self, "Image Stack Directory", defaultDirectory, options=options )

        if directory.isNull():
            # User cancelled
            return

        directory = encode_from_qstring( directory )
        PreferencesManager().set('DataSelection', 'recent stack directory', directory)

        self.directoryEdit.setText( decode_to_qstring(directory) )
        globstring = self._getGlobString(directory)
        if globstring is not None:
            filenames = [k.replace('\\', '/') for k in glob.glob(globstring)]
            self._updateFileList( sorted(filenames) )
        
            # As a convenience, also show the glob string in the pattern field
            self.patternEdit.setText( decode_to_qstring(globstring) )
Exemple #2
0
    def _initStorageCombo(self):
        # If there's only one dataset, show the path in the combo
        showpaths = False
        relPath = None
        if len( self._laneIndexes ) == 1:
            op = self.tempOps.values()[0]
            info = op.Dataset.value
            cwd = op.WorkingDirectory.value
            filePath = PathComponents(info.filePath).externalPath
            absPath, relPath = getPathVariants(filePath, cwd)
            
            # commented out: 
            # Show the paths even if the data is from a stack (they are grayed out, but potentially informative)
            #showpaths = not info.fromstack
            showpaths = True

        if showpaths:
            self.storageComboBox.addItem( "Copied to Project File", userData=StorageLocation.ProjectFile )
            self.storageComboBox.addItem( decode_to_qstring("Absolute Link: " + absPath), userData=StorageLocation.AbsoluteLink )
            if relPath is not None:
                self.storageComboBox.addItem( decode_to_qstring("Relative Link: " + relPath), userData=StorageLocation.RelativeLink )
        else:
            self.storageComboBox.addItem( "Copied to Project File", userData=StorageLocation.ProjectFile )
            self.storageComboBox.addItem( "Absolute Link", userData=StorageLocation.AbsoluteLink )
            self.storageComboBox.addItem( "Relative Link", userData=StorageLocation.RelativeLink )

        self.storageComboBox.setCurrentIndex(-1)
    def _chooseDirectory(self):
        # Find the directory of the most recently opened image file
        mostRecentStackDirectory = PreferencesManager().get(
            'DataSelection', 'recent stack directory')
        if mostRecentStackDirectory is not None:
            defaultDirectory = os.path.split(mostRecentStackDirectory)[0]
        else:
            defaultDirectory = os.path.expanduser('~')

        options = QFileDialog.Options(QFileDialog.ShowDirsOnly)
        if ilastik.config.cfg.getboolean("ilastik", "debug"):
            options |= QFileDialog.DontUseNativeDialog

        # Launch the "Open File" dialog
        directory = QFileDialog.getExistingDirectory(self,
                                                     "Image Stack Directory",
                                                     defaultDirectory,
                                                     options=options)

        if directory.isNull():
            # User cancelled
            return

        directory = encode_from_qstring(directory)
        PreferencesManager().set('DataSelection', 'recent stack directory',
                                 directory)

        self.directoryEdit.setText(decode_to_qstring(directory))
        globstring = self._getGlobString(directory)
        if globstring:
            filenames = OpStackLoader.expandGlobStrings(globstring)
            self._updateFileList(sorted(filenames))
            # As a convenience, also show the glob string in the pattern field
            self.patternEdit.setText(decode_to_qstring(globstring))
Exemple #4
0
 def handleMetadataChanged():
     if self.projectNameEdit.text() != self._projectMetadata.projectName:
         self.projectNameEdit.setText( decode_to_qstring(self._projectMetadata.projectName) )
     if self.labelerEdit.text() != self._projectMetadata.labeler:
         self.labelerEdit.setText( decode_to_qstring(self._projectMetadata.labeler) )
     if self.descriptionEdit.toPlainText() != self._projectMetadata.description:
         self.descriptionEdit.setText( decode_to_qstring(self._projectMetadata.description) )
Exemple #5
0
 def handleMetadataChanged():
     if self.projectNameEdit.text(
     ) != self._projectMetadata.projectName:
         self.projectNameEdit.setText(
             decode_to_qstring(self._projectMetadata.projectName,
                               'utf-8'))
     if self.labelerEdit.text() != self._projectMetadata.labeler:
         self.labelerEdit.setText(
             decode_to_qstring(self._projectMetadata.labeler, 'utf-8'))
     if self.descriptionEdit.toPlainText(
     ) != self._projectMetadata.description:
         self.descriptionEdit.setText(
             decode_to_qstring(self._projectMetadata.description,
                               'utf-8'))
Exemple #6
0
    def data(self, index, role):
        '''
        Reimplement, see labelListModel or boxListModel for concrete example
        :param index:
        :param role:
        '''

        if role == Qt.EditRole and index.column() == self.ColumnID.Name:
            name = self._elements[index.row()].name
            return decode_to_qstring(name, 'utf-8')

        elif role == Qt.ToolTipRole and index.column() == self.ColumnID.Delete:
            s = "Delete {}".format(self._elements[index.row()].name)
            return decode_to_qstring(s, 'utf-8')

        elif role == Qt.ToolTipRole and index.column() == self.ColumnID.Name:
            suffix = self._getToolTipSuffix(index.row())
            s = "{}\nDouble click to rename {}".format(
                self._elements[index.row()].name, suffix)
            return decode_to_qstring(s, 'utf-8')
        elif role == Qt.DisplayRole and index.column() == self.ColumnID.Name:
            name = self._elements[index.row()].name
            return decode_to_qstring(name, 'utf-8')

        if role == Qt.DecorationRole and index.column(
        ) == self.ColumnID.Delete:
            if index.row() in self.unremovable_rows: return

            row = index.row()
            pixmap = QPixmap(_NPIXELS, _NPIXELS)
            pixmap.fill(Qt.transparent)
            painter = QPainter()
            painter.begin(pixmap)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setBrush(QColor("red"))
            painter.drawEllipse(1, 1, _NPIXELS - 2, _NPIXELS - 2)
            pen = QPen(QColor("black"))
            pen.setWidth(2)
            painter.setPen(pen)

            x = _XSTART
            y = _NPIXELS - x
            painter.drawLine(x, x, y, y)
            painter.drawLine(y, x, x, y)

            painter.end()
            icon = QIcon(pixmap)
            return icon
    def _loadAnnotationFile(self, annotation_filepath):
        """
        Load the annotation file using the path stored in our member variable.
        """        
        try:
            # Configure operator
            self.opSplitBodyCarving.AnnotationFilepath.setValue( annotation_filepath )

            # Requesting annotations triggers parse.
            self._annotations = self.opSplitBodyCarving.Annotations.value
            self._ravelerLabels = self.opSplitBodyCarving.AnnotationBodyIds.value

            # Update gui
            self._reloadInfoWidgets()
            self.annotationFilepathEdit.setText( decode_to_qstring(annotation_filepath) )
            
        except OpParseAnnotations.AnnotationParsingException as ex :
            if ex.original_exc is not None:
                log_exception( logger, exc_info=( type(ex.original_exc), ex.original_exc, sys.exc_info[2]) )
            else:
                log_exception( logger )
            QMessageBox.critical(self,
                                 "Failed to parse",
                                 ex.msg + "\n\nSee console output for details." )
            
            self._annotations = None
            self._ravelerLabels = None
            self.annotationFilepathEdit.setText("")
        except:
            msg = "Wasn't able to parse your bookmark file.  See console output for details."
            QMessageBox.critical(self, "Failed to parse", msg )
            log_exception( logger, msg )
            self._annotations = None
            self._ravelerLabels = None
            self.annotationFilepathEdit.setText("")
Exemple #8
0
    def _getDisplayRoleData(self, index):
        laneIndex = index.row()
        ## Dataset info item
        roleIndex = (index.column() -
                     LaneColumn.NumColumns) // DatasetInfoColumn.NumColumns
        datasetInfoIndex = (index.column() - LaneColumn.NumColumns
                            ) % DatasetInfoColumn.NumColumns

        datasetSlot = self._op.DatasetGroup[laneIndex][roleIndex]
        if not datasetSlot.ready():
            return ""

        UninitializedDisplayData = {DatasetInfoColumn.Name: "<please select>"}

        datasetSlot = self._op.DatasetGroup[laneIndex][roleIndex]
        if datasetSlot.ready():
            datasetInfo = self._op.DatasetGroup[laneIndex][roleIndex].value
        else:
            return UninitializedDisplayData[datasetInfoIndex]

        if datasetInfoIndex == DatasetInfoColumn.Name:
            if datasetInfo.nickname is not None and datasetInfo.nickname != "":
                return datasetInfo.nickname
            return decode_to_qstring(
                PathComponents(datasetInfo.filePath).filename)

        if datasetInfoIndex == DatasetInfoColumn.Location:
            LocationNames = {
                DatasetInfo.Location.FileSystem: "External File",
                DatasetInfo.Location.ProjectInternal: "Project File"
            }
            return LocationNames[datasetInfo.location]

        assert False, "Unknown column"
    def _updatePathsFromSlot(self):
        if self._filepathSlot.ready():
            file_path = self._filepathSlot.value
            directory, filename_pattern = os.path.split( file_path )
            filename_pattern = os.path.splitext(filename_pattern)[0]

            # Auto-insert the {slice_index} field
            if re.search("{slice_index(:.*)?}", filename_pattern) is None:
                filename_pattern += '_{slice_index}'

            self.directoryEdit.setText( decode_to_qstring(directory) )
            self.filePatternEdit.setText( decode_to_qstring(filename_pattern + '.' + self._extension) )
            
            # Re-configure the slot in case we changed the extension
            file_path = os.path.join( directory, filename_pattern ) + '.' + self._extension            
            self._filepathSlot.setValue( file_path )
    def _updateFileList(self, files):
        self.selectedFiles = files

        self.fileListWidget.clear()

        for f in self.selectedFiles:
            self.fileListWidget.addItem(decode_to_qstring(f))
    def _chooseDirectory(self):
        # Find the directory of the most recently opened image file
        mostRecentStackDirectory = PreferencesManager().get(
            'DataSelection', 'recent stack directory')
        if mostRecentStackDirectory is not None:
            defaultDirectory = os.path.split(mostRecentStackDirectory)[0]
        else:
            defaultDirectory = os.path.expanduser('~')

        options = QFileDialog.Options(QFileDialog.ShowDirsOnly)
        if ilastik.config.cfg.getboolean("ilastik", "debug"):
            options |= QFileDialog.DontUseNativeDialog

        # Launch the "Open File" dialog
        directory = QFileDialog.getExistingDirectory(self,
                                                     "Image Stack Directory",
                                                     defaultDirectory,
                                                     options=options)

        if directory.isNull():
            # User cancelled
            return

        directory = encode_from_qstring(directory)
        PreferencesManager().set('DataSelection', 'recent stack directory',
                                 directory)

        self.directoryEdit.setText(decode_to_qstring(directory))
        try:
            globstring = self._getGlobString(directory)
        except StackFileSelectionWidget.DetermineStackError, e:
            QMessageBox.warning(self, "Invalid selection", str(e))
    def _updateFileList(self, files):
        self.selectedFiles = files

        self.fileListWidget.clear()

        for f in self.selectedFiles:
            self.fileListWidget.addItem(decode_to_qstring(f))
    def updateTableForSlot(self, slot):
        """
        Update the table row that corresponds to the given slot of the top-level operator (could be either input slot)
        """
        row = self.getSlotIndex( self.topLevelOperator.ExportPath, slot )
        assert row != -1, "Unknown input slot!"

        if not self.topLevelOperator.ExportPath[row].ready() or\
           not self.topLevelOperator.RawDatasetInfo[row].ready():
            return
        
        try:
            nickname = self.topLevelOperator.RawDatasetInfo[row].value.nickname
            exportPath = self.topLevelOperator.ExportPath[row].value
        except Slot.SlotNotReadyError:
            # Sadly, it is possible to get here even though we checked for .ready() immediately beforehand.
            # That's because the graph has a diamond-shaped DAG of connections, but the graph has no transaction mechanism
            # (It's therefore possible for RawDatasetInfo[row] to be ready() even though it's upstream partner is NOT ready.
            return
                
        self.batchOutputTableWidget.setItem( row, Column.Dataset, QTableWidgetItem( decode_to_qstring(nickname, 'utf-8') ) )
        self.batchOutputTableWidget.setItem( row, Column.ExportLocation, QTableWidgetItem( decode_to_qstring(exportPath) ) )

        exportNowButton = QPushButton("Export")
        exportNowButton.setToolTip("Generate individual batch output dataset.")
        exportNowButton.clicked.connect( bind(self.exportResultsForSlot, self.topLevelOperator[row] ) )
        self.batchOutputTableWidget.setCellWidget( row, Column.Action, exportNowButton )

        # Select a row if there isn't one already selected.
        selectedRanges = self.batchOutputTableWidget.selectedRanges()
        if len(selectedRanges) == 0:
            self.batchOutputTableWidget.selectRow(0)
    def setNameAndBrush(self, sigma, color=Qt.black):
        self.sigma = sigma
        self.setText(
            decode_to_qstring("σ=%.1fpx" % self.sigma, "utf-8")
        )  # This file is encoded as utf-8, so this string should be decoded as such.
        total_window = 1 + 2 * int(self.sigma * self.window_size + 0.5)
        self.setToolTip("sigma = {:.1f} pixels, window diameter = {:.1f}".format(self.sigma, total_window))
        font = QFont()
        font.setPointSize(10)
        font.setBold(True)
        self.setFont(font)
        self.setForeground(color)

        pixmap = QPixmap(self.pixmapSize)
        pixmap.fill(Qt.transparent)
        painter = QPainter()
        painter.begin(pixmap)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setPen(color)
        brush = QBrush(color)
        painter.setBrush(brush)
        painter.drawEllipse(
            QRect(
                self.pixmapSize.width() / 2 - self.brushSize / 2,
                self.pixmapSize.height() / 2 - self.brushSize / 2,
                self.brushSize,
                self.brushSize,
            )
        )
        painter.end()
        self.setIcon(QIcon(pixmap))
        self.setTextAlignment(Qt.AlignVCenter)
    def _getDisplayRoleData(self, index):
        laneIndex = index.row()
        ## Dataset info item
        roleIndex = (index.column() - LaneColumn.NumColumns) // DatasetInfoColumn.NumColumns
        datasetInfoIndex = (index.column() - LaneColumn.NumColumns) % DatasetInfoColumn.NumColumns
        
        datasetSlot = self._op.DatasetGroup[laneIndex][roleIndex]
        if not datasetSlot.ready():
            return ""

        UninitializedDisplayData = { DatasetInfoColumn.Name : "<please select>" }
        
        datasetSlot = self._op.DatasetGroup[laneIndex][roleIndex]
        if datasetSlot.ready():
            datasetInfo = self._op.DatasetGroup[laneIndex][roleIndex].value
        else:
            return UninitializedDisplayData[ datasetInfoIndex ]
        
        if datasetInfoIndex == DatasetInfoColumn.Name:
            if datasetInfo.nickname is not None and datasetInfo.nickname != "":
                return datasetInfo.nickname
            return decode_to_qstring( PathComponents( datasetInfo.filePath ).filename )

        if datasetInfoIndex == DatasetInfoColumn.Location:
            LocationNames = { DatasetInfo.Location.FileSystem : "External File",
                              DatasetInfo.Location.ProjectInternal : "Project File" }
            return LocationNames[ datasetInfo.location ]

        assert False, "Unknown column"
Exemple #16
0
    def data(self, index, role):
        '''
        Reimplement, see labelListModel or boxListModel for concrete example
        :param index:
        :param role:
        '''

        if role == Qt.EditRole and index.column() == self.ColumnID.Name:
            name = self._elements[index.row()].name
            return decode_to_qstring(name)

        elif role == Qt.ToolTipRole and index.column() == self.ColumnID.Delete:
            s = "Delete {}".format(self._elements[index.row()].name)
            return decode_to_qstring(s)

        elif role == Qt.ToolTipRole and index.column() == self.ColumnID.Name:
            suffix = self._getToolTipSuffix(index.row())
            s = "{}\nDouble click to rename {}".format(
                self._elements[index.row()].name, suffix)
            return decode_to_qstring(s)
        elif role == Qt.DisplayRole and index.column() == self.ColumnID.Name:
            name = self._elements[index.row()].name
            return decode_to_qstring(name)

        if role == Qt.DecorationRole and index.column() == self.ColumnID.Delete:
            if index.row() in self.unremovable_rows: return

            row = index.row()
            pixmap = QPixmap(_NPIXELS, _NPIXELS)
            pixmap.fill(Qt.transparent)
            painter = QPainter()
            painter.begin(pixmap)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setBrush(QColor("red"))
            painter.drawEllipse(1, 1, _NPIXELS - 2, _NPIXELS - 2)
            pen = QPen(QColor("black"))
            pen.setWidth(2)
            painter.setPen(pen)

            x = _XSTART
            y = _NPIXELS - x
            painter.drawLine(x, x, y, y)
            painter.drawLine(y, x, x, y)

            painter.end()
            icon = QIcon(pixmap)
            return icon
 def updateFromSlot(self):
     if self._filepathSlot.ready():
         file_path = self._filepathSlot.value
         file_path = os.path.splitext(file_path)[0] + "." + self._extension
         self.filepathEdit.setText( decode_to_qstring(file_path) )
         
         # Re-configure the slot in case we changed the extension
         self._filepathSlot.setValue( file_path )
Exemple #18
0
    def updateFromSlot(self):
        if self._filepathSlot.ready():
            file_path = self._filepathSlot.value
            file_path = os.path.splitext(file_path)[0]
            self.filepathEdit.setText(decode_to_qstring(file_path))

            # Re-configure the slot in case we changed the extension
            self._filepathSlot.setValue(file_path)
    def _updatePathsFromSlot(self):
        if self._filepathSlot.ready():
            file_path = self._filepathSlot.value
            directory, filename_pattern = os.path.split(file_path)
            filename_pattern = os.path.splitext(filename_pattern)[0]

            # Auto-insert the {slice_index} field
            if re.search("{slice_index(:.*)?}", filename_pattern) is None:
                filename_pattern += '_{slice_index}'

            self.directoryEdit.setText(decode_to_qstring(directory))
            self.filePatternEdit.setText(
                decode_to_qstring(filename_pattern + '.' + self._extension))

            # Re-configure the slot in case we changed the extension
            file_path = os.path.join(directory,
                                     filename_pattern) + '.' + self._extension
            self._filepathSlot.setValue(file_path)
Exemple #20
0
    def name( self, n ):
        if isinstance(n, str):
            n = decode_to_qstring(n, 'utf-8')
        assert isinstance(n, QString)
        pystr = encode_from_qstring(n, 'utf-8')

        if self._name != n:
            self._name = n
            self.nameChanged.emit(pystr)
Exemple #21
0
 def _updateNickname(self):
     firstOp = self.tempOps.values()[0]
     nickname = firstOp.Dataset.value.nickname
     for op in self.tempOps.values():
         info = op.Dataset.value
         if nickname != info.nickname:
             nickname = None
             break
     if nickname is None:
         self.nicknameEdit.setText("<multiple>")
     else:
         self.nicknameEdit.setText( decode_to_qstring(nickname, 'utf-8') )
Exemple #22
0
    def updateFromSlot(self):
        if self._urlSlot.ready():
            # FIXME: Choose a default dvid url...
            file_path = self._urlSlot.value
            if not isUrl(file_path):
                file_path = ""

            # Remove extension
            file_path = os.path.splitext(file_path)[0]
            self.urlLabel.setText(decode_to_qstring(file_path))

            # Re-configure the slot in case we removed the extension
            self._urlSlot.setValue(file_path)
    def updateFromSlot(self):
        if self._urlSlot.ready():
            # FIXME: Choose a default dvid url...            
            file_path = self._urlSlot.value
            if not isUrl( file_path ):
                file_path = ""

            # Remove extension
            file_path = os.path.splitext(file_path)[0]
            self.urlLabel.setText( decode_to_qstring(file_path) )
            
            # Re-configure the slot in case we removed the extension
            self._urlSlot.setValue( file_path )
Exemple #24
0
    def updateTableForSlot(self, slot):
        """
        Update the table row that corresponds to the given slot of the top-level operator (could be either input slot)
        """
        row = self.getSlotIndex(self.topLevelOperator.ExportPath, slot)
        assert row != -1, "Unknown input slot!"

        if not self.topLevelOperator.ExportPath[row].ready() or\
           not self.topLevelOperator.RawDatasetInfo[row].ready():
            return

        try:
            nickname = self.topLevelOperator.RawDatasetInfo[row].value.nickname
            exportPath = self.topLevelOperator.ExportPath[row].value
        except Slot.SlotNotReadyError:
            # Sadly, it is possible to get here even though we checked for .ready() immediately beforehand.
            # That's because the graph has a diamond-shaped DAG of connections, but the graph has no transaction mechanism
            # (It's therefore possible for RawDatasetInfo[row] to be ready() even though it's upstream partner is NOT ready.
            return

        self.batchOutputTableWidget.setItem(
            row, Column.Dataset,
            QTableWidgetItem(decode_to_qstring(nickname, 'utf-8')))
        self.batchOutputTableWidget.setItem(
            row, Column.ExportLocation,
            QTableWidgetItem(decode_to_qstring(exportPath)))

        exportNowButton = QPushButton("Export")
        exportNowButton.setToolTip("Generate individual batch output dataset.")
        exportNowButton.clicked.connect(
            bind(self.exportResultsForSlot, self.topLevelOperator[row]))
        self.batchOutputTableWidget.setCellWidget(row, Column.Action,
                                                  exportNowButton)

        # Select a row if there isn't one already selected.
        selectedRanges = self.batchOutputTableWidget.selectedRanges()
        if len(selectedRanges) == 0:
            self.batchOutputTableWidget.selectRow(0)
Exemple #25
0
    def _browseForFilepath(self):
        starting_dir = os.path.expanduser("~")
        if self._filepathSlot.ready():
            starting_dir = os.path.split(self._filepathSlot.value)[-1]

        dlg = QFileDialog(self, "Export Location", starting_dir,
                          self._file_filter)
        dlg.setAcceptMode(QFileDialog.AcceptSave)
        if not dlg.exec_():
            return

        exportPath = encode_from_qstring(dlg.selectedFiles()[0])
        self._filepathSlot.setValue(exportPath)
        self.filepathEdit.setText(decode_to_qstring(exportPath))
 def _browseForFilepath(self):
     starting_dir = os.path.expanduser("~")
     if self._filepathSlot.ready():
         starting_dir = os.path.split(self._filepathSlot.value)[-1]
     
     dlg = QFileDialog( self, "Export Location", starting_dir, self._file_filter )
     dlg.setDefaultSuffix(self._extension)
     dlg.setAcceptMode(QFileDialog.AcceptSave)
     if not dlg.exec_():
         return
     
     exportPath = encode_from_qstring( dlg.selectedFiles()[0] )
     self._filepathSlot.setValue( exportPath )
     self.filepathEdit.setText( decode_to_qstring(exportPath) )
    def _getDisplayRoleData(self, index):
        # Last row is just buttons
        if index.row() >= self.rowCount()-1:
            return ""

        laneIndex = index.row()
        
        if index.column() < LaneColumn.NumColumns:
            if index.column() == LaneColumn.LabelsAllowed:
                firstInfoSlot = self._op.DatasetGroup[laneIndex][0]
                if not firstInfoSlot.ready():
                    return ""
                info = firstInfoSlot.value
                return { True: "True", False : "False" }[ info.allowLabels ]
            else:
                assert False

        ## Dataset info item
        roleIndex = (index.column() - LaneColumn.NumColumns) // DatasetInfoColumn.NumColumns
        datasetInfoIndex = (index.column() - LaneColumn.NumColumns) % DatasetInfoColumn.NumColumns
        
        datasetSlot = self._op.DatasetGroup[laneIndex][roleIndex]
        if not datasetSlot.ready():
            return ""

        UninitializedDisplayData = { DatasetInfoColumn.Name : "<please select>" }
        
        datasetSlot = self._op.DatasetGroup[laneIndex][roleIndex]
        if datasetSlot.ready():
            datasetInfo = self._op.DatasetGroup[laneIndex][roleIndex].value
        else:
            return UninitializedDisplayData[ datasetInfoIndex ]
        
        if datasetInfoIndex == DatasetInfoColumn.Name:
            if datasetInfo.nickname is not None and datasetInfo.nickname != "":
                return datasetInfo.nickname
            return decode_to_qstring( PathComponents( datasetInfo.filePath ).filename )

        if datasetInfoIndex == DatasetInfoColumn.Location:
            LocationNames = { DatasetInfo.Location.FileSystem : "External File",
                              DatasetInfo.Location.ProjectInternal : "Project File" }
            return LocationNames[ datasetInfo.location ]

        assert False, "Unknown column"
    def updateFromSlots(self):
        was_valid = self.settings_are_valid
        if self._datasetNameSlot.ready():
            dataset_name = self._datasetNameSlot.value
            self.datasetEdit.setText(dataset_name)
            self.path_is_valid = (dataset_name != "")

        if self._filepathSlot.ready():
            file_path = self._filepathSlot.value
            file_path, ext = os.path.splitext(file_path)
            if ext != ".h5" and ext != ".hdf5":
                file_path += ".h5"
            else:
                file_path += ext
            self.filepathEdit.setText(decode_to_qstring(file_path))

            # Re-configure the file slot in case we changed the extension
            self._filepathSlot.setValue(file_path)

        if was_valid != self.path_is_valid:
            self.pathValidityChange.emit(self.settings_are_valid)
    def updateFromSlots(self):
        was_valid = self.settings_are_valid
        if self._datasetNameSlot.ready():
            dataset_name = self._datasetNameSlot.value
            self.datasetEdit.setText( dataset_name )
            self.path_is_valid = ( dataset_name != "" )

        if self._filepathSlot.ready():
            file_path = self._filepathSlot.value
            file_path, ext = os.path.splitext(file_path)
            if ext != ".h5" and ext != ".hdf5":
                file_path += ".h5"
            else:
                file_path += ext
            self.filepathEdit.setText( decode_to_qstring(file_path) )
            
            # Re-configure the file slot in case we changed the extension
            self._filepathSlot.setValue( file_path )

        if was_valid != self.path_is_valid:
            self.pathValidityChange.emit( self.settings_are_valid )
Exemple #30
0
    def _loadAnnotationFile(self, annotation_filepath):
        """
        Load the annotation file using the path stored in our member variable.
        """
        try:
            # Configure operator
            self.opSplitBodyCarving.AnnotationFilepath.setValue(
                annotation_filepath)

            # Requesting annotations triggers parse.
            self._annotations = self.opSplitBodyCarving.Annotations.value
            self._ravelerLabels = self.opSplitBodyCarving.AnnotationBodyIds.value

            # Update gui
            self._reloadInfoWidgets()
            self.annotationFilepathEdit.setText(
                decode_to_qstring(annotation_filepath))

        except OpParseAnnotations.AnnotationParsingException as ex:
            if ex.original_exc is not None:
                log_exception(logger,
                              exc_info=(type(ex.original_exc), ex.original_exc,
                                        sys.exc_info[2]))
            else:
                log_exception(logger)
            QMessageBox.critical(
                self, "Failed to parse",
                ex.msg + "\n\nSee console output for details.")

            self._annotations = None
            self._ravelerLabels = None
            self.annotationFilepathEdit.setText("")
        except:
            msg = "Wasn't able to parse your bookmark file.  See console output for details."
            QMessageBox.critical(self, "Failed to parse", msg)
            log_exception(logger, msg)
            self._annotations = None
            self._ravelerLabels = None
            self.annotationFilepathEdit.setText("")
 def setNameAndBrush(self, sigma, color=Qt.black):
     self.sigma = sigma
     self.setText(decode_to_qstring("σ=%.1fpx" % self.sigma, 'utf-8')) # This file is encoded as utf-8, so this string should be decoded as such.
     total_window = (1 + 2 * int(self.sigma * self.window_size + 0.5) )
     self.setToolTip( "sigma = {:.1f} pixels, window diameter = {:.1f}".format(self.sigma, total_window) )
     font = QFont() 
     font.setPointSize(10)
     font.setBold(True)
     self.setFont(font)
     self.setForeground(color)
                     
     pixmap = QPixmap(self.pixmapSize)
     pixmap.fill(Qt.transparent)
     painter = QPainter()
     painter.begin(pixmap)
     painter.setRenderHint(QPainter.Antialiasing, True)
     painter.setPen(color)
     brush = QBrush(color)
     painter.setBrush(brush)
     painter.drawEllipse(QRect(self.pixmapSize.width()/2 - self.brushSize/2, self.pixmapSize.height()/2 - self.brushSize/2, self.brushSize, self.brushSize))
     painter.end()
     self.setIcon(QIcon(pixmap))
     self.setTextAlignment(Qt.AlignVCenter)
Exemple #32
0
    def _getDisplayRoleData(self, index):
        laneIndex = index.row()

        UninitializedDisplayData = {
            DatasetDetailedInfoColumn.Nickname: "<empty>",
            DatasetDetailedInfoColumn.Location: "",
            DatasetDetailedInfoColumn.InternalID: "",
            DatasetDetailedInfoColumn.AxisOrder: "",
            DatasetDetailedInfoColumn.Shape: "",
            DatasetDetailedInfoColumn.Range: ""
        }

        if len( self._op.DatasetGroup ) <= laneIndex \
        or len( self._op.DatasetGroup[laneIndex] ) <= self._roleIndex:
            return UninitializedDisplayData[index.column()]

        datasetSlot = self._op.DatasetGroup[laneIndex][self._roleIndex]

        # Default
        if not datasetSlot.ready():
            return UninitializedDisplayData[index.column()]

        datasetInfo = self._op.DatasetGroup[laneIndex][self._roleIndex].value
        filePathComponents = PathComponents(datasetInfo.filePath)

        ## Input meta-data fields

        # Name
        if index.column() == DatasetDetailedInfoColumn.Nickname:
            return decode_to_qstring(datasetInfo.nickname, 'utf-8')

        # Location
        if index.column() == DatasetDetailedInfoColumn.Location:
            if datasetInfo.location == DatasetInfo.Location.FileSystem:
                if isUrl(datasetInfo.filePath) or os.path.isabs(
                        datasetInfo.filePath):
                    text = "Absolute Link: {}".format(
                        filePathComponents.externalPath)
                    return decode_to_qstring(text)
                else:
                    text = "Relative Link: {}".format(
                        filePathComponents.externalPath)
                    return decode_to_qstring(text)
            else:
                return "Project File"

        # Internal ID
        if index.column() == DatasetDetailedInfoColumn.InternalID:
            if datasetInfo.location == DatasetInfo.Location.FileSystem:
                return filePathComponents.internalPath
            return ""

        ## Output meta-data fields

        # Defaults
        imageSlot = self._op.ImageGroup[laneIndex][self._roleIndex]
        if not imageSlot.ready():
            return UninitializedDisplayData[index.column()]

        # Axis order
        if index.column() == DatasetDetailedInfoColumn.AxisOrder:
            original_axistags = imageSlot.meta.original_axistags
            axistags = imageSlot.meta.axistags
            if original_axistags is not None:
                return "".join(tag.key for tag in original_axistags)
            if axistags is not None:
                return "".join(imageSlot.meta.getAxisKeys())
            return ""

        # Shape
        if index.column() == DatasetDetailedInfoColumn.Shape:
            original_shape = imageSlot.meta.original_shape
            shape = imageSlot.meta.shape
            if original_shape is not None:
                return str(original_shape)
            if shape is None:
                return ""
            return str(shape)

        # Range
        if index.column() == DatasetDetailedInfoColumn.Range:
            drange = imageSlot.meta.drange
            if drange is None:
                return ""
            return str(drange)

        assert False, "Unknown column: row={}, column={}".format(
            index.row(), index.column())
    def _getDisplayRoleData(self, index):
        laneIndex = index.row()

        UninitializedDisplayData = { DatasetDetailedInfoColumn.Nickname : "<empty>",
                                     DatasetDetailedInfoColumn.Location : "",
                                     DatasetDetailedInfoColumn.InternalID : "",
                                     DatasetDetailedInfoColumn.AxisOrder : "",
                                     DatasetDetailedInfoColumn.Shape : "",
                                     DatasetDetailedInfoColumn.Range : "" }

        if len( self._op.DatasetGroup ) <= laneIndex \
        or len( self._op.DatasetGroup[laneIndex] ) <= self._roleIndex:
            return UninitializedDisplayData[ index.column() ]

        datasetSlot = self._op.DatasetGroup[laneIndex][self._roleIndex]

        # Default
        if not datasetSlot.ready():
            return UninitializedDisplayData[ index.column() ]
        
        datasetInfo = self._op.DatasetGroup[laneIndex][self._roleIndex].value
        filePathComponents = PathComponents( datasetInfo.filePath )

        ## Input meta-data fields

        # Name
        if index.column() == DatasetDetailedInfoColumn.Nickname:
            return decode_to_qstring( datasetInfo.nickname )

        # Location
        if index.column() == DatasetDetailedInfoColumn.Location:
            if datasetInfo.location == DatasetInfo.Location.FileSystem:
                if isUrl(datasetInfo.filePath) or os.path.isabs(datasetInfo.filePath):
                    text = "Absolute Link: {}".format( filePathComponents.externalPath )
                    return decode_to_qstring(text)
                else:
                    text = "Relative Link: {}".format( filePathComponents.externalPath )
                    return decode_to_qstring(text)
            else:
                return "Project File"

        # Internal ID        
        if index.column() == DatasetDetailedInfoColumn.InternalID:
            if datasetInfo.location == DatasetInfo.Location.FileSystem:
                return filePathComponents.internalPath
            return ""

        ## Output meta-data fields
        
        # Defaults        
        imageSlot = self._op.ImageGroup[laneIndex][self._roleIndex]
        if not imageSlot.ready():
            return UninitializedDisplayData[index.column()]

        # Axis order            
        if index.column() == DatasetDetailedInfoColumn.AxisOrder:
            original_axistags = imageSlot.meta.original_axistags
            axistags = imageSlot.meta.axistags
            if original_axistags is not None:
                return "".join( tag.key for tag in original_axistags )            
            if axistags is not None:
                return "".join( imageSlot.meta.getAxisKeys() )
            return ""

        # Shape
        if index.column() == DatasetDetailedInfoColumn.Shape:
            original_shape = imageSlot.meta.original_shape
            shape = imageSlot.meta.shape
            if original_shape is not None:
                return str(original_shape)
            if shape is None:
                return ""
            return str(shape)

        # Range
        if index.column() == DatasetDetailedInfoColumn.Range:
            drange = imageSlot.meta.drange
            if drange is None:
                return ""
            return str(drange)

        assert False, "Unknown column: row={}, column={}".format( index.row(), index.column() )
class StackFileSelectionWidget(QDialog):
    class DetermineStackError(Exception):
        """Class related to errors in determining the stack of files"""
        def __init__(self, message):
            super(StackFileSelectionWidget.DetermineStackError,
                  self).__init__(message)

    def __init__(self, parent, files=None):
        super(StackFileSelectionWidget, self).__init__(parent)

        self._initUi()

        if files is None:
            files = []
        self._updateFileList(files)

    def _initUi(self):
        # Load the ui file into this class (find it in our own directory)
        localDir = os.path.split(__file__)[0]
        uiFilePath = os.path.join(localDir, 'stackFileSelectionWidget.ui')
        uic.loadUi(uiFilePath, self)

        self.okButton.clicked.connect(self.accept)
        self.cancelButton.clicked.connect(self.reject)

        self.selectFilesRadioButton.clicked.connect(
            partial(self._configureGui, 'files'))
        self.directoryRadioButton.clicked.connect(
            partial(self._configureGui, 'directory'))
        self.patternRadioButton.clicked.connect(
            partial(self._configureGui, 'pattern'))

        self.selectFilesChooseButton.clicked.connect(self._selectFiles)
        self.directoryChooseButton.clicked.connect(self._chooseDirectory)
        self.patternApplyButton.clicked.connect(self._applyPattern)
        self.patternEdit.installEventFilter(self)

        # Default to "select files" option, since it's most generic
        self.selectFilesRadioButton.setChecked(True)
        self._configureGui("files")

        self.stackAcrossTButton.setChecked(True)

    def accept(self):
        self.patternEdit.removeEventFilter(self)
        super(StackFileSelectionWidget, self).accept()

    def reject(self):
        self.patternEdit.removeEventFilter(self)
        super(StackFileSelectionWidget, self).reject()

    @property
    def sequence_axis(self):
        if self.stackAcrossTButton.isChecked():
            return 't'
        return 'z'

    def _configureGui(self, mode):
        """
        Configure the gui to select files via one of our three selection modes.
        """
        self.directoryChooseButton.setEnabled(mode == 'directory')
        self.directoryEdit.setEnabled(mode == 'directory')
        self.directoryEdit.clear()

        self.selectFilesChooseButton.setEnabled(mode == 'files')

        self.patternApplyButton.setEnabled(mode == 'pattern')
        self.patternEdit.setEnabled(mode == 'pattern')
        if mode != 'pattern':
            self.patternEdit.clear()

    def _chooseDirectory(self):
        # Find the directory of the most recently opened image file
        mostRecentStackDirectory = PreferencesManager().get(
            'DataSelection', 'recent stack directory')
        if mostRecentStackDirectory is not None:
            defaultDirectory = os.path.split(mostRecentStackDirectory)[0]
        else:
            defaultDirectory = os.path.expanduser('~')

        options = QFileDialog.Options(QFileDialog.ShowDirsOnly)
        if ilastik.config.cfg.getboolean("ilastik", "debug"):
            options |= QFileDialog.DontUseNativeDialog

        # Launch the "Open File" dialog
        directory = QFileDialog.getExistingDirectory(self,
                                                     "Image Stack Directory",
                                                     defaultDirectory,
                                                     options=options)

        if directory.isNull():
            # User cancelled
            return

        directory = encode_from_qstring(directory)
        PreferencesManager().set('DataSelection', 'recent stack directory',
                                 directory)

        self.directoryEdit.setText(decode_to_qstring(directory))
        try:
            globstring = self._getGlobString(directory)
        except StackFileSelectionWidget.DetermineStackError, e:
            QMessageBox.warning(self, "Invalid selection", str(e))
        if globstring:
            self.patternEdit.setText(decode_to_qstring(globstring))
            self._applyPattern()