#!/usr/bin/env bash

#
#Version : 1.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 -291 $0 |head -236 >Rasmol2PyMOL.pl
tail -52 $0 >remote_ProSAT_load.py


#Change the path for the perl script
perl -p -e 's/\047*Rasmol2PyMOL/\047${ARGV[0]}Rasmol2PyMOL/' remote_ProSAT_load.py $WHERE >remote_ProSAT_load.pyt
mv -f remote_ProSAT_load.pyt remote_ProSAT_load.py


#Copy the scripts and remove the former ones
rm -f ${WHERE}remote_ProSAT_load.py ${WHERE}remote_ProSAT_load.pyc
rm -f ${WHERE}Rasmol2PyMOL.pl
mv -f Rasmol2PyMOL.pl remote_ProSAT_load.py ${WHERE}
chmod ug+x ${WHERE}Rasmol2PyMOL.pl


echo -e 'ProSAT plugin for PyMOL has been set '
exit


######@###
#!/usr/bin/env perl

use strict;
use warnings;
use diagnostics;
use Getopt::Long;


=head1 SYNOPSIS

Rasmol script converter for ProSAT results

--->  Rasmol2PyMOL.pl --pdb=pdb_code

or     Rasmol2PyMOL.pl --ras=file.ras

e.g.: Rasmol2PyMOL.pl --pdb=1hcl

e.g.: Rasmol2PyMOL.pl --ras=1brs.ras

=head1 DESCRIPTION

=over 4

=item    ProSAT - Protein Structure Annotation Tool

=item ProSAT is a tool to map SwissProt features and Prosite patterns on to a 3D structure of a protein.

=item http://projects.villa-bosch.de/dbase/pdba/

=back

=head1 VERSION

=over 4

=item Version: 1.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 $rasmol_file='';
GetOptions("pdb=s"      => \$pdb_code,
           "ras=s"      => \$rasmol_file);


#If input is a rasmol script file
my $counteur=0;
if ($rasmol_file =~ /\.ras$/ and $pdb_code eq ''){
    &rasmol_parser("$rasmol_file");
}
#If input is a PDB ID
elsif ($pdb_code =~ /^\d\w\w\w$/ and $rasmol_file eq ''){
    my $pdbID=lc($pdb_code);
    &Get_ras_script("$pdbID");
    &rasmol_parser("${pdbID}.ras",'');
}
else{
    system("perldoc $0");
    exit;
}


sub Get_ras_script{
#Get the rasmol script file
    my ($pdbID)=@_;

    $counteur=0;
    for(my $rep=0;$rep < 1; $rep++){
        $counteur++;
        `wget -O ${pdbID}.ras.gz 'http://projects.villa-bosch.de/dbase/pdba/rass/${pdbID}.ras.gz'`;
        last if ($counteur > 10);
        $rep=$rep-1 if ( -z "${pdbID}.ras.gz" );
    }
    if ( -z "${pdbID}.ras.gz" ){
        my ${PDB_CODE}=uc($pdbID);
        open(PYMOL,">${PDB_CODE}.pml");
        print PYMOL "cls\nprint \"The structure you seek for is not currently available on ProSat\"\n";
        close PYMOL;
	unlink("${pdbID}.ras.gz");
	`touch ${PDB_CODE}.pdb ${pdbID}.ras`;
        exit;
    }
    `gunzip -f ${pdbID}.ras.gz`;
}


sub rasmol_parser{
#Get Rasmol info in the script
    my ($rasmol_script)=@_;
    open(RASMOL,"$rasmol_script");

    my (%selections,%define,%colors);
    my $pdb_ID='';
    my ($flag,$drap)=(0,0);
    my $set_color='';
    while(<RASMOL>){
	my ($ac,$def)=('','');
	my $range='';
	if ($_ =~ /^echo .+ *: \((\w+)\) (.+)\. ?$/){
	    $ac=$1;
	    $def=$2;
	    $def =~ s/ /_/g;
	    $def =~ s/\//-/g;
	    $def =~ s/[\,\;\(\)\[\]\&\*\%\?]//g;
	    $def =~ s/^_//;
	    %selections=(%selections,$ac => $def);
	}
	elsif ($_ =~ /^define (\w+)\( *(.+) ?\)$/){
	    $ac=$1;
	    $range=$2;
	    $range =~ s/ //g;
	    $range =~ s/,/+/g;
#	    print STDERR "$range\n";
	    my @list=split(/\+/,$range);
	    $range='';
	    for(my $i=0; $i <= $#list; $i++){
		my @couple=split(/\-/,$list[$i]);
		my $chain=$couple[1];
		$chain =~ s/^.*://;
		$chain='' if ($chain eq '');
		$chain=' in chain '.$chain if ($chain ne '');
		$couple[1] =~ s/:\w*//g;
		if ($couple[0] == $couple[1]){
		    $range=$range.'(resi '.$couple[0].$chain.') or ';
		}
		else{
		    $range=$range.'(resi '.$couple[0].'-'.$couple[1].$chain.') or ';
		}
	    }
            $range =~ s/ or $//; #remove the last ' or '
#	    print STDERR "$range\n";
	    %define=(%define, $ac => $range);
	}
	elsif ($_ =~ /^select (\w+)$/){
	    $set_color=$1;
	    $flag=1;
	}
	elsif ($_ =~ /^colour \[(\d+),(\d+),(\d+)\] *$/ and $flag==1){
	    my $red=($1/255);
	    my $green=($2/255);
	    my $blue=($3/255);
	    $red=sprintf("%.1f, ", $red);
	    $green=sprintf("%.1f, ", $green);
	    $blue=sprintf("%.1f", $blue);
	    my $color_indice="[ ".$red.$green.$blue." ]";
#	    print STDERR "$red $green $blue";
	    %colors=(%colors,$set_color => $color_indice);
	}
	elsif ($drap==0 and $_ =~ /^HEADER.+(\d\w\w\w) *$/){
	    $pdb_ID=$1;
	    $drap=1;
#	    last;
	}
	if ($drap==1){ #Get pdb file
	    open(PQS,">>${pdb_ID}.pdb");
	    print PQS $_;
	    close PQS;
	}
    }
    close RASMOL;


#Get pdb file
#    my $pdb_lower=lc($pdb_ID);
#    `wget -O ${pdb_ID}.pdb.gz 'http://projects.villa-bosch.de/dbase/pdba/mmol/${pdb_lower}.pdb.gz'`;
#    `gunzip -f ${pdb_ID}.pdb.gz`;


#Print PyMOL script
    open(PYMOL,">${pdb_ID}.pml");
    print PYMOL "load ${pdb_ID}.pdb\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\ncolor slate, nt\n";
    print PYMOL "if cmd.count_atoms\(\"nt\"\) == 0: cmd.delete\(\"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\ncolor yellow, het\nshow stick, het\nhide (solvent)\n";

    while(my ($x,$y) = each(%colors)){
	print PYMOL "set_color ${x}c, $y\n";
    }
    my %PSA=%define;
    while(my ($x,$y) = each(%define)){
        delete( $define{$x} ) if ($x =~ /^PSA/);
        delete( $PSA{$x} ) if ($x !~ /^PSA/);
    }

    my $strict='and ! het';
    while(my ($x,$y) = each(%PSA)){
	if (exists $selections{$x}){
	    print PYMOL "select $selections{$x}, ($y) $strict\n";
	    print PYMOL "color ${x}c, $selections{$x}\n";
	}
	else {
	    print PYMOL "select $x, ($y) $strict\n";
	    print PYMOL "color ${x}c, $x\n";
	}
    }
    while(my ($x,$y) = each(%define)){
	if (exists $selections{$x}){
	    print PYMOL "select $selections{$x}, ($y) $strict\n";
	    print PYMOL "color ${x}c, $selections{$x}\n";
	}
	else {
	    print PYMOL "select $x, ($y) $strict\n";
	    print PYMOL "color ${x}c, $x\n";
	}
    }

    print PYMOL "delete ${pdb_ID}\nzoom aa\ncenter aa\nset_name aa, ${pdb_ID}\nselect AaA, none\ndelete AaA\n";
    close PYMOL;
}

exit;

######@###

###@######
#
# This simple plugin will automatically load a ProSAT annotation file from the
# web given the pdb code.  It does error handling as well.
# 
# To get .ras files from ProSAT for a pdb accession number.
#
# Charles Moad (cmoad@indiana.edu)
# Scientific Data Analysis Lab
# Indiana University
#
# Modifications for ProSAT, Sebastien Moretti (moretti.sebastien [AT] gmail.com)
# Structural and Genomic Informations lab (IGS)
# http://www.igs.cnrs-mrs.fr/
# 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',
                            'ProSAT - Protein Structure Annotation Tool Loader Service 1.4.0',
                            label = 'ProSAT - Protein Structure Annotation Tool Loader Service 1.4.0',
                            command = lambda s=self : FetchProSAT(s))


# Class that simply takes the pdbcode from a dialog and retrieves the files from ProSAT and RCSB
class FetchProSAT:
   def __init__(self, app):
      import tkSimpleDialog
      import tkMessageBox
      import urllib
#      import gzip
      import os
      import string

      pdbCode = tkSimpleDialog.askstring('ProSAT - Protein Structure Annotation Tool Loader Service 1.4.0',
                                         'Please enter a 4-digit pdb code (from PQS):',
                                         parent=app.root)
      
      if pdbCode: # None is returned for user cancel
         pdcCode = string.upper(pdbCode)
         pdbID = string.lower(pdbCode)

         os.system('Rasmol2PyMOL.pl --pdb=' + 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 + ".pdb")
         os.remove(os.environ['PWD'] + os.sep + pdbID + ".ras")
         os.remove(os.environ['PWD'] + os.sep + pdcCode + ".pml")
         
