#!/usr/bin/perl -w
use warnings;
use File::Temp;
use Getopt::Long;
use POSIX qw||;

our $config;
my $pkgdatadir;
BEGIN {
	use Config::IniFiles;
	
	my ( $defaultconfig, $etcconfig );
	if( -e "__pkgdatadir__/profisisrc.default" ) { $defaultconfig = Config::IniFiles->new( -file => "__pkgdatadir__/profisisrc.default" ); }
	if( -e "__sysconfdir__/profisisrc" ) { $etcconfig = Config::IniFiles->new( -file => "__sysconfdir__/profisisrc", -import => $defaultconfig ); } else { $etcconfig = $defaultconfig; }
	if( ( $ENV{PROFISISCONF} && -e "$ENV{PROFISISCONF}" ) || -e "$ENV{HOME}/.profisisrc" ) { $config = Config::IniFiles->new( -file => $ENV{PROFISISCONF} || "$ENV{HOME}/.profisisrc", -import => $etcconfig ); } else { $config = $etcconfig; }

	$pkgdatadir = glob( $config->val('profisis', 'pkgdatadir') );
}

# popularity contest
if( system('pp_popcon_cnt', '-p', 'profisis') == -1 ){ warn("The Rost Lab recommends you install the pp-popularity-contest package that provides pp_popcon_cnt:\n\nsudo apt-get install pp-popularity-contest\n"); }

my $debug = 0;
#$Fil=""; # lkajan: this was empty string was used like this: $hssp="$out.hssp$Fil" or $hssp="hssp/$sfile.hssp$Fil"
# lkajan: $out however is not initialized and $struct is hard-coded to 'n'
#$lsl="yes";
#$workdir=`pwd`;
#chomp $workdir;
#sub inKey{
#  my $key="";
#  while ($key eq ""){
#    if ($BSD_STYLE) {system "stty cbreak </dev/tty >/dev/tty 2>&1"}
#    else{system "stty", "-icanon", "eol", "\001"}
#    $key = getc;
#    if ($BSD_STYLE) {system "stty -cbreak </dev/tty >/dev/tty 2>&1"}
#    else{system "stty", "icanon", "eol", "^@"} # ASCII NUL
#    print "\n";
#    if ($key eq "y"){$r="yes"}
#    elsif($key eq "n"){$r="no"}
#    elsif ($key eq "q"){$r="q"}
#    else{print "only y/n\n";$key=""}
#  }
#  return $r;
#}

my %opt = ( help => 0, debug => \$debug, gap => 20, stretch => 5, crd => 7, fastafile => undef, hsspfile => undef, rdbproffile => undef, outfile => undef, outformat => 'pp', 'crd-restriction' => 1 , succinct =>undef );

if( !Getopt::Long::GetOptions(\%opt, 'help!', 'debug!', 'gap=i', 'stretch=i', 'crd=i', 'fastafile=s', 'hsspfile=s', 'rdbproffile=s', 'outfile=s', 'outformat=s', 'crd-restriction!' ,'succinct!' ) ) { print_help(); exit(1); }
if( $opt{help} ) { print_help(); exit(0); }

if( !$opt{fastafile} || !-e $opt{fastafile} ){ die( "--fastafile missing" ); }
if( !$opt{hsspfile} || !-e $opt{hsspfile} ){ die( "--hsspfile missing" ); }
if( !$opt{rdbproffile} || !-e $opt{rdbproffile} ){ die( "--rdbproffile missing" ); }
if( !$opt{outfile} ){ die( "--outfile missing" ); }

my $workdir = File::Temp::tempdir( CLEANUP => !$debug );

$g = $opt{gap}; #diff between output nodes
$sch = $opt{stretch}; #half stretch
$cr = $opt{crd}; #crowd
$crgs=1;#crowd of gs
$topgap=101;#maximal difference between outputnodes
$sfile = $opt{fastafile};
$nitr = $opt{iterations} || 0; # lkajan: not used

# lkajan: the following looks dangerous, commenting out
#if ($sfile=~/\.f$/o){$tmp=$sfile;chop $sfile;chop $sfile; { my @cmd = ( 'cp', $tmp, $sfile ); system( @cmd ) && die( "@cmd failed: ".($?>>8) ); } }
if( $debug ) { warn( "file=$sfile strech=$sch crowd_predictions=$cr crowd_gs=$crgs gap=$g top_gap=$topgap itr=$nitr\n" ); }
#############################################################

open( I1,  ">$workdir/tin_forTest") || die( "failed to open >$workdir/tin_forTest: $!" );
# lkajan: I1S is not opened anywhere in the original version. I put this open here and comment out all uses - is that logical?
#open( I1S,  ">$workdir/i1s") || die( "failed to open >$workdir/i1s: $!" );
open( O1,  ">$workdir/tout_forTest") || die( "failed to open >$workdir/tout_forTest: $!" );;
open( MAP, ">$workdir/map_forTest") || die( "failed to open >$workdir/map_forTest: $!" );;
open( OUT, ">", $opt{outfile} ) || die( "failed to open >$opt{outfile}: $!" );;
$empty="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ";

open( FASTA, '<', $sfile ) || die( "failed to open <$sfile: $!" );
while( my $l = <FASTA> ){ if( $l =~ /^>/o ){ chomp $l; if( $opt{outformat} eq 'pp' ){ print OUT $l; } last; } }
close( FASTA );

my $seq = ''; my $ss = ''; my $acc = '';

if( $opt{outformat} eq 'pp' ){ print OUT ": strech=$sch crowd_predictions=$cr gap=$g itr=$nitr\n"; }
#$struct ="n";
#if ($struct eq "n"){
#    $yesh="";
#    if ($lsl eq "yes"){$yesh=`ls $sfile.hssp`}
#    print "yesh=$yesh\n";
    #if ($yesh eq ""){system "/home/rost/pub/maxhom/scr/maxhom.pl $sfile"}
    #$yesh="";
#    if ($lsl eq "yes"){$yesh=`ls $sfile.rdbProf`}
    #if ($yesh eq ""){system "/home/rost/pub/prof/prof $sfile.hssp both"}
    open( PROFRDB, '<', $opt{rdbproffile} ) || die( "failed to open <$opt{rdbproffile}: $!" );
    while( my $l = <PROFRDB> )
    {
        if ($l=~/^No\s+AA/){
            @tit=split(/\s+/,$l);
            for ($i=0;$i<scalar @tit;$i++){
                if ($tit[$i] eq "AA"){$AA=$i}
                if ($tit[$i] eq "OtH"){$H=$i}
                if ($tit[$i] eq "OtE"){$E=$i}
                if ($tit[$i] eq "OtL"){$L=$i}
                if ($tit[$i] eq "PACC"){$ACC=$i}
            }
        }
        if (($l!~/^\#/) and ($l!~/^No/)){
            @a=split(/\s+/,$l);
            $seq .= $a[$AA];
            $ss .= "$a[$H] $a[$E] $a[$L],";
            $acc .= "$a[$ACC],";
        }
    }
    close( PROFRDB );
#}
$read="n";$readseq=2;
#if ($struct eq "y"){$hssp="$out.hssp";$readseq=0}#"MutLnoH-1b63A.hssp"}
#else{
  $hssp = $opt{hsspfile};
#}#MutLnoH.hssp"}

my $seqh = ''; my $wgt = '';

open( HSSP, '<', $hssp ) || die( "failed to open <$hssp: $!" );
while( my $l = <HSSP> )
{
  if ($l=~/^\sSeqNo\sPDBNo/){$read="y";next}
  if (($l=~/^\#\# INSERTION LIST/) or ($l=~/^\/\//)){last}
  if ($l=~/^\#\# ALIGNMENTS/){$readseq++;next}
  if ($l=~/SeqNo  PDBNo AA STRUCTURE/){next}
  if ($read eq "y"){
    $prf=substr ($l,13,79);
    $prf=~s/^\s+//;
    @tt=split (/\s+/,$prf);
    if (scalar @tt!=20){warn( "AHHHHHHHHHHHHH ".scalar(@tt) );}
    $seqh .= "$prf,";
    $w=substr ($l,124,6);
    #print "$l w=$w\n";
    $w=-(-$w);
    $wgt .= "$w,";
    $sl++;
  }
}
close( HSSP );
if (length $seq!=$sl){die "seq=$seq sl=$sl not same length\n"}
$sam1=1;
$st1=1;
###########################################################
if( $debug ) { warn( "seq=$seq" ); }
@{$a{hs}}=split (//,$seq);
@{$a{ss}}=split (/,/,$ss);
@{$a{acc}}=split (/,/,$acc);
@{$a{wgt}}=split (/,/,$wgt);
@{$a{prof}}=split (/,/,$seqh);
$c=0;
for ($i=0;$i<scalar @{$a{hs}};$i++){
  $seq="";$prf="";
  for ($j=-4;$j<5;$j++){
    if (($j+$i)<0){$prf=$prf."$empty";$seq=$seq."Z"}
    elsif (($i+$j)>=scalar @{$a{hs}}){$prf=$prf."$empty";$seq=$seq."Z"}
    else{
      $seq=$seq."$a{hs}[$i+$j]";
      $prf=$prf."$a{prof}[$i+$j] ";
    }
    #print "i=$i j=$j i+j=",$i+$j," prf=$prf\n";
  }
  $list{seq}[$c]=$seq;
  $list{ss}[$c]=$a{ss}[$i];
  $list{acc}[$c]=$a{acc}[$i];
  $list{wgt}[$c]=$a{wgt}[$i];
  $list{prof}[$c]=$prf;#print "list{prof}[$c]=$list{prof}[$c] prf=$prf\n";
  $list{pos}[$c]=$i;
  $c++;
}
###########################################################
for ($i=0;$i<scalar @{$list{seq}};$i++){
  undef @sam;undef @samseq;
  $seq=$list{seq}[$i];
  @a=split (//, $seq);#print "empty acid=@acid\n";
  @acid=split (/\s+/,$list{prof}[$i]);#print "full acid=@acid\n";
  push (@sam, @acid);
  @ss=split (/\s+/, $list{ss}[$i]);
  for ($notx=0;$notx<3;$notx++){
    if ($ss[$notx] eq ""){die "list{ss}[$i]=$list{ss}[$i] $i: ss[$notx]=$ss[$notx]"}
    else{$ss[$notx]=$ss[$notx]}
  }
  push (@sam,@ss);
  @ACC=("0","0","0");
  if (($i>0) and ($list{acc}[$i-1] ne "X")){$ACC[0]=int ($list{acc}[$i-1]/3)}
  if ($list{acc}[$i] ne "X"){$ACC[1]=int ($list{acc}[$i]/3)}
  if (($i< ( scalar( @{$list{acc}} ) - 1 )) && ($list{acc}[$i+1] ne "X")){
    $ACC[2]=int ($list{acc}[$i+1]/3);
    if ($ACC[2]==0){$ACC[2]="0"}
  }
  push (@sam,@ACC);

  @WGT=("0","0","0");
  if (($i>0) and ($list{wgt}[$i-1] ne "X")){$WGT[0]=int (50*$list{wgt}[$i-1])}
  if ($list{wgt}[$i] ne "X"){$WGT[1]=int (50*$list{wgt}[$i])}
  if ( $i < scalar( @{$list{wgt}} )-1 && $list{wgt}[$i+1] ne "X" )
  {
    # lkajan: the original uses int here but that is not recommended: it leads to differences between maple and jobtest runs
    #$WGT[2]=int (50*$list{wgt}[$i+1]);
    $WGT[2]=POSIX::floor(50*$list{wgt}[$i+1]);
    if ($WGT[2]==0){$WGT[2]="0"}
  }
  push (@sam,@WGT);
################################################################################################
  printf I1  "%6s %8d\n","ITSAM: ",$st1;
#  printf I1S "%6s %8d\n","ITSAM: ",$st1;
  printf O1 "%8d ", $st1;
  print MAP "$st1 $list{pos}[$i] $list{seq}[$i] $list{ss}[$i] ";
  print MAP @ACC;
  print MAP @WGT;
  # lkajan: $list{pp}
  #print MAP $list{pp}[$i];
  print MAP "\n";
  $aa=substr ($list{seq}[$i],4,1);
  $byP[$st1]="$aa";
  $check="$sam1 $list{pos}[$i] $list{seq}[$i] $list{ss}[$i] ";
  $check=$check."@ACC @WGT";
  @ck=split(/\s+/, $check);
  if (scalar @ck!=12){die "scalar ck!=15 ck=@ck\nACC=@ACC\nWGT=@WGT"}
  $sam1++;$st1++;
  $d125=1;$d1s25=1;
  if (scalar @sam!=189){die "i=$i seq=$seq scalar @sam=",scalar @sam}
  foreach $a (@sam){
    if ($d125==26){print I1 "\n";$d125=1}
    printf I1 "%6s",$a;
    $d125++;
  }
  foreach $a (@samseq){
    if ($d1s25==26){
#      print I1S "\n";
      $d1s25=1;
    }
#    printf I1S "%6s",$a;
    $d1s25++;
  }
  @pp=(100,0);
  print I1 "\n";
#  print I1S "\n";
  foreach $o (@out){printf O1 "%6s",$o}
  print O1 "\n";
}
################################################################################################
print I1 "//\n";

close (I1);
close (O1);
$st1--;

open( I1, ">$workdir/in_forTest" ) || die( "failed to open >$workdir/in_forTest: $!" );
print I1 "* overall: (A,T25,I8)\n";
print I1 "NUMIN                 :      189\n";
printf I1 "%23s %8d\n","NUMSAMFILE            :",$st1;
print I1 "*\n";
print I1 "* samples: count (A8,I8) NEWLINE 1..NUMIN (25I6)\n";
open( TIN, '<', "$workdir/tin_forTest" ) || die( $! );
while (<TIN>){print I1 $_}
close( TIN );
unlink( "$workdir/tin_forTest" );
close (I1);
################################################################################################
open (O1, ">$workdir/out_forTest") || die( "failed to open >$workdir/out_forTest: $!" );
print O1 "* overall: (A,T25,I8)\n";
print O1 "NUMOUT                :        2\n";
printf O1 "%23s %8d\n","NUMSAMFILE            :",$st1;
print O1 "*\n";
print O1 "* samples: count (I8) SPACE 1..NUMOUT (25I6)\n";
open( TOUT, '<', "$workdir/tout_forTest" ) || die( $! );
while (<TOUT>){print O1 $_}
close( TOUT );
unlink( "$workdir/tout_forTest" );
close (O1);
################################################################################################
open( TES, ">$workdir/parTest" ) || die( "failed to open >$workdir/parTest: $!" );
print TES "* I8
NUMIN                 :      189
NUMHID                :       50
NUMOUT                :        2
NUMLAYERS             :        2
NUMSAM                :";
printf TES "%9d\n",$st1;
print TES "NUMFILEIN_IN          :        1
NUMFILEIN_OUT         :        1
NUMFILEOUT_OUT        :        1
NUMFILEOUT_JCT        :        1
STPSWPMAX             :        0
STPMAX                :        0
STPINF                :        1
ERRBINSTOP            :        0
BITACC                :      100
DICESEED              :   100025
DICESEED_ADDJCT       :        0
LOGI_RDPARWRT         :        1
LOGI_RDINWRT          :        0
LOGI_RDOUTWRT         :        0
LOGI_RDJCTWRT         :        0
* --------------------
* F15.6
EPSILON               :        0.010000
ALPHA                 :        0.300000
TEMPERATURE           :        1.000000
ERRSTOP               :        0.000000
ERRBIAS               :        0.000000
ERRBINACC             :        0.200000
THRESHOUT             :        0.500000
DICEITRVL             :        0.100000
* --------------------
* A132
TRNTYPE               : ONLINE
TRGTYPE               : SIG
ERRTYPE               : DELTASQ
MODEPRED              : sec
MODENET               : 1st,unbal
MODEIN                : win=5,loc=aa
MODEOUT               : KN
MODEJOB               : mode_of_job
FILEIN_IN             : $workdir/in_forTest
FILEIN_OUT            : $workdir/out_forTest
FILEIN_JCT            : $pkgdatadir/jctAuto9newHssp990-51
FILEOUT_OUT           : $workdir/outresultsTest990
FILEOUT_JCT           : $workdir/jct_crap
FILEOUT_ERR           : $workdir/NNo_tst_err.dat
FILEOUT_YEAH          : $workdir/NNo-yeah1637.tmp
//\n";
close (TES);
{
  # lkajan: silence over talkative neural net:
    if( !$debug ) { open( OLDOUT, '>&', \*STDOUT ) || die; open( STDOUT, '>/dev/null' ) || die; }
	my @cmd = ( "profnet_isis", "$workdir/parTest" );
	system( @cmd ) && die( "@cmd failed: ".($?>>8) );
    if( !$debug ) { open( STDOUT, '>&', \*OLDOUT ) || die; }
}
######################################################################
################# RECORD PREDICTIED ###################
$out_res="$workdir/outresultsTest990";
#$ct=0;
if( $debug )
{
  $have=`ls $workdir/outresultsTest990`;
  warn( "in ISIS found $out_res $have\n" );
}

my @pr = ();

open( NETOUT, '<', $out_res ) || die( "failed to open <$out_res: $!" );
while( my $l = <NETOUT> )
{
  if ($l=~/^\s+\d/){
    chop $l;
    @a=split(/\s+/, $l);
    $pos=$a[1];
    $prval[$pos]=$a[3]-$a[2];
    $aa=$byP[$a[1]];
    if ((($a[3]-$a[2])>$g) and (($a[3]-$a[2])<$topgap)){
      $pr[$pos]="pp";
      if ($a[3]-$a[2]>25){$pr[$pos]="PP"}
      $pp++;
    }
    else{$pr[$pos]="notpp";$np++}
    $s[$pos]=$aa;
  }
}
close( NETOUT );
if( $debug ) { warn( "pred pp=$pp np=$np scalar s=".scalar(@s)."\n" ); }
#########################################################
# lkajan: $i is a residue index, residue indices start from 1
for ($i=1;$i<scalar @pr;$i++){
  for ($j=(-$sch);$j<$sch+1;$j++){
    if ((($i+$j)>-1) and (($i+$j)<scalar @pr)){
      if( $pr[$i+$j] && ( $pr[$i+$j] eq "pp" || $pr[$i+$j] eq "PP" ) )
      {
        $prp[$i]++;
        $sprp[$i] = ( $sprp[$i] || 0 ) + $prval[$i+$j];
      }
      if( ( $prval[$i+$j] || 0 ) >= $g ){ $stval[$i] = ( $stval[$i] || 0 ) + $prval[$i+$j]; }
    }
  }
  $prp[$i] //= 0;   # lkajan: set to 0 if not defined
  $sprp[$i] //= 0;  # lkajan: set to 0 if not defined
  # lkajan: note the $crd multiplier on the following original line: $crd is never set. Probably $cr was meant. However perhaps we should preserve the original buggy behaviour?
  #if (($pr[$i] eq "pp")and (($prp[$i]>$cr-1) or ($sprp[$i]>2.88571*$crd*10)))
  if( $pr[$i] eq "pp" && ( $prp[$i] > $cr-1 || $sprp[$i] > 2.88571* ( $opt{'crd-restriction'} ? 0 : $cr ) *10 ) )
  #if( $pr[$i] eq "pp" && ( $prp[$i] > $cr-1 || $sprp[$i] > 2.88571*$cr*10 ) )
  {
    $out{pp}[$i]="P";
    $cpp++;
  }
  elsif ($prp[$i]<$cr){$out{pp}[$i]="-"}
  else{$out{pp}[$i]="-"}
  if ($pr[$i] eq "PP"){$out{pp}[$i]="P";$cpp++}
}
$blk=0;$seq="";$pp="";
if( $debug ){ warn( "         1         2         3         4\n" ); }
if( $debug ){ warn( "1234567890123456789012345678901234567890\n" ); }
for ($i=1;$i<scalar @s;$i++){
  $blk++;
  if ($blk==41){
    if( $debug) { printf STDERR "%40s\n%40s\n\n",$seq,$pp; }
    if( $opt{outformat} eq 'pp' ){ printf OUT    "%40s\n%40s\n\n",$seq,$pp; }
    $blk=1;$seq="";$pp="";
  }
  $seq=$seq.$s[$i];
  $pp=$pp."$out{pp}[$i]";
}
if( $debug) { print STDERR "$seq\n$pp\n\n"; }
if( $opt{outformat} eq 'pp' ){ print OUT    "$seq\n$pp\n\n"; }
# lkajan: $i is a residue index, residue indices start from 1
for ($i=1;$i<scalar @pr;$i++){
  if( $debug ) { print STDERR "$i $s[$i] $prval[$i]\n"; }
  if (!$opt{succinct}){
                 print OUT    "$i $s[$i] $prval[$i]\n";
  }
}

exit(0);

sub								print_help
{
	print STDERR "Usage: $0 [OPTION]\n".qq|
  Required parameters:
  --fastafile     file that contains your sequence in fasta format
  --hsspfile      file with hssp data for sequence in --fastafile
  --rdbproffile   file with prof output for sequence in --fastafile
  --outfile       output file, suggested extension: .Isispred

  Optional parameters:
  --outformat     output format [pp\|prval]
    default=pp
    pp            original PredictProtein format:
      >3A1P:A\|PDBID\|CHAIN\|SEQUENCE: strech=5 crowd_predictions=7 gap=20 itr=0
      MRLVEIGRFGAPYALKGGLRFRGEPVVLHLERVYVEGHGW
      PPP-P-----P-P----P-------P--PPPP-PPP---P
      
      1 M 25
      ...
      40 W 34

    prval         'resn resi predicted_value', e.g. '1 M 25' each residue on a
                  line

  --debug
  --nodebug
  --succinct       succinct output (no confidence values)

  Parameters controlling post processing:
  --gap=int       default=20
  --stretch=int   default=5
  --crd=int       default=7
  --crd-restriction   use original (\$crd = undef) code - this is the default
  --nocrd-restriction use new (\$cr) code
|;

}

=pod

=head1 NAME

profisis - protein-protein interaction sites identified from sequence

=head1 SYNOPSIS

profisis [OPTION]

=head1 DESCRIPTION

profisis (ISIS) is a machine learning-based method that identifies interacting residues from sequence alone. Although the method is developed using transient protein-protein interfaces from complexes of experimentally known 3D structures, it never explicitly uses 3D infor- mation. Instead, we combine predicted structural features with evolutionary information. The strongest predictions of the method reached over 90% accuracy in a cross-validation experiment. Our results suggest that despite the significant diversity in the nature of protein-protein interactions, they all share common basic principles and that these principles are identifiable from sequence alone.

=head2 Conversion of PSI-BLAST alignment to HSSP format

The most up-to-date procedure can be found at L<https://www.rostlab.org/owiki/index.php/How_to_generate_an_HSSP_file_from_alignment#Generating_an_HSSP_profile>.

=over

=item 1. Convert BLAST output to a Single Alignment Format (SAF):

 __datadir__/librg-utils-perl/blast2saf.pl fasta=<query_fasta_file> maxAli=3000 eSaf=1 \
  saf=<saf_formatted_file> <blast_output>

=item 2. Convert SAF format to HSSP:

 __datadir__/librg-utils-perl/copf.pl <saf_formatted_file> formatIn=saf formatOut=hssp \
  fileOut=<hssp_formatted_file> exeConvertSeq=convert_seq

=item 3. Filter results to 80% redundancy:

 __datadir__/librg-utils-perl/hssp_filter.pl red=80 <hssp_formatted_file> fileOut=<filtered_hssp_formatted_file>

=back

=head2 Output format

See description of B<--outformat> option.

=head1 REFERENCES

=over

=item Ofran, Y. and Rost, B. (2007). ISIS: interaction sites identified from sequence.  Bioinformatics, 23(2), e13-6.  

=back

=head1 OPTIONS

Required parameters

=over

=item --fastafile

file that contains your sequence in fasta format

=item --hsspfile

file with hssp data for sequence in --fastafile

=item --rdbproffile

file with prof output for sequence in --fastafile

=item --outfile

output file

=back

Optional parameters

=over

=item --outformat

output format [pp|prval], default=pp

=over

=item pp

PredictProtein format:

 Output ::= Header_Line Binary_Out Raw_Out

 Header_Line ::= '>' Header_String '\n'

 Binary_Out ::= ( Horiz_Sequence '\n' Bin_Pred '\n\n' )+

 Horiz_Sequence ::= Amino_Acid_One_Letter_Code{,40}

 Bin_Pred ::= [P-]{,40}

'P' marks binding residue.

 Raw_Out ::= ( Amino_Acid_Number ' ' Amino_Acid_One_Letter_Code ' ' Prediction_Score '\n' )+

 Prediction_Score ::= Integer_Value

See example outputs in F<__docdir__/examples>.

=item prval

( 'resn resi predicted_value' )+, e.g.

 '1 M 25'
 '2 R 36'
 ...

=back

=item --debug

=item --nodebug

Default: --nodebug

=item --succinct

Succinct output (print no confidence values).

=back

Parameters controlling post processing - these parameters affect only the top part of the 'pp' output format

=over

=item --gap=int

default=20

=item --stretch=int

default=5

=item --crd=int

default=7

=item --crd-restriction

=item --nocrd-restriction

Default: --crd-restriction. Use original ($crd = undef) code (--crd-restriction) or use new ($cr) code (--nocrd-restriction).

=back

=head1 EXAMPLES

 profisis --fastafile __docdir__/examples/3A1P_A.fasta --hsspfile __docdir__/examples/3A1P_A.hssp --rdbproffile __docdir__/examples/3A1P_A.rdbProf --outfile /tmp/3A1P_A.profisis

=head1 ENVIRONMENT

=over

=item PROFISISCONF

Location of configuration file to use, overriding other configuration files

=back

=head1 FILES

=over

=item F<__pkgdatadir__/profisisrc.default>

Default configuration file. See this file for a description of the parameters.

=item F<__sysconfdir__/profisisrc>

System configuration file overriding values in F<__pkgdatadir__/profisisrc.default>

=item F<~/.profisisrc>

User configuration file overriding values in F<__sysconfdir__/profisisrc>

=item F<$PROFISISCONF>

If this environment variable is set F<~/.profisisrc> is disregarded and the value of the variable is read for configuration options overriding F<__sysconfdir__/profisisrc>

=back

=head1 AUTHOR

Yanay Ofran and Burkhard Rost

=head1 SEE ALSO

prof(1)

=cut

# vim:ts=2:ai:et:
