Exemplo n.º 1
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 880)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        MainWindow.setMinimumSize(QtCore.QSize(0, 640))
        MainWindow.setAutoFillBackground(True)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.main_frame = QtWidgets.QFrame(self.centralwidget)
        self.main_frame.setObjectName("main_frame")
        self.gridLayout_7 = QtWidgets.QGridLayout(self.main_frame)
        self.gridLayout_7.setObjectName("gridLayout_7")
        self.data_display_group = QtWidgets.QGroupBox(self.main_frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.data_display_group.sizePolicy().hasHeightForWidth())
        self.data_display_group.setSizePolicy(sizePolicy)
        self.data_display_group.setObjectName("data_display_group")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.data_display_group)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.sweep_value = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.sweep_value.setFont(font)
        self.sweep_value.setScaledContents(False)
        self.sweep_value.setAlignment(QtCore.Qt.AlignRight
                                      | QtCore.Qt.AlignTrailing
                                      | QtCore.Qt.AlignVCenter)
        self.sweep_value.setObjectName("sweep_value")
        self.gridLayout_2.addWidget(self.sweep_value, 5, 2, 1, 1)
        self.channelA_value = QtWidgets.QLabel(self.data_display_group)
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(33, 150, 243))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText,
                         brush)
        brush = QtGui.QBrush(QtGui.QColor(33, 150, 243))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(33, 150, 243))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText,
                         brush)
        brush = QtGui.QBrush(QtGui.QColor(33, 150, 243))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText,
                         brush)
        brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush)
        self.channelA_value.setPalette(palette)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.channelA_value.setFont(font)
        self.channelA_value.setAlignment(QtCore.Qt.AlignRight
                                         | QtCore.Qt.AlignTrailing
                                         | QtCore.Qt.AlignVCenter)
        self.channelA_value.setObjectName("channelA_value")
        self.gridLayout_2.addWidget(self.channelA_value, 3, 1, 1, 2)
        self.channelB_label = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.channelB_label.setFont(font)
        self.channelB_label.setObjectName("channelB_label")
        self.gridLayout_2.addWidget(self.channelB_label, 4, 0, 1, 1)
        self.channelB_value = QtWidgets.QLabel(self.data_display_group)
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 82, 82))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText,
                         brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 82, 82))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 82, 82))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText,
                         brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 82, 82))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush)
        brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText,
                         brush)
        brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush)
        self.channelB_value.setPalette(palette)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.channelB_value.setFont(font)
        self.channelB_value.setAlignment(QtCore.Qt.AlignRight
                                         | QtCore.Qt.AlignTrailing
                                         | QtCore.Qt.AlignVCenter)
        self.channelB_value.setObjectName("channelB_value")
        self.gridLayout_2.addWidget(self.channelB_value, 4, 1, 1, 2)
        self.dec_label = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.dec_label.setFont(font)
        self.dec_label.setObjectName("dec_label")
        self.gridLayout_2.addWidget(self.dec_label, 2, 0, 1, 1)
        self.dec_value = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.dec_value.setFont(font)
        self.dec_value.setScaledContents(False)
        self.dec_value.setAlignment(QtCore.Qt.AlignRight
                                    | QtCore.Qt.AlignTrailing
                                    | QtCore.Qt.AlignVCenter)
        self.dec_value.setObjectName("dec_value")
        self.gridLayout_2.addWidget(self.dec_value, 2, 1, 1, 2)
        self.ra_label = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.ra_label.setFont(font)
        self.ra_label.setObjectName("ra_label")
        self.gridLayout_2.addWidget(self.ra_label, 1, 0, 1, 1)
        self.ra_value = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.ra_value.setFont(font)
        self.ra_value.setScaledContents(False)
        self.ra_value.setAlignment(QtCore.Qt.AlignRight
                                   | QtCore.Qt.AlignTrailing
                                   | QtCore.Qt.AlignVCenter)
        self.ra_value.setObjectName("ra_value")
        self.gridLayout_2.addWidget(self.ra_value, 1, 1, 1, 2)
        self.sweep_label = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.sweep_label.setFont(font)
        self.sweep_label.setObjectName("sweep_label")
        self.gridLayout_2.addWidget(self.sweep_label, 5, 0, 1, 1)
        self.channelA_label = QtWidgets.QLabel(self.data_display_group)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.channelA_label.setFont(font)
        self.channelA_label.setObjectName("channelA_label")
        self.gridLayout_2.addWidget(self.channelA_label, 3, 0, 1, 1)
        self.gridLayout_7.addWidget(self.data_display_group, 1, 0, 1, 1)
        self.stripchart_control_group = QtWidgets.QGroupBox(self.main_frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.stripchart_control_group.sizePolicy().hasHeightForWidth())
        self.stripchart_control_group.setSizePolicy(sizePolicy)
        self.stripchart_control_group.setObjectName("stripchart_control_group")
        self.gridLayout_4 = QtWidgets.QGridLayout(
            self.stripchart_control_group)
        self.gridLayout_4.setObjectName("gridLayout_4")
        self.frame_2 = QtWidgets.QFrame(self.stripchart_control_group)
        self.frame_2.setObjectName("frame_2")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_2)
        self.gridLayout_3.setContentsMargins(-1, 0, -1, 0)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.stripchart_faster_label = QtWidgets.QLabel(self.frame_2)
        self.stripchart_faster_label.setAlignment(QtCore.Qt.AlignLeading
                                                  | QtCore.Qt.AlignLeft
                                                  | QtCore.Qt.AlignVCenter)
        self.stripchart_faster_label.setObjectName("stripchart_faster_label")
        self.gridLayout_3.addWidget(self.stripchart_faster_label, 0, 2, 1, 1)
        self.stripchart_speed_slider = QtWidgets.QSlider(self.frame_2)
        self.stripchart_speed_slider.setMaximum(6)
        self.stripchart_speed_slider.setProperty("value", 3)
        self.stripchart_speed_slider.setOrientation(QtCore.Qt.Horizontal)
        self.stripchart_speed_slider.setTickPosition(
            QtWidgets.QSlider.TicksBothSides)
        self.stripchart_speed_slider.setTickInterval(1)
        self.stripchart_speed_slider.setObjectName("stripchart_speed_slider")
        self.gridLayout_3.addWidget(self.stripchart_speed_slider, 0, 1, 1, 1)
        self.stripchart_slower_label = QtWidgets.QLabel(self.frame_2)
        self.stripchart_slower_label.setAlignment(QtCore.Qt.AlignLeading
                                                  | QtCore.Qt.AlignLeft
                                                  | QtCore.Qt.AlignVCenter)
        self.stripchart_slower_label.setObjectName("stripchart_slower_label")
        self.gridLayout_3.addWidget(self.stripchart_slower_label, 0, 0, 1, 1)
        self.gridLayout_4.addWidget(self.frame_2, 0, 0, 1, 4)
        self.frame = QtWidgets.QFrame(self.stripchart_control_group)
        self.frame.setObjectName("frame")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.toggle_channel_button = QtWidgets.QPushButton(self.frame)
        self.toggle_channel_button.setObjectName("toggle_channel_button")
        self.horizontalLayout.addWidget(self.toggle_channel_button)
        self.chart_clear_button = QtWidgets.QPushButton(self.frame)
        self.chart_clear_button.setObjectName("chart_clear_button")
        self.horizontalLayout.addWidget(self.chart_clear_button)
        self.gridLayout_4.addWidget(self.frame, 3, 0, 1, 4)
        self.gridLayout_7.addWidget(self.stripchart_control_group, 2, 0, 1, 1)
        self.message_group_box = QtWidgets.QGroupBox(self.main_frame)
        self.message_group_box.setObjectName("message_group_box")
        self.gridLayout_5 = QtWidgets.QGridLayout(self.message_group_box)
        self.gridLayout_5.setObjectName("gridLayout_5")
        self.refresh_label = QtWidgets.QLabel(self.message_group_box)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.refresh_label.sizePolicy().hasHeightForWidth())
        self.refresh_label.setSizePolicy(sizePolicy)
        self.refresh_label.setStyleSheet("color: #7a7c7e")
        self.refresh_label.setObjectName("refresh_label")
        self.gridLayout_5.addWidget(self.refresh_label, 2, 0, 1, 1)
        self.refresh_value = QtWidgets.QLabel(self.message_group_box)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.refresh_value.sizePolicy().hasHeightForWidth())
        self.refresh_value.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setBold(True)
        font.setWeight(75)
        self.refresh_value.setFont(font)
        self.refresh_value.setStyleSheet("color: #7a7c7e")
        self.refresh_value.setAlignment(QtCore.Qt.AlignRight
                                        | QtCore.Qt.AlignTrailing
                                        | QtCore.Qt.AlignVCenter)
        self.refresh_value.setObjectName("refresh_value")
        self.gridLayout_5.addWidget(self.refresh_value, 2, 1, 1, 1)
        self.progressBar = QtWidgets.QProgressBar(self.message_group_box)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.progressBar.sizePolicy().hasHeightForWidth())
        self.progressBar.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setPointSize(16)
        self.progressBar.setFont(font)
        self.progressBar.setAlignment(QtCore.Qt.AlignLeading
                                      | QtCore.Qt.AlignLeft
                                      | QtCore.Qt.AlignVCenter)
        self.progressBar.setInvertedAppearance(False)
        self.progressBar.setObjectName("progressBar")
        self.gridLayout_5.addWidget(self.progressBar, 1, 0, 1, 2)
        self.message_label = QtWidgets.QLabel(self.message_group_box)
        font = QtGui.QFont()
        font.setPointSize(20)
        self.message_label.setFont(font)
        self.message_label.setObjectName("message_label")
        self.gridLayout_5.addWidget(self.message_label, 0, 0, 1, 2)
        self.gridLayout_7.addWidget(self.message_group_box, 0, 0, 1, 1)
        self.console_background = QtWidgets.QFrame(self.main_frame)
        self.console_background.setObjectName("console_background")
        self.gridLayout_11 = QtWidgets.QGridLayout(self.console_background)
        self.gridLayout_11.setContentsMargins(0, -1, 0, -1)
        self.gridLayout_11.setObjectName("gridLayout_11")
        self.console_inner_frame_2 = QtWidgets.QFrame(self.console_background)
        self.console_inner_frame_2.setStyleSheet(
            "background: black; border-radius: 5px")
        self.console_inner_frame_2.setObjectName("console_inner_frame_2")
        self.gridLayout_12 = QtWidgets.QGridLayout(self.console_inner_frame_2)
        self.gridLayout_12.setObjectName("gridLayout_12")
        self.console_label = QtWidgets.QLabel(self.console_inner_frame_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.console_label.sizePolicy().hasHeightForWidth())
        self.console_label.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setFamily("Iosevka Aile")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.console_label.setFont(font)
        self.console_label.setStyleSheet("color: #0f0")
        self.console_label.setAlignment(QtCore.Qt.AlignBottom
                                        | QtCore.Qt.AlignLeading
                                        | QtCore.Qt.AlignLeft)
        self.console_label.setObjectName("console_label")
        self.gridLayout_12.addWidget(self.console_label, 0, 0, 1, 1)
        self.dec_view = QtWidgets.QGraphicsView(self.console_inner_frame_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.dec_view.sizePolicy().hasHeightForWidth())
        self.dec_view.setSizePolicy(sizePolicy)
        self.dec_view.setStyleSheet("background: transparent")
        self.dec_view.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.dec_view.setFrameShadow(QtWidgets.QFrame.Plain)
        self.dec_view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.dec_view.setHorizontalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOff)
        self.dec_view.setRenderHints(QtGui.QPainter.Antialiasing
                                     | QtGui.QPainter.TextAntialiasing)
        self.dec_view.setObjectName("dec_view")
        self.gridLayout_12.addWidget(self.dec_view, 0, 1, 1, 1)
        self.gridLayout_11.addWidget(self.console_inner_frame_2, 0, 0, 1, 1)
        self.gridLayout_7.addWidget(self.console_background, 3, 0, 1, 1)
        self.output_frame = QtWidgets.QFrame(self.main_frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.output_frame.sizePolicy().hasHeightForWidth())
        self.output_frame.setSizePolicy(sizePolicy)
        self.output_frame.setMinimumSize(QtCore.QSize(360, 0))
        self.output_frame.setObjectName("output_frame")
        self.gridLayout_10 = QtWidgets.QGridLayout(self.output_frame)
        self.gridLayout_10.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_10.setObjectName("gridLayout_10")
        self.stripchart = QChartView(self.output_frame)
        self.stripchart.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.stripchart.setFrameShadow(QtWidgets.QFrame.Plain)
        self.stripchart.setObjectName("stripchart")
        self.gridLayout_10.addWidget(self.stripchart, 0, 0, 2, 2)
        self.gridLayout_7.addWidget(self.output_frame, 0, 1, 4, 1)
        self.gridLayout.addWidget(self.main_frame, 0, 0, 1, 1)
        self.testing_frame = QtWidgets.QFrame(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.testing_frame.sizePolicy().hasHeightForWidth())
        self.testing_frame.setSizePolicy(sizePolicy)
        self.testing_frame.setMinimumSize(QtCore.QSize(0, 180))
        self.testing_frame.setObjectName("testing_frame")
        self.gridLayout_8 = QtWidgets.QGridLayout(self.testing_frame)
        self.gridLayout_8.setContentsMargins(-1, 0, -1, -1)
        self.gridLayout_8.setObjectName("gridLayout_8")
        self.dec_group_box = QtWidgets.QGroupBox(self.testing_frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.dec_group_box.sizePolicy().hasHeightForWidth())
        self.dec_group_box.setSizePolicy(sizePolicy)
        self.dec_group_box.setObjectName("dec_group_box")
        self.gridLayout_9 = QtWidgets.QGridLayout(self.dec_group_box)
        self.gridLayout_9.setObjectName("gridLayout_9")
        self.north_label = QtWidgets.QLabel(self.dec_group_box)
        self.north_label.setAlignment(QtCore.Qt.AlignLeading
                                      | QtCore.Qt.AlignLeft
                                      | QtCore.Qt.AlignTop)
        self.north_label.setObjectName("north_label")
        self.gridLayout_9.addWidget(self.north_label, 0, 1, 1, 1)
        self.south_label = QtWidgets.QLabel(self.dec_group_box)
        self.south_label.setAlignment(QtCore.Qt.AlignBottom
                                      | QtCore.Qt.AlignLeading
                                      | QtCore.Qt.AlignLeft)
        self.south_label.setObjectName("south_label")
        self.gridLayout_9.addWidget(self.south_label, 1, 1, 1, 1)
        self.declination_slider = QtWidgets.QSlider(self.dec_group_box)
        self.declination_slider.setMinimum(-99)
        self.declination_slider.setMaximum(99)
        self.declination_slider.setSingleStep(1)
        self.declination_slider.setProperty("value", 0)
        self.declination_slider.setTickInterval(20)
        self.declination_slider.setObjectName("declination_slider")
        self.gridLayout_9.addWidget(self.declination_slider, 0, 0, 2, 1)
        self.dec_auto_check_box = QtWidgets.QCheckBox(self.dec_group_box)
        self.dec_auto_check_box.setChecked(True)
        self.dec_auto_check_box.setObjectName("dec_auto_check_box")
        self.gridLayout_9.addWidget(self.dec_auto_check_box, 2, 0, 1, 2)
        self.gridLayout_8.addWidget(self.dec_group_box, 0, 1, 1, 1)
        self.signal_group_box = QtWidgets.QGroupBox(self.testing_frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.signal_group_box.sizePolicy().hasHeightForWidth())
        self.signal_group_box.setSizePolicy(sizePolicy)
        self.signal_group_box.setObjectName("signal_group_box")
        self.gridLayout_6 = QtWidgets.QGridLayout(self.signal_group_box)
        self.gridLayout_6.setObjectName("gridLayout_6")
        self.variance_dial = QtWidgets.QDial(self.signal_group_box)
        self.variance_dial.setMinimum(0)
        self.variance_dial.setMaximum(16)
        self.variance_dial.setPageStep(4)
        self.variance_dial.setProperty("value", 4)
        self.variance_dial.setWrapping(False)
        self.variance_dial.setNotchTarget(1.0)
        self.variance_dial.setNotchesVisible(True)
        self.variance_dial.setObjectName("variance_dial")
        self.gridLayout_6.addWidget(self.variance_dial, 1, 0, 1, 1)
        self.variance_label = QtWidgets.QLabel(self.signal_group_box)
        self.variance_label.setAlignment(QtCore.Qt.AlignCenter)
        self.variance_label.setObjectName("variance_label")
        self.gridLayout_6.addWidget(self.variance_label, 3, 0, 1, 1)
        self.noise_label = QtWidgets.QLabel(self.signal_group_box)
        self.noise_label.setAlignment(QtCore.Qt.AlignCenter)
        self.noise_label.setObjectName("noise_label")
        self.gridLayout_6.addWidget(self.noise_label, 3, 3, 1, 1)
        self.polarization_label = QtWidgets.QLabel(self.signal_group_box)
        self.polarization_label.setAlignment(QtCore.Qt.AlignCenter)
        self.polarization_label.setObjectName("polarization_label")
        self.gridLayout_6.addWidget(self.polarization_label, 3, 2, 1, 1)
        self.polarization_dial = QtWidgets.QDial(self.signal_group_box)
        self.polarization_dial.setMinimum(0)
        self.polarization_dial.setMaximum(16)
        self.polarization_dial.setPageStep(4)
        self.polarization_dial.setProperty("value", 4)
        self.polarization_dial.setWrapping(False)
        self.polarization_dial.setNotchTarget(1.0)
        self.polarization_dial.setNotchesVisible(True)
        self.polarization_dial.setObjectName("polarization_dial")
        self.gridLayout_6.addWidget(self.polarization_dial, 1, 2, 1, 1)
        self.noise_dial = QtWidgets.QDial(self.signal_group_box)
        self.noise_dial.setMinimum(0)
        self.noise_dial.setMaximum(16)
        self.noise_dial.setPageStep(4)
        self.noise_dial.setProperty("value", 4)
        self.noise_dial.setWrapping(False)
        self.noise_dial.setNotchTarget(1.0)
        self.noise_dial.setNotchesVisible(True)
        self.noise_dial.setObjectName("noise_dial")
        self.gridLayout_6.addWidget(self.noise_dial, 1, 3, 1, 1)
        self.calibration_check_box = QtWidgets.QCheckBox(self.signal_group_box)
        self.calibration_check_box.setObjectName("calibration_check_box")
        self.gridLayout_6.addWidget(self.calibration_check_box, 1, 4, 3, 1)
        self.gridLayout_8.addWidget(self.signal_group_box, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.testing_frame, 1, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 43))
        self.menubar.setObjectName("menubar")
        self.menuCalibration = QtWidgets.QMenu(self.menubar)
        self.menuCalibration.setObjectName("menuCalibration")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuMode = QtWidgets.QMenu(self.menubar)
        self.menuMode.setObjectName("menuMode")
        self.menuObservation = QtWidgets.QMenu(self.menubar)
        self.menuObservation.setObjectName("menuObservation")
        MainWindow.setMenuBar(self.menubar)
        self.actionRA = QtWidgets.QAction(MainWindow)
        self.actionRA.setObjectName("actionRA")
        self.actionDec = QtWidgets.QAction(MainWindow)
        self.actionDec.setObjectName("actionDec")
        self.actionSurvey = QtWidgets.QAction(MainWindow)
        self.actionSurvey.setObjectName("actionSurvey")
        self.actionInfo = QtWidgets.QAction(MainWindow)
        self.actionInfo.setObjectName("actionInfo")
        self.actionQuit = QtWidgets.QAction(MainWindow)
        self.actionQuit.setObjectName("actionQuit")
        self.actionHelp = QtWidgets.QAction(MainWindow)
        self.actionHelp.setEnabled(False)
        self.actionHelp.setObjectName("actionHelp")
        self.actionScan = QtWidgets.QAction(MainWindow)
        self.actionScan.setObjectName("actionScan")
        self.actionSpectrum = QtWidgets.QAction(MainWindow)
        self.actionSpectrum.setObjectName("actionSpectrum")
        self.actionNormal = QtWidgets.QAction(MainWindow)
        self.actionNormal.setCheckable(True)
        self.actionNormal.setObjectName("actionNormal")
        self.actionTesting = QtWidgets.QAction(MainWindow)
        self.actionTesting.setCheckable(True)
        self.actionTesting.setObjectName("actionTesting")
        self.actionLegacy = QtWidgets.QAction(MainWindow)
        self.actionLegacy.setCheckable(True)
        self.actionLegacy.setObjectName("actionLegacy")
        self.actionGetInfo = QtWidgets.QAction(MainWindow)
        self.actionGetInfo.setEnabled(False)
        self.actionGetInfo.setObjectName("actionGetInfo")
        self.menuCalibration.addAction(self.actionRA)
        self.menuCalibration.addAction(self.actionDec)
        self.menuFile.addAction(self.actionHelp)
        self.menuFile.addAction(self.actionInfo)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionQuit)
        self.menuMode.addAction(self.actionNormal)
        self.menuMode.addAction(self.actionTesting)
        self.menuMode.addSeparator()
        self.menuMode.addAction(self.actionLegacy)
        self.menuObservation.addAction(self.actionScan)
        self.menuObservation.addAction(self.actionSurvey)
        self.menuObservation.addAction(self.actionSpectrum)
        self.menuObservation.addSeparator()
        self.menuObservation.addAction(self.actionGetInfo)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuObservation.menuAction())
        self.menubar.addAction(self.menuCalibration.menuAction())
        self.menubar.addAction(self.menuMode.menuAction())

        self.retranslateUi(MainWindow)
        self.actionQuit.triggered.connect(MainWindow.close)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        MainWindow.setTabOrder(self.stripchart_speed_slider,
                               self.chart_clear_button)
        MainWindow.setTabOrder(self.chart_clear_button, self.dec_view)
        MainWindow.setTabOrder(self.dec_view, self.stripchart)
        MainWindow.setTabOrder(self.stripchart, self.variance_dial)
        MainWindow.setTabOrder(self.variance_dial, self.polarization_dial)
        MainWindow.setTabOrder(self.polarization_dial, self.noise_dial)
        MainWindow.setTabOrder(self.noise_dial, self.calibration_check_box)
        MainWindow.setTabOrder(self.calibration_check_box,
                               self.declination_slider)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.data_display_group.setTitle(_translate("MainWindow", "Data"))
        self.sweep_value.setText(_translate("MainWindow", "n/a"))
        self.channelA_value.setText(_translate("MainWindow", "0.0000V"))
        self.channelB_label.setText(_translate("MainWindow", "Channel B:"))
        self.channelB_value.setText(_translate("MainWindow", "0.0000V"))
        self.dec_label.setText(_translate("MainWindow", "Declination:"))
        self.dec_value.setText(_translate("MainWindow", "0.0000deg"))
        self.ra_label.setText(_translate("MainWindow", "Right Ascension:"))
        self.ra_value.setText(_translate("MainWindow", "00:00:00"))
        self.sweep_label.setText(_translate("MainWindow", "Sweep:"))
        self.channelA_label.setText(_translate("MainWindow", "Channel A:"))
        self.stripchart_control_group.setTitle(
            _translate("MainWindow", "Strip chart"))
        self.stripchart_faster_label.setText(_translate(
            "MainWindow", "Faster"))
        self.stripchart_slower_label.setText(_translate(
            "MainWindow", "Slower"))
        self.toggle_channel_button.setText(
            _translate("MainWindow", "Toggle Channels"))
        self.chart_clear_button.setText(_translate("MainWindow",
                                                   "Clear Chart"))
        self.message_group_box.setTitle(_translate("MainWindow", "Message"))
        self.refresh_label.setText(_translate("MainWindow", "Refresh rate:"))
        self.refresh_value.setText(_translate("MainWindow", "0.00Hz"))
        self.message_label.setText(_translate("MainWindow", "..."))
        self.console_label.setText(_translate("MainWindow", ">>>"))
        self.dec_group_box.setTitle(_translate("MainWindow", "Declinometer"))
        self.north_label.setText(_translate("MainWindow", "+"))
        self.south_label.setText(_translate("MainWindow", "-"))
        self.dec_auto_check_box.setText(_translate("MainWindow", "Auto"))
        self.signal_group_box.setTitle(_translate("MainWindow", "Signal"))
        self.variance_label.setText(_translate("MainWindow", "Variance"))
        self.noise_label.setText(_translate("MainWindow", "Interference"))
        self.polarization_label.setText(
            _translate("MainWindow", "Polarization"))
        self.calibration_check_box.setText(
            _translate("MainWindow", "Calibration"))
        self.menuCalibration.setTitle(_translate("MainWindow", "Calibrate"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuMode.setTitle(_translate("MainWindow", "Mode"))
        self.menuObservation.setTitle(_translate("MainWindow", "Observation"))
        self.actionRA.setText(_translate("MainWindow", "RA..."))
        self.actionRA.setShortcut(_translate("MainWindow", "Ctrl+R"))
        self.actionDec.setText(_translate("MainWindow", "Dec..."))
        self.actionDec.setShortcut(_translate("MainWindow", "Ctrl+D"))
        self.actionSurvey.setText(_translate("MainWindow", "New Survey..."))
        self.actionSurvey.setShortcut(_translate("MainWindow", "Ctrl+2"))
        self.actionInfo.setText(_translate("MainWindow", "Credits..."))
        self.actionQuit.setText(_translate("MainWindow", "Exit"))
        self.actionHelp.setText(_translate("MainWindow", "Help..."))
        self.actionScan.setText(_translate("MainWindow", "New Scan..."))
        self.actionScan.setShortcut(_translate("MainWindow", "Ctrl+1"))
        self.actionSpectrum.setText(_translate("MainWindow",
                                               "New Spectrum..."))
        self.actionSpectrum.setShortcut(_translate("MainWindow", "Ctrl+3"))
        self.actionNormal.setText(_translate("MainWindow", "Normal"))
        self.actionNormal.setShortcut(_translate("MainWindow", "Ctrl+N"))
        self.actionTesting.setText(_translate("MainWindow", "Testing"))
        self.actionTesting.setShortcut(_translate("MainWindow", "Ctrl+T"))
        self.actionLegacy.setText(_translate("MainWindow", "Legacy"))
        self.actionGetInfo.setText(_translate("MainWindow", "Get Info..."))
        self.actionGetInfo.setShortcut(_translate("MainWindow", "Ctrl+I"))
Exemplo n.º 2
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1072, 821)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setObjectName("groupBox")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox)
        self.verticalLayout.setObjectName("verticalLayout")
        self.cvGlycoforms = QChartView(self.groupBox)
        self.cvGlycoforms.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.cvGlycoforms.setRenderHints(QtGui.QPainter.Antialiasing
                                         | QtGui.QPainter.TextAntialiasing)
        self.cvGlycoforms.setObjectName("cvGlycoforms")
        self.verticalLayout.addWidget(self.cvGlycoforms)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.cbAggGlycoforms = QtWidgets.QCheckBox(self.groupBox)
        self.cbAggGlycoforms.setEnabled(False)
        self.cbAggGlycoforms.setChecked(True)
        self.cbAggGlycoforms.setObjectName("cbAggGlycoforms")
        self.horizontalLayout_7.addWidget(self.cbAggGlycoforms)
        self.sbAggGlycoforms = QtWidgets.QSpinBox(self.groupBox)
        self.sbAggGlycoforms.setEnabled(False)
        self.sbAggGlycoforms.setProperty("value", 7)
        self.sbAggGlycoforms.setObjectName("sbAggGlycoforms")
        self.horizontalLayout_7.addWidget(self.sbAggGlycoforms)
        self.lbAggGlycoforms = QtWidgets.QLabel(self.groupBox)
        self.lbAggGlycoforms.setEnabled(False)
        self.lbAggGlycoforms.setObjectName("lbAggGlycoforms")
        self.horizontalLayout_7.addWidget(self.lbAggGlycoforms)
        spacerItem = QtWidgets.QSpacerItem(1, 20,
                                           QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_7.addItem(spacerItem)
        self.verticalLayout.addLayout(self.horizontalLayout_7)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.btLoadGlycoforms = QtWidgets.QPushButton(self.groupBox)
        self.btLoadGlycoforms.setObjectName("btLoadGlycoforms")
        self.horizontalLayout_2.addWidget(self.btLoadGlycoforms)
        spacerItem1 = QtWidgets.QSpacerItem(1, 17,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.lbGlycoform = QtWidgets.QLabel(self.groupBox)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.lbGlycoform.sizePolicy().hasHeightForWidth())
        self.lbGlycoform.setSizePolicy(sizePolicy)
        self.lbGlycoform.setObjectName("lbGlycoform")
        self.horizontalLayout_2.addWidget(self.lbGlycoform)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_3.addWidget(self.groupBox)
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_2.setObjectName("groupBox_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_2)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.cvGlycation = QChartView(self.groupBox_2)
        self.cvGlycation.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.cvGlycation.setRenderHints(QtGui.QPainter.Antialiasing
                                        | QtGui.QPainter.TextAntialiasing)
        self.cvGlycation.setObjectName("cvGlycation")
        self.verticalLayout_2.addWidget(self.cvGlycation)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.btLoadGlycation = QtWidgets.QPushButton(self.groupBox_2)
        self.btLoadGlycation.setObjectName("btLoadGlycation")
        self.horizontalLayout_4.addWidget(self.btLoadGlycation)
        spacerItem2 = QtWidgets.QSpacerItem(1, 17,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_4.addItem(spacerItem2)
        self.lbGlycation = QtWidgets.QLabel(self.groupBox_2)
        self.lbGlycation.setObjectName("lbGlycation")
        self.horizontalLayout_4.addWidget(self.lbGlycation)
        self.verticalLayout_2.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_3.addWidget(self.groupBox_2)
        self.groupBox_3 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_3.setObjectName("groupBox_3")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox_3)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.twLibrary = QtWidgets.QTableWidget(self.groupBox_3)
        self.twLibrary.setAcceptDrops(True)
        self.twLibrary.setObjectName("twLibrary")
        self.twLibrary.setColumnCount(2)
        self.twLibrary.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.twLibrary.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.twLibrary.setHorizontalHeaderItem(1, item)
        self.twLibrary.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_3.addWidget(self.twLibrary)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.btLoadLibrary = QtWidgets.QPushButton(self.groupBox_3)
        self.btLoadLibrary.setObjectName("btLoadLibrary")
        self.horizontalLayout_5.addWidget(self.btLoadLibrary)
        spacerItem3 = QtWidgets.QSpacerItem(1, 17,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_5.addItem(spacerItem3)
        self.verticalLayout_3.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_3.addWidget(self.groupBox_3)
        self.verticalLayout_7.addLayout(self.horizontalLayout_3)
        self.groupBox_4 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_4.setObjectName("groupBox_4")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_4)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.horizontalLayout_9 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_9.setObjectName("horizontalLayout_9")
        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
        self.verticalLayout_6.setSpacing(0)
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.cvResults = QChartView(self.groupBox_4)
        self.cvResults.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.cvResults.setRenderHints(QtGui.QPainter.Antialiasing
                                      | QtGui.QPainter.TextAntialiasing)
        self.cvResults.setObjectName("cvResults")
        self.verticalLayout_6.addWidget(self.cvResults)
        self.lbResults = QtWidgets.QLabel(self.groupBox_4)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.lbResults.sizePolicy().hasHeightForWidth())
        self.lbResults.setSizePolicy(sizePolicy)
        self.lbResults.setMinimumSize(QtCore.QSize(0, 15))
        self.lbResults.setStyleSheet("QLabel {\n"
                                     "background: rgb(255, 255, 255)\n"
                                     "}")
        self.lbResults.setObjectName("lbResults")
        self.verticalLayout_6.addWidget(self.lbResults)
        self.horizontalLayout_9.addLayout(self.verticalLayout_6)
        self.twResults = QtWidgets.QTableWidget(self.groupBox_4)
        self.twResults.setObjectName("twResults")
        self.twResults.setColumnCount(6)
        self.twResults.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.twResults.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.twResults.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.twResults.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.twResults.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.twResults.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.twResults.setHorizontalHeaderItem(5, item)
        self.twResults.horizontalHeader().setDefaultSectionSize(70)
        self.horizontalLayout_9.addWidget(self.twResults)
        self.verticalLayout_5.addLayout(self.horizontalLayout_9)
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        self.cbAggResults = QtWidgets.QCheckBox(self.groupBox_4)
        self.cbAggResults.setEnabled(False)
        self.cbAggResults.setChecked(True)
        self.cbAggResults.setObjectName("cbAggResults")
        self.horizontalLayout_8.addWidget(self.cbAggResults)
        self.sbAggResults = QtWidgets.QSpinBox(self.groupBox_4)
        self.sbAggResults.setEnabled(False)
        self.sbAggResults.setProperty("value", 7)
        self.sbAggResults.setObjectName("sbAggResults")
        self.horizontalLayout_8.addWidget(self.sbAggResults)
        self.lbAggResults = QtWidgets.QLabel(self.groupBox_4)
        self.lbAggResults.setEnabled(False)
        self.lbAggResults.setObjectName("lbAggResults")
        self.horizontalLayout_8.addWidget(self.lbAggResults)
        spacerItem4 = QtWidgets.QSpacerItem(1, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem4)
        self.btSaveResults = QtWidgets.QPushButton(self.groupBox_4)
        self.btSaveResults.setEnabled(False)
        self.btSaveResults.setObjectName("btSaveResults")
        self.horizontalLayout_8.addWidget(self.btSaveResults)
        self.btSaveGraph = QtWidgets.QPushButton(self.groupBox_4)
        self.btSaveGraph.setEnabled(False)
        self.btSaveGraph.setObjectName("btSaveGraph")
        self.horizontalLayout_8.addWidget(self.btSaveGraph)
        self.verticalLayout_5.addLayout(self.horizontalLayout_8)
        self.verticalLayout_7.addWidget(self.groupBox_4)
        self.groupBox_5 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_5.setObjectName("groupBox_5")
        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_5)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.teLog = QtWidgets.QTextEdit(self.groupBox_5)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Ignored)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.teLog.sizePolicy().hasHeightForWidth())
        self.teLog.setSizePolicy(sizePolicy)
        self.teLog.setMinimumSize(QtCore.QSize(0, 80))
        self.teLog.setReadOnly(True)
        self.teLog.setObjectName("teLog")
        self.verticalLayout_4.addWidget(self.teLog)
        self.verticalLayout_7.addWidget(self.groupBox_5)
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.btCorrect = QtWidgets.QPushButton(self.centralwidget)
        self.btCorrect.setObjectName("btCorrect")
        self.horizontalLayout_6.addWidget(self.btCorrect)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem5)
        self.btSampleData = QtWidgets.QPushButton(self.centralwidget)
        self.btSampleData.setObjectName("btSampleData")
        self.horizontalLayout_6.addWidget(self.btSampleData)
        self.btHelp = QtWidgets.QPushButton(self.centralwidget)
        self.btHelp.setObjectName("btHelp")
        self.horizontalLayout_6.addWidget(self.btHelp)
        self.btQuit = QtWidgets.QPushButton(self.centralwidget)
        self.btQuit.setObjectName("btQuit")
        self.horizontalLayout_6.addWidget(self.btQuit)
        self.verticalLayout_7.addLayout(self.horizontalLayout_6)
        self.groupBox_4.raise_()
        self.groupBox_5.raise_()
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "cafog"))
        self.groupBox.setTitle(_translate("MainWindow", "Glycoforms"))
        self.cbAggGlycoforms.setText(
            _translate("MainWindow", "Only display the"))
        self.lbAggGlycoforms.setText(
            _translate("MainWindow", "most abundant glycoforms"))
        self.btLoadGlycoforms.setText(_translate("MainWindow", "Load ..."))
        self.lbGlycoform.setText(_translate("MainWindow", "(glycoform)"))
        self.groupBox_2.setTitle(_translate("MainWindow", "Glycation"))
        self.btLoadGlycation.setText(_translate("MainWindow", "Load ..."))
        self.lbGlycation.setText(_translate("MainWindow", "(glycation)"))
        self.groupBox_3.setTitle(_translate("MainWindow", "Glycan library"))
        item = self.twLibrary.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "Glycan"))
        item = self.twLibrary.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "Composition"))
        self.btLoadLibrary.setText(_translate("MainWindow", "Load ..."))
        self.groupBox_4.setTitle(_translate("MainWindow", "Results"))
        self.lbResults.setText(_translate("MainWindow", "(results)"))
        self.twResults.setSortingEnabled(True)
        item = self.twResults.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "Glycoform"))
        item = self.twResults.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "Observed"))
        item = self.twResults.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "Error"))
        item = self.twResults.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "Actual"))
        item = self.twResults.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "Error"))
        item = self.twResults.horizontalHeaderItem(5)
        item.setText(_translate("MainWindow", "Change"))
        self.cbAggResults.setText(_translate("MainWindow", "Only display the"))
        self.lbAggResults.setText(
            _translate("MainWindow", "most abundant glycoforms"))
        self.btSaveResults.setText(_translate("MainWindow",
                                              "Save results ..."))
        self.btSaveGraph.setText(
            _translate("MainWindow", "Save glycation graph ..."))
        self.groupBox_5.setTitle(_translate("MainWindow", "Log"))
        self.btCorrect.setText(_translate("MainWindow", "Correct abundances"))
        self.btSampleData.setText(_translate("MainWindow", "Load sample data"))
        self.btHelp.setText(_translate("MainWindow", "Help"))
        self.btHelp.setShortcut(_translate("MainWindow", "F1"))
        self.btQuit.setText(_translate("MainWindow", "Quit"))
class Ui_MainWindow(QtWidgets.QMainWindow):
    def setupUi(self):
        self.setObjectName("MainWindow")
        self.resize(600, 830)
        self.setWindowTitle("GA - Queens")
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")
        self.frameWorld = MyQFrame(self.centralwidget)
        self.frameWorld.img = QPixmap(1000, 1000)
        self.frameWorld.setGeometry(QtCore.QRect(10, 10, 400, 400))
        self.frameWorld.setFrameShape(QtWidgets.QFrame.Box)
        self.frameWorld.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frameWorld.setObjectName("frameWorld")
        self.frameChart = QChartView(self.centralwidget)
        self.frameChart.setGeometry(QtCore.QRect(10, 420, 400, 400))
        self.frameChart.setFrameShape(QtWidgets.QFrame.Box)
        self.frameChart.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frameChart.setRenderHint(QPainter.Antialiasing)
        self.frameChart.setObjectName("frameChart")
        self.gaParams = QtWidgets.QGroupBox(self.centralwidget)
        self.gaParams.setGeometry(QtCore.QRect(430, 10, 161, 171))
        self.gaParams.setObjectName("gaParams")
        self.gaParams.setTitle("GA parameters")
        self.label1 = QtWidgets.QLabel(self.gaParams)
        self.label1.setGeometry(QtCore.QRect(10, 20, 61, 16))
        self.label1.setObjectName("label1")
        self.label1.setText("Population:")
        self.label2 = QtWidgets.QLabel(self.gaParams)
        self.label2.setGeometry(QtCore.QRect(10, 50, 47, 16))
        self.label2.setObjectName("label2")
        self.label2.setText("Mutation:")
        self.label3 = QtWidgets.QLabel(self.gaParams)
        self.label3.setGeometry(QtCore.QRect(10, 80, 81, 16))
        self.label3.setObjectName("label3")
        self.label3.setText("Elite members:")
        self.label4 = QtWidgets.QLabel(self.gaParams)
        self.label4.setGeometry(QtCore.QRect(10, 110, 91, 16))
        self.label4.setObjectName("label4")
        self.label4.setText("No. generations:")
        self.cbxPermutation = QtWidgets.QCheckBox(self.gaParams)
        self.cbxPermutation.setGeometry(QtCore.QRect(35, 140, 91, 17))
        self.cbxPermutation.setObjectName("cbxPermutation")
        self.cbxPermutation.setText("Permutation")
        self.tbxPopulation = QtWidgets.QLineEdit(self.gaParams)
        self.tbxPopulation.setGeometry(QtCore.QRect(100, 20, 51, 20))
        self.tbxPopulation.setObjectName("tbxPopulation")
        self.tbxMutation = QtWidgets.QLineEdit(self.gaParams)
        self.tbxMutation.setGeometry(QtCore.QRect(100, 50, 51, 20))
        self.tbxMutation.setObjectName("tbxMutation")
        self.tbxElite = QtWidgets.QLineEdit(self.gaParams)
        self.tbxElite.setGeometry(QtCore.QRect(100, 80, 51, 20))
        self.tbxElite.setObjectName("tbxElite")
        self.tbxGenerations = QtWidgets.QLineEdit(self.gaParams)
        self.tbxGenerations.setGeometry(QtCore.QRect(100, 110, 51, 20))
        self.tbxGenerations.setObjectName("tbxGenerations")
        self.label5 = QtWidgets.QLabel(self.centralwidget)
        self.label5.setGeometry(QtCore.QRect(440, 190, 61, 16))
        self.label5.setObjectName("label5")
        self.label5.setText("No. queens:")
        self.tbxNoQueens = QtWidgets.QLineEdit(self.centralwidget)
        self.tbxNoQueens.setGeometry(QtCore.QRect(510, 190, 51, 20))
        self.tbxNoQueens.setObjectName("tbxNoQueens")
        self.cbxNoVis = QtWidgets.QCheckBox(self.centralwidget)
        self.cbxNoVis.setGeometry(QtCore.QRect(420, 215, 170, 17))
        self.cbxNoVis.setObjectName("cbxNoVis")
        self.cbxNoVis.setText("No visualization per generation")
        self.btnStart = QtWidgets.QPushButton(self.centralwidget)
        self.btnStart.setGeometry(QtCore.QRect(430, 250, 75, 23))
        self.btnStart.setObjectName("btnStart")
        self.btnStart.setText("Start")
        self.btnStop = QtWidgets.QPushButton(self.centralwidget)
        self.btnStop.setEnabled(False)
        self.btnStop.setGeometry(QtCore.QRect(510, 250, 75, 23))
        self.btnStop.setObjectName("btnStop")
        self.btnStop.setText("Stop")
        self.btnSaveWorld = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveWorld.setGeometry(QtCore.QRect(430, 370, 121, 41))
        self.btnSaveWorld.setObjectName("btnSaveWorld")
        self.btnSaveWorld.setText("Save world as image")
        self.btnSaveChart = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveChart.setGeometry(QtCore.QRect(430, 730, 121, 41))
        self.btnSaveChart.setObjectName("btnSaveChart")
        self.btnSaveChart.setText("Save chart as image")
        self.btnSaveChartSeries = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveChartSeries.setGeometry(QtCore.QRect(430, 780, 121, 41))
        self.btnSaveChartSeries.setObjectName("btnSaveChartSeries")
        self.btnSaveChartSeries.setText("Save chart as series")
        self.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(self)

        #Connect events
        self.btnStart.clicked.connect(self.btnStart_Click)
        self.btnStop.clicked.connect(self.btnStop_Click)
        self.btnSaveWorld.clicked.connect(self.btnSaveWorld_Click)
        self.btnSaveChart.clicked.connect(self.btnSaveChart_CLick)
        self.btnSaveChartSeries.clicked.connect(self.btnSaveChartSeries_Click)

        #Set default GA variables
        self.tbxNoQueens.insert(str(NO_QUEENS))
        self.tbxGenerations.insert(str(NGEN))
        self.tbxPopulation.insert(str(POP_SIZE))
        self.tbxMutation.insert(str(MUTPB))
        self.tbxElite.insert(str(NELT))

        self.new_image = QPixmap(1000, 1000)

    def btnStart_Click(self):

        global success  # Number of times when fitness function reached 0 -- Added by Denis Lazor
        global generations  # Number of times when fitness function reached 0 -- Added by Denis Lazor
        global combination_series  # List of lists containing min_series of 5 correct results -- Added by Denis Lazor
        global parameter_name  # Name of parameter used for writing its data to .csv file -- Added by Denis Lazor

        global ELITE_SIZES
        global BOARD_SIZES
        global POPULATION_SIZES
        global MUTATION_SIZES

        # Checking if files are empty or not -- Added by Denis Lazor
        csv_contains = os.stat("graphs_csv/original_.csv").st_size != 0
        csv_contains_permutation = os.stat(
            "graphs_csv/original_permutation.csv").st_size != 0
        permutation_checked = self.cbxPermutation.isChecked()

        # Clearing non empty files if we are trying to write to them -- Added by Denis Lazor
        if csv_contains_permutation and permutation_checked:
            clear_all_csv("p")
        if csv_contains and not permutation_checked:
            clear_all_csv("np")

        BOARD_SIZES = [12, 24]
        n = 5000
        # Automation for all necessary combinations -- Added by Denis Lazor
        for b in BOARD_SIZES:
            # Because we use slicing we need to restore parameters lists after changing board size
            POPULATION_SIZES = [50, 100, 200]
            MUTATION_SIZES = [0.04, 0.08, 0.16]
            ELITE_SIZES = [4, 8, 16]

            for p in POPULATION_SIZES:
                for m in MUTATION_SIZES:
                    for e in ELITE_SIZES:

                        success = 0
                        trials = 0  # Number of tries needed to find 5 'correct' results -- Added by Denis Lazor

                        while success < 5:  # Doing same combination till we get 5 'correct' results -- Added by Denis Lazor
                            trials = trials + 1

                            # Set global variables
                            global stop_evolution
                            global q_min_series
                            global q_max_series
                            global q_avg_series
                            stop_evolution = False
                            q_min_series.clear()
                            q_max_series.clear()
                            q_avg_series.clear()

                            # Set global variables from information on UI
                            global NO_QUEENS
                            global NGEN
                            global POP_SIZE
                            global MUTPB
                            global NELT
                            NO_QUEENS = b
                            NGEN = n
                            POP_SIZE = p
                            MUTPB = m
                            NELT = e

                            # Painting chess table
                            self.img = QPixmap(1000, 1000)
                            self.img.fill()
                            painter = QPainter(self.img)
                            painter.setPen(QPen(Qt.black, 10, Qt.SolidLine))
                            width = 1000 / NO_QUEENS
                            cur_width = 0
                            for i in range(
                                    NO_QUEENS + 1
                            ):  # +1 in order to draw the last line as well
                                painter.drawLine(cur_width, 0, cur_width, 1000)
                                painter.drawLine(0, cur_width, 1000, cur_width)
                                cur_width += width
                            painter.end()
                            self.frameWorld.img = self.img
                            # Redrawing frames
                            self.frameWorld.repaint()
                            app.processEvents()

                            ####Initialize deap GA objects####

                            # Make creator that minimize. If it would be 1.0 instead od -1.0 than it would be maxmize
                            creator.create("FitnessMin",
                                           base.Fitness,
                                           weights=(-1.0, ))

                            # Create an individual (a blueprint for cromosomes) as a list with a specified fitness type
                            creator.create("Individual",
                                           list,
                                           fitness=creator.FitnessMin)

                            # Create base toolbox for finishing creation of a individual (cromosome)
                            self.toolbox = base.Toolbox()

                            # Define what type of data (number, gene) will it be in the cromosome
                            if self.cbxPermutation.isChecked():
                                # Permutation coding
                                self.toolbox.register("indices", random.sample,
                                                      range(NO_QUEENS),
                                                      NO_QUEENS)
                                # initIterate requires that the generator of genes (such as random.sample) generates an iterable (a list) variable
                                self.toolbox.register("individual",
                                                      tools.initIterate,
                                                      creator.Individual,
                                                      self.toolbox.indices)
                            else:
                                # Standard coding
                                self.toolbox.register(
                                    "attr_int", random.randint, 0,
                                    NO_QUEENS - 1
                                )  # number in cromosome is from 0 till IND_SIZE - 1
                                # Initialization procedure (initRepeat) for the cromosome. For the individual to be completed we need to run initRepeat for the amaout of genes the cromosome includes
                                self.toolbox.register("individual",
                                                      tools.initRepeat,
                                                      creator.Individual,
                                                      self.toolbox.attr_int,
                                                      n=NO_QUEENS)

                            # Create a population of individuals (cromosomes). The population is then created by toolbox.population(n=300) where 'n' is the number of cromosomes in population
                            self.toolbox.register("population",
                                                  tools.initRepeat, list,
                                                  self.toolbox.individual)

                            # Register evaluation function
                            self.toolbox.register("evaluate", evaluateInd)

                            # Register what genetic operators to use
                            if self.cbxPermutation.isChecked():
                                # Permutation coding
                                self.toolbox.register(
                                    "mate",
                                    tools.cxUniformPartialyMatched,
                                    indpb=0.2
                                )  # Use uniform recombination for permutation coding
                                self.toolbox.register("mutate",
                                                      tools.mutShuffleIndexes,
                                                      indpb=0.2)
                            else:
                                # Standard coding
                                self.toolbox.register(
                                    "mate", tools.cxTwoPoint
                                )  # Use two point recombination
                                self.toolbox.register(
                                    "mutate",
                                    tools.mutUniformInt,
                                    low=0,
                                    up=NO_QUEENS - 1,
                                    indpb=0.2)  # 20% that the gene will change

                            self.toolbox.register(
                                "select", tools.selTournament,
                                tournsize=3)  # Use tournament selection

                            ##################################

                            # Generate initial poplation. Will be a member variable so we can easely pass everything to new thread
                            self.pop = self.toolbox.population(n=POP_SIZE)

                            # Evaluate initial population, we map() the evaluation function to every individual and then assign their respective fitness, map runs evaluate function for each individual in pop
                            fitnesses = list(
                                map(self.toolbox.evaluate, self.pop))
                            for ind, fit in zip(self.pop, fitnesses):
                                ind.fitness.values = fit  # Assign calcualted fitness value to individuals

                            # Extracting all the fitnesses of all individuals in a population so we can monitor and evovlve the algorithm until it reaches 0 or max number of generation is reached
                            self.fits = [
                                ind.fitness.values[0] for ind in self.pop
                            ]

                            self.fits

                            # Disable start and enable stop
                            self.btnStart.setEnabled(False)
                            self.btnStop.setEnabled(True)
                            self.gaParams.setEnabled(False)
                            self.tbxNoQueens.setEnabled(False)
                            self.cbxNoVis.setEnabled(False)

                            # Start evolution
                            self.evolve()

                        # Mean number of generations nedeed for finding 5 correct solutions -- Added by Denis Lazor
                        mean_gen = min(generations,
                                       key=lambda x: abs(x - statistics.mean(
                                           generations)))
                        # Index of mean_gen value -- Added by Denis Lazor
                        mean_idx = generations.index(mean_gen)

                        write_to_file(
                            combination_series[mean_idx], parameter_name,
                            permutation_checked
                        )  # First name will be "original", second one "elites" -- Added by Denis Lazor
                        parameter_name = "elites"

                        print_results(b, p, m, e, trials, generations,
                                      mean_gen, NGEN)

                        # Clearing past lists  -- Added by Denis Lazor
                        generations = []
                        combination_series = []

                    # Reducing number of combinations and changing .csv file for writing -- Added by Denis Lazor
                    ELITE_SIZES = ELITE_SIZES[0:1]
                    parameter_name = "mutation"
                MUTATION_SIZES = MUTATION_SIZES[0:1]
                parameter_name = "population"
            POPULATION_SIZES = POPULATION_SIZES[0:1]
            parameter_name = "original"

            n = 30000  # Increasing generation size for 24x24 board

    def btnStop_Click(self):
        global stop_evolution
        stop_evolution = True
        #Disable stop and enable start
        self.btnStop.setEnabled(False)
        self.btnStart.setEnabled(True)
        self.gaParams.setEnabled(True)
        self.tbxNoQueens.setEnabled(True)
        self.cbxNoVis.setEnabled(True)

    #Function for GA evolution
    def evolve(self):
        global q_min_series
        global q_max_series
        global q_avg_series
        global success
        global generations
        global combination_series
        global NO_QUEENS
        global NGEN
        global POP_SIZE
        global MUTPB
        global NELT

        combination_current_series = []

        # Variable for keeping track of the number of generations
        curr_g = 0

        # Begin the evolution till goal is reached or max number of generation is reached
        while min(self.fits) != 0 and curr_g < NGEN:
            #Check if evolution and thread need to stop
            if stop_evolution:
                break  #Break the evolution loop

            # A new generation
            curr_g = curr_g + 1
            #print("-- Generation %i --" % curr_g)

            # Select the next generation individuals
            #Select POP_SIZE - NELT number of individuals. Since recombination is between neigbours, not two naighbours should be the clone of the same individual
            offspring = []
            offspring.append(self.toolbox.select(
                self.pop, 1)[0])  #add first selected individual
            for i in range(
                    POP_SIZE - NELT - 1
            ):  # -1 because the first seleceted individual is already added
                while True:
                    new_o = self.toolbox.select(self.pop, 1)[0]
                    if new_o != offspring[len(
                            offspring
                    ) - 1]:  #if it is different than the last inserted then add to offspring and break
                        offspring.append(new_o)
                        break

            # Clone the selected individuals because all of the changes are inplace
            offspring = list(map(self.toolbox.clone, offspring))

            # Apply crossover on the selected offspring
            for child1, child2 in zip(offspring[::2], offspring[1::2]):
                self.toolbox.mate(child1, child2)  #inplace recombination
                #Invalidate new children fitness values
                del child1.fitness.values
                del child2.fitness.values

            #Apply mutation on the offspring
            for mutant in offspring:
                if random.random() < MUTPB:
                    self.toolbox.mutate(mutant)
                    del mutant.fitness.values

            #Add elite individuals #Is clonning needed?
            offspring.extend(
                list(map(self.toolbox.clone, tools.selBest(self.pop, NELT))))

            # Evaluate the individuals with an invalid fitness
            invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
            fitnesses = map(self.toolbox.evaluate, invalid_ind)
            for ind, fit in zip(invalid_ind, fitnesses):
                ind.fitness.values = fit

            #print("  Evaluated %i individuals" % len(invalid_ind))

            #Replace population with offspring
            self.pop[:] = offspring

            # Gather all the fitnesses in one list and print the stats
            self.fits = [ind.fitness.values[0] for ind in self.pop]

            length = len(self.pop)
            mean = sum(self.fits) / length
            sum2 = sum(x * x for x in self.fits)
            std = abs(sum2 / length - mean**2)**0.5

            q_min_series.append(curr_g, min(self.fits))
            q_max_series.append(curr_g, max(self.fits))
            q_avg_series.append(curr_g, mean)

            combination_current_series.append(
                min(self.fits)
            )  # Saving min_series fitness values of an experiment -- Added by Denis Lazor

            # Checking if fitness value of 0 is reached -- Added by Denis Lazor
            for f in self.fits:
                if f == 0:
                    success = success + 1
                    generations.append(curr_g)
                    combination_series.append(combination_current_series)
                    break

            #print("  Min %s" % q_min_series.at(q_min_series.count()-1).y())
            #print("  Max %s" % q_max_series.at(q_max_series.count()-1).y())
            #print("  Avg %s" % mean)
            #print("  Std %s" % std)

            if self.cbxNoVis.isChecked():
                app.processEvents()
            else:
                #Draw queen positions of best individual on a image
                best_ind = tools.selBest(self.pop, 1)[0]
                self.updateWorldFrame(generateQueenImage(best_ind))

                self.chart = QChart()
                #self.chart.addSeries(q_min_series)
                #self.chart.addSeries(q_max_series)
                #q_avg_series.setName("Board: " + str(b) + " Population: " + str(p) + " Elite: " + str(e) + " Mutation:" + str(m*100) + "% " + "Generations:" + str(NGSEN))
                self.chart.addSeries(q_avg_series)
                self.chart.setTitle("QN: " + str(NO_QUEENS) + " POP: " +
                                    str(POP_SIZE) + " EL: " + str(NELT) +
                                    " MT: " + str(MUTPB * 100) + "% ")
                self.chart.setAnimationOptions(QChart.NoAnimation)
                self.chart.createDefaultAxes()
                self.frameChart.setChart(self.chart)

        #Printing best individual
        best_ind = tools.selBest(self.pop, 1)[0]
        #print("Best individual is %s, %s \n" % (best_ind, best_ind.fitness.values))

        #Visulaize final solution
        if self.cbxNoVis.isChecked():
            #Draw queen positions of best individual on a image
            best_ind = tools.selBest(self.pop, 1)[0]
            self.updateWorldFrame(generateQueenImage(best_ind))

            self.chart = QChart()
            #self.chart.addSeries(q_min_series)
            #self.chart.addSeries(q_max_series)
            self.chart.addSeries(q_avg_series)
            self.chart.setTitle("QN: " + str(NO_QUEENS) + " POP: " +
                                str(POP_SIZE) + " EL: " + str(NELT) + " MT: " +
                                str(MUTPB * 100) + "% ")
            self.chart.setAnimationOptions(QChart.NoAnimation)
            self.chart.createDefaultAxes()
            self.frameChart.setChart(self.chart)

        #Disable stop and enable start
        self.btnStop.setEnabled(False)
        self.btnStart.setEnabled(True)
        self.gaParams.setEnabled(True)
        self.tbxNoQueens.setEnabled(True)
        self.cbxNoVis.setEnabled(True)

    def updateWorldFrame(self, queens_img):
        #new_image = QPixmap(1000,1000)
        self.new_image.fill()  #White color is default
        painter = QPainter(self.new_image)
        #First draw the table
        painter.drawPixmap(self.new_image.rect(), self.img)
        #Then draw the queens
        painter.drawImage(self.new_image.rect(), queens_img)
        painter.end()
        #Set new image to the frame
        self.frameWorld.img = self.new_image
        #Redrawing frames
        self.frameWorld.repaint()
        self.frameChart.repaint()
        app.processEvents()

    def btnSaveWorld_Click(self):
        filename, _ = QFileDialog.getSaveFileName(None,
                                                  "Save world as a image", "",
                                                  "Image Files (*.png)")
        self.frameWorld.img.save(filename, "PNG")
        print("World image saved to: ", filename)

    def btnSaveChart_CLick(self):
        p = self.frameChart.grab()
        filename, _ = QFileDialog.getSaveFileName(
            None, "Save series chart as a image", "", "Image Files (*.png)")
        p.save(filename, "PNG")
        print("Chart series image saved to: ", filename)

    def btnSaveChartSeries_Click(self):
        global q_min_series
        global q_max_series
        global q_avg_series
        filename, _ = QFileDialog.getSaveFileName(None,
                                                  "Save series to text file",
                                                  "",
                                                  "Text Files (*.txt, *.csv)")
        with open(filename, 'w') as dat:
            for i in range(q_min_series.count()):
                dat.write('%f,%f,%f\n' %
                          (q_min_series.at(i).y(), q_avg_series.at(i).y(),
                           q_max_series.at(i).y()))
        print("Chart series saved to: ", filename)
class Ui_MainWindow(QtWidgets.QMainWindow):
    def setupUi(self):
        self.setObjectName("MainWindow")
        self.resize(850, 550)
        self.setWindowTitle("Rastrigin")
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")

        self.frameChart = QChartView(self.centralwidget)
        self.frameChart.setGeometry(QtCore.QRect(10, 10, 620, 500))
        self.frameChart.setFrameShape(QtWidgets.QFrame.Box)
        self.frameChart.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frameChart.setRenderHint(QPainter.Antialiasing)
        self.frameChart.setObjectName("frameChart")

        self.genParams = QtWidgets.QGroupBox(self.centralwidget)
        self.genParams.setGeometry(QtCore.QRect(650, 10, 161, 110))
        self.genParams.setObjectName("genParams")
        self.genParams.setTitle("General parameters")

        self.label1 = QtWidgets.QLabel(self.genParams)
        self.label1.setGeometry(QtCore.QRect(10, 20, 61, 16))
        self.label1.setObjectName("label1")
        self.label1.setText("Population:")

        self.label2 = QtWidgets.QLabel(self.genParams)
        self.label2.setGeometry(QtCore.QRect(10, 50, 91, 16))
        self.label2.setObjectName("label2")
        self.label2.setText("No. generations:")

        self.label3 = QtWidgets.QLabel(self.genParams)
        self.label3.setGeometry(QtCore.QRect(10, 80, 81, 16))
        self.label3.setObjectName("label3")
        self.label3.setText("No. dimensions:")

        self.tbxPopulation = QtWidgets.QLineEdit(self.genParams)
        self.tbxPopulation.setGeometry(QtCore.QRect(100, 20, 51, 20))
        self.tbxPopulation.setObjectName("tbxPopulation")

        self.tbxGenerations = QtWidgets.QLineEdit(self.genParams)
        self.tbxGenerations.setGeometry(QtCore.QRect(100, 50, 51, 20))
        self.tbxGenerations.setObjectName("tbxGenerations")

        self.tbxDimensions = QtWidgets.QLineEdit(self.genParams)
        self.tbxDimensions.setGeometry(QtCore.QRect(100, 80, 51, 20))
        self.tbxDimensions.setObjectName("tbxDimensions")

        self.gaParams = QtWidgets.QGroupBox(self.centralwidget)
        self.gaParams.setGeometry(QtCore.QRect(650, 130, 191, 105))
        self.gaParams.setObjectName("gaParams")
        self.gaParams.setTitle("GA parameters")

        self.label4 = QtWidgets.QLabel(self.gaParams)
        self.label4.setGeometry(QtCore.QRect(10, 20, 61, 16))
        self.label4.setObjectName("label4")
        self.label4.setText("Mutation:")

        self.label5 = QtWidgets.QLabel(self.gaParams)
        self.label5.setGeometry(QtCore.QRect(10, 50, 91, 16))
        self.label5.setObjectName("label5")
        self.label5.setText("Elite members:")

        self.label9 = QtWidgets.QLabel(self.gaParams)
        self.label9.setGeometry(QtCore.QRect(10, 80, 61, 16))
        self.label9.setObjectName("label9")
        self.label9.setText("Max abs.:")

        self.tbxMutation = QtWidgets.QLineEdit(self.gaParams)
        self.tbxMutation.setGeometry(QtCore.QRect(100, 20, 51, 20))
        self.tbxMutation.setObjectName("tbxMutation")

        self.tbxElite = QtWidgets.QLineEdit(self.gaParams)
        self.tbxElite.setGeometry(QtCore.QRect(100, 50, 51, 20))
        self.tbxElite.setObjectName("tbxElite")

        self.tbxMaxAbs = QtWidgets.QLineEdit(self.gaParams)
        self.tbxMaxAbs.setGeometry(QtCore.QRect(100, 80, 51, 20))
        self.tbxMaxAbs.setObjectName("tbxMAxAbs")

        self.psoParams = QtWidgets.QGroupBox(self.centralwidget)
        self.psoParams.setGeometry(QtCore.QRect(650, 240, 161, 110))
        self.psoParams.setObjectName("psoParams")
        self.psoParams.setTitle("PSO parameters")

        self.label6 = QtWidgets.QLabel(self.psoParams)
        self.label6.setGeometry(QtCore.QRect(10, 20, 61, 16))
        self.label6.setObjectName("label6")
        self.label6.setText("Inertia factor:")

        self.label7 = QtWidgets.QLabel(self.psoParams)
        self.label7.setGeometry(QtCore.QRect(10, 50, 91, 16))
        self.label7.setObjectName("label7")
        self.label7.setText("Personal factor:")

        self.label8 = QtWidgets.QLabel(self.psoParams)
        self.label8.setGeometry(QtCore.QRect(10, 80, 81, 16))
        self.label8.setObjectName("label8")
        self.label8.setText("Social factor:")

        self.tbxInertia = QtWidgets.QLineEdit(self.psoParams)
        self.tbxInertia.setGeometry(QtCore.QRect(100, 20, 51, 20))
        self.tbxInertia.setObjectName("tbxInertia")

        self.tbxPersonal = QtWidgets.QLineEdit(self.psoParams)
        self.tbxPersonal.setGeometry(QtCore.QRect(100, 50, 51, 20))
        self.tbxPersonal.setObjectName("tbxPersonal")

        self.tbxSocial = QtWidgets.QLineEdit(self.psoParams)
        self.tbxSocial.setGeometry(QtCore.QRect(100, 80, 51, 20))
        self.tbxSocial.setObjectName("tbxSocial")

        self.cbxNoVis = QtWidgets.QCheckBox(self.centralwidget)
        self.cbxNoVis.setGeometry(QtCore.QRect(650, 350, 170, 17))
        self.cbxNoVis.setObjectName("cbxNoVis")
        self.cbxNoVis.setText("No visualization per generation")

        self.btnStartGA = QtWidgets.QPushButton(self.centralwidget)
        self.btnStartGA.setGeometry(QtCore.QRect(650, 370, 75, 23))
        self.btnStartGA.setObjectName("btnStartGA")
        self.btnStartGA.setText("Start GA")

        self.btnStartPSO = QtWidgets.QPushButton(self.centralwidget)
        self.btnStartPSO.setGeometry(QtCore.QRect(650, 400, 75, 23))
        self.btnStartPSO.setObjectName("btnStartPSO")
        self.btnStartPSO.setText("Start PSO")

        self.btnStop = QtWidgets.QPushButton(self.centralwidget)
        self.btnStop.setEnabled(False)
        self.btnStop.setGeometry(QtCore.QRect(740, 370, 75, 53))
        self.btnStop.setObjectName("btnStop")
        self.btnStop.setText("Stop")

        self.btnSaveChart = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveChart.setGeometry(QtCore.QRect(650, 450, 121, 41))
        self.btnSaveChart.setObjectName("btnSaveChart")
        self.btnSaveChart.setText("Save chart as image")

        self.btnSaveChartSeries = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveChartSeries.setGeometry(QtCore.QRect(650, 500, 121, 41))
        self.btnSaveChartSeries.setObjectName("btnSaveChartSeries")
        self.btnSaveChartSeries.setText("Save chart as series")

        self.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(self)

        #Connect events
        self.btnStartGA.clicked.connect(self.btnStartGA_Click)
        self.btnStartPSO.clicked.connect(self.btnStartPSO_Click)
        self.btnStop.clicked.connect(self.btnStop_Click)
        self.btnSaveChart.clicked.connect(self.btnSaveChart_CLick)
        self.btnSaveChartSeries.clicked.connect(self.btnSaveChartSeries_Click)

        #Set default variables
        self.tbxGenerations.insert(str(NGEN))
        self.tbxPopulation.insert(str(POP_SIZE))
        self.tbxDimensions.insert(str(NO_DIMS))
        self.tbxMutation.insert(str(GA_MUTPB))
        self.tbxElite.insert(str(GA_NELT))
        self.tbxMaxAbs.insert(str(GA_MAX_ABS))
        self.tbxInertia.insert(str(PSO_INERTIA))
        self.tbxPersonal.insert(str(PSO_PERSONAL))
        self.tbxSocial.insert(str(PSO_SOCIAL))

    def btnStartGA_Click(self):

        global combination_series  # List of lists containing min_series of 5   results -- Added by Denis Lazor
        global parameter_name  # Name of parameter used for writing its data to .csv file -- Added by Denis Lazor
        global best_fit_values  # List containing best fitness values for every of 5 experiments per combination -- Added by Denis Lazor

        global DIM_SIZES
        global ELITE_SIZES
        global MAX_ABS_SIZES
        global MUTATION_SIZES

        # Checking if files are empty or not -- Added by Denis Lazor
        csv_contains_ga = os.stat("graphs_csv/original_ga.csv").st_size != 0

        # Clearing non empty files if we are trying to write to them -- Added by Denis Lazor
        if csv_contains_ga:
            clear_all_csv("ga")

        parameter_name = "original"
        n = 5000
        print("GA:\n")

        # Automation for all necessary combinations -- Added by Denis Lazor
        for d in DIM_SIZES:
            MUTATION_SIZES = [0.05, 0.1, 0.2]
            ELITE_SIZES = [4, 8, 16]
            MAX_ABS_SIZES = [0.4]

            for m in MUTATION_SIZES:
                for e in ELITE_SIZES:
                    for ma in MAX_ABS_SIZES:

                        for i in range(5):
                            # Set global variables
                            global stop_evolution
                            global q_min_series
                            global q_max_series
                            global q_avg_series
                            stop_evolution = False
                            q_min_series.clear()
                            q_max_series.clear()
                            q_avg_series.clear()

                            # Set global variables from information on UI
                            global NGEN
                            global POP_SIZE
                            global GA_MUTPB
                            global GA_NELT
                            global GA_MAX_ABS
                            NGEN = int(self.tbxGenerations.text())
                            POP_SIZE = int(self.tbxPopulation.text())
                            GA_MUTPB = m
                            GA_NELT = e
                            GA_MAX_ABS = ma

                            ####Initialize deap GA objects####

                            # Make creator that minimize. If it would be 1.0 instead od -1.0 than it would be maxmize
                            self.creator = creator
                            self.creator.create("FitnessMin",
                                                base.Fitness,
                                                weights=(-1.0, ))

                            # Create an individual (a blueprint for cromosomes) as a list with a specified fitness type
                            self.creator.create(
                                "Individual",
                                list,
                                fitness=self.creator.FitnessMin)

                            # Create base toolbox for finishing creation of a individual (cromosome)
                            self.toolbox = base.Toolbox()

                            # Define what type of data (number, gene) will it be in the cromosome
                            self.toolbox.register("attr_float", random.uniform,
                                                  F_MIN, F_MAX)
                            # Initialization procedure (initRepeat) for the cromosome. For the individual to be completed we need to run initRepeat for the amaout of genes the cromosome includes
                            self.toolbox.register("individual",
                                                  tools.initRepeat,
                                                  self.creator.Individual,
                                                  self.toolbox.attr_float,
                                                  n=NO_DIMS)

                            # Create a population of individuals (cromosomes). The population is then created by toolbox.population(n=300) where 'n' is the number of cromosomes in population
                            self.toolbox.register("population",
                                                  tools.initRepeat, list,
                                                  self.toolbox.individual)

                            # Register evaluation function
                            self.toolbox.register("evaluate", evaluateInd)

                            # Register what genetic operators to use
                            # Standard coding
                            self.toolbox.register(
                                "mate", tools.cxTwoPoint
                            )  # Use two point recombination
                            self.toolbox.register("mutate",
                                                  tools.mutGaussian,
                                                  mu=0,
                                                  sigma=GA_MAX_ABS,
                                                  indpb=0.5)

                            self.toolbox.register(
                                "select", tools.selTournament,
                                tournsize=3)  # Use tournament selection

                            ##################################

                            # Generate initial poplation. Will be a member variable so we can easely pass everything to new thread
                            self.pop = self.toolbox.population(n=POP_SIZE)

                            # Evaluate initial population, we map() the evaluation function to every individual and then assign their respective fitness, map runs evaluate function for each individual in pop
                            fitnesses = list(
                                map(self.toolbox.evaluate, self.pop))
                            for ind, fit in zip(self.pop, fitnesses):
                                ind.fitness.values = fit  # Assign calcualted fitness value to individuals

                            # Extracting all the fitnesses of all individuals in a population so we can monitor and evovlve the algorithm until it reaches 0 or max number of generation is reached
                            self.fits = [
                                ind.fitness.values[0] for ind in self.pop
                            ]

                            # Disable start and enable stop
                            self.btnStartGA.setEnabled(False)
                            self.btnStartPSO.setEnabled(False)
                            self.btnStop.setEnabled(False)
                            self.genParams.setEnabled(False)
                            self.gaParams.setEnabled(False)
                            self.psoParams.setEnabled(False)
                            self.cbxNoVis.setEnabled(False)

                            # Start evolution
                            self.evolveGA()

                        # Best fitness value -- Added by Denis Lazor

                        best_fit = np.array(min(best_fit_values))[0]
                        mean_fit = np.array(
                            min(best_fit_values,
                                key=lambda x: abs(x - statistics.mean(
                                    np.asarray(best_fit_values).flatten())))
                        )[0]

                        # Index of best fitness value -- Added by Denis Lazor
                        mean_fit_idx = best_fit_values.index(mean_fit)

                        write_to_file(combination_series[mean_fit_idx],
                                      parameter_name, "ga")

                        # First name will be "original", second one "max_abs" -- Added by Denis Lazor
                        parameter_name = "max_abs"

                        print_results_GA(POP_SIZE, m, e, ma, mean_fit,
                                         best_fit, NGEN, d)

                        # Clearing past lists  -- Added by Denis Lazor
                        combination_series = []
                        best_fit_values = []

                    # Reducing number of combinations and changing .csv file for writing -- Added by Denis Lazor
                    MAX_ABS_SIZES = MAX_ABS_SIZES[0:1]
                    parameter_name = "elites"

                ELITE_SIZES = ELITE_SIZES[0:1]
                parameter_name = "mutation"

            MUTATION_SIZES = MUTATION_SIZES[0:1]
            parameter_name = "original"

    def btnStartPSO_Click(self):
        global combination_series  # List of lists containing min_series of 5   results -- Added by Denis Lazor
        global parameter_name  # Name of parameter used for writing its data to .csv file -- Added by Denis Lazor
        global best_fit_values  # List containing best fitness values for every of 5 experiments per combination -- Added by Denis Lazor

        global DIM_SIZES
        global INERTIA_SIZES
        global PERSONAL_F_SIZES
        global SOCIAL_F_SIZES

        # Checking if files are empty or not -- Added by Denis Lazor
        csv_contains_pso = os.stat("graphs_csv/original_pso.csv").st_size != 0

        # Clearing non empty files if we are trying to write to them -- Added by Denis Lazor
        if csv_contains_pso:
            clear_all_csv("pso")

        n = 5000
        parameter_name = "original"
        print("PSO:\n")

        # Automation for all necessary combinations -- Added by Denis Lazor
        for d in DIM_SIZES:
            INERTIA_SIZES = [0.0, 0.37, 0.74]
            PERSONAL_F_SIZES = [0.5, 1.0, 1.5]
            SOCIAL_F_SIZES = [0.5, 1.0, 1.5]

            for in_f in INERTIA_SIZES:
                for pers_f in PERSONAL_F_SIZES:
                    for soc_f in SOCIAL_F_SIZES:

                        for i in range(5):
                            # Set global variables
                            global stop_evolution
                            global q_min_series
                            global q_max_series

                            global q_avg_series
                            stop_evolution = False
                            q_min_series.clear()
                            q_max_series.clear()
                            q_avg_series.clear()

                            # Set global variables from information on UI
                            global NGEN
                            global POP_SIZE
                            global PSO_INERTIA
                            global PSO_PERSONAL
                            global PSO_SOCIAL
                            NGEN = int(self.tbxGenerations.text())
                            POP_SIZE = int(self.tbxPopulation.text())
                            PSO_INERTIA = in_f
                            PSO_PERSONAL = pers_f
                            PSO_SOCIAL = soc_f

                            ####Initialize deap PSO objects####

                            # Make creator that minimize. If it would be 1.0 instead od -1.0 than it would be maxmize
                            self.creator = creator
                            self.creator.create("FitnessMin",
                                                base.Fitness,
                                                weights=(-1.0, ))

                            # Create an individual (a blueprint for cromosomes) as a list with a specified fitness type
                            self.creator.create(
                                "Particle",
                                list,
                                fitness=self.creator.FitnessMin,
                                speed=list,
                                best=None)

                            # Create base toolbox for finishing creation of a individual (particle) and population
                            self.toolbox = base.Toolbox()

                            # Particle initialization
                            self.toolbox.register("particle",
                                                  generateParticle,
                                                  cr=self.creator,
                                                  size=NO_DIMS,
                                                  min_val=F_MIN,
                                                  max_val=F_MAX)

                            # Create a population of individuals (particles). The population is then created by e.g. toolbox.population(n=300) where 'n' is the number of particles in population
                            self.toolbox.register("population",
                                                  tools.initRepeat, list,
                                                  self.toolbox.particle)

                            # Update function for each particle
                            self.toolbox.register("update", updateParticle)

                            # Evaluation function for each particle
                            self.toolbox.register("evaluate", evaluateInd)

                            ##################################

                            # Create population
                            self.pop = self.toolbox.population(n=POP_SIZE)

                            # Evaluate initial population, we map() the evaluation function to every individual and then assign their respective fitness, map runs emaluet function for each individual in pop
                            fitnesses = list(
                                map(self.toolbox.evaluate, self.pop))
                            for ind, fit in zip(self.pop, fitnesses):
                                ind.fitness.values = fit

                            # Extracting all the fitnesses of all individuals in a population so we can monitor and evovlve the algorithm until it reaches 0 or max number of generation is reached
                            self.fits = [
                                ind.fitness.values[0] for ind in self.pop
                            ]

                            # Extraction current best position
                            self.global_best_position = tools.selBest(
                                self.pop, 1)[0][:]

                            # Disable start and enable stop
                            self.btnStartGA.setEnabled(False)
                            self.btnStartPSO.setEnabled(False)
                            self.btnStop.setEnabled(False)
                            self.genParams.setEnabled(False)
                            self.gaParams.setEnabled(False)
                            self.psoParams.setEnabled(False)
                            self.cbxNoVis.setEnabled(False)

                            # Start evolution
                            self.evolvePSO()

                        # Best fitness value -- Added by Denis Lazor
                        best_fit = np.array(min(best_fit_values))[0]
                        mean_fit = np.array(
                            min(best_fit_values,
                                key=lambda x: abs(x - statistics.mean(
                                    np.asarray(best_fit_values).flatten())))
                        )[0]

                        # Index of best fitness value -- Added by Denis Lazor
                        mean_fit_idx = best_fit_values.index(mean_fit)

                        write_to_file(combination_series[mean_fit_idx],
                                      parameter_name, "pso")

                        # First name will be "original", second one "social_factor" -- Added by Denis Lazor
                        parameter_name = "social_factor"

                        print_results_PSO(POP_SIZE, in_f, pers_f, soc_f,
                                          mean_fit, best_fit, NGEN, d)

                        # Clearing past lists  -- Added by Denis Lazor
                        print(best_fit_values)
                        combination_series = []
                        best_fit_values = []

                    # Reducing number of combinations and changing .csv file for writing -- Added by Denis Lazor
                    SOCIAL_F_SIZES = SOCIAL_F_SIZES[0:1]
                    parameter_name = "personal_factor"

                PERSONAL_F_SIZES = PERSONAL_F_SIZES[0:1]
                parameter_name = "inertia"

            INERTIA_SIZES = INERTIA_SIZES[0:1]
            parameter_name = "original"

    def btnStop_Click(self):
        global stop_evolution
        stop_evolution = True
        #Disable stop and enable start
        self.btnStartGA.setEnabled(True)
        self.btnStartPSO.setEnabled(True)
        self.btnStop.setEnabled(False)
        self.genParams.setEnabled(True)
        self.gaParams.setEnabled(True)
        self.psoParams.setEnabled(True)
        self.cbxNoVis.setEnabled(True)

    #Function for GA evolution
    def evolveGA(self):
        global q_min_series
        global q_max_series
        global q_avg_series

        global combination_series
        global best_fit_values

        combination_current_series = [
        ]  # Clearing fitness values series -- Added by Denis Lazor

        # Variable for keeping track of the number of generations
        curr_g = 0

        # Begin the evolution till goal is reached or max number of generation is reached
        while min(self.fits) != 0 and curr_g < NGEN:
            #Check if evolution and thread need to stop
            if stop_evolution:
                break  #Break the evolution loop

            # A new generation
            curr_g = curr_g + 1
            # print("-- Generation %i --" % curr_g)

            # Select the next generation individuals
            #Select POP_SIZE - NELT number of individuals. Since recombination is between neigbours, not two naighbours should be the clone of the same individual
            offspring = []
            offspring.append(self.toolbox.select(
                self.pop, 1)[0])  #add first selected individual
            for i in range(
                    POP_SIZE - GA_NELT - 1
            ):  # -1 because the first seleceted individual is already added
                while True:
                    new_o = self.toolbox.select(self.pop, 1)[0]
                    if new_o != offspring[len(
                            offspring
                    ) - 1]:  #if it is different than the last inserted then add to offspring and break
                        offspring.append(new_o)
                        break

            # Clone the selected individuals because all of the changes are inplace
            offspring = list(map(self.toolbox.clone, offspring))

            # Apply crossover on the selected offspring
            for child1, child2 in zip(offspring[::2], offspring[1::2]):
                self.toolbox.mate(child1, child2)  #inplace recombination
                #Invalidate new children fitness values
                del child1.fitness.values
                del child2.fitness.values

            #Apply mutation on the offspring
            for mutant in offspring:
                if random.random() < GA_MUTPB:
                    self.toolbox.mutate(mutant)
                    del mutant.fitness.values

            #Add elite individuals #Is clonning needed?
            offspring.extend(
                list(map(self.toolbox.clone, tools.selBest(self.pop,
                                                           GA_NELT))))

            # Evaluate the individuals with an invalid fitness
            invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
            fitnesses = map(self.toolbox.evaluate, invalid_ind)
            for ind, fit in zip(invalid_ind, fitnesses):
                ind.fitness.values = fit

            # print("  Evaluated %i individuals" % len(invalid_ind))

            #Replace population with offspring
            self.pop[:] = offspring

            # Gather all the fitnesses in one list and print the stats
            self.fits = [ind.fitness.values[0] for ind in self.pop]

            length = len(self.pop)
            mean = sum(self.fits) / length
            sum2 = sum(x * x for x in self.fits)
            std = abs(sum2 / length - mean**2)**0.5

            q_min_series.append(curr_g, min(self.fits))
            q_max_series.append(curr_g, max(self.fits))
            q_avg_series.append(curr_g, mean)

            combination_current_series.append(
                min(self.fits)
            )  # Saving min_series fitness values of an experiment -- Added by Denis Lazor

            # print("  Min %s" % q_min_series.at(q_min_series.count()-1).y())
            # print("  Max %s" % q_max_series.at(q_max_series.count()-1).y())
            # print("  Avg %s" % mean)
            # print("  Std %s" % std)
            #
            if self.cbxNoVis.isChecked():
                app.processEvents()
            else:
                self.chart = QChart()
                self.chart.addSeries(q_min_series)
                self.chart.addSeries(q_max_series)
                self.chart.addSeries(q_avg_series)
                self.chart.setTitle("Fitness value over time")
                self.chart.setAnimationOptions(QChart.NoAnimation)
                self.chart.createDefaultAxes()
                self.frameChart.setChart(self.chart)
                self.frameChart.repaint()
                app.processEvents()

        #Printing best individual
        best_ind = tools.selBest(self.pop, 1)[0]
        # print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values))

        #Visulaize final solution
        if self.cbxNoVis.isChecked():
            self.chart = QChart()
            self.chart.addSeries(q_min_series)
            self.chart.addSeries(q_max_series)
            self.chart.addSeries(q_avg_series)
            self.chart.setTitle("Fitness value over time")
            self.chart.setAnimationOptions(QChart.NoAnimation)
            self.chart.createDefaultAxes()
            self.frameChart.setChart(self.chart)
            self.frameChart.repaint()

        #Disable stop and enable start
        self.btnStartGA.setEnabled(True)
        self.btnStartPSO.setEnabled(True)
        self.btnStop.setEnabled(False)
        self.genParams.setEnabled(True)
        self.gaParams.setEnabled(True)
        self.psoParams.setEnabled(True)
        self.cbxNoVis.setEnabled(True)
        app.processEvents()

        combination_series.append(combination_current_series
                                  )  # Saving 5 results -- Added by Denis Lazor
        best_fit_values.append(
            best_ind.fitness.values
        )  # Adding best fitness value of experiment -- Added by Denis Lazor

    #Function for GA evolution
    def evolvePSO(self):
        global q_min_series
        global q_max_series
        global q_avg_series

        global combination_series
        global best_fit_values

        combination_current_series = [
        ]  # Clearing fitness values series -- Added by Denis Lazor

        # Variable for keeping track of the number of generations
        curr_g = 0

        while min(self.fits) != 0.0 and curr_g < NGEN:
            #Check if evolution and thread need to stop
            if stop_evolution:
                break  #Break the evolution loop

            # A new generation
            curr_g = curr_g + 1
            # print("-- Generation %i --" % curr_g)

            #Update particle position and evaluate particle
            for particle in self.pop:
                #Update
                self.toolbox.update(particle, self.global_best_position,
                                    PSO_INERTIA, PSO_PERSONAL, PSO_SOCIAL)
                #Evaluate
                fit = self.toolbox.evaluate(particle)
                #Update best position
                if fit[0] < particle.fitness.values[0]:
                    particle.best = particle[:]
                #Update fitness
                particle.fitness.values = fit

            #Extracting all the fitnesses of all individuals in a population so we can monitor and evovlve the algorithm until it reaches 0 or max number of generation is reached
            self.fits = [ind.fitness.values[0] for ind in self.pop]

            #Extraction current best position
            self.global_best_position = tools.selBest(self.pop, 1)[0][:]

            #Stats
            length = len(self.pop)
            mean = sum(self.fits) / length
            sum2 = sum(x * x for x in self.fits)
            std = abs(sum2 / length - mean**2)**0.5

            q_min_series.append(curr_g, min(self.fits))
            q_max_series.append(curr_g, max(self.fits))
            q_avg_series.append(curr_g, mean)

            combination_current_series.append(
                min(self.fits)
            )  # Saving min_series fitness values of an experiment -- Added by Denis Lazor

            # print("  Min %s" % q_min_series.at(q_min_series.count()-1).y())
            # print("  Max %s" % q_max_series.at(q_max_series.count()-1).y())
            # print("  Avg %s" % mean)
            # print("  Std %s" % std)
            #
            if self.cbxNoVis.isChecked():
                app.processEvents()
            else:
                self.chart = QChart()
                self.chart.addSeries(q_min_series)
                self.chart.addSeries(q_max_series)
                self.chart.addSeries(q_avg_series)
                self.chart.setTitle("Fitness value over time")
                self.chart.setAnimationOptions(QChart.NoAnimation)
                self.chart.createDefaultAxes()
                self.frameChart.setChart(self.chart)
                self.frameChart.repaint()
                app.processEvents()

        #Printing best individual
        best_ind = tools.selBest(self.pop, 1)[0]
        # print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values))

        #Visulaize final solution
        if self.cbxNoVis.isChecked():
            self.chart = QChart()
            self.chart.addSeries(q_min_series)
            self.chart.addSeries(q_max_series)
            self.chart.addSeries(q_avg_series)
            self.chart.setTitle("Fitness value over time")
            self.chart.setAnimationOptions(QChart.NoAnimation)
            self.chart.createDefaultAxes()
            self.frameChart.setChart(self.chart)
            self.frameChart.repaint()

        #Disable stop and enable start
        self.btnStartGA.setEnabled(True)
        self.btnStartPSO.setEnabled(True)
        self.btnStop.setEnabled(False)
        self.genParams.setEnabled(True)
        self.gaParams.setEnabled(True)
        self.psoParams.setEnabled(True)
        self.cbxNoVis.setEnabled(True)
        app.processEvents()

        combination_series.append(combination_current_series
                                  )  # Saving 5 results -- Added by Denis Lazor
        best_fit_values.append(
            best_ind.fitness.values
        )  # Adding best fitness value of experiment -- Added by Denis Lazor

    def btnSaveChart_CLick(self):
        p = self.frameChart.grab()
        filename, _ = QFileDialog.getSaveFileName(
            None, "Save series chart as a image", "", "Image Files (*.png)")
        p.save(filename, "PNG")
        print("Chart series image saved to: ", filename)

    def btnSaveChartSeries_Click(self):
        global q_min_series
        global q_max_series
        global q_avg_series
        filename, _ = QFileDialog.getSaveFileName(None,
                                                  "Save series to text file",
                                                  "",
                                                  "Text Files (*.txt, *.csv)")
        with open(filename, 'w') as dat:
            for i in range(q_min_series.count()):
                dat.write('%f,%f,%f\n' %
                          (q_min_series.at(i).y(), q_avg_series.at(i).y(),
                           q_max_series.at(i).y()))
        print("Chart series saved to: ", filename)
Exemplo n.º 5
0
class Ui_MainWindow(QtWidgets.QMainWindow):
    def setupUi(self):
        self.setObjectName("MainWindow")
        self.resize(850, 1080)
        self.setWindowTitle("GA - Queens")
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")
        self.frameWorld = MyQFrame(self.centralwidget)
        self.frameWorld.img = QPixmap(1000, 1000)
        self.frameWorld.setGeometry(QtCore.QRect(10, 10, 620, 600))
        self.frameWorld.setFrameShape(QtWidgets.QFrame.Box)
        self.frameWorld.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frameWorld.setObjectName("frameWorld")
        self.frameChart = QChartView(self.centralwidget)
        self.frameChart.setGeometry(QtCore.QRect(10, 620, 620, 400))
        self.frameChart.setFrameShape(QtWidgets.QFrame.Box)
        self.frameChart.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frameChart.setRenderHint(QPainter.Antialiasing)
        self.frameChart.setObjectName("frameChart")
        self.gaParams = QtWidgets.QGroupBox(self.centralwidget)
        self.gaParams.setGeometry(QtCore.QRect(650, 10, 161, 145))
        self.gaParams.setObjectName("gaParams")
        self.gaParams.setTitle("GA parameters")
        self.label1 = QtWidgets.QLabel(self.gaParams)
        self.label1.setGeometry(QtCore.QRect(10, 20, 61, 16))
        self.label1.setObjectName("label1")
        self.label1.setText("Population:")
        self.label2 = QtWidgets.QLabel(self.gaParams)
        self.label2.setGeometry(QtCore.QRect(10, 50, 47, 16))
        self.label2.setObjectName("label2")
        self.label2.setText("Mutation:")
        self.label3 = QtWidgets.QLabel(self.gaParams)
        self.label3.setGeometry(QtCore.QRect(10, 80, 81, 16))
        self.label3.setObjectName("label3")
        self.label3.setText("Elite members:")
        self.label4 = QtWidgets.QLabel(self.gaParams)
        self.label4.setGeometry(QtCore.QRect(10, 110, 91, 16))
        self.label4.setObjectName("label4")
        self.label4.setText("No. generations:")
        self.tbxPopulation = QtWidgets.QLineEdit(self.gaParams)
        self.tbxPopulation.setGeometry(QtCore.QRect(100, 20, 51, 20))
        self.tbxPopulation.setObjectName("tbxPopulation")
        self.tbxMutation = QtWidgets.QLineEdit(self.gaParams)
        self.tbxMutation.setGeometry(QtCore.QRect(100, 50, 51, 20))
        self.tbxMutation.setObjectName("tbxMutation")
        self.tbxElite = QtWidgets.QLineEdit(self.gaParams)
        self.tbxElite.setGeometry(QtCore.QRect(100, 80, 51, 20))
        self.tbxElite.setObjectName("tbxElite")
        self.tbxGenerations = QtWidgets.QLineEdit(self.gaParams)
        self.tbxGenerations.setGeometry(QtCore.QRect(100, 110, 51, 20))
        self.tbxGenerations.setObjectName("tbxGenerations")
        self.cbxNoVis = QtWidgets.QCheckBox(self.centralwidget)
        self.cbxNoVis.setGeometry(QtCore.QRect(650, 170, 170, 17))
        self.cbxNoVis.setObjectName("cbxNoVis")
        self.cbxNoVis.setText("No visualization per generation")
        self.cbxBorder = QtWidgets.QCheckBox(self.centralwidget)
        self.cbxBorder.setGeometry(QtCore.QRect(650, 200, 100, 17))
        self.cbxBorder.setObjectName("cbxBorder")
        self.cbxBorder.setText("Border patrol")
        self.btnStart = QtWidgets.QPushButton(self.centralwidget)
        self.btnStart.setGeometry(QtCore.QRect(650, 230, 75, 23))
        self.btnStart.setObjectName("btnStart")
        self.btnStart.setText("Start")
        self.btnStop = QtWidgets.QPushButton(self.centralwidget)
        self.btnStop.setEnabled(False)
        self.btnStop.setGeometry(QtCore.QRect(730, 230, 75, 23))
        self.btnStop.setObjectName("btnStop")
        self.btnStop.setText("Stop")
        self.btnSaveWorld = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveWorld.setGeometry(QtCore.QRect(650, 570, 121, 41))
        self.btnSaveWorld.setObjectName("btnSaveWorld")
        self.btnSaveWorld.setText("Save world as image")
        self.btnSaveChart = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveChart.setGeometry(QtCore.QRect(650, 930, 121, 41))
        self.btnSaveChart.setObjectName("btnSaveChart")
        self.btnSaveChart.setText("Save chart as image")
        self.btnSaveChartSeries = QtWidgets.QPushButton(self.centralwidget)
        self.btnSaveChartSeries.setGeometry(QtCore.QRect(650, 980, 121, 41))
        self.btnSaveChartSeries.setObjectName("btnSaveChartSeries")
        self.btnSaveChartSeries.setText("Save chart as series")
        self.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(self)

        #Connect events
        self.btnStart.clicked.connect(self.btnStart_Click)
        self.btnStop.clicked.connect(self.btnStop_Click)
        self.btnSaveWorld.clicked.connect(self.btnSaveWorld_Click)
        self.btnSaveChart.clicked.connect(self.btnSaveChart_CLick)
        self.btnSaveChartSeries.clicked.connect(self.btnSaveChartSeries_Click)

        #Set default GA variables
        self.tbxGenerations.insert(str(NGEN))
        self.tbxPopulation.insert(str(POP_SIZE))
        self.tbxMutation.insert(str(MUTPB))
        self.tbxElite.insert(str(NELT))

        self.new_image = QPixmap(1000, 1000)

    def btnStart_Click(self):

        global combination_series  # List of lists containing min_series of 5 correct results -- Added by Denis Lazor
        global parameter_name  # Name of parameter used for writing its data to .csv file -- Added by Denis Lazor
        global best_fit_values  # List containing best fitness values for every of 5 experiments per combination -- Added by Denis Lazor
        global best_individual  # Saving best individuals for drawing the best solution -- Added by Denis Lazor

        global ELITE_SIZES
        global POPULATION_SIZES
        global MUTATION_SIZES

        # Checking if files are empty or not -- Added by Denis Lazor
        csv_contains = os.stat("graphs_csv/original.csv").st_size != 0

        if csv_contains:
            clear_all_csv()

        n = 5000
        # Automation for all necessary combinations -- Added by Denis Lazor

        for p in POPULATION_SIZES:
            for m in MUTATION_SIZES:
                for e in ELITE_SIZES:
                    for i in range(5):

                        # Set global variables
                        global stop_evolution
                        global q_min_series
                        global q_max_series
                        global q_avg_series
                        stop_evolution = False
                        q_min_series.clear()
                        q_max_series.clear()
                        q_avg_series.clear()

                        # Set global variables from information on UI
                        global NGEN
                        global POP_SIZE
                        global MUTPB
                        global NELT
                        NGEN = n
                        POP_SIZE = p
                        MUTPB = m
                        NELT = e
                        global border_check
                        border_check = self.cbxBorder.isChecked()

                        # Loading Croatia map
                        self.img = QPixmap(620, 600)
                        self.img.load('Croatia620.png')
                        self.frameWorld.img = self.img
                        # Drawing towns
                        painter = QPainter(self.img)
                        painter.setPen(QPen(Qt.black, 10, Qt.SolidLine))
                        painter.setFont(QFont('Arial', 12))
                        for i in range(len(gradovi)):
                            x, y = GlobToImgCoords(sirine[i], duzine[i])
                            painter.drawPoint(x, y)
                            painter.drawText(x + 5, y + 5, gradovi[i])

                        painter.end()
                        # Redrawing frames
                        self.frameWorld.repaint()
                        app.processEvents()

                        ####Initialize deap GA objects####

                        # Make creator that minimize. If it would be 1.0 instead od -1.0 than it would be maxmize
                        creator.create("FitnessMin",
                                       base.Fitness,
                                       weights=(-1.0, ))

                        # Create an individual (a blueprint for cromosomes) as a list with a specified fitness type
                        creator.create("Individual",
                                       list,
                                       fitness=creator.FitnessMin)

                        # Create base toolbox for finishing creation of a individual (cromosome)
                        self.toolbox = base.Toolbox()

                        # This is if we want a permutation coding of genes in the cromosome
                        self.toolbox.register("indices", random.sample,
                                              range(IND_SIZE), IND_SIZE)

                        # initIterate requires that the generator of genes (such as random.sample) generates an iterable (a list) variable
                        self.toolbox.register("individual", tools.initIterate,
                                              creator.Individual,
                                              self.toolbox.indices)

                        # Create a population of individuals (cromosomes). The population is then created by toolbox.population(n=300) where 'n' is the number of cromosomes in population
                        self.toolbox.register("population", tools.initRepeat,
                                              list, self.toolbox.individual)

                        # Register evaluation function
                        self.toolbox.register("evaluate", evaluateInd)

                        # Register what genetic operators to use
                        self.toolbox.register(
                            "mate", tools.cxUniformPartialyMatched, indpb=0.2
                        )  # Use uniform recombination for permutation coding

                        # Permutation coding
                        self.toolbox.register("mutate",
                                              tools.mutShuffleIndexes,
                                              indpb=0.2)

                        self.toolbox.register(
                            "select", tools.selTournament,
                            tournsize=3)  # Use tournament selection

                        ##################################

                        # Generate initial poplation. Will be a member variable so we can easely pass everything to new thread
                        self.pop = self.toolbox.population(n=POP_SIZE)

                        # Evaluate initial population, we map() the evaluation function to every individual and then assign their respective fitness, map runs evaluate function for each individual in pop
                        fitnesses = list(map(self.toolbox.evaluate, self.pop))
                        for ind, fit in zip(self.pop, fitnesses):
                            ind.fitness.values = fit  # Assign calcualted fitness value to individuals

                        # Extracting all the fitnesses of all individuals in a population so we can monitor and evovlve the algorithm until it reaches 0 or max number of generation is reached
                        self.fits = [ind.fitness.values[0] for ind in self.pop]

                        # Disable start and enable stop
                        self.btnStart.setEnabled(False)
                        self.btnStop.setEnabled(True)
                        self.gaParams.setEnabled(False)
                        self.cbxBorder.setEnabled(False)
                        self.cbxNoVis.setEnabled(False)

                        # Start evolution
                        self.evolve()

                    # Best fitness value -- Added by Denis Lazor
                    best_fit = np.array(min(best_fit_values))[0]
                    mean_fit = min(
                        best_fit_values,
                        key=lambda x: abs(x - statistics.mean(
                            (np.asarray(best_fit_values)).flatten())))[0]

                    # Index of best fitness value -- Added by Denis Lazor
                    best_fit_idx = best_fit_values.index(best_fit)

                    write_to_file(combination_series[best_fit_idx],
                                  parameter_name)

                    # First name will be "original", second one "elites" -- Added by Denis Lazor
                    parameter_name = "elites"

                    print_results(p, m, e, best_fit, mean_fit, NGEN)

                    # Clearing past lists  -- Added by Denis Lazor
                    combination_series = []
                    best_fit_values = []

                # Reducing number of combinations and changing .csv file for writing -- Added by Denis Lazor
                ELITE_SIZES = ELITE_SIZES[0:1]
                parameter_name = "mutation"

            MUTATION_SIZES = MUTATION_SIZES[0:1]
            parameter_name = "population"

        print("Best individual: " + str(best_individual))
        self.updateWorldFrame(generateWorldImage(
            best_individual))  # Drawing best solution -- Added by Denis Lazor

    def btnStop_Click(self):
        global stop_evolution
        stop_evolution = True
        #Disable stop and enable start
        self.btnStop.setEnabled(False)
        self.btnStart.setEnabled(True)
        self.gaParams.setEnabled(True)
        self.cbxBorder.setEnabled(True)
        self.cbxNoVis.setEnabled(True)

    #Function for GA evolution
    def evolve(self):
        global q_min_series
        global q_max_series
        global q_avg_series

        global best_fit_values
        global combination_series
        global best_individual

        combination_current_series = [
        ]  # Clearing fitness values series -- Added by Denis Lazor

        # Variable for keeping track of the number of generations
        curr_g = 0

        # Begin the evolution till goal is reached or max number of generation is reached
        while min(self.fits) != 0 and curr_g < NGEN:
            #Check if evolution and thread need to stop
            if stop_evolution:
                break  #Break the evolution loop

            # A new generation
            curr_g = curr_g + 1
            #print("-- Generation %i --" % curr_g)

            # Select the next generation individuals
            #Select POP_SIZE - NELT number of individuals. Since recombination is between neigbours, not two naighbours should be the clone of the same individual
            offspring = []
            offspring.append(self.toolbox.select(
                self.pop, 1)[0])  #add first selected individual
            for i in range(
                    POP_SIZE - NELT - 1
            ):  # -1 because the first seleceted individual is already added
                while True:
                    new_o = self.toolbox.select(self.pop, 1)[0]
                    if new_o != offspring[len(
                            offspring
                    ) - 1]:  #if it is different than the last inserted then add to offspring and break
                        offspring.append(new_o)
                        break

            # Clone the selected individuals because all of the changes are inplace
            offspring = list(map(self.toolbox.clone, offspring))

            # Apply crossover on the selected offspring
            for child1, child2 in zip(offspring[::2], offspring[1::2]):
                self.toolbox.mate(child1, child2)  #inplace recombination
                #Invalidate new children fitness values
                del child1.fitness.values
                del child2.fitness.values

            #Apply mutation on the offspring
            for mutant in offspring:
                if random.random() < MUTPB:
                    self.toolbox.mutate(mutant)
                    del mutant.fitness.values

            #Add elite individuals #Is clonning needed?
            offspring.extend(
                list(map(self.toolbox.clone, tools.selBest(self.pop, NELT))))

            # Evaluate the individuals with an invalid fitness
            invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
            fitnesses = map(self.toolbox.evaluate, invalid_ind)
            for ind, fit in zip(invalid_ind, fitnesses):
                ind.fitness.values = fit

            #print("  Evaluated %i individuals" % len(invalid_ind))

            #Replace population with offspring
            self.pop[:] = offspring

            # Gather all the fitnesses in one list and print the stats
            self.fits = [ind.fitness.values[0] for ind in self.pop]

            length = len(self.pop)
            mean = sum(self.fits) / length
            sum2 = sum(x * x for x in self.fits)
            std = abs(sum2 / length - mean**2)**0.5

            q_min_series.append(curr_g, min(self.fits))
            q_max_series.append(curr_g, max(self.fits))
            q_avg_series.append(curr_g, mean)

            combination_current_series.append(
                min(self.fits)
            )  # Saving min_series fitness values of an experiment -- Added by Denis Lazor

            #print("  Min %s" % q_min_series.at(q_min_series.count()-1).y())
            #print("  Max %s" % q_max_series.at(q_max_series.count()-1).y())
            #print("  Avg %s" % mean)
            #print("  Std %s" % std)

            if self.cbxNoVis.isChecked():
                app.processEvents()
            else:
                self.chart = QChart()
                self.chart.addSeries(q_min_series)
                self.chart.addSeries(q_max_series)
                self.chart.addSeries(q_avg_series)
                self.chart.setTitle("Fitness value over time")
                self.chart.setAnimationOptions(QChart.NoAnimation)
                self.chart.createDefaultAxes()
                self.frameChart.setChart(self.chart)

                #Draw queen positions of best individual on a image
                best_ind = tools.selBest(self.pop, 1)[0]
                self.updateWorldFrame(generateWorldImage(best_ind))

        #Printing best individual
        best_ind = tools.selBest(self.pop, 1)[0]
        #print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values))

        combination_series.append(
            combination_current_series
        )  # Saving best 5 results -- Added by Denis Lazor

        if not best_individual:
            best_individual = best_ind

        elif best_ind.fitness.values < best_individual.fitness.values:  # Saving best individual in all combinations -- Added by Denis Lazor
            best_individual = best_ind

        best_fit_values.append(
            best_ind.fitness.values
        )  # Adding best fitness value of experiment -- Added by Denis Lazor

        # #Visulaize final solution
        # if self.cbxNoVis.isChecked():
        #     self.chart = QChart()
        #     self.chart.addSeries(q_min_series)
        #     self.chart.addSeries(q_max_series)
        #     self.chart.addSeries(q_avg_series)
        #     self.chart.setTitle("Fitness value over time")
        #     self.chart.setAnimationOptions(QChart.NoAnimation)
        #     self.chart.createDefaultAxes()
        #     self.frameChart.setChart(self.chart)
        #
        #     #Draw queen positions of best individual on a image
        #     best_ind = tools.selBest(self.pop, 1)[0]
        #     self.updateWorldFrame(generateWorldImage(best_ind))

        #Disable stop and enable start
        self.btnStop.setEnabled(False)
        self.btnStart.setEnabled(True)
        self.gaParams.setEnabled(True)
        self.cbxBorder.setEnabled(True)
        self.cbxNoVis.setEnabled(True)

    def updateWorldFrame(self, best_individual_img):
        #new_image = QPixmap(1000,1000)
        self.new_image.fill()  #White color is default
        painter = QPainter(self.new_image)
        #First draw the map with towns
        painter.drawPixmap(self.new_image.rect(), self.img)
        #Then draw the best individual
        painter.drawImage(self.new_image.rect(), best_individual_img)
        painter.end()
        #Set new image to the frame
        self.frameWorld.img = self.new_image
        #Redrawing frames
        self.frameWorld.repaint()
        self.frameChart.repaint()
        app.processEvents()

    def btnSaveWorld_Click(self):
        filename, _ = QFileDialog.getSaveFileName(None,
                                                  "Save world as a image", "",
                                                  "Image Files (*.png)")
        self.frameWorld.img.save(filename, "PNG")
        print("World image saved to: ", filename)

    def btnSaveChart_CLick(self):
        p = self.frameChart.grab()
        filename, _ = QFileDialog.getSaveFileName(
            None, "Save series chart as a image", "", "Image Files (*.png)")
        p.save(filename, "PNG")
        print("Chart series image saved to: ", filename)

    def btnSaveChartSeries_Click(self):
        global q_min_series
        global q_max_series
        global q_avg_series
        filename, _ = QFileDialog.getSaveFileName(None,
                                                  "Save series to text file",
                                                  "",
                                                  "Text Files (*.txt, *.csv)")
        with open(filename, 'w') as dat:
            for i in range(q_min_series.count()):
                dat.write('%f,%f,%f\n' %
                          (q_min_series.at(i).y(), q_avg_series.at(i).y(),
                           q_max_series.at(i).y()))
        print("Chart series saved to: ", filename)