source: tags/initial/AWT/AWT_iupac.cxx

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.8 KB
Line 
1#include <string.h>
2#include <ctype.h>
3
4#include "awt_assert.hxx"
5#include "awt_iupac.hxx"
6
7#define IUPAC_EMPTY " "
8#define ILL_CODE char(26)
9
10AWT_IUPAC_descriptor AWT_iupac_code[26][2]= {
11    {{ "A",     1 }, { "A",     1 }}, 
12    {{ "CGT",   3 }, { "CGU",   3 }}, 
13    {{ "C",     1 }, { "C",     1 }}, 
14    {{ "AGT",   3 }, { "AGU",   3 }}, 
15    {{ 0,       0 }, { 0,       0 }}, // E
16    {{ 0,       0 }, { 0,       0 }}, // F
17    {{ "G",     1 }, { "G",     1 }}, 
18    {{ "ACT",   3 }, { "ACU",   3 }}, 
19    {{ 0,       0 }, { 0,       0 }}, // I
20    {{ 0,       0 }, { 0,       0 }}, // J
21    {{ "GT",    2 }, { "GU",    2 }}, 
22    {{ 0,       0 }, { 0,       0 }}, // L
23    {{ "AC",    2 }, { "AC",    2 }}, 
24    {{ "ACGT",  1 }, { "ACGU",  1 }}, // N
25    {{ 0,       0 }, { 0,       0 }}, // O
26    {{ 0,       0 }, { 0,       0 }}, // P
27    {{ 0,       0 }, { 0,       0 }}, // Q
28    {{ "AG",    2 }, { "AG",    2 }}, 
29    {{ "CG",    2 }, { "CG",    2 }}, 
30    {{ "T",     1 }, { "U",     1 }}, // T
31    {{ "T",     1 }, { "U",     1 }}, // U
32    {{ "ACG",   3 }, { "ACG",   3 }}, 
33    {{ "AT",    2 }, { "AU",    2 }}, 
34    {{ 0,       0 }, { 0,       0 }}, // X
35    {{ "CT",    2 }, { "CU",    2 }}, 
36    {{ 0,       0 }, { 0,       0 }}  // Z
37   
38    // (In each single string the nucs have to be sorted alphabetically)
39};
40
41const int AWT_iupac_group[26] =  { // this is for amino_acids
42    1, // A
43    2, // B
44    0, // C
45    2, // D
46    2, // E
47    5, // F
48    1, // G
49    3, // H
50    4, // I
51    0, // J
52    3, // K
53    4, // L
54    4, // M
55    2, // N
56    0, // O
57    1, // P
58    2, // Q
59    3, // R
60    1, // S
61    1, // T
62    0, // U
63    4, // V
64    5, // W
65    0, // X
66    5, // Y
67    2, // Z
68};
69
70static char IUPAC_add[26][26]; // uses T
71static int IUPAC_add_initialized = 0;
72
73static void initialize_IUPAC_add()
74{
75    int c1, c2;
76
77    for (c1=0; c1<26; c1++) {
78        const char *decoded1 = AWT_iupac_code[c1][0].iupac;
79       
80        if (!decoded1) {
81            for (c2=0; c2<=c1; c2++) {
82                IUPAC_add[c1][c2] = ILL_CODE;
83                IUPAC_add[c2][c1] = ILL_CODE;
84            }
85        }
86        else {
87            IUPAC_add[c1][c1] = char(c1);       // add char to same char
88           
89            for (c2=0; c2<c1; c2++) {
90                if (strchr(decoded1, 'A'+c2)!=0) {      // char is already contained in this IUPAC
91                    IUPAC_add[c1][c2] = char(c1);
92                }
93                else {
94                    const char *decoded2 = AWT_iupac_code[c2][0].iupac;
95                   
96                    if (!decoded2) { // char is illegal
97                        IUPAC_add[c1][c2] = ILL_CODE;
98                    }
99                    else {
100#define MAX_MIXED 5
101                        char mixed[MAX_MIXED];
102                        char *mp = mixed;
103                        const char *d1 = decoded1;
104                        const char *d2 = decoded2;
105                       
106                        while (1) {
107                            char z1 = *d1;
108                            char z2 = *d2;
109                           
110                            if (!z1 && !z2) break;
111                           
112                            if (z1==z2) {
113                                *mp++ = z1;
114                                d1++;
115                                d2++;
116                            }
117                            else if (!z2 || (z1 && z1<z2)) {
118                                *mp++ = z1;
119                                d1++;
120                            }
121                            else {
122                                awt_assert(!z1 || (z2 && z2<z1));
123                                *mp++ = z2;
124                                d2++;
125                            }
126                        }
127                           
128                        awt_assert((mp-mixed)<MAX_MIXED);
129                        *mp++ = 0;
130                           
131#if !defined(NDEBUG) && 0
132                        printf("Mix '%s' + '%s' = '%s'\n", decoded1, decoded2, mixed);
133#endif                     
134                       
135                        int c3; 
136                       
137                        for (c3=0; c3<26; c3++) {
138                            if (AWT_iupac_code[c3][0].iupac && strcmp(mixed, AWT_iupac_code[c3][0].iupac)==0) {
139                                IUPAC_add[c1][c2] = char(c3);
140                                break;
141                            }
142                        }
143                           
144                        if (c3>=26) {
145                            IUPAC_add[c1][c2] = 0;
146                        }
147                    }
148                }
149                   
150                if (IUPAC_add[c1][c2]==('U'-'A')) {
151                    IUPAC_add[c1][c2] = 'T'-'A';
152                }
153                   
154                IUPAC_add[c2][c1] = IUPAC_add[c1][c2];
155            }
156        }
157
158    }
159}
160
161char AWT_encode_iupac(const char bases[], GB_alignment_type ali)
162{
163    if (!IUPAC_add_initialized) {
164        initialize_IUPAC_add();
165        IUPAC_add_initialized = 1;
166    }
167   
168    if (ali==GB_AT_AMI || ali==GB_AT_PRO) {
169        return '?';
170    }
171   
172    int i = 0;
173    char c1;
174   
175    while (1) {
176        c1 = bases[i++];
177        if (!c1) return '-';
178        if (isalpha(c1)) break;
179    }
180   
181    c1 = toupper(c1)-'A';
182    char c = IUPAC_add[c1][c1];
183   
184    while (c!=ILL_CODE && bases[i]) {
185        if (isalpha(bases[i])) {
186            int c2 = toupper(bases[i])-'A';
187            c = IUPAC_add[c][c2];
188        }
189        i++;
190    }
191   
192    if (c==ILL_CODE) {
193        return '-';
194    }
195   
196    c += 'A';
197    if (c=='T' && ali==GB_AT_RNA) c = 'U';
198    return c;
199}
200
201char AWT_iupac_add(char c1, char c2, GB_alignment_type ali) {
202    static char buffer[3];
203    buffer[0] = c1;
204    buffer[1] = c2;
205    buffer[2] = 0;
206    return AWT_encode_iupac(buffer, ali);
207}
208
209const char* AWT_decode_iupac(char iupac, GB_alignment_type ali, int decode_amino_iupac_groups)
210{
211    if (!isalpha(iupac)) {
212        return IUPAC_EMPTY;
213    }
214   
215    if (ali==GB_AT_AMI || ali==GB_AT_PRO) {
216        if (decode_amino_iupac_groups) { 
217            int group = AWT_iupac_group[toupper(iupac)-'A'];
218           
219            switch (group) {
220                case 1: return "AGPST";
221                case 2: return "BDENQZ";
222                case 3: return "HKR";
223                case 4: return "ILMV";
224                case 5: return "FWY";
225            }
226        }
227        return "?";
228    }
229   
230    const char *decoded = AWT_iupac_code[toupper(iupac)-'A'][ali==GB_AT_RNA ? 1 : 0].iupac;   
231   
232    return decoded ? decoded : IUPAC_EMPTY;
233}
234
Note: See TracBrowser for help on using the repository browser.