#!/usr/bin/env bash # #Version: 2.4.0 #Author: Sebastien Moretti #Lab. : Information Genomique et Structurale - IGS # CNRS - Life Sciences # Marseille, France #E-mail: moretti.sebastien [AT] gmail.com # echo -e " ############################################################################################ # # #This script, and the ones it contains, are developed under the GNU General Public License.# #So, you are free to # # - execute this program, whatever the usage # # - study this program and to adapt it for your needs # # - copy this program # # - enhance this program and to publish these enhancements # # # #Nevertheless, you MUST always retain the original authorship with every copy you could # #make of this program. # ############################################################################################ " #Test if 'perl' is set PERL=`which perl` if [ -z $PERL ]; then echo -e "Perl has not been found in your regular PATH\nIt must be set to be able to use this plugin\n" exit fi WGET=`which wget` if [ -z $WGET ]; then echo -e "wget has not been found in your regular PATH\nIt must be set to be able to use this plugin\n" exit fi #Get the most probable pymol.com location EXEC='pymol' PYMOL=`which $EXEC 2>/dev/null` if [ -z "$PYMOL" ]; then EXEC='pymol.com' PYMOL=`which $EXEC 2>/dev/null` fi if [ -z "$PYMOL" ]; then EXEC='pymol.exe' PYMOL=`which $EXEC 2>/dev/null` fi if [ -z "$PYMOL" ]; then echo -e "'pymol', or 'pymol.com', script cannot be reached\n" fi PYMOL_PATH=`perl -e 'while(<>){print $1 if $_ =~ /^PYMOL_PATH=(.*)$/;}' $PYMOL` #Ask where the plugin must be set echo -e "Where is PyMOL home directory, the location of '$EXEC' ?\n[${PYMOL_PATH}]" read WHERE #Set PyMOL plugins directory if [ -z "$WHERE" ]; then WHERE="${PYMOL_PATH}/modules/pmg_tk/startup/" else WHERE="${WHERE}/modules/pmg_tk/startup/" fi #Test if the directory exists and is writable if [ -d "$WHERE" ] && [ -w "$WHERE" ]; then echo -e "Processing ...\n" else echo -e "\n\nThe directory doesn't seem to be useable:\n\tThat is possible it doesn't exist,\n\tis unwritable for you,\n\tor the whole PyMOL repository is altered\n\n" exit fi #Extract scripts from the installation program tail -448 $0 |head -394 >rasmol2pymol.pl tail -51 $0 >remote_ConSurf_load.py #Change the path for the perl scripts perl -p -e 's/\047*rasmol2pymol/\047${ARGV[0]}rasmol2pymol/' remote_ConSurf_load.py $WHERE >remote_ConSurf_load.pyt mv -f remote_ConSurf_load.pyt remote_ConSurf_load.py perl -p -e 's/PYMOLHOME/${ARGV[0]}/' rasmol2pymol.pl $WHERE >rasmol2pymol.plt mv -f rasmol2pymol.plt rasmol2pymol.pl #Copy the scripts and remove the former ones rm -f ${WHERE}remote_ConSurf_load.py ${WHERE}remote_ConSurf_load.pyc rm -f ${WHERE}rasmol2pymol.pl rm -f ${WHERE}Legend.dx mv -f rasmol2pymol.pl remote_ConSurf_load.py ${WHERE} touch ${WHERE}Legend.dx chmod ug+x ${WHERE}rasmol2pymol.pl echo -e 'ConSurf-HSSP plugin for PyMOL has been set ' exit ######@### #!/usr/bin/env perl use strict; use warnings; use diagnostics; use Getopt::Long; use File::Basename; =head1 SYNOPSIS Rasmol script converter for ConSurf results rasmol2pymol.pl --ras=rasmol_script.ras --pdbFile=pdb_file or rasmol2pymol.pl --pdbCode=pdb_ID or rasmol2pymol.pl --pdbCode=pdb_IDCHAIN (if several chains) e.g.: rasmol2pymol.pl --pdbCode=1hcl e.g.: rasmol2pymol.pl --pdbCode=1cdkB (for chainB) =head1 DESCRIPTION =over 4 =item ConSurf =item Server for the Identification of Functional Regions in Proteins =item Identification of functional regions in proteins by surface-mapping of phylogenetic information. =item http://consurf-hssp.tau.ac.il/ =item Cyan => Variable positions =item . =item . =item . =item White => mid-variable positions =item . =item . =item . =item Violin => Conserved positions =back =head1 VERSION =over 4 =item Version: 2.4.0 =item License: GNU General Public License =back =head1 AUTHOR =over 8 =item Sebastien MORETTI =item moretti.sebastien [AT] gmail.com =item Lab. Information Genomique et Structurale - IGS =item CNRS - Life Sciences =item Marseille, France =back =cut #Options my $pdb_code=''; my $pdb_file=''; my $rasmol_file=''; GetOptions("pdbCode=s" => \$pdb_code, "pdbFile=s" => \$pdb_file, "ras=s" => \$rasmol_file); my $counteur=0; if ($pdb_code =~ /^\d\w\w\w$/){ my $pdbID=lc($pdb_code); my ${PDB_CODE}=uc($pdbID); unlink("${PDB_CODE}.pml"); ###On whole structure $counteur=0; for(my $rep=0;$rep < 1; $rep++){ $counteur++; `wget -O ${pdbID}.list 'http://consurf-hssp.tau.ac.il/cgi-bin/consurf-hsspNew.cgi?TMPL=indexPDB&pdb_ID=${pdbID}'`; last if ($counteur > 10); $rep=$rep-1 if ( -z "${pdbID}.list" ); } if ( -z "${pdbID}.list" ){ `touch pdb${pdbID}.ent`; open(PYMOL,">${PDB_CODE}.pml"); print PYMOL "cls\nprint \"The structure is not reachable from ConSurf server\"\n"; close PYMOL; exit; } open(LIST,"${pdbID}.list"); my $flagg=0; my @chain_list; while(){ if ($flagg==0 and $_ =~ />${pdbID}${PDB_CODE}.pml"); print PYMOL "cls\nprint \"The structure you seek for is not currently available on ConSurf\"\n"; close PYMOL; exit; } print STDERR "[@chain_list]\n"; for(my $t=0; $t <= $#chain_list; $t++){ if ( !-e "pdb${pdbID}.ent" ){ $counteur=0; for(my $rep=0;$rep < 1; $rep++){ $counteur++; `wget -O pdb${pdbID}.ent 'http://consurf.tau.ac.il/results/HSSP_ML_${pdbID}${chain_list[$t]}/pdb${pdbID}.ent'`; last if ($counteur > 10); $rep=$rep-1 if ( -z "pdb${pdbID}.ent" ); } if ( -z "pdb${pdbID}.ent" and $t<$#chain_list){ unlink("pdb${pdbID}.ent"); } elsif ( -z "pdb${pdbID}.ent" and $t==$#chain_list){ open(PYMOL,">${PDB_CODE}.pml"); print PYMOL "cls\nprint \"The structure you seek for is not currently available on ConSurf\"\n"; close PYMOL; exit; } } $counteur=0; for(my $rep=0;$rep < 1; $rep++){ $counteur++; `wget -O colors.txt 'http://consurf.tau.ac.il/results/HSSP_ML_${pdbID}${chain_list[$t]}/colors.txt'`; last if ($counteur > 10); $rep=$rep-1 if ( -z 'colors.txt' ); } if ( -z 'colors.txt' ){ open(PYMOL,">>${PDB_CODE}.pml"); print PYMOL "cls\nprint \"ConSurf has planed ${pdbID}${chain_list[$t]} to process but it is not currently available\"\n"; close PYMOL; } my $rasmol_script='colors.txt'; my $pdb_file="pdb${pdbID}.ent"; ${chain_list[$t]}='' if (${chain_list[$t]} eq '_'); &header_script($pdb_file) if ($t==0); &split_chains($pdb_file,${chain_list[$t]}); &script($rasmol_script,$pdb_file,${chain_list[$t]}) if ( ! -z 'colors.txt' ); &footer_script($pdb_file) if ($t==$#chain_list); } unlink('colors.txt'); ### } elsif ($pdb_code =~ /^\d\w\w\w\w$/){ my $pdbID=lc($pdb_code); my ${PDB_CODE}=uc($pdbID); unlink("${PDB_CODE}.pml"); my $chain=$pdbID; $pdbID =~ s/\w$//; $chain =~ s/(\w)$/\U$1/; my $name=lc($chain); $counteur=0; for(my $rep=0;$rep < 1; $rep++){ $counteur++; `wget -O pdb${name}.ent 'http://consurf.tau.ac.il/results/HSSP_ML_${chain}/pdb${pdbID}.ent'`; last if ($counteur > 10); $rep=$rep-1 if ( -z "pdb${pdbID}.ent" ); } if ( -z "pdb${name}.ent" ){ open(PYMOL,">${PDB_CODE}.pml"); print PYMOL "cls\nprint \"The structure you seek for is not currently available on ConSurf\"\n"; close PYMOL; exit; } $counteur=0; for(my $rep=0;$rep < 1; $rep++){ $counteur++; `wget -O colors.txt 'http://consurf.tau.ac.il/results/HSSP_ML_${chain}/colors.txt'`; last if ($counteur > 10); $rep=$rep-1 if ( -z 'colors.txt' ); } if ( -z 'colors.txt' ){ open(PYMOL,">>${PDB_CODE}.pml"); print PYMOL "cls\nprint \"ConSurf has planed this structure to process but it is not currently available\"\n"; close PYMOL; unlink('colors.txt'); exit; } $chain =~ s/^....//; $chain='' if ($chain eq '_'); my $rasmol_script='colors.txt'; my $pdb_file="pdb${name}.ent"; &header_script($pdb_file); &split_chains($pdb_file,$chain); &script($rasmol_script,$pdb_file,$chain); &footer_script($pdb_file); unlink('colors.txt'); } elsif ($pdb_code eq '' and -e $rasmol_file and -e $pdb_file){ &header_script($pdb_file); &script($rasmol_file,$pdb_file,''); &footer_script($pdb_file); } else{ system("perldoc $0"); exit; } sub header_script{ my ($pdb_file)=@_; my $PDB_ID=$pdb_file; $PDB_ID=basename($PDB_ID); $PDB_ID =~ s/^(.+)\..*$/$1/; my $PDB_CODE=$PDB_ID; $PDB_CODE =~ s/^pdb//; $PDB_CODE=uc($PDB_CODE); open(PYMOL,">${PDB_CODE}.pml"); print PYMOL "load $pdb_file\ndss $PDB_ID\nhide all\ncreate nt, resn a+c+g+t+u+n+r+y+m+k+s+w+h+b+v+d\nshow cartoon, nt\nshow sticks, nt\n"; print PYMOL "create aa, ${PDB_ID} and ! resn a+c+g+t+u+n+r+y+m+k+s+w+h+b+v+d\nshow surface, aa\ncolor gray, aa\nshow stick, het\nhide (solvent)\n"; print PYMOL "set_color Cons_9c = [0.6, 0.1, 0.4]\nset_color Cons_8c = [0.9, 0.5, 0.7]\nset_color Cons_7c = [1.0, 0.8, 0.9]\nset_color Cons_6c = [1.0, 0.9, 1.0]\nset_color Cons_5c = [1.0, 1.0, 1.0]\nset_color Cons_4c = [0.9, 1.0, 1.0]\nset_color Cons_3c = [0.8, 1.0, 1.0]\nset_color Cons_2c = [0.5, 1.0, 1.0]\nset_color Cons_1c = [0.1, 0.8, 0.8]\nset_color allc = [0.8, 0.8, 0.8]\ncolor allc, all\nset_color C9 = [0.6, 0.1, 0.4]\nset_color C1 = [0.1, 0.8, 0.8]\n"; close PYMOL; } sub split_chains{ my ($pdb_file,$chain)=@_; my $PDB_ID=$pdb_file; $PDB_ID=basename($PDB_ID); $PDB_ID =~ s/^(.+)\..*$/$1/; my $PDB_CODE=$PDB_ID; $PDB_CODE =~ s/^pdb//; $PDB_CODE=uc($PDB_CODE); open(PYMOL,">>${PDB_CODE}.pml"); # print PYMOL "#\ncreate ${PDB_CODE}$chain, aa and chain $chain\n"; print PYMOL "#\n"; close PYMOL; } sub script { my ($rasmol_script,$pdb_file,$chain)=@_; my $PDB_ID=$pdb_file; $PDB_ID=basename($PDB_ID); $PDB_ID =~ s/^(.+)\..*$/$1/; my $PDB_CODE=$PDB_ID; $PDB_CODE =~ s/^pdb//; $PDB_CODE=uc($PDB_CODE); open(RAS,"$rasmol_script"); open(PYMOL,">>${PDB_CODE}.pml"); my $selection="select trUc, /${PDB_CODE}//${chain}/"; my $largeSelect=$selection; $largeSelect =~ s/trUc,/trUc, trUc or/; my $residueNbr=0; while(){ if ($_ =~ /^spacefill/ or $_ =~ /^$/){ $selection="select trUc, /aa//${chain}/"; $largeSelect=$selection; $largeSelect =~ s/trUc,/trUc, trUc or/; $residueNbr=0; } elsif ($_ =~ /^select /){ while(/[A-Z]+([0-9]+):?\w*/g){ my $locus=$1; $residueNbr++; if ($residueNbr >= 80){ $selection=$selection."\n".$largeSelect.$locus; $residueNbr=0; next; } if ($selection !~ /\/\/\w*\/\d+/){ $selection=$selection."$locus"; } else{ $selection=$selection."+$locus"; } } } elsif ($_ =~ /^color \[(\d+),(\d+),(\d+)\]/ and $_ !~ /^color \[200,200,200\]/){ my $rang=&rang($1,$2,$3); my $name="Cons_$rang"; $name=$name.$chain if ($chain ne ''); $selection =~ s/trUc/$name/g; print PYMOL $selection."\ncolor Cons_${rang}c, $name\n"; $residueNbr=0; } } close PYMOL; close RAS; } sub footer_script{ my ($pdb_file)=@_; my $PDB_ID=$pdb_file; $PDB_ID=basename($PDB_ID); $PDB_ID =~ s/^(.+)\..*$/$1/; my $PDB_CODE=$PDB_ID; $PDB_CODE =~ s/^pdb//; $PDB_CODE=uc($PDB_CODE); open(PYMOL,">>${PDB_CODE}.pml"); print PYMOL "color yellow, het\ncolor slate, nt\ndelete ${PDB_ID}\nzoom aa\ncenter aa\nset_name aa, $PDB_CODE\nselect AaA, none\ndelete AaA\n"; print PYMOL "if cmd.count_atoms\(\"nt\"\) == 0: cmd.delete\(\"nt\"\)\n"; #remove nt object if there is no nucleotides in the structure print PYMOL "load PYMOLHOME/Legend.dx, map\nzoom $PDB_CODE\nramp_new legend, map, [1.0,5.0,9.0], color=['C1',[1.0,1.0,1.0],'C9']\ncmd.delete\(\"map\"\)\n"; #Add a legend box with defined ConSurf Colors close PYMOL; } sub rang{ my ($uno,$duo,$trio)=@_; my $rang=0; if ($uno==160 and $duo==37 and $trio==96){ $rang=9; } elsif ($uno==240 and $duo==125 and $trio==171){ $rang=8; } elsif ($uno==250 and $duo==201 and $trio==222){ $rang=7; } elsif ($uno==252 and $duo==237 and $trio==244){ $rang=6; } elsif ($uno==255 and $duo==255 and $trio==255){ $rang=5; } elsif ($uno==234 and $duo==255 and $trio==255){ $rang=4; } elsif ($uno==215 and $duo==255 and $trio==255){ $rang=3; } elsif ($uno==140 and $duo==255 and $trio==255){ $rang=2; } elsif ($uno==16 and $duo==200 and $trio==209){ $rang=1; } return $rang; } #sub color{ # my ($red,$green,$blue)=@_; # $red=($red/255); # $green=($green/255); # $blue=($blue/255); # $red=sprintf("%.1f, ", $red); # $green=sprintf("%.1f, ", $green); # $blue=sprintf("%.1f", $blue); # # return ($red,$green,$blue); #} exit; ######@### ###@###### # # This simple plugin will automatically load a ConSurf phylogenetic information file from the # web given the pdb code. It does error handling as well. # # To get color.txt, rasmol script result, files from ConSurf for a pdb accession number. # # Charles Moad (cmoad@indiana.edu) # Scientific Data Analysis Lab # Indiana University # # Modifications for ConSurf, Sebastien Moretti (moretti.sebastien [AT] gmail.com) # Structural and Genomic Informations lab (IGS) # CNRS, Life Sciences, France # from Tkinter import * from pymol import cmd def __init__(self): # Simply add the menu entry and callback self.menuBar.addmenuitem('Plugin', 'command', 'ConSurf - Surface-mapping of phylogenetic information Loader Service 2.4.0', label = 'ConSurf - Surface-mapping of phylogenetic information Loader Service 2.4.0', command = lambda s=self : FetchConSurf(s)) # Class that simply takes the pdbcode from a dialog and retrieves the files from ConSurf and RCSB class FetchConSurf: def __init__(self, app): import tkSimpleDialog import tkMessageBox import urllib # import gzip import os import string pdbCode = tkSimpleDialog.askstring('ConSurf - Surface-mapping of phylogenetic information Loader Service 2.4.0', 'Please enter a 4-digit pdb code: (or 5 to specify only one chain)', parent=app.root) if pdbCode: # None is returned for user cancel pdcCode = string.upper(pdbCode) pdbID = string.lower(pdbCode) os.system('rasmol2pymol.pl --pdbCode=' + pdbID ) # Execute the rasmol script parser to build pymol script cmd.do("@" + os.environ['PWD'] + os.sep + pdcCode + ".pml") # Load the structure with its annotation os.remove(os.environ['PWD'] + os.sep + pdcCode + ".pml") os.remove(os.environ['PWD'] + os.sep + 'pdb' + pdbID + ".ent")