How can I access all PyMol commands through a Python script?

319 Views Asked by At

Currently trying to use a Python script to automate protein modelling in PyMol, but I cannot access PyMol commands through the Python script.

Any ideas on how to solve this?

I tried doing it as below, but not working. The error I get is "module 'cmd' has no attribute 'fab'"

from pymol import cmd

pymol.cmd.do("fab APAPAP")
pymol.cmd.save(example.pdb)

Regards Paul

1

There are 1 best solutions below

0
pippo1980 On

To me works both :

import pymol

pymol.cmd.do('fab APAPAP, do_fab')

pymol.cmd.save('example_2.pdb' , 'do_fab') 

or

import pymol

pymol.cmd.fab('APAPAP', 'example')

pymol.cmd.save('example.pdb' , 'example') 

opened in pymol : enter image description here

fab command is in editor.py file in pymol program:

......
def _fab(input,name,mode,resi,chain,segi,state,dir,hydro,ss,quiet,_self=cmd):
    r = DEFAULT_ERROR
    code = _fab_codes.get(mode,None)
    quiet = int(quiet)
    resi = int(resi)
    state = int(state)
    dir = int(dir)
    hydro = int(hydro)

    if hydro < 0:
        hydro = not _self.get_setting_boolean("auto_remove_hydrogens")
    
    seq_len = 0
    if (mode == 'peptide') and is_string(input):
        # '123/ ADC B/234/ AFCD' to [ '123/','A','D','C','B/234/','F','C','D' ]
        frags = input.split()
        input = []
        for frag in frags:
            if '/' in frag:
                input.append(frag)
            else:
                seq_len = seq_len + len(frag)
                input.extend(list(frag))
                input.append("/") # breaks chain
    if name == None:
        name = _self.get_unused_name("obj")
    elif name in _self.get_names():
        _self.delete(name)

#    if mode in [ 'smiles' ]: # small molecule (FUTURE)
#        from chempy.champ import Champ
#        ch = Champ()
#        ch.insert_pattern_string(input)
    if mode in [ 'peptide' ]:  # polymers
        if (seq_len>99) and not quiet:
            print(" Generating a %d residue peptide from sequence..."%seq_len)
        input.reverse()
        sequence = input
        if code != None:
            while len(sequence):
                while len(sequence) and '/' in sequence[-1]:
                    part = sequence.pop().split('/')
                    if len(part)>1:
                        if len(part[-2]):
                            resi = int(part[-2])
                    if len(part)>2:
                        chain = part[-3]
                    if len(part)>3:
                        segi = part[-4]
                if len(sequence) and not _self.count_atoms("?pk1"): # new polymer segment
                    tmp_obj = _self.get_unused_name()
                    first = sequence.pop()
                    _self.fragment(code[first], tmp_obj)
                    if not hydro:
                        _self.remove(tmp_obj + ' and hydro')
                    _self.alter(tmp_obj,'resi="""%s""";chain="""%s""";segi="""%s"""'%(resi,chain,segi))
                    _self.create(name,tmp_obj+" or ?"+name,1,1,zoom=0)
                    tmp_sel = _self.get_unused_name()
                    if mode == 'peptide':
                        if dir>0:
                            _self.select(tmp_sel,"name C and "+tmp_obj)
                            resi = resi + 1
                        else:
                            _self.select(tmp_sel,"name N and "+tmp_obj)
                            resi = resi - 1
                    _self.edit(name+" in "+tmp_sel) # set the editor's pk1 selection
                    _self.delete(tmp_sel+" "+tmp_obj)
                if mode == 'peptide':
                    while len(sequence):
                        if '/' in sequence[-1]:
                            _self.unpick() # break chain at this point
                            break
                        if not _self.count_atoms("?pk1"):
                            break
                        else:
                            attach_amino_acid("pk1",code[sequence.pop()],animate=0,ss=ss,hydro=hydro,_self=_self)
                            if dir>0:
                                resi = resi + 1
                            else:
                                resi = resi - 1
    if not len(sequence):
        r = DEFAULT_SUCCESS

    if _self.get_setting_int('auto_zoom'):
        _self.zoom(name)

    return r

def fab(input,name=None,mode='peptide',resi=1,chain='',segi='',state=-1,
        dir=1,hydro=-1,ss=0,async_=0,quiet=1,_self=cmd, **kwargs):
    '''
DESCRIPTION

    Build a peptide

ARGUMENTS

    input = str: sequence in one-letter code

    name = str: name of object to create {default: }

    ss = int: Secondary structure 1=alpha helix, 2=antiparallel beta, 3=parallel beta, 4=flat

EXAMPLE

    fab ACDEFGH
    fab ACDEFGH, helix, ss=1
    '''
    async_ = int(kwargs.pop('async', async_))

    if kwargs:
        raise pymol.CmdException('unknown argument: ' + ', '.join(kwargs))

    if async_ < 1:
        r = _fab(input,name,mode,resi,chain,segi,
                 state,dir,hydro,ss,quiet,_self)
    else:
        fab_thread = threading.Thread(target=_fab, args=(input,name,mode,
                                                         resi,chain,
                                                         segi,state,dir,
                                                         hydro,ss,quiet,_self))
        fab_thread.setDaemon(1)
        fab_thread.start()
        r = DEFAULT_SUCCESS
    return r
......

figured out that:

import pymol

pymol.cmd.fab('APAPAP')

pymol.cmd.save('example_3.pdb' , 'obj01')

works, as long as the peptide is the first object you create in the pymol non GUI session