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

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