Example #1
0
class TestPython(object):

    def __init__(self, ID=None):
        self.Test = QProcess()
        self.ID = ID
        #a and b to test if i get a output or command error
        self.a = True
        self.Settings = QtCore.QSettings('Tyrant.cfg',
                                                    QtCore.QSettings.IniFormat)

    def TestVersion(self):
        print('Test python version')
        self.Test.readyReadStandardError.connect(self.getOutput)
        self.Test.readyReadStandardOutput.connect(self.getOutput)
        if self.ID is not None:
            self.Test.error.connect(self.Error)
        #if i have a custom pythonpath, i'll use it here
        Res = Resources()
        Python = Res.getPref('Python')
        #test if is a pythonpath, if not open a default
        if len(Python) < 5:
            Python = 'python'
        self.Test.start(Python, ['-V'])
        self.Test.waitForFinished()
        self.Test.terminate()
        if (self.a is False) & (self.ID is None):
            #test a diferent command to run python 2.7
            a = self.TestVersion2()
            print a
            return a
        elif self.a:
            #say to program that python is working
            print('Python version found')
            self.Settings.setValue('Python/PythonPath', str(Python))
            self.Settings.sync()
            return True
        elif ((self.ID is not None) & (self.a is False)):
            return False

    def Error(self):
        self.a = False

    def TestVersion2(self):
        print('Testing python version 2')
        self.Test.readyReadStandardError.connect(self.getOutput)
        Python = 'python2.7'
        self.Test.start(Python, ['-V'])
        self.Test.waitForStarted()
        self.Test.waitForFinished()
        self.Test.terminate()
        if (self.a is False):
            #say thar python is not working
            return False
        else:
            self.Settings.setValue('Python/PythonPath', str(Python))
            self.Settings.sync()
            return True

    def getOutput(self):
        Out = str(self.Test.readAllStandardError())
        print(Out)
        if Out > 'Python 2.8':
            self.a = False
            return
        self.a = True
Example #2
0
def parse_asn1(*files, **options):
    """ Call the ASN.1 parser on a number of files, and return the module
        containing the AST
        This function uses QProcess to launch the ASN.1 compiler because
        the subprocess module from Python has issues on the Windows platform
    """
    global AST

    ast_version = options.get("ast_version", ASN1.UniqueEnumeratedNames)
    rename_policy = options.get("rename_policy", ASN1.NoRename)
    flags = options.get("flags", [ASN1.AstOnly])
    assert isinstance(ast_version, ASN1)
    assert isinstance(rename_policy, ASN1)
    assert isinstance(flags, list)
    # if os.name == 'posix' and hasattr(sys, 'frozen'):
    # Frozen Linux binaries are expected to use the frozen ASN.1 compiler
    # No: there are issues with freezing the .NET applications - discard
    #     asn1exe = 'asn1scc'
    # else:
    #    asn1exe = 'asn1.exe'
    path_to_asn1scc = spawn.find_executable("asn1.exe")

    if not path_to_asn1scc:
        raise TypeError("ASN.1 Compiler not found in path")
    if os.name == "posix":
        path_to_mono = spawn.find_executable("mono")
        if not path_to_mono:
            raise TypeErorr('"mono" not found in path. Please install it.')
        binary = path_to_mono
        arg0 = path_to_asn1scc
    else:
        binary = path_to_asn1scc
        arg0 = ""
    asn1scc_root = os.path.abspath(os.path.dirname(path_to_asn1scc))
    # Create a temporary directory to store dataview.py and import it
    tempdir = tempfile.mkdtemp()
    sys.path.append(tempdir)
    if os.name == "nt":
        # On windows, remove the drive letter, workaround to ASN1SCC bug
        tempdir = tempdir[2:]
        asn1scc_root = asn1scc_root[2:]
    filename = str(uuid.uuid4()).replace("-", "_")
    filepath = tempdir + os.sep + filename + ".py"

    stg = asn1scc_root + os.sep + "python.stg"

    args = [
        arg0,
        "-customStgAstVerion",
        str(ast_version.value),
        "-customStg",
        stg + "::" + filepath,
        "-renamePolicy",
        str(rename_policy.value),
    ] + list(*files)
    asn1scc = QProcess()
    LOG.debug(os.getcwd())
    LOG.debug(binary + " " + " ".join(args))
    asn1scc.start(binary, args)
    if not asn1scc.waitForStarted():
        raise TypeError("Could not start ASN.1 Compiler")
    if not asn1scc.waitForFinished():
        raise TypeError("Execution of ASN.1 Compiler timed out")
    exitcode = asn1scc.exitCode()
    result = asn1scc.readAllStandardError()
    if exitcode != 0:
        raise TypeError("ASN.1 Compiler Error (exit code = {}) - {}".format(exitcode, str(result)))
    else:
        if filename in AST.viewkeys():
            # Re-import module if it was already loaded
            ast = AST[filename]
            reload(ast)
        else:
            ast = importlib.import_module(filename)
            AST[filename] = ast
        return ast
Example #3
0
class TestPython(object):
    def __init__(self, ID=None):
        self.Test = QProcess()
        self.ID = ID
        #a and b to test if i get a output or command error
        self.a = True
        self.Settings = QtCore.QSettings('Tyrant.cfg',
                                         QtCore.QSettings.IniFormat)

    def TestVersion(self):
        print('Test python version')
        self.Test.readyReadStandardError.connect(self.getOutput)
        self.Test.readyReadStandardOutput.connect(self.getOutput)
        if self.ID is not None:
            self.Test.error.connect(self.Error)
        #if i have a custom pythonpath, i'll use it here
        Res = Resources()
        Python = Res.getPref('Python')
        #test if is a pythonpath, if not open a default
        if len(Python) < 5:
            Python = 'python'
        self.Test.start(Python, ['-V'])
        self.Test.waitForFinished()
        self.Test.terminate()
        if (self.a is False) & (self.ID is None):
            #test a diferent command to run python 2.7
            a = self.TestVersion2()
            print a
            return a
        elif self.a:
            #say to program that python is working
            print('Python version found')
            self.Settings.setValue('Python/PythonPath', str(Python))
            self.Settings.sync()
            return True
        elif ((self.ID is not None) & (self.a is False)):
            return False

    def Error(self):
        self.a = False

    def TestVersion2(self):
        print('Testing python version 2')
        self.Test.readyReadStandardError.connect(self.getOutput)
        Python = 'python2.7'
        self.Test.start(Python, ['-V'])
        self.Test.waitForStarted()
        self.Test.waitForFinished()
        self.Test.terminate()
        if (self.a is False):
            #say thar python is not working
            return False
        else:
            self.Settings.setValue('Python/PythonPath', str(Python))
            self.Settings.sync()
            return True

    def getOutput(self):
        Out = str(self.Test.readAllStandardError())
        print(Out)
        if Out > 'Python 2.8':
            self.a = False
            return
        self.a = True
Example #4
0
class LaunchGUI(QtGui.QDialog):
    def __init__(self, app):
        super(LaunchGUI, self).__init__()
        self.app = app
        self.init_gui_layout()

    def init_gui_layout(self):
        gui_fname = pkg_resources.resource_filename(
            'circus', os.path.join('qt_GUI', 'qt_launcher.ui'))
        self.ui = uic.loadUi(gui_fname)
        self.task_comboboxes = [
            cb for cb in self.ui.grp_tasks.children()
            if isinstance(cb, QCheckBox)
        ]

        logo = pkg_resources.resource_filename(
            'circus', os.path.join('icons', 'icon.png'))
        self.ui.setWindowIcon(QtGui.QIcon(logo))

        try:
            import cudamat as cmt
            cmt.init()
            self.HAVE_CUDA = True
        except Exception:
            self.HAVE_CUDA = False

        self.ui.btn_run.clicked.connect(self.run)
        self.ui.btn_plots.clicked.connect(self.open_plot_folder)
        self.ui.btn_param.clicked.connect(self.view_param)
        self.ui.btn_phy.clicked.connect(self.help_phy)
        self.ui.btn_matlab.clicked.connect(self.help_matlab)
        self.ui.btn_help_cpus.clicked.connect(self.help_cpus)
        self.ui.btn_help_gpus.clicked.connect(self.help_gpus)
        self.ui.btn_help_file_format.clicked.connect(self.help_file_format)
        self.ui.tabWidget.currentChanged.connect(self.changing_tab)
        self.ui.btn_stop.clicked.connect(self.stop)
        self.ui.btn_file.clicked.connect(self.update_data_file)
        self.ui.btn_about.clicked.connect(self.show_about)
        self.ui.rb_gui_matlab.clicked.connect(self.update_gui_command)
        self.ui.rb_gui_python.clicked.connect(self.update_gui_command)
        self.ui.btn_output.clicked.connect(self.update_output_file)
        self.ui.btn_hostfile.clicked.connect(self.update_host_file)
        self.ui.btn_log.clicked.connect(self.open_log_file)
        self.ui.cb_batch.toggled.connect(self.update_batch_mode)
        self.ui.cb_preview.toggled.connect(self.update_preview_mode)
        self.ui.cb_results.toggled.connect(self.update_results_mode)
        self.ui.cb_benchmarking.toggled.connect(self.update_benchmarking)
        self.ui.cb_merging.toggled.connect(self.update_extension)
        self.ui.cb_converting.toggled.connect(self.update_extension)
        self.update_benchmarking()
        self.update_extension()
        for cb in self.task_comboboxes:
            cb.toggled.connect(self.store_tasks)
            cb.toggled.connect(self.update_command)
        self.ui.edit_file.textChanged.connect(self.update_command)
        self.ui.edit_output.textChanged.connect(self.update_command)
        self.ui.edit_hostfile.textChanged.connect(self.update_command)
        self.ui.edit_extension.textChanged.connect(self.update_command)
        self.ui.gui_extension.textChanged.connect(self.update_gui_command)
        self.ui.spin_cpus.valueChanged.connect(self.update_command)
        if not self.HAVE_CUDA:
            self.ui.spin_gpus.setEnabled(False)
        self.ui.spin_gpus.valueChanged.connect(self.update_command)
        self.store_tasks()
        self.process = None
        self.ui.closeEvent = self.closeEvent
        self.last_log_file = None
        try:
            import sklearn
        except ImportError:
            self.ui.cb_validating.setEnabled(False)
        self.ui.show()

    def store_tasks(self):
        self.stored_tasks = [cb.isChecked() for cb in self.task_comboboxes]
        if not numpy.any(self.stored_tasks):
            self.ui.btn_run.setEnabled(False)
        elif str(self.ui.edit_file.text()) != '':
            self.ui.btn_run.setEnabled(True)
            self.ui.btn_plots.setEnabled(True)

    def restore_tasks(self):
        for cb, prev_state in zip(self.task_comboboxes, self.stored_tasks):
            cb.setEnabled(True)
            cb.setChecked(prev_state)

    def update_batch_mode(self):
        batch_mode = self.ui.cb_batch.isChecked()
        self.ui.spin_cpus.setEnabled(not batch_mode)
        self.ui.spin_gpus.setEnabled(not batch_mode)
        self.ui.edit_hostfile.setEnabled(not batch_mode)
        self.ui.btn_hostfile.setEnabled(not batch_mode)
        self.update_tasks()
        self.update_extension()
        self.update_benchmarking()
        if batch_mode:
            self.ui.spin_cpus.setEnabled(not batch_mode)
            self.ui.spin_gpus.setEnabled(not batch_mode)
            self.ui.edit_hostfile.setEnabled(not batch_mode)
            self.ui.btn_hostfile.setEnabled(not batch_mode)
            self.update_tasks()
            self.update_extension()
            self.update_benchmarking()
            self.update_command()
            self.ui.cb_preview.setChecked(False)
            self.ui.cb_results.setChecked(False)
            self.ui.lbl_file.setText('Command file')
        else:
            self.last_mode = None
            self.ui.lbl_file.setText('Data file')
        self.update_command()

    def changing_tab(self):
        if self.ui.tabWidget.currentIndex() == 0:
            self.update_command()
        elif self.ui.tabWidget.currentIndex() == 1:
            self.update_gui_command()

    def update_preview_mode(self):
        preview_mode = self.ui.cb_preview.isChecked()

        self.update_tasks()

        if preview_mode:
            self.ui.cb_batch.setChecked(False)
            self.ui.cb_results.setChecked(False)

        self.update_command()

    def update_results_mode(self):
        results_mode = self.ui.cb_results.isChecked()
        self.ui.spin_cpus.setEnabled(not results_mode)
        self.ui.spin_gpus.setEnabled(not results_mode)
        self.ui.edit_hostfile.setEnabled(not results_mode)
        self.ui.btn_hostfile.setEnabled(not results_mode)
        self.update_tasks()
        self.update_extension()
        self.update_benchmarking()
        self.update_command()
        if results_mode:
            self.ui.cb_batch.setChecked(False)
            self.ui.cb_preview.setChecked(False)

    def update_result_tab(self):
        if str(self.ui.edit_file.text()) != '':
            f_next, _ = os.path.splitext(str(self.ui.edit_file.text()))
            ft = os.path.basename(os.path.normpath(f_next))
            f_results = os.path.join(f_next, ft + '.result.hdf5')
            if os.path.exists(f_results):
                self.ui.selection_gui.setEnabled(True)
                self.ui.extension_gui.setEnabled(True)
        else:
            self.ui.selection_gui.setEnabled(False)
            self.ui.extension_gui.setEnabled(False)

    def update_extension(self):
        batch_mode = self.ui.cb_batch.isChecked()
        if (not batch_mode and (self.ui.cb_merging.isChecked()
                                or self.ui.cb_converting.isChecked())):
            self.ui.edit_extension.setEnabled(True)
        else:
            self.ui.edit_extension.setEnabled(False)

    def update_benchmarking(self):
        batch_mode = self.ui.cb_batch.isChecked()
        enable = not batch_mode and self.ui.cb_benchmarking.isChecked()
        self.ui.edit_output.setEnabled(enable)
        self.ui.btn_output.setEnabled(enable)
        self.ui.cmb_type.setEnabled(enable)
        self.update_command()

    def update_tasks(self):
        batch_mode = self.ui.cb_batch.isChecked()
        preview_mode = self.ui.cb_preview.isChecked()
        results_mode = self.ui.cb_results.isChecked()
        if batch_mode or results_mode:
            self.restore_tasks()
            for cb in self.task_comboboxes:
                cb.setEnabled(False)
        elif preview_mode:
            prev_stored_tasks = self.stored_tasks
            for cb in self.task_comboboxes:
                cb.setEnabled(False)
                cb.setChecked(False)
            self.ui.cb_filtering.setChecked(True)
            self.ui.cb_whitening.setChecked(True)
            self.stored_tasks = prev_stored_tasks
        else:  # We come back from batch or preview mode
            self.restore_tasks()
        self.update_command()

    def update_data_file(self):
        if self.ui.cb_batch.isChecked():
            title = 'Select file with list of commands'
        else:
            title = 'Select data file'
        fname = QFileDialog.getOpenFileName(self, title,
                                            self.ui.edit_file.text())
        if fname:
            self.ui.edit_file.setText(fname)

        if str(self.ui.edit_file.text()) != '':
            self.ui.btn_run.setEnabled(True)
            f_next, _ = os.path.splitext(str(self.ui.edit_file.text()))
            f_params = f_next + '.params'
            if os.path.exists(f_params):
                self.ui.btn_param.setEnabled(True)
                self.ui.btn_plots.setEnabled(True)
        else:
            self.ui.btn_run.setEnabled(False)

        if self.ui.tabWidget.currentIndex() == 0:
            self.update_command()
        elif self.ui.tabWidget.currentIndex() == 1:
            self.update_gui_command()

        self.update_result_tab()

    def update_host_file(self):
        fname = QFileDialog.getOpenFileName(self, 'Select MPI host file',
                                            self.ui.edit_hostfile.text())
        if fname:
            self.ui.edit_hostfile.setText(fname)

    def update_output_file(self):
        fname = QFileDialog.getSaveFileName(self, 'Output file name',
                                            self.ui.edit_output.text())
        if fname:
            self.ui.edit_output.setText(fname)

    def open_log_file(self):
        assert self.last_log_file is not None
        QDesktopServices.openUrl(QUrl(self.last_log_file))

    def gui_command_line_args(self):

        if self.ui.rb_gui_matlab.isChecked():
            args = ['circus-gui-matlab']
        elif self.ui.rb_gui_python.isChecked():
            args = ['circus-gui-python']

        fname = str(self.ui.edit_file.text()).strip()
        if fname:
            args.append(fname)

        extension = str(self.ui.gui_extension.text()).strip()

        if extension:
            args.extend(['--extension', extension])

        return args

    def command_line_args(self):
        batch_mode = self.ui.cb_batch.isChecked()
        preview_mode = self.ui.cb_preview.isChecked()
        results_mode = self.ui.cb_results.isChecked()

        args = ['spyking-circus']
        fname = str(self.ui.edit_file.text()).strip()
        if fname:
            args.append(fname)

        if batch_mode:
            args.append('--batch')
        elif preview_mode:
            args.append('--preview')
            if self.ui.spin_cpus.value() > 1:
                args.extend(['--cpu', str(self.ui.spin_cpus.value())])
            if self.ui.spin_gpus.value() > 0:
                args.extend(['--gpu', str(self.ui.spin_gpus.value())])
        elif results_mode:
            args.append('--result')
        else:
            tasks = []
            for cb in self.task_comboboxes:
                if cb.isChecked():
                    label = str(cb.text()).lower()
                    tasks.append(label)
            if len(tasks) > 0:
                args.extend(['--method', ','.join(tasks)])
            if self.ui.spin_cpus.value() > 1:
                args.extend(['--cpu', str(self.ui.spin_cpus.value())])
            if self.ui.spin_gpus.value() > 0:
                args.extend(['--gpu', str(self.ui.spin_gpus.value())])
            hostfile = str(self.ui.edit_hostfile.text()).strip()
            if hostfile:
                args.extend(['--hostfile', hostfile])
            if 'merging' in tasks or 'converting' in tasks:
                extension = str(self.ui.edit_extension.text()).strip()
                if extension:
                    args.extend(['--extension', extension])
            if 'benchmarking' in tasks:
                args.extend(['--output', str(self.ui.edit_output.text())])
                args.extend(['--type', str(self.ui.cmb_type.currentText())])
        return args

    def update_gui_command(self):
        args = ' '.join(self.gui_command_line_args())
        self.ui.edit_command.setPlainText(args)

    def update_command(self, text=None):
        args = ' '.join(self.command_line_args())
        self.ui.edit_command.setPlainText(args)

    def run(self):
        if self.ui.cb_batch.isChecked():
            self.last_log_file = None
        else:
            f_next, _ = os.path.splitext(str(self.ui.edit_file.text()))
            f_params = f_next + '.params'
            if not os.path.exists(f_params):
                self.create_params_file(f_params)
                self.ui.btn_param.setEnabled(True)
                return
            self.last_log_file = f_next + '.log'

        if self.ui.tabWidget.currentIndex() == 0:
            args = self.command_line_args()
        elif self.ui.tabWidget.currentIndex() == 1:
            args = self.gui_command_line_args()

        self.update_result_tab()

        # # Start process
        self.ui.edit_stdout.clear()
        format = self.ui.edit_stdout.currentCharFormat()
        format.setFontWeight(QFont.Normal)
        format.setForeground(QtCore.Qt.blue)
        self.ui.edit_stdout.setCurrentCharFormat(format)
        time_str = datetime.datetime.now().ctime()
        start_msg = '''\
                       Starting spyking circus at {time_str}.

                       Command line call:
                       {call}
                    '''.format(time_str=time_str, call=' '.join(args))
        self.ui.edit_stdout.appendPlainText(textwrap.dedent(start_msg))
        format.setForeground(QtCore.Qt.black)
        self.ui.edit_stdout.setCurrentCharFormat(format)
        self.ui.edit_stdout.appendPlainText('\n')

        self.process = QProcess(self)
        self.connect(self.process, SIGNAL('readyReadStandardOutput()'),
                     self.append_output)
        self.connect(self.process, SIGNAL('readyReadStandardError()'),
                     self.append_error)
        self.connect(self.process, SIGNAL('started()'), self.process_started)
        self.connect(self.process, SIGNAL('finished(int)'),
                     self.process_finished)
        self.connect(self.process, SIGNAL('error()'), self.process_errored)
        self._interrupted = False
        self.process.start(args[0], args[1:])

    def restore_gui(self):
        for widget, previous_state in self._previous_state:
            widget.setEnabled(previous_state)
        self.app.restoreOverrideCursor()

    def process_started(self):
        # Disable everything except for the stop button and the output area
        all_children = [
            obj for obj in self.ui.findChildren(QWidget)
            if isinstance(obj, (QCheckBox, QPushButton, QLineEdit))
        ]
        self._previous_state = [(obj, obj.isEnabled()) for obj in all_children]
        for obj in all_children:
            obj.setEnabled(False)
        self.ui.btn_stop.setEnabled(True)
        # If we let the user interact, this messes with the cursor we use to
        # support the progress bar display
        self.ui.edit_stdout.setTextInteractionFlags(Qt.NoTextInteraction)
        self.app.setOverrideCursor(Qt.WaitCursor)

    def process_finished(self, exit_code):
        format = self.ui.edit_stdout.currentCharFormat()
        format.setFontWeight(QFont.Bold)
        if exit_code == 0:
            if self._interrupted:
                color = QtCore.Qt.red
                msg = ('Process interrupted by user')
            else:
                color = QtCore.Qt.green
                msg = ('Process exited normally')
        else:
            color = QtCore.Qt.red
            msg = ('Process exited with exit code %d' % exit_code)
        format.setForeground(color)
        self.ui.edit_stdout.setCurrentCharFormat(format)
        self.ui.edit_stdout.appendPlainText(msg)
        self.restore_gui()
        self.ui.edit_stdout.setTextInteractionFlags(
            Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
        self.process = None
        self.ui.btn_log.setEnabled(self.last_log_file is not None
                                   and os.path.isfile(self.last_log_file))

    def process_errored(self):
        exit_code = self.process.exitCode()
        format = self.ui.edit_stdout.currentCharFormat()
        format.setFontWeight(QFont.Bold)
        format.setForeground(QtCore.Qt.red)
        self.ui.edit_stdout.setCurrentCharFormat(format)
        self.ui.edit_stdout.appendPlainText('Process exited with exit code' %
                                            exit_code)
        self.restore_gui()
        self.ui.edit_stdout.setTextInteractionFlags(
            Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
        self.process = None

    def add_output_lines(self, lines):
        '''
        Add the output line by line to the text area, jumping back to the
        beginning of the line when we encounter a carriage return (to
        correctly display progress bars)
        '''
        cursor = self.ui.edit_stdout.textCursor()
        cursor.clearSelection()
        splitted_lines = lines.split('\n')
        for idx, line in enumerate(splitted_lines):
            if '\r' in line:
                chunks = line.split('\r')
                overwrite_text(cursor,
                               chunks[0])  # No going back for the first chunk
                for chunk in chunks[
                        1:]:  # Go back to start of line for each \r
                    cursor.movePosition(QTextCursor.StartOfLine)
                    overwrite_text(cursor, chunk)
            else:
                overwrite_text(cursor, line)

            # Take care to not introduce new newlines
            if '\n' in lines and (idx == 0 or idx != len(splitted_lines) - 1):
                cursor.movePosition(QTextCursor.EndOfLine)
                cursor.insertText('\n')
        self.ui.edit_stdout.setTextCursor(cursor)

    def append_output(self):
        if self.process is None:  # Can happen when manually interrupting
            return
        lines = strip_ansi_codes(to_str(self.process.readAllStandardOutput()))
        self.add_output_lines(lines)
        # We manually deal with keyboard input in the output
        if 'Export already made! Do you want to erase everything? (y)es / (n)o' in lines:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Question)
            msg.setWindowTitle('Erase everything?')
            msg.setText(
                'Export already made! Do you want to erase everything?')
            msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            answer = msg.exec_()
            if answer == QMessageBox.Yes:
                answer_string = 'y'
            else:
                answer_string = 'n'
        elif 'Do you want SpyKING CIRCUS to export PCs? (a)ll / (s)ome / (n)o' in lines:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Question)
            msg.setWindowTitle('Export PCs?')
            msg.setText('Do you want SpyKING CIRCUS to export PCs?')
            no_button = msg.addButton('No', QMessageBox.NoRole)
            some_button = msg.addButton('Some', QMessageBox.YesRole)
            all_button = msg.addButton('All', QMessageBox.YesRole)
            msg.exec_()
            if msg.clickedButton() == no_button:
                answer_string = 'n'
            elif msg.clickedButton() == some_button:
                answer_string = 's'
            elif msg.clickedButton() == all_button:
                answer_string = 'a'
            else:
                answer_string = 'n'
        else:
            answer_string = ''

        if answer_string:
            self.process.write(answer_string + '\n')
            self.add_output_lines(answer_string + '\n')

    def append_error(self):
        if self.process is None:  # Can happen when manually interrupting
            return
        lines = strip_ansi_codes(to_str(self.process.readAllStandardError()))
        self.add_output_lines(lines)

    def stop(self, force=False):
        if self.process is not None:

            if not force:
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Warning)
                msg.setWindowTitle('Confirm process termination')
                msg.setText(
                    'This will terminate the running process. Are you sure '
                    'you want to do this?')
                msg.setInformativeText(
                    'Interrupting the process may leave partly '
                    'created files that cannot be used for '
                    'further analysis.')
                msg.addButton('Stop process', QMessageBox.YesRole)
                cancel_button = msg.addButton('Cancel', QMessageBox.NoRole)
                msg.setDefaultButton(cancel_button)
                msg.exec_()
                if msg.clickedButton() == cancel_button:
                    # Continue to run
                    return

            self._interrupted = True
            # Terminate child processes as well
            pid = int(self.process.pid())
            if sys.platform == 'win32' and pid != 0:
                # The returned value is not a PID but a pointer
                lp = ctypes.cast(pid, LPWinProcInfo)
                pid = lp.contents.dwProcessID

            if pid != 0:
                process = psutil.Process(pid)
                children = process.children(recursive=True)
                for proc in children:
                    proc.terminate()
                gone, alive = psutil.wait_procs(children, timeout=3)
                for proc in alive:
                    proc.kill()

                self.process.terminate()
                self.process = None

    def create_params_file(self, fname):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Question)
        msg.setText(
            "Parameter file %r not found, do you want SpyKING CIRCUS to "
            "create it for you?" % fname)
        msg.setWindowTitle("Generate parameter file?")
        msg.setInformativeText("This will create a parameter file from a "
                               "template file and open it in your system's "
                               "standard text editor. Fill properly before "
                               "launching the code. See the documentation "
                               "for details")
        msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        answer = msg.exec_()
        if answer == QMessageBox.Yes:
            user_path = os.path.join(os.path.expanduser('~'), 'spyking-circus')
            if os.path.exists(user_path + 'config.params'):
                config_file = os.path.abspath(user_path + 'config.params')
            else:
                config_file = os.path.abspath(
                    pkg_resources.resource_filename('circus', 'config.params'))
            shutil.copyfile(config_file, fname)
            QDesktopServices.openUrl(QUrl(fname))

    def view_param(self):
        f_next, _ = os.path.splitext(str(self.ui.edit_file.text()))
        f_params = f_next + '.params'
        QDesktopServices.openUrl(QUrl(f_params))

    def show_about(self):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Question)
        msg.setText("SpyKING CIRCUS v%s" % circus.__version__)
        msg.setWindowTitle("About")
        msg.setInformativeText("Documentation can be found at\n"
                               "http://spyking-circus.rtfd.org\n"
                               "\n"
                               "Open a browser to see the online help?")
        msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        msg.setDefaultButton(QMessageBox.No)
        answer = msg.exec_()
        if answer == QMessageBox.Yes:
            QDesktopServices.openUrl(QUrl("http://spyking-circus.rtfd.org"))

    def help_cpus(self):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Question)
        msg.setText("Setting the number of CPUs")
        msg.setWindowTitle("Number of CPUs")
        msg.setInformativeText("SpyKING CIRCUS can use several CPUs "
                               "either locally or on multiple machines "
                               "using MPI (see documentation) "
                               "\n"
                               "\n"
                               "You have %d local CPUs available" %
                               psutil.cpu_count())
        msg.setStandardButtons(QMessageBox.Close)
        msg.setDefaultButton(QMessageBox.Close)
        answer = msg.exec_()

    def help_gpus(self):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Question)
        msg.setText("Setting the number of GPUs")
        msg.setWindowTitle("Number of GPUs")
        if not self.HAVE_CUDA:
            info = "No GPUs are detected on your system"
        else:
            gpu_id = 0
            is_available = True
            while is_available:
                try:
                    cmt.cuda_set_device(gpu_id)
                    is_available = True
                except Exception:
                    is_available = False
            info = "%d GPU is detected on your system" % (gpu_id + 1)

        msg.setInformativeText("SpyKING CIRCUS can use several GPUs\n"
                               "either locally or on multiple machine\n"
                               "using MPI (see documentation)"
                               "\n"
                               "\n"
                               "%s" % info)
        msg.setStandardButtons(QMessageBox.Close)
        msg.setDefaultButton(QMessageBox.Close)
        answer = msg.exec_()

    def help_file_format(self):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Question)
        msg.setText("Supported file formats")
        msg.setWindowTitle("File formats")

        msg.setInformativeText("\n".join(list_all_file_format()))
        msg.setStandardButtons(QMessageBox.Close)
        msg.setDefaultButton(QMessageBox.Close)
        answer = msg.exec_()

    def open_plot_folder(self):
        f_next, _ = os.path.splitext(str(self.ui.edit_file.text()))
        plot_folder = os.path.join(f_next, 'plots')
        QDesktopServices.openUrl(QUrl(plot_folder))

    def help_phy(self):
        QDesktopServices.openUrl(
            QUrl("https://github.com/kwikteam/phy-contrib"))

    def help_matlab(self):
        QDesktopServices.openUrl(
            QUrl("http://ch.mathworks.com/products/matlab/"))

    def closeEvent(self, event):
        if self.process is not None:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setWindowTitle('Confirm process interruption')
            msg.setText(
                'Closing the window will terminate the running process. '
                'Do you really want to exit?')
            msg.setInformativeText('Interrupting the process may leave partly '
                                   'created files that cannot be used for '
                                   'further analysis.')
            close_button = msg.addButton("Stop and close", QMessageBox.YesRole)
            cancel_button = msg.addButton("Cancel", QMessageBox.NoRole)
            msg.setDefaultButton(cancel_button)
            msg.exec_()
            if msg.clickedButton() == close_button:
                self.stop(force=True)
                super(LaunchGUI, self).closeEvent(event)
            else:
                event.ignore()