WSTester updated to work plus hopefully all the other changes that need to go into...
[jabaws.git] / binaries / src / ViennaRNA / Utils / b2ct.c
1 /* Last Changed Time-stamp: <2001-09-07 10:17:47 ivo> */
2 /* This program converts the bracket notation for RNA secondary structures
3    produced by RNAfold to .ct files used by Michael Zukers Program.
4    To compile enter:
5                     cc -o b2ct b2ct.c
6    And use as
7                     b2ct < structure_file > ct_file.ct
8    or
9                     RNAfold < sequence_file | b2ct > ct_file.ct
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #define MAXLENGTH 30000
16
17 void write_ct_file(char *fname, char *sequence, char *structure, char *name,
18                    float energy);
19 short *make_pair_table(const char *structure);
20 void *space(unsigned size);
21 void nrerror(char *message);
22
23 int main(void)
24 {
25    char line[MAXLENGTH+1];
26    char *string=NULL, *structure=NULL, *name=NULL;
27    float energy;
28    int n=0;
29    
30    while (fgets(line, MAXLENGTH, stdin)!=NULL) {
31        if (strcmp(line,"@")==0) break;
32       
33        switch (line[0]) {
34        case '>': name = (char *) space(strlen(line));
35          sscanf(line,"> %s", name);
36          break;
37        case '.':
38        case '(':
39        case ')': structure = (char *) space(strlen(line));
40          if (sscanf(line,"%s (%f)", structure, &energy)!=2) {
41            free(structure); structure=NULL; break;
42          }
43          n++;
44          break;
45        default: string = (char *) space(strlen(line)+1);
46          sscanf(line, "%s", string);
47        }
48        if (structure!=NULL) {
49          if (name==NULL) {
50            name = (char *) space(10);
51            sprintf(name,"%d",n);
52          }
53          write_ct_file("-", string, structure, name, energy);
54          free(string); 
55          free(structure); 
56          free(name);
57          string = structure = name = NULL;
58        }
59    }
60    return 0;
61 }
62
63 void write_ct_file(char *fname, char *sequence, char *structure, char *name,
64                    float energy)
65 {
66    int i, length;
67    short *table;
68    FILE *ct;
69
70    length = strlen(structure);
71    if ((table = make_pair_table(structure))==NULL) {
72      return;
73    }
74    if (length!=strlen(sequence))
75      nrerror("sequence and structure have unequal length");
76    
77    if (strcmp(fname,"-")==0) 
78      ct = stdout;
79    else {
80      ct = fopen(fname, "a");
81      if (ct==NULL) nrerror("can't open .ct file");
82    }
83
84    fprintf(ct, "%5d ENERGY = %7.1f    %s\n", length, energy, name);
85    for (i=1; i<=length; i++) 
86      fprintf(ct, "%5d %c   %5d %4d %4d %4d\n",
87              i, sequence[i-1], i-1, (i+1)%(length+1), table[i], i);
88    if (strcmp(fname,"-"))
89      fclose(ct);
90    else fflush(ct);
91 }
92
93 short *make_pair_table(const char *structure)
94 {
95     /* returns array representation of structure.
96        table[i] is 0 if unpaired or j if (i.j) pair.  */
97    int i,j,hx;
98    int length;
99    short *stack;
100    short *table;
101    
102    length = strlen(structure);
103    stack = (short *) space(sizeof(short)*(length+1));
104    table = (short *) space(sizeof(short)*(length+2));
105    table[0] = length;
106    
107    for (hx=0, i=1; i<=length; i++) {
108       switch (structure[i-1]) {
109        case '(': 
110          stack[hx++]=i;
111          break;
112        case ')':
113          j = stack[--hx];
114          if (hx<0) {
115             fprintf(stderr, "unbalanced brackets in %s\n", structure);
116             free(stack); free(table); return NULL;
117          }
118          table[i]=j;
119          table[j]=i;
120          break;
121        default:   /* unpaired base, usually '.' */
122          table[i]= 0;
123          break;
124       }
125    }
126    free(stack);
127    if (hx!=0) {
128       fprintf(stderr, "unbalanced brackets %s\n", structure);
129       free(table);
130       return NULL;
131    }
132    return(table);
133 }
134
135 void *space(unsigned size)
136 {
137     void *pointer;
138     
139     if ( (pointer = (void *) calloc(1, size)) == NULL) {
140        fprintf(stderr,"SPACE: requested size: %d\n", size);
141        nrerror("SPACE allocation failure -> no memory");
142     }
143     return  pointer;
144 }
145
146
147 void nrerror(char *message)       /* output message upon error */
148 {
149     fprintf(stderr, "\n%s\n", message);
150     exit(0);
151 }
152