JPRED-2 Add alscript to the Git repository
[jpred.git] / sources / alscript / src / fast2blc.c
1 /***************************************************************************
2
3 fast2blc:  A program to convert a FASTA format alignment file to an 
4                                                         AMPS blockfile.
5
6    Copyright:  Geoffrey J. Barton (1992,1997)
7
8    email: geoff@ebi.ac.uk
9    Please see the README file for details of conditions for use of this program.
10
11    $Id: fast2blc.c,v 1.3 1999/07/09 10:35:29 geoff Exp $
12    $Log: fast2blc.c,v $
13    Revision 1.3  1999/07/09 10:35:29  geoff
14    Change version and copyright statement to reflect 1997 status
15
16    Revision 1.2  1998/09/17 16:55:01  geoff
17    Check consistency with archive
18
19
20 ****************************************************************************
21
22 Notes:  This program can be run as a pipe:  type fast2blc -q < input > output
23 Only error messages will be output to std_err
24
25 Default mode is interactive and prompts for filenames.
26
27 The storage for the sequences is allocated dynamically, so the MAX_SEQ_LEN
28 defines in the header file "defaults.h" have no effect.  If a system memory
29 limit is reached, then a "malloc error" message will be written and the
30 program will stop.  Most computers should happily cope with large numbers of
31 long sequences.  If yours doesn't, some  possible solutions are outlined in
32 the user manual - alscript.doc.
33
34 24 Oct 1994 - modify to remove dots and dashes from input file before writing
35 output file (if -n option is second argument ).
36
37 19 April 1995 - fast2blc derived from clus2blc to read a FASTA style alignment
38 file.  This assumes the title line is after the id code rather than on the
39 next line.
40
41 ****************************************************************************/
42
43 #include <stdio.h>
44 #include <stdarg.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <ctype.h>
48
49 #include "gjutil.h"
50 #include "array.h"
51 #include "defaults.h"
52
53 #define TOKENS " \t\n"
54
55
56 main(int argc,char *argv[])
57 {
58         struct seqdat *seqs;
59         FILE *fp,*fout;
60         int nseq;
61         int found;
62         int i,j;
63         char *token,*sbit;
64         char *line;
65         extern FILE *std_err,*std_in,*std_out;
66         char *msffile;
67         char *blocfile;
68         int quiet;
69         char c;
70         int allen;  /* total alignment length */
71         int nodot;
72         
73         std_err = stderr;
74         std_in = stdin;
75         std_out = stdout;
76         
77         line = GJstrcreate(MAX_INLEN," ");
78         msffile = GJstrcreate(MAX_INLEN,NULL);
79         blocfile = GJstrcreate(MAX_INLEN,NULL);
80
81         nseq = 0;
82         found = 0;
83         quiet = 0;
84         allen = 0;
85         nodot = 0;
86
87         if(argc > 1){
88           if(strcmp(argv[1],"-q")==0){
89             /* Quiet mode - read .MSF file from stdin and output block file to stdout */
90             quiet = 1;
91             fp = std_in;
92             fout = std_out;
93           }
94           if(argc > 2){
95               if(strcmp(argv[2],"-n")==0){
96                   /* set flag to remove dots */
97                   nodot = 1;
98               }
99           }
100         }else{
101           /* Verbose mode - prompt for all filenames */
102           fprintf(std_out,"\n\n");
103           fprintf(std_out,"FASTA format to AMPS Blockfile conversion\n");
104           fprintf(std_out,"Copyright: G. J. Barton (1992)\n");
105           fprintf(std_out,"Author: G. J. Barton (1992)\n\n");
106           fprintf(std_out,"Max number/length of alignment - Defined by System\n");
107           fprintf(std_out,"If you get a malloc error message - see manual\n\n");
108           fprintf(std_out,"Enter FASTA format alignment filename: ");
109           
110           fscanf(std_in,"%s",msffile);
111           fprintf(std_out,"Opening: %s\n",msffile);
112           fp = GJfopen(msffile,"r",1);
113           
114           fprintf(std_out,"Enter Block filename: ");
115           fscanf(std_in,"%s",blocfile);
116           fprintf(std_out,"Opening: %s\n",blocfile);
117           fout = GJfopen(blocfile,"w",1);
118         }
119         
120         fprintf(fout,"\n");
121         fprintf(fout,"Conversion of FASTA file to AMPS BLOCKFILE format\n");
122         fprintf(fout,"fast2blc:  Geoffrey J. Barton (1992)\n\n");
123
124         seqs = (struct seqdat *) GJmalloc(sizeof(struct seqdat));
125
126         if(!quiet)fprintf(std_out,"Reading .fas file\n");
127         nseq = 0;
128         while(fgets(line,MAX_INLEN,fp) != NULL){
129           if(line[0] == '>'){
130             /* found an identifier */
131             token = strtok(&line[1]," -\n");
132             if(token != NULL){
133               seqs = (struct seqdat *) GJrealloc(seqs,sizeof(struct seqdat) * (nseq + 1));
134               seqs[nseq].id = GJstrdup(token);
135               token = strtok(NULL,"\n");
136               if(token != NULL){
137                   /* assign the title line */
138                   seqs[nseq].title = GJstrdup(token);
139                   seqs[nseq].seq = GJstrcreate(MAX_SEQ_LEN,NULL);
140                   seqs[nseq].slen = 0;
141                   seqs[nseq].seq = (char *) GJmalloc(sizeof(char));
142                   i=0;
143                   while((c = fgetc(fp)) != '*'){
144                     /* read characters until * */
145                     if(isalpha(c) || c == '-' || c == '.'){
146                         seqs[nseq].seq = (char *) GJrealloc(seqs[nseq].seq,sizeof(char) * (i+1));
147                         seqs[nseq].seq[i] = c;
148                         ++i;
149                     }else if(c == EOF){
150                         break;
151                     }
152                   }
153               }else{
154                   fprintf(std_err,
155                           "Error:  No title in sequence %s - is this FASTA format?\n",seqs[nseq].id);
156                   exit(1);
157               }
158               seqs[nseq].slen = i;
159               if(i > allen) allen = i;
160               ++nseq;
161             }
162           }
163         }
164
165         if(!quiet)fprintf(std_out,"All %d sequences read in\n",nseq);
166         if(!quiet)fprintf(std_out,"Writing .blc file\n");
167         
168         for(i=0;i<nseq;++i){
169             fprintf(fout,">%s %s\n",seqs[i].id,seqs[i].title);
170         }
171         fprintf(fout,"* iteration 1\n");
172         for(i=0;i<allen;++i){
173             for(j=0;j<nseq;++j){
174                 if(seqs[j].slen <= i){
175                   fprintf(fout,"%c",' ');
176                 }else{
177                 /* edit out dots and dashes if required */
178                 if(nodot == 1){
179                     if(seqs[j].seq[i] == '.' || seqs[j].seq[i] == '-'){
180                         seqs[j].seq[i] = ' ';
181                     }
182                 }
183                   fprintf(fout,"%c",seqs[j].seq[i]);
184                 }
185             }
186             fprintf(fout,"\n");
187         }
188         fprintf(fout,"*\n");
189         if(!quiet)fprintf(std_out,"All done\n");
190         
191         for(i=0;i<nseq;++i){
192           GJfree(seqs[i].seq);
193           GJfree(seqs[i].id);
194           GJfree(seqs[i].title);
195         }
196         GJfree(seqs);
197         GJfree(line);
198         GJfree(blocfile);
199         GJfree(msffile);
200
201 }