source: tags/arb_5.2/SL/HELIX/BI_helix.cxx

Last change on this file was 6124, checked in by westram, 15 years ago
  • fixed macro IDs for EDIT4 clone windows
  • reuse GC window (using GC manager of 1st editor window; possible cause all GC managers use the same awars)
  • HelixSettings? window
    • reuse in EDIT4 clone windows
    • added HELP button
    • tighter layout
    • added check for duplicate pair definitions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.1 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5// #include <malloc.h>
6#include <arbdb.h>
7#include <arbdbt.h>
8
9#include "BI_helix.hxx"
10
11#define LEFT_HELIX "{[<("
12#define RIGHT_HELIX "}]>)"
13#define LEFT_NONS "#*abcdefghij"
14#define RIGHT_NONS "#*ABCDEFGHIJ"
15
16char *BI_helix::helix_error = 0;
17
18struct helix_stack {
19    struct helix_stack *next;
20    long    pos;
21    BI_PAIR_TYPE type;
22    char    c;
23};
24
25void BI_helix::_init(void)
26{
27    int i;
28    for (i=0;i<HELIX_MAX; i++) pairs[i] = 0;
29    for (i=0;i<HELIX_MAX; i++) char_bind[i] = 0;
30
31    entries = 0;
32    Size = 0;
33
34    pairs[HELIX_NONE]=strdup("");
35    char_bind[HELIX_NONE] = strdup(" ");
36
37    pairs[HELIX_STRONG_PAIR]=strdup("CG");
38    char_bind[HELIX_STRONG_PAIR] = strdup("-");
39
40    pairs[HELIX_PAIR]=strdup("AU GU");
41    char_bind[HELIX_PAIR] = strdup("-");
42
43    pairs[HELIX_WEAK_PAIR]=strdup("GA GT");
44    char_bind[HELIX_WEAK_PAIR] = strdup(".");
45
46    pairs[HELIX_NO_PAIR]=strdup("AA AC CC CT CU TU");
47    char_bind[HELIX_NO_PAIR] = strdup("#");
48
49    pairs[HELIX_USER0]=strdup(".A .C .G .T .U");
50    char_bind[HELIX_USER0] = strdup("?");
51
52    pairs[HELIX_USER1]=strdup("-A -C -G -T -U");
53    char_bind[HELIX_USER1] = strdup("#");
54
55    pairs[HELIX_USER2]=strdup(".. --");
56    char_bind[HELIX_USER2] = strdup(" ");
57
58    pairs[HELIX_USER3]=strdup(".-");
59    char_bind[HELIX_USER3] = strdup(" ");
60
61    pairs[HELIX_DEFAULT]=strdup("");
62    char_bind[HELIX_DEFAULT] = strdup("?");
63
64    for (i=HELIX_NON_STANDARD0;i<=HELIX_NON_STANDARD9;i++){
65        pairs[i] = strdup("");
66        char_bind[i] = strdup("");
67    }
68
69    pairs[HELIX_NO_MATCH]=strdup("");
70    char_bind[HELIX_NO_MATCH] = strdup("|");
71}
72
73BI_helix::BI_helix(void) {
74    _init();
75}
76
77BI_helix::~BI_helix(void){
78    unsigned i;
79    for (i=0;i<HELIX_MAX; i++)  free(pairs[i]);
80    for (i=0;i<HELIX_MAX; i++)  free(char_bind[i]);
81
82    if (entries) {
83        for (i = 0; i<Size; ++i) {
84            if (entries[i].allocated) {
85                free(entries[i].helix_nr);
86            }
87        }
88        free(entries);
89    }
90}
91
92long BI_helix_check_error(const char *key, long val, void *) {
93    struct helix_stack *stack = (struct helix_stack *)val;
94    if (!BI_helix::get_error() && stack) { // don't overwrite existing error
95        BI_helix::set_error(GBS_global_string("Too many '%c' in Helix '%s' pos %li", stack->c, key, stack->pos));
96    }
97    return val;
98}
99
100
101long BI_helix_free_hash(const char *, long val, void *) {
102    struct helix_stack *stack = (struct helix_stack *)val;
103    struct helix_stack *next;
104    for ( ; stack; stack = next) {
105        next = stack->next;
106        delete stack;
107    }
108    return 0;
109}
110
111const char *BI_helix::initFromData(const char *helix_nr_in, const char *helix_in, size_t sizei)
112/* helix_nr string of helix identifiers
113   helix    helix
114   size     alignment len
115*/
116{
117    clear_error();
118   
119    GB_HASH *hash = GBS_create_hash(256, GB_IGNORE_CASE);
120    size_t pos;
121    char c;
122    char ident[256];
123    char *sident;
124    struct helix_stack *laststack = 0,*stack;
125
126    Size = sizei;
127
128    char *helix = 0;
129    {
130        size_t len          = strlen(helix_in);
131        if (len > Size) len = Size;
132
133        char *h = (char *)malloc(Size+1);
134        h[Size] = 0;
135       
136        if (len<Size) memset(h+len,'.', Size-len);
137        memcpy(h, helix_in, len);
138        helix = h;
139    }
140
141    char *helix_nr = 0;
142    if (helix_nr_in) {
143        size_t len          = strlen(helix_nr_in);
144        if (len > Size) len = (int)Size;
145
146        char *h = (char *)malloc((int)Size+1);
147        h[Size] = 0;
148
149        if (len<Size) memset(h+len,'.',(int)(Size-len));
150        memcpy(h, helix_nr_in, len);
151        helix_nr = h;
152    }
153
154    strcpy(ident,"0");
155    long pos_scanned_till = -1;
156
157    entries = (struct BI_helix_entry *)GB_calloc(sizeof(struct BI_helix_entry),(size_t)Size);
158    sident  = 0;
159   
160    for (pos = 0; pos < Size; pos ++ ) {
161        if (helix_nr) {
162            if (long(pos)>pos_scanned_till && isalnum(helix_nr[pos])) {
163                for (int j=0; (pos+j)<Size; j++) {
164                    char hn = helix_nr[pos+j];
165                    if (isalnum(hn)) {
166                        ident[j] = hn;
167                    }
168                    else {
169                        ident[j]         = 0;
170                        pos_scanned_till = pos+j;
171                        break;
172                    }
173                }
174            }
175        }
176        c = helix[pos];
177        if (strchr(LEFT_HELIX,c) || strchr(LEFT_NONS,c)  ){ // push
178            laststack = (struct helix_stack *)GBS_read_hash(hash,ident);
179            stack = new helix_stack;
180            stack->next = laststack;
181            stack->pos = pos;
182            stack->c = c;
183            GBS_write_hash(hash,ident,(long)stack);
184        }
185        else if (strchr(RIGHT_HELIX,c) || strchr(RIGHT_NONS,c) ){   // pop
186            stack = (struct helix_stack *)GBS_read_hash(hash,ident);
187            if (!stack) {
188                bi_assert(!helix_error); // already have an error
189                helix_error = GBS_global_string_copy("Too many '%c' in Helix '%s' pos %zu", c, ident, pos);
190                goto helix_end;
191            }
192            if (strchr(RIGHT_HELIX,c)) {
193                entries[pos].pair_type = HELIX_PAIR;
194                entries[stack->pos].pair_type = HELIX_PAIR;
195            }else{
196                c = tolower(c);
197                if (stack->c != c) {
198                    bi_assert(!helix_error); // already have an error
199                    helix_error = GBS_global_string_copy("Character '%c' pos %li doesn't match character '%c' pos %zu in Helix '%s'",
200                                                         stack->c, stack->pos, c, pos, ident);
201                    goto helix_end;
202                }
203                if (isalpha(c)) {
204                    entries[pos].pair_type = (BI_PAIR_TYPE)(HELIX_NON_STANDARD0+c-'a');
205                    entries[stack->pos].pair_type = (BI_PAIR_TYPE)(HELIX_NON_STANDARD0+c-'a');
206                }else{
207                    entries[pos].pair_type = HELIX_NO_PAIR;
208                    entries[stack->pos].pair_type = HELIX_NO_PAIR;
209                }
210            }
211            entries[pos].pair_pos = stack->pos;
212            entries[stack->pos].pair_pos = pos;
213            GBS_write_hash(hash,ident,(long)stack->next);
214
215            if (sident == 0 || strcmp(sident+1,ident) != 0) {
216                sident = (char*)malloc(strlen(ident)+2);
217                sprintf(sident,"-%s",ident);
218               
219                entries[stack->pos].allocated = true;
220            }
221            entries[pos].helix_nr        = sident+1;
222            entries[stack->pos].helix_nr = sident;
223            bi_assert((long)pos != stack->pos);
224
225            delete stack;
226        }
227    }
228
229    GBS_hash_do_loop(hash, BI_helix_check_error, NULL);
230
231 helix_end:
232    GBS_hash_do_loop(hash, BI_helix_free_hash, NULL);
233    GBS_free_hash(hash);
234
235    free(helix_nr);
236    free(helix);
237
238    return get_error();
239}
240
241
242const char *BI_helix::init(GBDATA *gb_helix_nr, GBDATA *gb_helix, size_t sizei) {
243    clear_error();
244   
245    if (!gb_helix) set_error("Can't find SAI:HELIX");
246    else if (!gb_helix_nr) set_error("Can't find SAI:HELIX_NR");
247    else {
248        GB_transaction ta(gb_helix);
249        initFromData(GB_read_char_pntr(gb_helix_nr), GB_read_char_pntr(gb_helix), sizei);
250    }
251   
252    return get_error();
253}
254
255const char *BI_helix::init(GBDATA *gb_main, const char *alignment_name, const char *helix_nr_name, const char *helix_name)
256{
257    GB_transaction ta(gb_main);
258    clear_error();
259
260    GBDATA *gb_sai_data = GBT_get_SAI_data(gb_main);
261    long    size2       = GBT_get_alignment_len(gb_main,alignment_name);
262
263    if (size2<=0) set_error(GB_await_error());
264    else {
265        GBDATA *gb_helix_nr_con = GBT_find_SAI_rel_SAI_data(gb_sai_data, helix_nr_name);
266        GBDATA *gb_helix_con    = GBT_find_SAI_rel_SAI_data(gb_sai_data, helix_name);
267        GBDATA *gb_helix        = 0;
268        GBDATA *gb_helix_nr     = 0;
269
270        if (gb_helix_nr_con)    gb_helix_nr = GBT_read_sequence(gb_helix_nr_con,alignment_name);
271        if (gb_helix_con)       gb_helix = GBT_read_sequence(gb_helix_con,alignment_name);
272
273        init(gb_helix_nr, gb_helix, size2);
274    }
275
276    return get_error();
277}
278
279const char *BI_helix::init(GBDATA *gb_main, const char *alignment_name)
280{
281    GB_transaction ta(gb_main);
282
283    char *helix    = GBT_get_default_helix(gb_main);
284    char *helix_nr = GBT_get_default_helix_nr(gb_main);
285
286    const char *err = init(gb_main, alignment_name, helix_nr, helix);
287
288    free(helix);
289    free(helix_nr);
290
291    return err;
292}
293
294const char *BI_helix::init(GBDATA *gb_main) {
295    GB_transaction ta(gb_main);
296   
297    char       *alignment_name = GBT_get_default_alignment(gb_main);
298    const char *err            = init(gb_main, alignment_name);
299
300    free(alignment_name);
301    return err;
302}
303
304bool BI_helix::is_pairtype(char left, char right, BI_PAIR_TYPE pair_type) {
305    int   len = strlen(pairs[pair_type])-1;
306    char *pai = pairs[pair_type];
307
308    for (int i=0; i<len;i+=3){
309        if ((pai[i] == left && pai[i+1] == right) ||
310            (pai[i] == right && pai[i+1] == left)) return true;
311    }
312    return false;
313}
314
315int BI_helix::check_pair(char left, char right, BI_PAIR_TYPE pair_type) {
316    // return value:
317    // 2  = helix
318    // 1  = weak helix
319    // 0  = no helix
320    // -1 = nothing
321
322    left  = toupper(left);
323    right = toupper(right);
324    switch(pair_type) {
325        case HELIX_PAIR:
326            if (is_pairtype(left,right,HELIX_STRONG_PAIR) ||
327                is_pairtype(left,right,HELIX_PAIR)) return 2;
328            if (is_pairtype(left,right,HELIX_WEAK_PAIR) ) return 1;
329            return 0;
330
331        case HELIX_NO_PAIR:
332            if (is_pairtype(left,right,HELIX_STRONG_PAIR) ||
333                is_pairtype(left,right,HELIX_PAIR) ) return 0;
334            return 1;
335           
336        default:
337            return is_pairtype(left,right,pair_type) ? 1 : 0;
338    }
339}
340
341long BI_helix::first_pair_position() const {
342    return entries[0].pair_type == HELIX_NONE ? next_pair_position(0) : 0;
343}
344
345long BI_helix::next_pair_position(size_t pos) const {
346    if (entries[pos].next_pair_pos == 0) {
347        size_t p;
348        long   next_pos = -1;
349        for (p = pos+1; p<Size && next_pos == -1; ++p) {
350            if (entries[p].pair_type != HELIX_NONE) {
351                next_pos = p;
352            }
353            else if (entries[p].next_pair_pos != 0) {
354                next_pos = entries[p].next_pair_pos;
355            }
356        }
357
358        size_t q = p<Size ? p-2: Size-1;
359
360        for (p = pos; p <= q; ++p) {
361            bi_assert(entries[p].next_pair_pos == 0);
362            entries[p].next_pair_pos = next_pos;
363        }
364    }
365    return entries[pos].next_pair_pos;
366}
367
368long BI_helix::first_position(const char *helix_Nr) const {
369    long pos;
370    for (pos = first_pair_position(); pos != -1; pos = next_pair_position(pos)) {
371        if (strcmp(helix_Nr, entries[pos].helix_nr) == 0) break;
372    }
373    return pos;
374}
375
376long BI_helix::last_position(const char *helix_Nr) const {
377    long pos = first_position(helix_Nr);
378    if (pos != -1) {
379        long next_pos = next_pair_position(pos);
380        while (next_pos != -1 && strcmp(helix_Nr, entries[next_pos].helix_nr) == 0) {
381            pos      = next_pos;
382            next_pos = next_pair_position(next_pos);
383        }
384    }
385    return pos;
386}
387
388
389
390
391/***************************************************************************************
392*******         Reference to abs pos                    ********
393****************************************************************************************/
394void BI_ecoli_ref::bi_exit(void){
395    delete [] abs2rel;
396    delete [] rel2abs;
397    abs2rel = 0;
398    rel2abs = 0;
399}
400
401BI_ecoli_ref::BI_ecoli_ref(void) {
402    memset((char *)this,0,sizeof(BI_ecoli_ref));
403}
404
405BI_ecoli_ref::~BI_ecoli_ref(void){
406    bi_exit();
407}
408
409inline bool isGap(char c) { return c == '-' || c == '.'; }
410
411const char *BI_ecoli_ref::init(const char *seq, size_t size) {
412    bi_exit();
413
414    abs2rel = new size_t[size];
415    rel2abs = new size_t[size];
416    memset((char *)rel2abs,0,(size_t)(sizeof(*rel2abs)*size));
417
418    relLen = 0;
419    absLen = size;
420    size_t i;
421    size_t sl = strlen(seq);
422    for (i=0; i<size; i++) {
423        abs2rel[i]      = relLen;
424        rel2abs[relLen] = i;
425        if (i<sl && !isGap(seq[i])) ++relLen;
426    }
427    return 0;
428}
429
430const char *BI_ecoli_ref::init(GBDATA *gb_main,char *alignment_name, char *ref_name) {
431    GB_transaction ta(gb_main);
432
433    GB_ERROR err  = 0;
434    long     size = GBT_get_alignment_len(gb_main,alignment_name);
435   
436    if (size<=0) err = GB_await_error();
437    else {
438        GBDATA *gb_ref_con   = GBT_find_SAI(gb_main, ref_name);
439        if (!gb_ref_con) err = GBS_global_string("I cannot find the SAI '%s'",ref_name);
440        else {
441            GBDATA *gb_ref   = GBT_read_sequence(gb_ref_con,alignment_name);
442            if (!gb_ref) err = GBS_global_string("Your SAI '%s' has no sequence '%s/data'", ref_name, alignment_name);
443            else {
444                err = init(GB_read_char_pntr(gb_ref), size);
445            }
446        }
447    }
448    return err;
449}
450
451const char *BI_ecoli_ref::init(GBDATA *gb_main) {
452    GB_transaction ta(gb_main);
453
454    char     *ref = GBT_get_default_ref(gb_main);
455    char     *use = GBT_get_default_alignment(gb_main);
456    GB_ERROR  err = init(gb_main,use,ref);
457
458    free(ref);
459    free(use);
460
461    return err;
462}
Note: See TracBrowser for help on using the repository browser.