def mutate_all(selection, new_resn, inplace=1, sculpt=0, *args, **kwargs): ''' DESCRIPTION Mutate all residues in selection. By default do mutation in-place (unlike the 'mutate' command which by default works on a copy). FOR SCULPTING ONLY SUPPORTS SELECTIONS WITHIN THE SAME MODEL! SEE ALSO mutate ''' inplace, sculpt = int(inplace), int(sculpt) if sculpt and len(cmd.get_object_list('(' + selection + ')')) > 1: print(' Error: Sculpting in multiple models not supported') raise CmdException kwargs.pop('_self', None) sele_list = set() cmd.iterate(selection, 'sele_list.add("/%s/%s/%s/%s" % (model, segi, chain, resi))', space={'sele_list': sele_list}) for sele in sele_list: mutate(sele, new_resn, inplace, sculpt and not inplace, *args, **kwargs) if sculpt and inplace: sculpt_relax('(' + ' '.join(sele_list) + ')', 0, sculpt == 2)
def get_dehydrons(): cmd.delete('dehydrons') cmd.delete('DH_pairs') cmd.hide() angle = float(angle_value.get()) cutoff = float(dist_cutoff_value.get()) desolv = float(desolv_sphere.get()) min_wrappers = float(min_value.get()) selection = 'name n or name o and not resn hoh' hb = cmd.find_pairs("((byres "+selection+") and n. n)","((byres "+selection+") and n. o)",mode=1,cutoff=cutoff,angle=angle) # sort the list for easier reading hb.sort(lambda x,y:(cmp(x[0][1],y[0][1]))) print "------------------------------------------------\n----------------dehydron Results-----------------\n------------------------------------------------\n Donor | Aceptor | \nChain Residue | Chain Residue | # dehydrons" sel = [] wra = 0 for pairs in hb: cmd.iterate("%s and index %s" % (pairs[0][0], pairs[0][1]), 'stored.nitro = chain, resi, resn') # extracts the nitrogen cmd.iterate("%s and index %s" % (pairs[1][0], pairs[1][1]), 'stored.oxy = chain, resi, resn') # extracts the oxygen wrappers = cmd.select('wrap', '(((chain %s and name ca and resi %s) around %f) or ((chain %s and name ca and resi %s) around %f)) and (not ((neighbor name n*+o*) or (name n*+o*+h*)))' % (stored.nitro[0], stored.nitro[1], desolv, stored.oxy[0], stored.oxy[1], desolv)) #Identifies the putative dehydrons if wrappers < min_wrappers: wra = 1 cmd.distance('Dehydrons',"%s and index %s" % (pairs[0][0],pairs[0][1]),"%s and index %s" % (pairs[1][0],pairs[1][1])) print ' %s%7s%5d | %s%7s%5d |%7s' % (stored.nitro[0], stored.nitro[2], int(stored.nitro[1]), stored.oxy[0], stored.oxy[2], int(stored.oxy[1]), wrappers) if stored.nitro[1] not in sel: sel.append(stored.nitro[1]) if stored.oxy[1] not in sel: sel.append(stored.oxy[1]) if wra == 1: cmd.select('DH_pairs', 'resi %s' % ('+').join(sel)) cmd.show('lines', 'DH_pairs') cmd.disable('DH_pairs') cmd.hide('labels') cmd.delete('wrap') cmd.show('cartoon') cmd.show('dashes')
def test_cbss(self): cmd.load(self.datafile('1oky-frag.pdb')) c = [2, 13, 22] # blue orange forest pymol.util.cbss('*', *c) stored.colors = set() cmd.iterate('*', 'stored.colors.add((ss or "L", color))') self.assertEqual(stored.colors, set(zip('HSL', c)))
def test_colors(self): cmd.fragment('gly') pymol.util.colors("jmol") stored.colors = set() cmd.iterate('elem C', 'stored.colors.add(color)') colors = [get_color_tuple(c, 3) for c in stored.colors] self.assertEqual(colors, [(0.567, 0.567, 0.567)])
def fade_color( sele = "all", fade_extent = 0.7, by_chain = True ): """ Fade out RGB color values associated with a selection. The by_chain variable assumes that chains are uniform color, to allow speedy color setting based on chain, rather than based on residue (which can take a long time!) """ pymol.stored.colors = [] cmd.iterate( sele, "stored.colors.append( (chain, resi, name, color))") res_colors = {} stored_colors = pymol.stored.colors; cols = [] colorname = '' chain = '' prev_chain = '' for chain, resi, name, color in stored_colors: if name == 'CA' or name == 'P': # c-alpha atom if by_chain and chain != prev_chain and len( colorname ) > 0: cmd.color( colorname, 'chain %s and %s' % (prev_chain,sele) ) color_tuple = cmd.get_color_tuple(color) cols = []; for i in range(3): cols.append( fade_extent + ( 1.0 - fade_extent ) * float(color_tuple[ i ]) ) colorname = 'temp_chain%s' % chain cmd.set_color( colorname, cols ) if not by_chain: cmd.color( colorname, 'resi %s and chain %s and %s' % (resi,chain,sele) ) prev_chain = chain if by_chain: cmd.color( colorname, 'chain %s and %s' % (chain,sele) )
def ss(selection): class SSE(object): def __init__(self, start, typ): self.start, self.typ = start, typ self.end = -1 def __repr__(self): return "%s-%s %s" % (self.start, self.end, self.typ) stored.pairs = [] cmd.iterate("%s and n. ca" % selection, "stored.pairs.append((resi, ss))") num, currentType = stored.pairs[0] sses = [SSE(num, currentType)] currentSSE = sses[0] for resi, ssType in stored.pairs: if ssType == currentType: currentSSE.end = resi else: sses.append(SSE(resi, ssType)) currentSSE = sses[-1] currentType = ssType for sse in sses: print sse
def cartoonize(color, rep): """draw a cartoon representation of glycans""" stored.ResiduesNumber = [] cmd.iterate('name c1', 'stored.ResiduesNumber.append((resi))') resn_list = [int(i) for i in stored.ResiduesNumber] bonds = get_glyco_bonds(resn_list[0], resn_list[-1]+1) con_matrix = writer(bonds) #con_matrix = writer2(bonds) rings = find_rings(resn_list) rings_coords = get_ring_coords(resn_list, rings) bonds_coords = get_bonds_coords(resn_list, con_matrix) colors = get_colors_c1(resn_list, color) bonds_colors = get_bonds_colors(resn_list, con_matrix, color) cmd.set('suspend_updates', 'on') for state, coords in enumerate(rings_coords): obj = [] if rep == 'beads': radius_s = 1.8 radius_b = 0.18 obj = beads(obj, coords, colors[state], radius_s) obj = cylinder(obj, bonds_coords[state], bonds_colors[state], radius_b) else: if rep == 'cartoon': radius = 0.075 else: radius = 0.035 obj = hexagon(obj, coords, colors[state], rep, radius) obj = cylinder(obj, bonds_coords[state], bonds_colors[state], radius) cmd.load_cgo(obj,'cgo01', state+1) cmd.select('glycan', 'byres name C1') cmd.delete('glycan') cmd.delete('tmp') cmd.set('two_sided_lighting', 1) cmd.set('suspend_updates', 'off')
def defineShiftRange(displayed, cs_fn, f3width, f3left): """ Define shift range of selected atoms @param displayed: hydrogen atoms in the center selection or covalently bonded to any atoms in the center selection """ # define shift range of selected atoms maxf3, minf3 = -10000.0, 10000.0 # get the chemshifts of the atoms in the selection sphere # make a copy of the chemshifts file first shutil.copyfile(cs_fn, cs_fn+'.bak') cs_dict = readChemshifts(cs_fn) cs_list = [] stored.list = [] cmd.iterate(displayed, "stored.list.append((resi,resn,name))") for resi,resn,name in stored.list: if name in ['HN','HT1','HT2','HT3']: name = 'H' # rename proton collecting to bb N k = "%5s %s %4s" % (resi, resn, name) try: cs_list.append(cs_dict[k]) csv = float(cs_dict[k][18:26]) if csv > maxf3: maxf3 = csv if csv < minf3: minf3 = csv except KeyError: #pass # TODO: check the output.txt after back-calc print "INFO: Could not find chemshift for", k #for cs in cs_list: print cs # debug print f3shift = maxf3 + 0.2 # left edge of the spectrum f3sweep = maxf3 - minf3 + 0.4 # direct 1H sweep width if f3width is not None: f3sweep = f3width if f3left is not None: f3shift = f3left return f3sweep, f3shift
def write_seq_positions(groupdict, selection, csvfile, object_name = 'molecule'): for name in groupdict: # Get the selection: seq_positions = get_seq_positions(name + '.' + object_name, name + '.' + selection) # The first position of each line holds the pdbid to_be_written = [name] # The second position holds the sequence of the selection # Programs loading these selections will see if they can replicate # the sequence. If they can't, they may be using different indices or # something else bad. stored.sequence = '' cmd.iterate(name + '.' + object_name + ' & polymer & n. CA', 'stored.sequence += one_letter[resn]') filtered_sequence = '' for n in seq_positions: filtered_sequence += stored.sequence[n] to_be_written.append(filtered_sequence) # All the positions after the second hold indices. to_be_written += seq_positions csvfile.writerow(to_be_written)
def collapse_resi(selection='(sele)', quiet=1): ''' DESCRIPTION Returns a compact selection macro for the given selection on residue number (resi) level. Rewrite of http://pymolwiki.org/index.php/CollapseSel ARGUMENTS selection = string: atom selection {default: (sele)} ''' from collections import defaultdict s_dict = defaultdict(set) cmd.iterate(selection, 's_dict[model,segi,chain].add(resv)', space=locals()) r_all = [] for key, s in s_dict.items(): s = sorted(s) r = [[s[0], s[0]]] for i in s[1:]: if i <= r[-1][1] + 1: r[-1][1] = i else: r.append([i,i]) resi = '+'.join(('%d-%d' % (f,t) if f != t else '%d' % (f)) for (f,t) in r) r_all.append('/%s/%s/%s/' % key + resi) if not int(quiet): for r in r_all: print(' collapse_resi: ' + str(r)) return ' '.join(r_all)
def measure_all_torsions(sele,prot_dict): id_list = cmd.identify("((%s) and name ca)"%sele) for a in id_list: res_sele = "(alt '' and (byres id %d) and (%s))"%(a,sele) lst = find_torsions(res_sele) if len(lst): cmd.iterate("(%s and n;ca)"%res_sele,"stored.resn=resn") resn = pymol.stored.resn print resn name_list = [] for a in lst: pymol.stored.names = [] for b in a: cmd.iterate("(%s and id %d)"%(res_sele,b),"stored.names.append(name)") name_list.append(tuple(pymol.stored.names)) res_dict = {} for a in name_list: dihe = cmd.get_dihedral("(%s and name %s)"%(res_sele,a[0]), "(%s and name %s)"%(res_sele,a[1]), "(%s and name %s)"%(res_sele,a[2]), "(%s and name %s)"%(res_sele,a[3])) res_dict[a]=dihe if not prot_dict.has_key(resn): prot_dict[resn]=[] prot_dict[resn].append(res_dict)
def testMAEchempy(self, molfilename): cmd.load(self.datafile(molfilename), 'test', object_props='*', atom_props='*') objs = cmd.get_object_list() for obj in objs: idxToVal = {} natoms = cmd.count_atoms(obj) for i in range(natoms): idxToVal[i+1] = i*10 cmd.set_atom_property('test_prop', i*10, "index %d and %s" % (i+1, obj)) model = cmd.get_model(obj) # test to make sure the properties that exist are the same prop_list= cmd.get_property_list(obj) mol_prop_list = [x[0] for x in model.molecule_properties] self.assertEqual(set(prop_list), set(mol_prop_list)) # need to test whether the values are the same for prop, val in model.molecule_properties: propval = cmd.get_property(prop, obj) self.assertEqual(propval, val) self.assertEqual(natoms, len(model.atom)) # need to test values of all atom properties, including the ones that were set above stored.prop_lookup = {} cmd.iterate(obj, "stored.prop_lookup[index-1] = properties.all") idx = 0 for at in model.atom: for prop in at.atom_properties.keys(): val = at.atom_properties[prop] self.assertEqual(val, stored.prop_lookup[idx][prop]) idx += 1
def ss(selection): """A command to list a summary of the secondary structure for a selection. Use like "ss my_protein" where "my_protein" is the name of the chain or structure in view. """ class SSE(object): def __init__(self, start, typ): self.start, self.typ = start, typ self.end = -1 def __repr__(self): return "%s-%s %s" % (self.start, self.end, self.typ) stored.pairs = [] cmd.iterate("%s and n. ca" % selection, "stored.pairs.append((resi, ss))") num, currentType = stored.pairs[0] sses = [SSE(num, currentType)] currentSSE = sses[0] for resi, ssType in stored.pairs: if ssType == currentType: currentSSE.end = resi else: sses.append(SSE(resi, ssType)) currentSSE = sses[-1] currentType = ssType for sse in sses: print sse
def preProcessPDB(fname): stored.residues = [] stored.chains = [] cmd.iterate('(name ca)', 'stored.residues.append(resi)') cmd.iterate('(name ca)', 'stored.chains.append(chain)') cmd.show_as("cartoon", '(all)') cmd.color("white", '(all)')
def sele2Color(self, sele): globalShader = self.optionMenu_shader.getvalue() newShader = self.seleShaderDict[sele] if newShader != globalShader: # should be different from global shader, otherwise do nothing newColorInc = ShaderFactory.seleSlot[newShader] stored.idcolor_list = set() cmd.iterate(sele, 'stored.idcolor_list.add(int(color))') if(len(stored.idcolor_list)>1): self.selectionConsole.set('Warning: Selection [%s] contains more than one color.' % sele) color = stored.idcolor_list.pop() rgb_color = cmd.get_color_tuple(color) if rgb_color[2] >= 0.990: color_id = '%s %s %s' % (str(rgb_color[0])[0:5].ljust(5, '0'), str(rgb_color[1])[0:5].ljust(5, '0'), str(rgb_color[2]-newColorInc)[0:5]) else: color_id = '%s %s %s' % (str(rgb_color[0])[0:5].ljust(5, '0'), str(rgb_color[1])[0:5].ljust(5, '0'), str(rgb_color[2]+newColorInc)[0:5]) # color_id from all the sele:shader dictionary # determine color_id:shader pair if color_id not in self.spColorShaderDict: self.spColorShaderDict[color_id] = [newShader, sele] # apply new color to atom set newRGB = color_id.split(' ') newColor = [float(newRGB[0]), float(newRGB[1]), float(newRGB[2])] cmd.set_color(color_id, newColor) cmd.color(color_id, sele) print 'apply shader [%s] to selection [%s].' % (newShader, sele)
def _testLabelByAtomType(self): cmd.load(self.datafile('1oky.pdb.gz')) cmd.remove("alt 'B'") cmd.label('resn STU', 'text_type') c3labels = [] cmd.iterate("resn STU", "c3labels.append(label == 'C.3')", space=locals()) self.assertEquals(sum(c3labels), 8)
def get_b_limits(input='[0,100]', selection='all'): from pymol import cmd, stored import math try: limits=str(input) if limits.startswith('['): # list limits=eval(limits)[:2] else: #integer selection=str(selection) limits=abs(float(limits)) if limits>50: return False stored.temp=[] cmd.iterate(selection, 'stored.temp.append(b)') stored.temp.sort() kl=(len(stored.temp)-1)*limits/100 fl=math.floor(kl) cl=math.ceil(kl) kr=(len(stored.temp)-1)*(100-limits)/100 fr=math.floor(kr) cr=math.ceil(kr) limits=[0,0] if fl==cl: limits[0]=stored.temp[int(kl)] else: limits[0]=stored.temp[int(kl)]*(cl-kl)+stored.temp[int(kl)]*(kl-fl) if fr==cr: limits[1]=stored.temp[int(kr)] else: limits[1]=stored.temp[int(kr)]*(cr-kr)+stored.temp[int(kr)]*(kr-fr) except: return False return limits
def testMMTF(self): '''Styled MMTF export/import''' S = 0b10 # 1 << 1 spheres D = 0b1000000000 # 1 << 9 dots B = 2 # blue R = 4 # red cmd.fragment('gly') cmd.color(B) cmd.color(R, 'elem C') cmd.show_as('spheres') cmd.show_as('dots', 'elem C') with testing.mktemp('.mmtf') as filename: cmd.save(filename) cmd.delete('*') cmd.load(filename) color_list = [] reps_list = [] cmd.iterate('*', 'color_list.append(color)', space=locals()) cmd.iterate('*', 'reps_list.append(reps)', space=locals()) self.assertEqual(color_list, [B, R, R, B, B, B, B]) self.assertEqual(reps_list, [S, D, D, S, S, S, S])
def testExportStyle(self): cmd.fab('ACDEF', 'm1') cmd.hide() cmd.show('cartoon', 'resi 1-3') cmd.show('lines', 'resn CYS') cmd.show('sticks', 'resn ASP+PHE') cmd.show('spheres', 'resn GLU') cmd.set('stick_ball', 1, 'resn PHE') cmd.set('stick_ball_ratio', 1.5, 'm1') testlabel = 'Hello "World"' cmd.label('name SG', repr(testlabel)) with testing.mktemp('.mae') as filename: cmd.save(filename) cmd.delete('*') cmd.load(filename, 'm2') g_labels = [] cmd.iterate('name SG', 'g_labels.append(label)', space=locals()) cmd.alter('*', 'b = 1 if s.stick_ball else 0') self._assertCountEqual('rep cartoon & guide', 'resi 1-3 & guide') self._assertCountEqual('rep lines', 'resn CYS', delta=1) self._assertCountEqual('rep sticks', 'resn ASP+PHE') self._assertCountEqual('rep spheres', 'resn GLU') self._assertCountEqual('b > 0.5', 'resn PHE') self.assertTrue(cmd.get_setting_float('stick_ball_ratio', 'm2') > 1.1) self.assertEqual(g_labels[0], testlabel)
def iterate_plot(selection, expr_y, expr_x=None, scatter=0, filename=None, space=None, quiet=1): ''' DESCRIPTION Plot atomic properties. ARGUMENTS selection = string: atom selection expr_y = string: python expression for y values expr_x = string: python expression for x values {default: None} scatter = 0/1: make line plot or scatter plot {default: 0, line plot} EXAMPLE # C-alpha b-factors iterate_plot name CA, b, resv ''' from . import matplotlib_fix from matplotlib.pyplot import figure scatter, quiet = int(scatter), int(quiet) if space is None: space = {'cmd': cmd, 'stored': cmd.pymol.stored} if cmd.is_string(selection): if selection.startswith('['): sele_list = selection[1:-1].split(',') else: sele_list = ['(%s) and (%s)' % (model, selection) for model in cmd.get_object_list('(' + selection + ')')] else: sele_list = selection fig = figure() plt = fig.add_subplot(111) for selection in sele_list: space['_values'] = y_values = [] cmd.iterate(selection, '_values.append(' + expr_y + ')', space=space) if expr_x is None: x_values = range(len(y_values)) else: space['_values'] = x_values = [] cmd.iterate(selection, '_values.append(' + expr_x + ')', space=space) color = get_model_color(selection) if scatter: plt.scatter(x_values, y_values, c=color) else: plt.plot(x_values, y_values, c=color) _showfigure(fig, filename, quiet)
def findSurfaceResidues(objSel="(all)", cutoff=2.5, doShow=False, verbose=True): """ findSurfaceResidues finds those residues on the surface of a protein that have at least 'cutoff' exposed A**2 surface area. PARAMS objSel (string) the object or selection in which to find exposed residues DEFAULT: (all) cutoff (float) your cutoff of what is exposed or not. DEFAULT: 2.5 Ang**2 asSel (boolean) make a selection out of the residues found RETURNS (list: (chain, resv ) ) A Python list of residue numbers corresponding to those residues w/more exposure than the cutoff. """ tmpObj="__tmp" cmd.create( tmpObj, objSel + " and polymer"); if verbose!=False: print "WARNING: I'm setting dot_solvent. You may not care for this." cmd.set("dot_solvent"); cmd.get_area(selection=tmpObj, load_b=1) # threshold on what one considers an "exposed" atom (in A**2): cmd.remove( tmpObj + " and b < " + str(cutoff) ) stored.tmp_dict = {} cmd.iterate(tmpObj, "stored.tmp_dict[(chain,resv)]=1") exposed = stored.tmp_dict.keys() exposed.sort() randstr = str(random.randint(0,10000)) selName = "exposed_atm_" + randstr if verbose!=False: print "Exposed residues are selected in: " + selName cmd.select(selName, objSel + " in " + tmpObj ) selNameRes = "exposed_res_" + randstr cmd.select(selNameRes, "byres " + selName ) if doShow!=False: cmd.show_as("spheres", objSel + " and poly") cmd.color("white", objSel) cmd.color("red", selName) cmd.delete(tmpObj) print exposed return exposed
def testAdvanced(self): cmd.fab('A/123/ ADC B/234/ AFCD') v = cmd.get_chains() self.assertEqual(v, ['A', 'B']) cmd.iterate('last chain B', 'stored.v = (resv, resn)') self.assertEqual(stored.v, (237, 'ASP'))
def _test_cba(self, fun, expected_color): cmd.fragment('gly') cmd.color('white') fun('*') stored.colors = set() cmd.iterate('elem C', 'stored.colors.add(color)') colors = [get_color_tuple(c, 3) for c in stored.colors] self.assertEqual(colors, [expected_color])
def start(self,sel): self.lock = 1 cmd.iterate('(%s) and name CA' % sel,'idx2resn[model,index] = (resn, color, ss)', space={'idx2resn': self.canvas.idx2resn}) for model_index, (phi,psi) in cmd.get_phipsi(sel, self.state).iteritems(): print " Plotting Phi,Psi: %8.2f,%8.2f" % (phi, psi) self.canvas.plot(phi, psi, model_index) self.lock = 0
def colorByProp(self, prop, palette="rainbow"): stored.propUniqVals = set() cmd.iterate(self.objName, "stored.propUniqVals.add(%s)" % prop) v = sorted(stored.propUniqVals) b = n.arange(1, len(v) + 1, dtype=float) # / len(v) stored.b = dict(zip(v, b)) cmd.alter(self.objName, "b=stored.b[%s]" % prop) cmd.spectrum("b", palette, self.objName)
def test_stub2ala(): cmd.reinitialize() cmd.fab('EFG', 'm1') cmd.remove('not (backbone or name CB)') psico.editing.stub2ala() my_values = [] cmd.iterate('guide', 'my_values.append(resn)', space=locals()) assert my_values == ['ALA', 'ALA', 'GLY']
def renumber(selection='all', start=1, startsele=None, quiet=1): ''' DESCRIPTION Set residue numbering (resi) based on connectivity. ARGUMENTS selection = string: atom selection to renumber {default: all} start = integer: counting start {default: 1} startsele = string: residue to start counting from {default: first in selection} ''' start, quiet = int(start), int(quiet) model = cmd.get_model(selection) cmd.iterate(selection, 'atom_it.next().model = model', space={'atom_it': iter(model.atom)}) if startsele is not None: startidx = cmd.index('first (' + startsele + ')')[0] for atom in model.atom: if (atom.model, atom.index) == startidx: startatom = atom break else: print(' Error: startsele not in selection') raise CmdException else: startatom = model.atom[0] for atom in model.atom: atom.adjacent = [] atom.visited = False for bond in model.bond: atoms = [model.atom[i] for i in bond.index] atoms[0].adjacent.append(atoms[1]) atoms[1].adjacent.append(atoms[0]) minmax = [start, start] def traverse(atom, resi): atom.resi = resi atom.visited = True for other in atom.adjacent: if other.visited: continue if (atom.name, other.name) in [('C', 'N'), ("O3'", 'P')]: minmax[1] = resi + 1 traverse(other, resi + 1) elif (atom.name, other.name) in [('N', 'C'), ('P', "O3'")]: minmax[0] = resi - 1 traverse(other, resi - 1) elif (atom.name, other.name) not in [('SG', 'SG')]: traverse(other, resi) traverse(startatom, start) cmd.alter(selection, 'resi = atom_it.next().resi', space={'atom_it': iter(model.atom)}) if not quiet: print(' Renumber: range (%d to %d)' % tuple(minmax))
def spectrumproperty(propname, color_list, selection='(all)', minimum=None, maximum=None, quiet=1): ''' DESCRIPTION Define a color spectrum with as many color-stops as you like (at least 2). ARGUMENTS propname = string: property name which has a float value. color_list = string: Space separated list of colors ... all other arguments like with `spectrum` command ''' quiet = int(quiet) colors = color_list.split() if len(colors) < 2: print 'failed! please provide at least 2 colors' return colvec = [cmd.get_color_tuple(i) for i in colors] parts = len(colvec) - 1 value_list = [] cmd.iterate(selection, 'value_list.append(properties[propname])', space=locals()) if len(value_list) == 0: print 'empty selection' return if minimum is None: minimum = min(value_list) if maximum is None: maximum = max(value_list) minimum, maximum = float(minimum), float(maximum) val_range = (maximum - minimum) * (1 + 1e-6) if not quiet: print ' Spectrum: range (%.5f to %.5f)' % (minimum, maximum) if maximum == minimum: print 'no spectrum possible, only equal values' return rgb = lambda i, p, j: int(255 * (colvec[i+1][j] * p + colvec[i][j] * (1.0 - p))) col_list = [] for value in value_list: p = (value - minimum) / val_range * parts i = int(p) p -= i col_list.append(0x40000000 + rgb(i, p, 0) * 0x10000 + rgb(i, p, 1) * 0x100 + rgb(i, p, 2)) cmd.alter(selection, 'color = col_iter.next()', space={'col_iter': iter(col_list)}) cmd.recolor()
def dehydron(selection='all', angle_range=40, max_distance=3.5, desolv=6.5, min_wrappers=19, quiet=0): ''' DESCRIPTION dehydron calculator USAGE dehydron [ selection [, angle_range [, max_distance [, desolv [, min_wrappers ]]]]] ''' angle, max_distance = float(angle_range), float(max_distance) desolv, min_wrappers = float(desolv), int(min_wrappers) quiet = int(quiet) name = cmd.get_legal_name('DH_%s' % selection) cmd.delete(name) selection_hb = '((%s) and polymer)' % (selection) hb = cmd.find_pairs("((byres "+selection_hb+") and n. n)","((byres "+selection_hb+") and n. o)",mode=1,cutoff=max_distance,angle=angle_range) if not quiet: hb.sort(lambda x,y:(cmp(x[0][1],y[0][1]))) print "--------------------------------------------------------------------" print "--------------------------Dehydron Results--------------------------" print "--------------------------------------------------------------------" print " Donor | Aceptor |" print " Object Chain Residue | Object Chain Residue | # wrappers" cmd.select('_nonpolar', '(elem C) and not (solvent or (elem N+O) extend 1)', 0) try: cmd.select('_selection', '%s' % selection, 0) except: pass sel = [] for pairs in hb: wrappers = cmd.count_atoms('((%s and _nonpolar and _selection) within %f of byca (%s`%d %s`%d))' % ((pairs[0][0], desolv) + pairs[0] + pairs[1])) if wrappers < min_wrappers: cmd.distance(name, pairs[0], pairs[1]) if not quiet: cmd.iterate(pairs[0], 'stored.nitro = chain, resi, resn') cmd.iterate(pairs[1], 'stored.oxy = chain, resi, resn') print ' %12s%4s%6s%5d | %12s%4s%6s%5d |%7s' % (pairs[0][0], stored.nitro[0], stored.nitro[2], int(stored.nitro[1]), pairs[1][0], stored.oxy[0], stored.oxy[2], int(stored.oxy[1]), wrappers) sel.append(pairs[0]) sel.append(pairs[1]) cmd.delete('_nonpolar') cmd.delete('_selection') if len(sel) > 0: cmd.show_as('dashes', name) elif not quiet and len(hb) != 0: print ' - no dehydrons were found - ' else: print ' - no hydrogen bonds were found - '
def getAllAtoms(sele): '''Get the names of all the atoms in the selection. ''' myspace = {'names':[]} cmd.iterate(sele, "names.append(name)", space=myspace) return myspace['names']
from pymol import cmd, stored stored.list = [] cmd.iterate("(wachin)", "stored.list.append(index)") print stored.list
def add_missing_atoms(selection='all', cycles=200, quiet=1): ''' DESCRIPTION Mutate those residues to themselves which have missing atoms SEE ALSO stub2ala ''' from collections import defaultdict from chempy import fragments cycles, quiet = int(cycles), int(quiet) reference = { 'ALA': set(['CB']), 'ARG': set(['CB', 'CG', 'NE', 'CZ', 'NH1', 'NH2', 'CD']), 'ASN': set(['CB', 'CG', 'OD1', 'ND2']), 'ASP': set(['CB', 'CG', 'OD1', 'OD2']), 'CYS': set(['CB', 'SG']), 'GLN': set(['CB', 'CG', 'CD', 'NE2', 'OE1']), 'GLU': set(['CB', 'CG', 'OE2', 'CD', 'OE1']), 'GLY': set([]), 'HIS': set(['CE1', 'CB', 'CG', 'CD2', 'ND1', 'NE2']), 'ILE': set(['CB', 'CD1', 'CG1', 'CG2']), 'LEU': set(['CB', 'CG', 'CD1', 'CD2']), 'LYS': set(['CB', 'CG', 'NZ', 'CE', 'CD']), 'MET': set(['CB', 'CG', 'CE', 'SD']), 'PHE': set(['CE1', 'CB', 'CG', 'CZ', 'CD1', 'CD2', 'CE2']), 'PRO': set(['CB', 'CG', 'CD']), 'SER': set(['OG', 'CB']), 'THR': set(['CB', 'OG1', 'CG2']), 'TRP': set([ 'CZ2', 'CB', 'CG', 'CH2', 'CE3', 'CD1', 'CD2', 'CZ3', 'NE1', 'CE2' ]), 'TYR': set(['CE1', 'OH', 'CB', 'CG', 'CZ', 'CD1', 'CD2', 'CE2']), 'VAL': set(['CB', 'CG1', 'CG2']), } namedsele = cmd.get_unused_name('_') cmd.select(namedsele, selection, 0) namelists = defaultdict(list) cmd.iterate('(%s) and polymer' % namedsele, 'namelists[model,segi,chain,resn,resi,resv].append(name)', space=locals()) sele_dict = defaultdict(list) tmp_name = cmd.get_unused_name('_') for key, namelist in namelists.items(): resn = key[3] if resn not in reference: if not quiet: print(' Unknown residue: + ' + resn) continue if not reference[resn].issubset(namelist): try: frag = fragments.get(resn.lower()) for a in frag.atom: a.segi = key[1] a.chain = key[2] a.resi = key[4] a.resi_number = key[5] cmd.load_model(frag, tmp_name, 1, zoom=0) skey = '/%s/%s/%s/%s`%s' % key[:5] cmd.remove(skey + ' and not name N+C+O+OXT+CA') cmd.align(tmp_name, skey + ' and name N+C+CA', cycles=0) cmd.remove(tmp_name + ' and (name N+C+O+CA or hydro)') cmd.fuse('name CB and ' + tmp_name, 'name CA and ' + skey, move=0) if resn == 'PRO': cmd.bond(skey + '/N', skey + '/CD') cmd.unpick() cmd.delete(tmp_name) sele_dict[key[0]].append(skey) if not quiet: print(' Mutated ' + skey) except: print(' Mutating ' + skey + ' failed') for model in sele_dict: cmd.sort(model) sculpt_relax(' '.join(sele_dict[model]), 0, 0, model, cycles) cmd.delete(namedsele)
def rand_sequence(selector): """ DESCRIPTION The "rand_sequence" takes a selection and randomizes the amino acid identities in it. Random rotamers are selected. USAGE rand_sequence selector ARGUMENTS selector = string: name of the selection to "design" NOTES Any residues that do not contain a CA atom will be ignored. """ #Create lists to contain object, chain and resi info for each residue in selection. stored.atomlist_object = [] stored.atomlist_chain = [] stored.atomlist_resi = [] #Populate the lists with all CA atoms in the selector. cmd.iterate( '(' + selector + ') and name ca', 'stored.atomlist_object.append(model); stored.atomlist_chain.append(chain); stored.atomlist_resi.append(resi)' ) #Make a list of residue types res_types = [ 'ALA', 'CYS', 'ASP', 'GLU', 'PHE', 'GLY', 'HIS', 'ILE', 'LYS', 'LEU', 'MET', 'ASN', 'PRO', 'GLN', 'ARG', 'SER', 'THR', 'VAL', 'TRP', 'TYR' ] #For each residue: #1. Select a random residue to mutate to. #2. Start the mutagenesis wizard interface. #3. Figure out how many backbone-dependent rotamers exist for that residue. #4. Select a random rotamer to mutate to. #5. Mutate to the desired residue. #6. Clean-up the wizard and make the mutation. for atomidx in range(len(stored.atomlist_resi)): curres = stored.atomlist_object[ atomidx] + ' and chain ' + stored.atomlist_chain[ atomidx] + ' and resi ' + stored.atomlist_resi[atomidx] #Pick a random residue type. newres = random.choice(res_types) #Set up the mutagenesis wizard. cmd.wizard('mutagenesis') cmd.refresh_wizard #Select the desired residue to mutate as (sele) cmd.select('sele', 'none') cmd.select('sele', curres) #Generate the library of backbone-independent rotamers. lib = cmd.get_wizard().ind_library.get(newres) print(newres) #Change the residue to the selected residue type cmd.get_wizard().do_select('''sele''') cmd.get_wizard().set_mode(newres) #If the residue is not GLY, pick a random rotamer and change to it. if (newres not in ('GLY', 'ALA')): newrot = random.randint(1, len(lib)) cmd.get_wizard().do_state(newrot) #Apply the changes cmd.get_wizard().apply() #Clear the wizard cmd.get_wizard().clear() cmd.set_wizard()
def tmFRET(obj, chain, r1, r2, dist, force=False, strict=False): """ DESCRIPTION Finds all residues within dist of the midpoint between n1 and n2, and calculates their solvent accessible radii. USAGE tmFRET obj, chain, r1, r2, dist[, force=False[, strict=False]] EXAMPLES tmFRET 3j5p, c, 378, 380, 20 # Finds calphas w/in 20 ang. of the MBS between 378 and 380 on chain c of object 3j5p """ # Identify target metal binding site residues res1str = "chain " + chain + " and resi " + r1 res2str = "chain " + chain + " and resi " + r2 cmd.set('dot_solvent', 1) sasa1 = cmd.get_area(res1str) sasa2 = cmd.get_area(res2str) if ((sasa1 < 10.0) or (sasa2 < 10.0)): if (not force): print "WARNING: One or both of the residues you selected are likely buried." print res1str + " SASA: " + str(sasa1) print res2str + " SASA: " + str(sasa2) print "If you wish to run the tmFRET helper on this pair anyway, please use:" print "tmFRET object, chain, residue1, residue2, distance, force=True" return else: print "WARNING: being forced to run the tmFRET helper on a poorly accessible site:" print res1str + " SASA: " + str(sasa1) print res2str + " SASA: " + str(sasa2) else: print res1str + " SASA: " + str(sasa1) print res2str + " SASA: " + str(sasa2) print "Beginning mutagenesis. Please be patient, this may take some time..." # mutate residues to his cmd.wizard("mutagenesis") cmd.do("refresh_wizard") cmd.get_wizard().set_mode("HIS") # Set up lists of nitrogen positions # also track CE1 posns to prevent odd orientations ND1_1list = [] NE2_1list = [] CE1_1list = [] ND1_2list = [] NE2_2list = [] CE1_2list = [] # find all posns for nitrogens for first histidine cmd.get_wizard().do_select(res1str) nRot = cmd.count_states() # Find number of possible rotomers for i in range(1,nRot+1): cmd.get_wizard().do_select(res1str) cmd.frame(i) cmd.get_wizard().apply() ND1pos = cmd.get_coords(res1str + " and name ND1")[0] NE2pos = cmd.get_coords(res1str + " and name NE2")[0] CE1pos = cmd.get_coords(res1str + " and name CE1")[0] pos1String = "[%3.2f,%3.2f,%3.2f]" % (ND1pos[0], ND1pos[1], ND1pos[2]) #print res1str + " rotamer " + str(i) + " ND1 at " + pos1String pos2String = "[%3.2f,%3.2f,%3.2f]" % (NE2pos[0], NE2pos[1], NE2pos[2]) #print res1str + " rotamer " + str(i) + " NE2 at " + pos2String ND1_1list.append(ND1pos) NE2_1list.append(NE2pos) CE1_1list.append(CE1pos) # find all posns for nitrogens for second histidine cmd.get_wizard().do_select(res2str) nRot = cmd.count_states() # Find number of possible rotomers for i in range(1,nRot+1): cmd.get_wizard().do_select(res2str) cmd.frame(i) cmd.get_wizard().apply() ND1pos = cmd.get_coords(res2str + " and name ND1")[0] NE2pos = cmd.get_coords(res2str + " and name NE2")[0] CE1pos = cmd.get_coords(res2str + " and name CE1")[0] pos1String = "[%3.2f,%3.2f,%3.2f]" % (ND1pos[0], ND1pos[1], ND1pos[2]) #print res2str + " rotamer " + str(i) + " ND1 at " + pos1String pos2String = "[%3.2f,%3.2f,%3.2f]" % (NE2pos[0], NE2pos[1], NE2pos[2]) #print res2str + " rotamer " + str(i) + " NE2 at " + pos2String ND1_2list.append(ND1pos) NE2_2list.append(NE2pos) CE1_2list.append(CE1pos) # iterate over all pairs of nitrogens, determining distance for each # Compare to distance for an "ideal" metal binding site, and save best pair idealDistance = 3.0 bestDistance = 3.6 # use default bestDist to gate what range of values we'll accept delta = math.fabs(idealDistance - bestDistance) besti = -1 bestj = -1 r1N = "" r2N = "" print "r1rot,r2rot,ND1-ND1,ND1-NE2,NE2-ND1,NE2-NE2" for i in range(len(ND1_1list)): # iterate over 1st H rotamers for j in range(len(ND1_2list)): # iterate over 2nd H rotamers # Debug diagnostic, or can be used to generate a printout to make a histogram in Excel dND11_ND12 = distance(ND1_1list[i],ND1_2list[j]) dND11_NE22 = distance(ND1_1list[i],NE2_2list[j]) dNE21_ND12 = distance(NE2_1list[i],ND1_2list[j]) dNE21_NE22 = distance(NE2_1list[i],NE2_2list[j]) print "%i,%i,%3.2f,%3.2f,%3.2f,%3.2f" % (i, j, dND11_ND12, dND11_NE22, dNE21_ND12, dNE21_NE22) tmpDist = distance(ND1_1list[i],ND1_2list[j]) tmpDelta = math.fabs(tmpDist-idealDistance) if (tmpDelta < delta): #check other nitrogen pair, to make sure they're facing away from MBS (ie: not clashing) tmpDist2 = distance(NE2_1list[i],NE2_2list[j]) if (tmpDist2 > tmpDist): # check apical carbons, to make sure they're not pointing into MBS tmpDist3 = distance(CE1_1list[i],CE1_2list[j]) if strict and (tmpDist3 > tmpDist): delta = tmpDelta bestDistance = tmpDist besti = i bestj = j r1N = "ND1" r2N = "ND1" tmpDist = distance(ND1_1list[i],NE2_2list[j]) tmpDelta = math.fabs(tmpDist-idealDistance) if (tmpDelta < delta): tmpDist2 = distance(NE2_1list[i],ND1_2list[j]) if (tmpDist2 > tmpDist): tmpDist3 = distance(CE1_1list[i],CE1_2list[j]) if strict and (tmpDist3 > tmpDist): delta = tmpDelta bestDistance = tmpDist besti = i bestj = j r1N = "ND1" r2N = "NE2" tmpDist = distance(NE2_1list[i],ND1_2list[j]) tmpDelta = math.fabs(tmpDist-idealDistance) if (tmpDelta < delta): tmpDist2 = distance(ND1_1list[i],NE2_2list[j]) if (tmpDist2 > tmpDist): tmpDist3 = distance(CE1_1list[i],CE1_2list[j]) if strict and (tmpDist3 > tmpDist): delta = tmpDelta bestDistance = tmpDist besti = i bestj = j r1N = "NE2" r2N = "ND1" tmpDist = distance(NE2_1list[i],NE2_2list[j]) tmpDelta = math.fabs(tmpDist-idealDistance) if (tmpDelta < delta): tmpDist2 = distance(ND1_1list[i],ND1_2list[j]) if (tmpDist2 > tmpDist): tmpDist3 = distance(CE1_1list[i],CE1_2list[j]) if strict and (tmpDist3 > tmpDist): delta = tmpDelta bestDistance = tmpDist besti = i bestj = j r1N = "NE2" r2N = "NE2" if (besti == -1 or bestj == -1): #couldn't find a rotamer pair in the accepted distance range print "No appropriate rotamers could be found for the selected metal binding site residue pair. Please try again with different residues." # recover original residues here somehow, should go back and build this in cmd.set_wizard("done") #cleanup return # set up the MBS cmd.get_wizard().do_select(res1str) cmd.frame(besti+1) cmd.get_wizard().apply() cmd.get_wizard().do_select(res2str) cmd.frame(bestj+1) cmd.get_wizard().apply() cmd.set_wizard("done") #cleanup # make the metal as a pseudoatom posn1 = cmd.get_coords(res1str + " and name " + r1N) posn2 = cmd.get_coords(res2str + " and name " + r2N) # midpoint between 2 coordinating nitrogens is the MBS MBS = (posn1 + posn2) / 2 MBS = MBS[0] # necessary b/c get_coords returns a coord list: [[x,y,z]] # make a pseudoatom at the MBS posString = "[%3.2f,%3.2f,%3.2f]" % (MBS[0], MBS[1], MBS[2]) print "Making metal pseudoatom at" + posString cmd.pseudoatom("XitionMetal", pos=posString) cmd.show("spheres", "XitionMetal") # find the residues within dist of the MBS selString="XitionMetal around " + dist + " and name cb" cmd.select("potentialSites", selString) # iterate over the residues in the selection, coloring Calpha by the solvent accessible surface area myspace={'markAccessible': markAccessible} cmd.iterate('(potentialSites)', 'markAccessible(model, chain, resi)', space=myspace)
'hip', 'hie', 'hid', 'ile', 'leu', 'lys', 'met', 'phe', 'pro', 'ser', 'thr', 'trp', 'tyr', 'val'): stored.fc_dict = {} print "'" + string.upper(grp) + "': [" for res in (grp, "nt_" + grp, "ct_" + grp): ch = Champ() print " (" if grp == 'wat' and len(res) > 3: continue cmd.fragment(res, "tmp") stored.pc_dict = {} stored.at_dict = {} cmd.iterate( "tmp", "stored.pc_dict[name]=partial_charge;stored.at_dict[name]=text_type", quiet=1) if res[0:3] == "ct_": cmd.alter("name OXT", "formal_charge=-1") elif res[0:3] == "nt_": cmd.alter("name N", "formal_charge=1") # some PyMOL fragments are missing formal charges... cmd.alter("GLU/OE2|ASP/OD2", "formal_charge=-1") cmd.alter("HIP/ND1|ARG/NH1|LYS/NZ", "formal_charge=1") model = cmd.get_model("tmp") cmd.delete("tmp") m1 = ch.insert_model(model) ch.pattern_detect_chirality(m1) ch.pattern_orient_bonds(m1) pat1 = ch.pattern_get_string_with_names(m1)
def test_dss(self): ss_list = [] cmd.fab('A' * 6, ss=1) cmd.dss() cmd.iterate('2-5/CA', 'ss_list.append(ss)', space=locals()) self.assertEqual(ss_list, ['H', 'H', 'H', 'H'])
def spectrumany(expression, color_list, selection='(all)', minimum=None, maximum=None, quiet=1): ''' DESCRIPTION Define a color spectrum with as many color-stops as you like (at least 2). USAGE spectrumany expression, color_list [, selection [, minimum [, maximum ]]] ARGUMENTS expression = count, resi, b, q, or pc: respectively, atom count, residue index, temperature factor, occupancy, or partial charge {default: count} color_list = string: Space separated list of colors ... all other arguments like with `spectrum` command EXAMPLE spectrumany count, forest green yellow white spectrumany b, red yellow white, (polymer), maximum=100.0 SEE ALSO spectrum ''' quiet = int(quiet) colors = color_list.split() if len(colors) < 2: print('failed! please provide at least 2 colors') return colvec = [cmd.get_color_tuple(i) for i in colors] parts = len(colvec) - 1 expression = { 'pc': 'partial_charge', 'fc': 'formal_charge', 'count': 'index' }.get(expression, expression) minmax_expr = {'resi': 'resv'}.get(expression, expression) discrete_expr = ['index', 'resi'] if cmd.count_atoms(selection) == 0: print('empty selection') return if None in [minimum, maximum]: stored.e = list() cmd.iterate(selection, 'stored.e.append(%s)' % (minmax_expr)) if minimum is None: minimum = min(stored.e) if maximum is None: maximum = max(stored.e) minimum, maximum = float(minimum), float(maximum) if not quiet: print(' Spectrum: range (%.5f to %.5f)' % (minimum, maximum)) if maximum == minimum: print('no spectrum possible, only equal %s values' % (expression)) return if expression in discrete_expr: val_range = int(maximum - minimum + 1) else: val_range = maximum - minimum cmd.color(colors[0], selection) steps = 60 / parts steps_total = steps * parts val_start = minimum for p in range(parts): for i in range(steps): ii = float(i) / steps col_list = [ colvec[p + 1][j] * ii + colvec[p][j] * (1.0 - ii) for j in range(3) ] col_name = '0x%02x%02x%02x' % (col_list[0] * 255, col_list[1] * 255, col_list[2] * 255) val_end = val_range * (i + 1 + p * steps) / steps_total + minimum if expression in discrete_expr: cmd.color( col_name, '(%s) and %s %d-%d' % (selection, expression, val_start, val_end)) else: cmd.color( col_name, '(%s) and %s > %f' % (selection, expression, val_start)) val_start = val_end
def dehydron(selection='all', angle_range=40, max_distance=3.5, desolv=6.5, min_wrappers=19, quiet=0): ''' DESCRIPTION dehydron calculator USAGE dehydron [ selection [, angle_range [, max_distance [, desolv [, min_wrappers ]]]]] ''' angle, max_distance = float(angle_range), float(max_distance) desolv, min_wrappers = float(desolv), int(min_wrappers) quiet = int(quiet) name = cmd.get_legal_name('DH_%s' % selection) cmd.delete(name) selection_hb = '((%s) and polymer)' % (selection) hb = cmd.find_pairs("((byres " + selection_hb + ") and n. n)", "((byres " + selection_hb + ") and n. o)", mode=1, cutoff=max_distance, angle=angle_range) if not quiet: hb.sort(lambda x, y: (cmp(x[0][1], y[0][1]))) print "--------------------------------------------------------------------" print "--------------------------Dehydron Results--------------------------" print "--------------------------------------------------------------------" print " Donor | Aceptor |" print " Object Chain Residue | Object Chain Residue | # wrappers" cmd.select('_nonpolar', '(elem C) and not (solvent or (elem N+O) extend 1)', 0) try: cmd.select('_selection', '%s' % selection, 0) except: pass sel = [] total_wrappers = 0 for pairs in hb: wrappers = cmd.count_atoms( '((%s and _nonpolar and _selection) within %f of byca (%s`%d %s`%d))' % ((pairs[0][0], desolv) + pairs[0] + pairs[1])) total_wrappers = total_wrappers + wrappers if wrappers < min_wrappers: cmd.distance(name, pairs[0], pairs[1]) if not quiet: cmd.iterate(pairs[0], 'stored.nitro = chain, resi, resn') cmd.iterate(pairs[1], 'stored.oxy = chain, resi, resn') print ' %12s%4s%6s%6s | %12s%4s%6s%6s |%7s' % ( pairs[0][0], stored.nitro[0], stored.nitro[2], stored.nitro[1], pairs[1][0], stored.oxy[0], stored.oxy[2], stored.oxy[1], wrappers) sel.append(pairs[0]) sel.append(pairs[1]) cmd.delete('_nonpolar') cmd.delete('_selection') #compute the z_scores for validation porpoises. stored.ResiduesNames = [] cmd.iterate('(name ca)', 'stored.ResiduesNames.append((resn))') total_residues = float(len(stored.ResiduesNames)) z_score_wrappers = ((total_wrappers / total_residues) - 17) / 2 z_score_hb = ((len(hb) / total_residues) - 0.62) / 0.06 if len(sel) > 0: cmd.show_as('dashes', name) print '\nz-score wrappers = %6.2f\nz-score hydrogen bonds = %6.2f\n' % ( z_score_wrappers, z_score_hb) elif not quiet and len(hb) != 0: print '\n - no dehydrons were found - ' print '\nz-score hydrogen bonds = %6.2f\n' % (z_score_hb) else: print '\n - no hydrogen bonds were found - '
def tmalign(mobile, target, mobile_state=1, target_state=1, args='', exe='TMalign', ter=0, transform=1, object=None, quiet=0): ''' DESCRIPTION TMalign wrapper. You may also use this as a TMscore or MMalign wrapper if you privide the corresponding executable with the "exe" argument. Reference: Y. Zhang and J. Skolnick, Nucl. Acids Res. 2005 33, 2302-9 http://zhanglab.ccmb.med.umich.edu/TM-align/ ARGUMENTS mobile, target = string: atom selections mobile_state, target_state = int: object states {default: 1} args = string: Extra arguments like -d0 5 -L 100 exe = string: Path to TMalign (or TMscore, MMalign) executable {default: TMalign} ter = 0/1: If ter=0, then ignore chain breaks because TMalign will stop at first TER record {default: 0} ''' import subprocess, tempfile, os, re from .exporting import save_pdb_without_ter ter, quiet = int(ter), int(quiet) mobile_filename = tempfile.mktemp('.pdb', 'mobile') target_filename = tempfile.mktemp('.pdb', 'target') matrix_filename = tempfile.mktemp('.txt', 'matrix') mobile_ca_sele = '(%s) and (not hetatm) and name CA and alt +A' % (mobile) target_ca_sele = '(%s) and (not hetatm) and name CA and alt +A' % (target) if ter: save = cmd.save else: save = save_pdb_without_ter save(mobile_filename, mobile_ca_sele, state=mobile_state) save(target_filename, target_ca_sele, state=target_state) exe = cmd.exp_path(exe) args = [exe, mobile_filename, target_filename, '-m', matrix_filename] + args.split() try: process = subprocess.Popen(args, stdout=subprocess.PIPE) lines = process.stdout.readlines() except OSError: print('Cannot execute "%s", please provide full path to TMscore or TMalign executable' % (exe)) raise CmdException finally: os.remove(mobile_filename) os.remove(target_filename) # TMalign >= 2012/04/17 if os.path.exists(matrix_filename): lines += open(matrix_filename).readlines() os.remove(matrix_filename) r = None re_score = re.compile(r'TM-score\s*=\s*(\d*\.\d*)') rowcount = 0 matrix = [] line_it = iter(lines) headercheck = False alignment = [] for line in line_it: if 4 >= rowcount > 0: if rowcount >= 2: a = list(map(float, line.split())) matrix.extend(a[2:5]) matrix.append(a[1]) rowcount += 1 elif not headercheck and line.startswith(' * '): a = line.split(None, 2) if len(a) == 3: headercheck = a[1] elif line.lower().startswith(' -------- rotation matrix'): rowcount = 1 elif line.startswith('(":" denotes'): alignment = [line_it.next().rstrip() for i in range(3)] else: match = re_score.search(line) if match is not None: r = float(match.group(1)) if not quiet: print(line.rstrip()) if not quiet: for i in range(0, len(alignment[0])-1, 78): for line in alignment: print(line[i:i+78]) print('') assert len(matrix) == 3*4 matrix.extend([0,0,0,1]) if int(transform): for model in cmd.get_object_list('(' + mobile + ')'): cmd.transform_object(model, matrix, state=0, homogenous=1) # alignment object if object is not None: mobile_idx, target_idx = [], [] space = {'mobile_idx': mobile_idx, 'target_idx': target_idx} cmd.iterate(mobile_ca_sele, 'mobile_idx.append("%s`%d" % (model, index))', space=space) cmd.iterate(target_ca_sele, 'target_idx.append("%s`%d" % (model, index))', space=space) for i, aa in enumerate(alignment[0]): if aa == '-': mobile_idx.insert(i, None) for i, aa in enumerate(alignment[2]): if aa == '-': target_idx.insert(i, None) if (len(mobile_idx) == len(target_idx) == len(alignment[2])): cmd.rms_cur( ' '.join(idx for (idx, m) in zip(mobile_idx, alignment[1]) if m in ':.'), ' '.join(idx for (idx, m) in zip(target_idx, alignment[1]) if m in ':.'), cycles=0, matchmaker=4, object=object) else: print('Could not load alignment object') if not quiet: if headercheck: print('Finished Program:', headercheck) if r is not None: print('Found in output TM-score = %.4f' % (r)) return r
# CD4 = chains C, E, F # 17b = chains H, K, M and L, N, O cmd.remove('c;C,E,F,H,K,M,L,N,O') # Tweak initial display and color of Env monomers cmd.hide('everything') cmd.bg_color('white') cmd.show('cartoon') cmd.color('grey40') #cmd.color('grey20', structure) cmd.set('cartoon_transparency', '0.5') cmd.set('cartoon_transparency', '0', structure) # Identify unique sites in structure sites_in_structure = [] cmd.iterate("(name ca)", "sites_in_structure.append(resi)") unique_sites_in_structure = [] for site in sites_in_structure: if site not in unique_sites_in_structure: unique_sites_in_structure.append(site) # Get site-specific RMSDcorrected values and whether the shift at a site is # significant RMSD_dict = {} sig_dict = {} with open('../BG505_to_BF520_prefs_dist.csv') as f: lines = f.readlines()[1:] for line in lines: elements = line.split(',') site = elements[0] RMSDcorrected = elements[1]
def list_hb(selection, selection2=None, cutoff=3.2, angle=55, mode=1, output='hbonds'): """ USAGE list_hb selection, [selection2 (default=None)], [cutoff (default=3.2)], [angle (default=55)], [mode (default=1)], [hb_list_name (default='hbonds')] The script automatically adds a requirement that atoms in the selection (and selection2 if used) must be either of the elements N or O. If mode is set to 0 instead of the default value 1, then no angle cutoff is used, otherwise the angle cutoff is used and defaults to 55 degrees. e.g. To get a list of all H-bonds within chain A of an object list_hb 1abc & c. a &! r. hoh, cutoff=3.2, hb_list_name=abc-hbonds To get a list of H-bonds between chain B and everything else: list_hb 1tl9 & c. b, 1tl9 &! c. b """ cutoff = float(cutoff) angle = float(angle) mode = float(mode) selection = selection + " & e. n+o" if not selection2: hb = cmd.find_pairs(selection, selection, mode=mode, cutoff=cutoff, angle=angle) else: selection2 = selection2 + " & e. n+o" hb = cmd.find_pairs(selection, selection2, mode=mode, cutoff=cutoff, angle=angle) # sort the list for easier reading hb.sort(lambda x, y: (cmp(x[0][1], y[0][1]))) stored.hb_list = [] for pairs in hb: cmd.iterate( "%s and index %s" % (pairs[0][0], pairs[0][1]), 'stored.hb_list.append("%1s,%3s,%s,%-4s," % (chain,resn,resi,name)),' ) cmd.iterate( "%s and index %s" % (pairs[1][0], pairs[1][1]), 'stored.hb_list.append("%1s,%3s,%s,%-4s," % (chain,resn,resi,name)),' ) stored.hb_list.append( "%.2f" % cmd.distance(output, "%s and index %s" % (pairs[0][0], pairs[0][1]), "%s and index %s" % (pairs[1][0], pairs[1][1]) + ',') + '\n')
def mutate( self, pdbid: str, replace_with: Dict[int, Optional[str]]) -> Union[List[str], rdchem.Mol]: """Modify amino acid residues at the defined positions. If the locations indexes exceed the amount in data, then they will be ignored and a warning will be announced. Params: ------- pdbid: str PDB ID associated with the structure. replace_with: dict The index location(s) within the full protein to replace certain residue(s) with. If a residue associated with a index location is None, then the modified residue is chosen randomly. If a certain index exceeds the number of available residues in the protein, then those enteries are simply ignored and the user is notified. Returns: -------- protein: list of str or rdkit.Chem.rdchem.Mol Modified protein with residues. If fmt="primary", then list of string (peptide names) is returned. If fmt="tertiary", then 3D molecule structure is returned. """ # Load PDB structure (download, if necessary) pdb_dir = maybe_create_dir(os.path.join(self.rootdir, pdbid)) pdb_file = os.path.join(pdb_dir, f"{pdbid}.pdb") if not os.path.exists(pdb_file): is_successful = cmd.fetch(pdbid, name=pdbid, state=1, type="pdb", path=pdb_dir) if is_successful == -1: raise DownloadError(f"Unable to download '{pdbid}'.") else: cmd.load(pdb_file, object=pdbid, state=1, format="pdb") # Get all residue names, see: https://pymolwiki.org/index.php/List_Selection resnames_dict = {"names": []} cmd.iterate("(name ca)", "names.append(resn)", space=resnames_dict) residue_names = resnames_dict["names"] num_residues = len(residue_names) # Cleanup idxs: remove indicies that exceed number of available residues nonvalid_idxs = [ idx for idx in replace_with.keys() if idx > num_residues ] for idx in nonvalid_idxs: print( f"OutOfRange: Removing idx {idx} (only {num_residues} residues)." ) replace_with.pop(idx) # Randomly choose an amino acid (AA) to replace residue, if None is provided. # Additionally, format string such that it is a valid 3 letter amino acid. for idx, residue in replace_with.items(): if residue is None: replace_with[idx] = np.random.choice(aa3) elif is_aa(residue): residue = residue.upper() if len(residue) == 1: replace_with[idx] = one_to_three.get(residue) elif len(residue) == 3: replace_with[idx] = residue else: raise ValueError( f"Invalid residue '{residue}'. Choose one from " f"the following {aa1+aa3}.") # Determine save filepath name modified_res_str = ":".join( [f"{k}{three_to_one.get(v)}" for k, v in replace_with.items()]) filename = f"{self.fmt}_{modified_res_str}" filename += ".pdb" if self.fmt == "tertiary" else ".json" save_filepath = os.path.join(self.rootdir, pdbid, filename) # Replace primary structure, i.e. residue names (str) if self.fmt == "primary": # Load data from cache, if it exists protein = None if os.path.exists(save_filepath): with open(save_filepath) as json_file: protein = json.load(json_file) if protein is None: for idx, residue in replace_with.items(): residue_names[ idx - 1] = residue # since PDB starts with idx of 1 protein = [three_to_one.get(name) for name in residue_names] # Save sequence temporarily _ = maybe_create_dir(save_filepath) with open(save_filepath, "w") as outfile: json.dump(protein, outfile) # Replace tertiary structure, i.e. residue's 3D coordinates elif self.fmt == "tertiary": if not os.path.exists(save_filepath): # Split states so that we can optimize only on specific state(s). # NOTE: Might be useful to choose lowest energy state to mutate, # OR mutate rotamers for all positions, then choose one with # lowest energy. cmd.split_states(object=pdbid) # Delete all other objects other than one we want to mutate # NOTE: For now, keep only first object. This might change # depending on which state needs to be kept. objs = cmd.get_object_list() # aka states keep_objs = [pdbid + "_0001"] for obj in objs: if obj not in keep_objs: cmd.delete(obj) assert keep_objs == cmd.get_object_list() # Mutate residues cmd.wizard("mutagenesis") wizard: Mutagenesis = cmd.get_wizard() for idx, res in replace_with.items(): selection = "{0:s}//A/{1:d}/".format(keep_objs[0], idx) wizard.do_select( selection) # select which residue index to replace wizard.set_mode( res) # choose name of residue to replace with wizard.do_state( 1 ) # select rotamer with least strain (aka conflicts w/ other atoms) wizard.apply() # apply point mutation cmd.set_wizard(None) # close wizard # Save PDB temporarily _ = maybe_create_dir(save_filepath) cmd.save(save_filepath, selection=pdbid, format="pdb") cmd.delete("all") # remove all objects, clears workspace # Load + choose model/structure with lowest energy # NOTE: If sanitize=True, the function checks if Mol has the correct # hybridization/valance structure (aka is it chemically reasonable). # When converting from the PDB block, this sometimes results in # improper parsing. Instead, for now, we just check if the Mol is # syntactically valid (i.e. all rings/branches closed, no illegal # atom types, etc). protein = rdmolfiles.MolFromPDBFile(save_filepath, sanitize=False, removeHs=False) if protein.GetNumConformers() > 1: protein = _get_conformer(protein, conformer="min", algo="MMFF") else: raise NotImplementedError # Remove file, if not needed if not self.cache: os.remove(save_filepath) return protein
def interfaceResidues(cmpx, cA='c. A', cB='c. B', cutoff=1.0, selName="interface"): """ interfaceResidues -- finds 'interface' residues between two chains in a complex. PARAMS cmpx The complex containing cA and cB cA The first chain in which we search for residues at an interface with cB cB The second chain in which we search for residues at an interface with cA cutoff The difference in area OVER which residues are considered interface residues. Residues whose dASA from the complex to a single chain is greater than this cutoff are kept. Zero keeps all residues. selName The name of the selection to return. RETURNS * A selection of interface residues is created and named depending on what you passed into selName * An array of values is returned where each value is: ( modelName, residueNumber, dASA ) NOTES If you have two chains that are not from the same PDB that you want to complex together, use the create command like: create myComplex, pdb1WithChainA or pdb2withChainX then pass myComplex to this script like: interfaceResidues myComlpex, c. A, c. X This script calculates the area of the complex as a whole. Then, it separates the two chains that you pass in through the arguments cA and cB, alone. Once it has this, it calculates the difference and any residues ABOVE the cutoff are called interface residues. AUTHOR: Jason Vertrees, 2009. """ # Save user's settings, before setting dot_solvent oldDS = cmd.get("dot_solvent") cmd.set("dot_solvent", 1) # set some string names for temporary objects/selections tempC, selName1 = "tempComplex", selName + "1" chA, chB = "chA", "chB" # operate on a new object & turn off the original cmd.create(tempC, cmpx) cmd.disable(cmpx) # remove cruft and inrrelevant chains cmd.remove(tempC + " and not (polymer and (%s or %s))" % (cA, cB)) # get the area of the complete complex cmd.get_area(tempC, load_b=1) # copy the areas from the loaded b to the q, field. cmd.alter(tempC, 'q=b') # extract the two chains and calc. the new area # note: the q fields are copied to the new objects # chA and chB cmd.extract(chA, tempC + " and (" + cA + ")") cmd.extract(chB, tempC + " and (" + cB + ")") cmd.get_area(chA, load_b=1) cmd.get_area(chB, load_b=1) # update the chain-only objects w/the difference cmd.alter("%s or %s" % (chA, chB), "b=b-q") # The calculations are done. Now, all we need to # do is to determine which residues are over the cutoff # and save them. stored.r, rVal, seen = [], [], [] cmd.iterate('%s or %s' % (chA, chB), 'stored.r.append((model,resi,b))') cmd.enable(cmpx) cmd.select(selName1, 'none') for (model, resi, diff) in stored.r: key = resi + "-" + model if abs(diff) >= float(cutoff): if key in seen: continue else: seen.append(key) rVal.append((model, resi, diff)) # expand the selection here; I chose to iterate over stored.r instead of # creating one large selection b/c if there are too many residues PyMOL # might crash on a very large selection. This is pretty much guaranteed # not to kill PyMOL; but, it might take a little longer to run. cmd.select(selName1, selName1 + " or (%s and i. %s)" % (model, resi)) # this is how you transfer a selection to another object. cmd.select(selName, cmpx + " in " + selName1) # clean up after ourselves cmd.delete(selName1) cmd.delete(chA) cmd.delete(chB) cmd.delete(tempC) # show the selection cmd.enable(selName) # reset users settings cmd.set("dot_solvent", oldDS) return rVal
def map_new_apbs(name, selection='all', grid=0.5, buffer=10.0, state=1, preserve=0, exe='', assign=-1, focus='', quiet=1): ''' DESCRIPTION Create electrostatic potential map with APBS. For more control over parameters and a graphical user interface I recommend to use the APBS Tools Plugin instead. In case of missing atoms or residues I recommend to remodel the input structure with modeller before calculating the electrostatic potential. If selection has no charges and radii, they will be automatically assigned with PyMOL (not with pdb2pqr). SEE ALSO apbs_surface, map_new (coulomb), APBS Tools Plugin ''' import tempfile, os, shutil, glob, subprocess from pymol.util import protein_assign_charges_and_radii from .modelling import add_missing_atoms selection = '(%s) and not solvent' % (selection) grid, buffer, state = float(grid), float(buffer), int(state) preserve, assign, quiet = int(preserve), int(assign), int(quiet) if exe: exe = cmd.exp_path(exe) else: try: import freemol.apbs exe = freemol.apbs.get_exe_path() except: pass if not exe: exe = "apbs" try: r = subprocess.call([exe, "--version"], stdout=open(os.devnull, "w"), stderr=subprocess.STDOUT) if r < 0: raise CmdException("Broken executable: " + exe) except OSError: raise CmdException("Cannot execute: " + exe) # temporary directory tempdir = tempfile.mkdtemp() if not quiet: print(' Tempdir:', tempdir) # filenames pqrfile = os.path.join(tempdir, 'mol.pqr') infile = os.path.join(tempdir, 'apbs.in') stem = os.path.join(tempdir, 'map') # temporary object tmpname = cmd.get_unused_name('mol' if preserve else '_') cmd.create(tmpname, selection, state, 1) # partial charges assign = [assign] if assign[0] == -1: # auto detect if selection has charges and radii cmd.iterate('first ((%s) and elem O)' % (tmpname), 'assign[0] = (elec_radius * partial_charge) == 0.0', space=locals()) if assign[0]: cmd.remove('hydro and model ' + tmpname) add_missing_atoms(tmpname, quiet=quiet) protein_assign_charges_and_radii(tmpname) elif not quiet: print(' Notice: using exsiting charges and radii') cmd.save(pqrfile, tmpname, 1, format='pqr', quiet=quiet) # grid dimensions extent = cmd.get_extent(tmpname) extentfocus = cmd.get_extent(focus) if focus else extent fglen = [(emax-emin + 2*buffer) for (emin, emax) in zip(*extentfocus)] cglen = [(emax-emin + 4*buffer) for (emin, emax) in zip(*extent)] if not preserve: cmd.delete(tmpname) apbs_in = defaults_apbs_in.copy() apbs_in['fglen'] = '%f %f %f' % tuple(fglen) apbs_in['cglen'] = '%f %f %f' % tuple(cglen) apbs_in['srad'] = cmd.get('solvent_radius') apbs_in['write'] = 'pot dx "%s"' % (stem) if focus: apbs_in['fgcent'] = '%f %f %f' % tuple((emax + emin) / 2.0 for (emin, emax) in zip(*extentfocus)) # apbs input file def write_input_file(): f = open(infile, 'w') print(''' read mol pqr "%s" end elec mg-auto ''' % (pqrfile), file=f) for (k,v) in apbs_in.items(): if v is None: print(k, file=f) elif isinstance(v, list): for vi in v: print(k, vi, file=f) else: print(k, v, file=f) print(''' end quit ''', file=f) f.close() try: # apbs will fail if grid does not fit into memory # -> on failure repeat with larger grid spacing for _ in range(3): dime = [1 + max(64, n / grid) for n in fglen] apbs_in['dime'] = '%d %d %d' % tuple(dime) write_input_file() # run apbs r = subprocess.call([exe, infile], cwd=tempdir) if r == 0: break if r in (-6, -9): grid *= 2.0 if not quiet: print(' Warning: retry with grid =', grid) continue print(' Error: apbs failed with code', r) raise CmdException dx_list = glob.glob(stem + '*.dx') if len(dx_list) != 1: print(' Error: dx file missing') raise CmdException # load map cmd.load(dx_list[0], name, quiet=quiet) except OSError: print(' Error: Cannot execute "%s"' % (exe)) raise CmdException finally: if not preserve: shutil.rmtree(tempdir) elif not quiet: print(' Notice: not deleting %s' % (tempdir))
def test_alter_list(self): cmd.fragment('gly') cmd.alter_list('gly', [[i + 1, 'name = "X%d"' % i] for i in range(7)]) name_list = [] cmd.iterate('gly', 'name_list.append(name)', space=locals()) self.assertEqual(name_list, ['X%d' % i for i in range(7)])
import __main__ __main__.pymol_argv = ['pymol', '-qc'] import pymol from pymol import cmd, stored pymol.finish_launching() cmd.set('dot_solvent', 1) cmd.set('dot_density', 4) # Lowest resolution pdb = '1y57_human_numbering' cmd.load('../pdbs/' + pdb + '.pdb') # use the name of your pdb file stored.residues = [] cmd.iterate('name ca', 'stored.residues.append(resi)') sasa_per_residue = [] idx = [] for i in stored.residues: sasa_per_residue.append(cmd.get_area('resi %s' % i)) idx.append(i) with open(pdb + '_SASA.txt', 'w') as f: for i, item in zip(idx, sasa_per_residue): #f.write("%s\n" % item) line = "{}\t{}\n".format(i, item) f.write(line) print sum(sasa_per_residue) print cmd.get_area( 'all' ) # just to check that the sum of sasa per residue equals the total area
def format_bonds( selection='all', bonds=4, ): ''' DESCRIPTION Formats bonds in aromatic or charged residues EXAMPLE frag PHE format_bonds USAGE format_bonds [ selection [, bonds ]] ARGUMENTS selection: <str> input selection {default: 'all'} bonds: <int> toogles format of bonds 1: single bonds (deactivates valence display) 2: regular double bonds (activates valence display) >=3: delocalized (activates valence display) ''' # Selection try: # group selection with bracketing and select complete residues selection = '(byres (' + str(selection) + '))' # checks functional selection cmd.count_atoms(selection) except: print("invalid selection") return False # PARAMETERS try: bonds = int(bonds) except: pass if (not (bonds in [1, 2])): bonds = 4 if bonds == 1: cmd.set('valence', 0) print("Valence display disabled!") return bonds else: cmd.set('valence', 1) print("Valence display enabled!") # proceed ##### SELECTION BY OBJECT AND CHAIN ##### # variable for the selections # get the names of the proteins in the selection objects = cmd.get_object_list(selection) # include chains # subselect chains names = [] for p in objects: for chain in cmd.get_chains('model ' + p) or ['']: names.append("(model %s and chain '%s')" % (p, chain)) ##### SELECTION LISTS ##### # get TRP stored.temp = [] for p in names: cmd.iterate(('(%s) and (resn TRP+NIW) ' 'and (name CA)' % (p)), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) # the integer is to ensure unique keys TRP_tuple = (1, ) + tuple(stored.temp) # get PHETYR stored.temp = [] for p in names: cmd.iterate(('(%s) and (resn PHE+TYR+PTR+NIY+PNIY) ' 'and (name CA)' % (p)), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) PHETYR_tuple = (2, ) + tuple(stored.temp) # get HIS stored.temp = [] for p in names: cmd.iterate(('(%s) and (resn HIS) ' 'and (name CA)' % (p)), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) HIS_tuple = (3, ) + tuple(stored.temp) # get NITRO stored.temp = [] for p in names: cmd.iterate(('(%s) and (resn NIY+PNIY+NIW) ' 'and (name CA)' % (p)), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) NITRO_tuple = (4, ) + tuple(stored.temp) # get GLU stored.temp = [] for p in names: cmd.iterate(('(%s) and (resn GLU) ' 'and (name CA)' % (p)), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) GLU_tuple = (5, ) + tuple(stored.temp) # get ASP stored.temp = [] for p in names: cmd.iterate(('(%s) and (resn ASP) ' 'and (name CA)' % (p)), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) ASP_tuple = (6, ) + tuple(stored.temp) # get CTERM stored.temp = [] for p in names: cmd.iterate( '(byres (last %s)) and (not (hetatm)) ' 'and (name OXT)' % (p), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) CTERM_tuple = (7, ) + tuple(stored.temp) # get ARG stored.temp = [] for p in names: cmd.iterate(('(%s) and (resn ARG) ' 'and (name CA)' % (p)), 'stored.temp.append("(%s and resi "+str(resi)+")")' % p) ARG_tuple = (8, ) + tuple(stored.temp) ##### SELECTION TUPLES DONE ##### ##### ATOM LISTS ##### TRP_bonds_all = [['CG', 'CD1'], ['CD1', 'NE1'], ['NE1', 'CE2'], ['CE2', 'CD2'], ['CD2', 'CG'], ['CD2', 'CE3'], ['CE3', 'CZ3'], ['CZ3', 'CH2'], ['CH2', 'CZ2'], ['CZ2', 'CE2']] TRP_bonds_double = [['CG', 'CD1'], ['CE2', 'CD2'], ['CE3', 'CZ3'], ['CH2', 'CZ2']] PHETYR_bonds_all = [['CG', 'CD1'], ['CD1', 'CE1'], ['CE1', 'CZ'], ['CZ', 'CE2'], ['CE2', 'CD2'], ['CD2', 'CG']] PHETYR_bonds_double = [['CG', 'CD1'], ['CE1', 'CZ'], ['CE2', 'CD2']] HIS_bonds_all = [ ['CG', 'CD2'], ['CD2', 'NE2'], ['NE2', 'CE1'], ['CE1', 'ND1'], ['ND1', 'CG'], ] HIS_bonds_double = [['CG', 'CD2'], ['CE1', 'ND1']] NITRO_bonds_all = [['NN', 'O1'], ['NN', 'O2']] NITRO_bonds_double = [['NN', 'O1']] GLU_bonds_all = [['CD', 'OE1'], ['CD', 'OE2']] GLU_bonds_double = [['CD', 'OE1']] ASP_bonds_all = [['CG', 'OD1'], ['CG', 'OD2']] ASP_bonds_double = [['CG', 'OD1']] CTERM_bonds_all = [['C', 'O'], ['C', 'OXT']] CTERM_bonds_double = [['C', 'O']] ARG_bonds_all = [['CZ', 'NH1'], ['CZ', 'NH2']] ARG_bonds_double = [['CZ', 'NH1']] ##### FORMATING ##### # dictionary: entries:atoms format_dict = { TRP_tuple: [TRP_bonds_all, TRP_bonds_double], PHETYR_tuple: [PHETYR_bonds_all, PHETYR_bonds_double], HIS_tuple: [HIS_bonds_all, HIS_bonds_double], NITRO_tuple: [NITRO_bonds_all, NITRO_bonds_double], GLU_tuple: [GLU_bonds_all, GLU_bonds_double], ASP_tuple: [ASP_bonds_all, ASP_bonds_double], CTERM_tuple: [CTERM_bonds_all, CTERM_bonds_double], ARG_tuple: [ARG_bonds_all, ARG_bonds_double] } if bonds != 2: lines = 4 print("Formating as delocalized bonds") else: lines = 1 print("Formating as double bonds") # for all tuples (i.e format_dict.keys()) for p in list(format_dict.keys()): # go through list except ID at pos 1 for q in p[1:]: # format bonds for r in format_dict[p][0]: cmd.unbond('%s and name %s' % (q, r[0]), '%s and name %s' % (q, r[1])) cmd.bond('%s and name %s' % (q, r[0]), '%s and name %s' % (q, r[1]), lines) if lines == 1: # add double bonds for r in format_dict[p][1]: cmd.unbond('%s and name %s' % (q, r[0]), '%s and name %s' % (q, r[1])) cmd.bond('%s and name %s' % (q, r[0]), '%s and name %s' % (q, r[1]), 2) return bonds
def drawNetwork(path, userSelection='all', r=1, edge_norm=None, alpha=0.5, node_color=(0.6, 0.6, 0.6), edge_color1=(1, 0, 0), edge_color2=(0, 0, 1), labelling='0', threshold=0): ''' Draws a NetworkX network on the PyMol structure ''' cmd.delete('nodes *edges') cmd.label(selection=userSelection, expression="") # Building position -- name correspondance stored.posCA = [] stored.names = [] userSelection = userSelection + " and n. CA or n. C" cmd.iterate_state(1, selector.process(userSelection), "stored.posCA.append([x,y,z])") cmd.iterate(userSelection, 'stored.names.append(resn+resi+chain)') stored.labels = list(map(relabel, stored.names)) stored.resid = list(map(selection, stored.names)) node2id = dict(zip(stored.labels, stored.resid)) node2CA = dict(zip(stored.labels, stored.posCA)) # Getting graph net = nx.read_gpickle(path) cmd.set('auto_zoom', 0) cmd.set("cgo_sphere_quality", 4) #Drawing nodes # selnodes = "" # for u in net.nodes(): # x, y, z = node2CA[u] # obj+=[SPHERE, x, y, z, r] # selnodes+=node2id[u] # selnodes = selnodes[4:] # if labelling=='1': # cmd.label(selection=selnodes, expression="t2o(resn)+resi") # if labelling=='3': # cmd.label(selection=selnodes, expression="resn+resi") # cmd.load_cgo(obj, 'nodes') if edge_norm == None: edge_norm = max( [net.edges()[(u, v)]['weight'] for u, v in net.edges()]) / r obj1, obj2, nodelist = [], [], [] for u, v in net.edges(): radius = net[u][v]['weight'] / edge_norm if abs(net[u][v]['weight']) >= threshold: if 'color' in net[u][v]: if net[u][v]['color'] == 'r': obj1 += [ CYLINDER, *node2CA[u], *node2CA[v], radius, *edge_color1, *edge_color1 ] else: obj2 += [ CYLINDER, *node2CA[u], *node2CA[v], radius, *edge_color2, *edge_color2 ] else: if net[u][v]['weight'] <= 0: obj1 += [ CYLINDER, *node2CA[u], *node2CA[v], radius, *edge_color1, *edge_color1 ] else: obj2 += [ CYLINDER, *node2CA[u], *node2CA[v], radius, *edge_color2, *edge_color2 ] nodelist += [u, v] #Drawing nodes obj = [COLOR, *node_color] nodelist = set(nodelist) selnodes = ''.join([node2id[u] for u in nodelist])[4:] for u in nodelist: x, y, z = node2CA[u] obj += [SPHERE, x, y, z, r] if labelling == '1': cmd.label(selection=selnodes, expression="t2o(resn)+resi") if labelling == '3': cmd.label(selection=selnodes, expression="resn+resi") cmd.load_cgo(obj, 'nodes') cmd.load_cgo(obj1, 'holo_edges') cmd.load_cgo(obj2, 'apo_edges')
firstChainToCompare.id.upper()), '%s & chain %s' % (structureName, chainToCompare.id.upper())) # Make sure the residues in each chain are zero-based. stored.first = None structureList = ['(model %s and (%s))' % (obj, structureName) for obj in cmd.get_object_list( '(' + structureName + ')')] structureChainList = ['(%s and chain %s)' % (structure, chain) for structure in structureList for chain in cmd.get_chains(structure)] for structureChain in structureChainList: cmd.iterate('first %s and polymer and n. CA' % structureChain, 'stored.first=resv') # Reassign the residue numbers. cmd.alter(structureChain, 'resi=str(int(resi)-%d)' % int(stored.first)) # Alter the coordinates if necessary. if first: shift = 100 else: shift = -100 if not setGridMode: print('altering', structureName, shift) cmd.alter_state(1, structureName, 'x+=%d' % shift) cmd.rebuild()
import os import os.path import glob from pymol import cmd from pymol import stored from pymol import selector files = glob.glob("*.pdb") print(files) for file in files: pdbName = os.path.basename(file).split(".")[0] cmd.load(file, pdbName) outFile = open(pdbName + '.ss', 'w+') stored.ss = "" cmd.iterate('(n. CA)', 'stored.ss = stored.ss + ("%1s"%ss)') for c in stored.ss: if c == " ": outFile.write('.') else: outFile.write(c) cmd.delete(pdbName) outFile.close()
def select_sspick(selection, name=None, caonly=0, quiet=0): ''' DESCRIPTION Extend selection by connected secondary structure elements. Also available as wizard (type: "wizard sspick"). USAGE select_sspick selection [, name [, caonly [, quiet ]]] ARGUMENTS selection = string: selection-expression name = string: create a named atom selection if not None {default: None} ''' caonly, quiet = int(caonly), int(quiet) qkeys = set() cmd.iterate('bycalpha (%s)' % (selection), 'qkeys.add(((model,segi,chain,ss), resv))', space={'qkeys': qkeys}) def in_intervals(i, intervals): for interval in intervals: if interval[0] <= i <= interval[1]: return True return False elements = dict() for key, resv in qkeys: element = elements.setdefault(key, []) if in_intervals(resv, element): continue resv_set = set() cmd.iterate('/%s/%s/%s//CA and ss "%s"' % key, 'resv_set.add(resv)', space={'resv_set': resv_set}) resv_min = resv resv_max = resv while (resv_min - 1) in resv_set: resv_min -= 1 while (resv_max + 1) in resv_set: resv_max += 1 element.append((resv_min, resv_max)) sele_list = [] ss_names = {'S': 'Strand', 'H': 'Helix', '': 'Loop', 'L': 'Loop'} for key in elements: model,segi,chain,ss = key for resv_min,resv_max in elements[key]: sele = '/%s/%s/%s/%d-%d' % (model, segi, chain, resv_min, resv_max) if caonly: sele += '/CA' sele_list.append(sele) if not quiet: print("%-6s %s" % (ss_names.get(ss, ss), sele)) sele = ' '.join(sele_list) if name is not None: cmd.select(name, sele) elif not quiet: print(' Selection: ' + sele) return sele
def hydro_pairs(selection, cut_off): """ Find hydrogen bonds for a given selection """ states = cmd.count_states(selection) if states: hb = [] for i in range(1, states + 1): p = cmd.find_pairs("%s and (name O* and neighbor elem H) or" "(name N* and neighbor elem H)" % selection, "%s and name N* or name O*" % selection, cutoff=3.5, mode=1, angle=70, state1=i, state2=i) hb.append(p) if any([j for i in hb for j in i]): seen = {} for state in hb: for pairs in state: if pairs in seen: seen[pairs] = seen[pairs] + 1 else: seen[pairs] = 1 occurrence = seen.items() occurrence = sorted(occurrence, key=lambda x: x[1], reverse=True) fd = open("Hydrogen_bonds.dat", "w") fd.write("--------------------------------------------------------" "------------\n") fd.write("-----------------------------Results--------------------" "------------\n") fd.write("--------------------------------------------------------" "------------\n") fd.write(" Donor |" " Aceptor |\n") fd.write(" Object Residue Atom Index|" " Object Residue Atom Index| % occurrence\n") stored.donors = [] stored.aceptors = [] sub = [] occurrence_list = [] for i in range(len(occurrence)): cmd.iterate("index %s" % (occurrence[i][0][0][1]), "stored.donors.append((resn, elem))") cmd.iterate("index %s" % (occurrence[i][0][1][1]), "stored.aceptors.append((resn, elem))") if (occurrence[i][1] * 100 / states) >= cut_off: fd.write("%8s%8s%6s%8s|%8s%8s%6s%8s|%5s\n" % (occurrence[i][0][0][0], stored.donors[i][0], stored.donors[i][1], occurrence[i][0][0][1], occurrence[i][0][1][0], stored.aceptors[i][0], stored.aceptors[i][1], occurrence[i][0][1][1], "%.2f" % (occurrence[i][1] * 100 /states) )) occurrence_list.append(occurrence[i][0]) fd.close() cmd.set('suspend_updates', 'on') for state, bonds in enumerate(hb): for bond in bonds: if bond in occurrence_list: cmd.distance('HB', 'index %s' % bond[0][1], 'index %s' % bond[1][1], state=state, cutoff=3.5) cmd.hide("labels", "HB") cmd.set('suspend_updates', 'off') print("Check working directory for hydrogen bonds text file report") else: print("No hydrogen bonds detected for this selection")
def test(self): cmd.load("PYMOL-1514.mae") b_list = [] cmd.iterate("all", "b_list.append(b)", space=locals()) self.assertArrayEqual(b_list, [-1.0, -1.0, -2.3, 2.86], 0.001)
def loadcd( recid, chain, ligid, ligname, pocket, flexdist="3", crossdock="~/Documents/datasets/crossdocking/CrossDocked", cdpath="", ): # Clear everything cmd.reinitialize("everything") # Convert flexdist to float flexdist = float(flexdist) # Print informations print(f"Loading {recid}_{chain}:{ligid}_{ligname}") print(f"flexdist = {flexdist}") # Build paths name = f"{recid}_{chain}_rec_{ligid}_{ligname}" path = os.path.join(cdpath, pocket) ligname = f"{name}_lig.pdb" ligandpath = os.path.join(path, ligname) # Docked ligand flexname = f"{name}_flex.pdb" flexpath = os.path.join(path, flexname) # Flexible residues #receptorname = f"{recid}_{chain}__rec.pdb" #receptorpath = os.path.join(crossdock, receptorname) crystalname = f"{recid}_{chain}_rec.pdb" crystalpath = os.path.join(crossdock, pocket, crystalname) # Crystal receptor # Load ligand and receptor cmd.load(ligandpath, "ligand") # Selection name: ligand cmd.load(flexpath, "flex") # Selection name: flex #cmd.load(receptorpath, "receptor") # Selection name: receptor cmd.load(crystalpath, "crystal") # Selection name: receptor # Hide everything cmd.hide("all") # Show receptor #cmd.show("cartoon", "receptor") #cmd.color("grey", "receptor") cmd.show("cartoon", "crystal") cmd.color("grey", "crystal") # Show docked ligand cmd.show("sticks", "ligand") cmd.show("spheres", "ligand") cmd.set("sphere_scale", 0.2, "ligand") cmd.color("marine", "ligand and name C*") # Show flexible residues cmd.show("licorice", "flex") cmd.set("stick_radius", 0.2, "flex") cmd.color("teal", "flex and name C*") # Center and zoom to ligand cmd.center("ligand") cmd.zoom("ligand", 10) # Remove solvent #cmd.remove("solvent") # Get residues of crystal close to flexible residues stored.list = [] cmd.iterate( "crystal within 0.1 of flex", # Selection "stored.list.append((resn, resi, chain))", # Action ) # Remove redundancies flexres = set(stored.list) # Set of flexible residues # Outline flexible residues of the receptor #for _, resi, chain in flexres: # if chain != "": # ??? # sel = f"receptor and (resi {resi} in chain {chain})" # cmd.show("sphere", sel) # cmd.set("sphere_scale", 0.2, sel) # cmd.color("yellow", sel) # cmd.remove(f"hydro in ({sel})") # Outline flexible residues of the crystal for _, resi, chain in flexres: if chain != "": # ??? sel = f"crystal and (resi {resi} in chain {chain})" cmd.show("licorice", sel) cmd.set("stick_radius", 0.15, sel) cmd.color("grey", sel) cmd.remove(f"hydro in ({sel})") # Show metal atoms cmd.show("spheres", "metals") cmd.set("sphere_scale", 0.5, "metals")
def mutate(selection, new_resn, inplace=0, sculpt=0, hydrogens='auto', mode=0, quiet=1): ''' DESCRIPTION Mutate a single residue. Does call the mutagenesis wizard non-interactively and tries to select the best rotamer. Can do some sculpting in the end to the best rotamer. USAGE mutate selection, new_resn [, inplace [, sculpt [, hydrogens]]] ARGUMENTS selection = string: atom selection of single residue new_resn = string: new residue name (3-letter or 1-letter) inplace = 0 or 1: work on copy of input object if 0 {default: 0} sculpt = 0: no sculpting {default} sculpt = 1: do sculpting on best rotamer sculpt = 2: do sculpting with neighbors hydrogens = string: keep, auto or none {default: auto} mode = 0: select rotamer with best clash score {default} mode = 1: take chi angles from original residue mode = 2: first rotamer EXAMPLE fetch 2x19, async=0 select x, A/CYS`122/ zoom x mutate x, LYS ''' from pymol.wizard import mutagenesis _assert_package_import() from . import three_letter inplace, sculpt = int(inplace), int(sculpt) mode = int(mode) quiet = int(quiet) org = cmd.get_object_list(selection)[0] tmp = cmd.get_unused_name() new_resn = new_resn.upper() new_resn = three_letter.get(new_resn, new_resn) if inplace: cpy = org else: cpy = cmd.get_unused_name(org + '_cpy') cmd.create(cpy, org, -1, 1, zoom=0) scr = [] cmd.iterate('first (%s)' % selection, 'scr[:] = (segi,chain,resi,resn)', space={'scr': scr}) res = '/%s/%s/%s/%s' % tuple([cpy] + scr[:3]) if mode == 1: old_resn = scr[3] chi_atoms = { 'ALA': [], 'ARG': ['C', 'CA', 'CB', 'CG', 'CD', 'NE', 'CZ'], 'ASN': ['C', 'CA', 'CB', 'CG', 'OD1'], 'ASP': ['C', 'CA', 'CB', 'CG', 'OD1'], 'CYS': ['C', 'CA', 'CB', 'SG'], 'GLN': ['C', 'CA', 'CB', 'CG', 'CD', 'OE1'], 'GLU': ['C', 'CA', 'CB', 'CG', 'CD', 'OE1'], 'GLY': [], 'HIS': ['C', 'CA', 'CB', 'CG', 'ND1'], 'ILE': ['C', 'CA', 'CB', 'CG1', 'CD1'], 'LEU': ['C', 'CA', 'CB', 'CG', 'CD1'], 'LYS': ['C', 'CA', 'CB', 'CG', 'CD', 'CE', 'NZ'], 'MET': ['C', 'CA', 'CB', 'CG', 'SD', 'CE'], 'MSE': ['C', 'CA', 'CB', 'CG', 'SE', 'CE'], 'PHE': ['C', 'CA', 'CB', 'CG', 'CD1'], 'PRO': [], 'SER': ['C', 'CA', 'CB', 'OG'], 'THR': ['C', 'CA', 'CB', 'OG1'], 'TRP': ['C', 'CA', 'CB', 'CG', 'CD2'], 'TYR': ['C', 'CA', 'CB', 'CG', 'CD1'], 'VAL': ['C', 'CA', 'CB', 'CG2'], } atoms = [res + '/' + name for name in chi_atoms.get(old_resn, [])] old_chi = [] for args in zip(atoms, atoms[1:], atoms[2:], atoms[3:]): try: old_chi.append(cmd.get_dihedral(*args)) except: break cmd.remove('%s and not name CA+C+N+O+OXT' % (res)) # start the wizard to count the number of rotamers for this residue cmd.wizard("mutagenesis") cmd.get_wizard().set_mode(new_resn) cmd.get_wizard().set_hyd(hydrogens) cmd.get_wizard().do_select("(" + res + ")") def get_best_state_bump(): best_state = (1, 1e9) cmd.create(tmp, '%s and not name CA+C+N+O or (%s within 8.0 of (%s and name CB))' % \ (mutagenesis.obj_name, cpy, mutagenesis.obj_name), zoom=0, singletons=1) cmd.bond('name CB and %s in %s' % (tmp, mutagenesis.obj_name), 'name CA and %s in %s' % (tmp, res)) cmd.sculpt_activate(tmp) for i in range(1, cmd.count_states(tmp) + 1): score = cmd.sculpt_iterate(tmp, state=i) if not quiet: print('Frame %d Score %.2f' % (i, score)) if score < best_state[1]: best_state = (i, score) cmd.delete(tmp) if not quiet: print(' Best: Frame %d Score %.2f' % best_state) return best_state if cmd.count_states(mutagenesis.obj_name) < 2 or mode > 0: best_state = (1, -1.0) else: best_state = get_best_state_bump() cmd.frame(best_state[0]) cmd.get_wizard().apply() cmd.wizard() if mode == 1: atoms = [res + '/' + name for name in chi_atoms.get(new_resn, [])] for args in zip(atoms, atoms[1:], atoms[2:], atoms[3:], old_chi): cmd.set_dihedral(*args) cmd.unpick() if sculpt > 0: sculpt_relax(res, 0, sculpt == 2, cpy) return cpy
with open(filename, 'r') as f: lines = f.readlines() lines = list(filter(filter_func, lines)) ang_pairs.extend(list(map(map_func, lines))) restraints.extend(list(map(map_func2, lines))) out_lines = [] for ang_pair, restraint in zip(ang_pairs, restraints): group1 = "(id %d)" % ang_pair[0] group2 = "(id %d)" % ang_pair[1] group3 = "(id %d)" % ang_pair[2] cmd.angle("%d-%d-%d" % ang_pair, group1, group2, group3) resns = [] resis = [] atoms = [] cmd.iterate("id %d+%d+%d" % ang_pair, "resns.append(resn)") cmd.iterate("id %d+%d+%d" % ang_pair, "resis.append(resi)") cmd.iterate("id %d+%d+%d" % ang_pair, "atoms.append(name)") angle = cmd.get_angle(group1, group2, group3) out_lines.append( "[ %s%s(%s)-%s%s(%s)-%s%s(%s) ~ %.2f degree (%s, %s, %s) ]\n" % ((resns[0], resis[0], atoms[0], resns[1], resis[1], atoms[1], resns[2], resis[2], atoms[2], angle) + restraint)) out_lines.append("%d %d %d\n" % ang_pair) # write dis_pairs to distance_pairs.ndx for analysis with open("angle_out.ndx", 'w') as f: for line in out_lines: f.write(line) print(line)
def muta(): ''' DESCRIPTION Creates an alignment of two proteins and superimposes them. Aligned residues that are different in the two (i.e. mutations) are highlighted and colored according to their difference in the BLOSUM90 matrix. Is meant to be used for similar proteins, e.g. close homologs or point mutants, to visualize their differences. USAGE color_by_mutation selection1, selection2 [,waters [,labels ]] ARGUMENTS obj1: object or selection obj2: object or selection waters: bool (0 or 1). If 1, waters are included in the view, colored differently for the both input structures. default = 0 labels: bool (0 or 1). If 1, the possibly mutated sidechains are labeled by their chain, name and id default = 0 EXAMPLE color_by_mutation protein1, protein2 SEE ALSO super ''' from pymol import stored, CmdException obj1 = "native_na" obj2 = "design_na" waters = 0 labels = 0 if cmd.count_atoms(obj1) == 0: print '%s is empty' % obj1 return if cmd.count_atoms(obj2) == 0: print '%s is empty' % obj2 return waters = int(waters) labels = int(labels) # align the two proteins aln = '__aln' # first, an alignment with 0 cycles (no atoms are rejected, which maximized the number of aligned residues) # for some mutations in the same protein this works fine). This is essentially done to get a # sequence alignment cmd.super(obj2, obj1, object=aln, cycles=0) # superimpose the the object using the default parameters to get a slightly better superimposition, # i.e. get the best structural alignment cmd.super(obj2, obj1) stored.resn1, stored.resn2 = [], [] stored.resi1, stored.resi2 = [], [] stored.chain1, stored.chain2 = [], [] # store residue ids, residue names and chains of aligned residues cmd.iterate(obj1 + ' and name CA and ' + aln, 'stored.resn1.append(resn)') cmd.iterate(obj2 + ' and name CA and ' + aln, 'stored.resn2.append(resn)') cmd.iterate(obj1 + ' and name CA and ' + aln, 'stored.resi1.append(resi)') cmd.iterate(obj2 + ' and name CA and ' + aln, 'stored.resi2.append(resi)') cmd.iterate(obj1 + ' and name CA and ' + aln, 'stored.chain1.append(chain)') cmd.iterate(obj2 + ' and name CA and ' + aln, 'stored.chain2.append(chain)') mutant_selection = '' non_mutant_selection = 'none or ' colors = [] # loop over the aligned residues for n1, n2, i1, i2, c1, c2 in zip(stored.resn1, stored.resn2, stored.resi1, stored.resi2, stored.chain1, stored.chain2): # take care of 'empty' chain names if c1 == '': c1 = '""' if c2 == '': c2 = '""' if n1 == n2: non_mutant_selection += '((%s and resi %s and chain %s) or (%s and resi %s and chain %s)) or ' % ( obj1, i1, c1, obj2, i2, c2) else: mutant_selection += '((%s and resi %s and chain %s) or (%s and resi %s and chain %s)) or ' % ( obj1, i1, c1, obj2, i2, c2) # get the similarity (according to the blosum matrix) of the two residues and c = getBlosum90ColorName(n1, n2) colors.append( (c, '%s and resi %s and chain %s and elem C' % (obj2, i2, c2))) if mutant_selection == '': print ' Error: No mutations found' raise CmdException # create selections cmd.select('mutations', mutant_selection[:-4]) cmd.select('non_mutations', non_mutant_selection[:-4]) cmd.select( 'not_aligned', '(%s or %s) and not mutations and not non_mutations' % (obj1, obj2)) # create the view and coloring cmd.hide('everything', '%s or %s' % (obj1, obj1)) cmd.show('cartoon', '%s or %s' % (obj2, obj1)) cmd.show( 'lines', '(%s or %s) and ((non_mutations or not_aligned) and not name c+o+n)' % (obj2, obj1)) cmd.show('sticks', '(%s or %s) and mutations and not name c+o+n' % (obj2, obj1)) cmd.color('white', 'elem C and non_mutations') cmd.color('cyan', 'elem C and mutations and %s' % obj1) cmd.color('gray', 'elem C and not_aligned') cmd.color('limon', 'chainA') cmd.util.cnc("all") for (col, sel) in colors: cmd.color(col, sel) cmd.hide('everything', '(hydro) and (%s or %s)' % (obj2, obj1)) cmd.center('%s or %s' % (obj2, obj1)) if labels: cmd.label('mutations and name CA', '"(%s-%s-%s)"%(chain, resi, resn)') if waters: cmd.set('sphere_scale', '0.1') cmd.show('spheres', 'resn HOH and (%s or %s)' % (obj2, obj1)) cmd.color('red', 'resn HOH and %s' % obj1) cmd.color('salmon', 'resn HOH and %s' % obj2) print ''' Mutations are highlighted in blue and red. All mutated sidechains of %s are colored blue, the corresponding ones from %s are colored on a spectrum from blue to red according to how similar the two amino acids are (as measured by the BLOSUM90 substitution matrix). Aligned regions without mutations are colored white. Regions not used for the alignment are gray. NOTE: There could be mutations in the gray regions that were not detected.''' % ( obj2, obj1) cmd.delete(aln) cmd.deselect() cmd.zoom("interface")
def peptide_rebuild(name, selection='all', cycles=1000, state=1, quiet=1): ''' DESCRIPTION Rebuild the peptide from selection. All atoms which are present in selection will be kept fixed, while atoms missing in selection are placed by sculpting. USAGE peptide_rebuild name [, selection [, cycles [, state ]]] SEE ALSO stub2ala, add_missing_atoms, peptide_rebuild_modeller ''' from chempy import fragments, feedback, models cycles, state, quiet = int(cycles), int(state), int(quiet) # suppress feedback for model merging feedback['actions'] = False # work with named selection namedsele = cmd.get_unused_name('_') cmd.select(namedsele, '{} & present'.format(selection), 0) identifiers = [] cmd.iterate(namedsele + ' and polymer and guide and alt +A', 'identifiers.append([segi,chain,resi,resv,resn])', space=locals()) model = models.Indexed() for (segi, chain, resi, resv, resn) in identifiers: try: fname = resn.lower() if resn != 'MSE' else 'met' frag = fragments.get(fname) except IOError: print(' Warning: unknown residue: ' + resn) continue for a in frag.atom: a.segi = segi a.chain = chain a.resi = resi a.resi_number = resv a.resn = resn model.merge(frag) if not quiet: print(' Loading model...') cmd.load_model(model, name, 1, zoom=0) if cmd.get_setting_boolean('auto_remove_hydrogens'): cmd.remove(name + ' and hydro') cmd.protect(name + ' in ' + namedsele) cmd.sculpt_activate(name) cmd.update(name, namedsele, 1, state) cmd.delete(namedsele) if not quiet: print(' Sculpting...') cmd.set('sculpt_field_mask', 0x003, name) # bonds and angles only cmd.sculpt_iterate(name, 1, int(cycles / 4)) cmd.set('sculpt_field_mask', 0x09F, name) # local + torsions cmd.sculpt_iterate(name, 1, int(cycles / 4)) cmd.set('sculpt_field_mask', 0x0FF, name) # ... + vdw cmd.sculpt_iterate(name, 1, int(cycles / 2)) cmd.sculpt_deactivate(name) cmd.deprotect(name) cmd.unset('sculpt_field_mask', name) if not quiet: print(' Connecting peptide...') pairs = cmd.find_pairs(name + ' and name C', name + ' and name N', 1, 1, 2.0) for pair in pairs: cmd.bond(*pair) cmd.h_fix(name) if not quiet: print(' peptide_rebuild: done')
def loadflexdock( system, dataset, idx="1", flexdist="3", pdbbindpath="../../PDBbind18", dockingpath="", ): # Clear everything cmd.reinitialize("everything") # Convert string of indices to numbers idx = int(idx) # Convert flexdist to float flexdist = float(flexdist) # Print informations print(f"Loading {dataset}/{system} (rank {idx})") print(f"flexdist = {flexdist}") # Build paths ligname = f"{system}_ligand-{idx}.pdb" ligandpath = os.path.join(dockingpath, dataset, system, ligname) # Docked ligand flexname = f"{system}_flex-{idx}.pdb" flexpath = os.path.join(dockingpath, dataset, system, flexname) # Flexible residues receptorname = f"{system}_protein-{idx}.pdb" receptorpath = os.path.join(dockingpath, dataset, system, receptorname) crystalname = f"{system}_protein.pdb" crystalpath = os.path.join( pdbbindpath, dataset, system, crystalname ) # Crystal receptor # Load ligand and receptor cmd.load(ligandpath, "ligand") # Selection name: ligand cmd.load(flexpath, "flex") # Selection name: flex cmd.load(receptorpath, "receptor") # Selection name: receptor cmd.load(crystalpath, "crystal") # Selection name: receptor # Hide everything cmd.hide("all") # Show receptor cmd.show("cartoon", "receptor") cmd.color("grey", "receptor") # Show docked ligand cmd.show("sticks", "ligand") cmd.show("spheres", "ligand") cmd.set("sphere_scale", 0.2, "ligand") cmd.color("marine", "ligand and name C*") # Show flexible residues cmd.show("licorice", "flex") cmd.set("stick_radius", 0.2, "flex") cmd.color("teal", "flex and name C*") # Center and zoom to ligand cmd.center("ligand") cmd.zoom("ligand", 10) # Remove solvent cmd.remove("solvent") # Get residues of receptor close to flexible residues stored.list = [] cmd.iterate( "receptor within 0.1 of flex", # Selection "stored.list.append((resn, resi, chain))", # Action ) # Remove redundancies flexres = set(stored.list) # Set of flexible residues # Outline flexible residues of the receptor for _, resi, chain in flexres: if chain != "": # ??? sel = f"receptor and (resi {resi} in chain {chain})" cmd.show("sphere", sel) cmd.set("sphere_scale", 0.2, sel) cmd.color("yellow", sel) cmd.remove(f"hydro in ({sel})") # Outline flexible residues of the crystal for _, resi, chain in flexres: if chain != "": # ??? sel = f"crystal and (resi {resi} in chain {chain})" cmd.show("licorice", sel) cmd.set("stick_radius", 0.15, sel) cmd.color("deeppurple", sel) cmd.remove(f"hydro in ({sel})") # Show metal atoms cmd.show("spheres", "metals") cmd.set("sphere_scale", 0.5, "metals")