Ejemplo n.º 1
0
Archivo: UI.py Proyecto: wkoder/mooi
class MainWindow(QMainWindow):

    __PREF_GEOM__ = "UI/Geometry"
    __PREF_STATE__ = "UI/State"
    __PREF_DIR__ = "Config/Directories"
    __PREF_SAVE__ = "Config/SaveDirectory"
    __PREF_SAVE_ALL__ = "Config/SaveAllDirectory"

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

        self.analyzer = Analyzer()
        self.currentSolution = None

        self._buildUI()
        self._loadSettings()
        QTimer.singleShot(0, self._loadInitialData)

    def _buildUI(self):
        self.setWindowTitle("MOOI: Multi-Objective Optimization Interface")
        self.resize(840, 480)
        self.statusBar().setSizeGripEnabled(False)
        self.statusBar().showMessage("Loading initial data...")

        # Plot widget
        self.plot = PlotWidget()
        self.plot.setMinimumSize(320, 480)
        self.plot.setAlignment(Qt.AlignCenter)
        self.plot.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.plot)

        # Function widget
        self.functionWidget = QListWidget()
        self.functionWidget.itemSelectionChanged.connect(self.solutionSelected)
        rightDock = QDockWidget("Functions", self)
        rightDock.setObjectName("Functions")
        rightDock.setWidget(self.functionWidget)
        rightDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.RightDockWidgetArea, rightDock)

        # Control widget
        self.showSolutionsRadio = QRadioButton("Functions")
        self.showSolutionsRadio.setChecked(True)
        self.showSolutionsRadio.toggled.connect(self._showSolution)
        self.showVariablesRadio = QRadioButton("Variables")

        radioWidget = QWidget()
        radioLayout = QHBoxLayout()
        radioLayout.addWidget(self.showSolutionsRadio)
        radioLayout.addWidget(self.showVariablesRadio)
        radioWidget.setLayout(radioLayout)

        self.generationLabel = QLabel("Run: 1")
        self.generationSlider = QSlider(Qt.Horizontal)
        self.generationSlider.setTickPosition(QSlider.TicksBothSides)
        self.generationSlider.setTracking(True)
        self.generationSlider.setMinimum(1)
        self.generationSlider.setMaximum(1)
        self.generationSlider.setTickInterval(1)
        self.generationSlider.valueChanged.connect(self._showSolution)

        self.solutionSelector = QWidget()
        self.solutionSelector.setLayout(QVBoxLayout())
        addSolutionButton = QPushButton("Add")
        addSolutionButton.clicked.connect(self.addImplementation)
        removeSolutionButton = QPushButton("Remove unselected")
        removeSolutionButton.clicked.connect(self.removeResult)
        solutionSelectorButtons = QWidget()
        solutionSelectorButtons.setLayout(QHBoxLayout())
        solutionSelectorButtons.layout().addWidget(addSolutionButton)
        solutionSelectorButtons.layout().addWidget(removeSolutionButton)
        self.solutionSelectorWidget = QWidget()
        self.solutionSelectorWidget.setLayout(QVBoxLayout())
        self.solutionSelectorWidget.layout().addWidget(solutionSelectorButtons)
        self.solutionSelectorWidget.layout().addWidget(self.solutionSelector)

        exportButton = QPushButton("Export image")
        exportButton.clicked.connect(self.exportImage)

        exportAllButton = QPushButton("Export all images")
        exportAllButton.clicked.connect(self.exportAllImages)

        computeMetricsButton = QPushButton("Compute metrics")
        computeMetricsButton.clicked.connect(self.computeMetricsAsync)

        refreshButton = QPushButton("Refresh")
        refreshButton.clicked.connect(self.updateUI)

        controlLayout = QVBoxLayout()
        controlLayout.addWidget(radioWidget)
        controlLayout.addWidget(self.generationLabel)
        controlLayout.addWidget(self.generationSlider)
        controlLayout.addWidget(self.solutionSelectorWidget)
        controlLayout.addStretch()
        controlLayout.addWidget(computeMetricsButton)
        controlLayout.addWidget(refreshButton)
        controlLayout.addWidget(exportButton)
        controlLayout.addWidget(exportAllButton)
        controlWidget = QWidget()
        controlWidget.setLayout(controlLayout)
        leftDock = QDockWidget("Control", self)
        leftDock.setObjectName("Control")
        leftDock.setWidget(controlWidget)
        leftDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.LeftDockWidgetArea, leftDock)

        # Metric widget
        self.metrics = MetricsPanel(self.analyzer)
        bottomDock = QDockWidget("Metrics", self)
        bottomDock.setObjectName("Metrics")
        bottomDock.setWidget(self.metrics)
        bottomDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.BottomDockWidgetArea, bottomDock)

        # Actions
        exitAction = QAction("&Exit", self)
        exitAction.setShortcut("Ctrl+Q")
        exitAction.setStatusTip("Exit application")
        exitAction.triggered.connect(qApp.quit)

        copyAction = QAction("&Copy", self)
        copyAction.setShortcut("Ctrl+C")
        copyAction.setStatusTip("Copy metrics")
        copyAction.triggered.connect(self.metrics.copyMetrics)

        aboutAction = QAction("&About", self)
        aboutAction.setStatusTip("About MOOI")
        aboutAction.triggered.connect(self.helpAbout)

        # Menus
        menubar = self.menuBar()
        fileMenu = menubar.addMenu("&File")
        fileMenu.addAction(copyAction)
        fileMenu.addAction(aboutAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)

    def _loadSettings(self):
        settings = QSettings()
        self.restoreState(settings.value(MainWindow.__PREF_STATE__).toByteArray())
        self.restoreGeometry(settings.value(MainWindow.__PREF_GEOM__).toByteArray())

        paretoDirectory = __RESOURCES_DIR__ + Analyzer.__PARETO__
        self.analyzer.setPareto(paretoDirectory)
        currentDirs = settings.value(MainWindow.__PREF_DIR__)
        if currentDirs is not None:
            self.analyzer.setResultDirectories([directory.toString() for directory in currentDirs.toList()])

        self._updateSolutionSelection()

    def exportImage(self):
        settings = QSettings()
        filename = settings.value(MainWindow.__PREF_SAVE__)
        if filename is None:
            filename = os.path.dirname(__file__)
        else:
            filename = os.path.abspath(os.path.join(str(filename.toString()), os.path.pardir)) + "/"
        filename += "%s_%s.png" % (
            self.currentSolution.functionName,
            "fun" if self.isFunctionSpaceSelected() else "var",
        )

        filename = QFileDialog.getSaveFileName(self, "Export image as", filename, ("PNG image (*.png)"))
        if filename is None or filename == "":
            return

        settings.setValue(MainWindow.__PREF_SAVE__, QVariant(filename))
        self._exportCurrentImage(filename)
        self.statusBar().showMessage("Image saved!", 5000)

    def isFunctionSpaceSelected(self):
        return self.showSolutionsRadio.isChecked()

    def _exportCurrentImage(self, filename=None):
        generation = self.generationSlider.value()
        self.generationLabel.setText("Run: %d" % generation)

        tmp = filename is None
        if tmp:
            prefix = "mooi_%s_" % self.currentSolution.functionName
            filename = tempfile.mkstemp(prefix=prefix, suffix=".png", text=False)[1]
        resultNames = self._getSelectedResultNames()
        self.analyzer.exportToImage(
            self.currentSolution,
            [generation - 1] * len(resultNames),
            self.isFunctionSpaceSelected(),
            resultNames,
            str(filename),
        )
        if tmp:
            self.plot.setPlotPixmap(filename)
            try:
                os.remove(filename)
            except:
                print >>sys.stderr, "Couldn't delete temporal file: %s" % filename

    def _getSelectedResultNames(self):
        resultNames = []
        for i in xrange(self.analyzer.nResults):
            implementationItem = self.solutionSelector.layout().itemAt(i).widget()
            if implementationItem.isChecked():
                resultNames.append(str(implementationItem.text()))
        return resultNames

    def exportAllImages(self):
        settings = QSettings()
        directory = settings.value(MainWindow.__PREF_SAVE_ALL__).toString()
        directory = QFileDialog.getExistingDirectory(self, "Select a directory to export to", directory)
        if directory is None or not os.path.exists(directory):
            return

        self.analyzer.exportAllImages(directory, self._getSelectedResultNames())
        settings.setValue(MainWindow.__PREF_SAVEL_ALL__, QVariant(directory))
        self.statusBar().showMessage("Images saved!", 5000)

    def computeMetricsAsync(self):
        self.statusBar().showMessage("Computing metrics...")
        QTimer.singleShot(0, self.computeMetrics)

    def computeMetrics(self):
        self._computeMetrics(self.currentSolution.functionName)
        self.statusBar().showMessage("Metrics computed!", 5000)

    def _computeMetrics(self, functionName):
        pareto = self.analyzer.getFunctionPareto(functionName)
        solutions = self.analyzer.getFunctionResults(functionName, self._getSelectedResultNames())
        self.metrics.updateMetrics(pareto, solutions, functionName)

    def helpAbout(self):
        QMessageBox.about(
            self,
            "About Image Changer",
            """<b>Multi-Objective Optimization Interface</b> v%s
            <p>Copyright &copy; 2011-2012 %s All rights reserved.
            <p>This application can be used to perform simple optimization analysis.
            <p><a href='%s'>%s</a>
            <p>Python %s - Qt %s - PyQt %s on %s"""
            % (
                __VERSION__,
                __AUTHOR__,
                __WEBSITE__,
                __WEBSITE__,
                platform.python_version(),
                QT_VERSION_STR,
                PYQT_VERSION_STR,
                platform.system(),
            ),
        )

    def addImplementation(self):
        if self.analyzer.nResults == 0:
            directory = ""
        else:
            directory = os.path.abspath(os.path.join(str(self.analyzer.resultDirectories[-1]), os.path.pardir))
        directory = QFileDialog.getExistingDirectory(
            self, "Select a directory to scan", directory, QFileDialog.ShowDirsOnly
        )
        if not os.path.exists(directory) or directory in self.analyzer.resultDirectories:
            return

        self.analyzer.addResultDirectory(directory)
        self.addSolutionForSelection(self.analyzer.getResultName(directory))

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__, QVariant(self.analyzer.resultDirectories))

    def removeResult(self):
        layout = self.solutionSelector.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            item = layout.itemAt(i)
            if not item.widget().isChecked():  # and self.analyzer.resultNames[i] != Analyzer.__PARETO__:
                item.widget().setVisible(False)
                layout.removeItem(item)
                self.analyzer.removeResultDirectory(self.analyzer.resultDirectories[i])
        layout.update()

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__, QVariant(self.analyzer.resultDirectories))

    def solutionSelected(self):
        selection = self.functionWidget.currentItem()
        if selection is None:
            return
        self.showSolution(str(selection.text()))

    def showSolution(self, functionName):
        self.currentSolution = self.analyzer.getResultsForFunction(functionName)
        self.metrics.clear()
        self._showSolution()

    def addSolutionForSelection(self, name):
        solution = QCheckBox(name)
        solution.setChecked(True)
        solution.stateChanged.connect(self._showSolution)
        self.solutionSelector.layout().addWidget(solution)
        self.solutionSelector.layout().update()

    def _updateSolutionSelection(self):
        self.clearWidget(self.solutionSelector)

        for directory in self.analyzer.resultDirectories:
            self.addSolutionForSelection(self.analyzer.getResultName(directory))

    def _showSolution(self):
        sol = self.currentSolution
        if sol is None:
            return

        if len(sol.variableImplementation) == 0 and self.showVariablesRadio.isEnabled():
            self.showVariablesRadio.setEnabled(False)
            if self.showVariablesRadio.isChecked():
                self.showSolutionsRadio.setChecked(True)
        else:
            self.showVariablesRadio.setEnabled(True)

        if len(sol.functionImplementation) == 0 and self.showSolutionsRadio.isEnabled():
            self.showSolutionsRadio.setEnabled(False)
            if self.showSolutionsRadio.isChecked():
                self.showVariablesRadio.setChecked(True)
        else:
            self.showSolutionsRadio.setEnabled(True)

        if self.showSolutionsRadio.isChecked():
            self.generationSlider.setMaximum(
                max([sol.getFunctionSolution(impl).count() for impl in sol.functionImplementation])
            )
        else:
            self.generationSlider.setMaximum(
                max([sol.getVariableSolution(impl).count() for impl in sol.variableImplementation])
            )
        self._exportCurrentImage()

    def clearWidget(self, widget):
        layout = widget.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            layout.removeItem(layout.itemAt(i))

    def updateUI(self):
        self.statusBar().showMessage("Updating solutions...")

        selectedRow = self.functionWidget.currentRow()
        self.functionWidget.clear()
        names = [] + self.analyzer.getFunctionNames()
        names.sort()
        for name in names:
            item = QListWidgetItem()
            item.setText(name)
            self.functionWidget.addItem(item)

        if self.functionWidget.count() > 0:
            self.functionWidget.setCurrentRow(
                selectedRow if selectedRow >= 0 and selectedRow < self.functionWidget.count() else 0
            )
        self.statusBar().showMessage("Updated!", 5000)

    def _loadInitialData(self):
        self.updateUI()
        self.statusBar().showMessage("Ready!", 5000)

    def closeEvent(self, event):
        self.statusBar().showMessage("Closing...")
        settings = QSettings()
        settings.setValue(MainWindow.__PREF_GEOM__, self.saveGeometry())
        settings.setValue(MainWindow.__PREF_STATE__, self.saveState())
        self.plot.clear()
Ejemplo n.º 2
0
class MainWindow(QMainWindow):

    __PREF_GEOM__ = "UI/Geometry"
    __PREF_STATE__ = "UI/State"
    __PREF_DIR__ = "Config/Directories"
    __PREF_SAVE__ = "Config/SaveDirectory"
    __PREF_SAVE_ALL__ = "Config/SaveAllDirectory"

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

        self.analyzer = Analyzer()
        self.currentSolution = None

        self._buildUI()
        self._loadSettings()
        QTimer.singleShot(0, self._loadInitialData)

    def _buildUI(self):
        self.setWindowTitle("MOOI: Multi-Objective Optimization Interface")
        self.resize(840, 480)
        self.statusBar().setSizeGripEnabled(False)
        self.statusBar().showMessage("Loading initial data...")

        # Plot widget
        self.plot = PlotWidget()
        self.plot.setMinimumSize(320, 480)
        self.plot.setAlignment(Qt.AlignCenter)
        self.plot.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.plot)

        # Function widget
        self.functionWidget = QListWidget()
        self.functionWidget.itemSelectionChanged.connect(self.solutionSelected)
        rightDock = QDockWidget("Functions", self)
        rightDock.setObjectName("Functions")
        rightDock.setWidget(self.functionWidget)
        rightDock.setFeatures(QDockWidget.DockWidgetFloatable
                              | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.RightDockWidgetArea, rightDock)

        # Control widget
        self.showSolutionsRadio = QRadioButton("Functions")
        self.showSolutionsRadio.setChecked(True)
        self.showSolutionsRadio.toggled.connect(self._showSolution)
        self.showVariablesRadio = QRadioButton("Variables")

        radioWidget = QWidget()
        radioLayout = QHBoxLayout()
        radioLayout.addWidget(self.showSolutionsRadio)
        radioLayout.addWidget(self.showVariablesRadio)
        radioWidget.setLayout(radioLayout)

        self.generationLabel = QLabel("Run: 1")
        self.generationSlider = QSlider(Qt.Horizontal)
        self.generationSlider.setTickPosition(QSlider.TicksBothSides)
        self.generationSlider.setTracking(True)
        self.generationSlider.setMinimum(1)
        self.generationSlider.setMaximum(1)
        self.generationSlider.setTickInterval(1)
        self.generationSlider.valueChanged.connect(self._showSolution)

        self.solutionSelector = QWidget()
        self.solutionSelector.setLayout(QVBoxLayout())
        addSolutionButton = QPushButton("Add")
        addSolutionButton.clicked.connect(self.addImplementation)
        removeSolutionButton = QPushButton("Remove unselected")
        removeSolutionButton.clicked.connect(self.removeResult)
        solutionSelectorButtons = QWidget()
        solutionSelectorButtons.setLayout(QHBoxLayout())
        solutionSelectorButtons.layout().addWidget(addSolutionButton)
        solutionSelectorButtons.layout().addWidget(removeSolutionButton)
        self.solutionSelectorWidget = QWidget()
        self.solutionSelectorWidget.setLayout(QVBoxLayout())
        self.solutionSelectorWidget.layout().addWidget(solutionSelectorButtons)
        self.solutionSelectorWidget.layout().addWidget(self.solutionSelector)

        exportButton = QPushButton("Export image")
        exportButton.clicked.connect(self.exportImage)

        exportAllButton = QPushButton("Export all images")
        exportAllButton.clicked.connect(self.exportAllImages)

        computeMetricsButton = QPushButton("Compute metrics")
        computeMetricsButton.clicked.connect(self.computeMetricsAsync)

        refreshButton = QPushButton("Refresh")
        refreshButton.clicked.connect(self.updateUI)

        controlLayout = QVBoxLayout()
        controlLayout.addWidget(radioWidget)
        controlLayout.addWidget(self.generationLabel)
        controlLayout.addWidget(self.generationSlider)
        controlLayout.addWidget(self.solutionSelectorWidget)
        controlLayout.addStretch()
        controlLayout.addWidget(computeMetricsButton)
        controlLayout.addWidget(refreshButton)
        controlLayout.addWidget(exportButton)
        controlLayout.addWidget(exportAllButton)
        controlWidget = QWidget()
        controlWidget.setLayout(controlLayout)
        leftDock = QDockWidget("Control", self)
        leftDock.setObjectName("Control")
        leftDock.setWidget(controlWidget)
        leftDock.setFeatures(QDockWidget.DockWidgetFloatable
                             | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.LeftDockWidgetArea, leftDock)

        # Metric widget
        self.metrics = MetricsPanel(self.analyzer)
        bottomDock = QDockWidget("Metrics", self)
        bottomDock.setObjectName("Metrics")
        bottomDock.setWidget(self.metrics)
        bottomDock.setFeatures(QDockWidget.DockWidgetFloatable
                               | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.BottomDockWidgetArea, bottomDock)

        # Actions
        exitAction = QAction('&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(qApp.quit)

        copyAction = QAction("&Copy", self)
        copyAction.setShortcut("Ctrl+C")
        copyAction.setStatusTip('Copy metrics')
        copyAction.triggered.connect(self.metrics.copyMetrics)

        aboutAction = QAction("&About", self)
        aboutAction.setStatusTip('About MOOI')
        aboutAction.triggered.connect(self.helpAbout)

        # Menus
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(copyAction)
        fileMenu.addAction(aboutAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)

    def _loadSettings(self):
        settings = QSettings()
        self.restoreState(
            settings.value(MainWindow.__PREF_STATE__).toByteArray())
        self.restoreGeometry(
            settings.value(MainWindow.__PREF_GEOM__).toByteArray())

        paretoDirectory = __RESOURCES_DIR__ + Analyzer.__PARETO__
        self.analyzer.setPareto(paretoDirectory)
        currentDirs = settings.value(MainWindow.__PREF_DIR__)
        if currentDirs is not None:
            self.analyzer.setResultDirectories(
                [directory.toString() for directory in currentDirs.toList()])

        self._updateSolutionSelection()

    def exportImage(self):
        settings = QSettings()
        filename = settings.value(MainWindow.__PREF_SAVE__)
        if filename is None:
            filename = os.path.dirname(__file__)
        else:
            filename = os.path.abspath(
                os.path.join(str(filename.toString()), os.path.pardir)) + "/"
        filename += "%s_%s.png" % (self.currentSolution.functionName, "fun" if
                                   self.isFunctionSpaceSelected() else "var")

        filename = QFileDialog.getSaveFileName(self, "Export image as",
                                               filename, ("PNG image (*.png)"))
        if filename is None or filename == "":
            return

        settings.setValue(MainWindow.__PREF_SAVE__, QVariant(filename))
        self._exportCurrentImage(filename)
        self.statusBar().showMessage("Image saved!", 5000)

    def isFunctionSpaceSelected(self):
        return self.showSolutionsRadio.isChecked()

    def _exportCurrentImage(self, filename=None):
        generation = self.generationSlider.value()
        self.generationLabel.setText("Run: %d" % generation)

        tmp = filename is None
        if tmp:
            prefix = "mooi_%s_" % self.currentSolution.functionName
            filename = tempfile.mkstemp(prefix=prefix,
                                        suffix=".png",
                                        text=False)[1]
        resultNames = self._getSelectedResultNames()
        self.analyzer.exportToImage(self.currentSolution, [generation-1]*len(resultNames), self.isFunctionSpaceSelected(), \
                                    resultNames, str(filename))
        if tmp:
            self.plot.setPlotPixmap(filename)
            try:
                os.remove(filename)
            except:
                print >> sys.stderr, "Couldn't delete temporal file: %s" % filename

    def _getSelectedResultNames(self):
        resultNames = []
        for i in xrange(self.analyzer.nResults):
            implementationItem = self.solutionSelector.layout().itemAt(
                i).widget()
            if implementationItem.isChecked():
                resultNames.append(str(implementationItem.text()))
        return resultNames

    def exportAllImages(self):
        settings = QSettings()
        directory = settings.value(MainWindow.__PREF_SAVE_ALL__).toString()
        directory = QFileDialog.getExistingDirectory(
            self, "Select a directory to export to", directory)
        if directory is None or not os.path.exists(directory):
            return

        self.analyzer.exportAllImages(directory,
                                      self._getSelectedResultNames())
        settings.setValue(MainWindow.__PREF_SAVEL_ALL__, QVariant(directory))
        self.statusBar().showMessage("Images saved!", 5000)

    def computeMetricsAsync(self):
        self.statusBar().showMessage("Computing metrics...")
        QTimer.singleShot(0, self.computeMetrics)

    def computeMetrics(self):
        self._computeMetrics(self.currentSolution.functionName)
        self.statusBar().showMessage("Metrics computed!", 5000)

    def _computeMetrics(self, functionName):
        pareto = self.analyzer.getFunctionPareto(functionName)
        solutions = self.analyzer.getFunctionResults(
            functionName, self._getSelectedResultNames())
        self.metrics.updateMetrics(pareto, solutions, functionName)

    def helpAbout(self):
        QMessageBox.about(
            self, "About Image Changer",
            """<b>Multi-Objective Optimization Interface</b> v%s
            <p>Copyright &copy; 2011-2012 %s All rights reserved.
            <p>This application can be used to perform simple optimization analysis.
            <p><a href='%s'>%s</a>
            <p>Python %s - Qt %s - PyQt %s on %s""" %
            (__VERSION__, __AUTHOR__, __WEBSITE__, __WEBSITE__,
             platform.python_version(), QT_VERSION_STR, PYQT_VERSION_STR,
             platform.system()))

    def addImplementation(self):
        if self.analyzer.nResults == 0:
            directory = ""
        else:
            directory = os.path.abspath(
                os.path.join(str(self.analyzer.resultDirectories[-1]),
                             os.path.pardir))
        directory = QFileDialog.getExistingDirectory(
            self, "Select a directory to scan", directory,
            QFileDialog.ShowDirsOnly)
        if not os.path.exists(
                directory) or directory in self.analyzer.resultDirectories:
            return

        self.analyzer.addResultDirectory(directory)
        self.addSolutionForSelection(self.analyzer.getResultName(directory))

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__,
                          QVariant(self.analyzer.resultDirectories))

    def removeResult(self):
        layout = self.solutionSelector.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            item = layout.itemAt(i)
            if not item.widget().isChecked(
            ):  # and self.analyzer.resultNames[i] != Analyzer.__PARETO__:
                item.widget().setVisible(False)
                layout.removeItem(item)
                self.analyzer.removeResultDirectory(
                    self.analyzer.resultDirectories[i])
        layout.update()

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__,
                          QVariant(self.analyzer.resultDirectories))

    def solutionSelected(self):
        selection = self.functionWidget.currentItem()
        if selection is None:
            return
        self.showSolution(str(selection.text()))

    def showSolution(self, functionName):
        self.currentSolution = self.analyzer.getResultsForFunction(
            functionName)
        self.metrics.clear()
        self._showSolution()

    def addSolutionForSelection(self, name):
        solution = QCheckBox(name)
        solution.setChecked(True)
        solution.stateChanged.connect(self._showSolution)
        self.solutionSelector.layout().addWidget(solution)
        self.solutionSelector.layout().update()

    def _updateSolutionSelection(self):
        self.clearWidget(self.solutionSelector)

        for directory in self.analyzer.resultDirectories:
            self.addSolutionForSelection(
                self.analyzer.getResultName(directory))

    def _showSolution(self):
        sol = self.currentSolution
        if sol is None:
            return

        if len(sol.variableImplementation
               ) == 0 and self.showVariablesRadio.isEnabled():
            self.showVariablesRadio.setEnabled(False)
            if self.showVariablesRadio.isChecked():
                self.showSolutionsRadio.setChecked(True)
        else:
            self.showVariablesRadio.setEnabled(True)

        if len(sol.functionImplementation
               ) == 0 and self.showSolutionsRadio.isEnabled():
            self.showSolutionsRadio.setEnabled(False)
            if self.showSolutionsRadio.isChecked():
                self.showVariablesRadio.setChecked(True)
        else:
            self.showSolutionsRadio.setEnabled(True)

        if self.showSolutionsRadio.isChecked():
            self.generationSlider.setMaximum(
                max([
                    sol.getFunctionSolution(impl).count()
                    for impl in sol.functionImplementation
                ]))
        else:
            self.generationSlider.setMaximum(
                max([
                    sol.getVariableSolution(impl).count()
                    for impl in sol.variableImplementation
                ]))
        self._exportCurrentImage()

    def clearWidget(self, widget):
        layout = widget.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            layout.removeItem(layout.itemAt(i))

    def updateUI(self):
        self.statusBar().showMessage("Updating solutions...")

        selectedRow = self.functionWidget.currentRow()
        self.functionWidget.clear()
        names = [] + self.analyzer.getFunctionNames()
        names.sort()
        for name in names:
            item = QListWidgetItem()
            item.setText(name)
            self.functionWidget.addItem(item)

        if self.functionWidget.count() > 0:
            self.functionWidget.setCurrentRow(
                selectedRow if selectedRow >= 0
                and selectedRow < self.functionWidget.count() else 0)
        self.statusBar().showMessage("Updated!", 5000)

    def _loadInitialData(self):
        self.updateUI()
        self.statusBar().showMessage("Ready!", 5000)

    def closeEvent(self, event):
        self.statusBar().showMessage("Closing...")
        settings = QSettings()
        settings.setValue(MainWindow.__PREF_GEOM__, self.saveGeometry())
        settings.setValue(MainWindow.__PREF_STATE__, self.saveState())
        self.plot.clear()
Ejemplo n.º 3
0
class View(wx.Frame):

    def __init__(self):
        self.app = wx.App(False)

        wx.Frame.__init__(self, None, title="Nocturnal hypoglycemia prediction", size=(1100, 800))
        panel = wx.Panel(self)

        menu = wx.Menu()
        about = menu.Append(wx.ID_ABOUT, "&About", "Information about this program")
        self.Bind(wx.EVT_MENU, lambda x: self.OnAbout(), about)

        menuBar = wx.MenuBar()
        menuBar.Append(menu, "&Help")
        self.SetMenuBar(menuBar)

        label = wx.StaticText(panel, label="Train dataset path:", pos=(10, 10))
        self.m_train_dataset_path_edit = wx.TextCtrl(panel, pos=(10, 30), size=(800, 20))
        self.m_train_dataset_path_edit.SetValue(u"D:\GDrive\Диплом 2\DataPreparation\output1\\fixed_dataset+_train.xlsx")

        label = wx.StaticText(panel, label="Test dataset path:", pos=(10, 60))
        self.m_test_dataset_path_edit = wx.TextCtrl(panel, pos=(10, 80), size=(800, 20))
        self.m_test_dataset_path_edit.SetValue(u"D:\GDrive\Диплом 2\DataPreparation\output1\\fixed_dataset+_validate_known.xlsx")

        label = wx.StaticText(panel, label="Choose method:", pos=(10, 110))
        self.m_predictor_combobox = wx.ComboBox(panel, pos=(10, 130), size=wx.DefaultSize, choices=['stub RNN', 'stub RNN+demographic'], style=wx.CB_READONLY)

        self.m_test_button = wx.Button(panel, label="Test", pos=(10, 160), size=wx.DefaultSize)
        self.m_train_button = wx.Button(panel, label="Train", pos=(110, 160), size=wx.DefaultSize)

        label = wx.StaticText(panel, label="Prediction log:", pos=(10, 200))
        self.m_log = wx.TextCtrl(panel, pos=(10, 220), size=(360, 480), style=wx.TE_MULTILINE | wx.CB_READONLY)

        self.plot = PlotWidget(panel, pos=(400, 220), size=(10, 20))

    def OnAbout(self):
        dlg = View.AboutBox()
        dlg.ShowModal()
        dlg.Destroy()

    # Custom bindings
    def SetOnTestAction(self, on_test_action):
        self.Bind(wx.EVT_BUTTON, lambda x: on_test_action(), self.m_test_button)

    def SetOnTrainAction(self, on_train_action):
        self.Bind(wx.EVT_BUTTON, lambda x: on_train_action(), self.m_train_button)

    # Custom functions
    def UpdateMethodList(self, i_method_list):
        self.m_predictor_combobox.Clear()
        for method in i_method_list:
            self.m_predictor_combobox.Append(method)
        self.m_predictor_combobox.SetSize((200, -1))

    def GetSelectedMethodName(self):
        return self.m_predictor_combobox.GetValue()

    def GetTrainDataPath(self):
        return self.m_train_dataset_path_edit.GetValue()

    def GetTestDataPath(self):
        return self.m_test_dataset_path_edit.GetValue()

    def PrintToLog(self, i_text):
        self.m_log.AppendText('[' + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + '] ' + i_text + '\n')

    def PlotGraph(self, x_arr, y_arr, col):
        self.plot.draw(x_arr, y_arr, col)

    def ClearGraph(self):
        self.plot.clear()

    class AboutBox(wx.Dialog):

        aboutText = "\nThis application is a part of Master's Thesis \"Prediction of nocturnal hypoglycemia in patients with typr 1 diabetes using mrthods based on decision tree and methods based on neural networks\"\n" \
                    "\nAuthors: Dmytro Yurchenko and Serhii Sakharov\n" \
                    "\nKyiv Polytechnic Institute, Department of Applied Math, 2016"

        def __init__(self):
            wx.Dialog.__init__(self, None, -1, "About Nocturnal hypoglycemia prediction", style=wx.DEFAULT_DIALOG_STYLE|wx.THICK_FRAME|wx.RESIZE_BORDER|wx.TAB_TRAVERSAL)
            hwin = wx.StaticText(self, label=View.AboutBox.aboutText, size=(400,200))
            self.CentreOnParent(wx.BOTH)
            self.SetFocus()

    # Run (all settings must be done before this function run)
    def Run(self):
        self.Show(True)
        self.app.MainLoop()