def testRepsExist(self): cmd.viewport(200, 150) cmd.load(self.datafile('1oky-frag.pdb'), 'm1') # make some nonbonded cmd.unbond('resi 115-', 'resi 115-') # labels cmd.label('all', 'name') # measurements cmd.distance('measure1', 'index 1', 'index 10') cmd.angle('measure1', 'index 1', 'index 10', 'index 20') cmd.dihedral('measure1', 'index 1', 'index 10', 'index 20', 'index 30') # color test setup cmd.color('white', '*') cmd.set('ambient', 1) cmd.set('depth_cue', 0) cmd.set('antialias', 0) cmd.set('line_smooth', 0) cmd.orient() # test most reps for rep in REPS: cmd.show_as(rep) self.assertImageHasColor('white', msg='rep missing: ' + rep) # test cartoon cmd.show_as('cartoon') for cart in CARTOONS: cmd.cartoon(cart) self.assertImageHasColor('white', msg='cartoon missing: ' + cart)
def draw_axis(chA, chB, scale_factor=20, w=0.6, r1=1, g1=1, b1=1, r2=1, g2=0, b2=0): T = transf_matrix(chA, chB) angle=angle_axis(chA, chB) angle_degrees=(angle*180)/math.pi axis1=[direction_cosines(chA, chB)[0], direction_cosines(chA, chB)[1], direction_cosines(chA, chB)[2]] p = nearest_point_to_axis(chA, chB) x1, y1, z1 = p[0] + (3*scale_factor*axis1[0]), p[1] + (3*scale_factor*axis1[1]), p[2] + (3*scale_factor*axis1[2]) x2, y2, z2 = p[0] - (3*scale_factor*axis1[0]), p[1] - (3*scale_factor*axis1[1]), p[2] - (3*scale_factor*axis1[2]) obj = [cgo.CYLINDER, x1, y1, z1, x2, y2, z2, w, r1, g1, b1, r2, g2, b2, 0.0] cmd.load_cgo(obj, angle_degrees) cmA=center_of_Mass(chA) cmB=cmW cmAver=(cmB+cmA)/2 vector=numpy.array([(cmB[0]-cmA[0]), (cmB[1]-cmA[1]), (cmB[2]-cmA[2])]) moduli_vector=numpy.linalg.norm(vector) vector_director=numpy.array([(cmB[0]-cmA[0])/moduli_vector, (cmB[1]-cmA[1])/moduli_vector, (cmB[2]-cmA[2])/moduli_vector]) pC_A = proyeccion_centroide(chA, chA, chB) pC_B = proyeccion_centroide_working(chA, chB) trans_vector = numpy.array([(pC_B[0]-pC_A[0]), (pC_B[1]-pC_A[1]), (pC_B[2]-pC_A[2])]) modu_tr = numpy.linalg.norm(trans_vector) rota_centroid_rad=numpy.dot(vector_director, axis1) rota_centroid = (rota_centroid_rad*180)/math.pi rota_centroid_absol_0= numpy.absolute(rota_centroid) rota_centroid_absol=round(rota_centroid_absol_0,2) if rota_centroid_absol == 0.00: p1 = '_1' p2 = '_2' p3 = '_3' cmd.pseudoatom (pos=[cmA[0], cmA[1], cmA[2]], object=p1) cmd.pseudoatom (pos=[pC_A[0], pC_A[1], pC_A[2]], object=p2) cmd.pseudoatom (pos=[cmB[0], cmB[1], cmB[2]], object=p3) cmd.angle(None, p1, p2, p3) print_information(T, axis1, angle_degrees, moduli_vector, obj, x1, y1, z1, x2, y2, z2, w, r1, g1, b1, r2, g2, b2) if rota_centroid_absol != 0: p1 = '_1' p2 = '_2' p3 = '_3' p4 = '_4' cmd.pseudoatom (pos=[cmA[0], cmA[1], cmA[2]], object=p1) cmd.pseudoatom (pos=[pC_A[0], pC_A[1], pC_A[2]], object=p2) cmd.pseudoatom (pos=[pC_B[0], pC_B[1], pC_B[2]], object=p3) cmd.pseudoatom (pos=[cmB[0], cmB[1], cmB[2]], object=p4) cmd.dihedral(None, p1, p2, p3, p4) cmd.distance(None, p2, p3) print_information(T, axis1, angle_degrees, moduli_vector, obj, x1, y1, z1, x2, y2, z2, w, r1, g1, b1, r2, g2, b2, modu_tr) cmd.create('working', chA) cmd.super('working', chB)
def testAngleColor(self): cmd.fragment('ala') cmd.color('blue') cmd.angle('ang01', 'index 8', 'index 5', 'index 2') cmd.hide('label') cmd.set('fog', '0') cmd.set('ambient', '1') cmd.set('angle_color', 'red') cmd.set('dash_gap', '0') cmd.zoom() #need to check to make sure screen image has red in it img_array = self.get_imagearray(width=100, height=100, ray=0) self.assertImageHasColor('red', img_array, delta=[10,0,0])
def doFinish(self): r_aA = cmd.get_distance(atom1="pw2", atom2="pw3", state=0) cmd.distance(self.params_str[0], "pw2", "pw3") th_a = cmd.get_angle(atom1="pw1", atom2="pw2", atom3="pw3", state=0) cmd.angle(self.params_str[1], "pw1", "pw2", "pw3") th_A = cmd.get_angle(atom1="pw2", atom2="pw3", atom3="pw4", state=0) cmd.angle(self.params_str[2], "pw2", "pw3", "pw4") if not (r_aA and th_a and th_A): showerror(self.parent, "Error!", "Maybe you made a mistake when choosing atoms!") self.reset() phi_ba = cmd.get_dihedral(atom1="pw0", atom2="pw1", atom3="pw2", atom4="pw3", state=0) cmd.dihedral(self.params_str[3], "pw0", "pw1", "pw2", "pw3") phi_aA = cmd.get_dihedral(atom1="pw1", atom2="pw2", atom3="pw3", atom4="pw4", state=0) cmd.dihedral(self.params_str[4], "pw1", "pw2", "pw3", "pw4") phi_AB = cmd.get_dihedral(atom1="pw2", atom2="pw3", atom3="pw4", atom4="pw5", state=0) cmd.dihedral(self.params_str[5], "pw2", "pw3", "pw4", "pw5") index_c = cmd.id_atom("pw0") index_c_name = getAtomString('pw0') index_b = cmd.id_atom("pw1") index_b_name = getAtomString('pw1') index_a = cmd.id_atom("pw2") index_a_name = getAtomString('pw2') index_A = cmd.id_atom("pw3") index_A_name = getAtomString('pw3') index_B = cmd.id_atom("pw4") index_B_name = getAtomString('pw4') index_C = cmd.id_atom("pw5") index_C_name = getAtomString('pw5') self.setBondForceParam(r_aA, th_a, th_A, phi_ba, phi_aA, phi_AB, index_c, index_b, index_a, index_A, index_B, index_C) self.setAtomsDef(index_c_name, index_b_name, index_a_name, index_A_name, index_B_name, index_C_name) top = Toplevel( self.parent) # <- freeze when open gro file in pymol 1.X Output(top, self.bondForceParams, self.atoms_def) cmd.set_wizard()
def testMeasureBetweenStates(self): cmd.load(self.datafile('1v5a-3models.cif'), 'm1') # distance d = cmd.distance('d1', '24/CZ', 'same', state1=2, state2=3) self.assertAlmostEqual(d, 3.0, delta=1e-1) # angle a = cmd.angle('a1', '24/CZ', 'same', 'same', state1=2, state2=3, state3=1) self.assertAlmostEqual(a, 73.5, delta=1e-1) # visual test cmd.viewport(100, 100) cmd.set('dash_radius', 1.0) self.ambientOnly() for name in ['d1', 'a1']: cmd.disable('*') cmd.enable(name) cmd.zoom(name) self.assertImageHasColor('yellow')
def angle_between_helices(selection1, selection2, method='helix', state1=STATE, state2=STATE, visualize=1, quiet=1): ''' DESCRIPTION Calculates the angle between two helices USAGE angle_between_helices selection1, selection2 [, method [, visualize]] ARGUMENTS selection1 = string: atom selection of first helix selection2 = string: atom selection of second helix method = string: function to calculate orientation {default: helix_orientation} visualize = 0 or 1: show fitted vector as arrow {default: 1} EXAMPLE fetch 2x19, async=0 select hel1, /2x19//B/23-36/ select hel2, /2x19//B/40-54/ angle_between_helices hel1, hel2 angle_between_helices hel1, hel2, cafit SEE ALSO helix_orientation, loop_orientation, cafit_orientation, angle_between_domains ''' import math state1, state2 = int(state1), int(state2) visualize, quiet = int(visualize), int(quiet) try: orientation = globals()[methods_sc[str(method)]] except KeyError: print 'no such method:', method raise CmdException if not int(quiet): print ' Using method:', orientation.__name__ cen1, dir1 = orientation(selection1, state1, visualize, quiet=1) cen2, dir2 = orientation(selection2, state2, visualize, quiet=1) angle = cpv.get_angle(dir1, dir2) angle = math.degrees(angle) if not quiet: print ' Angle: %.2f deg' % (angle) if visualize: # measurement object for angle center = cpv.scale(cpv.add(cen1, cen2), 0.5) tmp = get_unused_name('_') for pos in [center, cpv.add(center, cpv.scale(dir1, 5.0)), cpv.add(center, cpv.scale(dir2, 5.0))]: cmd.pseudoatom(tmp, pos=list(pos), state=1) name = get_unused_name('angle') cmd.angle(name, *[(tmp, i) for i in [2,1,3]]) cmd.delete(tmp) cmd.zoom('(%s) or (%s)' % (selection1, selection2), 2, state1 if state1 == state2 else 0) return angle
def draw_axis(chA, chB, scale_factor=20, w=0.6, r1=1, g1=1, b1=1, r2=1, g2=0, b2=0): T = transf_matrix(chA, chB) angle = angle_axis(chA, chB) angle_degrees = (angle * 180) / math.pi axis1 = [ direction_cosines(chA, chB)[0], direction_cosines(chA, chB)[1], direction_cosines(chA, chB)[2] ] p = nearest_point_to_axis(chA, chB) x1, y1, z1 = p[0] + (3 * scale_factor * axis1[0]), p[1] + ( 3 * scale_factor * axis1[1]), p[2] + (3 * scale_factor * axis1[2]) x2, y2, z2 = p[0] - (3 * scale_factor * axis1[0]), p[1] - ( 3 * scale_factor * axis1[1]), p[2] - (3 * scale_factor * axis1[2]) obj = [ cgo.CYLINDER, x1, y1, z1, x2, y2, z2, w, r1, g1, b1, r2, g2, b2, 0.0 ] cmd.load_cgo(obj, angle_degrees) cmA = center_of_Mass(chA) cmB = cmW cmAver = (cmB + cmA) / 2 vector = numpy.array([(cmB[0] - cmA[0]), (cmB[1] - cmA[1]), (cmB[2] - cmA[2])]) moduli_vector = numpy.linalg.norm(vector) vector_director = numpy.array([(cmB[0] - cmA[0]) / moduli_vector, (cmB[1] - cmA[1]) / moduli_vector, (cmB[2] - cmA[2]) / moduli_vector]) pC_A = proyeccion_centroide(chA, chA, chB) pC_B = proyeccion_centroide_working(chA, chB) trans_vector = numpy.array([(pC_B[0] - pC_A[0]), (pC_B[1] - pC_A[1]), (pC_B[2] - pC_A[2])]) modu_tr = numpy.linalg.norm(trans_vector) rota_centroid_rad = numpy.dot(vector_director, axis1) rota_centroid = (rota_centroid_rad * 180) / math.pi rota_centroid_absol_0 = numpy.absolute(rota_centroid) rota_centroid_absol = round(rota_centroid_absol_0, 2) if rota_centroid_absol == 0.00: p1 = '_1' p2 = '_2' p3 = '_3' cmd.pseudoatom(pos=[cmA[0], cmA[1], cmA[2]], object=p1) cmd.pseudoatom(pos=[pC_A[0], pC_A[1], pC_A[2]], object=p2) cmd.pseudoatom(pos=[cmB[0], cmB[1], cmB[2]], object=p3) cmd.angle(None, p1, p2, p3) print_information(T, axis1, angle_degrees, moduli_vector, obj, x1, y1, z1, x2, y2, z2, w, r1, g1, b1, r2, g2, b2) if rota_centroid_absol != 0: p1 = '_1' p2 = '_2' p3 = '_3' p4 = '_4' cmd.pseudoatom(pos=[cmA[0], cmA[1], cmA[2]], object=p1) cmd.pseudoatom(pos=[pC_A[0], pC_A[1], pC_A[2]], object=p2) cmd.pseudoatom(pos=[pC_B[0], pC_B[1], pC_B[2]], object=p3) cmd.pseudoatom(pos=[cmB[0], cmB[1], cmB[2]], object=p4) cmd.dihedral(None, p1, p2, p3, p4) cmd.distance(None, p2, p3) print_information(T, axis1, angle_degrees, moduli_vector, obj, x1, y1, z1, x2, y2, z2, w, r1, g1, b1, r2, g2, b2, modu_tr) cmd.create('working', chA) cmd.super('working', chB)
def angle_between_domains(selection1, selection2, method='align', state1=STATE, state2=STATE, visualize=1, quiet=1): ''' DESCRIPTION Angle by which a molecular selection would be rotated when superposing on a selection2. Do not use for measuring angle between helices, since the alignment of the helices might involve a rotation around the helix axis, which will result in a larger angle compared to the angle between helix axes. USAGE angle_between_domains selection1, selection2 [, method ] ARGUMENTS selection1 = string: atom selection of first helix selection2 = string: atom selection of second helix method = string: alignment command like "align" or "super" {default: align} EXAMPLE fetch 3iplA 3iplB, bsync=0 select domain1, resi 1-391 select domain2, resi 392-475 align 3iplA and domain1, 3iplB and domain1 angle_between_domains 3iplA and domain2, 3iplB and domain2 SEE ALSO align, super, angle_between_helices ''' import math try: import numpy except ImportError: print(' Error: numpy not available') raise CmdException state1, state2 = int(state1), int(state2) visualize, quiet = int(visualize), int(quiet) if cmd.is_string(method): try: method = cmd.keyword[method][0] except KeyError: print('no such method:', method) raise CmdException mobile_tmp = get_unused_name('_') cmd.create(mobile_tmp, selection1, state1, 1, zoom=0) try: method(mobile=mobile_tmp, target=selection2, mobile_state=1, target_state=state2, quiet=quiet) mat = cmd.get_object_matrix(mobile_tmp) except: print(' Error: superposition with method "%s" failed' % (method.__name__)) raise CmdException finally: cmd.delete(mobile_tmp) try: # Based on transformations.rotation_from_matrix # Copyright (c) 2006-2012, Christoph Gohlke R33 = [mat[i:i + 3] for i in [0, 4, 8]] R33 = numpy.array(R33, float) # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 w, W = numpy.linalg.eig(R33.T) i = w.real.argmax() direction = W[:, i].real # rotation angle depending on direction m = direction.argmax() i, j, k, l = [[2, 1, 1, 2], [0, 2, 0, 2], [1, 0, 0, 1]][m] cosa = (R33.trace() - 1.0) / 2.0 sina = (R33[i, j] + (cosa - 1.0) * direction[k] * direction[l]) / direction[m] angle = math.atan2(sina, cosa) angle = abs(math.degrees(angle)) except: print(' Error: rotation from matrix failed') raise CmdException if not quiet: try: # make this import optional to support running this script standalone from .querying import centerofmass, gyradius except (ValueError, ImportError): gyradius = None try: # PyMOL 1.7.1.6+ centerofmass = cmd.centerofmass except AttributeError: centerofmass = lambda s: cpv.scale(cpv.add(*cmd.get_extent(s)), 0.5) center1 = centerofmass(selection1) center2 = centerofmass(selection2) print(' Angle: %.2f deg, Displacement: %.2f angstrom' % (angle, cpv.distance(center1, center2))) if visualize: center1 = numpy.array(center1, float) center2 = numpy.array(center2, float) center = (center1 + center2) / 2.0 if gyradius is not None: rg = numpy.array(gyradius(selection1), float) else: rg = 10.0 h1 = numpy.cross(center2 - center1, direction) h2 = numpy.dot(R33, h1) h1 *= rg / cpv.length(h1) h2 *= rg / cpv.length(h2) for pos in [center1, center2, center1 + h1, center1 + h2]: cmd.pseudoatom(mobile_tmp, pos=list(pos), state=1) # measurement object for angle and displacement name = get_unused_name('measurement') cmd.distance(name, *['%s`%d' % (mobile_tmp, i) for i in [1, 2]]) cmd.angle(name, *['%s`%d' % (mobile_tmp, i) for i in [3, 1, 4]]) # CGO arrow for axis of rotation visualize_orientation(direction, center1, rg, color='blue') cmd.delete(mobile_tmp) return angle
def angle_between_helices(selection1, selection2, method='helix', state1=STATE, state2=STATE, visualize=1, quiet=1): ''' DESCRIPTION Calculates the angle between two helices USAGE angle_between_helices selection1, selection2 [, method [, visualize]] ARGUMENTS selection1 = string: atom selection of first helix selection2 = string: atom selection of second helix method = string: function to calculate orientation {default: helix_orientation} visualize = 0 or 1: show fitted vector as arrow {default: 1} EXAMPLE fetch 2x19, bsync=0 select hel1, /2x19//B/23-36/ select hel2, /2x19//B/40-54/ angle_between_helices hel1, hel2 angle_between_helices hel1, hel2, cafit SEE ALSO helix_orientation, loop_orientation, cafit_orientation, angle_between_domains ''' import math state1, state2 = int(state1), int(state2) visualize, quiet = int(visualize), int(quiet) try: orientation = globals()[methods_sc[str(method)]] except KeyError: print('no such method:', method) raise CmdException if not int(quiet): print(' Using method:', orientation.__name__) cen1, dir1 = orientation(selection1, state1, visualize, quiet=1) cen2, dir2 = orientation(selection2, state2, visualize, quiet=1) angle = cpv.get_angle(dir1, dir2) angle = math.degrees(angle) if not quiet: print(' Angle: %.2f deg' % (angle)) if visualize: # measurement object for angle center = cpv.scale(cpv.add(cen1, cen2), 0.5) tmp = get_unused_name('_') for pos in [ center, cpv.add(center, cpv.scale(dir1, 5.0)), cpv.add(center, cpv.scale(dir2, 5.0)) ]: cmd.pseudoatom(tmp, pos=list(pos), state=1) name = get_unused_name('angle') cmd.angle(name, *[(tmp, i) for i in [2, 1, 3]]) cmd.delete(tmp) cmd.zoom('(%s) or (%s)' % (selection1, selection2), 2, state1 if state1 == state2 else 0) return angle
cmd.select("current_surroundings", "current_surroundings and bindingsite") cmd.select("current_polar", "current_surroundings and polar_atoms") polar_distance = cmd.dist("polar_contacts", "ligand", "polar_atoms", mode=2) print("Polar contact: ") print polar_distance, halo.name, halo.resn, halo.resi model_polar = cmd.get_model("current_polar") for pol in model_polar.atom: cmd.select("current_polar", "id %s" % (pol.id)) # check for halogen bonds, distances 5.0, angles: > 140 current_distance = cmd.distance("current_distance", "current_halogen", "current_polar") current_angle = cmd.angle("current_angle", "current_neighbor", "current_halogen", "current_polar") if (current_angle >= 140) and (current_distance <= 5.0): print("Halogen bond: ") print current_distance, current_angle, pol.name, pol.resn, pol.resi cmd.delete("current_angle") cmd.delete("current_distance") # visualizations cmd.hide("lines") cmd.hide( "nonbonded") # hide all nonbonded atoms, i.e. oxygen of water or ions cmd.show("sticks", "ligand") cmd.show("lines", "bindingsite") cmd.show("nb_spheres", "water_bs") # nb_spheres = non bonded spheres
def create_selections(options): # Hide everything cmd.hide("lines") cmd.hide("nonbonded") # Protein structure cmd.select("protein_structure", "all") if options.has_key('no_ligand_selected'): # Super basic option, call ligand and chain from organic print("Attempting to automatically find ligand") ligand_candidates_number = cmd.select("ligand_candidate", "organic") candidate_resn = "" candidate_chain = "" if ligand_candidates_number: ligand_candidates_model = cmd.get_model("ligand_candidate") for cand_atom in ligand_candidates_model.atom: candidate_resn, candidate_chain = cand_atom.resn, cand_atom.chain break if candidate_resn and candidate_chain: print("Automatically detected ligand is '%s' in chain '%s'" % (candidate_resn, candidate_chain)) options['ligand_name'] = candidate_resn options['chain_name'] = candidate_chain else: raise argparse.ArgumentError( "Could not automatically detect ligand. Please make sure a ligand is contained in the provided pdb-file or use the 'Basic Mode'." ) # Ligand cmd.select( "sele_all_ligands", "organic and chain %s and resn %s" % (options['chain_name'], options["ligand_name"])) number_of_ligands_selected = cmd.select( "sele_ligand", 'organic and chain %s and resn %s and alt a+""' % (options['chain_name'], options["ligand_name"])) # remove all duplicate conformations cmd.remove("sele_all_ligands and not sele_ligand") cmd.delete("sele_all_ligands") #Feature: If we did not get a correct chain name from the user, we will try to guess through the whole alphabet to find it # otherwise the ligand will not appear in the visualization if not number_of_ligands_selected: #list holding all ascii-letters for letter in ascii_uppercase: number_of_ligands_selected = cmd.select( "sele_ligand", 'organic and chain %s and resn %s and alt a+""' % (letter, options["ligand_name"])) if number_of_ligands_selected: options['chain_name'] = letter break cmd.create("ligand", "sele_ligand") cmd.delete("sele_ligand") cmd.show("sticks", "ligand") cmd.color(options["colors"]['color_carbon'], "ligand and e. C") cmd.color(options["colors"]['oxygen'], "ligand and e. O") cmd.color(options["colors"]['nitrogen'], "ligand and e. N") # Cofactor if options["cofactor_in_binding_site"]: cmd.select( "sele_cofactor", "resn %s and chain %s" % (options['cofactor_name'], options['chain_name'])) cmd.create("cofactor", "sele_cofactor") cmd.show("sticks", "cofactor") cmd.color(options['colors']['color_cofactor'], "cofactor and e. C") cmd.delete("sele_cofactor") # Surface cmd.create("protein_surface", "all") cmd.hide("lines", "protein_surface") cmd.hide("sticks", "protein_surface") cmd.hide("nonbonded", "protein_surface") cmd.show("surface", "protein_surface") cmd.color(options["colors"]['protein_surface'], "protein_surface") # Cartoon cmd.copy("protein_cartoon", "protein_surface") cmd.hide("surface", "protein_cartoon") cmd.show("cartoon", "protein_cartoon") cmd.color(options["colors"]['protein_cartoon'], "protein_cartoon") # Transparent Cartoon cmd.copy("protein_cartoon_transparent", "protein_cartoon") cmd.set("cartoon_transparency", options['cartoon_transparency'], "protein_cartoon_transparent") # 2nd Transparent Cartoon cmd.copy("protein_cartoon_transparent_more", "protein_cartoon") cmd.set("cartoon_transparency", 0.9, "protein_cartoon_transparent_more") # Binding Site cmd.select("sele_binding_site", "ligand expand %s" % (options['binding_site_radius'])) cmd.select("sele_binding_site", "br. sele_binding_site") cmd.select("sele_binding_site", "sele_binding_site and protein_structure") cmd.select("sele_binding_site", "sele_binding_site and not ligand") cmd.create("binding_site", "sele_binding_site") cmd.delete("sele_binding_site") cmd.delete("protein_structure") cmd.hide("surface", "binding_site") cmd.hide("nonbonded") cmd.show("sticks", "binding_site") cmd.show("nb_spheres", "binding_site and not resn HOH") cmd.color(options["colors"]['binding_site'], "binding_site and e. C") cmd.color(options["colors"]['nitrogen'], "binding_site and e. N") cmd.color(options["colors"]['oxygen'], "binding_site and e. O") # get polar interacting residues in binding site without water cmd.select("sele_no_water_binding_site", "binding_site and not resn hoh") cmd.select( "sele_no_water_binding_site", "sele_no_water_binding_site and not resn %s" % options['ligand_name']) pairs = polarpairs("sele_no_water_binding_site", "ligand", cutoff=options['binding_site_radius'], name="polar_int_d") if pairs: cmd.hide("labels", "polar_int_d") cmd.color(options['colors']["interaction_polar"], "polar_int_d") else: print("No polar interaction pairs found") options["no_polar_interactions_found"] = True cmd.delete("sele_no_water_binding_site") interacting_tuples = polartuples(pairs, selection_name="polar_interaction") #create a list with selection names of polar_interacting residues polar_selection_names = [ "resi %s and resn %s and chain %s" % tup for tup in interacting_tuples ] # write the residues into a custom text file, with open("%s" % (POLAR_INTERACTIONS_FILENAME, ), "w") as f: f.write("#POLAR INTERACTION PARTNERS WITH %s\n" % (options['ligand_name'], )) f.write("RESI\tRESN\tCHAIN\n") for tup in interacting_tuples: f.write("%s\t%s\t%s\n" % tup) #select all polar interacting residues at once for an overview # cmd.select("polar_interacting_residues", "") for i, selection_name in enumerate(polar_selection_names): if i: # if i>0 and we already have sele_polar_interacting_residues cmd.select( "sele_polar_interacting_residues", "sele_polar_interacting_residues or %s" % selection_name) print( "select sele_polar_interacting_residues, sele_polar_interacting_residues or %s" % selection_name) else: cmd.select("sele_polar_interacting_residues", selection_name) print("select sele_polar_interacting_residues, %s" % selection_name) if not options.has_key("no_polar_interactions_found"): cmd.create("polar_interacting_residues", "sele_polar_interacting_residues") cmd.delete("sele_polar_interacting_residues") cmd.show("sticks", "polar_interacting_residues") cmd.color("grey50", "polar_interacting_residues and e. C") cmd.color(options["colors"]['nitrogen'], "polar_interacting_residues and e. N") cmd.color(options["colors"]['oxygen'], "polar_interacting_residues and e. O") # create selection for HOH molecules in binding pocket and make nb_spheres if options['water_in_binding_site']: cmd.select("sele_water_binding_site", "binding_site and resn hoh") water_pairs = polarpairs("sele_water_binding_site", "ligand", cutoff=options['binding_site_radius']) # further filter polar interactions, discard water molecules that don't interact with binding site and ligand # water molecules in interacting tuples are already forming a hbond to ligand water_list = [] water_distance_list = [] water_polar_tuples_list = [] if water_pairs: # print("water_bridge_candidates ", water_bridge_candidates) print("water_bridge_candidates ", water_pairs) # water_bridge_selection_names = ["resi %s and resn %s and chain %s and polar_interacting_residues" % tup for water_bridge_selection_names = [ "(%s`%s)" % tup[0] for tup in water_pairs ] for i, water_selection_name in enumerate( water_bridge_selection_names): print("Water bridge prediction \n") print("select sele_water%s, %s" % (i, water_selection_name)) water_selection = cmd.select("sele_water%s" % i, water_selection_name) print("water selection has %s atoms" % water_selection) cmd.select( "sele_water_partner%s" % i, "sele_water%s expand %s" % (i, options['binding_site_radius'])) cmd.select("sele_water_partner%s" % i, "sele_water_partner%s and binding_site" % i) cmd.select("sele_water_partner%s" % i, "sele_water_partner%s and not ligand" % i) possible_binding_site_partners = cmd.select( "sele_water_partner%s" % i, "sele_water_partner%s and (e. S or e. O or e. N)" % i) print("Predicted %s possible_binding_site_partners for %s" % (possible_binding_site_partners, water_selection_name)) if possible_binding_site_partners: # check if angles allow hbond possible_pairs = polarpairs( "sele_water_partner%s" % i, "sele_water%s" % i, name="d_water_%s" % i, cutoff=options['binding_site_radius']) water_list.append("sele_water%s" % i) # contains water molecule water_distance_list.append( "d_water_%s" % i) # contains distance between water and binding site # creates representation for residues interacting with water in binding site water_polar_tuples_list.append( polartuples(possible_pairs, selection_name="h20_inter_%s" % i)) print("water_polar_tuples_list", water_polar_tuples_list) cmd.delete("sele_water_partner%s" % i) else: cmd.delete("sele_water%s" % i) # print("water_list", water_list) # print("water_distance_list", water_distance_list) # print("water_polar_tuples_list", water_polar_tuples_list) # now only show water from water list water_to_output_list = [] # list of water selections to enable in the movie water_to_enable_list = [] for water_index, (water_name, water_distance_name) in enumerate( zip(water_list, water_distance_list)): # number_of_water = cmd.select("sele_water_binding_site", "binding_site and resn hoh") number_of_water = cmd.select("sele_water_binding_site", water_name) if number_of_water: cmd.create("water_%s" % water_index, "sele_water_binding_site") cmd.show("nb_spheres", "water_%s" % water_index) #get identifier of water for polar_interactions written to file w_model = cmd.get_model("water_%s" % water_index) for water_mol in w_model.atom: water_to_output_list.append( (water_mol.resi, water_mol.resn, water_mol.chain)) water_to_enable_list.append("water_%s" % water_index) water_to_enable_list.append(water_distance_name) cmd.color(options['colors']["interaction_polar"], water_distance_name) cmd.hide("label", water_distance_name) cmd.delete(water_name) cmd.delete("sele_water_binding_site") #append water molecules to polar interactions file with open("%s" % (POLAR_INTERACTIONS_FILENAME, ), "a+") as f: for tup in water_to_output_list: # f.write("RESI\tRESN\tCHAIN\n") f.write("%s\t%s\t%s\n" % tup) # residues interacting with water and options["water_to_enable_list"] = water_to_enable_list # Halogen Bond if options['check_halogen_interaction']: halogen_bond_selections = [] halogen_interaction_partners = [] for halogen in ["Cl", "Br", "I"]: number_of_halogen = cmd.select("sele_%s_interaction" % halogen, "ligand and e. %s" % halogen) print("We have %s %s atoms in our ligand" % (number_of_halogen, halogen)) if number_of_halogen: cmd.select("sele_candidates", "sele_%s_interaction expand 4.5" % halogen) cmd.select("sele_candidates", "sele_candidates and (e. O or e. S)") number_of_candidates = cmd.select( "sele_candidates", "sele_candidates and binding_site and not ligand") print("We have %s potential candidates for %s bonds" % (number_of_candidates, halogen)) if number_of_candidates: # if angle ~160 and distance up to 4.5 A # if angle 150-160 and distance up to 4.0 A candidate_model = cmd.get_model("sele_candidates") for atom in candidate_model.atom: print("Candidate from model = %s %s" % (atom.resn, atom.index)) cmd.select("sele_halo", "ligand and e. %s" % halogen) model_br = cmd.get_model("sele_halo") candidate_model = cmd.get_model("sele_candidates") for i, atom in enumerate(model_br.atom): # print("i= %s" % i) sele_halo = cmd.select("sele_halo%s" % i, "id %s and ligand" % atom.id) # model_sele_halo = cmd.get_model("sele_halo%s" % i) sele_halo_c = cmd.select("sele_halo%s_c" % i, "neighbor sele_halo%s" % i) # print("sele_halo %s" % sele_halo, "sele_halo_c %s" % sele_halo_c) for j, oxygen_or_sulfur in enumerate( candidate_model.atom): cmd.select( "ox_or_sulf_%s" % j, "id %s and binding_site" % oxygen_or_sulfur.id) distance = cmd.distance( "halogen_bond_%s_%s_%s" % (halogen, i, j), "sele_halo%s" % i, "ox_or_sulf_%s" % j) angle = cmd.angle( "halogen_bond_angle_%s_%s_%s" % (halogen, i, j), "sele_halo%s_c" % i, "sele_halo%s" % i, "ox_or_sulf_%s" % j) print("Distance = %s, angle = %s" % (distance, angle)) if (distance <= 4.5 and angle >= 160.0) or ( distance <= 4.0 and angle >= 150.0): print( "We have a halogen bond: halogen_bond_angle_%s_%s_%s" % (halogen, i, j)) cmd.hide( "label", "halogen_bond_%s_%s_%s" % (halogen, i, j)) cmd.hide( "label", "halogen_bond_angle_%s_%s_%s" % (halogen, i, j)) cmd.color( "cb_yellow", "halogen_bond_%s_%s_%s" % (halogen, i, j)) cmd.color( "cb_yellow", "halogen_bond_angle_%s_%s_%s" % (halogen, i, j)) #halogen_bond_selections.append("halogen_bond_%s_%s_%s" % (halogen, i, j)) halogen_bond_selections.append( "halogen_bond_angle_%s_%s_%s" % (halogen, i, j)) cmd.create("halogen_interaction_partner%s" % i, "br. ox_or_sulf_%s" % j) halogen_interaction_partners.append( "halogen_interaction_partner%s" % i) else: print("No halogen bond, deleting selection!\n") cmd.delete("halogen_bond_angle_%s_%s_%s" % (halogen, i, j)) # always delete bond, angle is enough cmd.delete("halogen_bond_%s_%s_%s" % (halogen, i, j)) cmd.delete("ox_or_sulf_%s" % j) #cleanup selections cmd.delete("sele_halo%s" % i) cmd.delete("sele_halo%s_c" % i) cmd.delete("sele_halo%s_c" % i) cmd.delete("sele_candidates") cmd.delete("sele_halo") cmd.delete("sele_%s_interaction" % halogen) # check whether we found any halogen bond interactions # if halogen_bond_selections has more than one element, it will # evaluate as true, if empty it will be false if halogen_bond_selections: options['halogen_bond_selections'] = halogen_bond_selections options[ 'halogen_interaction_partners'] = halogen_interaction_partners
def ens_measure(pk1 = None, pk2 = None, pk3 = None, pk4 = None, name = None, log = None, verbose = True): ''' DESCRIPTION Statistics from ensemble structure measurements. If: 2 selections give = distance 3 selections give = angle 4 selections give = dihedral angle USAGE ens_measure pk1, pk2, pk3, pk4, name, log, verbose ARGUMENTS log = name of log file verbose = prints individual measurements EXAMPLE ens_measure atom1, atom2, name = 'measure', log 'ens.log' ''' print >> log, '\nEnsemble measurement' if [pk1, pk2, pk3, pk4].count(None) > 2: print '\nERROR: Please supply at least 2 seletions' return number_models = cmd.count_states(pk1) measurements = [] # distance if [pk1, pk2, pk3, pk4].count(None) == 2: print >> log, 'Distance' if name == None: name = 'ens_distance' # display as object cmd.distance(name = name, selection1 = pk1, selection2 = pk2) # get individual values for n in xrange(number_models): measurements.append( cmd.get_distance(pk1, pk2, n+1) ) assert len(measurements) == number_models # angle if [pk1, pk2, pk3, pk4].count(None) == 1: print >> log, 'Angle' # display as object if name == None: name = 'ens_angle' cmd.angle(name = name, selection1 = pk1, selection2 = pk2, selection3 = pk3) # get individual values for n in xrange(number_models): measurements.append( cmd.get_angle(atom1 = pk1, atom2 = pk2, atom3 = pk3, state = n+1) ) assert len(measurements) == number_models # Dihedral angle if [pk1, pk2, pk3, pk4].count(None) == 0: print >> log, 'Dihedral angle' # display as object if name == None: name = 'ens_dihedral' cmd.dihedral(name = name, selection1 = pk1, selection2 = pk2, selection3 = pk3, selection4 = pk4) # get individual values for n in xrange(number_models): measurements.append( cmd.get_dihedral(atom1 = pk1, atom2 = pk2, atom3 = pk3, atom4 = pk4, state = n+1) ) assert len(measurements) == number_models # print stats if verbose: print >> log, ' State Value' for n, measurement in enumerate(measurements): print >> log, ' %4d %3.3f '%(n+1, measurement) print >> log, '\nMeasurement statistics' print_array_stats(array = measurements, log = log)
def find_halogen_bonds(): halogen_bonds = [] cmd.select("bindingsite1", "ligand_a expand 5.0" ) # expand selection by 5 angstrom, extend = extend along bonds cmd.select( "bindingsite1", "br. bindingsite") # br extends the selection to the full residue cmd.select("bindingsite1", "bindingsite and not ligand" ) # br extends the selection to the full residue cmd.select( "water", "resn hoh") # resn = residues name, hoh = name of water molecules cmd.select("water_bs", "water and bindingsite") #select all relevant halogen atoms number_of_halogens = cmd.select("hal", "hal and ligand_a") cmd.select("polar_atoms", "e. O or e. N or e. S") model_halogen = cmd.get_model("hal") # create model for halogen selection for halo in model_halogen.atom: print("A") cmd.select("current_halogen", "(e. I or e. Cl or e. Br) and id %s" % (halo.id)) cmd.select("current_neighbor", "current_halogen extend 1") cmd.select("current_neighbor", "current_neighbor and not current_halogen") cmd.select("current_neighbor", "neighbor current_halogen") cmd.select("current_surroundings", "current_halogen expand 5.0") cmd.select("current_surroundings", "current_surroundings and bindingsite1") cmd.select("current_polar", "current_surroundings and polar_atoms") model_polar = cmd.get_model("current_polar") for pol in model_polar.atom: cmd.select("current_polar", "not water and polar_atoms and id %s" % (pol.id)) # check for halogen bonds, distances 5.0, angles: > 140 current_distance = cmd.distance("current_distance", "current_halogen", "current_polar") current_angle = cmd.angle("current_angle", "current_neighbor", "current_halogen", "current_polar") print(current_distance, current_angle) if (current_angle >= 140) and (current_distance <= 5.0): halogen_bonds.append((pol.resn, pol.resi, pol.id, current_distance, current_angle)) #Append fitting halogen bonds to list cmd.delete("current_angle") cmd.delete("current_distance") #Clear up selections cmd.delete("current_halogen") cmd.delete("current_neighbor") cmd.delete("water") cmd.delete("water_bs") cmd.delete("current_polar") cmd.delete("current_surroundings") cmd.delete("bindingsite1") #Sort the list by distance halogen_bonds = sorted(halogen_bonds, key=lambda x: x[3]) return halogen_bonds
def angle_between_domains(selection1, selection2, method='align', state1=STATE, state2=STATE, visualize=1, quiet=1): ''' DESCRIPTION Angle by which a molecular selection would be rotated when superposing on a selection2. Do not use for measuring angle between helices, since the alignment of the helices might involve a rotation around the helix axis, which will result in a larger angle compared to the angle between helix axes. USAGE angle_between_domains selection1, selection2 [, method ] ARGUMENTS selection1 = string: atom selection of first helix selection2 = string: atom selection of second helix method = string: alignment command like "align" or "super" {default: align} EXAMPLE fetch 3iplA 3iplB, async=0 select domain1, resi 1-391 select domain2, resi 392-475 align 3iplA and domain1, 3iplB and domain1 angle_between_domains 3iplA and domain2, 3iplB and domain2 SEE ALSO align, super, angle_between_helices ''' import math try: import numpy except ImportError: print ' Error: numpy not available' raise CmdException state1, state2 = int(state1), int(state2) visualize, quiet = int(visualize), int(quiet) if cmd.is_string(method): try: method = cmd.keyword[method][0] except KeyError: print 'no such method:', method raise CmdException mobile_tmp = get_unused_name('_') cmd.create(mobile_tmp, selection1, state1, 1, zoom=0) try: method(mobile=mobile_tmp, target=selection2, mobile_state=1, target_state=state2, quiet=quiet) mat = cmd.get_object_matrix(mobile_tmp) except: print ' Error: superposition with method "%s" failed' % (method.__name__) raise CmdException finally: cmd.delete(mobile_tmp) try: # Based on transformations.rotation_from_matrix # Copyright (c) 2006-2012, Christoph Gohlke R33 = [mat[i:i+3] for i in [0,4,8]] R33 = numpy.array(R33, float) # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 w, W = numpy.linalg.eig(R33.T) i = w.real.argmax() direction = W[:, i].real # rotation angle depending on direction m = direction.argmax() i,j,k,l = [ [2,1,1,2], [0,2,0,2], [1,0,0,1]][m] cosa = (R33.trace() - 1.0) / 2.0 sina = (R33[i, j] + (cosa - 1.0) * direction[k] * direction[l]) / direction[m] angle = math.atan2(sina, cosa) angle = abs(math.degrees(angle)) except: print ' Error: rotation from matrix failed' raise CmdException if not quiet: try: # make this import optional to support running this script standalone from .querying import centerofmass, gyradius except (ValueError, ImportError): gyradius = None try: # PyMOL 1.7.1.6+ centerofmass = cmd.centerofmass except AttributeError: centerofmass = lambda s: cpv.scale(cpv.add(*cmd.get_extent(s)), 0.5) center1 = centerofmass(selection1) center2 = centerofmass(selection2) print ' Angle: %.2f deg, Displacement: %.2f angstrom' % (angle, cpv.distance(center1, center2)) if visualize: center1 = numpy.array(center1, float) center2 = numpy.array(center2, float) center = (center1 + center2) / 2.0 if gyradius is not None: rg = numpy.array(gyradius(selection1), float) else: rg = 10.0 h1 = numpy.cross(center2 - center1, direction) h2 = numpy.dot(R33, h1) h1 *= rg / cpv.length(h1) h2 *= rg / cpv.length(h2) for pos in [center1, center2, center1 + h1, center1 + h2]: cmd.pseudoatom(mobile_tmp, pos=list(pos), state=1) # measurement object for angle and displacement name = get_unused_name('measurement') cmd.distance(name, *['%s`%d' % (mobile_tmp, i) for i in [1,2]]) cmd.angle(name, *['%s`%d' % (mobile_tmp, i) for i in [3,1,4]]) # CGO arrow for axis of rotation visualize_orientation(direction, center1, rg, color='blue') cmd.delete(mobile_tmp) return angle
def ens_measure(pk1=None, pk2=None, pk3=None, pk4=None, name=None, log=None, verbose=True): ''' DESCRIPTION Statistics from ensemble structure measurements. If: 2 selections give = distance 3 selections give = angle 4 selections give = dihedral angle USAGE ens_measure pk1, pk2, pk3, pk4, name, log, verbose ARGUMENTS log = name of log file verbose = prints individual measurements EXAMPLE ens_measure atom1, atom2, name = 'measure', log 'ens.log' ''' print('\nEnsemble measurement', file=log) if [pk1, pk2, pk3, pk4].count(None) > 2: print('\nERROR: Please supply at least 2 seletions') return number_models = cmd.count_states(pk1) measurements = [] # distance if [pk1, pk2, pk3, pk4].count(None) == 2: print('Distance', file=log) if name == None: name = 'ens_distance' # display as object cmd.distance(name=name, selection1=pk1, selection2=pk2) # get individual values for n in range(number_models): measurements.append(cmd.get_distance(pk1, pk2, n + 1)) assert len(measurements) == number_models # angle if [pk1, pk2, pk3, pk4].count(None) == 1: print('Angle', file=log) # display as object if name == None: name = 'ens_angle' cmd.angle(name=name, selection1=pk1, selection2=pk2, selection3=pk3) # get individual values for n in range(number_models): measurements.append( cmd.get_angle(atom1=pk1, atom2=pk2, atom3=pk3, state=n + 1)) assert len(measurements) == number_models # Dihedral angle if [pk1, pk2, pk3, pk4].count(None) == 0: print('Dihedral angle', file=log) # display as object if name == None: name = 'ens_dihedral' cmd.dihedral(name=name, selection1=pk1, selection2=pk2, selection3=pk3, selection4=pk4) # get individual values for n in range(number_models): measurements.append( cmd.get_dihedral(atom1=pk1, atom2=pk2, atom3=pk3, atom4=pk4, state=n + 1)) assert len(measurements) == number_models # print stats if verbose: print(' State Value', file=log) for n, measurement in enumerate(measurements): print(' %4d %3.3f ' % (n + 1, measurement), file=log) print('\nMeasurement statistics', file=log) print_array_stats(array=measurements, log=log)
ang_pairs = [] restraints = [] for filename in filenames: 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: