def findSurfaceAtoms(selection="all", cutoff=2.5, quiet=1): """ DESCRIPTION Finds those atoms on the surface of a protein that have at least 'cutoff' exposed A**2 surface area. USAGE findSurfaceAtoms [ selection, [ cutoff ]] SEE ALSO findSurfaceResidues """ cutoff, quiet = float(cutoff), int(quiet) tmpObj = cmd.get_unused_name("_tmp") cmd.create(tmpObj, "(" + selection + ") and polymer", zoom=0) cmd.set("dot_solvent", 1, tmpObj) 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)) selName = cmd.get_unused_name("exposed_atm_") cmd.select(selName, "(" + selection + ") in " + tmpObj) cmd.delete(tmpObj) if not quiet: print("Exposed atoms are selected in: " + selName) return selName
def set_raw_alignment(name, aln, transform=0): ''' DESCRIPTION API only. Load an alignment object from a list like the one obtained with cmd.get_raw_alignment ''' import itertools if not isinstance(aln[0], dict): aln = [dict(idx_pair) for idx_pair in aln] models = set(model for idx_pdict in aln for model in idx_pdict) sele1 = cmd.get_unused_name('_sele1') sele2 = cmd.get_unused_name('_sele2') fit = cmd.fit if transform else cmd.rms_cur for model1, model2 in itertools.combinations(models, 2): index_list1 = [] index_list2 = [] for idx_pdict in aln: if model1 in idx_pdict and model2 in idx_pdict: index_list1.append(idx_pdict[model1]) index_list2.append(idx_pdict[model2]) cmd.select_list(sele1, model1, index_list1, mode='index') cmd.select_list(sele2, model2, index_list2, mode='index') fit(sele1, sele2, cycles=0, matchmaker=4, object=name) cmd.delete(sele1) cmd.delete(sele2)
def apbs_surface(selection='all', maximum=None, minimum=None, map_name=None, ramp_name=None, grid=0.5, quiet=1): ''' DESCRIPTION Show electrostatic potential on surface (calculated with APBS). Important: surface_color is a object property, so when calculating surface potential for different selections and visualize them all together, you should first split them into separate objects. USAGE apbs_surface [ selection [, maximum [, minimum ]]] EXAMPLE fetch 2x19, bsync=0 split_chains apbs_surface 2x19_A, 10 apbs_surface 2x19_B, 10 SEE ALSO map_new_apbs, APBS Tools Plugin, isosurface, gradient, util.protein_vacuum_esp ''' quiet = int(quiet) if ramp_name is None: ramp_name = cmd.get_unused_name('ramp') if map_name is None: map_name = cmd.get_unused_name('map') map_new_apbs(map_name, selection, float(grid), quiet=quiet) if maximum is not None: maximum = float(maximum) minimum = -maximum if minimum is None else float(minimum) kwargs = {'range': [minimum, (minimum + maximum) * 0.5, maximum]} else: kwargs = {'selection': selection} cmd.ramp_new(ramp_name, map_name, **kwargs) object_names = cmd.get_object_list('(' + selection + ')') for name in object_names: cmd.set('surface_color', ramp_name, name) cmd.show('surface', selection) cmd.set('surface_solvent', 0) cmd.set('surface_ramp_above_mode', 1)
def draw_shell_sphere(radius, polar_cone_angle=np.pi / 36., axis0=np.array([0., 1., 0.]), axis1=np.array([0., 0., 1.]), linewidth=1, linespacing=0.15, alpha=0.35, name=None): """Draw sphere and stereo regions at specified radius in PyMOL.""" center = np.array([0., 0., 0.], dtype=np.double) obj = [] # draw sphere obj.extend( get_cgo_sphere_obj(center, radius, color=[1., 1., 1.], alpha=alpha)) cmd.load_cgo(obj, cmd.get_unused_name('sphere_{:.4f}'.format(radius))) # draw polar circles obj = [] obj.extend([BEGIN, LINES, COLOR] + [0., 0., 0.]) v_to_cone_center = radius * np.cos(polar_cone_angle) * axis0 cone_radius = radius * np.sin(polar_cone_angle) obj.extend( get_cgo_circle_obj(center + v_to_cone_center, axis0, cone_radius, linespacing=linespacing)) obj.extend( get_cgo_circle_obj(center - v_to_cone_center, -axis0, cone_radius, linespacing=linespacing)) # draw equator obj.extend( get_cgo_circle_obj(center, axis0, radius, linespacing=linespacing)) # draw quadrant arcs for i in (1, 3, 5, 7): if i in (5, 7): color = [.8, .8, .8] else: color = [0., 0., 0.] disk_norm = get_disk_norm(axis0, axis1, i * np.pi / 4.) arc_start = (cone_radius * as_unit(np.cross(disk_norm, axis0)) + center + v_to_cone_center) obj.extend( get_cgo_arc_obj(center, disk_norm, arc_start, np.pi - 2 * polar_cone_angle, linespacing=linespacing, color=color)) # draw axes obj.append(END) lname = cmd.get_unused_name('contours_{:.4f}'.format(radius)) cmd.load_cgo(obj, lname) cmd.set("cgo_line_width", linewidth, lname)
def from_alignment(self, mobile, target, aln_obj): ''' Use alignment given by "aln_obj" (name of alignment object) ''' from .selecting import wait_for wait_for(aln_obj) self.mobile = '(%s) and %s' % (mobile, aln_obj) self.target = '(%s) and %s' % (target, aln_obj) if self.check(): return # difficult: if selections spans only part of the alignment or # if alignment object covers more than the two objects, then we # need to pick those columns that have no gap in any of the two # given selections mobileidx = set(cmd.index(mobile)) targetidx = set(cmd.index(target)) mobileidxsel = [] targetidxsel = [] for column in cmd.get_raw_alignment(aln_obj): mobiles = mobileidx.intersection(column) if len(mobiles) == 1: targets = targetidx.intersection(column) if len(targets) == 1: mobileidxsel.extend(mobiles) targetidxsel.extend(targets) self.mobile = cmd.get_unused_name('_mobile') self.target = cmd.get_unused_name('_target') self.temporary.append(self.mobile) self.temporary.append(self.target) mobile_objects = set(idx[0] for idx in mobileidxsel) target_objects = set(idx[0] for idx in targetidxsel) if len(mobile_objects) == len(target_objects) == 1: mobile_index_list = [idx[1] for idx in mobileidxsel] target_index_list = [idx[1] for idx in targetidxsel] cmd.select_list(self.mobile, mobile_objects.pop(), mobile_index_list, mode='index') cmd.select_list(self.target, target_objects.pop(), target_index_list, mode='index') else: cmd.select(self.mobile, ' '.join('%s`%d' % idx for idx in mobileidxsel)) cmd.select(self.target, ' '.join('%s`%d' % idx for idx in targetidxsel))
def apbs_surface(selection='all', maximum=None, minimum=None, map_name=None, ramp_name=None, grid=0.5, quiet=1): ''' DESCRIPTION Show electrostatic potential on surface (calculated with APBS). Important: surface_color is a object property, so when calculating surface potential for different selections and visualize them all together, you should first split them into separate objects. USAGE apbs_surface [ selection [, maximum [, minimum ]]] EXAMPLE fetch 2x19, async=0 split_chains apbs_surface 2x19_A, 10 apbs_surface 2x19_B, 10 SEE ALSO map_new_apbs, APBS Tools Plugin, isosurface, gradient, util.protein_vacuum_esp ''' quiet = int(quiet) if ramp_name is None: ramp_name = cmd.get_unused_name('ramp') if map_name is None: map_name = cmd.get_unused_name('map') map_new_apbs(map_name, selection, float(grid), quiet=quiet) if maximum is not None: maximum = float(maximum) minimum = -maximum if minimum is None else float(minimum) kwargs = {'range': [minimum, (minimum+maximum)*0.5, maximum]} else: kwargs = {'selection': selection} cmd.ramp_new(ramp_name, map_name, **kwargs) object_names = cmd.get_object_list('(' + selection + ')') for name in object_names: cmd.set('surface_color', ramp_name, name) cmd.show('surface', selection) cmd.set('surface_solvent', 0) cmd.set('surface_ramp_above_mode', 1)
def testGetUnusedName(self): n1 = cmd.get_unused_name() self.assertEqual(n1, "tmp01") n2 = cmd.get_unused_name("foo", 0) self.assertEqual(n2, "foo") cmd.pseudoatom("foo") n3 = cmd.get_unused_name("foo", 0) self.assertEqual(n3, "foo01") cmd.pseudoatom("foo01") cmd.pseudoatom("foo02") n4 = cmd.get_unused_name("foo") self.assertEqual(n4, "foo03") cmd.delete('*') n5 = cmd.get_unused_name("foo") self.assertEqual(n5, "foo01")
def myalign(method): newmobile = cmd.get_unused_name(mobile_obj + '_' + method) cmd.create(newmobile, mobile_obj) start = time.time() cmd.do('%s mobile=%s in %s, target=%s' % (method, newmobile, mobile, target)) if not quiet: print('Finished: %s (%.2f sec)' % (method, time.time() - start))
def com(selection,state=None,mass=None,object=None, quiet=1, **kwargs): """ DESCRIPTION Places a pseudoatom at the center of mass Author: Sean Law Michigan State University slaw (at) msu . edu SEE ALSO pseudoatom, get_com """ quiet = int(quiet) if (object == None): object = cmd.get_legal_name(selection) object = cmd.get_unused_name(object + "_COM", 0) cmd.delete(object) if (state != None): x, y, z=get_com(selection,mass=mass, quiet=quiet) if not quiet: print "%f %f %f" % (x, y, z) cmd.pseudoatom(object,pos=[x, y, z], **kwargs) cmd.show("spheres",object) else: for i in range(cmd.count_states()): x, y, z=get_com(selection,mass=mass,state=i+1, quiet=quiet) if not quiet: print "State %d:%f %f %f" % (i+1, x, y, z) cmd.pseudoatom(object,pos=[x, y, z],state=i+1, **kwargs) cmd.show("spheres", 'last ' + object)
def normalmodes_prody(selection, cutoff=15, first=7, last=10, guide=1, prefix='prody', states=7, factor=-1, quiet=1): ''' DESCRIPTION Anisotropic Network Model (ANM) analysis with ProDy. Based on: http://www.csb.pitt.edu/prody/examples/dynamics/enm/anm.html ''' try: import prody except ImportError: print('Failed to import prody, please add to PYTHONPATH') raise CmdException first, last, guide = int(first), int(last), int(guide) states, factor, quiet = int(states), float(factor), int(quiet) assert first > 6 if guide: selection = '(%s) and guide and alt A+' % (selection) tmpsele = cmd.get_unused_name('_') cmd.select(tmpsele, selection) f = StringIO(cmd.get_pdbstr(tmpsele)) conf = prody.parsePDBStream(f) modes = prody.ANM() modes.buildHessian(conf, float(cutoff)) modes.calcModes(last - first + 1) if factor < 0: from math import log natoms = modes.numAtoms() factor = log(natoms) * 10 if not quiet: print(' set factor to %.2f' % (factor)) for mode in range(first, last + 1): name = prefix + '%d' % mode cmd.delete(name) if not quiet: print(' normalmodes: object "%s" for mode %d' % (name, mode)) for state in range(1, states+1): xyz_it = iter(modes[mode-7].getArrayNx3() * (factor * ((state-1.0)/(states-1.0) - 0.5))) cmd.create(name, tmpsele, 1, state, zoom=0) cmd.alter_state(state, name, '(x,y,z) = xyz_it.next() + (x,y,z)', space=locals()) cmd.delete(tmpsele) if guide: cmd.set('ribbon_trace_atoms', 1, prefix + '*') cmd.show_as('ribbon', prefix + '*') else: cmd.show_as('lines', prefix + '*')
def do_select(self, name): # map selects into picks from .selecting import select_sspick if self.name not in cmd.get_names('selections', enabled_only=1): self.name = cmd.get_unused_name('ss') select_sspick(name, self.name, self.selection_mode) cmd.enable(self.name) cmd.refresh_wizard()
def CMVDialog(self): import tkFileDialog import tkMessageBox try: import pygame as pg except ImportError: tkMessageBox.showerror('Error', 'This plugin requires the "pygame" module') return myFormats = [('Portable Network Graphics', '*.png'), ('JPEG / JFIF', '*.jpg')] try: image_file = tkFileDialog.askopenfilename(parent=self.root, filetypes=myFormats, title='Choose the contact map image file') if not image_file: raise except: tkMessageBox.showerror('Error', 'No Contact Map!') return myFormatsPDB = [('Protein Data Bank', '*.pdb'), ('MDL mol', '*.mol'), ('PyMol Session File', '*.pse')] try: pdb_file = tkFileDialog.askopenfilename(parent=self.root, filetypes=myFormatsPDB, title='Choose the corresponding PDB file') if not pdb_file: raise except: tkMessageBox.showerror('Error', 'No PDB file!') return name = cmd.get_unused_name('protein') cmd.load(pdb_file, name) contact_map_visualizer(image_file, name, 1, 0)
def normalmodes_prody(selection, cutoff=15, first=7, last=10, guide=1, prefix='prody', states=7, factor=-1, quiet=1): ''' DESCRIPTION Anisotropic Network Model (ANM) analysis with ProDy. Based on: http://www.csb.pitt.edu/prody/examples/dynamics/enm/anm.html ''' try: import prody except ImportError: print('Failed to import prody, please add to PYTHONPATH') raise CmdException first, last, guide = int(first), int(last), int(guide) states, factor, quiet = int(states), float(factor), int(quiet) assert first > 6 if guide: selection = '(%s) and guide and alt A+' % (selection) tmpsele = cmd.get_unused_name('_') cmd.select(tmpsele, selection) f = StringIO(cmd.get_pdbstr(tmpsele)) conf = prody.parsePDBStream(f) modes = prody.ANM() modes.buildHessian(conf, float(cutoff)) modes.calcModes(last - first + 1) if factor < 0: from math import log natoms = modes.numAtoms() factor = log(natoms) * 10 if not quiet: print(' set factor to %.2f' % (factor)) for mode in range(first, last + 1): name = prefix + '%d' % mode cmd.delete(name) if not quiet: print(' normalmodes: object "%s" for mode %d' % (name, mode)) for state in range(1, states+1): xyz_it = iter(modes[mode-7].getArrayNx3() * (factor * ((state-1.0)/(states-1.0) - 0.5))) cmd.create(name, tmpsele, 1, state, zoom=0) cmd.alter_state(state, name, '(x,y,z) = next(xyz_it) + (x,y,z)', space={'xyz_it': xyz_it, 'next': next}) cmd.delete(tmpsele) if guide: cmd.set('ribbon_trace_atoms', 1, prefix + '*') cmd.show_as('ribbon', prefix + '*') else: cmd.show_as('lines', prefix + '*')
def visualize_orientation(direction, center=[0, 0, 0], scale=1.0, symmetric=False, color="green", color2="red"): """ Draw an arrow. Helper function for "helix_orientation" etc. """ from pymol import cgo color_list = cmd.get_color_tuple(color) color2_list = cmd.get_color_tuple(color2) if symmetric: scale *= 0.5 end = cpv.add(center, cpv.scale(direction, scale)) radius = 0.3 obj = [cgo.SAUSAGE] obj.extend(center) obj.extend(end) obj.extend([radius, 0.8, 0.8, 0.8]) obj.extend(color_list) if symmetric: start = cpv.sub(center, cpv.scale(direction, scale)) obj.append(cgo.SAUSAGE) obj.extend(center) obj.extend(start) obj.extend([radius, 0.8, 0.8, 0.8]) obj.extend(color2_list) coneend = cpv.add(end, cpv.scale(direction, 4.0 * radius)) if cmd.get_version()[1] >= 1.2: obj.append(cgo.CONE) obj.extend(end) obj.extend(coneend) obj.extend([radius * 1.75, 0.0]) obj.extend(color_list * 2) obj.extend([1.0, 1.0]) # Caps cmd.load_cgo(obj, get_unused_name("oriVec"), zoom=0)
def load_msms_surface(filename, name='', _colors=None): ''' DESCRIPTION Load MSMS .vert and .face files as a CGO ''' from pymol import cgo from pymol.cgo import NORMAL, VERTEX, COLOR if _colors: _colors = [cmd.get_color_tuple(c) for c in _colors] if filename.endswith('.vert') or filename.endswith('.face'): filename = filename[:-5] # vertex file line_iter = iter(open(filename + '.vert')) # skip header for line in line_iter: if not line.startswith('#'): break # read vertices vertices = [None] # make 1-indexable for line in line_iter: data = line.split() vertex = [float(x) for x in data[0:3]] normal = [float(x) for x in data[3:6]] sphere = int(data[7]) - 1 vertices.append((vertex, normal, sphere)) # faces file line_iter = iter(open(filename + '.face')) # skip header for line in line_iter: if not line.startswith('#'): break cgobuf = [cgo.BEGIN, cgo.TRIANGLES] # read triangles for line in line_iter: for index in line.split()[:3]: data = vertices[int(index)] if _colors: cgobuf.append(COLOR) cgobuf.extend(_colors[data[2]]) cgobuf.append(NORMAL) cgobuf.extend(data[1]) cgobuf.append(VERTEX) cgobuf.extend(data[0]) cgobuf.append(cgo.END) if not name: name = cmd.get_unused_name('msmssurf') cmd.load_cgo(cgobuf, name)
def myalign(method): newmobile = cmd.get_unused_name(mobile_obj + '_' + method) cmd.create(newmobile, mobile_obj) start = time.time() cmd.do('%s mobile=%s in %s, target=%s' % (method, newmobile, mobile, target)) if not quiet: print 'Finished: %s (%.2f sec)' % (method, time.time() - start)
def load_msms_surface(filename, name="", _colors=None): """ DESCRIPTION Load MSMS .vert and .face files as a CGO """ from pymol import cgo from pymol.cgo import NORMAL, VERTEX, COLOR if _colors: _colors = [cmd.get_color_tuple(c) for c in _colors] if filename.endswith(".vert") or filename.endswith(".face"): filename = filename[:-5] # vertex file line_iter = iter(open(filename + ".vert")) # skip header for line in line_iter: if not line.startswith("#"): break # read vertices vertices = [None] # make 1-indexable for line in line_iter: data = line.split() vertex = [float(x) for x in data[0:3]] normal = [float(x) for x in data[3:6]] sphere = int(data[7]) - 1 vertices.append((vertex, normal, sphere)) # faces file line_iter = iter(open(filename + ".face")) # skip header for line in line_iter: if not line.startswith("#"): break cgobuf = [cgo.BEGIN, cgo.TRIANGLES] # read triangles for line in line_iter: for index in line.split()[:3]: data = vertices[int(index)] if _colors: cgobuf.append(COLOR) cgobuf.extend(_colors[data[2]]) cgobuf.append(NORMAL) cgobuf.extend(data[1]) cgobuf.append(VERTEX) cgobuf.extend(data[0]) cgobuf.append(cgo.END) if not name: name = cmd.get_unused_name("msmssurf") cmd.load_cgo(cgobuf, name)
def visualize_orientation(direction, center=[0.0] * 3, scale=1.0, symmetric=False, color='green', color2='red'): ''' DESCRIPTION Draw an arrow. Helper function for "helix_orientation" etc. ''' from pymol import cgo color_list = cmd.get_color_tuple(color) color2_list = cmd.get_color_tuple(color2) if symmetric: scale *= 0.5 end = cpv.add(center, cpv.scale(direction, scale)) radius = 0.3 obj = [cgo.SAUSAGE] obj.extend(center) obj.extend(end) obj.extend([ radius, 0.8, 0.8, 0.8, ]) obj.extend(color_list) if symmetric: start = cpv.sub(center, cpv.scale(direction, scale)) obj.append(cgo.SAUSAGE) obj.extend(center) obj.extend(start) obj.extend([ radius, 0.8, 0.8, 0.8, ]) obj.extend(color2_list) coneend = cpv.add( end, cpv.scale(direction, 4.0 * radius / cpv.length(direction))) obj.append(cgo.CONE) obj.extend(end) obj.extend(coneend) obj.extend([ radius * 1.75, 0.0, ]) obj.extend(color_list * 2) obj.extend([ 1.0, 1.0, # Caps ]) cmd.load_cgo(obj, get_unused_name('oriVec'), zoom=0)
def drow2Dlattice(gName="",Type="Hexagonal",UCp0=[0,0,0],UCa=310,UCb=100,UCaAng=0,UCbAng=60,UCc=[218/256,165/256,32/256],UCr=1,SE=1,SEl=15,SEr=1.2): ''' Start input some documentation here This fucnction generate a pymol set of CGOs to illustrate the p632 plane symmetry inputs: UCp0 - origin of unit cell list/array of dimension 3 UCa - first unit cell primitive vector length (unit cell spacing) in Agstrom UCb - second unit cell primitive vector length (unit cell spacing) in Agstrom, for some unit cell types this value is predetermined as equal to the first primitive vector UCaAng - direction of the first primitive vector , by default along the x axis UCbAng - angle of the second primitive vector in x,y plane vs. the first primitive vector, this is a variables only for unit cells of type Oblique and Rhombic UCc - cgo cylinders color (currently type of orange) UCr - cgo cylinders radio=us. SE = boolian, drow symmetry elements SEl - diameter of rotation symmetry object to be printed SEr - cgo cylinders radius belonging to the rotation symmetry objects Output: gName = name of group all the objects are clustered under objList - list of objects geerated (this allows pther functions to modify or delete produced selections. ) np.array(UCp0),p1,p2,p3 - Unitcell corners position in x,y,z list format ''' SEc1 = [1,0,0] ; SEc2 = [0,1,0] ; SEc3 = [0,1,1] ; SEc4 = [0,0,1] # colors of symmetry operations UCp0 = np.array(UCp0) V0 = np.array([1,0,0]) # Default orientation (facing the x direction) in the plane in XY plane UCp0,p1,p2,p3,objList1 = drowUnitCell3(Type="Hexagonal", UCp0=UCp0,UCa=UCa,UCb=UCb,V0=V0,UCaAng=UCaAng,UCbAng=UCbAng,UCc=UCc,UCr=UCr) if SE: # default to drow the sym elements nfold = 6 objList11=drowRect(UCp0,SEl,nfold,SEr,SEc1) ; objList12=drowRect(p1,SEl,nfold,SEr,SEc1) ;objList13=drowRect(p2,SEl,nfold,SEr,SEc1) ;objList14=drowRect(p3,SEl,nfold,SEr,SEc1) nfold = 3 ; P3_1 = 2/3*np.array(UCp0)+1/3*p3 ; P3_2 = 1/3*np.array(UCp0)+ 2/3*p3 objList21=drowRect(P3_1,SEl,nfold,SEr,SEc2) ; objList22=drowRect(P3_2,SEl,nfold,SEr,SEc2) nfold = 2 ; SEr=3;SEl=10; P2_1 = (np.array(UCp0)+p1)/2 ; P2_2 = (np.array(UCp0)+p2)/2 ; P2_3 = (p1+p3)/2 ;P2_4 = (p2+p3)/2 ; P2_5 = (np.array(UCp0)+p3)/2 objList31=drowRect(P2_1,SEl,nfold,SEr,SEc4) ; objList32=drowRect(P2_2,SEl,nfold,SEr,SEc4) ; objList33=drowRect(P2_3,SEl,nfold,SEr,SEc4); objList34=drowRect(P2_4,SEl,nfold,SEr,SEc4) ; objList35=drowRect(P2_5,SEl,nfold,SEr,SEc4) ### preparing pumol CGO selection output groups objList = objList11+objList12+objList13+objList14+objList21+objList22+objList31+objList32+objList33+objList34+objList35 ### list of unique names not in use in the pymol session gName = cmd.get_unused_name('p6') frameName = cmd.get_unused_name('frame') elementsName = cmd.get_unused_name('elements') ### creating two sub groups of the unit cell frame and the symmetry elements within [ cmd.group(frameName, members=name , action='add', quiet=1) for name in objList1] [ cmd.group(elementsName, members=name , action='add', quiet=1) for name in objList] ### group of the two above [ cmd.group(gName, members=name , action='add', quiet=1) for name in [frameName,elementsName]] print("Unit Cell ",gName," Corbers are in: ", np.array(UCp0),p1,p2,p3) return np.array(UCp0),p1,p2,p3,objList,gName
def plane_orientation(selection, state=-1, visualize=1, quiet=1): ''' DESCRIPTION Fit plane (for example beta-sheet). Can also be used with angle_between_helices (even though this does not fit helices). Returns center and normal vector of plane. ''' try: import numpy except ImportError: print ' Error: numpy not available' raise CmdException state, visualize, quiet = int(state), int(visualize), int(quiet) coords = list() cmd.iterate_state(state, '(%s) and guide' % (selection), 'coords.append([x,y,z])', space=locals()) if len(coords) < 3: print 'not enough guide atoms in selection' raise CmdException x = numpy.array(coords) U,s,Vh = numpy.linalg.svd(x - x.mean(0)) # normal vector of plane is 3rd principle component vec = cpv.normalize(Vh[2]) if cpv.dot_product(vec, x[-1] - x[0]) < 0: vec = cpv.negate(vec) center = x.mean(0).tolist() _common_orientation(selection, center, vec, visualize, 4.0, quiet) # plane visualize if visualize: from pymol import cgo dir1 = cpv.normalize(Vh[0]) dir2 = cpv.normalize(Vh[1]) sx = [max(i/4.0, 2.0) for i in s] obj = [ cgo.BEGIN, cgo.TRIANGLES, cgo.COLOR, 0.5, 0.5, 0.5 ] for vertex in [ cpv.scale(dir1, sx[0]), cpv.scale(dir2, sx[1]), cpv.scale(dir2, -sx[1]), cpv.scale(dir1, -sx[0]), cpv.scale(dir2, -sx[1]), cpv.scale(dir2, sx[1]), ]: obj.append(cgo.VERTEX) obj.extend(cpv.add(center, vertex)) obj.append(cgo.END) cmd.load_cgo(obj, cmd.get_unused_name('planeFit')) return center, vec
def extra_fit(selection='(all)', reference=None, method='align', zoom=1, quiet=0, _self=cmd, **kwargs): ''' DESCRIPTION Like "intra_fit", but for multiple objects instead of multiple states. ARGUMENTS selection = string: atom selection of multiple objects {default: all} reference = string: reference object name {default: first object in selection} method = string: alignment method (command that takes "mobile" and "target" arguments, like "align", "super", "cealign" {default: align} ... extra arguments are passed to "method" SEE ALSO alignto, cmd.util.mass_align, align_all.py from Robert Campbell ''' zoom, quiet = int(zoom), int(quiet) sele_name = cmd.get_unused_name('_') cmd.select(sele_name, selection) # for speed models = cmd.get_object_list(sele_name) if reference is None: reference = models[0] models = models[1:] elif reference in models: models.remove(reference) else: cmd.select(sele_name, reference, merge=1) if cmd.is_string(method): if method in cmd.keyword: method = cmd.keyword[method][0] else: print('Unknown method:', method) raise CmdException for model in models: x = method(mobile='%s and model %s' % (sele_name, model), target='%s and model %s' % (sele_name, reference), **kwargs) if not quiet: if cmd.is_sequence(x): print('%-20s RMS = %8.3f (%d atoms)' % (model, x[0], x[1])) elif isinstance(x, float): print('%-20s RMS = %8.3f' % (model, x)) elif isinstance(x, dict) and 'RMSD' in x: natoms = x.get('alignment_length', 0) suffix = (' (%s atoms)' % natoms) if natoms else '' print('%-20s RMS = %8.3f' % (model, x['RMSD']) + suffix) else: print('%-20s' % (model,)) if zoom: cmd.zoom(sele_name) cmd.delete(sele_name)
def __init__(self, selection=None, name=None, symbols='', state=-1): try: from pymol.plugins import get_pmgapp pmgapp = get_pmgapp() except ImportError: pmgapp = None if pmgapp is not None: rootframe = Tkinter.Toplevel(pmgapp.root) parent = rootframe else: rootframe = Tkinter.Tk() parent = rootframe rootframe.title(' Dynamic Angle Plotting ') rootframe.protocol("WM_DELETE_WINDOW", self.close_callback) canvas = SimplePlot(parent, width=320, height=320) canvas.bind("<Button-2>", canvas.pickWhich) canvas.bind("<Button-3>", canvas.pickWhich) canvas.pack(side=Tkinter.LEFT, fill="both", expand=1) canvas.axis(xint=150, xlabels=[-180, -120, -60, 0, 60, 120, 180], ylabels=[ -180, -150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150, 180 ]) if symbols == 'ss': canvas.symbols = 1 if name is None: try: name = cmd.get_unused_name('DynoRama') except AttributeError: name = 'DynoRamaObject' self.rootframe = rootframe self.canvas = canvas self.name = name self.lock = 0 self.state = state if name != 'none': auto_zoom = cmd.get('auto_zoom') cmd.set('auto_zoom', 0) cmd.load_callback(self, name) cmd.set('auto_zoom', auto_zoom) canvas.bind("<ButtonPress-1>", canvas.down) canvas.bind("<ButtonRelease-1>", canvas.up) canvas.bind("<Motion>", canvas.drag) if selection is not None: self.start(selection) if with_mainloop and pmgapp is None: rootframe.mainloop()
def ellipsoid(sel='all'): model = cmd.get_model(sel + ' and name ca') obj = cmd.get_object_list()[0] coord = [] for at in model.atom: coord.append(at.coord) cm = get_cm(coord) abc, g, v = get_moi(coord, cm) # axis-length, eigenvalues, eigenvectors arrow_obj = [] color = 'red red' pos2 = [x + y * abc[0] for x, y in zip(cm, v[0])] arrow_obj += cgo_arrow(cm, pos2, color=color, radius=0.15) color = 'green green' pos2 = [x + y * abc[1] for x, y in zip(cm, v[1])] arrow_obj += cgo_arrow(cm, pos2, color=color, radius=0.15) color = 'blue blue' pos2 = [x + y * abc[2] for x, y in zip(cm, v[2])] arrow_obj += cgo_arrow(cm, pos2, color=color, radius=0.15) name = cmd.get_unused_name('axis') cmd.load_cgo(arrow_obj, name) cgo = makeEllipsoid(cm[0], cm[1], cm[2], abc[0], abc[1], abc[2], m=v) obj_ellipsoid = cmd.get_unused_name('ellipsoid') cmd.load_cgo(cgo, obj_ellipsoid) # Do some cosmetic work cmd.set('cgo_transparency', 0.4, obj_ellipsoid) cmd.color('green', obj_ellipsoid) cmd.show_as('cartoon', obj) cmd.color('orange', obj) cmd.zoom(obj, animate=1) print('The volume of the ellipsoid (4/3 Pi*a*b*c): %6.1f A' % \ (4.0/3.0*math.pi*abc[0]*abc[1]*abc[2])) print('The volume of the spheroid (4/3 Pi*r**3): %6.1f A' % \ (4.0/3.0*math.pi*((abc[0]**2+abc[1]**2+abc[2]**2))**1.5))
def symdiff(sele1, sele2, byres=1, name=None, operator='in', quiet=0): ''' DESCRIPTION Symmetric difference between two molecules SEE ALSO diff ''' byres, quiet = int(byres), int(quiet) if name is None: name = cmd.get_unused_name('symdiff') tmpname = cmd.get_unused_name('__tmp') diff(sele1, sele2, byres, name, operator, quiet) diff(sele2, sele1, byres, tmpname, operator, quiet) cmd.select(name, tmpname, merge=1) cmd.delete(tmpname) return name
def split(operator, selection, prefix='entity'): ''' DESCRIPTION Create a single object for each entity in selection, defined by operator (e.g. bymolecule, bysegment, ...). Returns the number of created objects. ''' cmd.disable(' '.join(cmd.get_object_list('(' + selection + ')'))) tmp = cmd.get_unused_name('_') cmd.create(tmp, selection) r = 0 while cmd.count_atoms(tmp) > 0: name = cmd.get_unused_name(prefix) cmd.extract(name, operator + ' first model ' + tmp) r += 1 cmd.delete(tmp) return r
def split(operator, selection, prefix="entity"): """ DESCRIPTION Create a single object for each entity in selection, defined by operator (e.g. bymolecule, bysegment, ...). Returns the number of created objects. """ cmd.disable(" ".join(cmd.get_object_list("(" + selection + ")"))) tmp = cmd.get_unused_name("_") cmd.create(tmp, selection) r = 0 while cmd.count_atoms(tmp) > 0: name = cmd.get_unused_name(prefix) cmd.extract(name, operator + " first model " + tmp) r += 1 cmd.delete(tmp) return r
def cubes(selection='all', name='', state=0, scale=0.5, atomcolors=1, _func=cgo_cube): ''' DESCRIPTION Create a cube representation CGO for all atoms in selection. ARGUMENTS selection = string: atom selection {default: all} name = string: name of CGO object to create state = int: object state {default: 0 = all states} scale = float: scaling factor. If scale=1.0, the corners of the cube will be on the VDW surface of the atom {default: 0.5} atomcolors = 0/1: use atom colors (cannot be changed), otherwise apply one color to the object (can be changed with color command) {default: 1} SEE ALSO tetrahedra ''' if not name: name = cmd.get_unused_name('cubes') state, scale, atomcolors = int(state), float(scale), int(atomcolors) if state < 0: state = cmd.get_setting_int('state') states = [state] if state else list( range(1, cmd.count_states(selection) + 1)) def callback(x, y, z, vdw, color): if atomcolors: obj.append(cgo.COLOR) obj.extend(cmd.get_color_tuple(color)) obj.extend(_func(x, y, z, vdw * scale)) space = {'xcb': callback} for state in states: obj = [] cmd.iterate_state(state, selection, 'xcb(x, y, z, vdw, color)', space=space) cmd.load_cgo(obj, name, state) if not atomcolors: cmd.color('auto', name)
def diff(sele1, sele2, byres=1, name=None, operator='in', quiet=0): ''' DESCRIPTION Difference between two molecules ARGUMENTS sele1 = string: atom selection sele2 = string: atom selection byres = 0/1: report residues, not atoms (does not affect selection) {default: 1} operator = in/like/align: operator to match atoms {default: in} SEE ALSO symdiff ''' byres, quiet = int(byres), int(quiet) if name is None: name = cmd.get_unused_name('diff') if operator == 'align': alnobj = cmd.get_unused_name('__aln') cmd.align(sele1, sele2, cycles=0, transform=0, object=alnobj) sele = '(%s) and not %s' % (sele1, alnobj) cmd.select(name, sele) cmd.delete(alnobj) else: sele = '(%s) and not ((%s) %s (%s))' % (sele1, sele1, operator, sele2) cmd.select(name, sele) if not quiet: if byres: seleiter = 'byca ' + name expr = 'print "/%s/%s/%s/%s`%s" % (model,segi,chain,resn,resi)' else: seleiter = name expr = 'print "/%s/%s/%s/%s`%s/%s" % (model,segi,chain,resn,resi,name)' cmd.iterate(seleiter, expr) return name
def load_apbs_in(form, filename, contents=''): import shlex from pymol import cmd, importing wdir = os.path.dirname(filename) if not contents: contents = cmd.file_read(filename) if not isinstance(contents, str): contents = contents.decode() sectionkeys = ('read', 'elec', 'apolar', 'print') section = '' insert_write_pot = True lines = [] for line in contents.splitlines(): a = shlex.split(line) key = a[0].lower() if a else '' if not section: if key in sectionkeys: section = key elif key == 'end': if section == 'elec' and insert_write_pot: lines.append('write pot dx "{mapfile}"') section = '' elif section == 'read': if len(a) > 2 and key in ('charge', 'kappa', 'mol', 'parm', 'pot'): filename = os.path.join(wdir, a[2]) if os.path.exists(filename): format = a[1].lower() if key == 'mol' and format in ('pqr', 'pdb'): # load into PyMOL and update selection dropdown oname = importing.filename_to_objectname(a[2]) oname = cmd.get_unused_name(oname, 0) cmd.load(filename, oname, format=format) form.input_sele.addItem(oname) form.input_sele.setEditText(oname) # absolute path in input file a[2] = '"' + filename + '"' line = ' '.join(a) elif section == 'elec': if key == 'write': if a[1:4] == ['pot', 'dx', "{mapfile}"]: insert_write_pot = False lines.append(line) return '\n'.join(lines)
def __init__(self, selection=None, name=None, symbols='', state=-1): try: from pymol.plugins import get_pmgapp pmgapp = get_pmgapp() except ImportError: pmgapp = None if pmgapp is not None: rootframe = Tkinter.Toplevel(pmgapp.root) parent = rootframe else: rootframe = Tkinter.Tk() parent = rootframe rootframe.title(' Dynamic Angle Plotting ') rootframe.protocol("WM_DELETE_WINDOW", self.close_callback) canvas = SimplePlot(parent, width=320, height=320) canvas.bind("<Button-2>", canvas.pickWhich) canvas.bind("<Button-3>", canvas.pickWhich) canvas.pack(side=Tkinter.LEFT, fill="both", expand=1) canvas.axis(xint=150, xlabels=[-180, -120, -60, 0, 60, 120, 180], ylabels=[-180, -150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150, 180]) if symbols == 'ss': canvas.symbols = 1 if name is None: try: name = cmd.get_unused_name('DynoRama') except AttributeError: name = 'DynoRamaObject' self.rootframe = rootframe self.canvas = canvas self.name = name self.lock = 0 self.state = state if name != 'none': auto_zoom = cmd.get('auto_zoom') cmd.set('auto_zoom', 0) cmd.load_callback(self, name) cmd.set('auto_zoom', auto_zoom) canvas.bind("<ButtonPress-1>", canvas.down) canvas.bind("<ButtonRelease-1>", canvas.up) canvas.bind("<Motion>", canvas.drag) if selection is not None: self.start(selection) if with_mainloop and pmgapp is None: rootframe.mainloop()
def draw_xy_axes(scale=1.0): """Draw x and y axes in PyMOL.""" logging.debug("Drawing axes.") obj = [] obj.extend( get_cgo_arrow_obj(start=np.array([0, 0, 0.]), stop=scale * np.array([0., 1., 0.]))) obj.extend( get_cgo_arrow_obj(start=np.array([0, 0, -.1]), stop=scale * np.array([0., 0., 1.]))) cmd.load_cgo(obj, cmd.get_unused_name('axes'))
def cgoCylinder3(p0=[0,0,0],v0=[1,0,0],inputAng=0, L=20, radius=0.5 ,color=[1,0,0] ,name=''): p0 = np.array(p0) V0 = np.array(v0) r = R.from_euler('z', inputAng, degrees=True) p1 = np.around(R.apply(r,V0), decimals=6)*L+p0 PP0 = list(p0) ; PP1=list(p1) obj = [cgo.CYLINDER] + PP0 + PP1 + [radius] + color + color if not name: name = cmd.get_unused_name('cylinderObj') cmd.load_cgo(obj, name) return name,obj, p1
def __init__(self, map_name, level, radius, name, sym_source): self.level = level self.radius = radius self.map_name = map_name self.name = name self.center_name = cmd.get_unused_name('_center') self.callback_name = cmd.get_unused_name('_cb') cmd.set("auto_zoom", 0) cmd.pseudoatom(self.center_name) cmd.hide("everything", self.center_name) symmetry = cmd.get_symmetry(sym_source or map_name) if symmetry: cmd.set("map_auto_expand_sym", 1) cmd.set_symmetry(self.center_name, *symmetry) cmd.set_key("pgup", self.contour_plus) cmd.set_key("pgdn", self.contour_minus) self.update()
def select_distances(names='', name='sele', state=1, selection='all', cutoff=-1, quiet=1): ''' DESCRIPTION Turns a distance object into a named atom selection. ARGUMENTS names = string: names of distance objects (no wildcards!) {default: all measurement objects} name = a unique name for the selection {default: sele} state = int: object state (-1: current, 0: all states) {default: 1} SEE ALSO get_raw_distances ''' from collections import defaultdict _assert_package_import() from .querying import get_raw_distances state, cutoff, quiet = int(state), float(cutoff), int(quiet) states = [state] if state else list( range(1, cmd.count_states(selection) + 1)) sele_dict = defaultdict(set) for state in states: distances = get_raw_distances(names, state, selection) for idx1, idx2, dist in distances: if cutoff <= 0.0 or dist <= cutoff: sele_dict[idx1[0]].add(idx1[1]) sele_dict[idx2[0]].add(idx2[1]) cmd.select(name, 'none') tmp_name = cmd.get_unused_name('_') r = 0 for model in sele_dict: cmd.select_list(tmp_name, model, list(sele_dict[model]), mode='index') r = cmd.select(name, tmp_name, merge=1) cmd.delete(tmp_name) if not quiet: print(' Selector: selection "%s" defined with %d atoms.' % (name, r)) return r
def align(self, mobile, target, match): ''' Align mobile to target using the alignment method given by "match" ''' aln_obj = cmd.get_unused_name('_') self.temporary.append(aln_obj) align = cmd.keyword[match][0] align(mobile, target, cycles=0, transform=0, object=aln_obj) cmd.disable(aln_obj) self.from_alignment(mobile, target, aln_obj)
def morpheasy_linear(source, target, source_state=0, target_state=0, name=None, steps=30, match='align', quiet=1): ''' DESCRIPTION Morph by linear interpolation in cartesian space (like LSQMAN). This is the poor man's version of morphing, it's quick but will produce distorted intermediate conformations. Does not require rigimol (incentive PyMOL product). Requires numpy. SEE ALSO morpheasy ''' from numpy import array from .fitting import matchmaker from .importing import load_coords from .querying import get_selection_state # arguments source_state = int(source_state) target_state = int(target_state) steps, quiet = int(steps), int(quiet) if source_state < 1: source_state = get_selection_state(source) if target_state < 1: target_state = get_selection_state(target) msource, mtarget, tmp_names = matchmaker(source, target, match) csource = array(cmd.get_model(msource, source_state).get_coord_list()) ctarget = array(cmd.get_model(mtarget, target_state).get_coord_list()) cdiff = ctarget - csource if name is None: name = cmd.get_unused_name('morph') cmd.create(name, msource, source_state, 1) for state in range(2, steps + 1): c = csource + cdiff * float(state - 1) / (steps - 1) load_coords(c.tolist(), name, state) # clean up for obj in tmp_names: cmd.delete(obj) return name
def count_molecules(selection="all"): """ By Thomas Holder. """ tmpsele = pm.get_unused_name("_tmp") count = 0 if pm.select(tmpsele, selection): count += 1 while pm.select(tmpsele, f"{tmpsele} &! bm. first {tmpsele}"): count += 1 pm.delete(tmpsele) return count
def set_raw_alignment(name, aln, transform=0, guide=''): ''' DESCRIPTION API only. Load an alignment object from a list like the one obtained with cmd.get_raw_alignment SEE ALSO cmd.set_raw_alignment in PyMOL 2.3 ''' if hasattr(cmd, 'set_raw_alignment') and not int(transform): return cmd.set_raw_alignment(name, aln, guide=guide) if not isinstance(aln[0], dict): aln = [dict(idx_pair) for idx_pair in aln] models = set(model for idx_pdict in aln for model in idx_pdict) sele1 = cmd.get_unused_name('_sele1') sele2 = cmd.get_unused_name('_sele2') fit = cmd.fit if transform else cmd.rms_cur if guide: models.remove(guide) model2 = guide else: model2 = models.pop() for model1 in models: index_list1 = [] index_list2 = [] for idx_pdict in aln: if model1 in idx_pdict and model2 in idx_pdict: index_list1.append(idx_pdict[model1]) index_list2.append(idx_pdict[model2]) cmd.select_list(sele1, model1, index_list1, mode='index') cmd.select_list(sele2, model2, index_list2, mode='index') fit(sele1, sele2, cycles=0, matchmaker=4, object=name) cmd.delete(sele1) cmd.delete(sele2)
def findSurfaceResidues(selection="all", cutoff=2.5, doShow=0, quiet=1, pdb_id="", oxygen=True): """ DESCRIPTION Finds those residues on the surface of a protein that have at least 'cutoff' exposed A**2 surface area. USAGE findSurfaceResidues [ selection, [ cutoff, [ doShow ]]] ARGUMENTS selection = string: object or selection in which to find exposed residues {default: all} cutoff = float: cutoff of what is exposed or not {default: 2.5 Ang**2} RETURNS (list: (chain, resv ) ) A Python list of residue numbers corresponding to those residues w/more exposure than the cutoff. """ cutoff, doShow, quiet = float(cutoff), int(doShow), int(quiet) selName = findSurfaceAtoms(selection, cutoff, quiet, oxygen) exposed = set() cmd.iterate(selName, "exposed.add((chain,resv))", space=locals()) selNameRes = cmd.get_unused_name("exposed_res_") cmd.select(selNameRes, "byres " + selName) if not quiet: print("Exposed residues are selected in: " + selNameRes) if doShow: cmd.show_as("spheres", "(" + selection + ") and polymer") cmd.color("white", selection) cmd.color("yellow", selNameRes) cmd.color("red", selName) print(sorted(exposed)) df = pd.DataFrame(list(sorted(exposed)), columns=['Chain', 'Residue']) write_df(df, pdb_id + "_surfaceresidues.csv", dir="./surface_residues") return sorted(exposed)
def tetrahedra(selection='all', name='', state=0, scale=0.5, atomcolors=1): ''' DESCRIPTION Create a tetrahedra representation CGO for all atoms in selection. SEE ALSO cubes ''' if not name: name = cmd.get_unused_name('tetrahedra') return cubes(selection, name, state, scale, atomcolors, cgo_tetrahedron)
def visualize_orientation(direction, center=[0.0]*3, scale=1.0, symmetric=False, color='green', color2='red'): ''' DESCRIPTION Draw an arrow. Helper function for "helix_orientation" etc. ''' from pymol import cgo color_list = cmd.get_color_tuple(color) color2_list = cmd.get_color_tuple(color2) if symmetric: scale *= 0.5 end = cpv.add(center, cpv.scale(direction, scale)) radius = 0.3 obj = [cgo.SAUSAGE] obj.extend(center) obj.extend(end) obj.extend([ radius, 0.8, 0.8, 0.8, ]) obj.extend(color_list) if symmetric: start = cpv.sub(center, cpv.scale(direction, scale)) obj.append(cgo.SAUSAGE) obj.extend(center) obj.extend(start) obj.extend([ radius, 0.8, 0.8, 0.8, ]) obj.extend(color2_list) coneend = cpv.add(end, cpv.scale(direction, 4.0*radius/cpv.length(direction))) obj.append(cgo.CONE) obj.extend(end) obj.extend(coneend) obj.extend([ radius * 1.75, 0.0, ]) obj.extend(color_list * 2) obj.extend([ 1.0, 1.0, # Caps ]) cmd.load_cgo(obj, get_unused_name('oriVec'), zoom=0)
def morpheasy_linear(source, target, source_state=0, target_state=0, name=None, steps=30, match='align', quiet=1): ''' DESCRIPTION Morph by linear interpolation in cartesian space (like LSQMAN). This is the poor man's version of morphing, it's quick but will produce distorted intermediate conformations. Does not require rigimol (incentive PyMOL product). Requires numpy. SEE ALSO morpheasy ''' from numpy import array from .fitting import matchmaker from .importing import load_coords from .querying import get_selection_state # arguments source_state = int(source_state) target_state = int(target_state) steps, quiet = int(steps), int(quiet) if source_state < 1: source_state = get_selection_state(source) if target_state < 1: target_state = get_selection_state(target) msource, mtarget, tmp_names = matchmaker(source, target, match) csource = array(cmd.get_model(msource, source_state).get_coord_list()) ctarget = array(cmd.get_model(mtarget, target_state).get_coord_list()) cdiff = ctarget - csource if name is None: name = cmd.get_unused_name('morph') cmd.create(name, msource, source_state, 1) for state in range(2, steps+1): c = csource + cdiff * float(state-1) / (steps-1) load_coords(c.tolist(), name, state) # clean up for obj in tmp_names: cmd.delete(obj) return name
def cubes(selection='all', name='', state=0, scale=0.5, atomcolors=1, _func=cgo_cube): ''' DESCRIPTION Create a cube representation CGO for all atoms in selection. ARGUMENTS selection = string: atom selection {default: all} name = string: name of CGO object to create state = int: object state {default: 0 = all states} scale = float: scaling factor. If scale=1.0, the corners of the cube will be on the VDW surface of the atom {default: 0.5} atomcolors = 0/1: use atom colors (cannot be changed), otherwise apply one color to the object (can be changed with color command) {default: 1} SEE ALSO tetrahedra ''' if not name: name = cmd.get_unused_name('cubes') state, scale, atomcolors = int(state), float(scale), int(atomcolors) if state < 0: state = cmd.get_setting_int('state') states = [state] if state else range(1, cmd.count_states(selection) + 1) def callback(x, y, z, vdw, color): if atomcolors: obj.append(cgo.COLOR) obj.extend(cmd.get_color_tuple(color)) obj.extend(_func(x, y, z, vdw * scale)) space = {'xcb': callback} for state in states: obj = [] cmd.iterate_state(state, selection, 'xcb(x, y, z, vdw, color)', space=space) cmd.load_cgo(obj, name, state) if not atomcolors: cmd.color('auto', name)
def findSurfaceResidues(selection="all", cutoff=2.5, doShow=0, quiet=1): """ DESCRIPTION Finds those residues on the surface of a protein that have at least 'cutoff' exposed A**2 surface area. USAGE findSurfaceResidues [ selection, [ cutoff, [ doShow ]]] ARGUMENTS selection = string: object or selection in which to find exposed residues {default: all} cutoff = float: cutoff of what is exposed or not {default: 2.5 Ang**2} RETURNS (list: (chain, resv ) ) A Python list of residue numbers corresponding to those residues w/more exposure than the cutoff. """ cutoff, doShow, quiet = float(cutoff), int(doShow), int(quiet) selName = findSurfaceAtoms(selection, cutoff, quiet) exposed = set() cmd.iterate(selName, "exposed.add((chain,resv))", space=locals()) selNameRes = cmd.get_unused_name("exposed_res_") cmd.select(selNameRes, "byres " + selName) if not quiet: print("Exposed residues are selected in: " + selNameRes) if doShow: cmd.show_as("spheres", "(" + selection + ") and polymer") cmd.color("white", selection) cmd.color("yellow", selNameRes) cmd.color("red", selName) return sorted(exposed)
def select_distances(names='', name='sele', state=1, selection='all', cutoff=-1, quiet=1): ''' DESCRIPTION Turns a distance object into a named atom selection. ARGUMENTS names = string: names of distance objects (no wildcards!) {default: all measurement objects} name = a unique name for the selection {default: sele} state = int: object state (-1: current, 0: all states) {default: 1} SEE ALSO get_raw_distances ''' from collections import defaultdict from .querying import get_raw_distances state, cutoff, quiet = int(state), float(cutoff), int(quiet) states = [state] if state else list(range(1, cmd.count_states(selection)+1)) sele_dict = defaultdict(set) for state in states: distances = get_raw_distances(names, state, selection) for idx1, idx2, dist in distances: if cutoff <= 0.0 or dist <= cutoff: sele_dict[idx1[0]].add(idx1[1]) sele_dict[idx2[0]].add(idx2[1]) cmd.select(name, 'none') tmp_name = cmd.get_unused_name('_') r = 0 for model in sele_dict: cmd.select_list(tmp_name, model, list(sele_dict[model]), mode='index') r = cmd.select(name, tmp_name, merge=1) cmd.delete(tmp_name) if not quiet: print(' Selector: selection "%s" defined with %d atoms.' % (name, r)) return r
def sketch_pseudo_coc(selection, state=None, name=None, prefix='', suffix='_coc', **kwargs): """Create a pseudo atom which indicate the center of coordinate of the selection USAGE sketch_pseudo_coc selection, state=state, name=name, prefix=prefix, suffix=suffix ARGUMENTS selection a selection-expression state a state-index if positive number or 0 to all, -1 to current name a name of the pseudoatom, it will automatically specified if None is specified (Default) prefix a prefix of the pseudoatom. it will used only when name is not specified suffix a suffix of the pseudoatom. it will used only when name is not specified EXAMPLE sketch_pcoc (resn PHE), state=10 """ if name is None: try: name = cmd.get_legal_name(selection) name = cmd.get_unused_name( '{}{}{}'.format(prefix, name, suffix), 0 ) except: name = '%s%s' % (prefix, suffix) if state is not None: com = geometry.find_center_of_coordinates(selection) cmd.pseudoatom(name, pos=com, **kwargs) else: for state in range(1, cmd.count_states()+1): com = geometry.find_center_of_coordinates(selection, state=state) cmd.pseudoatom(name, pos=com, state=state, **kwargs)
def join_states(name, selection="all", discrete=-1, zoom=0, quiet=1): """ DESCRIPTION The reverse of split_states ARGUMENTS name = string: name of object to create or modify selection = string: atoms to include in the new object discrete = -2: match atoms by sequence alignment discrete = -1: Assume identical input objects (matching all atom identifiers) but also check for missing atoms and only include atoms that are present in all input objects {default} discrete = 0: Assume identical input objects discrete = 1: Input object may be (totally) different """ discrete, quiet = int(discrete), int(quiet) if discrete == -2: from .selecting import wait_for aln_obj = cmd.get_unused_name("_") models = cmd.get_object_list("(" + selection + ")") for i in range(len(models)): if discrete == -1 and i > 0: cmd.remove("(%s) and not (alt A+ and (%s) in (%s))" % (name, name, models[i])) cmd.create(name, "(%s) in (%s)" % (models[i], name), 1, i + 1, 0, 0, quiet) elif discrete == -2 and i > 0: cmd.align(models[i], name, cycles=0, transform=0, object=aln_obj) wait_for(aln_obj) cmd.remove("(%s) and not (%s)" % (name, aln_obj)) cmd.create(name, name, 1, i + 1, 0, 0, quiet) cmd.update(name, "(%s) and (%s)" % (models[i], aln_obj), i + 1, 1, 0, quiet) cmd.delete(aln_obj) else: cmd.create(name, models[i], 1, i + 1, discrete == 1, 0, quiet) if int(zoom): cmd.zoom(name, state=0)
def get_sasa(selection, state=-1, dot_density=5, quiet=1): ''' DESCRIPTION Get solvent accesible surface area SEE ALSO get_area pymol.util.get_sasa (considered broken!) ''' state, dot_density, quiet = int(state), int(dot_density), int(quiet) if state < 1: state = cmd.get_state() n = cmd.get_unused_name('_') cmd.create(n, selection, state, 1, zoom=0, quiet=1) cmd.set('dot_solvent', 1, n) if dot_density > -1: cmd.set('dot_density', dot_density, n) r = cmd.get_area(n, quiet=int(quiet)) cmd.delete(n) return r