source: branches/port5/SL/AW_HELIX/AW_helix.cxx

Last change on this file was 6124, checked in by westram, 16 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: 9.1 KB
Line 
1// ==================================================================== //
2//                                                                      //
3//   File      : AW_helix.cxx                                           //
4//   Purpose   : Wrapper for BI_helix + AW-specific functions           //
5//                                                                      //
6//                                                                      //
7// Coded by Ralf Westram (coder@reallysoft.de) in December 2004         //
8// Copyright Department of Microbiology (Technical University Munich)   //
9//                                                                      //
10// Visit our web site at: http://www.arb-home.de/                       //
11//                                                                      //
12// ==================================================================== //
13
14#include "AW_helix.hxx"
15
16#include <cctype>
17#include <cstring>
18#include <aw_device.hxx>
19#include <aw_window.hxx>
20
21#define HELIX_AWAR_ENABLE          "Helix/enable"
22#define HELIX_AWAR_SYMBOL_TEMPLATE "Helix/symbols/%s"
23#define HELIX_AWAR_PAIR_TEMPLATE   "Helix/pairs/%s"
24
25struct helix_pair_def {
26    const char *awar;
27    BI_PAIR_TYPE pair_type;
28};
29
30helix_pair_def helix_awars[] = {
31    { "Strong_Pair",      HELIX_STRONG_PAIR },
32    { "Normal_Pair",      HELIX_PAIR },
33    { "Weak_Pair",        HELIX_WEAK_PAIR },
34    { "No_Pair",          HELIX_NO_PAIR },
35    { "User_Pair",        HELIX_USER0 },
36    { "User_Pair2",       HELIX_USER1 },
37    { "User_Pair3",       HELIX_USER2 },
38    { "User_Pair4",       HELIX_USER3 },
39    { "Default",          HELIX_DEFAULT },
40    { "Non_Standard_aA",  HELIX_NON_STANDARD0 },
41    { "Non_Standard1",    HELIX_NON_STANDARD1 },
42    { "Non_Standard2",    HELIX_NON_STANDARD2 },
43    { "Non_Standard3",    HELIX_NON_STANDARD3 },
44    { "Non_Standard4",    HELIX_NON_STANDARD4 },
45    { "Non_Standard5",    HELIX_NON_STANDARD5 },
46    { "Non_Standard6",    HELIX_NON_STANDARD6 },
47    { "Non_Standard7",    HELIX_NON_STANDARD7 },
48    { "Non_Standard8",    HELIX_NON_STANDARD8 },
49    { "Non_Standard9",    HELIX_NON_STANDARD9 },
50    { "Not_Non_Standard", HELIX_NO_MATCH },
51    { 0,                  HELIX_NONE },
52};
53
54inline const char *helix_symbol_awar(int idx) { return GBS_global_string(HELIX_AWAR_SYMBOL_TEMPLATE, helix_awars[idx].awar); }
55inline const char *helix_pair_awar  (int idx) { return GBS_global_string(HELIX_AWAR_PAIR_TEMPLATE,   helix_awars[idx].awar); }
56
57AW_helix::AW_helix(AW_root * aw_root)
58    : enabled(0)
59{
60    for (int j=0; helix_awars[j].awar; j++){
61        int i = helix_awars[j].pair_type;
62        aw_root->awar_string(helix_pair_awar(j),   pairs[i])    ->add_target_var(&pairs[i]);
63        aw_root->awar_string(helix_symbol_awar(j), char_bind[i])->add_target_var(&char_bind[i]);
64    }
65    aw_root->awar_int(HELIX_AWAR_ENABLE, 1)->add_target_var(&enabled);
66}
67
68char AW_helix::get_symbol(char left, char right, BI_PAIR_TYPE pair_type){
69    left  = toupper(left);
70    right = toupper(right);
71   
72    int erg;
73    if (pair_type < HELIX_NON_STANDARD0) {
74        erg = *char_bind[HELIX_DEFAULT];
75        for (int i = HELIX_STRONG_PAIR; i< HELIX_NON_STANDARD0; i++){
76            if (is_pairtype(left,right,(BI_PAIR_TYPE)i)){
77                erg = *char_bind[i];
78                break;
79            }
80        }
81    }
82    else {
83        erg = *char_bind[HELIX_NO_MATCH];
84        if (is_pairtype(left,right,pair_type)) erg =  *char_bind[pair_type];
85    }
86    if (!erg) erg = ' ';
87    return erg;
88}
89
90char *AW_helix::seq_2_helix(char *sequence,char undefsymbol){
91    size_t size2 = strlen(sequence);
92    bi_assert(size2<=size()); // if this fails there is a sequence longer than the alignment
93    char *helix = (char *)GB_calloc(sizeof(char),size()+1);
94    size_t i,j;
95    for (i=0; i<size2; i++) {
96        BI_PAIR_TYPE pairType = pairtype(i);
97
98        if (pairType == HELIX_NONE) {
99            helix[i] = undefsymbol;
100        }
101        else {
102            j        = opposite_position(i);
103            char sym = get_symbol(sequence[i], sequence[j], pairType);
104            helix[i] = sym == ' ' ? undefsymbol : sym;
105        }
106    }
107    return helix;
108}
109
110int 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,
111                            AW_pos x,AW_pos y, AW_pos opt_ascent,AW_pos opt_descent,
112                            AW_CL cduser, AW_CL cd1, AW_CL cd2)
113{
114    AWUSE(opt_ascent);AWUSE(opt_descent);
115    AW_helix *helix = (AW_helix *)cduser;
116    char *buffer = GB_give_buffer(size+1);
117    register unsigned long i,j,k;
118
119    for (k=0; k<size; k++) {
120        i = k+start;
121
122        BI_PAIR_TYPE pairType = helix->pairtype(i);
123        if (pairType == HELIX_NONE) {
124            buffer[k] = ' ';
125        }
126        else {
127            j             = helix->opposite_position(i);
128            char pairchar = j<opt_string_size ? opt_string[j] : '.';
129            buffer[k]     = helix->get_symbol(opt_string[i],pairchar, pairType);
130        }
131    }
132    buffer[size] = 0;
133    return device->text(gc,buffer,x,y,0.0,(AW_bitset)-1,cd1,cd2);
134}
135
136int AW_helix::show_helix( void *devicei, int gc1 , char *sequence,
137                          AW_pos x, AW_pos y,
138                          AW_bitset filter,
139                          AW_CL cd1, AW_CL cd2){
140
141    if (!has_entries()) return 0;
142    AW_device *device = (AW_device *)devicei;
143    return device->text_overlay(gc1, sequence, 0, x , y, 0.0 , filter, (AW_CL)this, cd1, cd2,
144                                1.0,1.0, BI_show_helix_on_device);
145}
146
147static void helix_pairs_changed_cb(AW_window *aww, AW_CL changed, AW_CL cl_cb_struct) {
148    static bool recursion = false;
149
150    if (!recursion) {
151        AW_cb_struct *awcbs     = reinterpret_cast<AW_cb_struct*>(cl_cb_struct);
152        AW_root      *aw_root   = aww->get_root();
153        AW_awar      *awar_pair = aw_root->awar(helix_pair_awar(changed));
154        char         *pairdef   = awar_pair->read_string();
155
156        recursion = true;
157        for (int i = 0; ; i += 3) {
158            char left  = toupper(pairdef[i]); if (!left) break;
159            char right = toupper(pairdef[i+1]); if (!right) break;
160
161            pairdef[i]   = left;
162            pairdef[i+1] = right;
163
164            for (int j = 0; helix_awars[j].awar; j++) {
165                if (j != changed) {
166                    AW_awar *awar_pair2 = aw_root->awar(helix_pair_awar(j));
167                    char    *pd2        = awar_pair2->read_string();
168                    int      dst        = 0;
169                    bool     modified   = false;
170
171                    for (int k = 0; ; k += 3) {
172                        char l = toupper(pd2[k]); if (!l) break;
173                        char r = toupper(pd2[k+1]); if (!r) break;
174
175                        if ((left == l && right == r) || (left == r && right == l)) {
176                            // remove duplicated pair
177                            modified = true;
178                        }
179                        else {
180                            pd2[dst]   = l;
181                            pd2[dst+1] = r;
182
183                            dst += 3;
184                        }
185                        if (!pd2[k+2]) break;
186                    }
187
188                    if (modified) {
189                        pd2[dst-1] = 0;
190                        awar_pair2->write_string(pd2);
191                    }
192
193                    free(pd2);
194                }
195            }
196
197            if (!pairdef[i+2]) break;
198        }
199        awar_pair->write_string(pairdef); // write back uppercase version
200        recursion = false;
201
202        awcbs->run_callback();
203
204        free(pairdef);
205    }
206}
207
208AW_window *create_helix_props_window(AW_root *awr, AW_cb_struct *awcbs){
209    static AW_window_simple *aws = 0;
210    if (!aws) {
211        aws = new AW_window_simple;
212        aws->init(awr, "HELIX_PROPS", "HELIX_PROPERTIES");
213
214        aws->at(10,10);
215        aws->auto_space(3,3);
216
217        aws->callback(AW_POPDOWN);
218        aws->create_button("CLOSE", "CLOSE", "C");
219        aws->callback( AW_POPUP_HELP, (AW_CL)"helixsym.hlp");
220        aws->create_button("HELP","HELP","H");
221
222        aws->at_newline();
223
224        const size_t max_awar_len = 18;
225        aws->label_length(max_awar_len);
226
227        aws->label("Show helix?");
228        aws->callback(awcbs);
229        aws->create_toggle(HELIX_AWAR_ENABLE);
230
231        aws->at_newline();
232
233        int ex = 0;
234        for (int j = 0; helix_awars[j].awar; j++) {
235            int  i = helix_awars[j].pair_type;
236
237            aw_assert(strlen(helix_awars[j].awar) <= max_awar_len);
238
239            if (i != HELIX_DEFAULT && i!= HELIX_NO_MATCH ) {
240                aws->label(helix_awars[j].awar);
241                aws->callback(helix_pairs_changed_cb, j, (AW_CL)awcbs);
242                aws->create_input_field(helix_pair_awar(j), 20);
243               
244                if (j == 0) ex = aws->get_at_xposition();
245            }
246            else {
247                aw_assert(j != 0);
248                aws->create_autosize_button(0,helix_awars[j].awar);
249                aws->at_x(ex);
250            }
251
252            aws->callback(awcbs);
253            aws->create_input_field(helix_symbol_awar(j), 3);
254            aws->at_newline();
255        }
256        aws->window_fit();
257    }
258    return aws;
259}
260
261
Note: See TracBrowser for help on using the repository browser.