Author: Steffen Moeller <moeller@debian.org>
LastChanged: Sat, 12 Jun 2010 16:03:22 +0200
Description:
 * coils-wrap now uses Getopt::Long
 * coils-wrap now also writes out raw prediction
 * coils-wrap input file format recognition improved
 * ncoils.c does not require the env var COILSDIR defined any more
 * -max_seq_len is not a cmd line argument any more
 * added coils-wrap.pod and ncoils.pod


--- a/coils-wrap.pl
+++ b/coils-wrap.pl
@@ -1,6 +1,8 @@
-#!/usr/local/bin/perl 
-
+#!/usr/bin/perl -w
 $|=1;
+use Carp qw| cluck :DEFAULT |;
+use Getopt::Long;
+use File::Temp qw||;
 
 
 # Runs coils multiply to give you a three-window output
@@ -9,42 +11,75 @@
 # You may need to change these, in addition 
 # to the "/usr/local/bin/perl" above if necessary
 #
-$ENV{"COILSDIR"} = "/data/ATG/coils/";
-$coils_root = "/data/ATG/coils/";
-$coils_exec = "/apps/ATG/bin/coils";
+#$ENV{"COILSDIR"} = "__MAKE_PREFIX__/usr/share/coiledcoils";
+$coils_root = "__pkgdatadir__";
+$coils_exec = "ncoils";
 
-$tmpdir = "/tmp/";
+$tmpdir = File::Temp::tempdir( CLEANUP => 1 );
 
 undef($in_seq);
 undef($id);
 $mode = "threewin";
 $weighted = "";
 $matrix = "MTK";
-$win    = "21";
+#$win    = "21";
 $extra  =  "";
 
-for($i=0; $i<=$#ARGV; ++$i) {
-   if($ARGV[$i] eq "-m") { # matrix file
-      if(($i+1)>($#ARGV)) { exit_error(); }
-      $matrix = uc($ARGV[$i+1]);
-      $i++;
-   } elsif($ARGV[$i] eq "-w") { # matrix file
-        $weighted = " -w ";
-   } elsif(!defined($fastafile)) {
-        $fastafile = $ARGV[$i];
-   } else {
-        exit_error();
-   }
+$nameScr = $0;
+$nameScr =~ s/.*\///g;
+
+$Lok = GetOptions ("m=s"    => \$matrix,
+		   "w!"   => \$opt_weight,
+		   "i=s" => \$fastafile,
+		   "o=s" => \$outfile,
+		   "r=s" => \$fileRaw,
+		   "debug!"    => \$dbg
+		   #'help'     => \$opt_help);
+		   );
+
+
+if ( ! $Lok ) {
+    print STDERR 
+	"Invalid arguments found, -h or --help for help\n",
+	"Usage: $nameScr [options]  -i fastafile -o out_file -r raw_file\n",
+	"   -m [matrix type]  set matrix (MTK or MTIDK)\n",
+	"   -w                weight a&d = b,c,e,f&g\n",
+        "Try $nameScr --help for more information\n";
+    
+    exit(1);
+}
+
+
+if ( ! $fastafile or ! $outfile ) {
+    print STDERR
+        "Usage: $nameScr [options]  -i fastafile -o out_file -r raw_file\n",
+	"   -m [matrix type]  set matrix (MTK or MTIDK)\n",
+	"   -w                weight a&d = b,c,e,f&g\n",
+        "Try $nameScr --help for more information\n";
+    exit(1);
+}
+
+if ( ! -f $fastafile ) {
+    print STDERR
+        "input file '$fastafile' not found, exiting..\n";
+    exit(1);
+}
+
+$fileRaw = $outfile."_raw" if ( ! defined $fileRaw );
+
+$matrix = uc($matrix);
+if ( $opt_weight ) {
+    $weighted = " -w ";
 }
 
 sub exit_error {
-   print STDERR "coils-wrap.pl [options] [fasta file]\n";
+   print STDERR "coils-wrap.pl [options] [fasta file] [output file]\n";
    print STDERR "   -m [matrix type]  set matrix (MTK or MTIDK)\n";
    print STDERR "   -w                weight a&d = b,c,e,f&g\n";
    exit;
 }
 
-@data = read_align($fastafile,$type);
+@data = read_align($fastafile,\$type);
 if($type ne "f") {
    die "Error file must be in FASTA format\n";
 }
@@ -61,14 +96,14 @@
 
 $seqs = get_afasta(@data);
 
-print "What should appear below is the result of running COILS three \n";
-print "times with windows of 14,21 & 28.\n`frame' denotes the predicted \n";
-print "position of the heptad repeat for the highest scoring window that \n";
-print "overlaps each position.\n`prob' gives a single integer value \n";
-print "representation of P (where 0-9 covers the range 0.0-1.0)\n";
-print "This will be repeated for each sequence \n\n\n";
+#print "What should appear below is the result of running COILS three \n";
+#print "times with windows of 14,21 & 28.\n`frame' denotes the predicted \n";
+#print "position of the heptad repeat for the highest scoring window that \n";
+#print "overlaps each position.\n`prob' gives a single integer value \n";
+#print "representation of P (where 0-9 covers the range 0.0-1.0)\n";
+#print "This will be repeated for each sequence \n\n\n";
 
-print "A total of $seqs->{nseq} sequences found in $seqfile\n\n\n";
+#print "A total of $seqs->{nseq} sequences found in $seqfile\n\n\n";
 for($n=0; $n<$seqs->{nseq}; ++$n) {
    $id = $seqs->{list}[$n];
    $in_seq = $seqs->{ids}{$id}{seq};
@@ -76,7 +111,8 @@
 #   print "ID $id seq $seq\n";
 
    &write_fasta($seqfile,$id,$in_seq);
-
+   @result = ();
+   push @result, ">$id\n\n";
    if($mode eq "threewin") {
            # Runs threewin style mode
            # Three windows 14,21,28
@@ -94,7 +130,10 @@
            for($i=14; $i<=28; $i+=7) {
                $j=($i-14)/7;
                $command = $coils_exec . $extra . " -win " . $i . " < " . $seqfile;
-#   	       print "Command is $command\n";
+	       if ( $i == 28 ) {
+		   open (RAW,">$fileRaw") or die "cannot write to $fileRaw:$!";
+	       }
+   	       if($dbg){ cluck("Command is $command"); }
                open(IN,"$command|");
 
                $fid = "frame-" . $i;
@@ -107,7 +146,18 @@
 
                $p=0;
                while(<IN>) {
-                   if(!/sequences/) {
+		   if ( $i == 28 ) { # print the raw file if window is 28
+		       print RAW $_;
+		   }
+		   if ( /^\#/ ) {
+		       chomp($result = $_);
+		       $result =~ s/.*aas//;
+		       $result =~ s/in coil\s*//g;
+		       $result = "window size = $i ".$result." residues in coiled coil".
+			   " domain\n";
+		       push @result, $result;
+		       next;
+		   } else {
                        $_ =~ s/^ *//;
                        @t=split(/ +/);
                        $align->{ids}{$fid}{seq} .= $t[2];
@@ -118,18 +168,22 @@
                        else { $sP = substr($P,0,1); }
                        if($sP eq "0") { $sP = "-"; }
                        $align->{ids}{$pid}{seq} .= $sP;
-                   } else {
-                       print;
                    }
                }
                close(IN);
            }
-           write_clustal($align,"-");
-    }
-}
-#unlink $seqfile;
+	   
+  
+	   if ( defined($outfile)) { # Write output to file
+	       write_clustal($align,\@result, $outfile);
+	   } else {
+	       write_clustal($align,\@result, "-");
+	   }
+       }
+}  
+unlink $seqfile;	     
 
-exit;
+exit(0);
 
 sub write_fasta {
    my($fn,$id,$seq) = @_;
@@ -139,7 +193,7 @@
    while($i<length($seq)) {
       $aa = substr($seq,$i,1);
       print SEQ $aa;
-      if((($i+1)%60)==0){ print SEQ "\n" }
+      if((($i+1)%50)==0){ print SEQ "\n" }
       $i++;
    }
    print SEQ "\n";
@@ -150,12 +204,14 @@
         my($align) = $_[0];
         my($i,$j,$k,$id);
 
-        my($outfile) = $_[1];
+	my($header)= $_[1];
+        my($outfile) = $_[2];
         open(OUT,">$outfile") || die "Error opening output file $outfile\n";
 
-
-
 #        print OUT "CLUSTAL W(1.60) multiple sequence alignment\n\n";
+	
+	print OUT @$header;
+	print OUT "\n";
 
         foreach $id (keys %{$align->{ids}}) {
                 if(defined($align->{ids}{$id}{start})) {
@@ -164,24 +220,44 @@
                                 $align->{ids}{$id}{newid} .= $align->{ids}{$id}{ranges};
                         }
                 } else {
-                        $align->{ids}{$id}{newid} = $id;
-                }
-        }
-        $i=0;
-        while($i<$align->{alen}) {      
-                for($k=0; $k<$align->{nseq}; ++$k) {
-                        $id = $align->{list}[$k];
-                        printf(OUT "%-10s ",$align->{ids}{$id}{newid});
-                        for($j=0; $j<60; ++$j) {
-                                last if(($i+$j)>=$align->{alen});
-                                print OUT substr($align->{ids}{$id}{seq},($i+$j),1);
-                        }
-                        printf(OUT "\n");
-                }
-                $i+=60;
-                printf(OUT "\n");
+		    if ( $id !~ /frame/ and $id !~ /prob/) {
+			$align->{ids}{$id}{newid} = "seq";
+		    } else {
+			$align->{ids}{$id}{newid} = $id;
+		    }
+                }		# 
+	    }
+    				# 
+	$i=0;
+
+        while($i<$align->{alen}) {
+	    printf OUT "%-10s ", ' ';
+	    for ($z = 1; $z <=50; $z++) {
+		if ($z == 50) {
+		    print OUT ($i+50)/10 ;
+		} elsif ($z % 10 == 0) {
+		    print OUT ":";
+		} elsif ($z % 5 == 0) {
+		    print OUT ".";
+		} else {
+		    print OUT " ";
+		}
+	    }
+	    print OUT "\n";
+	    
+	    for($k=0; $k<$align->{nseq}; ++$k) {
+		$id = $align->{list}[$k];
+		printf(OUT "%-10s ",$align->{ids}{$id}{newid});
+		for($j=0; $j<50; ++$j) {
+		    last if(($i+$j)>=$align->{alen});
+		    print OUT substr($align->{ids}{$id}{seq},($i+$j),1);
+		}
+		print OUT "\n";
+	    }
+	    $i+=50;
         }
-        close(OUT);
+	print OUT "// End\n\n"; 
+        close OUT;
 }
 
 sub get_afasta {
@@ -222,7 +298,7 @@
 		if(defined($align->{ids}{$label})) {
 			$_ =~ s/-/ /g;
 			$align->{ids}{$label}{seq} .= $_;
-			print "Adding $_ to $label\n";
+#			print "Adding $_ to $label\n";
 		}
 	}
    }
@@ -233,6 +309,7 @@
 }
 
 sub read_align { # Just read in text and modify format if necessary
+        #( $fastafile, \$type )
 
 #
 # Likely format is determined by looking for signs of one format over another
@@ -255,7 +332,7 @@
    my($file) = $_[0];
    my(@data);
    my($i,$type);
-   my($winner,$highest);
+   my($winner,$highest) = ('x', 0);
 
    @data=();
 
@@ -268,18 +345,19 @@
 
    for($i=0; $i<=$#data; ++$i) {
 	$_ = $data[$i];
-        if(($i==0) && ($_  =~ / *[0-9]+ +[0-9]+ */)) { $votes{"y"}+=1000; }
+        if( $file =~ /\.fa(sta)?$/oi ){ $votes{"f"}+=1000; last; }
+        elsif(($i==0) && ($_  =~ / *[0-9]+ +[0-9]+ */)) { $votes{"y"}+=1000; }
+        elsif(($i==0) && ($_  =~ /^>/o) && $data[1] && $data[1] =~ /^[a-z]/io ) { $votes{"f"}+=10; }
 	elsif(($_ =~ /^ *Name:/) || ($_ =~ /pileUp/) || ($_ =~ /MSF.*Check.*\.\./)) { $votes{"m"}++; last; }
 	elsif($_ =~ /^CLUSTAL/) { $votes{"c"}+=10; last; }
 	elsif($_ =~ /^>P1;/) { $votes{"p"}+=10;  last; }
-   	elsif($_ =~ /HMMER/) { $votes{"h"}+=10; last; }
+   	elsif($_ =~ /HMMER/o && $data[0] !~ /^>/o) { $votes{"h"}+=10; last; }
    	elsif(($_ =~ /^#=SQ/) || ($_ =~ /^#=RF/)) { $votes{"h"}++; }
 	elsif($_ =~ /^>/) { $votes{"f"}++; $votes{"b"}++;  }
 	elsif($_ =~ /^ *\* iteration [0-9]*/) { $votes{"b"}++; $block_start++; }
 	elsif($_ =~ /^ *\*/) { $votes{"b"}++; $block_end++; }
 	elsif(($_ =~ /^ID  /) || ($_ =~ /^CC  /) || ($_ =~ /^AC  /) || ($_ =~ /^SE  /)) { $votes{"s"}++; }
         elsif(($_ =~ /^HSSP .*HOMOLOGY DERIVED SECONDARY STRUCTURE OF PROTEINS/)) { $votes{"e"}+=1000; }
-
    }
 
    # Block and FASTA are quite hard to tell apart in a quick parse,
@@ -289,14 +367,12 @@
     	if($block_end==0) { $votes{"f"}++; }
    }
 
-   $winner = "x";
-   $highest = 0;
    foreach $type (keys %votes) {
 #	print $type," ", $votes{$type},"\n";
 	if($votes{$type}>$highest) { $winner = $type; $highest = $votes{$type}; }
    }
-#   print "File is apparently of type $winner\n";
-   $_[1] = $winner;
+   if( $dbg ){ warn( "File is apparently of type $winner" ); }
+   ${$_[1]} = $winner;
    return @data;
 }
 sub get_print_string {
@@ -311,3 +387,5 @@
         }
         return $max_len;
 }
+
+# vim:et:ai:
--- a/ncoils.c
+++ b/ncoils.c
@@ -1,4 +1,5 @@
 #include <ncoils.h>
+#include <string.h>
 
 /* Copyright (c) 2002 Robert B. Russell 
  *  EMBL, Meyerhofstrasse 1, 69917 Heidelberg, Germany 
@@ -22,16 +23,19 @@
 
 
 /* Rob Russell's attempt to make a COILS program */
+#ifndef __PKGDATADIR__
+#define __PKGDATADIR__ ""
+#endif
 
-main(int argc, char *argv[]) {
+int main(int argc, char *argv[]) {
 
-	int i,j,k,l;
+	int i,j;
 	int verb;
 	int window,pt;
 	int which,weighted;
 	int nseq;
 	int t,tc;
-	int seqlen;
+	int seqlen = 0;
 	int mode;
 	int min_seg;
 
@@ -39,7 +43,8 @@
 	char heptfile[HEPTFILELENGTH];
 	char *buff;
 	static char *env;
-	char *seq,*title,*ident;
+	char *seq = NULL;
+	char *title,*ident;
 
 	float min_P;
 
@@ -55,10 +60,10 @@
 	mode = 0; /* 0 = column mode, 1 = fasta, 2 = concise */
 	min_P = 0.5;
 
-	if((env=getenv("COILSDIR"))==NULL) {
+	if((env=getenv("COILSDIR"))==NULL) env = __PKGDATADIR__;
+
+	if( env[0] == 0 ){ // empty string
 		fprintf(stderr,"error: environment variable COILSDIR must be set\n");
-		fprintf(stderr,"       Assuming /usr/share/ncoils\n");
-		env=strdup("/usr/share/ncoils"); // a little leak, tolerated as singleton
 		exit(-1);
 	}
 
@@ -67,19 +72,19 @@
 
 
 	for(i=1; i<argc; ++i) {
-           if(argv[i][0]!='-') exit_error();
+           if(argv[i][0]!='-') exit_error( env );
 	   if(strcmp(&argv[i][1],"m")==0) {
-             if((i+1)>=argc) exit_error();
+             if((i+1)>=argc) exit_error( env );
              strncpy(&heptfile[0],argv[i+1],HEPTFILELENGTH-1);
              i++;
 	   } else if(strcmp(&argv[i][1],"win")==0) {
-             if((i+1)>=argc) exit_error();
+             if((i+1)>=argc) exit_error( env );
              sscanf(argv[i+1],"%d",&window);
              i++;
 	   } else if(strcmp(&argv[i][1],"c")==0) {
              mode=2;
 	   } else if(strcmp(&argv[i][1],"min_seg")==0) {
-             if((i+1)>=argc) exit_error();
+             if((i+1)>=argc) exit_error( env );
              sscanf(argv[i+1],"%d",&min_seg);
              i++;
 	   } else if(strcmp(&argv[i][1],"c")==0) {
@@ -87,18 +92,18 @@
 	   } else if((strcmp(&argv[i][1],"f")==0) || (strcmp(&argv[i][1],"fasta")==0)) {
 	     mode=1;
 	   } else if((strcmp(&argv[i][1],"min_P")==0)) {
-             if((i+1)>=argc) exit_error();
+             if((i+1)>=argc) exit_error( env );
              sscanf(argv[i+1],"%f",&min_P);
              i++;
 	   } else if(strcmp(&argv[i][1],"help")==0) {
-	     exit_error();
+	     exit_error( env );
 	   } else if(strcmp(&argv[i][1],"w")==0) {
 	     weighted=1;
 	   } else if(strcmp(&argv[i][1],"V")==0 || strcmp(&argv[i][1],"v")==0) {
 	     verb=1;
            } else {
 	     fprintf(stderr," can't understand flag/field %s\n",argv[i]);
-             exit_error();
+             exit_error( env );
            }
         }
 
@@ -175,14 +180,14 @@
 		pred_coils(seq,ident,title,h,window,which,weighted,mode,min_P,&t,&tc,min_seg); 
 		free(seq);
 	}
-	fprintf(stderr,"%8d sequences %8d aas %8d in coil\n",nseq,t,tc);
+	if( verb ) fprintf(stderr,"%8d sequences %8d aas %8d in coil\n",nseq,t,tc);
 	free(title); free(ident); 
 
 	exit(0);
 
 }
 
-void exit_error() {
+void exit_error( const char* __coilsdir ) {
 	fprintf(stderr,"format: ncoils [options] < [sequence file]\n");
 	fprintf(stderr,"       -f or -fasta        [fasta output - coils as 'x', like '-x' in seg]\n");
 	fprintf(stderr,"       -c                  [concise mode - which sequences have any coils (and how many)]\n");
@@ -191,7 +196,7 @@
 	fprintf(stderr,"       -win <int>          [window size; DEFAULT = 21]\n");
 	fprintf(stderr,"       -w                  [weight heptad positions a&d the same as b,c,e,f,g]\n");
 	fprintf(stderr,"       -v                  [verbose/debug mode - print extra junk]\n");
-	fprintf(stderr,"       -max_seq_len <int>  [longest sequence tolerated; DEFAULT = 100 000]\n");
+	fprintf(stderr,"Effective COILSDIR: %s\n", __coilsdir );
 	fprintf(stderr,"\n");
 	fprintf(stderr,"NCOILS, Rob Russell and Andrei Lupas, 1999\n");
 	fprintf(stderr," based on Lupas, Van Dyck & Stock (1991) Science 252,1162-1164\n");
@@ -206,7 +211,6 @@
 
 	int i,j;
 	int len,pos,aa_pt;
-	int pt;
 	int total_coil_segments;
 	int are_there_coils;
 
--- /dev/null
+++ b/coils-wrap.pod
@@ -0,0 +1,77 @@
+=head1 NAME
+
+coils-wrap - runs ncoils three times to give you a three-window output
+
+=head1 SYNOPSIS
+
+coils-wrap [OPTION]
+
+=head1 DESCRIPTION
+
+coils-wrap runs ncoils three times to give you a three-window output.
+
+ncoils is a program that compares a sequence to a database of known parallel two-stranded coiled-coils and derives a similarity score. By comparing this score to the distribution of scores in globular and coiled-coil proteins, the program then calculates the probability that the sequence will adopt a coiled-coil conformation. 
+
+=head1 OPTIONS
+
+=over
+
+=item -i
+
+input file in FASTA format
+
+=item -o
+
+output file
+
+=item -r
+
+raw output file, default: `<output file>_raw'
+
+=item -m
+
+matrix type; set matrix (MTK or MTIDK)
+
+=item -w
+
+weight a&d = b,c,e,f&g (boolean)
+
+=back
+
+=head1 EXAMPLES
+
+C<coils-wrap -m MTIDK -i /usr/share/doc/ncoils/1srya.fa -o /tmp/coils.out -r /tmp/coils_raw.txt && less /tmp/coils.out /tmp/coils_raw.txt>
+
+C<ncoils -win 14 < /usr/share/doc/ncoils/1srya.fa>
+
+=head1 FILES
+
+=over
+
+=item F</usr/share/coiledcoils/*.mat>
+
+matrix data files
+
+=back
+
+=head1 AUTHOR
+
+R.B. Russell, A.N. Lupas, 1999
+
+=head1 COPYRIGHT AND LICENSE
+
+GPL
+
+Based on Lupas, Van Dyck & Stock (1991) Science 252,1162-1164
+
+=head1 SEE ALSO
+
+L<ncoils(1)>, L</usr/share/doc/coils/README>, L<http://www.russelllab.org/cgi-bin/coils/coils-svr.pl>
+
+=over
+
+=item A Lupas: Prediction and Analysis of Coiled-Coil Structures. Methods in Enzymology, 266, 513-525, 1996
+
+=item A. Lupas, M. Van Dyke, and J. Stock: Predicting coiled coils from protein sequences. Science, 252, 1162-1164, 1991
+
+=back
--- /dev/null
+++ b/ncoils.pod
@@ -0,0 +1,89 @@
+=head1 NAME
+
+ncoils - prediction of coiled-coil secondary structure elements
+
+=head1 SYNOPSIS
+
+ncoils [OPTION] < [FASTA FILE]
+
+ncoils -f < /usr/share/doc/ncoils/1srya.fa
+
+=head1 DESCRIPTION
+
+ncoils is a program that compares a sequence to a database of known parallel two-stranded coiled-coils and derives a similarity score. By comparing this score to the distribution of scores in globular and coiled-coil proteins, the program then calculates the probability that the sequence will adopt a coiled-coil conformation. 
+
+=head1 OPTIONS
+
+=over
+
+=item -f, -fasta
+
+fasta output - coils as 'x', like '-x' in seg
+
+=item -c
+
+concise mode - which sequences have any coils (and how many)
+
+=item -min_seg <int>
+
+for concise mode - only report sequence if >= min coil segments
+
+=item -min_P <float>
+
+minimum P to define coil segment; DEFAULT = 0.5
+
+=item -win <int>
+
+window size; DEFAULT = 21
+
+=item -w
+
+weight heptad positions a&d the same as b,c,e,f,g
+
+=item -v
+
+verbose/debug mode - print extra junk
+
+=back
+
+=head1 EXAMPLES
+
+C<coils-wrap -m MTIDK -i /usr/share/doc/ncoils/1srya.fa -o /tmp/coils.out -r /tmp/coils_raw.txt && less /tmp/coils.out /tmp/coils_raw.txt>
+
+C<ncoils -win 14 < /usr/share/doc/ncoils/1srya.fa>
+
+=head1 ENVIRONMENT
+
+COILSDIR - specifies the directory containing the file new.mat overriding the default F</usr/share/ncoils>
+
+=head1 FILES
+
+=over
+
+=item F</usr/share/ncoils/*.mat>
+
+matrix data files
+
+=back
+
+=head1 AUTHOR
+
+R.B. Russell, A.N. Lupas
+
+=head1 COPYRIGHT AND LICENSE
+
+GPL
+
+Based on Lupas, Van Dyck & Stock (1991) Science 252,1162-1164
+
+=head1 SEE ALSO
+
+L<coils-wrap(1)>, L</usr/share/doc/coils/README>, L<http://www.russelllab.org/cgi-bin/coils/coils-svr.pl>
+
+=over
+
+=item A Lupas: Prediction and Analysis of Coiled-Coil Structures. Methods in Enzymology, 266, 513-525, 1996
+
+=item A. Lupas, M. Van Dyke, and J. Stock: Predicting coiled coils from protein sequences. Science, 252, 1162-1164, 1991
+
+=back
--- a/ncoils.h
+++ b/ncoils.h
@@ -1,7 +1,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
-#include <string.h>
 
 #define AAs "A_CDEFGHI_KLMN_PQRST_VW_Y_"
 #define PI  3.1415
@@ -25,6 +24,6 @@
 
 
 struct hept_pref *read_matrix(FILE *MAT);
-void exit_error();
+void exit_error(const char*);
 void pred_coils(char *seq,char *ident,char *title,struct hept_pref *h,int win,int which,
    int weighted,int fasta,float min_P, int *t, int *tc, int min_segs);
--- a/read_matrix.c
+++ b/read_matrix.c
@@ -1,4 +1,5 @@
 #include <ncoils.h>
+#include <string.h>
 
 /* Copyright (c) 2002 Robert B. Russell
  *  EMBL, Meyerhofstrasse 1, 69917 Heidelberg, Germany
