source: tags/arb-6.0/SL/HELIX/BI_helix.cxx

Last change on this file was 8623, checked in by westram, 12 years ago

merge from e4fix [8376] [8377] [8378] [8379] [8380] [8386] [8387] [8388] [8389]

  • do not save AWARs which have default values
    • motivation: edit4-props saved after [8362] did not load with older versions
    • pros:
      • if the user did not change the default, changing the default in code will propagate to the user
    • cons:
      • AWARs used by multiple applications will trigger in non-saving application, when the database containing the awar is saved
        • only happens once if AWAR was previously stored with default-value
        • the most obvious ones were those edit4-search-strings linked to ntree (primer, probe, gene). disarmed them by setting the default to NULL
  • always generate definitions of SAI color translation tables (since default no longer saved)
    • drawback: when user deletes a default color translation table, it will re-appear after restart
  • allow experts to save fast-aligner protection to properties
  • deliver errors exported by awar callbacks (when triggered by widget change)
  • sequence color mapping
    • translate stored old default ('=0') to new default ('') on awar creation
    • removed code talking to AWARs via ARBDB interface - just use AWARs straightforward
  • ignore request_refresh_for_sequence_terminals when there is no hierarchy yet (now triggered by seq colors)
  • lib/arb_default/edit4.arb
    • removed default values (where code defaulted to same value)
    • changed some defaults
      • aligner (explicit, but empty ref)
      • helix setting (stolen from WL)
  • lib/arb_default/ntree.arb
    • removed all values
      • equal to default value
      • obsolete entries (former awar names)
      • entries that are now stored in main DB
  • removed unused AWARS (AWTC_create_rename_awars)
  • default for AWAR_TREE now "" everywhere
  • removed unused AISC variable
  • renamed edit direction related variables/awars
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : BI_helix.cxx                                      //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "BI_helix.hxx"
12
13#include <arbdbt.h>
14
15#include <cctype>
16
17#define LEFT_HELIX "{[<("
18#define RIGHT_HELIX "}]>)"
19#define LEFT_NONS "#*abcdefghij"
20#define RIGHT_NONS "#*ABCDEFGHIJ"
21
22char *BI_helix::helix_error = 0;
23
24struct helix_stack {
25    struct helix_stack *next;
26    long    pos;
27    BI_PAIR_TYPE type;
28    char    c;
29};
30
31void BI_helix::_init()
32{
33    int i;
34    for (i=0; i<HELIX_MAX; i++) pairs[i] = 0;
35    for (i=0; i<HELIX_MAX; i++) char_bind[i] = 0;
36
37    entries = 0;
38    Size = 0;
39
40    pairs[HELIX_NONE]=strdup("");
41    char_bind[HELIX_NONE] = strdup(" ");
42
43    pairs[HELIX_STRONG_PAIR]=strdup("CG AT AU");
44    char_bind[HELIX_STRONG_PAIR] = strdup("~");
45
46    pairs[HELIX_PAIR]=strdup("GT GU");
47    char_bind[HELIX_PAIR] = strdup("-");
48
49    pairs[HELIX_WEAK_PAIR]=strdup("GA");
50    char_bind[HELIX_WEAK_PAIR] = strdup("=");
51
52    pairs[HELIX_NO_PAIR]=strdup("AA AC CC CT CU GG TU");
53    char_bind[HELIX_NO_PAIR] = strdup("#");
54
55    pairs[HELIX_USER0]=strdup(".A .C .G .T .U");
56    char_bind[HELIX_USER0] = strdup("*");
57
58    pairs[HELIX_USER1]=strdup("-A -C -G -T -U");
59    char_bind[HELIX_USER1] = strdup("#");
60
61    pairs[HELIX_USER2]=strdup("UU TT");
62    char_bind[HELIX_USER2] = strdup("+");
63
64    pairs[HELIX_USER3]=strdup("");
65    char_bind[HELIX_USER3] = strdup("");
66
67    pairs[HELIX_DEFAULT]=strdup("");
68    char_bind[HELIX_DEFAULT] = strdup("");
69
70    for (i=HELIX_NON_STANDARD0; i<=HELIX_NON_STANDARD9; i++) {
71        pairs[i] = strdup("");
72        char_bind[i] = strdup("");
73    }
74
75    pairs[HELIX_NO_MATCH]=strdup("");
76    char_bind[HELIX_NO_MATCH] = strdup("|");
77}
78
79BI_helix::BI_helix() {
80    _init();
81}
82
83BI_helix::~BI_helix() {
84    unsigned i;
85    for (i=0; i<HELIX_MAX; i++) free(pairs[i]);
86    for (i=0; i<HELIX_MAX; i++) free(char_bind[i]);
87
88    if (entries) {
89        for (i = 0; i<Size; ++i) {
90            if (entries[i].allocated) {
91                free(entries[i].helix_nr);
92            }
93        }
94        free(entries);
95    }
96}
97
98static long BI_helix_check_error(const char *key, long val, void *) {
99    struct helix_stack *stack = (struct helix_stack *)val;
100    if (!BI_helix::get_error() && stack) { // don't overwrite existing error
101        BI_helix::set_error(GBS_global_string("Too many '%c' in Helix '%s' pos %li", stack->c, key, stack->pos));
102    }
103    return val;
104}
105
106
107static long BI_helix_free_hash(const char *, long val, void *) {
108    struct helix_stack *stack = (struct helix_stack *)val;
109    struct helix_stack *next;
110    for (; stack; stack = next) {
111        next = stack->next;
112        delete stack;
113    }
114    return 0;
115}
116
117const char *BI_helix::initFromData(const char *helix_nr_in, const char *helix_in, size_t sizei)
118/* helix_nr string of helix identifiers
119   helix    helix
120   size     alignment len
121*/
122{
123    clear_error();
124
125    GB_HASH *hash = GBS_create_hash(256, GB_IGNORE_CASE);
126    size_t   pos;
127    char     c;
128    char     ident[256];
129    char    *sident;
130   
131    struct helix_stack *laststack = 0, *stack;
132
133    Size = sizei;
134
135    char *helix = 0;
136    {
137        size_t len          = strlen(helix_in);
138        if (len > Size) len = Size;
139
140        char *h = (char *)malloc(Size+1);
141        h[Size] = 0;
142
143        if (len<Size) memset(h+len, '.', Size-len);
144        memcpy(h, helix_in, len);
145        helix = h;
146    }
147
148    char *helix_nr = 0;
149    if (helix_nr_in) {
150        size_t len          = strlen(helix_nr_in);
151        if (len > Size) len = (int)Size;
152
153        char *h = (char *)malloc((int)Size+1);
154        h[Size] = 0;
155
156        if (len<Size) memset(h+len, '.', (int)(Size-len));
157        memcpy(h, helix_nr_in, len);
158        helix_nr = h;
159    }
160
161    strcpy(ident, "0");
162    long pos_scanned_till = -1;
163
164    entries = (BI_helix_entry *)GB_calloc(sizeof(BI_helix_entry), (size_t)Size);
165    sident  = 0;
166
167    for (pos = 0; pos < Size; pos ++) {
168        if (helix_nr) {
169            if (long(pos)>pos_scanned_till && isalnum(helix_nr[pos])) {
170                for (int j=0; (pos+j)<Size; j++) {
171                    char hn = helix_nr[pos+j];
172                    if (isalnum(hn)) {
173                        ident[j] = hn;
174                    }
175                    else {
176                        ident[j]         = 0;
177                        pos_scanned_till = pos+j;
178                        break;
179                    }
180                }
181            }
182        }
183        c = helix[pos];
184        if (strchr(LEFT_HELIX, c) || strchr(LEFT_NONS, c)) { // push
185            laststack = (struct helix_stack *)GBS_read_hash(hash, ident);
186            stack = new helix_stack;
187            stack->next = laststack;
188            stack->pos = pos;
189            stack->c = c;
190            GBS_write_hash(hash, ident, (long)stack);
191        }
192        else if (strchr(RIGHT_HELIX, c) || strchr(RIGHT_NONS, c)) { // pop
193            stack = (struct helix_stack *)GBS_read_hash(hash, ident);
194            if (!stack) {
195                bi_assert(!helix_error); // already have an error
196                helix_error = GBS_global_string_copy("Too many '%c' in Helix '%s' pos %zu", c, ident, pos);
197                goto helix_end;
198            }
199            if (strchr(RIGHT_HELIX, c)) {
200                entries[pos].pair_type = HELIX_PAIR;
201                entries[stack->pos].pair_type = HELIX_PAIR;
202            }
203            else {
204                c = tolower(c);
205                if (stack->c != c) {
206                    bi_assert(!helix_error); // already have an error
207                    helix_error = GBS_global_string_copy("Character '%c' pos %li doesn't match character '%c' pos %zu in Helix '%s'",
208                                                         stack->c, stack->pos, c, pos, ident);
209                    goto helix_end;
210                }
211                if (isalpha(c)) {
212                    entries[pos].pair_type = (BI_PAIR_TYPE)(HELIX_NON_STANDARD0+c-'a');
213                    entries[stack->pos].pair_type = (BI_PAIR_TYPE)(HELIX_NON_STANDARD0+c-'a');
214                }
215                else {
216                    entries[pos].pair_type = HELIX_NO_PAIR;
217                    entries[stack->pos].pair_type = HELIX_NO_PAIR;
218                }
219            }
220            entries[pos].pair_pos = stack->pos;
221            entries[stack->pos].pair_pos = pos;
222            GBS_write_hash(hash, ident, (long)stack->next);
223
224            if (sident == 0 || strcmp(sident+1, ident) != 0) {
225                sident = (char*)malloc(strlen(ident)+2);
226                sprintf(sident, "-%s", ident);
227
228                entries[stack->pos].allocated = true;
229            }
230            entries[pos].helix_nr        = sident+1;
231            entries[stack->pos].helix_nr = sident;
232            bi_assert((long)pos != stack->pos);
233
234            delete stack;
235        }
236    }
237
238    GBS_hash_do_loop(hash, BI_helix_check_error, NULL);
239
240 helix_end :
241    GBS_hash_do_loop(hash, BI_helix_free_hash, NULL);
242    GBS_free_hash(hash);
243
244    free(helix_nr);
245    free(helix);
246
247    return get_error();
248}
249
250
251const char *BI_helix::init(GBDATA *gb_helix_nr, GBDATA *gb_helix, size_t sizei) {
252    clear_error();
253
254    if (!gb_helix) set_error("Can't find SAI:HELIX");
255    else if (!gb_helix_nr) set_error("Can't find SAI:HELIX_NR");
256    else {
257        GB_transaction ta(gb_helix);
258        initFromData(GB_read_char_pntr(gb_helix_nr), GB_read_char_pntr(gb_helix), sizei);
259    }
260
261    return get_error();
262}
263
264const char *BI_helix::init(GBDATA *gb_main, const char *alignment_name, const char *helix_nr_name, const char *helix_name)
265{
266    GB_transaction ta(gb_main);
267    clear_error();
268
269    GBDATA *gb_sai_data = GBT_get_SAI_data(gb_main);
270    long    size2       = GBT_get_alignment_len(gb_main, alignment_name);
271
272    if (size2<=0) set_error(GB_await_error());
273    else {
274        GBDATA *gb_helix_nr_con = GBT_find_SAI_rel_SAI_data(gb_sai_data, helix_nr_name);
275        GBDATA *gb_helix_con    = GBT_find_SAI_rel_SAI_data(gb_sai_data, helix_name);
276        GBDATA *gb_helix        = 0;
277        GBDATA *gb_helix_nr     = 0;
278
279        if (gb_helix_nr_con)    gb_helix_nr = GBT_read_sequence(gb_helix_nr_con, alignment_name);
280        if (gb_helix_con)       gb_helix = GBT_read_sequence(gb_helix_con, alignment_name);
281
282        init(gb_helix_nr, gb_helix, size2);
283    }
284
285    return get_error();
286}
287
288const char *BI_helix::init(GBDATA *gb_main, const char *alignment_name)
289{
290    GB_transaction ta(gb_main);
291
292    char *helix    = GBT_get_default_helix(gb_main);
293    char *helix_nr = GBT_get_default_helix_nr(gb_main);
294
295    const char *err = init(gb_main, alignment_name, helix_nr, helix);
296
297    free(helix);
298    free(helix_nr);
299
300    return err;
301}
302
303const char *BI_helix::init(GBDATA *gb_main) {
304    GB_transaction ta(gb_main);
305
306    char       *alignment_name = GBT_get_default_alignment(gb_main);
307    const char *err            = init(gb_main, alignment_name);
308
309    free(alignment_name);
310    return err;
311}
312
313bool BI_helix::is_pairtype(char left, char right, BI_PAIR_TYPE pair_type) {
314    int   len = strlen(pairs[pair_type])-1;
315    char *pai = pairs[pair_type];
316
317    for (int i=0; i<len; i+=3) {
318        if ((pai[i] == left && pai[i+1] == right) ||
319            (pai[i] == right && pai[i+1] == left)) return true;
320    }
321    return false;
322}
323
324int BI_helix::check_pair(char left, char right, BI_PAIR_TYPE pair_type) {
325    // return value:
326    // 2  = helix
327    // 1  = weak helix
328    // 0  = no helix
329    // -1 = nothing
330
331    left  = toupper(left);
332    right = toupper(right);
333    switch (pair_type) {
334        case HELIX_PAIR:
335            if (is_pairtype(left, right, HELIX_STRONG_PAIR) ||
336                is_pairtype(left, right, HELIX_PAIR)) return 2;
337            if (is_pairtype(left, right, HELIX_WEAK_PAIR)) return 1;
338            return 0;
339
340        case HELIX_NO_PAIR:
341            if (is_pairtype(left, right, HELIX_STRONG_PAIR) ||
342                is_pairtype(left, right, HELIX_PAIR)) return 0;
343            return 1;
344
345        default:
346            return is_pairtype(left, right, pair_type) ? 1 : 0;
347    }
348}
349
350long BI_helix::first_pair_position() const {
351    return entries[0].pair_type == HELIX_NONE ? next_pair_position(0) : 0;
352}
353
354long BI_helix::next_pair_position(size_t pos) const {
355    if (entries[pos].next_pair_pos == 0) {
356        size_t p;
357        long   next_pos = -1;
358        for (p = pos+1; p<Size && next_pos == -1; ++p) {
359            if (entries[p].pair_type != HELIX_NONE) {
360                next_pos = p;
361            }
362            else if (entries[p].next_pair_pos != 0) {
363                next_pos = entries[p].next_pair_pos;
364            }
365        }
366
367        size_t q = p<Size ? p-2 : Size-1;
368
369        for (p = pos; p <= q; ++p) {
370            bi_assert(entries[p].next_pair_pos == 0);
371            entries[p].next_pair_pos = next_pos;
372        }
373    }
374    return entries[pos].next_pair_pos;
375}
376
377long BI_helix::first_position(const char *helix_Nr) const {
378    long pos;
379    for (pos = first_pair_position(); pos != -1; pos = next_pair_position(pos)) {
380        if (strcmp(helix_Nr, entries[pos].helix_nr) == 0) break;
381    }
382    return pos;
383}
384
385long BI_helix::last_position(const char *helix_Nr) const {
386    long pos = first_position(helix_Nr);
387    if (pos != -1) {
388        long next_pos = next_pair_position(pos);
389        while (next_pos != -1 && strcmp(helix_Nr, entries[next_pos].helix_nr) == 0) {
390            pos      = next_pos;
391            next_pos = next_pair_position(next_pos);
392        }
393    }
394    return pos;
395}
396
Note: See TracBrowser for help on using the repository browser.