def object_tfm_interpolate(object_properties, number_of_frames, frameno): tmpnames = [] for objnm, properties in object_properties.items(): [source_tfm, target_tfm, reverse, color, small_molecule] = properties[:5] transparency_range = properties[5] if len(properties) > 5 else None frame = frameno if reverse: frame = number_of_frames - frame tfm = intermediate_tfm(source_tfm, target_tfm, number_of_frames, frame) if objnm == "lipid": lipid_decimate(number_of_frames, frameno) tmpnm = objnm + str(frameno) cmd.copy(tmpnm, objnm, zoom=0) cmd.transform_selection(tmpnm, tfm) transparency = -1 if transparency_range: transparency = transparency_range[0] \ + float(frameno)/number_of_frames*(transparency_range[1]-transparency_range[0]) if small_molecule: if objnm == "lipid": style_lipid(tmpnm) else: style_substrate(tmpnm, mol_color[objnm], transparency) else: clump_representation([tmpnm], color, tmpnm, small_molecule=small_molecule, transparency=transparency) tmpnames.append(tmpnm) return tmpnames
def rotateline(Pos1,Pos2,degangle,molecule): diffvector = vector(Pos1,Pos2) uvector = unitvector(diffvector)[0] xyz = getxyz(Pos2)[0] rmat = rotmat(radangle(float(degangle)),uvector,xyz) cmd.transform_selection(molecule,rmat) return(None)
def rotateline(Pos1, Pos2, degangle, molecule): diffvector = vector(Pos1, Pos2) uvector = unitvector(diffvector)[0] xyz = getxyz(Pos2)[0] rmat = rotmat(radangle(float(degangle)), uvector, xyz) cmd.transform_selection(molecule, rmat) return (None)
def alpraxin(sel): """run alpraxin and apply transformation matrix""" with TemporaryDirectory(): pdbfn = writePdb(sel, "in_") outfn = sel + ".pdb" systemCommand(["alpraxin", "-o", outfn, pdbfn]) tmat = readTransformationMatrixFromPdbRemark(outfn) cmd.transform_selection(sel, tmat)
def transform_by_camera_rotation(): view = list(cmd.get_view()) M = view[0:3] + [-view[12]] + \ view[3:6] + [-view[13]] + \ view[6:9] + [-view[14]] + \ view[12:15] + [1.] cmd.transform_selection('(all)', M, transpose=1) cmd.set_view([1,0,0,0,1,0,0,0,1] + view[9:])
def orient_origin(selection): shift_to_center(selection) cmd.orient(selection) cv = list(cmd.get_view(quiet=1)) #cmd.origin(selection, position=origin1) cmd.transform_selection(selection, cv[0:3] + [0.0] + cv[3:6] + [0.0] + cv[6:9] + [0.0] + cv[12:15] + [1.0], transpose=1) cmd.reset()
def toline(Pos1, Pos2, atom, molecule, dist=1): dist = float(dist) diffvector = vector(atom, Pos2) move = transmat(diffvector) cmd.transform_selection("%s" % molecule, move) diffvector = vector(Pos1, Pos2) uvector = unitvector(diffvector)[0] move = transmat(uvector, dist) cmd.transform_selection("%s" % molecule, move) return (None)
def toline(Pos1,Pos2,atom,molecule,dist=1): dist = float(dist) diffvector = vector(atom,Pos2) move = transmat(diffvector) cmd.transform_selection("%s"%molecule,move) diffvector = vector(Pos1,Pos2) uvector = unitvector(diffvector)[0] move = transmat(uvector,dist) cmd.transform_selection("%s"%molecule,move) return(None)
def supalm(template, toalign): """run supalm and apply transformation matrix""" if(toalign == template): message("ERROR Please choose different models for superimposition\n") return with TemporaryDirectory('supalm'): f1 = writePdb(template) f2 = writePdb(toalign, "in_") outfn = toalign + ".pdb" systemCommand(['supalm', '-o', outfn, '--prog2=crysol'] + [f1, f2]) tmat = readTransformationMatrixFromPdbRemark(outfn) nsd = readNSDFromSupalmPdb(outfn) cmd.transform_selection(toalign, tmat) message("SUPALM NSD = " + repr(nsd))
def rdkitalign(mobile, target, mobile_state=-1, target_state=-1, reflect=0, max_iters=500): """ DESCRIPTION Align two molecules using RDKit. USAGE rdkitalign mobile, target, [, target_state [, mobile_state [, reflect [, max_iters ]]]] NOTES "rdkitalign" uses RDKit's alignment interface. "target_state" and "mobile_state" indicate the states of the molecules that will be used the alignment, though all states will be transformed accordingly. These default to -1, the use of the currently visible states. "reflect" reflects the conformation of the mobile molecule (defaults to 0). EXAMPLES # align molA onto molB rdkitalign molA, molB """ print("Aligning %s to %s with RDKit" % (mobile, target)) mobile_mol = obj_to_rdmol(mobile, int(mobile_state)) target_mol = obj_to_rdmol(target, int(target_state)) try: rmsd, trans_matrix = rdMolAlign.GetAlignmentTransform( mobile_mol, target_mol, reflect=bool(int(reflect)), maxIters=int(max_iters)) except RuntimeError: print " RDKitAlign-Error: alignment failed." return False cmd.transform_selection(mobile, trans_matrix.flatten().tolist(), homogenous=1) if HAS_NP: inv_array_string = "["+", ".join( ["%.4g" % x for x in np.linalg.inv(trans_matrix).flatten().tolist()])+"]" print("Molecules are aligned. To reverse the alignment, run:") print('cmd.transform_selection("%s", %s, homogenous=1)' % ( mobile, inv_array_string)) print("RMSD: %.4f" % rmsd)
def open3dalign(mobile, target, mobile_state=-1, target_state=-1, options=0, max_iters=500): """ DESCRIPTION Align two molecules using Open3DAlign. USAGE open3dalign mobile, target, [, target_state [, mobile_state [, options [, max_iters ]]]] NOTES "open3dalign" uses RDKit's interface for Open3DAlign. "target_state" and "mobile_state" indicate the states of the molecules that will be used the alignment, though all states will be transformed accordingly. These default to -1, the use of the currently visible states. For description of other parameters, see RDKit's Open3DAlign documentation: http://www.rdkit.org/Python_Docs/rdkit.Chem.rdMolAlign-module.html#GetO3A EXAMPLES # align molA onto molB open3dalign molA, molB """ print("Aligning %s to %s with Open3DAlign" % (mobile, target)) mobile_mol = obj_to_rdmol(mobile, int(mobile_state)) target_mol = obj_to_rdmol(target, int(target_state)) alignment = rdMolAlign.GetO3A(mobile_mol, target_mol, options=int(options), maxIters=int(max_iters)) rmsd, trans_matrix = alignment.Trans() cmd.transform_selection(mobile, trans_matrix.flatten().tolist(), homogenous=1) if HAS_NP: inv_array_string = "["+", ".join( ["%.4g" % x for x in np.linalg.inv(trans_matrix).flatten().tolist()])+"]" print("Molecules are aligned. To reverse the alignment, run:") print('cmd.transform_selection("%s", %s, homogenous=1)' % ( mobile, inv_array_string)) score = alignment.Score() print("RMSD: %.4f" % rmsd) print("Score: %.4f" % score)
def supalm(template, toalign): """run supalm and apply transformation matrix""" if(toalign == template): message("ERROR Please choose different models for superimposition\n") return with TemporaryDirectory('supalm'): f1 = writePdb(template) f2 = writePdb(toalign, "in_") outfn = toalign + ".pdb" systemCommand(['supalm', '-o', outfn, '--prog2=crysol'] + [f1, f2]) #reloading file approach, needed for ATSAS 2.7.1 #cmd.delete(toalign) #cmd.load(outfn) #and the following works properly for ATSAS 2.7.2 tmat = readTransformationMatrixFromPdbRemark(outfn) nsd = readNSDFromSupalmPdb(outfn) cmd.transform_selection(toalign, tmat) message("SUPALM NSD = " + repr(nsd))
def supalm(template, toalign): """run supalm and apply transformation matrix""" if (toalign == template): message("ERROR Please choose different models for superimposition\n") return with TemporaryDirectory('supalm'): f1 = writePdb(template) f2 = writePdb(toalign, "in_") outfn = toalign + ".pdb" sargs = ['supalm', '-o', outfn] sargs.append('--prog2=crysol') sargs.append('--enantiomorphs=N') sargs.append(f1) sargs.append(f2) systemCommand(sargs) tmat = readTransformationMatrixFromPdbRemark(outfn) nsd = readNSDFromSupalmPdb(outfn) cmd.transform_selection(toalign, tmat) message("SUPALM NSD = " + repr(nsd))
def transformar(selection): ''' DESCRIPTION Rotate the molecule and draw the inertia axis. ''' rotacion_orig(selection) model_rot = cmd.transform_selection(selection, transf_array, homogenous=0, transpose=1); draw_inertia_axis(selection)
def alpraxin(models, enantiomode): """run alpraxin and apply transformation matrix""" sel = " or ".join(models) with TemporaryDirectory(): pdbfn = writePdb(sel, "in_") outfn = sel + ".pdb" outfn = outfn.replace(" ", "") aargs = ["alpraxin", pdbfn] if ('yes' == enantiomode): message("ALPRAXIN will create enantiomer as new model") aargs.append("--enantiomorph=Y") aargs.append("-o") aargs.append(outfn) systemCommand(aargs) if ('no' == enantiomode): tmat = readTransformationMatrixFromPdbRemark(outfn) cmd.transform_selection(sel, tmat) if ('yes' == enantiomode): cmd.load(outfn, "enantiomorph_" + sel)
def princ_align(selection='(all)'): model = cmd.get_model(f"{selection} and name CA") coords = np.array([at.coord for at in model.atom]) try: center = np.mean(coords, axis=0) except NameError: print( "This command will not work without numpy.\nConsider installing numpy (or anaconda, provides numpy)." ) return coords -= center eig_vec = get_principal_axes(coords) # Now i have to calculate angles... # largest should be aligned with Z-axis x0 = np.array([1, 0, 0]) y0 = np.array([0, 1, 0]) z0 = np.array([0, 0, 1]) # Transform everything such that it is centered around # selection's center, and rotated # Such that the principal axes of the selection # align with those of the frame of reference # For some reason x0 is the right one to align with the z-axis rot_mat = rotation_matrix_from_vectors(eig_vec[0], x0) TTT = [ *rot_mat[0], -center[0], *rot_mat[1], -center[1], *rot_mat[2], -center[2], 0, 0, 0, 1 ] cmd.transform_selection('(all)', TTT, transpose=1) # Finally center all cmd.center() return eig_vec # Just in case i need them later
def tx(obj_name=None, tran_before=[0, 0, 0], rot=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], tran_after=[0, 0, 0]): """Transforms an object. Args: - obj_name - string - tran_before - a 3x1 translation vector applied before rotation - rot - a 3x3 rotation matrix - tran_after - a 3x1 translation vector applied after rotation """ if obj_name is None: print(tx.__doc__) else: rot_tran_mat = np.array(rot) rot_tran_mat = np.append(rot_tran_mat, np.transpose([tran_after]), axis=1) rot_tran_mat = np.append(rot_tran_mat, [tran_before + [1]], axis=0) pymol_rot_tran_vals = [v for row in rot_tran_mat for v in row] cmd.transform_selection(obj_name, matrix=pymol_rot_tran_vals, homogenous=0)
def translacion_cM(selection): ''' DESCRIPTION Translate the center of mass of the molecule to the origin. ''' model = cmd.get_model(selection) totmass = 0.0 x,y,z = 0,0,0 for a in model.atom: m = a.get_mass() x += a.coord[0]*m y += a.coord[1]*m z += a.coord[2]*m totmass += m cM = numpy.array([x/totmass, y/totmass, z/totmass]) trans_array = ([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -cM[0], -cM[1], -cM[2], 1]) model_trans = cmd.transform_selection(selection, trans_array)
def affine(selection, sh_x=0.1, sh_y=0.1): """ Perform distortion from circular geometry on scaffold Peform rotation-translation-rotation on a PDB 1. load scaffold 2. apply transfromation sh_x,sh_y = shear factors (x,y) """ # set-up transformation shift0 = 0.0 shift1 = 0.0 shift2 = 0.0 # sh_x = 0.1 # shear factor for transformation in x # sh_y = 0.1 # shear factor for transformation in y rotMat = [ 1.0, sh_x, 0.0, shift0, sh_y, 1.0, 0.0, shift1, 0.0, 0.0, 1.0, shift2, 0.0, 0.0, 0.0, 1.0 ] # perform the transformation return cmd.transform_selection(selection, rotMat)
def sasref(SaxsDataFileName, models = [], mode = 'local', viewer='sasplot'): '''Execute SASREF and apply obtained transformations to subunits''' global modelingRuns #parameter configuration #local refinment (to reproduce MASSHA behaviour): confp = {'spst':'1.0', # spatial step, SASREF default is 5.0 Angstrom 'anst':'5.0', #angular step, SASREF default is 20 degrees 'init':'1.0', # Initial annealing temperature (def= 10) 'sche':'0.9', # Annealing schedule factor 'iter':'500', # Max # of iterations at each T (def = 10000) 'maxs':' 50', # Max # of successes at each T (def = 1000) 'mins':' 10', # Min # of successes to continue (def = 100) 'maxa':' 10', # Max # of annealing steps (def = 100) 'msol':' 1', # Max # of solutions to store (def = 1) 'shft':' '} #xyz init shift, blank for local #0.0 for global search if 'global' == mode: #settings for default global search confp['spst'] = '5.0' confp['anst'] = '20.0' confp['init'] = '10.0' confp['sche'] = '0.9' confp['iter'] = '10000' confp['maxs'] = '1000' confp['mins'] = '100' confp['maxa'] = '100' confp['msol'] = '1' confp['shft'] = '0.0' if False == os.path.isfile(SaxsDataFileName): message("SAXS .dat file \'"+SaxsDataFileName+"\' not found") return 113 fileFullPath = os.path.abspath(SaxsDataFileName) prefix = 'sasref' modelingRuns += 1 prefix = prefix + repr(modelingRuns) numberOfSubunits = len(models); with TemporaryDirectory(prefix) as tmpdir: #sasref can not deal with long path/names tmpsaxsfn = os.path.basename(SaxsDataFileName) tmpdir.copy_in(fileFullPath, tmpsaxsfn); sc = "" sc += "Expert ! Configuration mode\n" sc += prefix + " ! logfilename\n" sc += prefix + " ! projectDescription\n" sc += " ! initRandomSeed\n" sc += repr(numberOfSubunits) + " ! totalNumberOfSubunits\n" sc += "P1 ! Symmetry\n" sc += "1 ! totalNumberOfScatteringCurves\n" sc += "N ! KratkyGeometry\n" sc += "1,2 ! Input first & last subunits in 1-st construct\n" sc += tmpsaxsfn+ " ! Enter file name, 1-st experimental data\n" sc += " ! Angular units input file\n" sc += "1.0 ! Fitting range in fractions of Smax\n" count = 1 for m in models: pdbtmpfn = writePdb(m) pdbtmpfn = os.path.basename(pdbtmpfn) fid = os.path.splitext(pdbtmpfn)[0] #print "abs: " + m + " and temp: "+pdbtmpfn + "while id: "+fid; #tmpdir.copy_in(m, pdbtmpfn); #compute amplitudes systemCommand(["crysol"] + ["-p"] + [fid] + [pdbtmpfn]) print "computed alm for : "+ fid +"\n" sc += fid+".alm"+"! subunit " +repr(count)+" amplitudes\n" sc += "0.0 ! Initial rotation by alpha\n" sc += "0.0 ! Initial rotation by beta\n" sc += "0.0 ! Initial rotation by gamma\n" sc += confp['shft']+" ! Initial shift along X\n" sc += confp['shft']+" ! Initial shift along Y\n" sc += confp['shft']+" ! Initial shift along Z\n" sc += "N ! Movements limitations of subunit: N/F/X/Y/Z/D\n" sc += confp['spst'] + " ! Spatial step in Angstrom\n" sc += confp['anst'] + " ! Angular step in degrees\n" #continue with rest of commands sc += " ! Cross penalty weight\n" sc += " ! Disconnectivity penalty weight\n" sc += " ! Docking penalty weight\n" sc += " ! File name, contacts conditions, CR for none\n" sc += "U ! Expected particle shape: <P>rolate, <O>blate or <U>nknown\n" sc += " ! Shift penalty weight \n" sc += confp['init'] + " ! Initial annealing temperature (def= 10) \n" sc += confp['sche'] + " ! Annealing schedule factor\n" sc += confp['iter'] + " ! Max # of iterations at each T (def = 10000)\n" sc += confp['maxs'] + " ! Max # of successes at each T (def = 1000)\n" sc += confp['mins'] +" ! Min # of successes to continue (def = 100)\n" sc += confp['maxa'] +" ! Max # of annealing steps (def = 100)\n" sc += confp['msol']+" ! Max # of solutions to store (def = 1)\n" comfn = 'setup_sasref.com' with open(comfn, 'w') as commandfile: commandfile.write(sc) with open(comfn, 'r') as commandfile: systemCommand(['sasref'], stdin=commandfile) outpdb = prefix + ".pdb" #read and apply movements moves = parseEulerAngles(outpdb); idx = 0 for mov in moves: tmat = anglesToTTTMat(mov) cmd.transform_selection(models[idx], tmat) idx = idx+1 outpdbfn = tmpdir.move_out_numbered(prefix + ".pdb", prefix, '.pdb') message( ".pdb file written to " + outpdbfn) cf = tmpdir.move_out_numbered(prefix + "-1.fit", prefix, '.fit') message( ".fit file written to " + cf) openSingleDatFile(viewer, cf) return
def sasref(SaxsDataFileName, models=[], mode='local', viewer='primus'): '''Execute SASREF and apply obtained transformations to subunits''' global modelingRuns #parameter configuration #local refinment (to reproduce MASSHA behaviour): confp = { 'spst': '1.0', # spatial step, SASREF default is 5.0 Angstrom 'anst': '5.0', #angular step, SASREF default is 20 degrees 'init': '1.0', # Initial annealing temperature (def= 10) 'sche': '0.9', # Annealing schedule factor 'iter': '500', # Max # of iterations at each T (def = 10000) 'maxs': ' 50', # Max # of successes at each T (def = 1000) 'mins': ' 10', # Min # of successes to continue (def = 100) 'maxa': ' 10', # Max # of annealing steps (def = 100) 'msol': ' 1', # Max # of solutions to store (def = 1) 'shft': ' ' } #xyz init shift, blank for local #0.0 for global search if 'global' == mode: #settings for default global search confp['spst'] = '5.0' confp['anst'] = '20.0' confp['init'] = '10.0' confp['sche'] = '0.9' confp['iter'] = '10000' confp['maxs'] = '1000' confp['mins'] = '100' confp['maxa'] = '100' confp['msol'] = '1' confp['shft'] = '0.0' if False == os.path.isfile(SaxsDataFileName): message("SAXS .dat file \'" + SaxsDataFileName + "\' not found") return 113 fileFullPath = os.path.abspath(SaxsDataFileName) prefix = 'sasref' modelingRuns += 1 prefix = prefix + repr(modelingRuns) numberOfSubunits = len(models) with TemporaryDirectory(prefix) as tmpdir: #sasref can not deal with long path/names tmpsaxsfn = os.path.basename(SaxsDataFileName) tmpdir.copy_in(fileFullPath, tmpsaxsfn) sc = "" sc += "Expert ! Configuration mode\n" sc += prefix + " ! logfilename\n" sc += prefix + " ! projectDescription\n" sc += " ! initRandomSeed\n" sc += repr(numberOfSubunits) + " ! totalNumberOfSubunits\n" sc += "P1 ! Symmetry\n" sc += "1 ! totalNumberOfScatteringCurves\n" sc += "N ! KratkyGeometry\n" sc += "1,2 ! Input first & last subunits in 1-st construct\n" sc += tmpsaxsfn + " ! Enter file name, 1-st experimental data\n" sc += " ! Angular units input file\n" sc += "1.0 ! Fitting range in fractions of Smax\n" count = 1 for m in models: pdbtmpfn = writePdb(m) pdbtmpfn = os.path.basename(pdbtmpfn) fid = os.path.splitext(pdbtmpfn)[0] #print "abs: " + m + " and temp: "+pdbtmpfn + "while id: "+fid; #tmpdir.copy_in(m, pdbtmpfn); #compute amplitudes systemCommand(["crysol"] + ["-p"] + [fid] + [pdbtmpfn]) print "computed alm for : " + fid + "\n" sc += fid + ".alm" + "! subunit " + repr(count) + " amplitudes\n" sc += "0.0 ! Initial rotation by alpha\n" sc += "0.0 ! Initial rotation by beta\n" sc += "0.0 ! Initial rotation by gamma\n" sc += confp['shft'] + " ! Initial shift along X\n" sc += confp['shft'] + " ! Initial shift along Y\n" sc += confp['shft'] + " ! Initial shift along Z\n" sc += "N ! Movements limitations of subunit: N/F/X/Y/Z/D\n" sc += confp['spst'] + " ! Spatial step in Angstrom\n" sc += confp['anst'] + " ! Angular step in degrees\n" #continue with rest of commands sc += " ! Cross penalty weight\n" sc += " ! Disconnectivity penalty weight\n" sc += " ! Docking penalty weight\n" sc += " ! File name, contacts conditions, CR for none\n" sc += "U ! Expected particle shape: <P>rolate, <O>blate or <U>nknown\n" sc += " ! Shift penalty weight \n" sc += confp[ 'init'] + " ! Initial annealing temperature (def= 10) \n" sc += confp['sche'] + " ! Annealing schedule factor\n" sc += confp[ 'iter'] + " ! Max # of iterations at each T (def = 10000)\n" sc += confp[ 'maxs'] + " ! Max # of successes at each T (def = 1000)\n" sc += confp[ 'mins'] + " ! Min # of successes to continue (def = 100)\n" sc += confp['maxa'] + " ! Max # of annealing steps (def = 100)\n" sc += confp['msol'] + " ! Max # of solutions to store (def = 1)\n" comfn = 'setup_sasref.com' with open(comfn, 'w') as commandfile: commandfile.write(sc) if "win32" != platform: with open(comfn, 'r') as commandfile: systemCommand(['sasref'], stdin=commandfile) #somehow this doesn't work on Windows with PyMOL 2.0 #there's an issue with the underlying libraries... else: os.system('sasref < setup_sasref.com') outpdb = prefix + ".pdb" #read and apply movements moves = parseEulerAngles(outpdb) idx = 0 for mov in moves: tmat = anglesToTTTMat(mov) cmd.transform_selection(models[idx], tmat) idx = idx + 1 outpdbfn = tmpdir.move_out_numbered(prefix + ".pdb", prefix, '.pdb') message(".pdb file written to " + outpdbfn) cf = tmpdir.move_out_numbered(prefix + "-1.fit", prefix, '.fit') message(".fit file written to " + cf) openSingleDatFile(viewer, cf) return
def tmalign(mobile, target, args='', exe='TMalign', ter=0, transform=1, object=None, quiet=0): """ DESCRIPTION TMalign wrapper Reference: Y. Zhang and J. Skolnick, Nucl. Acids Res. 2005 33, 2302-9 http://zhanglab.ccmb.med.umich.edu/TM-align/ USAGE tmalign mobile, target [, args [, exe ]] ARGUMENTS mobile, target = string: atom selections args = string: Extra arguments like -d0 5 -L 100 exe = string: Path to TMalign executable {default: TMalign} ter = 0/1: If ter=0, then ignore chain breaks because TMalign will stop at first TER record {default: 0} SEE ALSO tmscore, mmalign """ import subprocess import tempfile import os import re 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) save(target_filename, target_ca_sele) 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) 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 line.lower().startswith(' -------- rotation matrix'): rowcount = 1 elif line.startswith('(":" denotes'): alignment = [] for i in range(3): alignment.append(line_it.next().rstrip()) 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): cmd.transform_selection('byobject (%s)' % mobile, matrix, 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 ':.'), matchmaker=4, object=object) else: print('Could not load alignment object') if not quiet and r is not None: print('Found in output TM-score = %.4f' % r) return r
def tmalign(mobile, target, args='', exe='TMalign', ter=0, transform=1, object=None, quiet=0): ''' DESCRIPTION TMalign wrapper Reference: Y. Zhang and J. Skolnick, Nucl. Acids Res. 2005 33, 2302-9 http://zhanglab.ccmb.med.umich.edu/TM-align/ USAGE tmalign mobile, target [, args [, exe ]] ARGUMENTS mobile, target = string: atom selections args = string: Extra arguments like -d0 5 -L 100 exe = string: Path to TMalign executable {default: TMalign} ter = 0/1: If ter=0, then ignore chain breaks because TMalign will stop at first TER record {default: 0} SEE ALSO tmscore, mmalign ''' import subprocess import tempfile import os import re 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) save(target_filename, target_ca_sele) 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) 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 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): cmd.transform_selection('byobject (%s)' % (mobile), matrix, 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 and r is not None: print('Found in output TM-score = %.4f' % (r)) return r
obj.extend( [ VERTEX ] + v1 + [ VERTEX ] + v0 ) obj.extend( [END] ) # then we load it into PyMOL cmd.load_cgo(obj,'cgo06') # position haemolysin through pore if 1: cmd.fetch("7ahl") cmd.transform_selection("7ahl", (0.70349078502033213, 0.19033556773811347, -0.68474258132841503, -11.993190038310882, -0.15869362855324043, 0.98121371667870472, 0.10970571819737528, -29.939406659327624, 0.69276001846262825, 0.03148755047390385, 0.72048024614206196, -26.250180846754432, 0.0, 0.0, 0.0, 1.0)) cmd.show_as("cartoon","7ahl") cmd.do("util.cbc") cmd.set_view((\ -0.589197695, -0.440498680, 0.677344978,\ 0.574851871, -0.817646086, -0.031699535,\ 0.567794442, 0.370693058, 0.734975874,\ 0.000004128, -0.000099868, -651.343872070,\ -4.874452114, 8.360315323, 11.387301445,\ 528.689147949, 773.963684082, 0.000000000 ))
def alignZ(selection, name="tensor", state=1, scaling=0, quiet=1): """ DESCRIPTION This script will draw the inertia tensor of the selection. ARGUMENTS selection = string: selection for the atoms included in the tensor calculation name = string: name of the tensor object to be created {default: "tensor"} state = int: state/model in the molecule object used in the tensor calculation scaling = int {0, 1, or 2}: 0 for no scaling of the inertia axes, 1 for scaling according to the molecular shape, 2 for scaling according to the eigenvalues {default: 0} EXAMPLE PyMOL> run inertia_tensor.py PyMOL> tensor molecule_object & i. 2-58+63-120 & n. n+ca+c, "tensor_model5_dom2", 5, 1 NOTES Requires numpy. """ import numpy totmass = 0.0 x_com, y_com, z_com = 0, 0, 0 model = cmd.get_model(selection, state) for a in model.atom: x_com += a.coord[0] * a.get_mass() y_com += a.coord[1] * a.get_mass() z_com += a.coord[2] * a.get_mass() totmass += a.get_mass() x_com /= totmass y_com /= totmass z_com /= totmass if not int(quiet): print() print("Center of mass: ") print() print(x_com, y_com, z_com) cmd.translate([-x_com, -y_com, -z_com], selection) # Go back and rewrite the COM section to be a function, then it can # be called again to ensure the translation was correct x_com = 0.0 y_com = 0.0 z_com = 0.0 I = [] for index in range(9): I.append(0) for a in model.atom: temp_x, temp_y, temp_z = a.coord[0], a.coord[1], a.coord[2] temp_x -= x_com temp_y -= y_com temp_z -= z_com I[0] += a.get_mass() * (temp_y ** 2 + temp_z ** 2) I[4] += a.get_mass() * (temp_x ** 2 + temp_z ** 2) I[8] += a.get_mass() * (temp_x ** 2 + temp_y ** 2) I[1] -= a.get_mass() * temp_x * temp_y I[3] -= a.get_mass() * temp_x * temp_y I[2] -= a.get_mass() * temp_x * temp_z I[6] -= a.get_mass() * temp_x * temp_z I[5] -= a.get_mass() * temp_y * temp_z I[7] -= a.get_mass() * temp_y * temp_z tensor = numpy.array([(I[0:3]), (I[3:6]), (I[6:9])]) vals, vects = numpy.linalg.eig(tensor) # they come out unsorted, so the command below is needed eig_ord = numpy.argsort(vals) # a thing to note is that here COLUMN i corrensponds to eigenvalue i. ord_vals = vals[eig_ord] ord_vects = vects[:, eig_ord].T if not int(quiet): print() print("Inertia tensor z, y, x eigenvalues:") print() print(ord_vals) print() print("Inertia tensor z, y, x eigenvectors:") print() print(ord_vects) if int(scaling) == 0: norm_vals = [sum(numpy.sqrt(ord_vals / totmass)) / 3 for i in range(3)] elif int(scaling) == 1: normalizer = numpy.sqrt(max(ord_vals) / totmass) norm_vals = normalizer / numpy.sqrt(ord_vals / totmass) * normalizer norm_vals = norm_vals / (max(norm_vals) / min(norm_vals)) elif int(scaling) == 2: normalizer = numpy.sqrt(max(ord_vals) / totmass) norm_vals = numpy.sqrt(ord_vals / totmass) start = [x_com, y_com, z_com] ends = [[(norm_vals[0] - 1) * ord_vects[0][0], (norm_vals[0] - 1) * ord_vects[0][1], (norm_vals[0] - 1) * ord_vects[0][2]], [(norm_vals[1] - 1) * ord_vects[1][0], (norm_vals[1] - 1) * ord_vects[1][1], (norm_vals[1] - 1) * ord_vects[1][2]], [(norm_vals[2] - 1) * ord_vects[2][0], (norm_vals[2] - 1) * ord_vects[2][1], (norm_vals[2] - 1) * ord_vects[2][2]]] import numpy as np zvec = np.array([[0],[0],[1]]) newvec = np.array([[(norm_vals[0]-1) * ord_vects[0][2]], [(norm_vals[1]-1) * ord_vects[1][2]], [(norm_vals[2]-1) * ord_vects[2][2]]]) print(newvec) norm = np.linalg.norm(newvec) newvecnorm = np.divide(newvec, norm) newvec = newvecnorm print(newvec) #create the rotation matrix, cross product, and dot prduct rotmat = np.zeros((3,3)) cross = np.cross(newvec, zvec, axis=0) crossnorm = np.linalg.norm(cross) dot = np.dot(np.transpose(newvec), zvec) vxmat = np.zeros((3,3)) vxmat[0,1] = -cross[2] vxmat[0,2] = cross[1] vxmat[1,0] = cross[2] vxmat[1,2] = -cross[0] vxmat[2,0] = -cross[1] vxmat[2,1] = cross[0] thirdterm = np.matmul(vxmat, vxmat) * (1/(1+dot)) rotmat = np.diag((1,1,1)) + vxmat + thirdterm newvectrans = np.matmul(rotmat, newvec) print("New vector after alignment: %s" % newvectrans) cmd.transform_selection(selection, ([rotmat[0,0], rotmat[0,1], rotmat[0,2], 0.0, rotmat[1,0], rotmat[1,1], rotmat[1,2], 0.0, rotmat[2,0], rotmat[2,1], rotmat[2,2], 0.0, 0.0, 0.0, 0.0, 1.0]))
obj.extend([VERTEX] + v1 + [VERTEX] + v0) obj.extend([END]) # then we load it into PyMOL cmd.load_cgo(obj, 'cgo06') # position haemolysin through pore if 1: cmd.fetch("7ahl") cmd.transform_selection( "7ahl", (0.70349078502033213, 0.19033556773811347, -0.68474258132841503, -11.993190038310882, -0.15869362855324043, 0.98121371667870472, 0.10970571819737528, -29.939406659327624, 0.69276001846262825, 0.03148755047390385, 0.72048024614206196, -26.250180846754432, 0.0, 0.0, 0.0, 1.0)) cmd.show_as("cartoon", "7ahl") cmd.do("util.cbc") cmd.set_view((\ -0.589197695, -0.440498680, 0.677344978,\ 0.574851871, -0.817646086, -0.031699535,\ 0.567794442, 0.370693058, 0.734975874,\ 0.000004128, -0.000099868, -651.343872070,\ -4.874452114, 8.360315323, 11.387301445,\ 528.689147949, 773.963684082, 0.000000000 ))
def align_to_axis(obj, atom_sel=None, axis="y", axes_dict=AXES): """ DESCRIPTION Align protein to arbitrary axis with atom selection at origin. USAGE align_to_axis obj [, atom_sel [, axis ]] NOTES "atom_sel" must contain a single atom in "obj". If not specified, defaults to N-terminal nitrogen. "axis" must be either x, y, or z, or coordinates for an axis (e.g. [1, 2, 3]). EXAMPLES # align to y-axis with N-terminus at origin align_to_axis obj # align to x-axis align_to_axis obj, axis=x # align to y-axis with C-terminus at origin cmd.select("cterm", "index %d:%d" % cmd.get_model("obj and not het", 1).get_residues()[-1]) align_to_axis obj, cterm and n. c """ if atom_sel is None: stored.list = [] cmd.iterate("%s and not hetatm and n. n" % obj, "stored.list.append(resi)") atom_sel = "%s and resi %s and n. n" % (obj, stored.list[0]) if axis.lower() in axes_dict: target_vect = np.asarray(axes_dict[axis], dtype=np.float) else: try: target_vect = np.asarray(ast.literal_eval(axis), dtype=np.float) except (ValueError, TypeError): print ("AlignToAxisError: Provided axis is of unknown format: %s." % (repr(axis))) return False target_vect = as_unit(target_vect) cmd.reset() origin_coord_list = cmd.get_model(atom_sel, 1).get_coord_list() if len(origin_coord_list) != 1: print ( "AlignToAxisError: atom selection should contain exactly 1 atom. Selection contains %d atoms." % (len(origin_coord_list)) ) return False origin_coord = np.asarray(origin_coord_list[0], dtype=np.float) com_coord = np.asarray(get_com(obj), dtype=np.float) com_vect = com_coord - origin_coord pre_trans_vect = -com_coord post_trans_vect = target_vect * np.linalg.norm(com_vect) rot_matrix = create_rot_matrix(com_vect, target_vect) trans_matrix = create_trans_matrix(rot_matrix, pre_trans_vect, post_trans_vect) cmd.transform_selection(obj, trans_matrix.flatten().tolist(), homogenous=0) cmd.reset()