From 73be223cd9005e1b7d907e329099967f54e0ec6f Mon Sep 17 00:00:00 2001 From: Daniel Bauer Date: Sun, 17 Dec 2017 12:56:13 +0100 Subject: [PATCH] pymol --- .pymol/startup/Draw_Protein_Dimensions.py | 362 ++++++++ .pymol/startup/Draw_Protein_Dimensions.pyc | Bin 0 -> 9483 bytes .pymol/startup/axes.py | 68 ++ .pymol/startup/axes.pyc | Bin 0 -> 2798 bytes .pymol/startup/center_of_mass.py | 86 ++ .pymol/startup/center_of_mass.pyc | Bin 0 -> 2408 bytes .pymol/startup/color_h.py | 128 +++ .pymol/startup/color_h.pyc | Bin 0 -> 4544 bytes .pymol/startup/dssp_stride.py | 981 +++++++++++++++++++++ .pymol/startup/dssp_stride.pyc | Bin 0 -> 26465 bytes .pymol/startup/propka.py | 887 +++++++++++++++++++ .pymol/startup/propka.pyc | Bin 0 -> 32049 bytes .pymol/startup/show_contact_map.py | 58 ++ .pymol/startup/show_contact_map.pyc | Bin 0 -> 2421 bytes .pymol/startup/spectrum_states.py | 92 ++ .pymol/startup/spectrum_states.pyc | Bin 0 -> 2857 bytes .pymol/startup/tmalign.py | 257 ++++++ .pymol/startup/tmalign.pyc | Bin 0 -> 7810 bytes .pymol/startup/visualize_dca_scores.py | 87 ++ .pymol/startup/visualize_dca_scores.pyc | Bin 0 -> 3846 bytes .pymolrc | 4 + 21 files changed, 3010 insertions(+) create mode 100644 .pymol/startup/Draw_Protein_Dimensions.py create mode 100644 .pymol/startup/Draw_Protein_Dimensions.pyc create mode 100644 .pymol/startup/axes.py create mode 100644 .pymol/startup/axes.pyc create mode 100644 .pymol/startup/center_of_mass.py create mode 100644 .pymol/startup/center_of_mass.pyc create mode 100644 .pymol/startup/color_h.py create mode 100644 .pymol/startup/color_h.pyc create mode 100644 .pymol/startup/dssp_stride.py create mode 100644 .pymol/startup/dssp_stride.pyc create mode 100644 .pymol/startup/propka.py create mode 100644 .pymol/startup/propka.pyc create mode 100644 .pymol/startup/show_contact_map.py create mode 100644 .pymol/startup/show_contact_map.pyc create mode 100644 .pymol/startup/spectrum_states.py create mode 100644 .pymol/startup/spectrum_states.pyc create mode 100644 .pymol/startup/tmalign.py create mode 100644 .pymol/startup/tmalign.pyc create mode 100644 .pymol/startup/visualize_dca_scores.py create mode 100644 .pymol/startup/visualize_dca_scores.pyc create mode 100644 .pymolrc diff --git a/.pymol/startup/Draw_Protein_Dimensions.py b/.pymol/startup/Draw_Protein_Dimensions.py new file mode 100644 index 0000000..3014a49 --- /dev/null +++ b/.pymol/startup/Draw_Protein_Dimensions.py @@ -0,0 +1,362 @@ + +''' +Calculate and display the dimensions of a protein. + + +This is a first version, please use at your own risk! + +REQUIREMENTS + +numpy (http://numpy.scipy.org) that should be built into the newers versions of Pymol + +(c) Pablo Guardado Calvo + +Based on "inertia_tensor.py" (c) 2010 by Mateusz Maciejewski + +License: MIT + +''' + +from __future__ import print_function + +__author__ = 'Pablo Guardado Calvo' +__version__ = '0.1' +__email__ = 'pablo.guardado (at) gmail.com' +__date__ = '13/08/2015' + +########################################################################################################################################################### +# USAGE +# +# The idea behing this script is to calculate an aproximate minimal bounding box to extract the cell dimensions of a protein. To calculate the minimal bounding +# is not trivial and usually the Axis Aligned Bounding Box (AABB) does not show up the real dimensions of the protein. This script calculates the inertia tensor +# of the object, extract the eigenvalues and use them to rotate the molecule (using as rotation matrix the transpose of the eigenvalues matrix). The result is that +# the molecule is oriented with the inertia axis aligned with the cartesian axis. A new Bounding Box is calculated that is called Inertia Axis Aligned Bounding Box +#(IABB), whose volume is always lower than AABB volume, and in many cases will correspond with the lowest volume. Of course, maybe it exists another Bounding Box +# with a lower volume (the minimal Bounding Box). +# +# As always with these type of things, you have to use at your own risk. I did not try all the possible combinations, but if you find a bug, do +# not hesitate to contact me (pablo.guardado (at) gmail.com) or try to modify the code for yourself to correct it. +# +# To load the script just type: +# +# run path-to-the-script/Draw_Protein_Dimensions.py +# +# or if you want something more permanent add the previous line to your .pymolrc file +# +# The script works just typing: +# +# draw_Protein_Dimensions selection +# +# This will draw the cell dimensions of your selection based on a IABB. It also generates the IABB box and the inertia axis, you just need to do "show cgo" to display them. +# +# You could also try: +# +# draw_BB selection +# +# This will draw the AABB and IABB boxes with their cell dimensions and show in the command line their volumes, you can compare both of them. +############################################################################################################################################################ + +from pymol import cmd, cgo +from pymol.cgo import * +import numpy +from random import randint + +def matriz_inercia(selection): + ''' + DESCRIPTION + + The method calculates the mass center, the inertia tensor and the eigenvalues and eigenvectors + for a given selection. Mostly taken from inertia_tensor.py + ''' + + 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 + global cM + cM = numpy.array([x/totmass, y/totmass, z/totmass]) + + + 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 + temp_y -= y + temp_z -= z + + I[0] += a.get_mass() * (temp_y**2 + temp_z**2) + I[1] -= a.get_mass() * temp_x * temp_y + I[2] -= a.get_mass() * temp_x * temp_z + I[3] -= a.get_mass() * temp_x * temp_y + I[4] += a.get_mass() * (temp_x**2 + temp_z**2) + I[5] -= a.get_mass() * temp_y * temp_z + I[6] -= a.get_mass() * temp_x * temp_z + I[7] -= a.get_mass() * temp_y * temp_z + I[8] += a.get_mass() * (temp_x**2 + temp_y**2) + + global tensor + tensor = numpy.array([(I[0:3]), (I[3:6]), (I[6:9])]) + + global autoval, autovect, ord_autoval, ord_autovect + autoval, autovect = numpy.linalg.eig(tensor) + auto_ord = numpy.argsort(autoval) + ord_autoval = autoval[auto_ord] + ord_autovect_complete = autovect[:, auto_ord].T + ord_autovect = numpy.around(ord_autovect_complete, 3) + + return ord_autoval + + +def draw_inertia_axis(selection): + ''' + DESCRIPTION + + This method draw the inertia axis calculated with the method matriz_inercia. + ''' + + matriz_inercia(selection) + axis1 = ord_autovect[0] + x1, y1, z1 = cM[0], cM[1], cM[2] + x2, y2, z2 = cM[0]+50*axis1[0], cM[1]+50*axis1[1], cM[2]+50*axis1[2] + eje1 = [cgo.CYLINDER, x1, y1, z1, x2, y2, z2, 0.6, 1, 0, 0, 1, 0, 0, 0.0] + cmd.load_cgo(eje1, 'Inertia_Axis1') + axis2 = ord_autovect[1] + x3, y3, z3 = cM[0]+40*axis2[0], cM[1]+40*axis2[1], cM[2]+40*axis2[2] + eje1 = [cgo.CYLINDER, x1, y1, z1, x3, y3, z3, 0.6, 1, 0.5, 0, 1, 0.5, 0, 0.0] + cmd.load_cgo(eje1, 'Inertia_Axis2') + axis4 = ord_autovect[2] + x4, y4, z4 = cM[0]+30*axis4[0], cM[1]+30*axis4[1], cM[2]+30*axis4[2] + eje1 = [cgo.CYLINDER, x1, y1, z1, x4, y4, z4, 0.6, 1, 1, 0, 1, 1, 0, 0.0] + cmd.load_cgo(eje1, 'Inertia_Axis3') + +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 rotacion_orig(selection): + ''' + DESCRIPTION + + Find the proper rotation matrix, i.e. the transpose of the matrix formed by the eigenvectors of the inertia tensor + ''' + + translacion_cM(selection) + matriz_inercia(selection) + global transf, transf_array, ord_autovect_array, transf_array_print + ord_autovect_array = numpy.array([[ord_autovect[0][0], ord_autovect[0][1], ord_autovect[0][2]], + [ord_autovect[1][0], ord_autovect[1][1], ord_autovect[1][2]], + [ord_autovect[2][0], ord_autovect[2][1], ord_autovect[2][2]]]) + if numpy.linalg.det(ord_autovect_array) == -1: + ord_autovect_array = numpy.array([[ord_autovect[2][0], ord_autovect[2][1], ord_autovect[2][2]], + [ord_autovect[1][0], ord_autovect[1][1], ord_autovect[1][2]], + [ord_autovect[0][0], ord_autovect[0][1], ord_autovect[0][2]]]) + transf = numpy.transpose(ord_autovect_array) + transf_array = numpy.array([transf[0][0], transf[0][1], transf[0][2], 0, + transf[1][0], transf[1][1], transf[1][2], 0, + transf[2][0], transf[2][1], transf[2][2], 0, + 0, 0, 0, 1]) + + +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 draw_AABB(selection): + """ + DESCRIPTION + For a given selection, draw the Axes Aligned bounding box around it without padding. Code taken and modified from DrawBoundingBox.py. + + """ + + AA_original = selection + "_original" + model_orig = cmd.create(AA_original, selection) + + ([min_X, min_Y, min_Z],[max_X, max_Y, max_Z]) = cmd.get_extent(AA_original) + + print("The Axis Aligned Bounding Box (AABB) dimensions are (%.2f, %.2f, %.2f)" % (max_X-min_X, max_Y-min_Y, max_Z-min_Z)) + print("The Axis Aligned Bounding Box (AABB) volume is %.2f A3" % ((max_X-min_X)*(max_Y-min_Y)*(max_Z-min_Z))) + + + min_X = min_X + min_Y = min_Y + min_Z = min_Z + max_X = max_X + max_Y = max_Y + max_Z = max_Z + + boundingBox = [ + LINEWIDTH, float(2), + + BEGIN, LINES, + COLOR, float(1), float(1), float(0), + + VERTEX, min_X, min_Y, min_Z, + VERTEX, min_X, min_Y, max_Z, + VERTEX, min_X, max_Y, min_Z, + VERTEX, min_X, max_Y, max_Z, + VERTEX, max_X, min_Y, min_Z, + VERTEX, max_X, min_Y, max_Z, + VERTEX, max_X, max_Y, min_Z, + VERTEX, max_X, max_Y, max_Z, + VERTEX, min_X, min_Y, min_Z, + VERTEX, max_X, min_Y, min_Z, + VERTEX, min_X, max_Y, min_Z, + VERTEX, max_X, max_Y, min_Z, + VERTEX, min_X, max_Y, max_Z, + VERTEX, max_X, max_Y, max_Z, + VERTEX, min_X, min_Y, max_Z, + VERTEX, max_X, min_Y, max_Z, + VERTEX, min_X, min_Y, min_Z, + VERTEX, min_X, max_Y, min_Z, + VERTEX, max_X, min_Y, min_Z, + VERTEX, max_X, max_Y, min_Z, + VERTEX, min_X, min_Y, max_Z, + VERTEX, min_X, max_Y, max_Z, + VERTEX, max_X, min_Y, max_Z, + VERTEX, max_X, max_Y, max_Z, + + END + ] + + p0 = '_0' + str(randint(0, 100)) + p1 = '_1' + str(randint(0, 100)) + p2 = '_2' + str(randint(0, 100)) + p3 = '_3' + str(randint(0, 100)) + cmd.pseudoatom (pos=[min_X, min_Y, min_Z], object=p0) + cmd.pseudoatom (pos=[min_X, min_Y, max_Z], object=p1) + cmd.pseudoatom (pos=[min_X, max_Y, min_Z], object=p2) + cmd.pseudoatom (pos=[max_X, min_Y, min_Z], object=p3) + cmd.distance(None, p0, p3) + cmd.distance(None, p0, p2) + cmd.distance(None, p0, p1) + cmd.hide("nonbonded") + + boxName = "box_AABB_" + str(randint(0, 100)) + cmd.load_cgo(boundingBox,boxName) + return boxName + + +def draw_IABB(selection): + """ + DESCRIPTION + For a given selection, draw the Inertia Axes Aligned bounding box around it without padding. Code taken and modified from DrawBoundingBox.py. + + """ + + transformar(selection) + + ([minX, minY, minZ],[maxX, maxY, maxZ]) = cmd.get_extent(selection) + + print("The Inertia Axis Aligned Bounding Box (IABB) dimensions are (%.2f, %.2f, %.2f)" % (maxX-minX, maxY-minY, maxZ-minZ)) + print("The Inertia Axis Aligned Bounding Box (IABB) volume is %.2f A3" % ((maxX-minX)*(maxY-minY)*(maxZ-minZ))) + + + minX = minX + minY = minY + minZ = minZ + maxX = maxX + maxY = maxY + maxZ = maxZ + + boundingBox = [ + LINEWIDTH, float(2), + + BEGIN, LINES, + COLOR, float(1), float(0), float(0), + + VERTEX, minX, minY, minZ, + VERTEX, minX, minY, maxZ, + VERTEX, minX, maxY, minZ, + VERTEX, minX, maxY, maxZ, + VERTEX, maxX, minY, minZ, + VERTEX, maxX, minY, maxZ, + VERTEX, maxX, maxY, minZ, + VERTEX, maxX, maxY, maxZ, + VERTEX, minX, minY, minZ, + VERTEX, maxX, minY, minZ, + VERTEX, minX, maxY, minZ, + VERTEX, maxX, maxY, minZ, + VERTEX, minX, maxY, maxZ, + VERTEX, maxX, maxY, maxZ, + VERTEX, minX, minY, maxZ, + VERTEX, maxX, minY, maxZ, + VERTEX, minX, minY, minZ, + VERTEX, minX, maxY, minZ, + VERTEX, maxX, minY, minZ, + VERTEX, maxX, maxY, minZ, + VERTEX, minX, minY, maxZ, + VERTEX, minX, maxY, maxZ, + VERTEX, maxX, minY, maxZ, + VERTEX, maxX, maxY, maxZ, + + END + ] + + p4 = '_4' + str(randint(0, 100)) + p5 = '_5' + str(randint(0, 100)) + p6 = '_6' + str(randint(0, 100)) + p7 = '_7' + str(randint(0, 100)) + cmd.pseudoatom (pos=[minX, minY, minZ], object=p4) + cmd.pseudoatom (pos=[minX, minY, maxZ], object=p5) + cmd.pseudoatom (pos=[minX, maxY, minZ], object=p6) + cmd.pseudoatom (pos=[maxX, minY, minZ], object=p7) + cmd.distance(None, p4, p7) + cmd.distance(None, p4, p6) + cmd.distance(None, p4, p5) + cmd.hide("nonbonded") + + boxName = "box_IABB_" + str(randint(0, 100)) + cmd.load_cgo(boundingBox,boxName) + return boxName + + +def draw_BB(selection): + draw_AABB(selection) + draw_IABB(selection) + +def draw_Protein_Dimensions(selection): + draw_IABB(selection) + cmd.hide("cgo") + +cmd.extend ("draw_Protein_Dimensions", draw_Protein_Dimensions) +cmd.extend ("draw_BB", draw_BB) + + + + + + + diff --git a/.pymol/startup/Draw_Protein_Dimensions.pyc b/.pymol/startup/Draw_Protein_Dimensions.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5479534c1c8892d1af1ad4fd17441f3f6ea1a9ef GIT binary patch literal 9483 zcmd5?+j88-5glN8TaXkfk&?(YvEXOKWxVtlro}QVWTc4f= zOaGp#&U6RI((wk9Dpu6~8iPAGpu zh$-by3Nfwx6GEI+{*(}>ls_%RjPg$kF{}JjLY!9qj1Xs3FsAm-Dt}f5XVfz&ojspc z!D)GhCU+`lFvjG%p_FyQt5@4~FAZ$3>DzvowCdi0o$dyp8$mM(qh?}9JGN)H;wTNm z=7MEeo4a9R-m$D^yU{wZE4yjhdV6tEo)(g7*g9B<;@SnMfEJS7s9pE%?ZDn{hxODBn`tD< zHG?PUGw)b5ynWD!>XuchUa)U_+x5tPzwO1o=SMci_&Bnx6{zOhQPVyjHiI|~JvYSw zqj;fpaNcIME0-=`vbPWHTbPb^@)UVB4EBO2$-~gHJ`Agn4&JtJt#4XZ_#gaLFo7yP zfut2fGk2%mtfri>S+EA_kZ_Y-TDY8ipLM9@LM>Oa;-wetTEh$L3)QHRSdh59w0P^v7tDn!Pqp~{0HZM~Ru#884R(JP*ZsckwMy7VACk6nD%4rH3mCPec9gVA_33X^u zhwFGg9OqcBgMA40Feqf`*Hl#wH=hTH`9o?3GR)4-UMsyrsZx)WrDh>HdtH|f4Je%` zN=F8i9@ic1D;?DTSdSFyL&d!Ra!)C>J1(_)O1tZh_mo{Ez-oET_yD?BY4j z32b9oQ&_8EbuL?1OL6VT)!u|kEw11LQ+bohJ0bijl}?g*G)dxcQq6nQJZ7+v`2HGu zXj1K9LH16nBVFT^Iz;gZ?VC5F(rH*Yp33BRNUZYe+MOHD`t8m2k2Wl;yb06R2-4li zx2w7BOT?x$yd<%4$kQOcD2&WZ*xF2pfuvy!!dlRL?A6-=EFg@geh#W>6em`BCyHSg zYvJRdX(vG)Y*>T^`&N{sbr@FfA^1CS)PODPF+x@uyIuc<%t9XFkS9MZGvV69U*I2B{OEvV~LtDuz5;Znuj2KhKv@v0v zmd^?EmC}eYW1KXnjSGgwkNHF6CHds}>!mkJbEst*^TsK&%9%NdAE#14;$PqZBs4-8 zm>WREJdgsbPl_2%9y6Fz7*R9BjjSAY2}YQbvu88ejD=d7g?bqa)a+TbF-(*JxM07) zP7@7-d*I%!s} zQw|QjI%$xAA<{ZYyVOY&{W`(A!3U#GXqg60^q+^<2P4+4lV)}4q*=L6C)5!}3{%)M zPbbvjlsbgJsCCjagj5s#I!%a9K>f^0eu2gBw~}!0GBfF8e|FhJZy$w)@$~H{VY;g= zsJ5%!J9fb;Ym3Cqrp?(EP_-rb`}>azqX%QJ)OuzWm(j=Nkmn~W|J#rI%CCekp}dd1 zv{B*dcV1(1mI-Z(BQ6x}-HrPnu5YZaIodFiQ;$5~t-__)Xom&JJ|;^i8oDl6(Wh!GUny#B9*j z zeq4KRI)`sKj=HsJI+=8r;q<~DmU(92BI1nQk=>Qt!u0f=8USM=mnr%Q+LhqtNjwYW z7D!o< zBf*{S%rp58lkYO&{&09dad^0#mzhvl09smdwLd_nV67|M7qV^XwMlDrT)m>ETfOxg za1!dNM*8s1c*R&VWWVM(Cj0eIy%?6GnaPU`PATm!e>n-8o0G7$@KN~$W-dcAlOcI5 z11gsxnaPmUGMT$OOtTM=!d}AJhi3}_d}ylpRfBxp-B&gByefUw&YBl-9ncy5|WF|xIu}nTF$dJrrNa_+akbO;_II58yG4AICfswu= zb`wsToFjxIT0v~XZSv@0pO3`8p2P8^)Z${1Ti+=CA03MlhtAk%M*>M3=LO zpaISr{1dJ!Os@pXo|z^cNO*P?6@qIjNWBD$rn@oO$M8YZ>@3|J*nqg*M$SjM|%q_1M{}CM| z95%uCB|V$m4b)g>^B%SZrU+Aamh+_}H9A-W=rM(Z`8Bfp@`H|$4QX+q=?@FiAy@$~ zdJf(*A{ui5ID|9ic1r3D&X_?F3FLH$%w{sPB7p)O*g;4LHQ}P8K?YSuB?>eqj`t9) z8B7_P#OB3i4mTrm#Kd(GxS2x+L7UvMKc-Pd^Pws1WI<~_dK3l7*L1-z@KdalzOZoyw ze@jfQ++f^Gp$~?p_1(zTS08r?wg#bY1ixtdqU}9~eK@RU)ZC5`Z}H^`Q|MB6ccVh! z)HgHMsKx={K#V-2R|wA_J_p;9h1{hwZgXpQ*H<@xBK#d(=Cs7h+WYGp!lT3;p>BNi z;YW_>^68qhxpq&~TiaNbJV|3`2u(|Ott4psXetYm;mt_uHLC$|48gXjsfpdt51fnO zNH9tx3GM#!a- z{YVLu1;wO6Z0wAN!kUJr;+>N(cuYQ2EaWw<dKP`5 z&Hnav-J;FTehb|?+v(}6XtU5?10({1=u4v-=1`)30+6`$14RcE08$I&?5Y7sEs(RT z0F7WX0U!~9(<&k)fPEwHgPsw?dWsQc)5QoB^cKrtv*HY1i`p2Q%u80B!7GY^h6w7x zZ_A*slZ8fzhMg>Qo3Q|p^7h2Q>*GO_fmbf52!I4`>qsE7I~7KIlHVgK(C2>v$SisX zi27E6GTDIQ#Ixi6zZ4?ZVZNRRB6(BzT1`G5RKD2(m2YXpysEQn&TVw*e9Xi_BG^V? zq{cZge!x=NLFW@DpE9}2UEkNWQ|!qU46YX+8q!`~t}fzR>eVF4(-Xvc>t}3M#~P z1u?rcWr(j!Q(W1BhT>3DSq^DKLgn&4QIysDjXUK9tIgQFsNMha>x<4|IL{#H{E`aD zOmn!d>qk}B74OQ$e_o{RIB;E_8|}Wie37^t#So#_RlKNlCatPHM5>qP>hmDvKZM zAD;%HzCpO3gLnr{CgRHP(t%Fc;D|X5FHAn?&tNx97}I9?YWYlgwmes!EdR9pL3yY= HG;RDB)Ea6L literal 0 HcmV?d00001 diff --git a/.pymol/startup/axes.py b/.pymol/startup/axes.py new file mode 100644 index 0000000..bc2e0a4 --- /dev/null +++ b/.pymol/startup/axes.py @@ -0,0 +1,68 @@ +from pymol import cmd +from chempy import cpv + +class PutCenterCallback(object): + prev_v = None + + def __init__(self, name, corner=0): + self.name = name + self.corner = corner + self.cb_name = cmd.get_unused_name('_cb') + + def load(self): + cmd.load_callback(self, self.cb_name) + + def __call__(self): + if self.name not in cmd.get_names('objects'): + import threading + threading.Thread(None, cmd.delete, args=(self.cb_name,)).start() + return + + v = cmd.get_view() + if v == self.prev_v: + return + self.prev_v = v + + t = v[12:15] + + if self.corner: + vp = cmd.get_viewport() + R_mc = [v[0:3], v[3:6], v[6:9]] + off_c = [0.15 * v[11] * vp[0] / vp[1], 0.15 * v[11], 0.0] + if self.corner in [2,3]: + off_c[0] *= -1 + if self.corner in [3,4]: + off_c[1] *= -1 + off_m = cpv.transform(R_mc, off_c) + t = cpv.add(t, off_m) + + z = -v[11] / 30.0 + m = [z, 0, 0, t[0] / z, 0, z, 0, t[1] / z, 0, 0, z, t[2] / z, 0, 0, 0, 1] + cmd.set_object_ttt(self.name, m, homogenous=1) + +def axes(name='axes'): + ''' +DESCRIPTION + + Puts coordinate axes to the lower left corner of the viewport. + ''' + from pymol import cgo + + cmd.set('auto_zoom', 0) + + w = 0.06 # cylinder width + l = 0.75 # cylinder length + h = 0.25 # cone hight + d = w * 1.618 # cone base diameter + + obj = [cgo.CYLINDER, 0.0, 0.0, 0.0, l, 0.0, 0.0, w, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, + cgo.CYLINDER, 0.0, 0.0, 0.0, 0.0, l, 0.0, w, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, + cgo.CYLINDER, 0.0, 0.0, 0.0, 0.0, 0.0, l, w, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, + cgo.CONE, l, 0.0, 0.0, h+l, 0.0, 0.0, d, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, + cgo.CONE, 0.0, l, 0.0, 0.0, h+l, 0.0, d, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, + cgo.CONE, 0.0, 0.0, l, 0.0, 0.0, h+l, d, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0] + + PutCenterCallback(name, 1).load() + cmd.load_cgo(obj, name) + +cmd.extend('axes', axes) diff --git a/.pymol/startup/axes.pyc b/.pymol/startup/axes.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79df3208b2cfd6f6a4e7c033e6d5ba0149714629 GIT binary patch literal 2798 zcmb7G&u<$=6n?XI?AUP{_eWYHA>{I_MnH4m1ge?}w}(pLmQ9Ojq-y1O$BrG_YweEH zAF>Z9<=@~>;M_ZR;L4c`5*H*62yuY#d$UcN!l7Mz#&2fcd-G=A`@VJIkJakmUuR!+ zC4UO|y@r;3i7v+1$Vg;tWXFi%IFL~w#&(n7lo6Ejw{GZFNSY-A;G^D9Qk< zpQ2?SptHi@5CTH-5p(Y%Lq$*wsGveg!tLe~38gbb7M_%3@B(&k<=wwt@1nN2q@Palnw(Prj4shdqVI}dG!DaVVAqQPX~ zqKF%0j6_TYpDwSOjhpFlFFG_Jq&z?cseS!H7> zdZ;`lJ=XA>@iN7SScOza(-40|9E=QsqK<+*3;ShBKWBE4h*3cnH~>~PFH|cr-?S>T zG7keYTxMmmc(=J;;b?*MYKDhZ*$*TgX;$;3SGk6ILfKwicwZ}$-ZiwYsdZ5`uv1ws zQWqt@?4@OiD{`@quuym2(TZ%Go5Ncv|Ea|k(~^V6I=_52*oYtpaFqN2H~=Xsk~BtFe0nfkRdd;z# z0Gp(5C&?^R(0Vnx^+Vl&R!vflM;`=nx*t$WxMn(Xd#UZjgGpZzen&?dcsrSR)W>#Y zomFr+LRbN+uq6Hu2KIrPPE&gj9Vo~h&--j~nxrn|q5O7fXOi`jbgVSfiDP$)F5$@E zT;!Z<@`MV(kf=e0iX3R~KwOZg8ekZWyBbi^>qW=XST!GOKYn!#d%7VdL=iKlY%JzA zQ#0?FVo)<{rf4d`YEZ$<+h!Bvv)ay>^kg6Y=mKW1`6SM zcFae}w1;n@JC0VRmt@G0cfw?6jJ;$^L2ap0@WlrXRgz>#_t9EZ`xX}p?&n)i-+~|; zlfMxFfg%xQKog)7AOKteCRliKSeA33fSj3t0{s#!t z*Uyzt>QfoP9PN$}3vwY31w?gH+s|`95SUte*SY?YF=*ykRgaa&c+&EJjE^l}*jX+6 z_eqC93RoO8g*yh9AA-Vp^I$7o(3`K}UB!1(b{Ads`i<>Yc=Pt1o44B4Y6B1cKxB<> zlB57_$JqwolMR3K|&OE<96Mow2U-)Ff^JN>?;^wn;%t`(d5P7g0(=wG^I zCZJv6(Yp89&Gz*hp_XdvR{Mrlvcf^v{mZ$ZD4;xv(UBtif%YTq_q30dQNSX{D0*1{ zy$i4JGqBguNvR&x1HcHMYVe`q=M#Lc1!sY6LM(ib9aa6mqCGpFKJpYtQujpW&qB|t hWFI;^iH}25=_TXS%edm%<0{EefnGQD;QXc9#=p90`5gcN literal 0 HcmV?d00001 diff --git a/.pymol/startup/center_of_mass.py b/.pymol/startup/center_of_mass.py new file mode 100644 index 0000000..e9b103f --- /dev/null +++ b/.pymol/startup/center_of_mass.py @@ -0,0 +1,86 @@ +''' +See more here: http://www.pymolwiki.org/index.php/center_of_mass + +DESCRIPTION + + Places a pseudoatom at the center of mass + + Author: Sean Law + Michigan State University + slaw (at) msu . edu + +SEE ALSO + + pseudoatom, get_com +''' + +from __future__ import print_function +from pymol import cmd + + +def com(selection, state=None, mass=None, object=None, quiet=1, **kwargs): + quiet = int(quiet) + if (object == None): + try: + object = cmd.get_legal_name(selection) + object = cmd.get_unused_name(object + "_COM", 0) + except AttributeError: + object = 'COM' + 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) + +cmd.extend("com", com) + + +def get_com(selection, state=1, mass=None, quiet=1): + """ + DESCRIPTION + + Calculates the center of mass + + Author: Sean Law + Michigan State University + slaw (at) msu . edu + """ + quiet = int(quiet) + + totmass = 0.0 + if mass != None and not quiet: + print("Calculating mass-weighted COM") + + state = int(state) + model = cmd.get_model(selection, state) + x, y, z = 0, 0, 0 + for a in model.atom: + if (mass != None): + m = a.get_mass() + x += a.coord[0] * m + y += a.coord[1] * m + z += a.coord[2] * m + totmass += m + else: + x += a.coord[0] + y += a.coord[1] + z += a.coord[2] + + if (mass != None): + return x / totmass, y / totmass, z / totmass + else: + return x / len(model.atom), y / len(model.atom), z / len(model.atom) + +cmd.extend("get_com", get_com) + +# vi:expandtab:sw=3 diff --git a/.pymol/startup/center_of_mass.pyc b/.pymol/startup/center_of_mass.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a853fa8aaa6540a4cd087ac8cc7eac15135822ea GIT binary patch literal 2408 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 literal 0 HcmV?d00001 diff --git a/.pymol/startup/dssp_stride.py b/.pymol/startup/dssp_stride.py new file mode 100644 index 0000000..20c2def --- /dev/null +++ b/.pymol/startup/dssp_stride.py @@ -0,0 +1,981 @@ +""" 2011_04_11: Hongbo Zhu + PyMOL plugin for running DSSP and display SS using different colors. + The DSSP codes for secondary structure are: + + H - Alpha helix (4-12) + G - 3-10 helix + I - pi helix + E - Strand + B - Isolated beta-bridge residue + T - Turn + S - Bend + - - None + 2011_04_24: add stride + STRIDE code (taken from stride.doc) is nearly the same as DSSP + H Alpha helix + G 3-10 helix + I PI-helix + E Extended conformation + B or b Isolated bridge + T Turn + C Coil (none of the above) +""" + +# Copyright Notice +# ================ +# +# The PyMOL Plugin source code in this file is copyrighted, but you can +# freely use and copy it as long as you don't change or remove any of +# the copyright notices. +# +# ---------------------------------------------------------------------- +# This PyMOL Plugin is Copyright (C) 2011 by +# Hongbo Zhu +# +# All Rights Reserved +# +# Permission to use, copy, modify, distribute, and distribute modified +# versions of this software and its documentation for any purpose and +# without fee is hereby granted, provided that the above copyright +# notice appear in all copies and that both the copyright notice and +# this permission notice appear in supporting documentation, and that +# the name(s) of the author(s) not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# THE AUTHOR(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN +# NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# ---------------------------------------------------------------------- + +# python lib +import os +import sys +import platform +if sys.version_info >= (2,4): + import subprocess # subprocess is introduced in python 2.4 +import math +import random +import tempfile +import tkSimpleDialog +import tkMessageBox +import tkFileDialog +import tkColorChooser + +import Tkinter + +# pymol lib +try: + from pymol import cmd + from pymol.cgo import * +except ImportError: + print 'Warning: pymol library cmd not found.' + sys.exit(1) + +# external lib +try: + import Pmw +except ImportError: + print 'Warning: failed to import Pmw. Exit ...' + sys.exit(1) + +VERBOSE = True + +################# +## here we go +################# +def __init__(self): + """ DSSP and Stride plugin for PyMol + """ + self.menuBar.addmenuitem('Plugin', 'command', + 'DSSP & Stride', label = 'DSSP & Stride', + command = lambda s=self : DSSPPlugin(s)) + + +################# +## GUI related +################# +class DSSPPlugin: + + def __init__(self, app): + + self.parent = app.root + self.dialog = Pmw.Dialog(self.parent, + buttons = ('Run DSSP', + 'Run Stride', + 'Update Color', + 'Update ss', + 'Exit'), + title = 'DSSP and Stride Plugin for PyMOL', + command = self.execute) + Pmw.setbusycursorattributes(self.dialog.component('hull')) + + # parameters used by DSSP + self.pymol_sel = Tkinter.StringVar() + self.dssp_bin = Tkinter.StringVar() + self.stride_bin = Tkinter.StringVar() + self.dssp_rlt_dict = {} + self.stride_rlt_dict = {} + self.ss_asgn_prog = None # which program is used to assign ss + + self.sel_obj_list = [] # there may be more than one seletion or object + # defined by self.pymol_sel + # treat each selection and object separately + if 'DSSP_BIN' not in os.environ and 'PYMOL_GIT_MOD' in os.environ: + if sys.platform.startswith('linux') and platform.machine() == 'x86_32': + initialdir_dssp = os.path.join(os.environ['PYMOL_GIT_MOD'],"DSSP","i86Linux2","dssp-2") + os.environ['DSSP_BIN'] = initialdir_dssp + elif sys.platform.startswith('linux') and platform.machine() == 'x86_64': + initialdir_dssp = os.path.join(os.environ['PYMOL_GIT_MOD'],"DSSP","ia64Linux2","dssp-2") + os.environ['DSSP_BIN'] = initialdir_dssp + elif sys.platform.startswith('win'): + initialdir_dssp = os.path.join(os.environ['PYMOL_GIT_MOD'],"DSSP","win32","dssp.exe") + os.environ['DSSP_BIN'] = initialdir_dssp + else: + pass + if 'DSSP_BIN' in os.environ: + if VERBOSE: print 'Found DSSP_BIN in environmental variables', os.environ['DSSP_BIN'] + self.dssp_bin.set(os.environ['DSSP_BIN']) + else: + if VERBOSE: print 'DSSP_BIN not found in environmental variables.' + self.dssp_bin.set('') + if 'STRIDE_BIN' not in os.environ and 'PYMOL_GIT_MOD' in os.environ: + if sys.platform.startswith('linux') and platform.machine() == 'x86_32': + initialdir_stride = os.path.join(os.environ['PYMOL_GIT_MOD'],"Stride","i86Linux2","stride") + os.environ['STRIDE_BIN'] = initialdir_stride + elif sys.platform.startswith('linux') and platform.machine() == 'x86_64': + initialdir_stride = os.path.join(os.environ['PYMOL_GIT_MOD'],"Stride","ia64Linux2","stride") + os.environ['STRIDE_BIN'] = initialdir_stride + elif sys.platform.startswith('win'): + initialdir_stride = os.path.join(os.environ['PYMOL_GIT_MOD'],"Stride","win32","stride.exe") + os.environ['STRIDE_BIN'] = initialdir_stride + else: + pass + if 'STRIDE_BIN' in os.environ: + if VERBOSE: print 'Found STRIDE_BIN in environmental variables', os.environ['STRIDE_BIN'] + self.stride_bin.set(os.environ['STRIDE_BIN']) + else: + if VERBOSE: print 'STRIDE_BIN not found in environmental variables.' + self.stride_bin.set('') + + # DSSP visualization color + # - H Alpha helix (4-12) + # - G 3-10 helix + # - I pi helix + # + # - E Extended strand + # - B Isolated beta-bridge residue + # + # - T Turn + # - S Bend + # - - None + # STRIDE does not have S and None, but it has two more + # codes: 'b' same as 'B' and 'C' for coil + self.DSSP_SSE_list = ['H','G','I', 'E','B','T','S','-'] # for the record of the order + self.STRIDE_SSE_list = ['H','G','I', 'E','B','b','T','C'] # for the record of the order + self.SSE_map = {'H':'H', + 'G':'H', + 'I':'H', + 'E':'S', + 'B':'S', + 'T':'L', + 'S':'L', + '-':'L', + + 'b':'S', + 'C':'L' + } + self.SSE_name = { + 'H' : 'Alpha helix', + 'G' : '3-10 helix', + 'I' : 'Pi helix', + + 'E' : 'Extended strand', + 'B' : 'Isolated beta-bridge', + + 'T' : 'Turn', + 'S' : 'Bend', + '-' : 'None', + + 'b' : 'Isolated beta-bridge', + 'C' : 'Coil' + } + + self.SSE_col_RGB = { + 'H':(255, 0, 0), + 'G':(255, 0,128), + 'I':(255,170,170), + + 'E':(255,255, 0), + 'B':(153,119, 85), + + 'T':( 0,255,255), + 'S':(153,255,119), + '-':(179,179,179), + + 'b':(153,119, 85), # same as 'B' + 'C':( 0, 0,255) + } + self.SSE_col = {} + for sse in self.SSE_col_RGB.keys(): + self.SSE_col[sse] = '#%s%s%s' % (hex(self.SSE_col_RGB[sse][0])[2:].zfill(2), + hex(self.SSE_col_RGB[sse][1])[2:].zfill(2), + hex(self.SSE_col_RGB[sse][2])[2:].zfill(2)) + + self.SSE_res_dict = {} + self.SSE_sel_dict = {} + + w = Tkinter.Label(self.dialog.interior(), +# text = '\nDSSP Plugin for PyMOL\nHongbo Zhu, 2011.\n\nColor proteins according to the secondary structure determined by DSSP.', + text = '\nDSSP and Stride Plugin for PyMOL\nby Hongbo Zhu, 2011\n', + background = 'black', foreground = 'green' + ) + w.pack(expand = 1, fill = 'both', padx = 10, pady = 5) + + # make a few tabs within the dialog + self.notebook = Pmw.NoteBook(self.dialog.interior()) + self.notebook.pack(fill = 'both', expand=1, padx=10, pady=10) + + + ###################### + # Tab : Structure Tab + ###################### + page = self.notebook.add('Structure') + self.notebook.tab('Structure').focus_set() + group_struc = Tkinter.LabelFrame(page, text = 'Structure') + group_struc.pack(fill='both', expand=True, padx=10, pady=5) + + pymol_sel_ent = Pmw.EntryField(group_struc, + label_text='PyMOL selection/object:', + labelpos='wn', + entry_textvariable=self.pymol_sel + ) + + dssp_bin_ent = Pmw.EntryField(group_struc, + label_text='DSSP binary:', labelpos='wn', + entry_textvariable=self.dssp_bin, + entry_width=20) + dssp_bin_but = Tkinter.Button(group_struc, text = 'Browse...', + command = self.getDSSPBin) + + stride_bin_ent = Pmw.EntryField(group_struc, + label_text='Stride binary:', labelpos='wn', + entry_textvariable=self.stride_bin, + entry_width=20) + stride_bin_but = Tkinter.Button(group_struc, text = 'Browse...', + command = self.getStrideBin) + + # arrange widgets using grid + pymol_sel_ent.grid(sticky='we', row=0, column=0, + columnspan=2, padx=5, pady=5) + dssp_bin_ent.grid(sticky='we', row=1, column=0, padx=5, pady=1) + dssp_bin_but.grid(sticky='we', row=1, column=1, padx=5, pady=1) + stride_bin_ent.grid(sticky='we', row=2, column=0, padx=5, pady=1) + stride_bin_but.grid(sticky='we', row=2, column=1, padx=5, pady=1) + group_struc.columnconfigure(0, weight=9) + group_struc.columnconfigure(1, weight=1) + + + ###################### + # Tab : Color Tab + ###################### + # H = alpha helix + # G = 3-helix (3/10 helix) + # I = 5 helix (pi helix) + + # E = extended strand, participates in beta ladder + # B = residue in isolated beta-bridge + + # T = hydrogen bonded turn + # S = bend + # + # H Alpha helix (4-12) + # G 3-10 helix + # I pi helix + # E Strand + # B Isolated beta-bridge residue + # T Turn + # S Bend + # - None + + page = self.notebook.add('Color') + + group_sse_color = Tkinter.LabelFrame(page, text = 'Secondary Structure Element Color') + group_sse_color.grid(sticky='eswn', row=0, column=0, padx=10, pady=5) + + # colors for DSSP surface + H_col_lab = Tkinter.Label(group_sse_color, text='Alpha helix (H):') + self.H_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['H'], + activebackground=self.SSE_col['H'], + command = self.custermizeHColor) + G_col_lab = Tkinter.Label(group_sse_color, text='3-10 helix (G):') + self.G_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['G'], + activebackground=self.SSE_col['G'], + command = self.custermizeGColor) + I_col_lab = Tkinter.Label(group_sse_color, text='PI helix (I):') + self.I_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['I'], + activebackground=self.SSE_col['G'], + command = self.custermizeIColor) + + + E_col_lab = Tkinter.Label(group_sse_color, text='Extended strand (E):') + self.E_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['E'], + activebackground=self.SSE_col['E'], + command = self.custermizeEColor) + B_col_lab = Tkinter.Label(group_sse_color, text='Isolated beta-bridge (B):') + self.B_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['B'], + activebackground=self.SSE_col['B'], + command = self.custermizeBColor) + + T_col_lab = Tkinter.Label(group_sse_color, text='Turn (T):') + self.T_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['T'], + activebackground=self.SSE_col['T'], + command = self.custermizeTColor) + S_col_lab = Tkinter.Label(group_sse_color, text='Bend (DSSP S):') + self.S_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['S'], + activebackground=self.SSE_col['S'], + command = self.custermizeSColor) + N_col_lab = Tkinter.Label(group_sse_color, text='None (DSSP NA):') + self.N_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['-'], + activebackground=self.SSE_col['-'], + command = self.custermizeNColor) + + + b_col_lab = Tkinter.Label(group_sse_color, text='Isolated beta-bridge (Stride b):') + self.b_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['b'], + activebackground=self.SSE_col['b'], + command = self.custermizebColor) + + C_col_lab = Tkinter.Label(group_sse_color, text='Coil (Stride C):') + self.C_col_but = Tkinter.Button(group_sse_color, + bg=self.SSE_col['C'], + activebackground=self.SSE_col['C'], + command = self.custermizeCColor) + + + + H_col_lab.grid(sticky='e', row=0, column=0, padx=5, pady=3) + self.H_col_but.grid(sticky='we', row=0, column=1, padx=5, pady=3) + G_col_lab.grid(sticky='e', row=1, column=0, padx=5, pady=3) + self.G_col_but.grid(sticky='we', row=1, column=1, padx=5, pady=3) + I_col_lab.grid(sticky='e', row=2, column=0, padx=5, pady=3) + self.I_col_but.grid(sticky='we', row=2, column=1, padx=5, pady=3) + + E_col_lab.grid(sticky='e', row=0, column=2, padx=5, pady=3) + self.E_col_but.grid(sticky='we', row=0, column=3, padx=5, pady=3) + B_col_lab.grid(sticky='e', row=1, column=2, padx=5, pady=3) + self.B_col_but.grid(sticky='we', row=1, column=3, padx=5, pady=3) + + T_col_lab.grid(sticky='e', row=0, column=4, padx=5, pady=3) + self.T_col_but.grid(sticky='we', row=0, column=5, padx=5, pady=3) + S_col_lab.grid(sticky='e', row=1, column=4, padx=5, pady=3) + self.S_col_but.grid(sticky='we', row=1, column=5, padx=5, pady=3) + N_col_lab.grid(sticky='e', row=2, column=4, padx=5, pady=3) + self.N_col_but.grid(sticky='we', row=2, column=5, padx=5, pady=3) + + b_col_lab.grid(sticky='e', row=2, column=2, padx=5, pady=3) + self.b_col_but.grid(sticky='we', row=2, column=3, padx=5, pady=3) + + C_col_lab.grid(sticky='e', row=3, column=4, padx=5, pady=3) + self.C_col_but.grid(sticky='we', row=3, column=5, padx=5, pady=3) + ###################### + # Tab : About Tab + ###################### + page = self.notebook.add('About') + group_about = Tkinter.LabelFrame(page, text = 'About DSSP and Stride Plugin for PyMOL') + group_about.grid(sticky='we', row=0,column=0,padx=5,pady=3) + about_plugin = """ Assign and color secondary structures using DSSP or Stride. +by Hongbo Zhu +Please cite this plugin if you use it in a publication. +Hongbo Zhu. DSSP and Stride plugin for PyMOL, 2011, BIOTEC, TU Dresden. +""" + + label_about = Tkinter.Label(group_about,text=about_plugin) + label_about.grid(sticky='we', row=0, column=0, padx=5, pady=10) + + self.notebook.setnaturalsize() + + return + + + def getDSSPBin(self): + dssp_bin_fname = tkFileDialog.askopenfilename( + title='DSSP Binary', initialdir='', + filetypes=[('all','*')], parent=self.parent) + if dssp_bin_fname: # if nonempty + self.dssp_bin.set(dssp_bin_fname) + return + + def getStrideBin(self): + stride_bin_fname = tkFileDialog.askopenfilename( + title='Stride Binary', initialdir='', + filetypes=[('all','*')], parent=self.parent) + if stride_bin_fname: # if nonempty + self.stride_bin.set(stride_bin_fname) + return + + def runDSSPOneObj(self, one_obj_sel): + """ Run DSSP on only one object. + + @param one_obj_sel: the selection/object involving only one object + @param type: string + """ + SSE_res = { + 'H':{}, 'G':{}, 'I':{}, + 'E':{}, 'B':{}, + 'T':{}, 'S':{}, '-':{} + } + SSE_sel = { + 'H':None, 'G':None, 'I':None, + 'E':None, 'B':None, + 'T':None, 'S':None, '-':None + } + + pdb_fn = None + pdb_os_fh, pdb_fn = tempfile.mkstemp(suffix='.pdb') # file os handle, file name + os.close(pdb_os_fh) + # DSSP 2.0.4 ignores all residues after 1st TER in the same chain + v = cmd.get(name='pdb_use_ter_records') + if v: cmd.set(name='pdb_use_ter_records', value=0) # do not insert TER into the pdb + cmd.save(filename=pdb_fn, selection=one_obj_sel) + if v: cmd.set(name='pdb_use_ter_records', value=v) # restore old value + + if VERBOSE: + print 'Selection %s saved to %s.' % (one_obj_sel, pdb_fn) + + if pdb_fn is None: + print 'WARNING: DSSP has no pdb file to work on!' + return None + + print 'Running DSSP for %s ...' % (one_obj_sel,) + dssp_sse_dict = {} + if sys.version_info >= (2,4): + dssp_proc = subprocess.Popen([self.dssp_bin.get(), pdb_fn], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + dssp_stdout, dssp_stderr = dssp_proc.communicate() + else: # use os.system + tempfile + dssp_tmpout_os_fh, dssp_tmpout_fn = tempfile.mkstemp(suffix='.dssp') + os.close(dssp_tmpout_os_fh) + dssp_cmd = '%s %s > %s' % (self.dssp_bin.get(), pdb_fn, dssp_tmpout_fn) + os.system(dssp_cmd) + fh = open(dssp_tmpout_fn) + dssp_stdout = ''.join(fh.readlines()) + fh.close() + + sse_started = False + for line in dssp_stdout.splitlines(): + if line.startswith(' # RESIDUE'): + sse_started = True + continue + elif line.startswith(' !!!'): + sse_started = False + continue + elif sse_started: + if len(line) < 10 or line[9] == ' ': continue + ch,resname = line[11],line[13] + residen,sscode = line[5:11].strip(),line[16] # residen = resnum+icode, col 10 is for icode + if sscode == ' ': sscode = '-' + k = (ch,resname,residen) + dssp_sse_dict[k] = sscode + + self.dssp_rlt_dict[one_obj_sel] = dssp_sse_dict + print 'Got SSE for %d residues.' % (len(self.dssp_rlt_dict[one_obj_sel]),) + + # group residues according to their SSE, and chain name + for k in self.dssp_rlt_dict[one_obj_sel].keys(): + #res = '/%s//%s/%d%s/' % (sel,k[0],k[1][1], k[1][2].strip()) # sel name, chain ID, res serial num, icode + sse = self.dssp_rlt_dict[one_obj_sel][k] + chn = k[0] + res = k[2] + if VERBOSE: print '(%s) and \"%s\"/%s/ sse=%s' % (str(one_obj_sel), + chn.strip(), res, sse) + SSE_res[sse].setdefault(chn,[]).append(res) + + self.SSE_res_dict[one_obj_sel] = SSE_res + + for sse in self.DSSP_SSE_list: + sse_sel_name = self.selectSSE(one_obj_sel, sse) + SSE_sel[sse] = sse_sel_name + + self.SSE_sel_dict[one_obj_sel] = SSE_sel + + print '\nNumber of residues with SSE element:' + for sse in self.DSSP_SSE_list: + num = sum([len(SSE_res[sse][chn]) for chn in SSE_res[sse]]) + print '%20s (%s) : %5d' % (self.SSE_name[sse], sse, num) + print + + # clean up pdb_fn and dssp_tmpout_fn created by tempfile.mkstemp() + if os.path.isfile(pdb_fn): + os.remove(pdb_fn) + if sys.version_info < (2,4) and os.path.isfile(dssp_tmpout_fn): + os.remove(dssp_tmpout_fn) + + return + + + def runDSSP(self): + """ + @return: whether DSSP has been executed successfully + @rtype: boolean + """ + # delete old results + self.sel_obj_list = [] + self.dssp_rlt_dict = {} + self.SSE_res_dict = {} + self.SSE_sel_dict = {} + + pdb_fn = None + sel_name= None + sel = self.pymol_sel.get() + + if len(sel) > 0: # if any pymol selection/object is specified + # save the pymol selection/object in the tmp dir + all_sel_names = cmd.get_names('all') # get names of all selections + if sel in all_sel_names: + if cmd.count_atoms(sel) == 0: + err_msg = 'ERROR: The selection %s is empty.' % (sel,) + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + return False + else: + sel_name = sel + # no selection/object with the input name is found + # we assume either a single-word selector or + # some other selection-expression is used + # NOTE: if more than one selection is selected, they should be + # saved separately and SSE should be calculated for each + # of the selections. + else: + print 'The selection/object you specified is not found.' + print 'Your input will be interpreted as a selection-expression.' + # check whether the selection is empty + tmpsel = self.randomSeleName(prefix='your_sele_') + cmd.select(tmpsel,sel) + if cmd.count_atoms(tmpsel) == 0: + cmd.delete(tmpsel) + err_msg = 'ERROR: The selection %s is empty.' % (sel,) + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + return False + else: + sel_name = tmpsel + else: # what structure do you want DSSP to work on? + err_msg = 'No PyMOL selection/object specified!' + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + return False + + # each object in the selection is treated as an independent struc + objlist = cmd.get_object_list(sel_name) + self.ss_asgn_prog = 'DSSP' + print 'Starting %s ...' % (self.ss_asgn_prog, ) + + for objname in objlist: + self.sel_obj_list.append('%s and %s' % (sel_name, objname)) + self.runDSSPOneObj(self.sel_obj_list[-1]) + +## cmd.delete(tmpsel) + + return True + + + def runStrideOneObj(self, one_obj_sel): + """ Run Stride on only one object. + + @param one_obj_sel: the selection/object involving only one object + @param type: string + """ + SSE_res = { + 'H':{}, 'G':{}, 'I':{}, + 'E':{}, 'B':{}, 'b':{}, + 'T':{}, 'C':{} + } + SSE_sel = { + 'H':None, 'G':None, 'I':None, + 'E':None, 'B':None, 'b':None, + 'T':None, 'C':None + } + + pdb_fn = None + pdb_os_fh, pdb_fn = tempfile.mkstemp(suffix='.pdb') # file os handle, file name + os.close(pdb_os_fh) + cmd.save(filename=pdb_fn, selection=one_obj_sel) + if VERBOSE: + print 'Selection %s saved to %s.' % (one_obj_sel, pdb_fn) + + if pdb_fn is None: + print 'WARNING: Stride has no pdb file to work on!' + return None + + print 'Running Stride for %s ...' % (one_obj_sel,) + stride_sse_dict = {} + if sys.version_info >= (2,4): + stride_proc = subprocess.Popen([self.stride_bin.get(), pdb_fn], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT + ) + stride_stdout, stride_stderr = stride_proc.communicate() + else: # use os.system + tempfile + stride_tmpout_os_fh, stride_tmpout_fn = tempfile.mkstemp(suffix='.stride') + os.close(stride_tmpout_os_fh) + stride_cmd = '%s %s > %s' % (self.stride_bin.get(), pdb_fn, stride_tmpout_fn) + os.system(stride_cmd) + fh = open(stride_tmpout_fn) + stride_stdout = ''.join(fh.readlines()) + fh.close() + + for line in stride_stdout.splitlines(): + if line.startswith('ASG'): + resname,ch=line[5:8], line[9] + # according to stride doc, col 12-15 are used for residue number + # actually, resnum+icode is used in 12-15. + # In addition, if residue number is 4-digit or longer, + # the field 12-16 or more are used. + + if line[15] == ' ': # col 16 is not occupied + residen, sscode = line[11:15].strip(),line[24] # residen = resnum+icode + else: + shift = line[15:].find(' ') # find where residen stops + residen, sscode = line[11:15+shift].strip(),line[24+shift] + + k = (ch,resname,residen) + stride_sse_dict[k] = sscode + + self.stride_rlt_dict[one_obj_sel] = stride_sse_dict + print 'Got SSE for %d residues.' % (len(self.stride_rlt_dict[one_obj_sel]),) + + # group residues according to their SSE, and chain name + for k in self.stride_rlt_dict[one_obj_sel].keys(): + sse=self.stride_rlt_dict[one_obj_sel][k] + chn = k[0] # this can be a space! + res = k[2] + if VERBOSE: print '(%s) and \"%s\"/%s/ sse=%s' % (str(one_obj_sel), + chn.strip(), res, sse) + SSE_res[sse].setdefault(chn,[]).append(res) + + self.SSE_res_dict[one_obj_sel] = SSE_res + + for sse in self.STRIDE_SSE_list: + sse_sel_name = self.selectSSE(one_obj_sel, sse) + SSE_sel[sse] = sse_sel_name + self.SSE_sel_dict[one_obj_sel] = SSE_sel + + print '\nNumber of residues with SSE element:' + for sse in self.STRIDE_SSE_list: + num = sum([len(SSE_res[sse][chn]) for chn in SSE_res[sse]]) + print '%20s (%s) : %5d' % (self.SSE_name[sse], sse, num) + print + + # clean up pdb_fn and dssp_tmpout_fn created by tempfile.mkstemp() + if os.path.isfile(pdb_fn): + os.remove(pdb_fn) + if sys.version_info < (2,4) and os.path.isfile(stride_tmpout_fn): + os.remove(stride_tmpout_fn) + + return True + + + def runStride(self): + """ + """ + # delete old results + self.sel_obj_list = [] + self.stride_rlt_dict = {} + self.SSE_res_dict = {} + self.SSE_sel_dict = {} + + pdb_fn = None + sel_name= None + sel = self.pymol_sel.get() + + if len(sel) > 0: # if any pymol selection/object is specified + all_sel_names = cmd.get_names('all') # get names of all selections + if sel in all_sel_names: + if cmd.count_atoms(sel) == 0: + err_msg = 'ERROR: The selection %s is empty.' % (sel,) + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + return False + else: + sel_name = sel + # no selection/object with the input name is found + # we assume either a single-word selector or + # some other selection-expression is uesd + else: + print 'The selection/object you specified is not found.' + print 'Your input will be interpreted as a selection-expression.' + tmpsel = self.randomSeleName(prefix='your_sele_') + cmd.select(tmpsel,sel) + if cmd.count_atoms(tmpsel) == 0: + cmd.delete(tmpsel) + err_msg = 'ERROR: The selection %s is empty.' % (sel,) + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + return False + else: + sel_name = tmpsel + + else: # what structure do you want Stride to work on? + err_msg = 'No PyMOL selection/object specified!' + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + return False + + # each object in the selection is treated as an independent struc + objlist = cmd.get_object_list(sel_name) + self.ss_asgn_prog = 'Stride' + print 'Starting %s ...' % (self.ss_asgn_prog, ) + + for objname in objlist: + self.sel_obj_list.append('%s and %s' % (sel_name, objname)) + self.runStrideOneObj(self.sel_obj_list[-1]) + + return True + + + def randomSeleName(self, prefix='sele',suffix=''): + """ generate a random selection name. + """ + sel_list = cmd.get_names('all') + sel_dict = dict(zip(sel_list, range(len(sel_list)))) + sel_name = '%s%d%s' % (prefix, random.randint(1000,9999), suffix) + while(sel_name in sel_dict): + sel_name = '%s%d%s' % (prefix, random.randint(1000,9999), suffix) + + return sel_name + + + def selectSSE(self, sel, sse): + """ generate selector for selecting all residues having the given sse. + return the selection name. + """ + #sel = self.pymol_sel.get() + sel_list_chn = [] + + if VERBOSE: print '\nSelecting SSE %s ... \n' % (sse) + + for chn in self.SSE_res_dict[sel][sse]: # color one chain at a time + if chn == ' ': chn_str = '-' + else: chn_str = chn + if VERBOSE: print 'Selecting SSE %s on chain %s ... \n' % (sse, chn) + limit=150 # color every 150 residues + sel_name_chn = self.randomSeleName(prefix='%s_%s_%s_' % ('_'.join(sel.split()),chn_str,sse)) + + if len(self.SSE_res_dict[sel][sse][chn]) < limit: + #sel_expr = '/%s//%s/%s/' % (sel,chn.strip(), '+'.join(self.SSE_res[sse][chn])) + # always quote chain name in case it is empty (otherwise sel misinterpreted) + sel_expr = '(%s) and \"%s\"/%s/' % (sel,chn.strip(), '+'.join(self.SSE_res_dict[sel][sse][chn])) + cmd.select(sel_name_chn, sel_expr) + if VERBOSE: print 'select %s, %s' % (sel_name_chn, sel_expr) + sel_list_chn.append(sel_name_chn) + else: + rn = len(self.SSE_res_dict[sel][sse][chn]) + print 'total number of res with %s = %d' % (sse,rn) + sz = int(math.ceil(rn/float(limit))) + sel_list_seg = [] + for i in xrange(sz): + s,e = i*limit, min((i+1)*limit, rn) + print s,e + #sel_expr = '/%s//%s/%s/' % (sel,chn.strip(), '+'.join(self.SSE_res[sse][chn][s:e])) + # always quote chain name in case it is empty (otherwise sel misinterpreted) + sel_expr = '(%s) and \"%s\"/%s/' % (sel, chn.strip(), + '+'.join(self.SSE_res_dict[sel][sse][chn][s:e])) + sel_name_seg = self.randomSeleName(prefix='%s_%s_%s_tmp_' % ('_'.join(sel.split()),chn_str,sse)) + cmd.select(sel_name_seg, sel_expr) + if VERBOSE: print 'select %s, %s' % (sel_name_seg, sel_expr) + sel_list_seg.append(sel_name_seg) + + sel_expr = ' or '.join(sel_list_seg) + cmd.select(sel_name_chn, sel_expr) + if VERBOSE: print 'select %s, %s' % (sel_name_chn, sel_expr) + [cmd.delete(asel) for asel in sel_list_seg] + sel_list_chn.append(sel_name_chn) + + if len(sel_list_chn) > 0: + sel_name = self.randomSeleName(prefix='%s_%s_%s_' % ('_'.join(sel.split()), sse, self.ss_asgn_prog)) + sel_expr = ' or '.join(sel_list_chn) + cmd.select(sel_name,sel_expr) + [cmd.delete(asel) for asel in sel_list_chn] + else: + print 'INFO: No residues are assigned to SSE \'%s\'.' % (sse,) + sel_name = None + + return sel_name + + + def updateColor(self): + if self.ss_asgn_prog is None: + err_msg = 'Run DSSP or Stride to assign secondary structures first!' + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + else: + print 'Update color for %s' % (self.pymol_sel.get()), + print 'using secondary structure assignment by %s' % (self.ss_asgn_prog,) + + if self.ss_asgn_prog == 'DSSP': SSE_list = self.DSSP_SSE_list + elif self.ss_asgn_prog == 'Stride': SSE_list = self.STRIDE_SSE_list + + for sse in SSE_list: # give color names + cmd.set_color('%s_color'%(sse,), self.SSE_col_RGB[sse]) + for sse in SSE_list: # color each SSE + for sel_obj in self.sel_obj_list: + if self.SSE_sel_dict[sel_obj][sse] is not None: + cmd.color('%s_color'%(sse,), self.SSE_sel_dict[sel_obj][sse]) + print 'color',self.SSE_sel_dict[sel_obj][sse],',',self.SSE_col_RGB[sse] + else: + print 'No residues with SSE \'%s\' to color.' % (sse,) + + return + + def updateSS(self): + if self.ss_asgn_prog is None: + err_msg = 'Run DSSP or Stride to assign secondary structures first!' + print 'ERROR: %s' % (err_msg,) + tkMessageBox.showinfo(title='ERROR', message=err_msg) + else: + print 'Update secondary structures for %s' % (self.pymol_sel.get()), + print 'using secondary structure assignment by %s' % (self.ss_asgn_prog,) + print 'SSE mapping: (H,G,I) ==> H; (E,B,b) ==> S; (T,S,-,C) ==> L' + + if self.ss_asgn_prog == 'DSSP': SSE_list = self.DSSP_SSE_list + elif self.ss_asgn_prog == 'Stride': SSE_list = self.STRIDE_SSE_list + + for sse in SSE_list: + for sel_obj in self.sel_obj_list: + if self.SSE_sel_dict[sel_obj][sse] is not None: + cmd.alter(self.SSE_sel_dict[sel_obj][sse], 'ss=\'%s\''% (self.SSE_map[sse],)) + print 'alter %s, ss=%s' % (self.SSE_sel_dict[sel_obj][sse], self.SSE_map[sse]) + else: + print 'No residue with SSE %s to update ss.' % (sse,) + + # show cartoon for the input selection, and rebuild + cmd.show('cartoon',self.pymol_sel.get()) + cmd.rebuild(self.pymol_sel.get()) + return + + + def custermizeHColor(self): + self.custermizeSSEColor('H') + def custermizeGColor(self): + self.custermizeSSEColor('G') + def custermizeIColor(self): + self.custermizeSSEColor('I') + + def custermizeEColor(self): + self.custermizeSSEColor('E') + def custermizeBColor(self): + self.custermizeSSEColor('B') + + def custermizeTColor(self): + self.custermizeSSEColor('T') + def custermizeSColor(self): + self.custermizeSSEColor('S') + def custermizeNColor(self): + self.custermizeSSEColor('-') + + def custermizebColor(self): + self.custermizeSSEColor('b') + def custermizeCColor(self): + self.custermizeSSEColor('C') + + def custermizeSSEColor(self,sse): + SSE_col_but = { + 'H':self.H_col_but, + 'G':self.G_col_but, + 'I':self.I_col_but, + + 'E':self.E_col_but, + 'B':self.B_col_but, + + 'T':self.T_col_but, + 'S':self.S_col_but, + '-':self.N_col_but, + + 'b':self.b_col_but, + 'C':self.C_col_but, + } + try: + color_tuple, color = tkColorChooser.askcolor(color=self.SSE_col[sse]) + if color_tuple is not None and color is not None: + self.SSE_col_RGB[sse] = color_tuple + self.SSE_col[sse] = color + + SSE_col_but[sse]['bg']=self.SSE_col[sse] + SSE_col_but[sse]['activebackground']=self.SSE_col[sse] + SSE_col_but[sse].update() + except Tkinter._tkinter.TclError: + print 'Old color (%s) will be used.' % (self.mesh_col) + + + def execute(self, butcmd): + """ Run the cmd represented by the botton clicked by user. + """ + if butcmd == 'OK': + print 'is everything OK?' + + elif butcmd == 'Run DSSP': + rtn = self.runDSSP() + if rtn and VERBOSE: print 'Done with DSSP!' + + elif butcmd == 'Run Stride': + rtn = self.runStride() + if rtn and VERBOSE: print 'Done with Stride!' + + elif butcmd == 'Update Color': + self.updateColor() + + elif butcmd == 'Update ss': + self.updateSS() + + elif butcmd == 'Exit': + print 'Exiting DSSP and Stride Plugin ...' + if __name__ == '__main__': + self.parent.destroy() + else: + self.dialog.withdraw() + print 'Done.' + else: + print 'Exiting DSSP and Stride Plugin because of unknown button click ...' + self.dialog.withdraw() + print 'Done.' + + + def quit(self): + self.dialog.destroy() + + +############################################# +# +# +# Create demo in root window for testing. +# +# +############################################## +if __name__ == '__main__': + + class App: + def my_show(self,*args,**kwargs): + pass + + app = App() + app.root = Tkinter.Tk() + Pmw.initialise(app.root) + app.root.title('It seems to work!') + + widget = DSSPPlugin(app) + app.root.mainloop() diff --git a/.pymol/startup/dssp_stride.pyc b/.pymol/startup/dssp_stride.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75c888b3247526a4cc1deeebe472cca4fe4fa96c GIT binary patch literal 26465 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 HCiH&*yX=c{ literal 0 HcmV?d00001 diff --git a/.pymol/startup/propka.py b/.pymol/startup/propka.py new file mode 100644 index 0000000..a8c4d0b --- /dev/null +++ b/.pymol/startup/propka.py @@ -0,0 +1,887 @@ +''' +Described at PyMOL wiki: +http://www.pymolwiki.org/index.php/propka + +#------------------------------------------------------------------------------- +# Name: propka for pymol +# Purpose: To fetch and display the pka values for protein of intetest +# +# Author: Troels E. Linnet +# +# Created: 14/08/2011 +# Copyright: (c) Troels E. Linnet 2011 +# Contact: tlinnet snabela gmail dot com +# Licence: Free for all +# +# +#------------------------------------------------------------------------------- + + The PROPKA method is developed by the + Jensen Research Group + Department of Chemistry + University of Copenhagen + + Please cite these references in publications: +Hui Li, Andrew D. Robertson, and Jan H. Jensen +"Very Fast Empirical Prediction and Interpretation of Protein pKa Values" +Proteins, 2005, 61, 704-721. + +Delphine C. Bas, David M. Rogers, and Jan H. Jensen +"Very Fast Prediction and Rationalization of pKa Values for Protein-Ligand Complexes" +Proteins, 2008, 73, 765-783. + +Mats H.M. Olsson, Chresten R. Soendergard, Michal Rostkowski, and Jan H. Jensen +"PROPKA3: Consistent Treatment of Internal and Surface Residues in Empirical pKa predictions" +Journal of Chemical Theory and Computation, 2011 7 (2), 525-537 + +Chresten R. Soendergaard, Mats H.M. Olsson, Michaz Rostkowski, and Jan H. Jensen +"Improved Treatment of Ligands and Coupling Effects in Empirical Calculation and Rationalization of pKa Values" +Journal of Chemical Theory and Computation, 2011 in press +""" +#------------------------------------------------------------------------------- +# The script needs mechanize to run. +# On windows, it is not easy to make additional modules available for pymol. So put in into your working folder. +#1)The easy manual way: +#a)Go to: http://wwwsearch.sourceforge.net/mechanize/download.html +#b)Download mechanize-0.2.5.zip. http://pypi.python.org/packages/source/m/mechanize/mechanize-0.2.5.zip +#c)Extract to .\mechanize-0.2.5 then move the in-side folder "mechanize" to your folder with propka.py. The rest of .\mechanize-0.2.5 you don't need. +#You can also see other places where you could put the "mechanize" folder. Write this in pymol to see the paths where pymol is searching for "mechanize" +# import sys; print(sys.path) + +#------------------------------------------------------------------------------- +""" +Example for pymol script to start the functions. For example: trypropka.pml +Execute with pymol or start pymol and: File->Run->trypropka.pml +############################################################################################################################################################################################################################## + +### Point to your directory with your pdb file and where to save the results +#cd /homes/linnet/Documents/Speciale/5NT-project/Mutant-construct/predict_reactivity/propka +cd C:/Users/tlinnet/Documents/My Dropbox/Speciale/5NT-project/Mutant-construct/predict_reactivity/propka + +### The fastest method is just to write propka. Then the last pymol molecule is assumed and send to server. verbose=yes makes the script gossip mode. +import propka + +fetch 4ins, async=0 +propka +#fetch 1hp1, async=0 +#propka logtime=_, resi=5-10.20-30, resn=CYS.ATP.TRP, verbose=yes + +### Fetch 4ins from web. async make sure, we dont execute script before molecule is loaded. The resi and resn prints the interesting results right to command line. +#fetch 4ins, async=0 +#propka chain=*, resi=5-10.20-30, resn=ASP.CYS, logtime=_ + +### If there is no web connection, one can process a local .pka file. Either from a previous run or from a downloaded propka webpage result. +### Then run and point to .pka file with: pkafile=./Results_propka/pkafile.pka Remember the dot "." in the start, to make it start in the current directory. +#load 4ins.pdb +#propka pkafile=./Results_propka/4ins_.pka, resi=18.25-30, resn=cys, + +### Some more examples. This molecule has 550 residues, so takes a longer time. We select to run the last molecule, by writing: molecule=1hp1 +#fetch 4ins, async=0 +#fetch 1hp1, async=0 +#propka molecule=1hp1, chain=A, resi=300-308.513, resn=CYS.ATP.TRP, logtime=_, verbose=no, showresult=no +#propka molecule=1hp1, pkafile=./Results_propka/1hp1_.pka, verbose=yes + +### One can also just make a lookup for a protein. Use function: getpropka +### Note. This does only print the result to the pymol command line +#getpropka source=ID, PDBID=4ake, logtime=_, showresult=yes +#getpropka source=ID, PDBID=4ins, logtime=_, server_wait=10.0, verbose=yes, showresult=no +############################################Input parameters: propka############################################ +############# The order of input and changable things: +############# propka(molecule="NIL",chain="*",resi="0",resn="NIL",method="upload",logtime=time.strftime("%m%d",time.localtime()),server_wait=3.0,version="v3.1",verbose="no",showresult="no",pkafile="NIL") +# method : method=upload is default. This sends .pdb file and request result from propka server. +## method=file will only process a manual .pka file, and write a pymol command file. No use of mechanize. +## If one points to an local .pka file, then method is auto-changed to method=file. This is handsome in off-line environment, ex. teaching or seminar. +# pkafile: Write the path to .pka file. Ex: pkafile=./Results_propka/4ins_.pka +# molecule : name of the molecule. Ending of file is assumed to be .pdb +# chain : which chains are saved to file, before molecule file is send to server. Separate with "." Ex: chain=A.b +# resi : Select by residue number, which residues should be printed to screen and saved to the log file: /Results_propka/_Results.log. +## Separate with "." or make ranges with "-". Ex: resi=35.40-50 +# resn : Select by residue name, which residues should be printed to screen and saved to the log file: /Results_propka/_Results.log. +## Separate with "." Ex: resn=cys.tyr +# logtime : Each execution give a set of files with the job id=logtime. If logtime is not provided, the current time is used. +## Normal it usefull to set it empty. Ex: logtime=_ +# verbose : Verbose is switch, to turn on messages for the mechanize section. This is handsome to see how mechanize works, and for error searching. +# showresult : Switch, to turn on all results in pymol command window. Ex: showresult=yes +# server_wait=10.0 is default. This defines how long time between asking the server for a result. Set no lower than 3 seconds. +# version=v3.1 is default. This is what version of propka which would be used. +## Possible: 'v3.1','v3.0','v2.0'. If a newer version is available than the current v3.1, a error message is raised to make user update the script. +############################################Input parameters: getpropka############################################ +############# The order of input and changable things: +############# getpropka(PDB="NIL",chain="*",resi="0",resn="NIL",source="upload",PDBID="",logtime=time.strftime("%Y%m%d%H%M%S",time.localtime()),server_wait=3.0,version="v3.1",verbose="no",showresult="no") +# PDB: points the path to a .pdb file. This is auto-set from propka function. +# source : source=upload is default and is set at the propka webpage. +# source=ID, PDBID=4ake , one can print to the command line, the pka value for any official pdb ID. No files are displayed in pymol. +# PDBID: is used as the 4 number/letter pdb code, when invoking source=ID. + +############################################################################################################################################################################################################################## +''' + +from __future__ import print_function + +try: + from pymol import cmd + runningpymol = 'yes' +except: + runningpymol = 'no' + pass +import time +import platform +import os +import sys + + +def propka(molecule="NIL", chain="*", resi="0", resn="NIL", method="upload", logtime=time.strftime("%m%d", time.localtime()), server_wait=3.0, version="v3.1", verbose="no", showresult="no", pkafile="NIL", makebonds="yes"): + Script_Version = "20110823" + # First we have to be sure, we give reasonable arguments + if pkafile != "NIL": + method = 'file' + assert method in ['upload', 'file'], "'method' has to be either: method=upload or method=file" + # If molecule="all", then try to get the last molecule + ##assert molecule not in ['NIL'], "You always have to provide molecule name. Example: molecule=4ins" + if molecule == "NIL": + assert len(cmd.get_names()) != 0, "Did you forget to load a molecule? There are no objects in pymol." + molecule = cmd.get_names()[-1] + # To print out to screen for selected residues. Can be separated with "." or make ranges with "-". Example: resi="4-8.10" + if resi != "0": + resi_range = ResiRange(resi) + else: + resi_range = [] + # Also works for residue names. They are all converted to bigger letters. Example: resn="cys.Tyr" + if resn != "NIL": + resn_range = ResnRange(resn) + else: + resn_range = resn + # Make chain range, and upper case. + chain = ChainRange(chain) + # Make result directory. We also the absolut path to the new directory. + Newdir = createdirs() + if method == "upload": + # We try to load mechanize. If this fail, one can always get the .pka file manual and the run: method=file + try: + from modules import mechanize + importedmechanize = 'yes' + except ImportError: + print("Import error. Is a module missing?") + print(sys.exc_info()) + print("Look if missing module is in your python path\n%s" % sys.path) + importedmechanize = 'no' + import modules.mechanize as mechanize + # The name for the new molecule + newmolecule = "%s%s" % (molecule, logtime) + # Create the new molecule from original loaded and for the specified chains. Save it, and disable the old molecule. + cmd.create("%s" % newmolecule, "%s and chain %s" % (molecule, chain)) + cmd.save("%s%s.pdb" % (Newdir, newmolecule), "%s" % newmolecule) + cmd.disable("%s" % molecule) + if molecule == "all": + cmd.enable("%s" % molecule) + cmd.show("cartoon", "%s" % molecule) + # Let the new molecule be shown in cartoon. + cmd.hide("everything", "%s" % newmolecule) + cmd.show("cartoon", "%s" % newmolecule) + # Make the absolut path to the newly created .pdb file. + PDB = "%s%s.pdb" % (Newdir, newmolecule) + source = "upload" + PDBID = "" + # Request server, and get the absolut path to the result file. + pkafile = getpropka(PDB, chain, resi, resn, source, PDBID, logtime, server_wait, version, verbose, showresult) + # Open the result file and put in into a handy list. + list_results, ligands_results = importpropkaresult(pkafile) + if method == "file": + assert pkafile not in ['NIL'], "You have to provide path to file. Example: pkafile=./Results_propka/4ins_2011.pka" + assert ".pka" in pkafile, 'The propka result file should end with ".pka" \nExample: pkafile=./Results_propka/4ins_2011.pka \npkafile=%s' % (pkafile) + # The name for the molecule we pass to the writing script of pymol commands + newmolecule = "%s" % molecule + cmd.hide("everything", "%s" % newmolecule) + cmd.show("cartoon", "%s" % newmolecule) + # We open the result file we have got in the manual way and put in into a handy list. + list_results, ligands_results = importpropkaresult(pkafile) + # Then we print the interesting residues to the screen. + printpropkaresult(list_results, resi, resi_range, resn, resn_range, showresult, ligands_results) + # Now create the pymol command file. This should label the protein. We get back the absolut path to the file, so we can execute it. + result_pka_pymol_name = writepymolcmd(newmolecule, pkafile, verbose, makebonds) + # Now run our command file. But only if we are running pymol. + if runningpymol == 'yes': + cmd.do("run %s" % result_pka_pymol_name) + ##if runningpymol=='yes': cmd.do("@%s"%result_pka_pymol_name) + return(list_results) +if runningpymol != 'no': + cmd.extend("propka", propka) + + +def getpropka(PDB="NIL", chain="*", resi="0", resn="NIL", source="upload", PDBID="", logtime=time.strftime("%Y%m%d%H%M%S", time.localtime()), server_wait=3.0, version="v3.1", verbose="no", showresult="no"): + try: + import modules.mechanize as mechanize + importedmechanize = 'yes' + except ImportError: + print("Import error. Is a module missing?") + print(sys.exc_info()) + print("Look if missing module is in your python path \n %s" % sys.path) + importedmechanize = 'no' + propka_v_201108 = 3.1 + url = "http://propka.ki.ku.dk/" + assert version in ['v2.0', 'v3.0', 'v3.1'], "'version' has to be either: 'v2.0', 'v3.0', 'v3.1'" + assert source in ['ID', 'upload', 'addr', 'input_file'], "'source' has to be either: 'ID', 'upload', 'addr', 'input_file'" + if source == "upload": + assert PDB not in ['NIL'], "You always have to provide PDB path. Example: PDB=.\Results_propka\4ins2011.pdb" + if source == "ID": + assert len(PDBID) == 4, "PDBID has to be 4 characters" + # To print out to screen for selected residues. Can be separated with "." or make ranges with "-". Example: resi="4-8.10" + if resi != "0": + resi_range = ResiRange(resi) + else: + resi_range = [] + # Also works for residue names. They are all converted to bigger letters. Example: resn="cys.Tyr" + if resn != "NIL": + resn_range = ResnRange(resn) + else: + resn_range = resn + # Start the browser + br = mechanize.Browser() + # We pass to the server, that we are not a browser, but this python script. Can be used for statistics at the propka server. + br.addheaders = [('User-agent', 'pythonMechanizeClient')] + # To turn on debugging messages + # br.set_debug_http(True) + # To open the start page. + page_start = br.open(url) + read_start = page_start.read() + if verbose == 'yes': + print(br.title()) + print(br.geturl()) + # To get available forms + page_forms = [f.name for f in br.forms()] + if verbose == 'yes': + print(page_forms) + # Select first form + br.select_form(name=page_forms[0]) + # Print the current selected form, so we see that we values we start with. + if verbose == 'yes': + print(br.form) + # Print the parameters of the 'version' RadioControl button and current value + if verbose == 'yes': + print(br.find_control(name='version'), br.find_control(name='version').value) + # This is to check, that the current script is "up-to-date". + propka_v_present = float(br.find_control(name='version').value[0].replace('v', '')) + if propka_v_present > propka_v_201108: + raise UserWarning('\nNew version of propka exist.\nCheck/Update your script.\nPresent:v%s > Script:v%s' % (propka_v_present, propka_v_201108)) + # Change the parameters of the 'version' radio button and then reprint the new value. Input has to be in a list [input]. + br.form['version'] = [version] + if verbose == 'yes': + print(br.find_control(name='version').value) + # Print the parameters of the 'source' RadioControl button and current value + if verbose == 'yes': + print(br.find_control(name='source'), br.find_control(name='source').value) + # Change the parameters of the 'source' radio button and then reprint the new value. Input has to be in a list [input]. + br.form['source'] = [source] + if verbose == 'yes': + print(br.find_control(name='source').value) + # This step was the must strange and took a long time. For finding the information and the double negative way. + # One have to enable the pdb button. Read more here: http://wwwsearch.sourceforge.net/old/ClientForm/ ("# All Controls may be disabled.....) + PDBID_control = br.find_control("PDBID") + PDB_control = br.find_control("PDB") + if verbose == 'yes': + print(PDBID_control.disabled, PDB_control.disabled) + if source == "ID": + PDBID_control.disabled = False + PDB_control.disabled = True + if source == "upload": + PDBID_control.disabled = True + PDB_control.disabled = False + if verbose == 'yes': + print(PDBID_control.disabled, PDB_control.disabled) + # We create the result dir, and take with us the 'path' to the result dir. + Newdir = createdirs() + # Open all the files, and assign them. + if source == "upload": + filename = PDB + if source == "ID": + filename = PDBID + files = openfiles(Newdir, filename, logtime, source) + result_pka_file = files[0] + result_input_pka_file = files[1] + result_log = files[2] + filepath = files[3] + result_pka_pkafile = files[4] + result_pka_file_stripped = files[5] + result_pka_file_bonds = files[6] + # Print the parameters of the 'PDBID' TextControl button and current value + if source == "ID" and verbose == 'yes': + print(br.find_control(name='PDBID')) + print(br.find_control(name='PDBID').value) + # Change the parameters of the 'PDBID' TextControl and then reprint the new value. Input has just to be a string. + if source == "ID": + br.form["PDBID"] = PDBID + if source == "ID" and verbose == 'yes': + print(br.find_control(name='PDBID').value) + # Print the parameters of the 'PDB' TextControl button and current value + if source == "upload" and verbose == 'yes': + print(br.find_control(name='PDB')) + print(br.find_control(name='PDB').value) + # Change the parameters of the 'PDB' FileControl and then reprint the new value. Input has just to be a string. + if source == "upload": + PDBfilename = PDB + PDBfilenamepath = PDB + if source == "upload": + br.form.add_file(open(PDBfilename), 'text/plain', PDBfilenamepath, name='PDB') + if source == "upload" and verbose == 'yes': + print(br.find_control(name='PDB')) + print(br.find_control(name='PDB').value) + # Now reprint the current selected form, so we see that we have the right values. + if verbose == 'yes': + print(br.form) + # Make "how" we would like the next request. We would like to "Click the submit button", but we have not opened the request yet. + req = br.click(type="submit", nr=0) + # Have to pass by a mechanize exception. Thats the reason for the why True + # The error was due to: br.open(req) + # mechanize._response.httperror_seek_wrapper: HTTP Error refresh: The HTTP server returned a redirect error that would lead to an infinite loop. + # The last 30x error message was: + # OK + # I haven't been able to find the refresh problem or extend the time. So we make a pass on the raised exception. + try: + print("Now sending request to server") + br.open(req) + # If there is raised an exception, we jump through to the result page after some sleep. + except mechanize.HTTPError: + # We can extract the jobid from the current browser url. + jobid = br.geturl()[32:-5] + # We notice how the script at the server presents the final result page. + url_result = url + "pka/" + jobid + ".html" + # Now we continue to try to find the result page, until we have succes. If page doesn't exist, we wait a little. + while True: + print("Result still not there. Waiting %s seconds more" % server_wait) + time.sleep(float(server_wait)) + # To pass the "break" after the exception, we make a hack, wait and then go to the result page, which is the jobid. + try: + page_result = br.open(url_result) + read_result = page_result.read() + # If we don't receive a error in getting the result page, we break out of the while loop. + break + # If the page doesn't exist yet. We go back in the while loop. + except mechanize.HTTPError: + # Wait another round + pass + # If we get a timeout, we also wait. + except mechanize.URLError: + # Wait another round + pass + htmlresult = "The detailed result is now available at: %s" % br.geturl() + print(htmlresult) + read_result = br.response().read() + # Now save the available links from the current page. But only links that satisfy the expression. + links_result = [] + for l in br.links(url_regex='http://propka.ki.ku.dk/pka'): + links_result.append(l) + # We also extract the information for neighbour bons. This is given in the url links. + bonds = [] + for l in br.links(url_regex='http://propka.ki.ku.dk/view/new_view.cgi'): + l_split = str(l).split() + lresn = l_split[2] + lresi = l_split[3] + lchain = l_split[4] + lurl = l_split[1] + lurl_split = lurl.split("&") + lresn2 = lurl_split[1] + lchain2 = lurl_split[2] + lpka = lurl_split[3] + ldesolvation = lurl_split[4] + lneighbours = lurl_split[5:] + for i in range(len(lneighbours)): + bonds.append([lresn, lresi, lchain, lresn2, lchain2, lpka, ldesolvation, lneighbours[i]]) + # Now follow the link to the .propka_input resultpage + if len(links_result) > 1: + br.follow_link(links_result[1]) + # Now get the page text for the current link + if len(links_result) > 1: + read_result1 = br.response().read() + # Save the result + if len(links_result) > 1: + result_input_pka_file.write(read_result1) + # Now follow the link to the .pka resultpage + if len(links_result) > 1: + br.back() + result_input_pka_file.close() + # Now follow first link. "Should be" available for all versions of propka. + br.follow_link(links_result[0]) + # Now get the page for the current link + read_result0 = br.response().read() + # Save the result and close file. + result_pka_file.write(read_result0) + result_pka_file.close() + # Now get the result in a list, which is sorted + list_results, ligands_results = importpropkaresult(result_pka_pkafile) + # Print to log file + result_log.write("# executed: %s \n# logtime: %s \n# source=%s \n# PDB=%s \n# chain=%s \n# PDBID=%s \n# server_wait=%s version=%s verbose=%s showresult=%s \n# resi=%s resn=%s\n# %s \n" % (time.strftime("%Y%m%d%H%M%S", time.localtime()), logtime, source, PDB, chain, PDBID, server_wait, version, verbose, showresult, resi, resn, htmlresult)) + # Print to screen + printpropkaresult(list_results, resi, resi_range, resn, resn_range, showresult, ligands_results) + # Now write to log and the stripped file + for l in list_results: + if resi != "0" and int(l[1]) in resi_range: + result_log.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n') + if resn != "NIL" and l[0] in resn_range and int(l[1]) not in resi_range: + result_log.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n') + result_pka_file_stripped.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n') + for l in ligands_results: + if resn != "NIL" and l[0] in resn_range: + result_log.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n') + result_pka_file_stripped.write("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + '\n') + result_pka_file_stripped.close() + result_log.close() + # Now handle the bonds. We have to delete dublicates first. + bonds.sort() + last = bonds[-1] + for i in range(len(bonds) - 2, -1, -1): + if last == bonds[i]: + del bonds[i] + else: + last = bonds[i] + # Now make a selection for known residue + bonds_selected = [] + bonds_ligands = [] + for l in bonds: + if l[0][6:] in ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'C-', 'N+']: + bonds_selected.append(l) + else: + bonds_ligands.append(l) + # And now sort it. + bonds_selected.sort(key=lambda residue: int(residue[1])) + # Now write it to file + bonddic = {'=': ' ', ':': ' ', ',': ' ', "'": " "} + for l in bonds_selected: + nb = replace_all(l[7], bonddic) + result_pka_file_bonds.write("%3s %3s %s %7s %7s %9s %17s %s" % (l[0][6:], l[1], l[2][:1], l[3][8:], l[4], l[5], l[6], nb) + '\n') + for l in bonds_ligands: + nb = replace_all(l[7], bonddic) + result_pka_file_bonds.write("%3s %3s %s %7s %7s %9s %17s %s" % (l[0][6:], l[1], l[2][:1], l[3][8:], l[4], l[5], l[6], nb) + '\n') + result_pka_file_bonds.close() + return(result_pka_pkafile) +if runningpymol != 'no': + cmd.extend("getpropka", getpropka) + + +def openpymolfiles(pkafile): + result_pka_pymol_name = pkafile.replace(".pka", ".pml") + result_pka_pymol = open(result_pka_pymol_name, "w") + return(result_pka_pymol, result_pka_pymol_name) + + +def printpropkaresult(list_results, resi, resi_range, resn, resn_range, showresult, ligands_results): + for l in list_results: + if resi != "0" and int(l[1]) in resi_range: + if showresult != 'yes': + print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8])) + if resn != "NIL" and l[0] in resn_range and int(l[1]) not in resi_range: + if showresult != 'yes': + print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8])) + if showresult == 'yes': + print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8])) + for l in ligands_results: + if resn != "NIL" and l[0] in resn_range: + if showresult != 'yes': + print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8])) + if showresult == 'yes': + print("%3s %3s %s %6s %3s %5s %3s %4s %s" % (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8])) + + +def importpropkaresult(result_pka_pkafile): + result_pka_file = open(result_pka_pkafile, "r") + list_results = [] + ligands_results = [] + ##bonding_partners = [] + for l in result_pka_file: + if not l.strip(): + continue + else: + # To search for the right lines + if l.strip().split()[0] in ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'C-', 'N+'] and len(l.strip().split()) > 20: + list_results.append([l.strip().split()[0], l.strip().split()[1], l.strip().split()[2], l.strip().split()[3], l.strip().split()[4], l.strip().split()[6], l.strip().split()[7], l.strip().split()[8], l.strip().split()[9]]) + # bonding_partners.append(l.strip().split()[11]);bonding_partners.append(l.strip().split()[15]);bonding_partners.append(l.strip().split()[19]) + if l.strip().split()[0] not in ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'C-', 'N+'] and len(l.strip().split()) > 20: + ligands_results.append([l.strip().split()[0], l.strip().split()[1], l.strip().split()[2], l.strip().split()[3], l.strip().split()[4], l.strip().split()[6], l.strip().split()[7], l.strip().split()[8], l.strip().split()[9]]) + # bonding_partners.append(l.strip().split()[11]);bonding_partners.append(l.strip().split()[15]);bonding_partners.append(l.strip().split()[19]) + # Sort the result after the residue number and then chain. + list_results.sort(key=lambda residue: int(residue[1])) + list_results.sort(key=lambda chain: chain[2]) + # bonding_partners=uniqifi(bonding_partners) + ##bonding_partners[:] = [x for x in bonding_partners if x != "XXX"] + result_pka_file.close() + return(list_results, ligands_results) + + +def importpropkabonds(result_pka_pkafile): + bonds = [] + result_pka_file_bonds = open(result_pka_pkafile[:-4] + ".bonds", "r") + for l in result_pka_file_bonds: + bonds.append(l.split()) + result_pka_file_bonds.close() + return(bonds) + + +def createdirs(): + if platform.system() == 'Windows': + Newdir = os.getcwd() + "\Results_propka\\" + if platform.system() == 'Linux': + Newdir = os.getcwd() + "/Results_propka/" + if not os.path.exists(Newdir): + os.makedirs(Newdir) + return(Newdir) + + +def openfiles(Newdir, filename, logtime, source): + if source == "upload": + result_pka_pkafile = filename.replace(".pdb", ".pka") + result_pka_input_pkafile = filename.replace(".pdb", ".propka_input") + result_log_name = "%s_Results.log" % (Newdir) + result_pka_file_stripped_name = filename.replace(".pdb", ".stripped") + result_pka_file_bonds_name = filename.replace(".pdb", ".bonds") + if source == "ID": + result_pka_pkafile = "%s%s%s.pka" % (Newdir, filename, logtime) + result_pka_input_pkafile = "%s%s%s.propka_input" % (Newdir, filename, logtime) + result_log_name = "%s_Results.log" % (Newdir) + result_pka_file_stripped_name = "%s%s%s.stripped" % (Newdir, filename, logtime) + result_pka_file_bonds_name = "%s%s%s.bonds" % (Newdir, filename, logtime) + if platform.system() == 'Windows': + filepath = "\\" + if platform.system() == 'Linux': + filepath = "/" + # Open the files + result_pka_file = open(result_pka_pkafile, "w") + result_input_pka_file = open(result_pka_input_pkafile, "w") + result_log = open(result_log_name, "a") + result_pka_file_stripped = open(result_pka_file_stripped_name, "w") + result_pka_file_bonds = open(result_pka_file_bonds_name, "w") + return(result_pka_file, result_input_pka_file, result_log, filepath, result_pka_pkafile, result_pka_file_stripped, result_pka_file_bonds) + + +def ResiRange(resi): + resi = resi.split('.') + resiList = [] + for i in resi: + if '-' in i: + tmp = i.split('-') + resiList.extend(list(range(int(tmp[0]), int(tmp[-1]) + 1))) + if '-' not in i: + resiList.append(int(i)) + return(resiList) + + +def ResnRange(resn): + resn_split = resn.split('.') + resn_range = [resnr.upper() for resnr in resn_split] + return(resn_range) + + +def ChainRange(chain): + chainstring = chain.replace(".", "+").upper() + return(chainstring) + + +def writepymolcmd(newmolecule, pkafile, verbose, makebonds): + list_results, ligands_results = importpropkaresult(pkafile) + # Now find the available bonding partners that pymol knows of + bonding_partners = [] + bonding_partners_str = cmd.get_pdbstr("%s and resn * and not resn ASP+GLU+ARG+LYS+HIS+CYS+TYR+GLN+ASN+SER+THR+GLY+PHE+LEU+ALA+ILE+TRP+MET+PRO+VAL+HOH" % (newmolecule)) + for i in range(len(bonding_partners_str.splitlines()) - 1): + bonding_partners_split = bonding_partners_str.splitlines()[i].split() + if bonding_partners_split[0] == "HETATM" or bonding_partners_split[0] == "ATOM": + bonding_partners_single = bonding_partners_split[3] + bonding_partners.append(bonding_partners_single) + bonding_partners = uniqifi(bonding_partners) + if verbose == 'yes': + print("And other possible bonding partners is: %s" % bonding_partners) + # Read in the bond file, if it exists + writebonds = "no" + if os.path.isfile(pkafile[:-4] + ".bonds") and makebonds == "yes": + bonds = importpropkabonds(pkafile) + writebonds = "yes" + # Open the pymol command file for writing + files_pka_pymol = openpymolfiles(pkafile) + result_pka_pymol = files_pka_pymol[0] + result_pka_pymol_name = files_pka_pymol[1] + # Make some dictionary for propka->pymol name conversion + dictio = {'ASP': 'CG', 'GLU': 'CD', 'ARG': 'CZ', 'LYS': 'NZ', 'HIS': 'CG', 'CYS': 'SG', 'TYR': 'OH', 'C-': 'C', 'N+': 'N', 'NTR': 'N', 'CTR': 'C', 'GLN': 'CD', 'ASN': 'CG', 'SER': 'OG', 'THR': 'OG1', 'GLY': 'CA', 'PHE': 'CZ', 'LEU': 'CG', 'ALA': 'CB', 'ILE': 'CD1', 'TRP': 'NE1', 'MET': 'SD', 'PRO': 'CG', 'VAL': 'CB'} + dictio2 = {'ASP': 'D', 'GLU': 'E', 'ARG': 'R', 'LYS': 'K', 'HIS': 'H', 'CYS': 'C', 'TYR': 'Y', 'C-': 'C-', 'N+': 'N+'} + # This list is from: http://en.wikipedia.org/wiki/Protein_pKa_calculations + pkaaminoacid = ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR'] + pkadictio = {'ASP': 3.9, 'GLU': 4.3, 'ARG': 12.0, 'LYS': 10.5, 'HIS': 6.0, 'CYS': 8.3, 'TYR': 10.1} + # Now start write to the file. + # Try to make silent + # result_pka_pymol.write("cmd.feedback('disable','all','actions')\n") + # result_pka_pymol.write("cmd.feedback('disable','all','results')\n") + # Change the GUI width, to make the long names possible. + result_pka_pymol.write("cmd.set('internal_gui_width','360')\n") + # Set fonts + result_pka_pymol.write("cmd.set('label_font_id','12')\n") + result_pka_pymol.write("cmd.set('label_size','-0.5')\n") + result_pka_pymol.write("cmd.set('label_color','grey')\n") + # No auto zoom the new objects + result_pka_pymol.write("cmd.set('auto_zoom','off')\n") + # The name for the molecules are defined here + pkamolecule = "%spKa" % (newmolecule) + pkalabelmolecule = "%sLab" % (newmolecule) + # Create the groups now, so they come in order. They will be empty + result_pka_pymol.write("cmd.group('%sResi','Res*')\n" % (newmolecule)) + result_pka_pymol.write("cmd.group('%sLigands','Lig*')\n" % (newmolecule)) + if writebonds == "yes": + result_pka_pymol.write("cmd.group('%sBonds','%sBond*')\n" % (newmolecule, newmolecule)) + # Create new empty pymol pka molecules. For pka atoms and its label. This is a "bucket" we where we will put in the atoms together. + result_pka_pymol.write("cmd.create('%s','None')\n" % (pkamolecule)) + result_pka_pymol.write("cmd.create('%s','None')\n" % (pkalabelmolecule)) + # Now make the pka atoms and alter, color and such + for l in list_results: + name = dictio[l[0]] + resn = dictio2[l[0]] + resi = l[1] + chain = l[2] + pka = l[3] + buried = l[4] + if "*" in pka: + pka = pka.replace("*", "") + comment = "*Coupled residue" + else: + comment = "" + if l[0] in pkaaminoacid: + pkadiff = (float(pka) - pkadictio[l[0]]) + pkadiff = "(%s)" % pkadiff + if pka == "99.99": + pkadiff = "" + else: + pkadiff = "" + # Make the selection for which atom to copy + newselection = ("/%s//%s/%s/%s" % (newmolecule, chain, resi, name)) + protselect = ("%sRes_%s%s%s" % (newmolecule, chain, resn, resi)) + result_pka_pymol.write("cmd.select('%s','byres %s')\n" % (protselect, newselection)) + result_pka_pymol.write("cmd.show('sticks','byres %s')\n" % (protselect)) + # The temporary name + tempname = ("%s%s%s%s" % (pkamolecule, chain, resi, name)) + tempnamelabel = ("%s%s%s%s" % (pkalabelmolecule, chain, resi, name)) + tempselect = ("/%s//%s/%s" % (tempname, chain, resi)) + tempselectlabel = ("/%s//%s/%s" % (tempnamelabel, chain, resi)) + # Copy the atom, call it by the residue name + result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempname, newselection)) + # Alter the name and the b value of the newly created atom + result_pka_pymol.write("cmd.alter('%s','b=%s')\n" % (tempselect, pka)) + result_pka_pymol.write("cmd.alter('%s','vdw=0.5')\n" % (tempselect)) + result_pka_pymol.write("cmd.alter('%s','name=%s%s%s')\n" % (tempselect, '"', pka, '"')) + # Now create a fake label atom, and translate it + result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempnamelabel, tempname)) + movelabelxyz = (1.5, 0, 0) + result_pka_pymol.write("cmd.translate('[%s,%s,%s]','%s',camera=0)\n" % (movelabelxyz[0], movelabelxyz[1], movelabelxyz[2], tempnamelabel)) + # Labelling alternate positions are not allowed, so we delete that attribute for the label atoms. + result_pka_pymol.write("cmd.alter('%s','alt=%s%s')\n" % (tempselectlabel, '"', '"')) + result_pka_pymol.write("cmd.label('%s','text_type=%spka=%s%s Bu:%s%s%s%s')\n" % (tempselectlabel, '"', pka, pkadiff, buried, '%', comment, '"')) + # Now put the atoms into a bucket of atoms + result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkamolecule, pkamolecule, tempselect)) + result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkalabelmolecule, pkalabelmolecule, tempselectlabel)) + # Remove the temporary atoms + result_pka_pymol.write("cmd.remove('%s')\n" % (tempname)) + result_pka_pymol.write("cmd.remove('%s')\n" % (tempnamelabel)) + # Delete the temporary molecule/selection + result_pka_pymol.write("cmd.delete('%s')\n" % (tempname)) + result_pka_pymol.write("cmd.delete('%s')\n" % (tempnamelabel)) + # Group the resi together + result_pka_pymol.write("cmd.group('%sResi','%sRes*')\n" % (newmolecule, newmolecule)) + for l in ligands_results: + resn = l[0] + atom = l[1] + chain = l[2] + pka = l[3] + buried = l[4] + if verbose == 'yes': + print("Ligand. resn:%s atom:%s chain:%s pka:%s buried:%s" % (resn, atom, chain, pka, buried)) + if Check_bonding_partners(bonding_partners, resn)[0]: + if "*" in pka: + pka = pka.replace("*", "") + comment = "*Coupled residue" + else: + comment = "" + # Make the selection for which atom to copy + ligselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, chain, resn, atom)) + ligselect = ("%sLig_%s%s%s" % (newmolecule, chain, resn, atom)) + result_pka_pymol.write("cmd.select('%s','%s')\n" % (ligselect, ligselection)) + result_pka_pymol.write("cmd.show('sticks','byres %s')\n" % (ligselect)) + result_pka_pymol.write("cmd.util.cbap('byres %s')\n" % (ligselect)) + # The temporary name + tempname = ("%s%s%s%s" % (pkamolecule, chain, resn, atom)) + tempnamelabel = ("%s%s%s%s" % (pkalabelmolecule, chain, resn, atom)) + tempselect = ("/%s and chain %s and resn %s" % (tempname, chain, resn)) + tempselectlabel = ("/%s and chain %s and resn %s" % (tempnamelabel, chain, resn)) + # Copy the atom, call it by the residue name + result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempname, ligselection)) + # Alter the name and the b value of the newly created atom + result_pka_pymol.write("cmd.alter('%s','b=%s')\n" % (tempselect, pka)) + result_pka_pymol.write("cmd.alter('%s','vdw=0.5')\n" % (tempselect)) + result_pka_pymol.write("cmd.alter('%s','name=%s%s%s')\n" % (tempselect, '"', pka, '"')) + # Now create a fake label atom, and translate it + result_pka_pymol.write("cmd.create('%s','%s',quiet=1)\n" % (tempnamelabel, tempname)) + movelabelxyz = (1.5, 0, 0) + result_pka_pymol.write("cmd.translate('[%s,%s,%s]','%s',camera=0)\n" % (movelabelxyz[0], movelabelxyz[1], movelabelxyz[2], tempnamelabel)) + # Labelling alternate positions are not allowed, so we delete that attribute for the label atoms. + result_pka_pymol.write("cmd.alter('%s','alt=%s%s')\n" % (tempselectlabel, '"', '"')) + result_pka_pymol.write("cmd.label('%s','text_type=%spka=%s Bu:%s%s%s%s')\n" % (tempselectlabel, '"', pka, buried, '%', comment, '"')) + # Now put the atoms into a bucket of atoms + result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkamolecule, pkamolecule, tempselect)) + result_pka_pymol.write("cmd.create('%s','%s or (%s)',quiet=1)\n" % (pkalabelmolecule, pkalabelmolecule, tempselectlabel)) + # Remove the temporary atoms + result_pka_pymol.write("cmd.remove('%s')\n" % (tempname)) + result_pka_pymol.write("cmd.remove('%s')\n" % (tempnamelabel)) + # Delete the temporary molecule/selection + result_pka_pymol.write("cmd.delete('%s')\n" % (tempname)) + result_pka_pymol.write("cmd.delete('%s')\n" % (tempnamelabel)) + # Group the resi together + result_pka_pymol.write("cmd.group('%sLigands','%sLig*')\n" % (newmolecule, newmolecule)) + # Finish the pka atoms, and show spheres + result_pka_pymol.write("cmd.show('spheres','%s')\n" % (pkamolecule)) + result_pka_pymol.write("cmd.spectrum('b','red_white_blue',selection='%s',minimum='0',maximum='14')\n" % (pkamolecule)) + result_pka_pymol.write("cmd.alter('%s and name 99.9','vdw=0.8')\n" % (pkamolecule)) + result_pka_pymol.write("cmd.show('spheres','%s and name 99.9')\n" % (pkamolecule)) + result_pka_pymol.write("cmd.color('sulfur','%s and name 99.9')\n" % (pkamolecule)) + # Now we make the bonds + if writebonds == "yes": + Bondgroups = [] + naturalaminoacids = ['ASP', 'GLU', 'ARG', 'LYS', 'HIS', 'CYS', 'TYR', 'NTR', 'N+', 'CTR', 'C-', 'GLN', 'ASN', 'SER', 'THR', 'GLY', 'PHE', 'LEU', 'ALA', 'ILE', 'TRP', 'MET', 'PRO', 'VAL'] + for l in bonds: + if l[0] in naturalaminoacids: + name = dictio[l[0]] + resi = l[1] + chain = l[2] + desolvation = l[6][12:] + pkachange = l[11] + NBresi = l[8][3:] + NBchain = l[9] + NBbond = l[-1][:2] + if l[8][:3] in naturalaminoacids: + NBname, cutoff = BondTypeName(dictio[l[8][:3]], NBbond) + fromselection = ("/%s//%s/%s/%s" % (newmolecule, chain, resi, name)) + toselection = ("/%s//%s/%s/%s" % (newmolecule, NBchain, NBresi, NBname)) + if l[8][:3] == 'NTR': + extind = cmd.identify("chain %s and name N" % (NBchain))[0] + toselection = ("/%s and id %s and name N" % (newmolecule, extind)) + NBresi = "N+" + if l[8][:3] == 'CTR': + extind = cmd.identify("chain %s and name C" % (NBchain))[-1] + toselection = ("/%s and id %s and name C" % (newmolecule, extind)) + NBresi = "C-" + distname = ("%s_%s%s%s%s_%s_%s" % (newmolecule, chain, resi, NBchain, NBresi, NBbond, pkachange)) + result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff)) + result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname)) + # result_pka_pymol.write("cmd.disable('%s')\n"%(distname)) + Bondgroups.append("%s%s" % (chain, resi)) + if l[8][:3] not in naturalaminoacids and Check_bonding_partners(bonding_partners, l[8])[0]: + cutoff = "" + NBresn = Check_bonding_partners(bonding_partners, l[8])[1] + NBname = l[8][len(NBresn):] + "*" + fromselection = ("/%s//%s/%s/%s" % (newmolecule, chain, resi, name)) + toselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, NBchain, NBresn, NBname)) + if verbose == 'yes': + print("Res->Ligand: (%s) -> (%s)" % (fromselection, toselection)) + result_pka_pymol.write("cmd.show('sticks','%s')\n" % (toselection)) + distname = ("%s_%s%s%s_%s_%s" % (newmolecule, chain, resi, NBresn, NBbond, pkachange)) + result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff)) + result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname)) + # result_pka_pymol.write("cmd.disable('%s')\n"%(distname)) + Bondgroups.append("%s%s" % (chain, resi)) + if l[0] in bonding_partners: + resn = l[0] + atom = l[1] + chain = l[2] + desolvation = l[6][12:] + pkachange = l[11] + NBresi = l[8][3:] + NBchain = l[9] + NBbond = l[-1][:2] + if not Check_bonding_partners(bonding_partners, l[8])[0]: + NBname, cutoff = BondTypeName(dictio[l[8][:3]], NBbond) + fromselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, chain, resn, atom)) + toselection = ("/%s//%s/%s/%s" % (newmolecule, NBchain, NBresi, NBname)) + if l[8][:3] == 'NTR': + extind = cmd.identify("chain %s and name N" % (NBchain))[0] + toselection = ("/%s and id %s and name N" % (newmolecule, extind)) + NBresi = "N+" + if l[8][:3] == 'CTR': + extind = cmd.identify("chain %s and name C" % (NBchain))[-1] + toselection = ("/%s and id %s and name C" % (newmolecule, extind)) + NBresi = "C-" + distname = ("%s_%s%s%s%s%s_%s_%s" % (newmolecule, chain, resn, atom, NBchain, NBresi, NBbond, pkachange)) + result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff)) + result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname)) + Bondgroups.append("%s%s%s" % (chain, resn, atom)) + # result_pka_pymol.write("cmd.disable('%s')\n"%(distname)) + if Check_bonding_partners(bonding_partners, l[8])[0]: + cutoff = "" + NBresn = Check_bonding_partners(bonding_partners, l[8])[1] + NBname = l[8][len(NBresn):] + "*" + fromselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, chain, resn, atom)) + toselection = ("/%s and chain %s and resn %s and name %s" % (newmolecule, NBchain, NBresn, NBname)) + if verbose == 'yes': + print("Ligand->Ligand: (%s) -> (%s)" % (fromselection, toselection)) + result_pka_pymol.write("cmd.show('sticks','%s')\n" % (toselection)) + distname = ("%s_%s%s%s%s_%s_%s" % (newmolecule, chain, resn, atom, NBresn, NBbond, pkachange)) + result_pka_pymol.write("cmd.distance('%s','%s','%s'%s)\n" % (distname, fromselection, toselection, cutoff)) + result_pka_pymol.write("cmd.color('%s','%s')\n" % (SetDashColor(NBbond), distname)) + # result_pka_pymol.write("cmd.disable('%s')\n"%(distname)) + Bondgroups.append("%s%s%s" % (chain, resn, atom)) + Bondgroups = uniqifi(Bondgroups) + for l in Bondgroups: + result_pka_pymol.write("cmd.group('%sBonds_%s','%s_%s*')\n" % (newmolecule, l, newmolecule, l)) + result_pka_pymol.write("cmd.disable('%sBonds_%s')\n" % (newmolecule, l)) + result_pka_pymol.write("cmd.group('%sBonds','%sBonds_*')\n" % (newmolecule, newmolecule)) + result_pka_pymol.write("cmd.set('auto_zoom','on')\n") + # result_pka_pymol.write("cmd.feedback('enable','all','actions')\n") + # result_pka_pymol.write("cmd.feedback('enable','all','results')\n") + result_pka_pymol.close() + return(result_pka_pymol_name) + + +def replace_all(text, dic): + for i, j in dic.items(): + text = text.replace(i, j) + return(text) + + +def uniqifi(seq, idfun=None): + # Order preserving + if idfun is None: + def idfun(x): + return x + seen = {} + result = [] + for item in seq: + marker = idfun(item) + if marker in seen: + continue + seen[marker] = 1 + result.append(item) + return(result) + + +def BondTypeName(NBname, NBbond): + if NBbond == "SH": + cutoff = "" + return(NBname, cutoff) + if NBbond == "BH": + cutoff = "" + return("N", cutoff) + else: + cutoff = "" + return(NBname, cutoff) + + +def Check_bonding_partners(bonding_partners, NBname): + answer = False + for l in bonding_partners: + if l in NBname: + answer = True + NBname = l + break + else: + answer = False + return(answer, NBname) + + +def SetDashColor(NBbond): + if NBbond == "SH": + color = "brightorange" + if NBbond == "BH": + color = "lightorange" + if NBbond == "CC": + color = "red" + return(color) diff --git a/.pymol/startup/propka.pyc b/.pymol/startup/propka.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ee65c3d5a387ac4b34a3c08491782f3c1663b0a GIT binary patch literal 32049 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 settings + settings = [] + for r in representations.split(): + if r[-1] == 's': + r = r[:-1] + s = r + '_color' + if s in cmd.setting.name_list: + settings.append(s) + elif not quiet: + print(' Warning: no such setting:', s) + + # object names only + selection = ' '.join(cmd.get_object_list('(' + selection + ')')) + if cmd.count_atoms(selection) == 0: + print(' Error: empty selection') + raise CmdException + + if last < 1: + last = cmd.count_states(selection) + + val_range = int(last - first + 1) + if val_range < 2: + print(' Error: no spectrum possible, need more than 1 state') + raise CmdException + + for i in range(val_range): + p = float(i) / (val_range - 1) * (len(colvec) - 1) + p0, p1 = int(floor(p)), int(ceil(p)) + ii = (p - p0) + col_list = [colvec[p1][j] * ii + colvec[p0][j] * (1.0 - ii) for j in range(3)] + col_name = '0x%02x%02x%02x' % (col_list[0] * 255, col_list[1] * 255, col_list[2] * 255) + for s in settings: + cmd.set(s, col_name, selection, state=i + first) + +cmd.extend('spectrum_states', spectrum_states) + +# tab-completion of arguments +cmd.auto_arg[0]['spectrum_states'] = cmd.auto_arg[0]['disable'] +cmd.auto_arg[1]['spectrum_states'] = [cmd.auto_arg[0]['show'][0], 'representation', ' '] +cmd.auto_arg[2]['spectrum_states'] = [cmd.auto_arg[0]['color'][0], 'color', ' '] + +# vi:expandtab:smarttab diff --git a/.pymol/startup/spectrum_states.pyc b/.pymol/startup/spectrum_states.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4491a2c12939a94783847386a5c9e196bcd86e32 GIT binary patch literal 2857 zcmbVOOK%)S5U$y^*Y@}sKV#s~1O=@X+iP2#tUw616(WIy){ZP3%xb*Twr4#rPxtyE zb}ocp5^>!*Z}7|rx_S5;S4e^u4p<-dmA)8D@Nx=G!q5C2ce zA@eIbKG7~(hx`(S4n-x}Es?|HGKFP|dT6(YqF&nV1+|C#Uh*sC_mST(?Ew8yq1_7U z9%_N;lCIEeDBv+9`f1i5q}dxImmc334S~-x!{m?9VOi9O;#sJ=DLC2{9K9_#1~LTw zd$d&@$7+m0;~rU?uGVVlMU;eR!EvydWQVmN_VxKvC@{IaC34NWp?iWE*$40NJ&$iYVRu zVBC(NNwXlfje~aFv_TSAOH41LX-2*s!hbFDH_n?nWv(#1Ff=@|>18%aVwDB^`$=rx z2WdZSYt_8)Vs)5l9jgl+hRK;qGA};VD${Y2Wq(p{#y_*x(ebniom zmFFYWfx!Z{A4TEFZH4E5lfB16kY3;WUBDafBF9sQ>HZYs?}}#_P3EIwr$U`krr~9? zSn%brl#fvkomkHp-OtAvc-ZiTzrHt5`2_3h+@smf1io>a`ctpwQAKH{4Q6>vF-&T*#YPwy%cFxJ zD>|Wv{~kZC`?UV-<(C_q+gn{5R~kQtlh^?cS5?=m*o(AL)w3i!HtH;}M^GQ7p|-j! zVN?=_7jv@K?|gmWVP&fdyFy;*zU$z%1(SMBjn$-HhRw`Z;&F0tcS(0N-`;1sMs6(m zzx9i-QP<91?NegvU-l|k+S=GqPrulDaXT>c>M}%Ld?6Z&EmgM8UL?jrm?W9)L9eNU zFkrf=qEQ=JmSn36XnIDgG)qncUn|clCRnvnMABH^B@Jqss8RU-4$t24vREP&C(5)r zy|lGV5P2nSRoXe(V$IAAn>tGE#dRjhMr=O1A;3zzhmA@TV}kuq&#PD?PEnF+Wsk6} zFBd5t@Bx7u<>!wlavCh1KU`Y5`hvIMU=!eFAk>@HNggvIk!O$U+^I7c`vA^^*cPH` z7+9f%NN;A#*;Hrz>T+IjGiS`hraG}W;$mRku7U1}(j zy^tHktY*^2Dd^cGGIHt_sDZ`;3D(I2#*h=1q%jNV)o``YwSBLxv)ZEER%$>eLk#ZTQNR@lF0-k7b>S<6 zS!bp1PM1D(hMaN7bp}cg$`xnA8FPj)8pprlOqP{1B|ONKCLzgk6V3zYA$m`oN06=8 zphrUQ2gXCD3XbL|Ig>lhZS?EBEWuZ>lzQB(a;}JmM#E2= 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 + + +def tmscore(mobile, target, args='', exe='TMscore', quiet=0, **kwargs): + ''' +DESCRIPTION + +TMscore wrapper + +Reference: Yang Zhang and Jeffrey Skolnick, Proteins 2004 57: 702-710 +http://zhanglab.ccmb.med.umich.edu/TM-score/ + +ARGUMENTS + +mobile, target = string: atom selections + +args = string: Extra arguments like -d 5 + +exe = string: Path to TMscore executable {default: TMscore} + +ter = 0/1: If ter=0, then ignore chain breaks because TMscore will stop +at first TER record {default: 0} + +SEE ALSO + +tmalign, mmalign + ''' + kwargs.pop('_self', None) + return tmalign(mobile, target, args, exe, quiet=quiet, **kwargs) + + +def mmalign(mobile, target, args='', exe='MMalign', ter=0, transform=1, quiet=0): + ''' +DESCRIPTION + +MMalign wrapper + +Reference: S. Mukherjee and Y. Zhang, Nucleic Acids Research 2009; 37: e83 +http://zhanglab.ccmb.med.umich.edu/MM-align/ + +SEE ALSO + +tmalign, tmscore + ''' + return tmalign(mobile, target, args, exe, ter, transform, quiet=quiet) + +# pymol commands +cmd.extend('alignwithanymethod', alignwithanymethod) +cmd.extend('tmalign', tmalign) +cmd.extend('tmscore', tmscore) +cmd.extend('mmalign', tmalign) + +# autocompletion +cmd.auto_arg[0].update({ + 'tmalign': cmd.auto_arg[0]['align'], + 'tmscore': cmd.auto_arg[0]['align'], + 'mmalign': cmd.auto_arg[0]['align'], +}) +cmd.auto_arg[1].update({ + 'tmalign': cmd.auto_arg[1]['align'], + 'tmscore': cmd.auto_arg[1]['align'], + 'mmalign': cmd.auto_arg[1]['align'], +}) diff --git a/.pymol/startup/tmalign.pyc b/.pymol/startup/tmalign.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2cc90cf74b10747e429de5013d681389f323e4b GIT binary patch literal 7810 zcmb_hOLH7Ya?b7b=zHqwPLw^wV}f`103I-?`6yl^*hUn8? z+6EC_mxMAb%-{iKluS}ENn6D!?16b3 zMWN`=s^!I{rFj&~>iJ&W@QnItTn}_Ir`9*0scM|4RsBlW<7PugsaIF;hH*XKJuZa* zi=QGkkt4&~q6{1mW*abINw&06)^vdqOiKQ^|btK^ZBz6HwuL<@0C`YtM966Sl8+>O!wkes-CZv zRigbk2~0_?9i=*nU>UF3tcSiQ>sR$~U#sWqUOn86loths)#GS2ZYYz+O^o$|Fxov8 zY?OCS=$ty-3;jLS2zU2VwWC!l3bY9m9jGuW_@2=!uAf5d}$MW>8yzU+IM%ucecPQuDYG*B4CcC26aMMBRPdG?W-ORqt9*&pF6@Gew72hkxHe)a`A@>IhxP>CiGq9)LV7&Y~U zL!S|ShSH_aa`aiAs$lD-zlFG7I@)6Ct1sWDPM>(|@2TBGwO&F9YoqL^b{|#YkeCMb zeya8HX@_iw8~v=6bMOiCf|1E+yb!-FU`1vHt3B_xPsH#1xEX3Az7p@S1E;Zq;j#PT z%F5tmC+xY*&F5QTYxm;76betuKl$1E+Q##(LZM;DK8Ek&kngU*S=o_KcE3=_M1C_v zCRKGgOw;o`Zd^1(U1bP(3i)TX+$Y)35 z;J`jK%0Bc4!LJYe>2i}6X%p4MqAUq5Gr{mx?lU3L9aHJwcDn5)GqG83{Kz+t2YmmpN!3Z;EF56@f%mg^z z3!~8N>0kwYsyI_xuEO&EY>}5_W5OlWI3~0r1dgC0N1S_oM5Zflt;@lH(`4_YB&56^11v^;|99~(q?6C1~} z1U7z) zj7jbmZeEM1`bR|B%NQf(;RuWKV)yMPsD=g8$N(%g;7mE!+-v=Vu-G+c&>3{$+0chI z&+asPIQl`D#)nP#ln)1@-kAUkTy}!(IzVT(?otN;&DL|&xyakm&P%XGMZ%lg$xEcX zkOf-=S{$d&0JTpkJwh2gp-3oYo*{{*MB^PmH^fp0wPBW@`~zW|5Li1S6!r3ThDsZM zka|f@D>oo;SQ^ZGA-e=D#9&4Nl3 zm#KZ3YJ*f8l1MO0FQOUBr)X{G`Bk7?-o>JRPB5ITShc5l8rTfohPzqHr15 z2H++dA8~7xYGVY2KuCV$v_~nuk~Qsgk2<3#B7`Z!I~@$VNVN$@$r#$X!Z5WnPP+(I z6O>L8Br$zbC{uJa@3bdzfz3Fbs}u}Tdz|vQ{T_<{$HBn;JVh?KPV$k94xnrFB=5WF z6s1=wy+-Y;R1;HSgIFpk6I8oS?P~(Xhv_z`4%2Q3ZG@(nfPly1M(7bVi~df;++-Wp zZZSv)OY+J^H}^KB7j)4(`K^nUq>2Et!M6Hxk~)}fl4`eQ{4|%paOvRh-Odz6_o;n_ zYHzRzaCe}@4Gz@%7by8pm-W9vwI8q|=w*g6V%7S{{DHTQS0@6|3f;+U2`{S>3>6`31*0!Ac*uN3lmDA<$Im5Am+5RQR?tO=lJ>a$(#|Y#F zygt_vtK&4;<-gMdJL1pn+@#Je3gM48DVU;%ZJ7EhJ?tnsR7E~Q0d^B=E0MzTL50pR z(F{QI-OtJd%9({~Md!0JBsePM*o4k_bULLd5?urTEF}O$%?&b0KqC5VQxX3q* z-_Jw6^W*pP2mARKY%+KdE^1V6aRpxNQv7fEY=^8^kgPv1_3%3GQ2=ps6e!L&(|MM` z+sSSUR0k>e%UEuou-y6@mTB3NH~0VrKVUHT+RZr!@AUB2&aecv=*MP&&$oSP$>Lt>&Z{n01Pd<&+y3!EKxt7Q+)gKw?5M9<;$;uo2SfO z%y=Gl0;7tMZa)&S#AC@BPLvdEK3G%_)cgl(X>qYo;OV*pHobI@A@PaH(CfESZwElR z3m>!24pxISgi_mgUM+)dUPPFp(Jm9Y#fQWsAtj*{2_Eh*`Sg%X= zS3s_3ab`D-JTu=SX4+a?Q%^qF`j9PXkY?&R1whO=_AFp!6jMU7)P)vCNa>LUBn=OE z{m9ILtvF+5Wz&mMoT@#YdTGNF80x8~Po&eUr|RAl!ys?I0ndkjr2+C?vw`YUFXFM* zMp{kJnCUsyMCOP!Hk0^O7-&^(VU5jGtBUFXCLB4`l7jcTmWy#Llq= zZUDk&R&Xe?(|8vHTIMV)4TB?TS}+MOfmmW`b!oql%3<(DgZh z@IW8U&Sn4-iH?ly3i|&?a?&v`@K5F2{xZ>=t^nB0!bDlIKH%KaV^%#Q#5QhYV_^lq+#IqHjJl_n#nu=#AA8J z-fr6TC)B#U1kvSXF7BiF{`&qNQZjwT+x=s|t}`d_Qh%?3yfcv=>oVpR20V>h^+54a zsK;J#CUri;^InVx8_vaWc$)lPlsP)W$4u#m)lmGj1YzP~rnQ3u1TQi2#**qrliyin zlVT%Zi7xZpqDy0+IV2Y;O9sc%WF$7B!l$pya9+G`Glq*wy0iIgbFF-r>AYo}=hVXp zi|s?}!>zR>iIXzF43&BRWS#^G4BmkF6tYmE=_6!2Mrfy!H{wW(7-a2D)?3ak!lP6q zJz^(lcui5M3bWbxr15YT1tQlTCF!rnhZri)8aOej;XFk;65KpiIK0hDK(d~MO_5-< zm-v=(H;G$K@ohX-$>Zb`V;~cOLe?pdWVk9KgV)Ul-oZ|uvDg+N6z7zet)wH|B+_C# zhj<%HQdw!zFcrUL7g&pt8S(-@37f@fe0Rff`8t}?hrlP_Y!#M#I(zvckC1Hc5!Zgi z#ampgpg@vv8gWja-k6rfl5;d011qPrq3&4UlU0f>vY{DCJV@4b;({D&t!r>pNW`%c zU6DX-8}XqJ|4z%ZtO(nT*(*qsd1Z1-@jFen`|u5x<4GCHMnX}4ugup{d7cY72<&#A z_g&7ksE{Fz_aMdm1_fQWdF+5YR z*%^0+!NKp0;KgUqxsLB^&KQ0Noh!}-^p!Ar03&;y3Gm(leaabeC!Hx5Zw$Esw8tQ4 z9PbSSczLkpGPvJx-gL&@L3b3~qV)51v8p^%vWNBKBX8Vn8-5_Pxinso0D%z)5cCn; z5$lmEa%w1e{?~cOz6qIsgrU#B0%jAauf>9l1J9sAU9Bei_zWc6#Oe02|;-5#DaV zFSw(^1#iW7-h~Y3{|96UG@-%rn=F)fzue;D5QVslXuDD57d_dhN+pQ>N=5F@3jP(B zwh*@~{QokGGb$CYh1dNAEEhqmRPgw3a4DX)@!ub8a*BDa!_V7{!z715}s_SvD|7uRET*Fr0HP Z-MRKRm#= cutoff, scores)) + + # filter for score floor + scores = list(filter(lambda x: x[2] >= floor, scores)) + + # show distances + counter = 0 + for score in scores: + if counter > max_contacts: + print("max contacts reached! (%s contacts not shown)" % (len(scores)-int(max_contacts))) + break + print("new msa contact between %s and %s" % (score[0], score[1])) + name = "msa{}-{}_{:.3f}".format(score[0], score[1], score[2]) + seleA = "resid %s and n. CA and %s" % (score[0], selection) + seleB = "resid %s and n. CA and %s" % (score[1], selection) + if cmd.select("seleA", seleA) == "0" or cmd.select("seleB", seleB) == "0": + continue + cmd.distance(name, seleA, seleB) + counter += 1 + + cmd.delete('seleA') + cmd.delete('seleB') + + +def read_scores(scores_file): + scores = [] + if not isinstance(scores_file, file): + scores_file = open(scores_file, 'r') + for line in scores_file.readlines(): + split = line.split(",") + resA = int(split[0]) + resB = int(split[1]) + score = float(split[2]) + dist = abs(resB - resA) + scores.append([resA, resB, score, dist]) + scores_file.close() + return scores + +def remove_scores(): + cmd.delete("msa*") +cmd.extend("remove_scores", remove_scores) +cmd.extend("show_scores", show_scores) diff --git a/.pymol/startup/visualize_dca_scores.pyc b/.pymol/startup/visualize_dca_scores.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ac321146e40c34d5b71028e63822276100df0c9 GIT binary patch literal 3846 zcmb_f&2Ah;5U$=o@A{u4BsL<^1QfEM#0~@r$%+EDgW-^@!>p5lCA1pPw4L$JkF(vI z7~Z@}3@2TK$$W{D5~XF@ER!naDzsUl2vb#x(66!F<`_j)dW24$ zqMCFX6k)PXx<(q3P}iVGRoa}OXj}v)DVmVZ6zMYUPE#~VdWsH9q>3>XCS;7=?dCL0 zjsL-?)l}%(GMX@r;&J@lxh$VQKMr|`p9Y>)JmvzL1EO90U;}<7Ha?OgppPZCT+v~< z#3yVw`EFX4+nY&$C(i5`x?!HCK^7T)*^TzH*ADZZHnxgk5^U*Y^xhI?+IU3L%Bv6A zdbX)B{1|V_gQ#OfNhgYfB;Rp|VlmT1L(-TJ&|AElr+RTK= zqm%7dV@0PEXR+;cCRr;RKuYe4Z*JtHUopU4J?Ef9Dh(7J2oSq<>NOc@ZTNi`&I6=? zyfK0c05V|fuv8kro$xLZOWz(zLvCDtkRF4a8kFe(5O8weJu3%r0+x`gi(G{c@G2+w z)X4$XQ)1J!ylX}@&9dAfRUCj`!)aQUk-|rZbECLt*|7_P7aQ9|8@~GM0D_29dYs1A3-ind zp*3cXg@Sz%8cupP_sre=f!OejImN5lQ`%9jZ(> z-_zMPW^DyhEu6)&J+|A9)4h=_YY0piQKolvPb98=y0(1l`bKB<*2enUnj91oupqFO z&p2FPyS~2e+Y`^s+*tmyv%22eSYF*|ixqsTA}X4E4B?DmZ_h2d=wlOo4oUwwH>~fa zk?-@7*^TB6G^FO#q^hVh(z?EDojpk+WZ`apAvE_xwv}&&Nr-9A{0t8xKpqo;OnyXP z(PK~+`id-2FMR|HWEhEx1`fK@917-hfw7`)iF$Vk{wU-tltERM;P@ZlW8uc{p#j=T zq67-vs*=?*J+}%L9aL%mFWz$P>py5vqk}5HtXrYpZycnfmyIl&JNen?H}PJC?*SsS zLi7A*jOMpXge3&??$~oHEYP6&!!iw!QpQKCuo-&>2!A&RC7^SeYj6nfB3LKrfMc2C z8pk(JhVuww=8R&#r`5eDavRtMWw4+w0!Vu}5zPAt2ZhKTRtuIuUQ(or0g@I5(KKjY zoc=pp=G`7rvx{&Ke)Yz^;sbuwp^fuw$!ib0-ge&ehJ+sQ;z(S=Z^=WvOW+Dp{zu#e z?vZ>HBVS~p_O`TrpmpX2(3E>Y7$c#LOpa2bNFF=a^#qkXgHfH z@d8ro{2cJwt>RW#rX?&DqgTWiZx&kIm%Jk}D3SMqNzdnKS->O7Ze$**l8tE01C^PD-F&2lT8oV{z# zVn?PQc&Q17>mx^E3#tp zN>*Y-E{i)Zjm9gjCg&YtDKNCmJ09lj1;d9WjDKnke1v(cU2J zKXvTl8(76-enGQCRIs|(}J5@$t4ZT6Db`tM-gKaa*`$t@$` zK=#&IB%ThF+~_9XrSEaW=qSLKX@6-r0`8Y(8l4rN3u+lLbqc7dP(;M_z6jt{o7>?@75X(c&*+>d02?=!F^kNL0jkPjx;E&qAA=oJ$Kd)Mdk#($HW)7-GHrS=g* z5KTT?D~iQ^df&o*ujnjwsJ@csQ9sdF%jiqB#lbj>aIC=@wNj(pn3-!frW>VM^)CSW BDH8wy literal 0 HcmV?d00001 diff --git a/.pymolrc b/.pymolrc new file mode 100644 index 0000000..4832bb2 --- /dev/null +++ b/.pymolrc @@ -0,0 +1,4 @@ +set opaque_background, 0 +log_open /tmp/pymol_log.pml +set cartoon_side_chain_helper, 1 +set cartoon_highlight_color, grey50