コード例 #1
0
def file_fetch_pdb(parent):
    form = parent.load_form('fetch')
    form.input_assembly.setEditText(parent.cmd.get('assembly'))

    def get_command(*args):
        code = form.input_code.text()
        if len(code) != 4:
            return ''

        def get_name(w):
            name = w.text()
            if name:
                return ', ' + name
            return ''

        if form.input_check_pdb.isChecked():
            command = 'set assembly, "%s"\nfetch %s%s%s' % (
                form.input_assembly.currentText(), code,
                form.input_chain.currentText(), get_name(form.input_name))
        else:
            command = ''

        if form.input_check_2fofc.isChecked():
            command += '\nfetch %s%s, type=2fofc' % (
                code, get_name(form.input_name_2fofc))

        if form.input_check_fofc.isChecked():
            command += '\nfetch %s%s, type=fofc' % (
                code, get_name(form.input_name_fofc))

        return command

    def update_output_command(*args):
        form.output_command.setText(get_command())

    def code_changed(code):
        for combo in [form.input_assembly, form.input_chain]:
            if combo.count() != 1:
                text = combo.currentText()
                combo.clear()
                combo.addItem('')
                combo.setEditText(text)
        if len(code) == 4:
            update_assemblies(code)
            update_chains(code)
        update_output_command()

    def run():
        if len(form.input_code.text()) != 4:
            QtWidgets.QMessageBox.warning(parent, "Error",
                                          "Need 4 letter PDB code")
            return
        parent.cmd.do(get_command())
        form._dialog.close()

    # async events
    update_assemblies = AsyncFunc(_get_assemblies,
                                  form.input_assembly.addItems)
    update_chains = AsyncFunc(_get_chains, form.input_chain.addItems)

    # hook up events
    form.input_code.textChanged.connect(code_changed)
    form.input_chain.editTextChanged.connect(update_output_command)
    form.input_assembly.editTextChanged.connect(update_output_command)
    form.input_name.textChanged.connect(update_output_command)
    form.input_name_2fofc.textChanged.connect(update_output_command)
    form.input_name_fofc.textChanged.connect(update_output_command)
    form.input_check_pdb.stateChanged.connect(update_output_command)
    form.input_check_2fofc.stateChanged.connect(update_output_command)
    form.input_check_fofc.stateChanged.connect(update_output_command)
    form.button_ok.clicked.connect(run)

    update_output_command()
    form._dialog.show()
コード例 #2
0
def dialog(_self=None):
    if _self is None:
        from pymol import cmd as _self

    dialog = QtWidgets.QDialog()
    uifile = os.path.join(os.path.dirname(__file__), 'apbs.ui')
    form = loadUi(uifile, dialog)
    form._dialog = dialog
    form._proclist = []

    def set_apbs_in(contents):
        form.apbs_template.setPlainText(contents.strip())

    # hide options widgets
    form.optarea_prep.setVisible(False)
    form.optarea_apbs.setVisible(False)
    form.optarea_surf.setVisible(False)
    form.optarea_other.setVisible(False)

    # pre-fill form with likely data
    names = _self.get_object_list()
    names += ['(' + n + ')' for n in _self.get_names('public_selections')]
    if names:
        form.input_sele.clear()
        form.input_sele.addItems([
            ('polymer & ' +
             name) if _self.count_atoms('polymer & ' + name) > 0 else name
            for name in names
        ])
    form.surf_map.addItems(_self.get_names_of_type('object:map'))
    set_apbs_in(electrostatics.template_apbs_in)

    # executables
    from distutils.spawn import find_executable
    form.apbs_exe.setText(electrostatics.find_apbs_exe() or 'apbs')
    form.pdb2pqr_exe.setText(
        find_executable('pdb2pqr') or
        # acellera::htmd-pdb2pqr provides pdb2pqr_cli
        find_executable('pdb2pqr_cli') or find_executable(
            'share/pdb2pqr/pdb2pqr.py', os.getenv('FREEMOL', '/usr'))
        or 'pdb2pqr')

    # for async panels
    form._callInMainThread = MainThreadCaller()
    run_impl_async = AsyncFunc(run_impl)

    # "Run" button callback
    def run():
        form.tabWidget.setEnabled(False)
        form.button_ok.clicked.disconnect()
        form.button_ok.clicked.connect(abort)
        form.button_ok.setText('Abort')

        form._capture = StdOutCapture()

        # detach from main thread
        run_impl_async(form, _self)

    # "Run" button "finally" actions (main thread)
    @run_impl_async.finished.connect
    def run_finally(args):
        _, exception = args

        form._proclist[:] = []
        stdout = form._capture.release()
        print(stdout)

        form.button_ok.setText('Run')
        form.button_ok.clicked.disconnect()
        form.button_ok.clicked.connect(run)
        form.button_ok.setEnabled(True)
        form.tabWidget.setEnabled(True)

        if exception is not None:
            handle_exception(exception, stdout)
            return

        quit_msg = "Finished with Success. Close the APBS dialog?"
        if QMessageBox.Yes == QMessageBox.question(form._dialog, 'Finished',
                                                   quit_msg, QMessageBox.Yes,
                                                   QMessageBox.No):
            form._dialog.close()

    def handle_exception(e, stdout):
        if isinstance(e, SilentAbort):
            return

        msg = str(e) or 'unknown error'
        msgbox = QMessageBox(QMessageBox.Critical, 'Error', msg,
                             QMessageBox.Close, form._dialog)
        if stdout.strip():
            msgbox.setDetailedText(stdout)
        msgbox.exec_()

    # "Abort" button callback
    def abort():
        form.button_ok.setEnabled(False)
        while form._proclist:
            p = form._proclist.pop()
            try:
                p.terminate()
                p.returncode = -15  # SIGTERM
            except OSError as e:
                print(e)

    # selection checker
    check_sele_timer = QtCore.QTimer()
    check_sele_timer.setSingleShot(True)

    # grid auto-value
    form.apbs_grid_userchanged = False
    form.apbs_grid.setStyleSheet('background: #ff6')

    @form.apbs_grid.editingFinished.connect
    def _():
        form.apbs_grid_userchanged = True
        form.apbs_grid.setStyleSheet('')

    @check_sele_timer.timeout.connect
    def _():
        has_props = ['no', 'no']

        def callback(partial_charge, elec_radius):
            if partial_charge: has_props[0] = 'YES'
            if elec_radius > 0: has_props[1] = 'YES'

        n = _self.iterate(form.input_sele.currentText(),
                          'callback(partial_charge, elec_radius)',
                          space={'callback': callback})

        # grid auto-value (keep map size in the order of 200x200x200)
        if n > 1 and not form.apbs_grid_userchanged:
            e = _self.get_extent(form.input_sele.currentText())
            volume = (e[1][0] - e[0][0]) * (e[1][1] - e[0][1]) * (e[1][2] -
                                                                  e[0][2])
            grid = max(0.5, volume**0.333 / 200.0)
            form.apbs_grid.setValue(grid)

        if n < 1:
            label = 'Selection is invalid'
            color = '#f66'
        elif has_props == ['YES', 'YES']:
            label = 'No preparation necessary, selection has charges and radii'
            form.do_prepare.setChecked(False)
            color = '#6f6'
        else:
            label = 'Selection needs preparation (partial_charge: %s, elec_radius: %s)' % tuple(
                has_props)
            form.do_prepare.setChecked(True)
            color = '#fc6'

        form.label_sele_has.setText(label)
        form.label_sele_has.setStyleSheet('background: %s; padding: 5' % color)

    check_sele_timer.start(0)

    @form.apbs_exe_browse.clicked.connect
    def _():
        fnames = getOpenFileNames(None,
                                  filter='apbs (apbs*);;All Files (*)')[0]
        if fnames:
            form.apbs_exe.setText(fnames[0])

    @form.pdb2pqr_exe_browse.clicked.connect
    def _():
        fnames = getOpenFileNames(
            None, filter='pdb2pqr (pdb2pqr*);;All Files (*)')[0]
        if fnames:
            form.pdb2pqr_exe.setText(fnames[0])

    # hook up events
    form.input_sele.currentIndexChanged.connect(
        lambda: check_sele_timer.start(0))
    form.input_sele.editTextChanged.connect(
        lambda: check_sele_timer.start(1000))

    form.button_ok.clicked.connect(run)

    # "Register" opens a web browser
    @form.button_register.clicked.connect
    def _():
        import webbrowser
        webbrowser.open("http://www.poissonboltzmann.org/")

    @form.button_load.clicked.connect
    def _():
        fnames = getOpenFileNames(None,
                                  filter='APBS Input (*.in);;All Files (*)')[0]
        if fnames:
            contents = load_apbs_in(form, fnames[0])
            set_apbs_in(contents)

    @form.button_reset.clicked.connect
    def _():
        set_apbs_in(electrostatics.template_apbs_in)

    form._dialog.show()
    form._dialog.resize(500, 600)