source: tags/initial/AWT/BI_helix.cxx

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

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.5 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#ifdef _USE_AW_WINDOW
10#include <aw_root.hxx>
11#include <aw_device.hxx>
12#include <aw_window.hxx>
13#endif
14
15#include "BI_helix.hxx"
16
17#define LEFT_HELIX "{[<("
18#define RIGHT_HELIX "}]>)"
19#define LEFT_NONS "#*abcdefghij"
20#define RIGHT_NONS "#*ABCDEFGHIJ"
21
22char BI_helix::error[256];
23
24struct helix_stack {
25    struct helix_stack *next;
26    long        pos;
27    BI_PAIR_TYPE type;
28    char        c;     
29};
30
31struct {
32    const char *awar;
33    BI_PAIR_TYPE pair_type;
34} helix_awars[] = {
35    { "Strong_Pair", HELIX_STRONG_PAIR },
36    { "Normal_Pair", HELIX_PAIR },
37    { "Weak_Pair", HELIX_WEAK_PAIR },
38    { "No_Pair", HELIX_NO_PAIR },
39    { "User_Pair", HELIX_USER0 },
40    { "User_Pair2", HELIX_USER1 },
41    { "User_Pair3", HELIX_USER2 },
42    { "User_Pair4", HELIX_USER3 },
43    { "Default", HELIX_DEFAULT },
44    { "Non_Standart_aA", HELIX_NON_STANDART0 },
45    { "Non_Standart1", HELIX_NON_STANDART1 },
46    { "Non_Standart2", HELIX_NON_STANDART2 },
47    { "Non_Standart3", HELIX_NON_STANDART3 },
48    { "Non_Standart4", HELIX_NON_STANDART4 },
49    { "Non_Standart5", HELIX_NON_STANDART5 },
50    { "Non_Standart6", HELIX_NON_STANDART6 },
51    { "Non_Standart7", HELIX_NON_STANDART7 },
52    { "Non_Standart8", HELIX_NON_STANDART8 },
53    { "Non_Standart9", HELIX_NON_STANDART9 },
54    { "Not_Non_Standart", HELIX_NO_MATCH },
55    { 0, HELIX_NONE },
56};
57
58void BI_helix::_init(void)
59{
60    int i;
61    for (i=0;i<HELIX_MAX; i++) pairs[i] = 0;
62    for (i=0;i<HELIX_MAX; i++) char_bind[i] = 0;
63
64    entries = 0;
65    size = 0;
66       
67    pairs[HELIX_NONE]=strdup("");
68    char_bind[HELIX_NONE] = strdup(" ");
69
70    pairs[HELIX_STRONG_PAIR]=strdup("CG");
71    char_bind[HELIX_STRONG_PAIR] = strdup("-");
72
73    pairs[HELIX_PAIR]=strdup("AU GU");
74    char_bind[HELIX_PAIR] = strdup("-");
75
76    pairs[HELIX_WEAK_PAIR]=strdup("GA GT");
77    char_bind[HELIX_WEAK_PAIR] = strdup(".");
78
79    pairs[HELIX_NO_PAIR]=strdup("AA AC CC CT CU TU");
80    char_bind[HELIX_NO_PAIR] = strdup("#");
81
82    pairs[HELIX_USER0]=strdup(".A .C .G .T .U");
83    char_bind[HELIX_USER0] = strdup("?");
84
85    pairs[HELIX_USER1]=strdup("-A -C -G -T -U");
86    char_bind[HELIX_USER1] = strdup("#");
87
88    pairs[HELIX_USER2]=strdup(".. --");
89    char_bind[HELIX_USER2] = strdup(" ");
90
91    pairs[HELIX_USER3]=strdup(".-");
92    char_bind[HELIX_USER3] = strdup(" ");
93
94    pairs[HELIX_DEFAULT]=strdup("");
95    char_bind[HELIX_DEFAULT] = strdup("?");
96
97    for (i=HELIX_NON_STANDART0;i<=HELIX_NON_STANDART9;i++){
98        pairs[i] = strdup("");
99        char_bind[i] = strdup("");
100    }
101
102    pairs[HELIX_NO_MATCH]=strdup("");
103    char_bind[HELIX_NO_MATCH] = strdup("|");
104
105    deleteable = 1;
106}
107
108BI_helix::BI_helix(void)
109{ _init(); }
110
111#ifdef _USE_AW_WINDOW
112BI_helix::BI_helix(AW_root * aw_root)
113{
114    int i;
115    char awar[256];
116
117    _init();
118    int j;
119    for (j=0; helix_awars[j].awar; j++){
120        i = helix_awars[j].pair_type;
121        sprintf(awar,HELIX_AWAR_PAIR_TEMPLATE, helix_awars[j].awar);
122        aw_root->awar_string( awar,pairs[i])->add_target_var(&pairs[i]);
123        sprintf(awar,HELIX_AWAR_SYMBOL_TEMPLATE, helix_awars[j].awar);
124        aw_root->awar_string( awar, char_bind[i])->add_target_var(&char_bind[i]);
125    }
126    deleteable = 0;
127}
128#endif
129
130BI_helix::~BI_helix(void){
131    if (!deleteable){
132        GB_warning("Internal Programm Error: You cannot delete BI_helix !!");
133    }
134    int i;
135    for (i=0;i<HELIX_MAX; i++)  delete pairs[i];
136    for (i=0;i<HELIX_MAX; i++)  delete char_bind[i];
137
138    delete entries;
139}
140
141extern "C" long BI_helix_check_error(const char *key, long val)
142{
143    struct helix_stack *stack = (struct helix_stack *)val;
144    if (BI_helix::error[0]) return val;
145    if (stack) {
146        sprintf(BI_helix::error,"Too many '%c' in Helix '%s' pos %li",
147                stack->c, key, stack->pos);
148    }
149    return val;
150}
151
152
153extern "C" long BI_helix_free_hash(const char *key, long val)
154{
155    key = key;
156    struct helix_stack *stack = (struct helix_stack *)val;
157    struct helix_stack *next;
158    for ( ; stack; stack = next) {
159        next = stack->next;
160        delete stack;
161    }
162    return 0;
163}
164
165const char *BI_helix::init(char *helix_nr, char *helix, size_t sizei)
166    /* helix_nr string of helix identifiers
167   helix        helix
168   size         alignment len
169*/
170{
171    GB_HASH *hash = GBS_create_hash(256,1);
172    size_t pos;
173    char c;
174    char ident[256];
175    char *sident;
176    struct helix_stack *laststack = 0,*stack;
177       
178    size = sizei;
179
180    {
181        size_t len = strlen(helix);
182        if (len > size) len = size;
183        char *h = (char *)malloc(size+1);
184        h[size] = 0;
185        if (len<size) memset(h+len,'.', size-len);
186        memcpy(h,helix,len);
187        helix = h;
188    }
189
190    if (helix_nr) {
191        size_t len = strlen(helix_nr);
192        if (len > size) len = (int)size;
193        char *h = (char *)malloc((int)size+1);
194        h[size] = 0;
195        if (len<size) memset(h+len,'.',(int)(size-len));
196        memcpy(h,helix_nr,len);
197        helix_nr = h;
198    }
199
200    error[0] = 0;
201
202    strcpy(ident,"0");
203    entries = (struct BI_helix_entry *)GB_calloc(sizeof(struct BI_helix_entry),(size_t)size);
204    sident = strdup("-");
205    for (pos = 0; pos < size; pos ++ ) {
206        if (helix_nr) {
207            if ( isdigit(helix_nr[pos])) {
208                int j;
209                for (j=0;j<3 && pos+j<size;j++) {
210                    c = helix_nr[pos+j];
211                    helix_nr[pos+j] = ' ';
212                    if ( isalnum(c) ) {
213                        ident[j] = c;
214                        ident[j+1] = 0;
215                        if ( isdigit(c) ) continue;
216                    }
217                    break;
218                }
219            }
220        }
221        c = helix[pos];
222        if (strchr(LEFT_HELIX,c) || strchr(LEFT_NONS,c)  ){     // push
223            laststack = (struct helix_stack *)GBS_read_hash(hash,ident);
224            stack = new helix_stack;
225            stack->next = laststack;
226            stack->pos = pos;
227            stack->c = c;
228            GBS_write_hash(hash,ident,(long)stack);
229        }
230        else if (strchr(RIGHT_HELIX,c) || strchr(RIGHT_NONS,c) ){       // pop
231            stack = (struct helix_stack *)GBS_read_hash(hash,ident);
232            if (!stack) {
233                sprintf(error,"Too many '%c' in Helix '%s' pos %i",c,ident,pos);
234                goto helix_end;
235            }
236            if (strchr(RIGHT_HELIX,c)) {
237                entries[pos].pair_type = HELIX_PAIR;
238                entries[stack->pos].pair_type = HELIX_PAIR;
239            }else{
240                c = tolower(c);
241                if (stack->c != c) {
242                    sprintf(error,"Character '%c' pos %li don't mach character '%c' pos %i in Helix '%s'",
243                            stack->c,stack->pos,c,pos,ident);
244                    goto helix_end;
245                }
246                if (isalpha(c)) {
247                    entries[pos].pair_type = (BI_PAIR_TYPE)(HELIX_NON_STANDART0+c-'a');
248                    entries[stack->pos].pair_type = (BI_PAIR_TYPE)(HELIX_NON_STANDART0+c-'a');
249                }else{
250                    entries[pos].pair_type = HELIX_NO_PAIR;
251                    entries[stack->pos].pair_type = HELIX_NO_PAIR;
252                }
253            }
254            entries[pos].pair_pos = stack->pos;
255            entries[stack->pos].pair_pos = pos;
256            GBS_write_hash(hash,ident,(long)stack->next);
257
258            if (strcmp(sident+1,ident)) {
259                //free(sident);
260                sident = new char[strlen(ident)+2];
261                sprintf(sident,"-%s",ident);
262            }
263            entries[pos].helix_nr = sident+1;
264            entries[stack->pos].helix_nr = sident;
265
266            delete stack;
267        }
268    }
269
270    GBS_hash_do_loop(hash,BI_helix_check_error);
271
272 helix_end:;
273    GBS_hash_do_loop(hash,BI_helix_free_hash);
274    GBS_free_hash(hash);
275    delete helix_nr;
276    delete helix;
277    if (error[0]) return error;
278    return 0;
279}
280
281
282const char *BI_helix::init(GBDATA *gb_helix_nr,GBDATA *gb_helix,size_t sizei)
283{
284    if (gb_helix) GB_push_transaction(gb_helix);
285    char *helix_nr = 0;
286    char *helix = 0;
287    const char *err = 0;
288    if (!gb_helix) err =  "Cannot find the helix";
289    else if (gb_helix_nr) helix_nr = GB_read_string(gb_helix_nr);
290    if (!err) {
291        helix = GB_read_string(gb_helix);
292        err = init(helix_nr,helix,sizei);
293    }
294    delete helix_nr;
295    delete helix;
296    if (gb_helix) GB_pop_transaction(gb_helix);
297    return err;
298}
299
300const char *BI_helix::init(GBDATA *gb_main, const char *alignment_name, const char *helix_nr_name, const char *helix_name)
301{
302    const char *err = 0;
303    GB_push_transaction(gb_main);
304    GBDATA *gb_extended_data = GB_search(gb_main,"extended_data",GB_CREATE_CONTAINER);
305    long size2 = GBT_get_alignment_len(gb_main,alignment_name);
306    if (size2<=0) err = (char *)GB_get_error();
307    if (!err) {
308        GBDATA *gb_helix_nr_con = GBT_find_SAI_rel_exdata(gb_extended_data, helix_nr_name);
309        GBDATA *gb_helix_con = GBT_find_SAI_rel_exdata(gb_extended_data, helix_name);
310        GBDATA *gb_helix = 0;
311        GBDATA *gb_helix_nr = 0;
312       
313        if (gb_helix_nr_con)    gb_helix_nr = GBT_read_sequence(gb_helix_nr_con,alignment_name);
314        if (gb_helix_con)       gb_helix = GBT_read_sequence(gb_helix_con,alignment_name);
315       
316        err = init(gb_helix_nr, gb_helix, size2);
317    }
318    GB_pop_transaction(gb_main);
319    return err;
320}
321
322const char *BI_helix::init(GBDATA *gb_main)
323{
324    const char *err = 0;
325    GB_push_transaction(gb_main);
326    char *helix = GBT_get_default_helix(gb_main);
327    char *helix_nr = GBT_get_default_helix_nr(gb_main);
328    char *use = GBT_get_default_alignment(gb_main);
329    err =       init(gb_main,use,helix_nr,helix);
330    GB_pop_transaction(gb_main);
331    delete helix;
332    delete helix_nr;
333    delete use;
334
335    return err;
336
337}
338
339extern "C" {
340    char *GB_give_buffer(long size);
341}
342
343int BI_helix::_check_pair(char left, char right, BI_PAIR_TYPE pair_type)
344{
345    int i;
346    int len = strlen(pairs[pair_type])-1;
347    char *pai = pairs[pair_type];
348    for (i=0; i<len;i+=3){
349        if ( pai[i] == left && pai[i+1] == right) return 1;
350        if ( pai[i] == right && pai[i+1] == left) return 1;
351    }
352    return 0;
353}
354
355int BI_helix::check_pair(char left, char right, BI_PAIR_TYPE pair_type)
356    // returns 2 helix 1 weak helix 0 no helix  -1 nothing
357{
358    left = toupper(left);
359    right = toupper(right);
360    switch(pair_type) {
361        case HELIX_PAIR:
362            if (        _check_pair(left,right,HELIX_STRONG_PAIR) ||
363                    _check_pair(left,right,HELIX_PAIR) ) return 2;
364            if (        _check_pair(left,right,HELIX_WEAK_PAIR) ) return 1;
365            return 0;
366        case HELIX_NO_PAIR:
367            if (        _check_pair(left,right,HELIX_STRONG_PAIR) ||
368                    _check_pair(left,right,HELIX_PAIR) ) return 0;
369            return 1;
370        default:
371            return _check_pair(left,right,pair_type);
372    }
373}
374
375
376#ifdef _USE_AW_WINDOW
377
378char BI_helix::get_symbol(char left, char right, BI_PAIR_TYPE pair_type){
379    left = toupper(left);
380    right = toupper(right);
381    int i;
382    int erg;
383    if (pair_type< HELIX_NON_STANDART0) {
384        erg = *char_bind[HELIX_DEFAULT];
385        for (i=HELIX_STRONG_PAIR; i< HELIX_NON_STANDART0; i++){
386            if (_check_pair(left,right,(BI_PAIR_TYPE)i)){
387                erg = *char_bind[i];
388                break;
389            }
390        }
391    }else{
392        erg = *char_bind[HELIX_NO_MATCH];
393        if (_check_pair(left,right,pair_type)) erg =  *char_bind[pair_type];
394    }
395    if (!erg) erg = ' ';
396    return erg;
397}
398
399char *BI_helix::seq_2_helix(char *sequence,char undefsymbol){
400    size_t size2 = strlen(sequence);
401    bi_assert(size2<=size); // if this fails there is a sequence longer than the alignment
402    char *helix = (char *)GB_calloc(sizeof(char),size+1);
403    register unsigned long i,j;
404    for (i=0; i<size2; i++) {
405        if ( i<size && entries[i].pair_type) {
406            j = entries[i].pair_pos;
407            helix[i] = get_symbol(sequence[i],sequence[j],
408                                  entries[i].pair_type);
409        }else{
410            helix[i] = undefsymbol;
411        }
412        if (helix[i] == ' ') helix[i] = undefsymbol;
413    }
414    return helix;
415}
416
417int BI_show_helix_on_device(AW_device *device, int gc, const char *opt_string, size_t opt_string_size, size_t start, size_t size,
418                            AW_pos x,AW_pos y, AW_pos opt_ascent,AW_pos opt_descent,
419                            AW_CL cduser, AW_CL cd1, AW_CL cd2)
420{
421    AWUSE(opt_ascent);AWUSE(opt_descent);
422    BI_helix *THIS = (BI_helix *)cduser;
423    char *buffer = GB_give_buffer(size+1);
424    register unsigned long i,j,k;
425       
426    for (k=0; k<size; k++) {
427        i = k+start;
428        if ( i<THIS->size && THIS->entries[i].pair_type) {
429            j = THIS->entries[i].pair_pos;
430            char pairing_character = '.';
431            if (j < opt_string_size){
432                pairing_character = opt_string[j];
433            }
434            buffer[k] = THIS->get_symbol(opt_string[i],pairing_character,
435                                         THIS->entries[i].pair_type);
436        }else{
437            buffer[k] = ' ';
438        }
439    }
440    buffer[size] = 0;
441    return device->text(gc,buffer,x,y,0.0,(AW_bitset)-1,cd1,cd2);
442}
443
444int BI_helix::show_helix( void *devicei, int gc1 , char *sequence,
445                          AW_pos x, AW_pos y,
446                          AW_bitset filter,
447                          AW_CL cd1, AW_CL cd2){
448
449    if (!entries) return 0;
450    AW_device *device = (AW_device *)devicei;
451    return device->text_overlay(gc1, sequence, 0, x , y, 0.0 , filter, (AW_CL)this, cd1, cd2,
452                                1.0,1.0, BI_show_helix_on_device);
453}
454
455
456
457AW_window *create_helix_props_window(AW_root *awr, AW_cb_struct * /*owner*/awcbs){
458    AW_window_simple *aws = new AW_window_simple;
459    aws->init( awr, "HELIX_PROPS", "HELIX_PROPERTIES",400, 300 );
460
461    aws->at           ( 10,10 );
462    aws->auto_space(3,3);
463    aws->callback     ( AW_POPDOWN );
464    aws->create_button( "CLOSE", "CLOSE", "C" );
465    aws->at_newline();
466
467    aws->label_length( 18 );   
468    int i;
469    int j;
470    int ex= 0,ey = 0;
471    char awar[256];
472    for (j=0; helix_awars[j].awar; j++){
473
474        aws->label_length( 25 );       
475        i = helix_awars[j].pair_type;
476
477        if (i != HELIX_DEFAULT && i!= HELIX_NO_MATCH ) {
478            sprintf(awar,HELIX_AWAR_PAIR_TEMPLATE, helix_awars[j].awar);
479            aws->label(helix_awars[j].awar);
480            aws->callback(awcbs);
481            aws->create_input_field(awar,20);
482        }else{
483            aws->create_button(0,helix_awars[j].awar);
484            aws->at_x(ex);
485        }
486        if (!j) aws->get_at_position(&ex,&ey);
487
488        sprintf(awar,HELIX_AWAR_SYMBOL_TEMPLATE, helix_awars[j].awar);
489        aws->callback(awcbs);
490        aws->create_input_field(awar,3);
491        aws->at_newline();
492    }
493    aws->window_fit();
494    return (AW_window *)aws;
495}
496#endif
497
498/***************************************************************************************
499*******                 Reference to abs pos                                    ********
500****************************************************************************************/
501void BI_ecoli_ref::exit(void){
502    delete _abs_2_rel1;
503    delete _abs_2_rel2;
504    delete _rel_2_abs;
505    _abs_2_rel1 = 0;
506    _abs_2_rel2 = 0;
507    _rel_2_abs = 0;
508}
509
510BI_ecoli_ref::BI_ecoli_ref(void)
511{
512    memset((char *)this,0,sizeof(BI_ecoli_ref));
513}
514
515BI_ecoli_ref::~BI_ecoli_ref(void){
516    exit();
517}
518
519const char *BI_ecoli_ref::init(char *seq,long size)
520{
521    exit();
522    _abs_2_rel1 = new long[size];
523    _abs_2_rel2 = new long[size];
524    _rel_2_abs = new long[size];
525    memset((char *)_rel_2_abs,0,(size_t)(sizeof(long)*size));
526
527    _rel_len = 0;
528    _abs_len = size;
529    long rel_len2 = 0;
530    long i;
531    long sl = strlen(seq);
532    for (i= 0;i<size;i++) {
533        _abs_2_rel1[i] = _rel_len;
534        _abs_2_rel2[i] = rel_len2;
535        _rel_2_abs[_rel_len] = i;
536        if (i>=sl || seq[i] == '.' || seq[i] == '-') {
537            rel_len2++;
538        }else{
539            rel_len2 = 0;
540            _rel_len ++;
541        }
542    }
543    return 0;
544}
545
546const char *BI_ecoli_ref::init(GBDATA *gb_main,char *alignment_name, char *ref_name)
547{
548    const char *err = 0;
549    GB_transaction dummy(gb_main);
550    long size = GBT_get_alignment_len(gb_main,alignment_name);
551    if (size<=0) err = (char*)GB_get_error();
552    if (!err) {
553        GBDATA *gb_ref_con =
554            GBT_find_SAI(gb_main, ref_name);
555        GBDATA *gb_ref = 0;
556        if (gb_ref_con){
557            gb_ref = GBT_read_sequence(gb_ref_con,alignment_name);
558            if (gb_ref){
559                err = init(GB_read_char_pntr(gb_ref), size);
560            }else{
561                err = (char *)GB_export_error("Your SAI '%s' has no sequence '%s/data'",
562                                              ref_name,alignment_name);
563            }
564        }else{
565            err = (char *)GB_export_error("I cannot find the SAI '%s'",ref_name);
566        }
567    }
568    return err;
569}
570
571const char *BI_ecoli_ref::init(GBDATA *gb_main)
572{
573    const char *err = 0;
574    GB_transaction dummy(gb_main);
575    char *ref = GBT_get_default_ref(gb_main);
576    char *use = GBT_get_default_alignment(gb_main);
577    err =       init(gb_main,use,ref);
578    delete ref;
579    delete use;
580
581    return err;
582
583}
584
585
586const char *BI_ecoli_ref::abs_2_rel(long in,long &out,long &add){
587    if (!_abs_2_rel1) {
588        out = in;
589        add = 0;
590        return "BI_ecoli_ref is not correctly initialized";
591    }
592    if (in >= _abs_len) in = _abs_len -1;
593    if (in < 0 ) in  = 0;
594    out = _abs_2_rel1[in];
595    add = _abs_2_rel2[in];
596    return 0;
597}
598
599const char *BI_ecoli_ref::rel_2_abs(long in,long add,long &out){
600    if (!_abs_2_rel1) {
601        out = in;
602        return ("BI_ecoli_ref is not correctly initialized");
603    }
604    if (in >= _rel_len) in = _rel_len -1;
605    if (in < 0 ) in  = 0;
606    out = _rel_2_abs[in]+add;
607    return 0;
608}
Note: See TracBrowser for help on using the repository browser.